/* api.c API unit tests
 *
 * Copyright (C) 2006-2024 wolfSSL Inc.
 *
 * This file is part of wolfSSL.
 *
 * wolfSSL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * wolfSSL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
 */

/* For AES-CBC, input lengths can optionally be validated to be a
 * multiple of the block size, by defining WOLFSSL_AES_CBC_LENGTH_CHECKS,
 * also available via the configure option --enable-aescbc-length-checks.
 */


/*----------------------------------------------------------------------------*
 | Includes
 *----------------------------------------------------------------------------*/

#ifdef HAVE_CONFIG_H
    #include <config.h>
#endif

#include <wolfssl/wolfcrypt/settings.h>
#undef TEST_OPENSSL_COEXIST /* can't use this option with this example */

#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/hash.h>

#if defined(WOLFSSL_STATIC_MEMORY)
    #include <wolfssl/wolfcrypt/memory.h>
#endif
#ifdef WOLFSSL_ASNC_CRYPT
    #include <wolfssl/wolfcrypt/async.h>
#endif
#ifdef HAVE_ECC
    #include <wolfssl/wolfcrypt/ecc.h>   /* wc_ecc_fp_free */
    #ifdef WOLFSSL_SM2
        #include <wolfssl/wolfcrypt/sm2.h>
    #endif
#endif
#ifndef NO_ASN
    #include <wolfssl/wolfcrypt/asn_public.h>
#endif

#include <stdlib.h>
#include <wolfssl/ssl.h>  /* compatibility layer */
#include <wolfssl/error-ssl.h>

#include <wolfssl/test.h>
#include <tests/unit.h>
#include <tests/utils.h>

/* for testing compatibility layer callbacks */
#include "examples/server/server.h"

#ifndef NO_MD5
    #include <wolfssl/wolfcrypt/md5.h>
#endif
#ifndef NO_SHA
    #include <wolfssl/wolfcrypt/sha.h>
#endif
#ifndef NO_SHA256
    #include <wolfssl/wolfcrypt/sha256.h>
#endif
#ifdef WOLFSSL_SHA512
    #include <wolfssl/wolfcrypt/sha512.h>
#endif
#ifdef WOLFSSL_SHA384
    #include <wolfssl/wolfcrypt/sha512.h>
#endif
#ifdef WOLFSSL_SHA3
    #include <wolfssl/wolfcrypt/sha3.h>
#endif
#ifdef WOLFSSL_SM3
    #include <wolfssl/wolfcrypt/sm3.h>
#endif
#ifndef NO_AES
    #include <wolfssl/wolfcrypt/aes.h>
    #ifdef HAVE_AES_DECRYPT
        #include <wolfssl/wolfcrypt/wc_encrypt.h>
    #endif
#endif
#ifdef WOLFSSL_SM4
    #include <wolfssl/wolfcrypt/sm4.h>
#endif
#ifdef WOLFSSL_RIPEMD
    #include <wolfssl/wolfcrypt/ripemd.h>
#endif
#ifndef NO_DES3
    #include <wolfssl/wolfcrypt/des3.h>
    #include <wolfssl/wolfcrypt/wc_encrypt.h>
#endif
#ifdef WC_RC2
    #include <wolfssl/wolfcrypt/rc2.h>
#endif

#ifndef NO_HMAC
    #include <wolfssl/wolfcrypt/hmac.h>
#endif

#ifdef HAVE_CHACHA
    #include <wolfssl/wolfcrypt/chacha.h>
#endif

#ifdef HAVE_POLY1305
    #include <wolfssl/wolfcrypt/poly1305.h>
#endif

#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
    #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
#endif

#ifdef HAVE_CAMELLIA
    #include <wolfssl/wolfcrypt/camellia.h>
#endif

#ifndef NO_RC4
    #include <wolfssl/wolfcrypt/arc4.h>
#endif

#ifdef HAVE_BLAKE2
    #include <wolfssl/wolfcrypt/blake2.h>
#endif

#ifndef NO_RSA
    #include <wolfssl/wolfcrypt/rsa.h>
#endif

#ifndef NO_SIG_WRAPPER
    #include <wolfssl/wolfcrypt/signature.h>
#endif

#ifdef HAVE_AESCCM
    #include <wolfssl/wolfcrypt/aes.h>
#endif

#ifdef HAVE_PKCS7
    #include <wolfssl/wolfcrypt/pkcs7.h>
    #include <wolfssl/wolfcrypt/asn.h>
    #ifdef HAVE_LIBZ
        #include <wolfssl/wolfcrypt/compress.h>
    #endif
#endif

#ifdef WOLFSSL_SMALL_CERT_VERIFY
    #include <wolfssl/wolfcrypt/asn.h>
#endif

#ifndef NO_DSA
    #include <wolfssl/wolfcrypt/dsa.h>
#endif

#ifdef WOLFSSL_CMAC
    #include <wolfssl/wolfcrypt/cmac.h>
#endif

#ifdef HAVE_ED25519
    #include <wolfssl/wolfcrypt/ed25519.h>
#endif
#ifdef HAVE_CURVE25519
    #include <wolfssl/wolfcrypt/curve25519.h>
#endif
#ifdef HAVE_ED448
    #include <wolfssl/wolfcrypt/ed448.h>
#endif
#ifdef HAVE_CURVE448
    #include <wolfssl/wolfcrypt/curve448.h>
#endif

#ifdef WOLFSSL_HAVE_KYBER
    #include <wolfssl/wolfcrypt/kyber.h>
#ifdef WOLFSSL_WC_KYBER
    #include <wolfssl/wolfcrypt/wc_kyber.h>
#endif
#endif
#ifdef HAVE_DILITHIUM
    #include <wolfssl/wolfcrypt/dilithium.h>
#endif

#ifdef HAVE_PKCS12
    #include <wolfssl/wolfcrypt/pkcs12.h>
#endif

#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
    defined(OPENSSL_ALL)
    #include <wolfssl/openssl/ssl.h>
    #ifndef NO_ASN
        /* for ASN_COMMON_NAME DN_tags enum */
        #include <wolfssl/wolfcrypt/asn.h>
    #endif
    #ifdef HAVE_OCSP
        #include <wolfssl/openssl/ocsp.h>
    #endif
#endif
#ifdef OPENSSL_EXTRA
    #include <wolfssl/openssl/cmac.h>
    #include <wolfssl/openssl/x509v3.h>
    #include <wolfssl/openssl/asn1.h>
    #include <wolfssl/openssl/crypto.h>
    #include <wolfssl/openssl/pkcs12.h>
    #include <wolfssl/openssl/evp.h>
    #include <wolfssl/openssl/dh.h>
    #include <wolfssl/openssl/bn.h>
    #include <wolfssl/openssl/buffer.h>
    #include <wolfssl/openssl/pem.h>
    #include <wolfssl/openssl/ec.h>
    #include <wolfssl/openssl/ecdh.h>
    #include <wolfssl/openssl/engine.h>
    #include <wolfssl/openssl/hmac.h>
    #include <wolfssl/openssl/objects.h>
    #include <wolfssl/openssl/rand.h>
    #include <wolfssl/openssl/modes.h>
    #include <wolfssl/openssl/fips_rand.h>
    #include <wolfssl/openssl/kdf.h>
    #include <wolfssl/openssl/x509_vfy.h>
#ifdef OPENSSL_ALL
    #include <wolfssl/openssl/txt_db.h>
    #include <wolfssl/openssl/lhash.h>
#endif
#ifndef NO_AES
    #include <wolfssl/openssl/aes.h>
#endif
#ifndef NO_DES3
    #include <wolfssl/openssl/des.h>
#endif
#ifndef NO_RC4
    #include <wolfssl/openssl/rc4.h>
#endif
#ifdef HAVE_ECC
    #include <wolfssl/openssl/ecdsa.h>
#endif
#ifdef HAVE_PKCS7
    #include <wolfssl/openssl/pkcs7.h>
#endif
#ifdef HAVE_CURVE25519
    #include <wolfssl/openssl/ec25519.h>
#endif
#ifdef HAVE_ED25519
    #include <wolfssl/openssl/ed25519.h>
#endif
#ifdef HAVE_CURVE448
    #include <wolfssl/openssl/ec448.h>
#endif
#ifdef HAVE_ED448
    #include <wolfssl/openssl/ed448.h>
#endif
#endif /* OPENSSL_EXTRA */

#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) && \
    !defined(NO_SHA256) && !defined(RC_NO_RNG)
        #include <wolfssl/wolfcrypt/srp.h>
#endif

#if (defined(SESSION_CERTS) && defined(TEST_PEER_CERT_CHAIN)) || \
    defined(HAVE_SESSION_TICKET) || (defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)) || \
    defined(WOLFSSL_TEST_STATIC_BUILD) || defined(WOLFSSL_DTLS) || \
    defined(HAVE_ECH) || defined(HAVE_EX_DATA) || !defined(NO_SESSION_CACHE) \
    || !defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13)
    /* for testing SSL_get_peer_cert_chain, or SESSION_TICKET_HINT_DEFAULT,
     * for setting authKeyIdSrc in WOLFSSL_X509, or testing DTLS sequence
     * number tracking */
    #include "wolfssl/internal.h"
#endif

/* force enable test buffers */
#ifndef USE_CERT_BUFFERS_2048
    #define USE_CERT_BUFFERS_2048
#endif
#ifndef USE_CERT_BUFFERS_256
    #define USE_CERT_BUFFERS_256
#endif
#include <wolfssl/certs_test.h>

/* include misc.c here regardless of NO_INLINE, because misc.c implementations
 * have default (hidden) visibility, and in the absence of visibility, it's
 * benign to mask out the library implementation.
 */
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>



#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_RSA)        && !defined(SINGLE_THREADED) && \
    !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT)
    #define HAVE_IO_TESTS_DEPENDENCIES
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \
    !defined(WOLFSSL_TIRTOS)
    #define HAVE_SSL_MEMIO_TESTS_DEPENDENCIES
#endif

#if !defined(NO_RSA) && !defined(NO_SHA) && !defined(NO_FILESYSTEM) && \
    !defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
    !defined(WOLFSSL_NO_CLIENT_AUTH))
    #define HAVE_CERT_CHAIN_VALIDATION
#endif

#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
    /* FIPS build has replaced ecc.h. */
    #define wc_ecc_key_get_priv(key) (&((key)->k))
    #define WOLFSSL_HAVE_ECC_KEY_GET_PRIV
#endif

#if defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFCRYPT_ONLY)
    #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) || defined(SESSION_CERTS)
        #ifdef OPENSSL_EXTRA
            #define TEST_TLS_STATIC_MEMSZ (400000)
        #else
            #define TEST_TLS_STATIC_MEMSZ (320000)
        #endif
    #else
            #define TEST_TLS_STATIC_MEMSZ (80000)
    #endif
#endif

#ifdef HAVE_ECC
    #ifndef ECC_ASN963_MAX_BUF_SZ
        #define ECC_ASN963_MAX_BUF_SZ 133
    #endif
    #ifndef ECC_PRIV_KEY_BUF
        #define ECC_PRIV_KEY_BUF 66  /* For non user defined curves. */
    #endif
    /* ecc key sizes: 14, 16, 20, 24, 28, 30, 32, 40, 48, 64 */
    /* logic to choose right key ECC size */
    #if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
        #define KEY14 14
    #else
        #define KEY14 32
    #endif
    #if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
        #define KEY16 16
    #else
        #define KEY16 32
    #endif
    #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
        #define KEY20 20
    #else
        #define KEY20 32
    #endif
    #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
        #define KEY24 24
    #else
        #define KEY24 32
    #endif
    #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
        #define KEY28 28
    #else
        #define KEY28 32
    #endif
    #if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)
        #define KEY30 30
    #else
        #define KEY30 32
    #endif
    #define KEY32 32
    #if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)
        #define KEY40 40
    #else
        #define KEY40 32
    #endif
    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
        #define KEY48 48
    #else
        #define KEY48 32
    #endif
    #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
        #define KEY64 64
    #else
        #define KEY64 32
    #endif

    #if !defined(HAVE_COMP_KEY)
        #if !defined(NOCOMP)
            #define NOCOMP 0
        #endif
    #else
        #if !defined(COMP)
            #define COMP 1
        #endif
    #endif
    #if !defined(DER_SZ)
        #define DER_SZ(ks) ((ks) * 2 + 1)
    #endif
#endif /* HAVE_ECC */

#ifndef NO_DSA
    #ifndef DSA_SIG_SIZE
        #define DSA_SIG_SIZE 40
    #endif
    #ifndef MAX_DSA_PARAM_SIZE
        #define MAX_DSA_PARAM_SIZE 256
    #endif
#endif

#ifndef NO_RSA
    #define GEN_BUF  294
#endif

#ifndef ONEK_BUF
    #define ONEK_BUF 1024
#endif
#ifndef TWOK_BUF
    #define TWOK_BUF 2048
#endif
#ifndef FOURK_BUF
    #define FOURK_BUF 4096
#endif

#ifndef HEAP_HINT
    #define HEAP_HINT NULL
#endif




typedef struct testVector {
    const char* input;
    const char* output;
    size_t inLen;
    size_t outLen;

} testVector;

#if defined(HAVE_PKCS7)
    typedef struct {
        const byte* content;
        word32      contentSz;
        int         contentOID;
        int         encryptOID;
        int         keyWrapOID;
        int         keyAgreeOID;
        byte*       cert;
        size_t      certSz;
        byte*       privateKey;
        word32      privateKeySz;
    } pkcs7EnvelopedVector;

    #ifndef NO_PKCS7_ENCRYPTED_DATA
        typedef struct {
            const byte*     content;
            word32          contentSz;
            int             contentOID;
            int             encryptOID;
            byte*           encryptionKey;
            word32          encryptionKeySz;
        } pkcs7EncryptedVector;
    #endif
#endif /* HAVE_PKCS7 */

typedef int (*ctx_cb)(WOLFSSL_CTX* ctx);
typedef int (*ssl_cb)(WOLFSSL* ssl);
typedef int (*test_cbType)(WOLFSSL_CTX *ctx, WOLFSSL *ssl);
typedef int (*hs_cb)(WOLFSSL_CTX **ctx, WOLFSSL **ssl);

typedef struct test_ssl_cbf {
    method_provider method;
    ctx_cb ctx_ready;
    ssl_cb ssl_ready;
    ssl_cb on_result;
    ctx_cb on_ctx_cleanup;
    ssl_cb on_cleanup;
    hs_cb  on_handshake;
    WOLFSSL_CTX* ctx;
    const char* caPemFile;
    const char* certPemFile;
    const char* keyPemFile;
    const char* crlPemFile;
#ifdef WOLFSSL_STATIC_MEMORY
    byte*               mem;
    word32              memSz;
    wolfSSL_method_func method_ex;
#endif
    int devId;
    int return_code;
    int last_err;
    unsigned char isSharedCtx:1;
    unsigned char loadToSSL:1;
    unsigned char ticNoInit:1;
    unsigned char doUdp:1;
} test_ssl_cbf;

#define TEST_SSL_MEMIO_BUF_SZ   (64 * 1024)
typedef struct test_ssl_memio_ctx {
    WOLFSSL_CTX* s_ctx;
    WOLFSSL_CTX* c_ctx;
    WOLFSSL* s_ssl;
    WOLFSSL* c_ssl;

    const char* c_ciphers;
    const char* s_ciphers;

    char* c_msg;
    int c_msglen;
    char* s_msg;
    int s_msglen;

    test_ssl_cbf s_cb;
    test_ssl_cbf c_cb;

    byte c_buff[TEST_SSL_MEMIO_BUF_SZ];
    int c_len;
    byte s_buff[TEST_SSL_MEMIO_BUF_SZ];
    int s_len;
} test_ssl_memio_ctx;

int test_wolfSSL_client_server_nofail_memio(test_ssl_cbf* client_cb,
    test_ssl_cbf* server_cb, test_cbType client_on_handshake);

#ifdef WOLFSSL_DUMP_MEMIO_STREAM
const char* currentTestName;
char tmpDirName[16];
int tmpDirNameSet = 0;
#endif

/*----------------------------------------------------------------------------*
 | Constants
 *----------------------------------------------------------------------------*/

/* Returns the result based on whether check is true.
 *
 * @param [in] check  Condition for success.
 * @return  When condition is true: TEST_SUCCESS.
 * @return  When condition is false: TEST_FAIL.
 */
#ifdef DEBUG_WOLFSSL_VERBOSE
#define XSTRINGIFY(s) STRINGIFY(s)
#define STRINGIFY(s)  #s
#define TEST_RES_CHECK(check) ({ \
    int _ret = (check) ? TEST_SUCCESS : TEST_FAIL; \
    if (_ret == TEST_FAIL) { \
        fprintf(stderr, " check \"%s\" at %d ", \
            XSTRINGIFY(check), __LINE__); \
    } \
    _ret; })
#else
#define TEST_RES_CHECK(check) \
    ((check) ? TEST_SUCCESS : TEST_FAIL)
#endif /* DEBUG_WOLFSSL_VERBOSE */

#define TEST_STRING    "Everyone gets Friday off."
#define TEST_STRING_SZ 25

#ifndef NO_RSA
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4)) && \
    (defined(RSA_MIN_SIZE) && (RSA_MIN_SIZE <= 1024))
#define TEST_RSA_BITS 1024
#else
#define TEST_RSA_BITS 2048
#endif
#define TEST_RSA_BYTES (TEST_RSA_BITS/8)
#endif /* !NO_RSA */

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    (!defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT))
    static const char* bogusFile  =
    #ifdef _WIN32
        "NUL"
    #else
        "/dev/null"
    #endif
    ;
#endif /* !NO_FILESYSTEM && !NO_CERTS && (!NO_WOLFSSL_SERVER || !NO_WOLFSSL_CLIENT) */

enum {
    TESTING_RSA = 1,
    TESTING_ECC = 2
};

#ifdef WOLFSSL_QNX_CAAM
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
static int testDevId = WOLFSSL_CAAM_DEVID;
#else
static int testDevId = INVALID_DEVID;
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT)

/* This set of memio functions allows for more fine tuned control of the TLS
 * connection operations. For new tests, try to use ssl_memio first. */

/* To dump the memory in gdb use
 *   dump memory client.bin test_ctx.c_buff test_ctx.c_buff+test_ctx.c_len
 *   dump memory server.bin test_ctx.s_buff test_ctx.s_buff+test_ctx.s_len
 * This can be imported into Wireshark by transforming the file with
 *   od -Ax -tx1 -v client.bin > client.bin.hex
 *   od -Ax -tx1 -v server.bin > server.bin.hex
 * And then loading test_output.dump.hex into Wireshark using the
 * "Import from Hex Dump..." option ion and selecting the TCP
 * encapsulation option.
 */

#define HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES

static WC_INLINE int test_memio_write_cb(WOLFSSL *ssl, char *data, int sz,
    void *ctx)
{
    struct test_memio_ctx *test_ctx;
    byte *buf;
    int *len;

    test_ctx = (struct test_memio_ctx*)ctx;

    if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
        buf = test_ctx->c_buff;
        len = &test_ctx->c_len;
    }
    else {
        buf = test_ctx->s_buff;
        len = &test_ctx->s_len;
    }

    if ((unsigned)(*len + sz) > TEST_MEMIO_BUF_SZ)
        return WOLFSSL_CBIO_ERR_WANT_WRITE;

#ifdef WOLFSSL_DUMP_MEMIO_STREAM
    {
        char dump_file_name[64];
        WOLFSSL_BIO *dump_file;
        sprintf(dump_file_name, "%s/%s.dump", tmpDirName, currentTestName);
        dump_file = wolfSSL_BIO_new_file(dump_file_name, "a");
        if (dump_file != NULL) {
            (void)wolfSSL_BIO_write(dump_file, data, sz);
            wolfSSL_BIO_free(dump_file);
        }
    }
#endif
    XMEMCPY(buf + *len, data, (size_t)sz);
    *len += sz;

    return sz;
}

static WC_INLINE int test_memio_read_cb(WOLFSSL *ssl, char *data, int sz,
    void *ctx)
{
    struct test_memio_ctx *test_ctx;
    int read_sz;
    byte *buf;
    int *len;

    test_ctx = (struct test_memio_ctx*)ctx;

    if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
        buf = test_ctx->s_buff;
        len = &test_ctx->s_len;
    }
    else {
        buf = test_ctx->c_buff;
        len = &test_ctx->c_len;
    }

    if (*len == 0)
        return WOLFSSL_CBIO_ERR_WANT_READ;

    read_sz = sz < *len ? sz : *len;

    XMEMCPY(data, buf, (size_t)read_sz);
    XMEMMOVE(buf, buf + read_sz,(size_t) (*len - read_sz));

    *len -= read_sz;

    return read_sz;
}

int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s,
    int max_rounds, int *rounds)
{
    byte handshake_complete = 0, hs_c = 0, hs_s = 0;
    int ret, err;

    if (rounds != NULL)
        *rounds = 0;
    while (!handshake_complete && max_rounds > 0) {
        if (!hs_c) {
            wolfSSL_SetLoggingPrefix("client");
            ret = wolfSSL_connect(ssl_c);
            wolfSSL_SetLoggingPrefix(NULL);
            if (ret == WOLFSSL_SUCCESS) {
                hs_c = 1;
            }
            else {
                err = wolfSSL_get_error(ssl_c, ret);
                if (err != WOLFSSL_ERROR_WANT_READ &&
                    err != WOLFSSL_ERROR_WANT_WRITE)
                    return -1;
            }
        }
        if (!hs_s) {
            wolfSSL_SetLoggingPrefix("server");
            ret = wolfSSL_accept(ssl_s);
            wolfSSL_SetLoggingPrefix(NULL);
            if (ret == WOLFSSL_SUCCESS) {
                hs_s = 1;
            }
            else {
                err = wolfSSL_get_error(ssl_s, ret);
                if (err != WOLFSSL_ERROR_WANT_READ &&
                    err != WOLFSSL_ERROR_WANT_WRITE)
                    return -1;
            }
        }
        handshake_complete = hs_c && hs_s;
        max_rounds--;
        if (rounds != NULL)
            *rounds = *rounds + 1;
    }

    if (!handshake_complete)
        return -1;

    return 0;
}

int test_memio_setup_ex(struct test_memio_ctx *ctx,
    WOLFSSL_CTX **ctx_c, WOLFSSL_CTX **ctx_s, WOLFSSL **ssl_c, WOLFSSL **ssl_s,
    method_provider method_c, method_provider method_s,
    byte *caCert, int caCertSz, byte *serverCert, int serverCertSz,
    byte *serverKey, int serverKeySz)
{
    int ret;
    (void)caCert;
    (void)caCertSz;
    (void)serverCert;
    (void)serverCertSz;
    (void)serverKey;
    (void)serverKeySz;

    if (ctx_c != NULL && *ctx_c == NULL) {
        *ctx_c = wolfSSL_CTX_new(method_c());
        if (*ctx_c == NULL)
            return -1;
#ifndef NO_CERTS
        if (caCert == NULL) {
            ret = wolfSSL_CTX_load_verify_locations(*ctx_c, caCertFile, 0);
        }
        else {
            ret = wolfSSL_CTX_load_verify_buffer(*ctx_c, caCert, (long)caCertSz,
                                                 WOLFSSL_FILETYPE_ASN1);
        }
        if (ret != WOLFSSL_SUCCESS)
            return -1;
#endif /* NO_CERTS */
        wolfSSL_SetIORecv(*ctx_c, test_memio_read_cb);
        wolfSSL_SetIOSend(*ctx_c, test_memio_write_cb);
        if (ctx->c_ciphers != NULL) {
            ret = wolfSSL_CTX_set_cipher_list(*ctx_c, ctx->c_ciphers);
            if (ret != WOLFSSL_SUCCESS)
                return -1;
        }
    }

    if (ctx_s != NULL && *ctx_s == NULL) {
        *ctx_s = wolfSSL_CTX_new(method_s());
        if (*ctx_s == NULL)
            return -1;
#ifndef NO_CERTS
        if (serverKey == NULL) {
            ret = wolfSSL_CTX_use_PrivateKey_file(*ctx_s, svrKeyFile,
                WOLFSSL_FILETYPE_PEM);
        }
        else {
            ret = wolfSSL_CTX_use_PrivateKey_buffer(*ctx_s, serverKey,
                (long)serverKeySz, WOLFSSL_FILETYPE_ASN1);
        }
        if (ret != WOLFSSL_SUCCESS)
            return- -1;

        if (serverCert == NULL) {
            ret = wolfSSL_CTX_use_certificate_file(*ctx_s, svrCertFile,
                                                   WOLFSSL_FILETYPE_PEM);
        }
        else {
            ret = wolfSSL_CTX_use_certificate_chain_buffer_format(*ctx_s,
                serverCert, (long)serverCertSz, WOLFSSL_FILETYPE_ASN1);
        }
        if (ret != WOLFSSL_SUCCESS)
            return -1;
#endif /* NO_CERTS */
        wolfSSL_SetIORecv(*ctx_s, test_memio_read_cb);
        wolfSSL_SetIOSend(*ctx_s, test_memio_write_cb);
        if (ctx->s_ciphers != NULL) {
            ret = wolfSSL_CTX_set_cipher_list(*ctx_s, ctx->s_ciphers);
            if (ret != WOLFSSL_SUCCESS)
                return -1;
        }
    }

    if (ctx_c != NULL && ssl_c != NULL) {
        *ssl_c = wolfSSL_new(*ctx_c);
        if (*ssl_c == NULL)
            return -1;
        wolfSSL_SetIOWriteCtx(*ssl_c, ctx);
        wolfSSL_SetIOReadCtx(*ssl_c, ctx);
    }
    if (ctx_s != NULL && ssl_s != NULL) {
        *ssl_s = wolfSSL_new(*ctx_s);
        if (*ssl_s == NULL)
            return -1;
        wolfSSL_SetIOWriteCtx(*ssl_s, ctx);
        wolfSSL_SetIOReadCtx(*ssl_s, ctx);
#if !defined(NO_DH)
        SetDH(*ssl_s);
#endif
    }

    return 0;
}

int test_memio_setup(struct test_memio_ctx *ctx,
    WOLFSSL_CTX **ctx_c, WOLFSSL_CTX **ctx_s, WOLFSSL **ssl_c, WOLFSSL **ssl_s,
    method_provider method_c, method_provider method_s)
{
    return test_memio_setup_ex(ctx, ctx_c, ctx_s, ssl_c, ssl_s, method_c,
                               method_s, NULL, 0, NULL, 0, NULL, 0);
}
#endif

/*----------------------------------------------------------------------------*
 | BIO with fixed read/write size
 *----------------------------------------------------------------------------*/

#if defined(OPENSSL_EXTRA) && !defined(NO_BIO)

static int wolfssl_bio_s_fixed_mem_write(WOLFSSL_BIO* bio, const char* data,
    int len)
{
    if ((bio == NULL) || (bio->ptr.mem_buf_data == NULL) || (data == NULL)) {
        len = 0;
    }
    else {
        if (bio->wrSz - bio->wrIdx < len) {
            len = bio->wrSz - bio->wrIdx;
        }
        XMEMCPY(bio->ptr.mem_buf_data + bio->wrIdx, data, len);
        bio->wrIdx += len;
    }

    return len;
}

static int wolfssl_bio_s_fixed_mem_read(WOLFSSL_BIO* bio, char* data, int len)
{
    if ((bio == NULL) || (bio->ptr.mem_buf_data == NULL) || (data == NULL)) {
        len = 0;
    }
    else {
        if (bio->wrSz - bio->rdIdx < len) {
            len = bio->wrSz - bio->rdIdx;
        }
        XMEMCPY(data, bio->ptr.mem_buf_data + bio->rdIdx, len);
        bio->rdIdx += len;
    }

    return len;
}

static WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_fixed_mem(void)
{
    static WOLFSSL_BIO_METHOD meth;

    meth.type = WOLFSSL_BIO_BIO;
    XMEMCPY(meth.name, "Fixed Memory Size", 18);
    meth.writeCb = wolfssl_bio_s_fixed_mem_write;
    meth.readCb = wolfssl_bio_s_fixed_mem_read;

    return &meth;
}

#endif

/*----------------------------------------------------------------------------*
 | Setup
 *----------------------------------------------------------------------------*/

static int test_wolfSSL_Init(void)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_Init(), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}


static int test_wolfSSL_Cleanup(void)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_Cleanup(), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}


/*  Initialize the wolfCrypt state.
 *  POST: 0 success.
 */
static int test_wolfCrypt_Init(void)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfCrypt_Init(), 0);
    return EXPECT_RESULT();

} /* END test_wolfCrypt_Init */

static int test_wolfCrypt_Cleanup(void)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfCrypt_Cleanup(), 0);
    return EXPECT_RESULT();
}


#ifdef WOLFSSL_STATIC_MEMORY
    #define TEST_LSM_STATIC_SIZE 440000
    /* Create new bucket list, using the default list, adding
     * one dang large buffer size. */
    #define TEST_LSM_DEF_BUCKETS (WOLFMEM_DEF_BUCKETS+1)
    #define TEST_LSM_BUCKETS WOLFMEM_BUCKETS,(LARGEST_MEM_BUCKET*2)
    #define TEST_LSM_DIST WOLFMEM_DIST,1
#endif

static int test_wc_LoadStaticMemory_ex(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_STATIC_MEMORY
    byte staticMemory[TEST_LSM_STATIC_SIZE];
    word32 sizeList[TEST_LSM_DEF_BUCKETS] = { TEST_LSM_BUCKETS };
    word32 distList[TEST_LSM_DEF_BUCKETS] = { TEST_LSM_DIST };
    WOLFSSL_HEAP_HINT* heap;

    /* For this test, the size and dist lists will be the ones configured
     * for the build, or default. The value of WOLFMEM_DEF_BUCKETS is 9,
     * so these lists are 10 long. For most tests, the value of
     * WOLFMEM_DEF_BUCKETS is used. There's a test case where one is added
     * to that, to make sure the list size is larger than
     * WOLFMEM_MAX_BUCKETS. */

    /* Pass in zero everything. */
    ExpectIntEQ(wc_LoadStaticMemory_ex(NULL, 0, NULL, NULL, NULL, 0, 0, 0),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Set the heap pointer to NULL. */
    ExpectIntEQ(wc_LoadStaticMemory_ex(NULL,
                WOLFMEM_DEF_BUCKETS, sizeList, distList,
                staticMemory, (word32)sizeof(staticMemory),
                0, 1),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Set other pointer values to NULL one at a time. */
    heap = NULL;
    ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
                WOLFMEM_DEF_BUCKETS, NULL, distList,
                staticMemory, (word32)sizeof(staticMemory),
                0, 1),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    heap = NULL;
    ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
                WOLFMEM_DEF_BUCKETS, sizeList, NULL,
                staticMemory, (word32)sizeof(staticMemory),
                0, 1),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    heap = NULL;
    ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
                WOLFMEM_DEF_BUCKETS, sizeList, distList,
                NULL, (word32)sizeof(staticMemory),
                0, 1),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Set the size of the static buffer to 0. */
    heap = NULL;
    ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
                WOLFMEM_DEF_BUCKETS, sizeList, distList,
                staticMemory, 0,
                0, 1),
            WC_NO_ERR_TRACE(BUFFER_E));

    /* Set the size of the static buffer to one less than minimum allowed. */
    heap = NULL;
    ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
                WOLFMEM_DEF_BUCKETS, sizeList, distList,
                staticMemory,
                (word32)(sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) - 1,
                0, 1),
            WC_NO_ERR_TRACE(BUFFER_E));

    /* Set the size of the static buffer to exactly the minimum size. */
    heap = NULL;
    ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
                WOLFMEM_DEF_BUCKETS, sizeList, distList,
                staticMemory,
                (word32)(sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)),
                0, 1),
            0);
    wc_UnloadStaticMemory(heap);

    /* Use more buckets than able. Success case. */
    heap = NULL;
    ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
                WOLFMEM_DEF_BUCKETS*2, sizeList, distList,
                staticMemory, (word32)sizeof(staticMemory),
                0, 1),
            0);
    wc_UnloadStaticMemory(heap);

    /* Success case. */
    heap = NULL;
    ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
                WOLFMEM_DEF_BUCKETS, sizeList, distList,
                staticMemory, (word32)sizeof(staticMemory),
                0, 1),
            0);
    wc_UnloadStaticMemory(heap);
#endif /* WOLFSSL_STATIC_MEMORY */
    return EXPECT_RESULT();
}


/*----------------------------------------------------------------------------*
 | Platform dependent function test
 *----------------------------------------------------------------------------*/
static int test_fileAccess(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_TEST_PLATFORMDEPEND) && !defined(NO_FILESYSTEM)
    const char *fname[] = {
        svrCertFile, svrKeyFile, caCertFile,
        eccCertFile, eccKeyFile, eccRsaCertFile,
        cliCertFile, cliCertDerFile, cliKeyFile,
        dhParamFile,
        cliEccKeyFile, cliEccCertFile, caEccCertFile, edCertFile, edKeyFile,
        cliEdCertFile, cliEdKeyFile, caEdCertFile,
        NULL
    };
    const char derfile[] = "./certs/server-cert.der";
    XFILE f = XBADFILE;
    size_t sz;
    byte *buff = NULL;
    int i;

    ExpectTrue(XFOPEN("badfilename", "rb") == XBADFILE);
    for (i=0; EXPECT_SUCCESS() && fname[i] != NULL ; i++) {
        ExpectTrue((f = XFOPEN(fname[i], "rb")) != XBADFILE);
        XFCLOSE(f);
    }

    ExpectTrue((f = XFOPEN(derfile, "rb")) != XBADFILE);
    ExpectTrue(XFSEEK(f, 0, XSEEK_END) == 0);
    ExpectIntGE(sz = (size_t) XFTELL(f), sizeof_server_cert_der_2048);
    ExpectTrue(XFSEEK(f, 0, XSEEK_SET) == 0);
    ExpectTrue((buff = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE)) != NULL);
    ExpectTrue(XFREAD(buff, 1, sz, f) == sz);
    ExpectIntEQ(XMEMCMP(server_cert_der_2048, buff, sz), 0);
    XFREE(buff, NULL, DYNAMIC_TYPE_FILE);
    XFCLOSE(f);
#endif
    return EXPECT_RESULT();
}

/*----------------------------------------------------------------------------*
 | Method Allocators
 *----------------------------------------------------------------------------*/

static int test_wolfSSL_Method_Allocators(void)
{
    EXPECT_DECLS;

    #define TEST_METHOD_ALLOCATOR(allocator, condition) \
        do {                                            \
            WOLFSSL_METHOD *method = NULL;              \
            condition(method = allocator());            \
            XFREE(method, 0, DYNAMIC_TYPE_METHOD);      \
        } while (0)

    #define TEST_VALID_METHOD_ALLOCATOR(a) \
            TEST_METHOD_ALLOCATOR(a, ExpectNotNull)

    #define TEST_INVALID_METHOD_ALLOCATOR(a) \
            TEST_METHOD_ALLOCATOR(a, ExpectNull)

#ifndef NO_OLD_TLS
    #ifdef WOLFSSL_ALLOW_SSLV3
        #ifndef NO_WOLFSSL_SERVER
        TEST_VALID_METHOD_ALLOCATOR(wolfSSLv3_server_method);
        #endif
        #ifndef NO_WOLFSSL_CLIENT
        TEST_VALID_METHOD_ALLOCATOR(wolfSSLv3_client_method);
        #endif
    #endif
    #ifdef WOLFSSL_ALLOW_TLSV10
        #ifndef NO_WOLFSSL_SERVER
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_server_method);
        #endif
        #ifndef NO_WOLFSSL_CLIENT
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_client_method);
        #endif
    #endif
    #ifndef NO_WOLFSSL_SERVER
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_1_server_method);
    #endif
    #ifndef NO_WOLFSSL_CLIENT
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_1_client_method);
    #endif
#endif /* !NO_OLD_TLS */

#ifndef WOLFSSL_NO_TLS12
    #ifndef NO_WOLFSSL_SERVER
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_2_server_method);
    #endif
    #ifndef NO_WOLFSSL_CLIENT
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_2_client_method);
    #endif
#endif /* !WOLFSSL_NO_TLS12 */

#ifdef WOLFSSL_TLS13
    #ifndef NO_WOLFSSL_SERVER
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_3_server_method);
    #endif
    #ifndef NO_WOLFSSL_CLIENT
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_3_client_method);
    #endif
#endif /* WOLFSSL_TLS13 */

#ifndef NO_WOLFSSL_SERVER
    TEST_VALID_METHOD_ALLOCATOR(wolfSSLv23_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
    TEST_VALID_METHOD_ALLOCATOR(wolfSSLv23_client_method);
#endif

#ifdef WOLFSSL_DTLS
    #ifndef NO_OLD_TLS
        #ifndef NO_WOLFSSL_SERVER
        TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_server_method);
        #endif
        #ifndef NO_WOLFSSL_CLIENT
        TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_client_method);
        #endif
    #endif
    #ifndef WOLFSSL_NO_TLS12
        #ifndef NO_WOLFSSL_SERVER
        TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_2_server_method);
        #endif
        #ifndef NO_WOLFSSL_CLIENT
        TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_2_client_method);
        #endif
    #endif
#endif /* WOLFSSL_DTLS */

#if !defined(NO_OLD_TLS) && defined(OPENSSL_EXTRA)
    /* Stubs */
    #ifndef NO_WOLFSSL_SERVER
        TEST_INVALID_METHOD_ALLOCATOR(wolfSSLv2_server_method);
    #endif
    #ifndef NO_WOLFSSL_CLIENT
        TEST_INVALID_METHOD_ALLOCATOR(wolfSSLv2_client_method);
    #endif
#endif

    /* Test Either Method (client or server) */
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    TEST_VALID_METHOD_ALLOCATOR(wolfSSLv23_method);
    #ifndef NO_OLD_TLS
        #ifdef WOLFSSL_ALLOW_TLSV10
            TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_method);
        #endif
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_1_method);
    #endif /* !NO_OLD_TLS */
    #ifndef WOLFSSL_NO_TLS12
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_2_method);
    #endif /* !WOLFSSL_NO_TLS12 */
    #ifdef WOLFSSL_TLS13
        TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_3_method);
    #endif /* WOLFSSL_TLS13 */
    #ifdef WOLFSSL_DTLS
        TEST_VALID_METHOD_ALLOCATOR(wolfDTLS_method);
        #ifndef NO_OLD_TLS
            TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_method);
        #endif /* !NO_OLD_TLS */
        #ifndef WOLFSSL_NO_TLS12
            TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_2_method);
        #endif /* !WOLFSSL_NO_TLS12 */
        #ifdef WOLFSSL_DTLS13
            TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_3_method);
        #endif /* WOLFSSL_DTLS13 */
    #endif /* WOLFSSL_DTLS */
#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */

    return EXPECT_RESULT();
}

#if defined(WOLFSSL_DUAL_ALG_CERTS) && !defined(NO_FILESYSTEM)
/*----------------------------------------------------------------------------*
 | Dual algorithm Certificate Tests
 *----------------------------------------------------------------------------*/
#define LARGE_TEMP_SZ 4096

/* To better understand this, please see the X9.146 example in wolfssl-examples
 * repo. */
static int do_dual_alg_root_certgen(byte **out, char *caKeyFile,
                                    char *sapkiFile, char *altPrivFile)
{
    EXPECT_DECLS;
    FILE* file = NULL;
    Cert newCert;
    DecodedCert preTBS;

    byte caKeyBuf[LARGE_TEMP_SZ];
    word32 caKeySz = LARGE_TEMP_SZ;
    byte sapkiBuf[LARGE_TEMP_SZ];
    word32 sapkiSz = LARGE_TEMP_SZ;
    byte altPrivBuf[LARGE_TEMP_SZ];
    word32 altPrivSz = LARGE_TEMP_SZ;
    byte altSigAlgBuf[LARGE_TEMP_SZ];
    word32 altSigAlgSz = LARGE_TEMP_SZ;
    byte scratchBuf[LARGE_TEMP_SZ];
    word32 scratchSz = LARGE_TEMP_SZ;
    byte preTbsBuf[LARGE_TEMP_SZ];
    word32 preTbsSz = LARGE_TEMP_SZ;
    byte altSigValBuf[LARGE_TEMP_SZ];
    word32 altSigValSz = LARGE_TEMP_SZ;
    byte *outBuf = NULL;
    word32 outSz = LARGE_TEMP_SZ;
    WC_RNG rng;
    RsaKey caKey;
    ecc_key altCaKey;
    word32 idx = 0;

    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(&caKey, 0, sizeof(RsaKey));
    XMEMSET(&altCaKey, 0, sizeof(ecc_key));

    ExpectNotNull(outBuf = (byte*)XMALLOC(outSz, NULL,
                  DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(wc_InitRng(&rng), 0);
    XMEMSET(caKeyBuf, 0, caKeySz);
    ExpectNotNull(file = fopen(caKeyFile, "rb"));
    ExpectIntGT(caKeySz = (word32)fread(caKeyBuf, 1, caKeySz, file), 0);
    if (file) {
        fclose(file);
        file = NULL;
    }
    ExpectIntEQ(wc_InitRsaKey_ex(&caKey, NULL, INVALID_DEVID), 0);
    idx = 0;
    ExpectIntEQ(wc_RsaPrivateKeyDecode(caKeyBuf, &idx, &caKey, caKeySz),
                0);
    XMEMSET(sapkiBuf, 0, sapkiSz);
    ExpectNotNull(file = fopen(sapkiFile, "rb"));
    ExpectIntGT(sapkiSz = (word32)fread(sapkiBuf, 1, sapkiSz, file), 0);
    if (file) {
        fclose(file);
        file = NULL;
    }
    XMEMSET(altPrivBuf, 0, altPrivSz);
    ExpectNotNull(file = fopen(altPrivFile, "rb"));
    ExpectIntGT(altPrivSz = (word32)fread(altPrivBuf, 1, altPrivSz, file), 0);
    if (file) {
        fclose(file);
        file = NULL;
    }
    wc_ecc_init(&altCaKey);
    idx = 0;
    ExpectIntEQ(wc_EccPrivateKeyDecode(altPrivBuf, &idx, &altCaKey,
                                       (word32)altPrivSz), 0);
    XMEMSET(altSigAlgBuf, 0, altSigAlgSz);
    ExpectIntGT(altSigAlgSz = SetAlgoID(CTC_SHA256wECDSA, altSigAlgBuf,
                                         oidSigType, 0), 0);
    wc_InitCert(&newCert);
    strncpy(newCert.subject.country, "US", CTC_NAME_SIZE);
    strncpy(newCert.subject.state, "MT", CTC_NAME_SIZE);
    strncpy(newCert.subject.locality, "Bozeman", CTC_NAME_SIZE);
    strncpy(newCert.subject.org, "wolfSSL", CTC_NAME_SIZE);
    strncpy(newCert.subject.unit, "Engineering", CTC_NAME_SIZE);
    strncpy(newCert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
    strncpy(newCert.subject.email, "root@wolfssl.com", CTC_NAME_SIZE);
    newCert.sigType = CTC_SHA256wRSA;
    newCert.isCA    = 1;

    ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "1.2.3.4.5",
                (const byte *)"This is NOT a critical extension", 32), 0);
    ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.72", sapkiBuf,
                sapkiSz), 0);
    ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.73", altSigAlgBuf,
                                altSigAlgSz), 0);

    XMEMSET(scratchBuf, 0, scratchSz);
    ExpectIntGT(scratchSz = wc_MakeSelfCert(&newCert, scratchBuf, scratchSz,
                &caKey, &rng), 0);
    wc_InitDecodedCert(&preTBS, scratchBuf, scratchSz, 0);
    ExpectIntEQ(wc_ParseCert(&preTBS, CERT_TYPE, NO_VERIFY, NULL), 0);

    XMEMSET(preTbsBuf, 0, preTbsSz);
    ExpectIntGT(preTbsSz = wc_GeneratePreTBS(&preTBS, preTbsBuf, preTbsSz), 0);
    XMEMSET(altSigValBuf, 0, altSigValSz);
    ExpectIntGT(altSigValSz = wc_MakeSigWithBitStr(altSigValBuf, altSigValSz,
                CTC_SHA256wECDSA, preTbsBuf, preTbsSz, ECC_TYPE, &altCaKey,
                &rng), 0);
    ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.74", altSigValBuf,
                altSigValSz), 0);

    /* Finally, generate the new certificate. */
    if (outBuf != NULL) {
        XMEMSET(outBuf, 0, outSz);
    }
    ExpectIntGT(outSz = wc_MakeSelfCert(&newCert, outBuf, outSz, &caKey, &rng),
                0);
    *out = outBuf;
    wc_FreeRsaKey(&caKey);
    wc_FreeRng(&rng);
    wc_FreeDecodedCert(&preTBS);
    return outSz;
}

static int do_dual_alg_server_certgen(byte **out, char *caKeyFile,
                                      char *sapkiFile, char *altPrivFile,
                                      char *serverKeyFile,
                                      byte *caCertBuf, int caCertSz)
{
    EXPECT_DECLS;
    FILE* file = NULL;
    Cert newCert;
    DecodedCert preTBS;

    byte serverKeyBuf[LARGE_TEMP_SZ];
    word32 serverKeySz = LARGE_TEMP_SZ;
    byte caKeyBuf[LARGE_TEMP_SZ];
    word32 caKeySz = LARGE_TEMP_SZ;
    byte sapkiBuf[LARGE_TEMP_SZ];
    word32 sapkiSz = LARGE_TEMP_SZ;
    byte altPrivBuf[LARGE_TEMP_SZ];
    word32 altPrivSz = LARGE_TEMP_SZ;
    byte altSigAlgBuf[LARGE_TEMP_SZ];
    word32 altSigAlgSz = LARGE_TEMP_SZ;
    byte scratchBuf[LARGE_TEMP_SZ];
    word32 scratchSz = LARGE_TEMP_SZ;
    byte preTbsBuf[LARGE_TEMP_SZ];
    word32 preTbsSz = LARGE_TEMP_SZ;
    byte altSigValBuf[LARGE_TEMP_SZ];
    word32 altSigValSz = LARGE_TEMP_SZ;
    byte *outBuf = NULL;
    word32 outSz = LARGE_TEMP_SZ;
    WC_RNG rng;
    RsaKey caKey;
    RsaKey serverKey;
    ecc_key altCaKey;
    word32 idx = 0;

    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(&caKey, 0, sizeof(RsaKey));
    XMEMSET(&serverKey, 0, sizeof(RsaKey));
    XMEMSET(&altCaKey, 0, sizeof(ecc_key));

    ExpectNotNull(outBuf = (byte*)XMALLOC(outSz, NULL,
                  DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(wc_InitRng(&rng), 0);
    XMEMSET(serverKeyBuf, 0, serverKeySz);
    ExpectNotNull(file = fopen(serverKeyFile, "rb"));
    ExpectIntGT(serverKeySz = (word32)fread(serverKeyBuf, 1, serverKeySz, file),
                0);
    if (file) {
        fclose(file);
        file = NULL;
    }
    ExpectIntEQ(wc_InitRsaKey_ex(&serverKey, NULL, INVALID_DEVID), 0);
    idx = 0;
    ExpectIntEQ(wc_RsaPrivateKeyDecode(serverKeyBuf, &idx, &serverKey,
                (word32)serverKeySz), 0);
    XMEMSET(caKeyBuf, 0, caKeySz);
    ExpectNotNull(file = fopen(caKeyFile, "rb"));
    ExpectIntGT(caKeySz = (word32)fread(caKeyBuf, 1, caKeySz, file), 0);
    if (file) {
        fclose(file);
        file = NULL;
    }
    ExpectIntEQ(wc_InitRsaKey_ex(&caKey, NULL, INVALID_DEVID), 0);
    idx = 0;
    ExpectIntEQ(wc_RsaPrivateKeyDecode(caKeyBuf, &idx, &caKey,
                (word32)caKeySz), 0);
    XMEMSET(sapkiBuf, 0, sapkiSz);
    ExpectNotNull(file = fopen(sapkiFile, "rb"));
    ExpectIntGT(sapkiSz = (word32)fread(sapkiBuf, 1, sapkiSz, file), 0);
    if (file) {
        fclose(file);
        file = NULL;
    }
    XMEMSET(altPrivBuf, 0, altPrivSz);
    ExpectNotNull(file = fopen(altPrivFile, "rb"));
    ExpectIntGT(altPrivSz = (word32)fread(altPrivBuf, 1, altPrivSz, file), 0);
    if (file) {
        fclose(file);
        file = NULL;
    }
    wc_ecc_init(&altCaKey);
    idx = 0;
    ExpectIntEQ(wc_EccPrivateKeyDecode(altPrivBuf, &idx, &altCaKey,
                (word32)altPrivSz), 0);
    XMEMSET(altSigAlgBuf, 0, altSigAlgSz);
    ExpectIntGT(altSigAlgSz = SetAlgoID(CTC_SHA256wECDSA, altSigAlgBuf,
                oidSigType, 0), 0);
    wc_InitCert(&newCert);
    strncpy(newCert.subject.country, "US", CTC_NAME_SIZE);
    strncpy(newCert.subject.state, "MT", CTC_NAME_SIZE);
    strncpy(newCert.subject.locality, "Bozeman", CTC_NAME_SIZE);
    strncpy(newCert.subject.org, "wolfSSL", CTC_NAME_SIZE);
    strncpy(newCert.subject.unit, "Engineering", CTC_NAME_SIZE);
    strncpy(newCert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
    strncpy(newCert.subject.email, "server@wolfssl.com", CTC_NAME_SIZE);

    newCert.sigType = CTC_SHA256wRSA;
    newCert.isCA    = 0;
    ExpectIntEQ(wc_SetIssuerBuffer(&newCert, caCertBuf, caCertSz), 0);
    ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.72", sapkiBuf,
                sapkiSz), 0);
    ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.73", altSigAlgBuf,
                altSigAlgSz), 0);
    XMEMSET(scratchBuf, 0, scratchSz);
    ExpectIntGT(wc_MakeCert(&newCert, scratchBuf, scratchSz, &serverKey, NULL,
                &rng), 0);
    ExpectIntGT(scratchSz = wc_SignCert(newCert.bodySz, newCert.sigType,
                scratchBuf, scratchSz, &caKey, NULL, &rng), 0);
    wc_InitDecodedCert(&preTBS, scratchBuf, scratchSz, 0);
    ExpectIntEQ(wc_ParseCert(&preTBS, CERT_TYPE, NO_VERIFY, NULL), 0);
    XMEMSET(preTbsBuf, 0, preTbsSz);
    ExpectIntGT(preTbsSz = wc_GeneratePreTBS(&preTBS, preTbsBuf, preTbsSz), 0);
    XMEMSET(altSigValBuf, 0, altSigValSz);
    ExpectIntGT(altSigValSz = wc_MakeSigWithBitStr(altSigValBuf, altSigValSz,
                CTC_SHA256wECDSA, preTbsBuf, preTbsSz, ECC_TYPE, &altCaKey,
                &rng), 0);
    ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.74",
                 altSigValBuf, altSigValSz), 0);
    /* Finally, generate the new certificate. */
    if (outBuf != NULL) {
        XMEMSET(outBuf, 0, outSz);
    }
    ExpectIntGT(wc_MakeCert(&newCert, outBuf, outSz, &serverKey, NULL, &rng),
                0);
    ExpectIntGT(outSz = wc_SignCert(newCert.bodySz, newCert.sigType, outBuf,
                outSz, &caKey, NULL, &rng), 0);
    *out = outBuf;
    wc_FreeRsaKey(&caKey);
    wc_FreeRsaKey(&serverKey);
    wc_FreeRng(&rng);
    wc_FreeDecodedCert(&preTBS);
    return outSz;
}

static int do_dual_alg_tls13_connection(byte *caCert, word32 caCertSz,
                                        byte *serverCert, word32 serverCertSz,
                                        byte *serverKey, word32 serverKeySz,
                                        int negative_test)
{
    EXPECT_DECLS;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup_ex(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
                wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
                caCert, caCertSz, serverCert, serverCertSz,
                serverKey, serverKeySz), 0);
    if (negative_test) {
        ExpectTrue(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL) != 0);
    }
    else {
        ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
    }
    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
    return EXPECT_RESULT();
}

static int test_dual_alg_support(void)
{
    EXPECT_DECLS;
    /* Root CA and server keys will be the same. This is only appropriate for
     * testing. */
    char keyFile[] = "./certs/ca-key.der";
    char sapkiFile[] = "./certs/ecc-keyPub.der";
    char altPrivFile[] = "./certs/ecc-key.der";
    char wrongPrivFile[] = "./certs/ecc-client-key.der";
    byte *serverKey = NULL;
    size_t serverKeySz = 0;
    byte *root = NULL;
    int rootSz = 0;
    byte *server = NULL;
    int serverSz = 0;

    ExpectIntEQ(load_file(keyFile, &serverKey, &serverKeySz), 0);

    /* Base normal case. */
    if (EXPECT_SUCCESS()) {
        rootSz = do_dual_alg_root_certgen(&root, keyFile, sapkiFile,
            altPrivFile);
    }
    ExpectNotNull(root);
    ExpectIntGT(rootSz, 0);
    if (EXPECT_SUCCESS()) {
        serverSz = do_dual_alg_server_certgen(&server, keyFile, sapkiFile,
            altPrivFile, keyFile, root, rootSz);
    }
    ExpectNotNull(server);
    ExpectIntGT(serverSz, 0);
    ExpectIntEQ(do_dual_alg_tls13_connection(root, rootSz,
                server, serverSz, serverKey, (word32)serverKeySz, 0),
                TEST_SUCCESS);
    XFREE(root, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    root = NULL;
    XFREE(server, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    server = NULL;

    /* Now we try a negative case. Note that we use wrongPrivFile to generate
     * the alternative signature and then set negative_test to true for the
     * call to do_dual_alg_tls13_connection(). Its expecting a failed connection
     * because the signature won't verify. The exception is if
     * WOLFSSL_TRUST_PEER_CERT is defined. In that case, no verification happens
     * and this is no longer a negative test. */
    if (EXPECT_SUCCESS()) {
        rootSz = do_dual_alg_root_certgen(&root, keyFile, sapkiFile,
            wrongPrivFile);
    }
    ExpectNotNull(root);
    ExpectIntGT(rootSz, 0);
    if (EXPECT_SUCCESS()) {
        serverSz = do_dual_alg_server_certgen(&server, keyFile, sapkiFile,
            wrongPrivFile, keyFile, root, rootSz);
    }
    ExpectNotNull(server);
    ExpectIntGT(serverSz, 0);
#ifdef WOLFSSL_TRUST_PEER_CERT
    ExpectIntEQ(do_dual_alg_tls13_connection(root, rootSz,
                server, serverSz, serverKey, (word32)serverKeySz, 0),
                TEST_SUCCESS);
#else
    ExpectIntEQ(do_dual_alg_tls13_connection(root, rootSz,
                server, serverSz, serverKey, (word32)serverKeySz, 1),
                TEST_SUCCESS);
#endif

    XFREE(root, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(server, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    free(serverKey);

    return EXPECT_RESULT();
}
#else
static int test_dual_alg_support(void)
{
    return TEST_SKIPPED;
}
#endif /* WOLFSSL_DUAL_ALG_CERTS && !NO_FILESYSTEM */

/*----------------------------------------------------------------------------*
 | Context
 *----------------------------------------------------------------------------*/
#ifndef NO_WOLFSSL_SERVER
static int test_wolfSSL_CTX_new(void)
{
    EXPECT_DECLS;
    WOLFSSL_CTX *ctx;
    WOLFSSL_METHOD* method = NULL;

    ExpectNull(ctx = wolfSSL_CTX_new(NULL));
    ExpectNotNull(method = wolfSSLv23_server_method());
    if (method != NULL)
        ExpectNotNull(ctx = wolfSSL_CTX_new(method));

    wolfSSL_CTX_free(ctx);

    return EXPECT_RESULT();
}
#endif

#if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
    (!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_FILESYSTEM)
static int test_for_double_Free(void)
{
    EXPECT_DECLS;
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;
    int skipTest = 0;
    const char* testCertFile;
    const char* testKeyFile;
    char optionsCiphers[] = "RC4-SHA:RC4-MD5:DES-CBC3-SHA:AES128-SHA:AES256-SHA"
":NULL-SHA:NULL-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-PSK-AES256-GCM"
"-SHA384:DHE-PSK-AES128-GCM-SHA256:PSK-AES256-GCM-SHA384:PSK-AES128-GCM-SHA256:"
"DHE-PSK-AES256-CBC-SHA384:DHE-PSK-AES128-CBC-SHA256:PSK-AES256-CBC-SHA384:PSK-"
"AES128-CBC-SHA256:PSK-AES128-CBC-SHA:PSK-AES256-CBC-SHA:DHE-PSK-AES128-CCM:DHE"
"-PSK-AES256-CCM:PSK-AES128-CCM:PSK-AES256-CCM:PSK-AES128-CCM-8:PSK-AES256-CCM-"
"8:DHE-PSK-NULL-SHA384:DHE-PSK-NULL-SHA256:PSK-NULL-SHA384:PSK-NULL-SHA256:PSK-"
"NULL-SHA:AES128-CCM-8:AES256-CCM-8:ECDHE-ECDSA-"
"AES128-CCM:ECDHE-ECDSA-AES128-CCM-8:ECDHE-ECDSA-AES256-CCM-8:ECDHE-RSA-AES128-"
"SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-R"
"SA-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-ECDSA-DES-CBC3-SHA"
":AES128-SHA256:AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDH-"
"RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA"
":ECDH-RSA-RC4-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-RC4-SHA:ECDH-ECDSA-DES-CBC3"
"-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES"
"256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-E"
"CDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES128-GCM-SHA25"
"6:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES256-GC"
"M-SHA384:CAMELLIA128-SHA:DHE-RSA-CAMELLIA128-SHA:CAMELLIA256-SHA:DHE-RSA-CAMEL"
"LIA256-SHA:CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA256:CAMELLIA256-SHA256:DH"
"E-RSA-CAMELLIA256-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECD"
"H-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECD"
"SA-AES256-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDHE-RSA-CHA"
"CHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-R"
"SA-CHACHA20-POLY1305-OLD:ECDHE-ECDSA-CHACHA20-POLY1305-OLD:DHE-RSA-CHACHA20-PO"
"LY1305-OLD:ECDHE-ECDSA-NULL-SHA:ECDHE-PSK-NULL-SHA256:ECDHE-PSK-A"
"ES128-CBC-SHA256:PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:DHE-PSK-CHA"
"CHA20-POLY1305:EDH-RSA-DES-CBC3-SHA:TLS13-AES128-GCM-SHA256:TLS13-AES256-GCM-S"
"HA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES128-CCM-SHA256:TLS13-AES128-CCM-"
"8-SHA256:TLS13-SHA256-SHA256:TLS13-SHA384-SHA384";
    /* OpenVPN uses a "blacklist" method to specify which ciphers NOT to use */
#ifdef OPENSSL_EXTRA
    char openvpnCiphers[] = "DEFAULT:!EXP:!LOW:!MEDIUM:!kDH:!kECDH:!DSS:!PSK:"
                            "!SRP:!kRSA:!aNULL:!eNULL";
#endif

#ifndef NO_RSA
    testCertFile = svrCertFile;
    testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
    testCertFile = eccCertFile;
    testKeyFile = eccKeyFile;
#else
    skipTest = 1;
#endif

    if (skipTest != 1) {
#ifndef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
        ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
            WOLFSSL_FILETYPE_PEM));
        ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
            WOLFSSL_FILETYPE_PEM));
        ExpectNotNull(ssl = wolfSSL_new(ctx));

        /* First test freeing SSL, then CTX */
        wolfSSL_free(ssl);
        ssl = NULL;
        wolfSSL_CTX_free(ctx);
        ctx = NULL;

#ifndef NO_WOLFSSL_CLIENT
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
        ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
            WOLFSSL_FILETYPE_PEM));
        ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
            WOLFSSL_FILETYPE_PEM));
        ExpectNotNull(ssl = wolfSSL_new(ctx));

        /* Next test freeing CTX then SSL */
        wolfSSL_CTX_free(ctx);
        ctx = NULL;
        wolfSSL_free(ssl);
        ssl = NULL;

#ifndef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
        /* Test setting ciphers at ctx level */
        ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
            WOLFSSL_FILETYPE_PEM));
        ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
            WOLFSSL_FILETYPE_PEM));
        ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, optionsCiphers));
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && defined(HAVE_AESGCM) && \
        defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
        /* only update TLSv13 suites */
        ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"));
#endif
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(HAVE_AESGCM) && \
    !defined(NO_SHA256) && !defined(WOLFSSL_NO_TLS12) && \
    defined(WOLFSSL_AES_128) && !defined(NO_RSA)
        /* only update pre-TLSv13 suites */
        ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx,
            "ECDHE-RSA-AES128-GCM-SHA256"));
#endif
#ifdef OPENSSL_EXTRA
        ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, openvpnCiphers));
#endif
        ExpectNotNull(ssl = wolfSSL_new(ctx));
        wolfSSL_CTX_free(ctx);
        ctx = NULL;
        wolfSSL_free(ssl);
        ssl = NULL;

#ifndef NO_WOLFSSL_CLIENT
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
        ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
            WOLFSSL_FILETYPE_PEM));
        ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
            WOLFSSL_FILETYPE_PEM));
        ExpectNotNull(ssl = wolfSSL_new(ctx));
        /* test setting ciphers at SSL level */
        ExpectTrue(wolfSSL_set_cipher_list(ssl, optionsCiphers));
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && defined(HAVE_AESGCM) && \
        defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
        /* only update TLSv13 suites */
        ExpectTrue(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384"));
#endif
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(HAVE_AESGCM) && \
    !defined(NO_SHA256) && !defined(WOLFSSL_NO_TLS12) && \
    defined(WOLFSSL_AES_128) && !defined(NO_RSA)
        /* only update pre-TLSv13 suites */
        ExpectTrue(wolfSSL_set_cipher_list(ssl, "ECDHE-RSA-AES128-GCM-SHA256"));
#endif
        wolfSSL_CTX_free(ctx);
        ctx = NULL;
        wolfSSL_free(ssl);
        ssl = NULL;
    }

    return EXPECT_RESULT();
}
#endif


static int test_wolfSSL_CTX_set_cipher_list_bytes(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
    (!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_FILESYSTEM)
    const char* testCertFile;
    const char* testKeyFile;
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL* ssl = NULL;

    const byte cipherList[] =
    {
        /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */ 0x00, 0x16,
        /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA  */ 0x00, 0x39,
        /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA  */ 0x00, 0x33,
        /* TLS_DH_anon_WITH_AES_128_CBC_SHA  */ 0x00, 0x34,
        /* TLS_RSA_WITH_AES_256_CBC_SHA      */ 0x00, 0x35,
        /* TLS_RSA_WITH_AES_128_CBC_SHA      */ 0x00, 0x2F,
        /* TLS_RSA_WITH_NULL_MD5             */ 0x00, 0x01,
        /* TLS_RSA_WITH_NULL_SHA             */ 0x00, 0x02,
        /* TLS_PSK_WITH_AES_256_CBC_SHA      */ 0x00, 0x8d,
        /* TLS_PSK_WITH_AES_128_CBC_SHA256   */ 0x00, 0xae,
        /* TLS_PSK_WITH_AES_256_CBC_SHA384   */ 0x00, 0xaf,
        /* TLS_PSK_WITH_AES_128_CBC_SHA      */ 0x00, 0x8c,
        /* TLS_PSK_WITH_NULL_SHA256          */ 0x00, 0xb0,
        /* TLS_PSK_WITH_NULL_SHA384          */ 0x00, 0xb1,
        /* TLS_PSK_WITH_NULL_SHA             */ 0x00, 0x2c,
        /* SSL_RSA_WITH_RC4_128_SHA          */ 0x00, 0x05,
        /* SSL_RSA_WITH_RC4_128_MD5          */ 0x00, 0x04,
        /* SSL_RSA_WITH_3DES_EDE_CBC_SHA     */ 0x00, 0x0A,

        /* ECC suites, first byte is 0xC0 (ECC_BYTE) */
        /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA     */ 0xC0, 0x14,
        /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     */ 0xC0, 0x13,
        /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   */ 0xC0, 0x0A,
        /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA   */ 0xC0, 0x09,
        /* TLS_ECDHE_RSA_WITH_RC4_128_SHA         */ 0xC0, 0x11,
        /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA       */ 0xC0, 0x07,
        /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA    */ 0xC0, 0x12,
        /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA  */ 0xC0, 0x08,
        /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256  */ 0xC0, 0x27,
        /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256*/ 0xC0, 0x23,
        /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384  */ 0xC0, 0x28,
        /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384*/ 0xC0, 0x24,
        /* TLS_ECDHE_ECDSA_WITH_NULL_SHA          */ 0xC0, 0x06,
        /* TLS_ECDHE_PSK_WITH_NULL_SHA256         */ 0xC0, 0x3a,
        /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256  */ 0xC0, 0x37,

        /* static ECDH, first byte is 0xC0 (ECC_BYTE) */
        /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA      */ 0xC0, 0x0F,
        /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA      */ 0xC0, 0x0E,
        /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA    */ 0xC0, 0x05,
        /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA    */ 0xC0, 0x04,
        /* TLS_ECDH_RSA_WITH_RC4_128_SHA          */ 0xC0, 0x0C,
        /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA        */ 0xC0, 0x02,
        /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA     */ 0xC0, 0x0D,
        /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA   */ 0xC0, 0x03,
        /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256   */ 0xC0, 0x29,
        /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */ 0xC0, 0x25,
        /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384   */ 0xC0, 0x2A,
        /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */ 0xC0, 0x26,

        /* WDM_WITH_NULL_SHA256 */ 0x00, 0xFE, /* wolfSSL DTLS Multicast */

        /* SHA256 */
        /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */ 0x00, 0x6b,
        /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */ 0x00, 0x67,
        /* TLS_RSA_WITH_AES_256_CBC_SHA256     */ 0x00, 0x3d,
        /* TLS_RSA_WITH_AES_128_CBC_SHA256     */ 0x00, 0x3c,
        /* TLS_RSA_WITH_NULL_SHA256            */ 0x00, 0x3b,
        /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */ 0x00, 0xb2,
        /* TLS_DHE_PSK_WITH_NULL_SHA256        */ 0x00, 0xb4,

        /* SHA384 */
        /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */ 0x00, 0xb3,
        /* TLS_DHE_PSK_WITH_NULL_SHA384        */ 0x00, 0xb5,

        /* AES-GCM */
        /* TLS_RSA_WITH_AES_128_GCM_SHA256      */ 0x00, 0x9c,
        /* TLS_RSA_WITH_AES_256_GCM_SHA384      */ 0x00, 0x9d,
        /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256  */ 0x00, 0x9e,
        /* TLS_DHE_RSA_WITH_AES_256_GCM_SHA384  */ 0x00, 0x9f,
        /* TLS_DH_anon_WITH_AES_256_GCM_SHA384  */ 0x00, 0xa7,
        /* TLS_PSK_WITH_AES_128_GCM_SHA256      */ 0x00, 0xa8,
        /* TLS_PSK_WITH_AES_256_GCM_SHA384      */ 0x00, 0xa9,
        /* TLS_DHE_PSK_WITH_AES_128_GCM_SHA256  */ 0x00, 0xaa,
        /* TLS_DHE_PSK_WITH_AES_256_GCM_SHA384  */ 0x00, 0xab,

        /* ECC AES-GCM, first byte is 0xC0 (ECC_BYTE) */
        /* TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 */ 0xC0, 0x2b,
        /* TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 */ 0xC0, 0x2c,
        /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256  */ 0xC0, 0x2d,
        /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384  */ 0xC0, 0x2e,
        /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   */ 0xC0, 0x2f,
        /* TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   */ 0xC0, 0x30,
        /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256    */ 0xC0, 0x31,
        /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384    */ 0xC0, 0x32,

        /* AES-CCM, first byte is 0xC0 but isn't ECC,
         * also, in some of the other AES-CCM suites
         * there will be second byte number conflicts
         * with non-ECC AES-GCM */
        /* TLS_RSA_WITH_AES_128_CCM_8         */ 0xC0, 0xa0,
        /* TLS_RSA_WITH_AES_256_CCM_8         */ 0xC0, 0xa1,
        /* TLS_ECDHE_ECDSA_WITH_AES_128_CCM   */ 0xC0, 0xac,
        /* TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 */ 0xC0, 0xae,
        /* TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 */ 0xC0, 0xaf,
        /* TLS_PSK_WITH_AES_128_CCM           */ 0xC0, 0xa4,
        /* TLS_PSK_WITH_AES_256_CCM           */ 0xC0, 0xa5,
        /* TLS_PSK_WITH_AES_128_CCM_8         */ 0xC0, 0xa8,
        /* TLS_PSK_WITH_AES_256_CCM_8         */ 0xC0, 0xa9,
        /* TLS_DHE_PSK_WITH_AES_128_CCM       */ 0xC0, 0xa6,
        /* TLS_DHE_PSK_WITH_AES_256_CCM       */ 0xC0, 0xa7,

        /* Camellia */
        /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA        */ 0x00, 0x41,
        /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA        */ 0x00, 0x84,
        /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256     */ 0x00, 0xba,
        /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256     */ 0x00, 0xc0,
        /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA    */ 0x00, 0x45,
        /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA    */ 0x00, 0x88,
        /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */ 0x00, 0xbe,
        /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */ 0x00, 0xc4,

        /* chacha20-poly1305 suites first byte is 0xCC (CHACHA_BYTE) */
        /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   */ 0xCC, 0xa8,
        /* TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ 0xCC, 0xa9,
        /* TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256     */ 0xCC, 0xaa,
        /* TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256   */ 0xCC, 0xac,
        /* TLS_PSK_WITH_CHACHA20_POLY1305_SHA256         */ 0xCC, 0xab,
        /* TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256     */ 0xCC, 0xad,

        /* chacha20-poly1305 earlier version of nonce and padding (CHACHA_BYTE) */
        /* TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256   */ 0xCC, 0x13,
        /* TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 */ 0xCC, 0x14,
        /* TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256     */ 0xCC, 0x15,

        /* ECDHE_PSK RFC8442, first byte is 0xD0 (ECDHE_PSK_BYTE) */
        /* TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 */ 0xD0, 0x01,

        /* TLS v1.3 cipher suites */
        /* TLS_AES_128_GCM_SHA256       */ 0x13, 0x01,
        /* TLS_AES_256_GCM_SHA384       */ 0x13, 0x02,
        /* TLS_CHACHA20_POLY1305_SHA256 */ 0x13, 0x03,
        /* TLS_AES_128_CCM_SHA256       */ 0x13, 0x04,
        /* TLS_AES_128_CCM_8_SHA256     */ 0x13, 0x05,

        /* TLS v1.3 Integrity only cipher suites - 0xC0 (ECC) first byte */
        /* TLS_SHA256_SHA256 */ 0xC0, 0xB4,
        /* TLS_SHA384_SHA384 */ 0xC0, 0xB5
    };

#ifndef NO_RSA
    testCertFile = svrCertFile;
    testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
    testCertFile = eccCertFile;
    testKeyFile = eccKeyFile;
#endif

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif

    ExpectTrue(wolfSSL_CTX_set_cipher_list_bytes(ctx, &cipherList[0U],
                                                           sizeof(cipherList)));

    wolfSSL_CTX_free(ctx);
    ctx = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif

    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
                                                         WOLFSSL_FILETYPE_PEM));

    ExpectNotNull(ssl = wolfSSL_new(ctx));

    ExpectTrue(wolfSSL_set_cipher_list_bytes(ssl, &cipherList[0U],
                                                           sizeof(cipherList)));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif /* (OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES) &&
    (!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) && (!NO_RSA || HAVE_ECC) */

    return EXPECT_RESULT();
}


static int test_wolfSSL_CTX_use_certificate(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
    defined(WOLFSSL_HAPROXY)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX* ctx = NULL;
    X509* x509 = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif

    ExpectNotNull(x509 = wolfSSL_X509_new());

    /* Negative tests. */
    ExpectIntEQ(SSL_CTX_use_certificate(NULL, NULL), 0);
    ExpectIntEQ(SSL_CTX_use_certificate(ctx, NULL), 0);
    ExpectIntEQ(SSL_CTX_use_certificate(NULL, x509), 0);
    /* Empty certificate */
    ExpectIntEQ(SSL_CTX_use_certificate(ctx, x509), 0);

    wolfSSL_X509_free(x509);
    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_use_certificate_file(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX *ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    /* invalid context */
    ExpectFalse(wolfSSL_CTX_use_certificate_file(NULL, svrCertFile,
                                                         WOLFSSL_FILETYPE_PEM));
    /* invalid cert file */
    ExpectFalse(wolfSSL_CTX_use_certificate_file(ctx, bogusFile,
                                                         WOLFSSL_FILETYPE_PEM));
    /* invalid cert type */
    ExpectFalse(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, 9999));

#ifdef NO_RSA
    /* rsa needed */
    ExpectFalse(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
                                                         WOLFSSL_FILETYPE_PEM));
#else
    /* success */
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
                                                         WOLFSSL_FILETYPE_PEM));
#endif

    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA)
static int test_wolfSSL_CTX_use_certificate_ASN1(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_WOLFSSL_SERVER) && !defined(NO_ASN)
    WOLFSSL_CTX* ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    /* Failure cases. */
    ExpectIntEQ(SSL_CTX_use_certificate_ASN1(NULL, 0, NULL                ),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CTX_use_certificate_ASN1(ctx , 0, NULL                ),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CTX_use_certificate_ASN1(NULL, 0, server_cert_der_2048),
       WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CTX_use_certificate_ASN1(ctx , 0, server_cert_der_2048),
       WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(SSL_CTX_use_certificate_ASN1(ctx, sizeof_server_cert_der_2048,
        server_cert_der_2048), WOLFSSL_SUCCESS);

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}
#endif /* (OPENSSL_ALL || WOLFSSL_ASIO) && !NO_RSA */

/*  Test function for wolfSSL_CTX_use_certificate_buffer. Load cert into
 *  context using buffer.
 *  PRE: NO_CERTS not defined; USE_CERT_BUFFERS_2048 defined; compile with
 *  --enable-testcert flag.
 */
static int test_wolfSSL_CTX_use_certificate_buffer(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(USE_CERT_BUFFERS_2048) && \
        !defined(NO_RSA) && !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX* ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    /* Invalid parameters. */
    ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(NULL, NULL, 0,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx, NULL, 0,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));
    ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(NULL, server_cert_der_2048,
        0, WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048, 0,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));

    ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx,
        server_cert_der_2048, sizeof_server_cert_der_2048,
        WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();

} /* END test_wolfSSL_CTX_use_certificate_buffer */

static int test_wolfSSL_use_certificate_buffer(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(USE_CERT_BUFFERS_2048) && \
        !defined(NO_RSA) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    /* Invalid parameters. */
    ExpectIntEQ(wolfSSL_use_certificate_buffer(NULL, NULL, 0,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_use_certificate_buffer(ssl, NULL, 0,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));
    ExpectIntEQ(wolfSSL_use_certificate_buffer(NULL, client_cert_der_2048, 0,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_use_certificate_buffer(ssl, client_cert_der_2048, 0,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));

    ExpectIntEQ(wolfSSL_use_certificate_buffer(ssl,
        client_cert_der_2048, sizeof_client_cert_der_2048,
        WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_use_PrivateKey_file(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX *ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    /* invalid context */
    ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(NULL, svrKeyFile,
                                                         WOLFSSL_FILETYPE_PEM));
    /* invalid key file */
    ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, bogusFile,
                                                         WOLFSSL_FILETYPE_PEM));
    /* invalid key type */
    ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, 9999));

    /* success */
#ifdef NO_RSA
    /* rsa needed */
    ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
                                                         WOLFSSL_FILETYPE_PEM));
#else
    /* success */
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
                                                         WOLFSSL_FILETYPE_PEM));
#endif

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_use_RSAPrivateKey_file(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_SERVER) && defined(OPENSSL_EXTRA)
    WOLFSSL_CTX *ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    /* invalid context */
    ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(NULL, svrKeyFile,
        WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* invalid key file */
    ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(ctx, bogusFile,
        WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* invalid key type */
    ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(ctx, svrKeyFile, 9999),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* success */
#ifdef NO_RSA
    /* rsa needed */
    ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(ctx, svrKeyFile,
        WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#else
    /* success */
    ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(ctx, svrKeyFile,
        WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_use_RSAPrivateKey_file(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_CLIENT) && defined(OPENSSL_EXTRA)
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ssl = SSL_new(ctx));

    /* invalid context */
    ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(NULL, svrKeyFile,
        WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* invalid key file */
    ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(ssl, bogusFile,
        WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* invalid key type */
    ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(ssl, svrKeyFile, 9999),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* success */
#ifdef NO_RSA
    /* rsa needed */
    ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(ssl, svrKeyFile,
        WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#else
    /* success */
    ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(ssl, svrKeyFile,
        WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_use_PrivateKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_SERVER) && defined(OPENSSL_EXTRA)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL_EVP_PKEY* pkey = NULL;
    const unsigned char* p;

    (void)p;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(NULL, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* No data. */
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;

#if defined(USE_CERT_BUFFERS_2048)
#if !defined(NO_RSA)
    p = client_key_der_2048;
    ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
        sizeof_client_key_der_2048));
#if defined(WOLFSSL_KEY_GEN)
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
#endif
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)
#ifndef NO_DSA
    p = dsa_key_der_2048;
    ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_DSA, NULL, &p,
        sizeof_dsa_key_der_2048));
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
    defined(WOLFSSL_CERT_GEN))
    /* Not supported in ProcessBuffer. */
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_BAD_FILE));
#else
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
#endif
#endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH */
#if !defined(NO_DH) && defined(OPENSSL_ALL) && \
    (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
    p = dh_ffdhe_statickey_der_2048;
    ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_DH, NULL, &p,
        sizeof_dh_ffdhe_statickey_der_2048));
    /* Not supported. */
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
#endif
#endif /* USE_CERT_BUFFERS_2048 */
#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
    p = ecc_clikey_der_256;
    ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_EC, NULL, &p,
        sizeof_ecc_clikey_der_256));
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WOLFSSL_SUCCESS);
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
#endif
    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
        (unsigned char*)"01234567012345670123456701234567", 32));
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

/* test both file and buffer versions along with unloading trusted peer certs */
static int test_wolfSSL_CTX_trust_peer_cert(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(WOLFSSL_TRUST_PEER_CERT) && \
    !defined(NO_WOLFSSL_CLIENT) && !defined(NO_RSA)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL* ssl = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ssl = wolfSSL_new(ctx));

#if !defined(NO_FILESYSTEM)
    /* invalid file */
    ExpectIntNE(wolfSSL_CTX_trust_peer_cert(ctx, NULL,
                                     WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntNE(wolfSSL_CTX_trust_peer_cert(ctx, bogusFile,
                                     WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntNE(wolfSSL_CTX_trust_peer_cert(ctx, cliCertFile,
                                     WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* success */
    ExpectIntEQ(wolfSSL_CTX_trust_peer_cert(ctx, cliCertFile,
                                     WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    /* unload cert */
    ExpectIntNE(wolfSSL_CTX_Unload_trust_peers(NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_Unload_trust_peers(ctx), WOLFSSL_SUCCESS);

    /* invalid file */
    ExpectIntNE(wolfSSL_trust_peer_cert(ssl, NULL,
                                     WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntNE(wolfSSL_trust_peer_cert(ssl, bogusFile,
                                     WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntNE(wolfSSL_trust_peer_cert(ssl, cliCertFile,
                                     WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* success */
    ExpectIntEQ(wolfSSL_trust_peer_cert(ssl, cliCertFile,
                                     WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    #ifdef WOLFSSL_LOCAL_X509_STORE
    /* unload cert */
    ExpectIntNE(wolfSSL_Unload_trust_peers(NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_Unload_trust_peers(ssl), WOLFSSL_SUCCESS);
    #endif
#endif

    /* Test of loading certs from buffers */

    /* invalid buffer */
    ExpectIntNE(wolfSSL_CTX_trust_peer_buffer(ctx, NULL, -1,
                                     WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* success */
#ifdef USE_CERT_BUFFERS_1024
    ExpectIntEQ(wolfSSL_CTX_trust_peer_buffer(ctx, client_cert_der_1024,
          sizeof_client_cert_der_1024, WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif
#ifdef USE_CERT_BUFFERS_2048
    ExpectIntEQ(wolfSSL_CTX_trust_peer_buffer(ctx, client_cert_der_2048,
          sizeof_client_cert_der_2048, WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif

    /* unload cert */
    ExpectIntNE(wolfSSL_CTX_Unload_trust_peers(NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_Unload_trust_peers(ctx), WOLFSSL_SUCCESS);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_load_verify_locations(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX *ctx = NULL;
#ifndef NO_RSA
    WOLFSSL_CERT_MANAGER* cm = NULL;
#ifdef PERSIST_CERT_CACHE
    int cacheSz = 0;
    unsigned char* cache = NULL;
    int used = 0;
#ifndef NO_FILESYSTEM
    const char* cacheFile = "./tests/cert_cache.tmp";
#endif
    int i;
    int t;
    int* p;
#endif
#endif
#if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_TIRTOS)
    const char* load_certs_path = "./certs/external";
    const char* load_no_certs_path = "./examples";
    const char* load_expired_path = "./certs/test/expired";
#endif

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));

    /* invalid arguments */
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(NULL, caCertFile, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, NULL, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* invalid ca file */
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, bogusFile, NULL),
        WS_RETURN_CODE(WC_NO_ERR_TRACE(WOLFSSL_BAD_FILE),
                       WC_NO_ERR_TRACE(WOLFSSL_FAILURE)));


#if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_TIRTOS) && \
  ((defined(WOLFSSL_QT) || defined(WOLFSSL_IGNORE_BAD_CERT_PATH)) && \
  !(WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS & WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR))
    /* invalid path */
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, NULL, bogusFile),
        WS_RETURN_CODE(WC_NO_ERR_TRACE(BAD_PATH_ERROR),WC_NO_ERR_TRACE(WOLFSSL_FAILURE)));
#endif
#if defined(WOLFSSL_QT) || defined(WOLFSSL_IGNORE_BAD_CERT_PATH)
    /* test ignoring the invalid path */
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, bogusFile,
        WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR), WOLFSSL_SUCCESS);
#endif

    /* load ca cert */
#ifdef NO_RSA
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, NULL),
        WS_RETURN_CODE(WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E),WC_NO_ERR_TRACE(WOLFSSL_FAILURE)));
#else /* Skip the following test without RSA certs. */
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, NULL),
        WOLFSSL_SUCCESS);

#ifdef PERSIST_CERT_CACHE
    /* Get cert cache size */
    ExpectIntGT(cacheSz = wolfSSL_CTX_get_cert_cache_memsize(ctx), 0);

    ExpectNotNull(cache = (byte*)XMALLOC(cacheSz, NULL,
                            DYNAMIC_TYPE_TMP_BUFFER));

    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, NULL, -1, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, NULL, -1, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, cache, -1, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, NULL, cacheSz, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, NULL, -1, &used),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, cache, cacheSz, &used),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, NULL, cacheSz, &used),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, -1, &used),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, cacheSz, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, cacheSz - 10, &used),
        WC_NO_ERR_TRACE(BUFFER_E));
    ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, cacheSz, &used), 1);
    ExpectIntEQ(cacheSz, used);

    ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, NULL, -1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, NULL, -1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, cache, -1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, NULL, cacheSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, cache, cacheSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, NULL, cacheSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, -1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Smaller than header. */
    ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, 1), WC_NO_ERR_TRACE(BUFFER_E));
    for (i = 1; i < cacheSz; i++) {
        ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz - i),
            WC_NO_ERR_TRACE(BUFFER_E));
    }
    if (EXPECT_SUCCESS()) {
        /* Modify header for bad results! */
        p = (int*)cache;
        /* version */
        t = p[0]; p[0] = 0xff;
        ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz),
            WC_NO_ERR_TRACE(CACHE_MATCH_ERROR));
        p[0] = t; p++;
        /* rows */
        t = p[0]; p[0] = 0xff;
        ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz),
            WC_NO_ERR_TRACE(CACHE_MATCH_ERROR));
        p[0] = t; p++;
        /* columns[0] */
        t = p[0]; p[0] = -1;
        ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz),
            WC_NO_ERR_TRACE(PARSE_ERROR));
        p[0] = t; p += CA_TABLE_SIZE;
        /* signerSz*/
        t = p[0]; p[0] = 0xff;
        ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz),
            WC_NO_ERR_TRACE(CACHE_MATCH_ERROR));
        p[0] = t;
    }

    ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz), 1);
    ExpectIntEQ(cacheSz = wolfSSL_CTX_get_cert_cache_memsize(ctx), used);

#ifndef NO_FILESYSTEM
    ExpectIntEQ(wolfSSL_CTX_save_cert_cache(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_save_cert_cache(ctx, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_save_cert_cache(NULL, cacheFile), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_save_cert_cache(ctx, cacheFile), 1);

    ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(NULL, cacheFile), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, "no-file"),
        WC_NO_ERR_TRACE(WOLFSSL_BAD_FILE));
    ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, cacheFile), 1);
    /* File contents is not a cache. */
    ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, "./certs/ca-cert.pem"),
        WC_NO_ERR_TRACE(CACHE_MATCH_ERROR));
#endif

    XFREE(cache, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    /* Test unloading CA's */
    ExpectIntEQ(wolfSSL_CTX_UnloadCAs(ctx), WOLFSSL_SUCCESS);

#ifdef PERSIST_CERT_CACHE
    /* Verify no certs (result is less than cacheSz) */
    ExpectIntGT(cacheSz, wolfSSL_CTX_get_cert_cache_memsize(ctx));
#endif

    /* load ca cert again */
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, NULL),
        WOLFSSL_SUCCESS);

    /* Test getting CERT_MANAGER */
    ExpectNotNull(cm = wolfSSL_CTX_GetCertManager(ctx));

    /* Test unloading CA's using CM */
    ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(cm), WOLFSSL_SUCCESS);

#ifdef PERSIST_CERT_CACHE
    /* Verify no certs (result is less than cacheSz) */
    ExpectIntGT(cacheSz, wolfSSL_CTX_get_cert_cache_memsize(ctx));
#endif
#endif

#if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_TIRTOS)
    /* Test loading CA certificates using a path */
    #ifdef NO_RSA
    /* failure here okay since certs in external directory are RSA */
    ExpectIntNE(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, load_certs_path,
        WOLFSSL_LOAD_FLAG_PEM_CA_ONLY), WOLFSSL_SUCCESS);
    #else
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, load_certs_path,
        WOLFSSL_LOAD_FLAG_PEM_CA_ONLY), WOLFSSL_SUCCESS);
    #endif

    /* Test loading path with no files */
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL,
        load_no_certs_path, WOLFSSL_LOAD_FLAG_PEM_CA_ONLY),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* Test loading expired CA certificates */
    #ifdef NO_RSA
    ExpectIntNE(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL,
        load_expired_path,
        WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY | WOLFSSL_LOAD_FLAG_PEM_CA_ONLY),
        WOLFSSL_SUCCESS);
    #else
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL,
        load_expired_path,
        WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY | WOLFSSL_LOAD_FLAG_PEM_CA_ONLY),
        WOLFSSL_SUCCESS);
    #endif

    /* Test loading CA certificates and ignoring all errors */
    #ifdef NO_RSA
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, load_certs_path,
        WOLFSSL_LOAD_FLAG_IGNORE_ERR), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    #else
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, load_certs_path,
        WOLFSSL_LOAD_FLAG_IGNORE_ERR), WOLFSSL_SUCCESS);
    #endif
#endif

    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_load_system_CA_certs(void)
{
    int res = TEST_SKIPPED;
#if defined(WOLFSSL_SYS_CA_CERTS) && !defined(NO_WOLFSSL_CLIENT) && \
    (!defined(NO_RSA) || defined(HAVE_ECC))
    WOLFSSL_CTX* ctx;
    byte dirValid = 0;
    int ret = 0;

    ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
    if (ctx == NULL) {
        fprintf(stderr, "wolfSSL_CTX_new failed.\n");
        ret = -1;
    }
    if (ret == 0) {
    #if defined(USE_WINDOWS_API) || defined(__APPLE__)
        dirValid = 1;
    #else
        word32 numDirs;
        const char** caDirs = wolfSSL_get_system_CA_dirs(&numDirs);

        if (caDirs == NULL || numDirs == 0) {
            fprintf(stderr, "wolfSSL_get_system_CA_dirs failed.\n");
            ret = -1;
        }
        else {
            ReadDirCtx dirCtx;
            word32 i;

            for (i = 0; i < numDirs; ++i) {
                if (wc_ReadDirFirst(&dirCtx, caDirs[i], NULL) == 0) {
                    /* Directory isn't empty. */
                    dirValid = 1;
                    wc_ReadDirClose(&dirCtx);
                    break;
                }
            }
        }
    #endif
    }
    /*
     * If the directory isn't empty, we should be able to load CA
     * certs from it. On Windows/Mac, we assume the CA cert stores are
     * usable.
     */
    if (ret == 0 && dirValid && wolfSSL_CTX_load_system_CA_certs(ctx) !=
        WOLFSSL_SUCCESS) {
        fprintf(stderr, "wolfSSL_CTX_load_system_CA_certs failed.\n");
        ret = -1;
    }
#ifdef OPENSSL_EXTRA
    if (ret == 0 &&
        wolfSSL_CTX_set_default_verify_paths(ctx) != WOLFSSL_SUCCESS) {
        fprintf(stderr, "wolfSSL_CTX_set_default_verify_paths failed.\n");
        ret = -1;
    }
#endif /* OPENSSL_EXTRA */

    wolfSSL_CTX_free(ctx);

    res = TEST_RES_CHECK(ret == 0);
#endif /* WOLFSSL_SYS_CA_CERTS && !NO_WOLFSSL_CLIENT */

    return res;
}

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
static int test_cm_load_ca_buffer(const byte* cert_buf, size_t cert_sz,
    int file_type)
{
    int ret;
    WOLFSSL_CERT_MANAGER* cm;

    cm = wolfSSL_CertManagerNew();
    if (cm == NULL) {
        fprintf(stderr, "test_cm_load_ca failed\n");
        return -1;
    }

    ret = wolfSSL_CertManagerLoadCABuffer(cm, cert_buf, (sword32)cert_sz, file_type);

    wolfSSL_CertManagerFree(cm);

    return ret;
}

static int test_cm_load_ca_file(const char* ca_cert_file)
{
    int ret = 0;
    byte* cert_buf = NULL;
    size_t cert_sz = 0;
#if defined(WOLFSSL_PEM_TO_DER)
    DerBuffer* pDer = NULL;
#endif

    ret = load_file(ca_cert_file, &cert_buf, &cert_sz);
    if (ret == 0) {
        /* normal test */
        ret = test_cm_load_ca_buffer(cert_buf, cert_sz, WOLFSSL_FILETYPE_PEM);

        if (ret == WOLFSSL_SUCCESS) {
            /* test including null terminator in length */
            byte* tmp = (byte*)realloc(cert_buf, cert_sz+1);
            if (tmp == NULL) {
                ret = MEMORY_E;
            }
            else {
                cert_buf = tmp;
                cert_buf[cert_sz] = '\0';
                ret = test_cm_load_ca_buffer(cert_buf, cert_sz+1,
                        WOLFSSL_FILETYPE_PEM);
            }

        }

    #if defined(WOLFSSL_PEM_TO_DER)
        if (ret == WOLFSSL_SUCCESS) {
            /* test loading DER */
            ret = wc_PemToDer(cert_buf, (sword32)cert_sz, CA_TYPE, &pDer,
                    NULL, NULL, NULL);
            if (ret == 0 && pDer != NULL) {
                ret = test_cm_load_ca_buffer(pDer->buffer, pDer->length,
                    WOLFSSL_FILETYPE_ASN1);

                wc_FreeDer(&pDer);
            }
        }
    #endif

    }
    free(cert_buf);

    return ret;
}

static int test_cm_load_ca_buffer_ex(const byte* cert_buf, size_t cert_sz,
                                     int file_type, word32 flags)
{
    int ret;
    WOLFSSL_CERT_MANAGER* cm;

    cm = wolfSSL_CertManagerNew();
    if (cm == NULL) {
        fprintf(stderr, "test_cm_load_ca failed\n");
        return -1;
    }

    ret = wolfSSL_CertManagerLoadCABuffer_ex(cm, cert_buf, (sword32)cert_sz, file_type,
                                             0, flags);

    wolfSSL_CertManagerFree(cm);

    return ret;
}

static int test_cm_load_ca_file_ex(const char* ca_cert_file, word32 flags)
{
    int ret = 0;
    byte* cert_buf = NULL;
    size_t cert_sz = 0;
#if defined(WOLFSSL_PEM_TO_DER)
    DerBuffer* pDer = NULL;
#endif

    ret = load_file(ca_cert_file, &cert_buf, &cert_sz);
    if (ret == 0) {
        /* normal test */
        ret = test_cm_load_ca_buffer_ex(cert_buf, cert_sz,
                                        WOLFSSL_FILETYPE_PEM, flags);

        if (ret == WOLFSSL_SUCCESS) {
            /* test including null terminator in length */
            byte* tmp = (byte*)realloc(cert_buf, cert_sz+1);
            if (tmp == NULL) {
                ret = MEMORY_E;
            }
            else {
                cert_buf = tmp;
                cert_buf[cert_sz] = '\0';
                ret = test_cm_load_ca_buffer_ex(cert_buf, cert_sz+1,
                        WOLFSSL_FILETYPE_PEM, flags);
            }

        }

    #if defined(WOLFSSL_PEM_TO_DER)
        if (ret == WOLFSSL_SUCCESS) {
            /* test loading DER */
            ret = wc_PemToDer(cert_buf, (sword32)cert_sz, CA_TYPE, &pDer,
                              NULL, NULL, NULL);
            if (ret == 0 && pDer != NULL) {
                ret = test_cm_load_ca_buffer_ex(pDer->buffer, pDer->length,
                    WOLFSSL_FILETYPE_ASN1, flags);

                wc_FreeDer(&pDer);
            }
        }
    #endif

    }
    free(cert_buf);

    return ret;
}

#endif /* !NO_FILESYSTEM && !NO_CERTS */

static int test_wolfSSL_CertManagerAPI(void)
{
    EXPECT_DECLS;
#ifndef NO_CERTS
    WOLFSSL_CERT_MANAGER* cm = NULL;
    unsigned char c;

    ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));

    wolfSSL_CertManagerFree(NULL);
    ExpectIntEQ(wolfSSL_CertManager_up_ref(NULL), 0);
    ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_TRUST_PEER_CERT
    ExpectIntEQ(wolfSSL_CertManagerUnload_trust_peers(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer_ex(NULL, &c, 1,
        WOLFSSL_FILETYPE_ASN1, 0, 0), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));

#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(NULL, NULL, -1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, NULL, -1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(NULL, &c, -1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(NULL, NULL, 1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(NULL, &c, 1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, NULL, 1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, &c, -1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, &c, 1, -1),
        WC_NO_ERR_TRACE(WOLFSSL_BAD_FILETYPE));
#endif

#if !defined(NO_FILESYSTEM)
    {
        const char* ca_cert = "./certs/ca-cert.pem";
    #if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
        const char* ca_cert_der = "./certs/ca-cert.der";
    #endif
        const char* ca_path = "./certs";

    #if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
        ExpectIntEQ(wolfSSL_CertManagerVerify(NULL, NULL, -1),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wolfSSL_CertManagerVerify(cm, NULL, WOLFSSL_FILETYPE_ASN1),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wolfSSL_CertManagerVerify(NULL, ca_cert,
            WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wolfSSL_CertManagerVerify(cm, ca_cert, -1),
            WC_NO_ERR_TRACE(WOLFSSL_BAD_FILETYPE));
        ExpectIntEQ(wolfSSL_CertManagerVerify(cm, "no-file",
            WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_BAD_FILE));
        ExpectIntEQ(wolfSSL_CertManagerVerify(cm, ca_cert_der,
            WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));
    #endif

        ExpectIntEQ(wolfSSL_CertManagerLoadCA(NULL, NULL, NULL),
            WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
        ExpectIntEQ(wolfSSL_CertManagerLoadCA(NULL, ca_cert, NULL),
            WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
        ExpectIntEQ(wolfSSL_CertManagerLoadCA(NULL, NULL, ca_path),
            WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
        ExpectIntEQ(wolfSSL_CertManagerLoadCA(NULL, ca_cert, ca_path),
            WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    }
#endif

#ifdef OPENSSL_COMPATIBLE_DEFAULTS
    ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, 0), 1);
#elif !defined(HAVE_CRL)
    ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, 0), WC_NO_ERR_TRACE(NOT_COMPILED_IN));
#endif

    ExpectIntEQ(wolfSSL_CertManagerDisableCRL(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerDisableCRL(cm), 1);
#ifdef HAVE_CRL
    /* Test APIs when CRL is disabled. */
#ifdef HAVE_CRL_IO
    ExpectIntEQ(wolfSSL_CertManagerSetCRL_IOCb(cm, NULL), 1);
#endif
    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, server_cert_der_2048,
        sizeof_server_cert_der_2048), 1);
    ExpectIntEQ(wolfSSL_CertManagerFreeCRL(cm), 1);
#endif

    /* OCSP */
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerDisableOCSP(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSPStapling(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerDisableOCSPStapling(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSPMustStaple(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerDisableOCSPMustStaple(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#if !defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
    !defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
    ExpectIntEQ(wolfSSL_CertManagerDisableOCSPStapling(cm), WC_NO_ERR_TRACE(NOT_COMPILED_IN));
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSPMustStaple(cm), WC_NO_ERR_TRACE(NOT_COMPILED_IN));
    ExpectIntEQ(wolfSSL_CertManagerDisableOCSPMustStaple(cm), WC_NO_ERR_TRACE(NOT_COMPILED_IN));
#endif

#ifdef HAVE_OCSP
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(NULL, NULL, -1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, NULL, -1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(NULL, &c, -1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(NULL, &c, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, &c, -1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(NULL, NULL, 0,
        NULL, NULL, NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, NULL, 1,
        NULL, NULL, NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(NULL, &c, 1,
        NULL, NULL, NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(NULL, ""),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(cm, NULL), 1);

    ExpectIntEQ(wolfSSL_CertManagerSetOCSP_Cb(NULL, NULL, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerSetOCSP_Cb(cm, NULL, NULL, NULL), 1);

    ExpectIntEQ(wolfSSL_CertManagerDisableOCSP(cm), 1);
    /* Test APIs when OCSP is disabled. */
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, &c, 1,
        NULL, NULL, NULL, NULL), 1);
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, &c, 1), 1);

#endif

    ExpectIntEQ(wolfSSL_CertManager_up_ref(cm), 1);
    if (EXPECT_SUCCESS()) {
        wolfSSL_CertManagerFree(cm);
    }
    wolfSSL_CertManagerFree(cm);
    cm = NULL;

    ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));

#ifdef HAVE_OCSP
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(cm, WOLFSSL_OCSP_URL_OVERRIDE |
         WOLFSSL_OCSP_CHECKALL), 1);
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
    defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSPStapling(cm), 1);
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSPStapling(cm), 1);
    ExpectIntEQ(wolfSSL_CertManagerDisableOCSPStapling(cm), 1);
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSPStapling(cm), 1);
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSPMustStaple(cm), 1);
    ExpectIntEQ(wolfSSL_CertManagerDisableOCSPMustStaple(cm), 1);
#endif

    ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(cm, ""), 1);
    ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(cm, ""), 1);
#endif

#ifdef WOLFSSL_TRUST_PEER_CERT
    ExpectIntEQ(wolfSSL_CertManagerUnload_trust_peers(cm), 1);
#endif
    wolfSSL_CertManagerFree(cm);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CertManagerLoadCABuffer(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    const char* ca_cert = "./certs/ca-cert.pem";
    const char* ca_expired_cert = "./certs/test/expired/expired-ca.pem";
    int ret;

    ExpectIntLE(ret = test_cm_load_ca_file(ca_cert), 1);
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#elif defined(NO_RSA)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E));
#else
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);
#endif

    ExpectIntLE(ret = test_cm_load_ca_file(ca_expired_cert), 1);
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#elif defined(NO_RSA)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E));
#elif !(WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY) && \
      !defined(NO_ASN_TIME)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_AFTER_DATE_E));
#else
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CertManagerLoadCABuffer_ex(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    const char* ca_cert = "./certs/ca-cert.pem";
    const char* ca_expired_cert = "./certs/test/expired/expired-ca.pem";
    int ret;

    ExpectIntLE(ret = test_cm_load_ca_file_ex(ca_cert, WOLFSSL_LOAD_FLAG_NONE),
        1);
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#elif defined(NO_RSA)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E));
#else
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);
#endif

    ExpectIntLE(ret = test_cm_load_ca_file_ex(ca_expired_cert,
        WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), 1);
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#elif defined(NO_RSA)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E));
#elif !(WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY) && \
      !defined(NO_ASN_TIME) && defined(WOLFSSL_TRUST_PEER_CERT) && \
      defined(OPENSSL_COMPATIBLE_DEFAULTS)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_AFTER_DATE_E));
#else
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);
#endif

#endif

    return EXPECT_RESULT();
}


static int test_wolfSSL_CertManagerGetCerts(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
    !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \
     defined(WOLFSSL_SIGNER_DER_CERT)
    WOLFSSL_CERT_MANAGER* cm = NULL;
    WOLFSSL_STACK* sk = NULL;
    X509* x509 = NULL;
    X509* cert1 = NULL;
    FILE* file1 = NULL;
#ifdef DEBUG_WOLFSSL_VERBOSE
    WOLFSSL_BIO* bio = NULL;
#endif
    int i = 0;
    int ret = 0;
    const byte* der = NULL;
    int derSz = 0;

    ExpectNotNull(file1 = fopen("./certs/ca-cert.pem", "rb"));

    ExpectNotNull(cert1 = wolfSSL_PEM_read_X509(file1, NULL, NULL, NULL));
    if (file1 != NULL) {
        fclose(file1);
    }

    ExpectNull(sk = wolfSSL_CertManagerGetCerts(NULL));
    ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
    ExpectNull(sk = wolfSSL_CertManagerGetCerts(cm));

    ExpectNotNull(der = wolfSSL_X509_get_der(cert1, &derSz));
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
    /* Check that ASN_SELF_SIGNED_E is returned for a self-signed cert for QT
     * and full OpenSSL compatibility */
    ExpectIntEQ(ret = wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E));
#else
    ExpectIntEQ(ret = wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
#endif

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCA(cm,
                "./certs/ca-cert.pem", NULL));

    ExpectNotNull(sk = wolfSSL_CertManagerGetCerts(cm));

    for (i = 0; EXPECT_SUCCESS() && i < sk_X509_num(sk); i++) {
        ExpectNotNull(x509 = sk_X509_value(sk, i));
        ExpectIntEQ(0, wolfSSL_X509_cmp(x509, cert1));

#ifdef DEBUG_WOLFSSL_VERBOSE
        bio = BIO_new(wolfSSL_BIO_s_file());
        if (bio != NULL) {
            BIO_set_fp(bio, stderr, BIO_NOCLOSE);
            X509_print(bio, x509);
            BIO_free(bio);
        }
#endif /* DEBUG_WOLFSSL_VERBOSE */
    }
    wolfSSL_X509_free(cert1);
    sk_X509_pop_free(sk, NULL);
    wolfSSL_CertManagerFree(cm);
#endif /* defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
          !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \
          defined(WOLFSSL_SIGNER_DER_CERT) */

    return EXPECT_RESULT();
}

static int test_wolfSSL_CertManagerSetVerify(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH))
    WOLFSSL_CERT_MANAGER* cm = NULL;
    int tmp = myVerifyAction;
    const char* ca_cert = "./certs/ca-cert.pem";
    const char* expiredCert = "./certs/test/expired/expired-cert.pem";

    wolfSSL_CertManagerSetVerify(NULL, NULL);
    wolfSSL_CertManagerSetVerify(NULL, myVerify);

    ExpectNotNull(cm = wolfSSL_CertManagerNew());

    wolfSSL_CertManagerSetVerify(cm, myVerify);

#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
    ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL), -1);
#else
    ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL),
                WOLFSSL_SUCCESS);
#endif
    /* Use the test CB that always accepts certs */
    myVerifyAction = VERIFY_OVERRIDE_ERROR;

    ExpectIntEQ(wolfSSL_CertManagerVerify(cm, expiredCert,
        WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

#ifdef WOLFSSL_ALWAYS_VERIFY_CB
    {
        const char* verifyCert = "./certs/server-cert.der";
        /* Use the test CB that always fails certs */
        myVerifyAction = VERIFY_FORCE_FAIL;

        ExpectIntEQ(wolfSSL_CertManagerVerify(cm, verifyCert,
            WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(VERIFY_CERT_ERROR));
    }
#endif

    wolfSSL_CertManagerFree(cm);
    myVerifyAction = tmp;
#endif

    return EXPECT_RESULT();
}

#if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
    defined(DEBUG_UNIT_TEST_CERTS)
/* Used when debugging name constraint tests. Not static to allow use in
 * multiple locations with complex define guards. */
void DEBUG_WRITE_CERT_X509(WOLFSSL_X509* x509, const char* fileName)
{
    BIO* out = BIO_new_file(fileName, "wb");
    if (out != NULL) {
        PEM_write_bio_X509(out, x509);
        BIO_free(out);
    }
}
void DEBUG_WRITE_DER(const byte* der, int derSz, const char* fileName)
{
    BIO* out = BIO_new_file(fileName, "wb");
    if (out != NULL) {
        BIO_write(out, der, derSz);
        BIO_free(out);
    }
}
#else
#define DEBUG_WRITE_CERT_X509(x509, fileName) WC_DO_NOTHING
#define DEBUG_WRITE_DER(der, derSz, fileName) WC_DO_NOTHING
#endif


static int test_wolfSSL_CertManagerNameConstraint(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA) && \
    defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN) && \
    defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_ALT_NAMES) && \
    !defined(NO_SHA256)
    WOLFSSL_CERT_MANAGER* cm = NULL;
    WOLFSSL_EVP_PKEY *priv = NULL;
    WOLFSSL_X509_NAME* name = NULL;
    const char* ca_cert = "./certs/test/cert-ext-nc.der";
    const char* server_cert = "./certs/test/server-goodcn.pem";
    int i = 0;
    static const byte extNameConsOid[] = {85, 29, 30};

    RsaKey  key;
    WC_RNG  rng;
    byte    *der = NULL;
    int     derSz = 0;
    word32  idx = 0;
    byte    *pt;
    WOLFSSL_X509 *x509 = NULL;
    WOLFSSL_X509 *ca = NULL;

    wc_InitRng(&rng);

    /* load in CA private key for signing */
    ExpectIntEQ(wc_InitRsaKey_ex(&key, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_RsaPrivateKeyDecode(server_key_der_2048, &idx, &key,
                sizeof_server_key_der_2048), 0);

    /* get ca certificate then alter it */
    ExpectNotNull(der =
            (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(ca_cert,
                WOLFSSL_FILETYPE_ASN1));
    ExpectNotNull(pt = (byte*)wolfSSL_X509_get_tbs(x509, &derSz));
    if (EXPECT_SUCCESS() && (der != NULL)) {
        XMEMCPY(der, pt, derSz);

        /* find the name constraint extension and alter it */
        pt = der;
        for (i = 0; i < derSz - 3; i++) {
            if (XMEMCMP(pt, extNameConsOid, 3) == 0) {
                pt += 3;
                break;
            }
            pt++;
        }
        ExpectIntNE(i, derSz - 3); /* did not find OID if this case is hit */

        /* go to the length value and set it to 0 */
        while (i < derSz && *pt != 0x81) {
            pt++;
            i++;
        }
        ExpectIntNE(i, derSz); /* did not place to alter */
        pt++;
        *pt = 0x00;
    }

    /* resign the altered certificate */
    ExpectIntGT((derSz = wc_SignCert(derSz, CTC_SHA256wRSA, der,
                             FOURK_BUF, &key, NULL, &rng)), 0);

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));
    wolfSSL_CertManagerFree(cm);

    XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    wolfSSL_X509_free(x509);
    wc_FreeRsaKey(&key);
    wc_FreeRng(&rng);

    /* add email alt name to satisfy constraint */
    pt = (byte*)server_key_der_2048;
    ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
                (const unsigned char**)&pt, sizeof_server_key_der_2048));

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectNotNull(ca = wolfSSL_X509_load_certificate_file(ca_cert,
                WOLFSSL_FILETYPE_ASN1));

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(ca, &derSz)));
    DEBUG_WRITE_DER(der, derSz, "ca.der");

    ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* Good cert test with proper alt email name */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
                    (byte*)"support@info.wolfssl.com", 24, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "wolfssl@info.wolfssl.com", ASN_RFC822_TYPE);

    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "good-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    wolfSSL_X509_free(x509);
    x509 = NULL;


    /* Cert with bad alt name list */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
                    (byte*)"support@info.wolfssl.com", 24, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);

    wolfSSL_X509_add_altname(x509, "wolfssl@info.com", ASN_RFC822_TYPE);
    wolfSSL_X509_add_altname(x509, "wolfssl@info.wolfssl.com", ASN_RFC822_TYPE);

    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "bad-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));

    wolfSSL_CertManagerFree(cm);
    wolfSSL_X509_free(x509);
    wolfSSL_X509_free(ca);
    wolfSSL_EVP_PKEY_free(priv);
#endif

    return EXPECT_RESULT();
}


static int test_wolfSSL_CertManagerNameConstraint2(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA) && \
    defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN) && \
    defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_ALT_NAMES)
    const char* ca_cert  = "./certs/test/cert-ext-ndir.der";
    const char* ca_cert2 = "./certs/test/cert-ext-ndir-exc.der";
    const char* server_cert = "./certs/server-cert.pem";
    WOLFSSL_CERT_MANAGER* cm = NULL;
    WOLFSSL_X509 *x509 = NULL;
    WOLFSSL_X509 *ca = NULL;

    const unsigned char *der = NULL;
    const unsigned char *pt;
    WOLFSSL_EVP_PKEY *priv = NULL;
    WOLFSSL_X509_NAME* name = NULL;
    int   derSz = 0;

    /* C=US*/
    char altName[] = {
        0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09,
        0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53
    };

    /* C=ID */
    char altNameFail[] = {
        0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09,
        0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x44
    };

    /* C=US ST=California*/
    char altNameExc[] = {
        0x30, 0x22,
        0x31, 0x0B,
        0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
        0x31, 0x13,
        0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A,
        0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61
    };
    /* load in CA private key for signing */
    pt = ca_key_der_2048;
    ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, &pt,
                                                sizeof_ca_key_der_2048));

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectNotNull(ca = wolfSSL_X509_load_certificate_file(ca_cert,
                WOLFSSL_FILETYPE_ASN1));
    ExpectNotNull((der = wolfSSL_X509_get_der(ca, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
    wolfSSL_X509_sign(x509, priv, EVP_sha3_256());
#else
    wolfSSL_X509_sign(x509, priv, EVP_sha256());
#endif
    ExpectNotNull((der = wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* add in matching DIR alt name and resign */
    wolfSSL_X509_add_altname_ex(x509, altName, sizeof(altName), ASN_DIR_TYPE);
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
    wolfSSL_X509_sign(x509, priv, EVP_sha3_256());
#else
    wolfSSL_X509_sign(x509, priv, EVP_sha256());
#endif

    ExpectNotNull((der = wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* check verify fail */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);

    /* add in miss matching DIR alt name and resign */
    wolfSSL_X509_add_altname_ex(x509, altNameFail, sizeof(altNameFail),
            ASN_DIR_TYPE);

#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
    wolfSSL_X509_sign(x509, priv, EVP_sha3_256());
#else
    wolfSSL_X509_sign(x509, priv, EVP_sha256());
#endif
    ExpectNotNull((der = wolfSSL_X509_get_der(x509, &derSz)));
#ifndef WOLFSSL_NO_ASN_STRICT
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
#else
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif

    /* check that it still fails if one bad altname and one good altname is in
     * the certificate */
    wolfSSL_X509_free(x509);
    x509 = NULL;
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    wolfSSL_X509_add_altname_ex(x509, altName, sizeof(altName), ASN_DIR_TYPE);
    wolfSSL_X509_add_altname_ex(x509, altNameFail, sizeof(altNameFail),
            ASN_DIR_TYPE);

#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
    wolfSSL_X509_sign(x509, priv, EVP_sha3_256());
#else
    wolfSSL_X509_sign(x509, priv, EVP_sha256());
#endif
    ExpectNotNull((der = wolfSSL_X509_get_der(x509, &derSz)));
#ifndef WOLFSSL_NO_ASN_STRICT
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
#else
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif

    /* check it fails with switching position of bad altname */
    wolfSSL_X509_free(x509);
    x509 = NULL;
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    wolfSSL_X509_add_altname_ex(x509, altNameFail, sizeof(altNameFail),
            ASN_DIR_TYPE);
    wolfSSL_X509_add_altname_ex(x509, altName, sizeof(altName), ASN_DIR_TYPE);

#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
    wolfSSL_X509_sign(x509, priv, EVP_sha3_256());
#else
    wolfSSL_X509_sign(x509, priv, EVP_sha256());
#endif
    ExpectNotNull((der = wolfSSL_X509_get_der(x509, &derSz)));
#ifndef WOLFSSL_NO_ASN_STRICT
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
#else
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif
    wolfSSL_CertManagerFree(cm);

    wolfSSL_X509_free(x509);
    x509 = NULL;
    wolfSSL_X509_free(ca);
    ca = NULL;

    /* now test with excluded name constraint */
    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectNotNull(ca = wolfSSL_X509_load_certificate_file(ca_cert2,
                WOLFSSL_FILETYPE_ASN1));
    ExpectNotNull((der = wolfSSL_X509_get_der(ca, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    wolfSSL_X509_add_altname_ex(x509, altNameExc, sizeof(altNameExc),
            ASN_DIR_TYPE);
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);

#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
    wolfSSL_X509_sign(x509, priv, EVP_sha3_256());
#else
    wolfSSL_X509_sign(x509, priv, EVP_sha256());
#endif
    ExpectNotNull((der = wolfSSL_X509_get_der(x509, &derSz)));
#ifndef WOLFSSL_NO_ASN_STRICT
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
#else
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif
    wolfSSL_CertManagerFree(cm);
    wolfSSL_X509_free(x509);
    wolfSSL_X509_free(ca);
    wolfSSL_EVP_PKEY_free(priv);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CertManagerNameConstraint3(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA) && \
    defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN) && \
    defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_ALT_NAMES) && \
    !defined(NO_SHA256)
    WOLFSSL_CERT_MANAGER* cm = NULL;
    WOLFSSL_EVP_PKEY *priv = NULL;
    WOLFSSL_X509_NAME* name = NULL;
    const char* ca_cert = "./certs/test/cert-ext-mnc.der";
    const char* server_cert = "./certs/test/server-goodcn.pem";

    byte    *der = NULL;
    int     derSz = 0;
    byte    *pt;
    WOLFSSL_X509 *x509 = NULL;
    WOLFSSL_X509 *ca = NULL;

    pt = (byte*)server_key_der_2048;
    ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
                (const unsigned char**)&pt, sizeof_server_key_der_2048));

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectNotNull(ca = wolfSSL_X509_load_certificate_file(ca_cert,
                WOLFSSL_FILETYPE_ASN1));
    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(ca, &derSz)));
    DEBUG_WRITE_DER(der, derSz, "ca.der");

    ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* check satisfying .wolfssl.com constraint passes */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
                    (byte*)"support@info.wolfssl.com", 24, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "wolfssl@info.wolfssl.com", ASN_RFC822_TYPE);

    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "good-1st-constraint-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* check satisfying .random.com constraint passes */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
                    (byte*)"support@info.example.com", 24, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "wolfssl@info.example.com", ASN_RFC822_TYPE);

    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "good-2nd-constraint-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* check fail case when neither constraint is matched */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
                     (byte*)"support@info.com", 16, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);

    wolfSSL_X509_add_altname(x509, "wolfssl@info.com", ASN_RFC822_TYPE);

    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "bad-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));

    wolfSSL_CertManagerFree(cm);
    wolfSSL_X509_free(x509);
    wolfSSL_X509_free(ca);
    wolfSSL_EVP_PKEY_free(priv);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CertManagerNameConstraint4(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA) && \
    defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN) && \
    defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_ALT_NAMES) && \
    !defined(NO_SHA256)
    WOLFSSL_CERT_MANAGER* cm = NULL;
    WOLFSSL_EVP_PKEY *priv = NULL;
    WOLFSSL_X509_NAME* name = NULL;
    const char* ca_cert = "./certs/test/cert-ext-ncdns.der";
    const char* server_cert = "./certs/test/server-goodcn.pem";

    byte    *der = NULL;
    int     derSz;
    byte    *pt;
    WOLFSSL_X509 *x509 = NULL;
    WOLFSSL_X509 *ca = NULL;

    pt = (byte*)server_key_der_2048;
    ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
                (const unsigned char**)&pt, sizeof_server_key_der_2048));

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectNotNull(ca = wolfSSL_X509_load_certificate_file(ca_cert,
                WOLFSSL_FILETYPE_ASN1));
    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(ca, &derSz)));
    DEBUG_WRITE_DER(der, derSz, "ca.der");

    ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* check satisfying wolfssl.com constraint passes */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "www.wolfssl.com", ASN_DNS_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "good-1st-constraint-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* check satisfying example.com constraint passes */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"example.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "www.example.com", ASN_DNS_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "good-2nd-constraint-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* check satisfying wolfssl.com constraint passes with list of DNS's */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "www.wolfssl.com", ASN_DNS_TYPE);
    wolfSSL_X509_add_altname(x509, "www.info.wolfssl.com", ASN_DNS_TYPE);
    wolfSSL_X509_add_altname(x509, "extra.wolfssl.com", ASN_DNS_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "good-multiple-constraint-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* check fail when one DNS in the list is bad */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "www.wolfssl.com", ASN_DNS_TYPE);
    wolfSSL_X509_add_altname(x509, "www.nomatch.com", ASN_DNS_TYPE);
    wolfSSL_X509_add_altname(x509, "www.info.wolfssl.com", ASN_DNS_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "bad-multiple-constraint-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* check fail case when neither constraint is matched */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"common", 6, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);

    wolfSSL_X509_add_altname(x509, "www.random.com", ASN_DNS_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "bad-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));

    wolfSSL_CertManagerFree(cm);
    wolfSSL_X509_free(x509);
    wolfSSL_X509_free(ca);
    wolfSSL_EVP_PKEY_free(priv);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CertManagerNameConstraint5(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA) && \
    defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN) && \
    defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_ALT_NAMES) && \
    !defined(NO_SHA256)
    WOLFSSL_CERT_MANAGER* cm = NULL;
    WOLFSSL_EVP_PKEY *priv = NULL;
    WOLFSSL_X509_NAME* name = NULL;
    const char* ca_cert = "./certs/test/cert-ext-ncmixed.der";
    const char* server_cert = "./certs/test/server-goodcn.pem";

    byte    *der = NULL;
    int     derSz;
    byte    *pt;
    WOLFSSL_X509 *x509 = NULL;
    WOLFSSL_X509 *ca = NULL;

    pt = (byte*)server_key_der_2048;
    ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
                (const unsigned char**)&pt, sizeof_server_key_der_2048));

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectNotNull(ca = wolfSSL_X509_load_certificate_file(ca_cert,
                WOLFSSL_FILETYPE_ASN1));
    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(ca, &derSz)));
    DEBUG_WRITE_DER(der, derSz, "ca.der");

    ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* check satisfying wolfssl.com constraint passes */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"example", 7, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "good.example", ASN_DNS_TYPE);
    wolfSSL_X509_add_altname(x509, "facts@into.wolfssl.com", ASN_RFC822_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "good-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* fail with DNS check because of common name */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "example", ASN_DNS_TYPE);
    wolfSSL_X509_add_altname(x509, "facts@wolfssl.com", ASN_RFC822_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "bad-cn-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* fail on permitted DNS name constraint */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "www.example", ASN_DNS_TYPE);
    wolfSSL_X509_add_altname(x509, "www.wolfssl", ASN_DNS_TYPE);
    wolfSSL_X509_add_altname(x509, "info@wolfssl.com", ASN_RFC822_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "bad-1st-constraint-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* fail on permitted email name constraint */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;

    wolfSSL_X509_add_altname(x509, "example", ASN_DNS_TYPE);
    wolfSSL_X509_add_altname(x509, "info@wolfssl.com", ASN_RFC822_TYPE);
    wolfSSL_X509_add_altname(x509, "info@example.com", ASN_RFC822_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "bad-2nd-constraint-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* success with empty email name */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert,
                WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
    name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
    X509_NAME_free(name);

    wolfSSL_X509_add_altname(x509, "example", ASN_DNS_TYPE);
    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    DEBUG_WRITE_CERT_X509(x509, "good-missing-constraint-cert.pem");

    ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz)));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    wolfSSL_X509_free(x509);

    wolfSSL_CertManagerFree(cm);
    wolfSSL_X509_free(ca);
    wolfSSL_EVP_PKEY_free(priv);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CertManagerCRL(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(HAVE_CRL) && \
    !defined(NO_RSA)
    const char* ca_cert = "./certs/ca-cert.pem";
    const char* crl1     = "./certs/crl/crl.pem";
    const char* crl2     = "./certs/crl/crl2.pem";
#ifdef WC_RSA_PSS
    const char* crl_rsapss = "./certs/crl/crl_rsapss.pem";
    const char* ca_rsapss  = "./certs/rsapss/ca-rsapss.pem";
#endif
    const unsigned char crl_buff[] = {
        0x30, 0x82, 0x02, 0x04, 0x30, 0x81, 0xed, 0x02,
        0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
        0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
        0x00, 0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09,
        0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
        0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
        0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, 0x6e, 0x74,
        0x61, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06,
        0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f,
        0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, 0x11, 0x30,
        0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08,
        0x53, 0x61, 0x77, 0x74, 0x6f, 0x6f, 0x74, 0x68,
        0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
        0x0b, 0x0c, 0x0a, 0x43, 0x6f, 0x6e, 0x73, 0x75,
        0x6c, 0x74, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30,
        0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f,
        0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66,
        0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x31,
        0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48,
        0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10,
        0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c,
        0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d,
        0x17, 0x0d, 0x32, 0x32, 0x31, 0x32, 0x31, 0x36,
        0x32, 0x31, 0x31, 0x37, 0x35, 0x30, 0x5a, 0x17,
        0x0d, 0x32, 0x35, 0x30, 0x39, 0x31, 0x31, 0x32,
        0x31, 0x31, 0x37, 0x35, 0x30, 0x5a, 0x30, 0x14,
        0x30, 0x12, 0x02, 0x01, 0x02, 0x17, 0x0d, 0x32,
        0x32, 0x31, 0x32, 0x31, 0x36, 0x32, 0x31, 0x31,
        0x37, 0x35, 0x30, 0x5a, 0xa0, 0x0e, 0x30, 0x0c,
        0x30, 0x0a, 0x06, 0x03, 0x55, 0x1d, 0x14, 0x04,
        0x03, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09,
        0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
        0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
        0x39, 0x44, 0xff, 0x39, 0xf4, 0x04, 0x45, 0x79,
        0x7e, 0x73, 0xe2, 0x42, 0x48, 0xdb, 0x85, 0x66,
        0xfd, 0x99, 0x76, 0x94, 0x7c, 0xb5, 0x79, 0x5d,
        0x15, 0x71, 0x36, 0xa9, 0x87, 0xf0, 0x73, 0x05,
        0x50, 0x08, 0x6b, 0x1c, 0x6e, 0xde, 0x96, 0x45,
        0x31, 0xc3, 0xc0, 0xba, 0xba, 0xf5, 0x08, 0x1d,
        0x05, 0x4a, 0x52, 0x39, 0xe9, 0x03, 0xef, 0x59,
        0xc8, 0x1d, 0x4a, 0xf2, 0x86, 0x05, 0x99, 0x7b,
        0x4b, 0x74, 0xf6, 0xd3, 0x75, 0x8d, 0xb2, 0x57,
        0xba, 0xac, 0xa7, 0x11, 0x14, 0xd6, 0x6c, 0x71,
        0xc4, 0x4c, 0x1c, 0x68, 0xbc, 0x49, 0x78, 0xf0,
        0xc9, 0x52, 0x8a, 0xe7, 0x8b, 0x54, 0xe6, 0x20,
        0x58, 0x20, 0x60, 0x66, 0xf5, 0x14, 0xd8, 0xcb,
        0xff, 0xe0, 0xa0, 0x45, 0xbc, 0xb4, 0x81, 0xad,
        0x1d, 0xbc, 0xcf, 0xf8, 0x8e, 0xa8, 0x87, 0x24,
        0x55, 0x99, 0xd9, 0xce, 0x47, 0xf7, 0x5b, 0x4a,
        0x33, 0x6d, 0xdb, 0xbf, 0x93, 0x64, 0x1a, 0xa6,
        0x46, 0x5f, 0x27, 0xdc, 0xd8, 0xd4, 0xf9, 0xc2,
        0x42, 0x2a, 0x7e, 0xb2, 0x7c, 0xdd, 0x98, 0x77,
        0xf5, 0x88, 0x7d, 0x15, 0x25, 0x08, 0xbc, 0xe0,
        0xd0, 0x8d, 0xf4, 0xc3, 0xc3, 0x04, 0x41, 0xa4,
        0xd1, 0xb1, 0x39, 0x4a, 0x6b, 0x2c, 0xb5, 0x2e,
        0x9a, 0x65, 0x43, 0x0d, 0x0e, 0x73, 0xf4, 0x06,
        0xe1, 0xb3, 0x49, 0x34, 0x94, 0xb0, 0xb7, 0xff,
        0xc0, 0x27, 0xc1, 0xb5, 0xea, 0x06, 0xf7, 0x71,
        0x71, 0x97, 0xbb, 0xbc, 0xc7, 0x1a, 0x9f, 0xeb,
        0xf6, 0x3d, 0xa5, 0x7b, 0x55, 0xa7, 0xbf, 0xdd,
        0xd7, 0xee, 0x97, 0xb8, 0x9d, 0xdc, 0xcd, 0xe3,
        0x06, 0xdb, 0x9a, 0x2c, 0x60, 0xbf, 0x70, 0x84,
        0xfa, 0x6b, 0x8d, 0x70, 0x7d, 0xde, 0xe8, 0xb7,
        0xab, 0xb0, 0x38, 0x68, 0x6c, 0xc0, 0xb1, 0xe1,
        0xba, 0x45, 0xe0, 0xd7, 0x12, 0x3d, 0x71, 0x5b
    };

    WOLFSSL_CERT_MANAGER* cm = NULL;

    ExpectNotNull(cm = wolfSSL_CertManagerNew());

    ExpectIntEQ(wolfSSL_CertManagerEnableCRL(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECKALL), 1);
    ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK), 1);
    ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm,
        WOLFSSL_CRL_CHECK | WOLFSSL_CRL_CHECKALL), 1);
    ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, 16), 1);
    ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECKALL), 1);

    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(NULL, NULL, -1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, NULL, -1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(NULL, server_cert_der_2048, -1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(NULL, server_cert_der_2048, 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, server_cert_der_2048, -1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, server_cert_der_2048,
        sizeof_server_cert_der_2048), WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));

    ExpectIntEQ(wolfSSL_CertManagerSetCRL_Cb(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerSetCRL_Cb(cm, NULL), 1);
#ifdef HAVE_CRL_IO
    ExpectIntEQ(wolfSSL_CertManagerSetCRL_IOCb(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerSetCRL_IOCb(cm, NULL), 1);
#endif

#ifndef NO_FILESYSTEM
    ExpectIntEQ(wolfSSL_CertManagerLoadCRL(NULL, NULL, WOLFSSL_FILETYPE_ASN1,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerLoadCRL(cm, NULL, WOLFSSL_FILETYPE_ASN1,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* -1 seen as !WOLFSSL_FILETYPE_PEM */
    ExpectIntEQ(wolfSSL_CertManagerLoadCRL(cm, "./certs/crl", -1, 0), 1);

    ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(NULL, NULL,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, NULL, WOLFSSL_FILETYPE_ASN1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* -1 seen as !WOLFSSL_FILETYPE_PEM */
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, "./certs/crl/crl.pem", -1),
        WC_NO_ERR_TRACE(ASN_PARSE_E));
#endif

    ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(NULL, NULL, -1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(cm, NULL, -1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(NULL, crl_buff, -1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(NULL, NULL, 1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(NULL, crl_buff, 1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(cm, NULL, 1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(cm, crl_buff, -1,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_CertManagerFreeCRL(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    DoExpectIntEQ(wolfSSL_CertManagerFreeCRL(cm), 1);

    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL));
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CertManagerLoadCRL(cm, crl1, WOLFSSL_FILETYPE_PEM, 0));
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CertManagerLoadCRL(cm, crl2, WOLFSSL_FILETYPE_PEM, 0));
    wolfSSL_CertManagerFreeCRL(cm);

#ifndef WOLFSSL_CRL_ALLOW_MISSING_CDP
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CertManagerLoadCRL(cm, crl1, WOLFSSL_FILETYPE_PEM, 0));
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL));
    ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, server_cert_der_2048,
        sizeof_server_cert_der_2048), WC_NO_ERR_TRACE(CRL_MISSING));
    ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, server_cert_der_2048,
        sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(CRL_MISSING));
#endif /* !WOLFSSL_CRL_ALLOW_MISSING_CDP */

    ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(cm, crl_buff, sizeof(crl_buff),
        WOLFSSL_FILETYPE_ASN1), 1);

#if !defined(NO_FILESYSTEM) && defined(WC_RSA_PSS)
    /* loading should fail without the CA set */
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, crl_rsapss,
        WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(ASN_CRL_NO_SIGNER_E));

    /* now successfully load the RSA-PSS crl once loading in it's CA */
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CertManagerLoadCA(cm, ca_rsapss, NULL));
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, crl_rsapss,
        WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif

    wolfSSL_CertManagerFree(cm);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CertManagerCheckOCSPResponse(void)
{
    EXPECT_DECLS;
#if defined(HAVE_OCSP) && !defined(NO_RSA) && !defined(NO_SHA)
/* Need one of these for wolfSSL_OCSP_REQUEST_new. */
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
    defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_APACHE_HTTPD) || \
    defined(HAVE_LIGHTY)
    WOLFSSL_CERT_MANAGER* cm = NULL;
    /* Raw OCSP response bytes captured using the following setup:
     * - Run responder with
     *      openssl ocsp -port 9999 -ndays 9999
     *      -index certs/ocsp/index-intermediate1-ca-issued-certs.txt
     *      -rsigner certs/ocsp/ocsp-responder-cert.pem
     *      -rkey certs/ocsp/ocsp-responder-key.pem
     *      -CA certs/ocsp/intermediate1-ca-cert.pem
     * - Run client with
     *      openssl ocsp -host 127.0.0.1:9999 -respout resp.out
     *      -issuer certs/ocsp/intermediate1-ca-cert.pem
     *      -cert certs/ocsp/server1-cert.pem
     *      -CAfile certs/ocsp/root-ca-cert.pem -noverify
     * - Select the response packet in Wireshark, and export it using
     *   "File->Export Packet Dissection->As "C" Arrays".  Select "Selected
     *   packets only".  After importing into the editor, remove the initial
     *   ~148 bytes of header, ending with the Content-Length and the \r\n\r\n.
     */
    static const byte response[] = {
        0x30, 0x82, 0x07, 0x40, /* ....0..@ */
        0x0a, 0x01, 0x00, 0xa0, 0x82, 0x07, 0x39, 0x30, /* ......90 */
        0x82, 0x07, 0x35, 0x06, 0x09, 0x2b, 0x06, 0x01, /* ..5..+.. */
        0x05, 0x05, 0x07, 0x30, 0x01, 0x01, 0x04, 0x82, /* ...0.... */
        0x07, 0x26, 0x30, 0x82, 0x07, 0x22, 0x30, 0x82, /* .&0.."0. */
        0x01, 0x40, 0xa1, 0x81, 0xa1, 0x30, 0x81, 0x9e, /* .@...0.. */
        0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, /* 1.0...U. */
        0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, /* ...US1.0 */
        0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, /* ...U.... */
        0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, /* Washingt */
        0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, /* on1.0... */
        0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, /* U....Sea */
        0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, /* ttle1.0. */
        0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, /* ..U....w */
        0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, /* olfSSL1. */
        0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, /* 0...U... */
        0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, /* .Enginee */
        0x72, 0x69, 0x6e, 0x67, 0x31, 0x1f, 0x30, 0x1d, /* ring1.0. */
        0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x77, /* ..U....w */
        0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, /* olfSSL O */
        0x43, 0x53, 0x50, 0x20, 0x52, 0x65, 0x73, 0x70, /* CSP Resp */
        0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, 0x1f, 0x30, /* onder1.0 */
        0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, /* ...*.H.. */
        0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, /* ......in */
        0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, /* fo@wolfs */
        0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x18, 0x0f, /* sl.com.. */
        0x32, 0x30, 0x32, 0x33, 0x31, 0x31, 0x30, 0x38, /* 20231108 */
        0x30, 0x30, 0x32, 0x36, 0x33, 0x37, 0x5a, 0x30, /* 002637Z0 */
        0x64, 0x30, 0x62, 0x30, 0x3a, 0x30, 0x09, 0x06, /* d0b0:0.. */
        0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, /* .+...... */
        0x04, 0x14, 0x71, 0x4d, 0x82, 0x23, 0x40, 0x59, /* ..qM.#@Y */
        0xc0, 0x96, 0xa1, 0x37, 0x43, 0xfa, 0x31, 0xdb, /* ...7C.1. */
        0xba, 0xb1, 0x43, 0x18, 0xda, 0x04, 0x04, 0x14, /* ..C..... */
        0x83, 0xc6, 0x3a, 0x89, 0x2c, 0x81, 0xf4, 0x02, /* ..:.,... */
        0xd7, 0x9d, 0x4c, 0xe2, 0x2a, 0xc0, 0x71, 0x82, /* ..L.*.q. */
        0x64, 0x44, 0xda, 0x0e, 0x02, 0x01, 0x05, 0x80, /* dD...... */
        0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x33, 0x31, /* ...20231 */
        0x31, 0x30, 0x38, 0x30, 0x30, 0x32, 0x36, 0x33, /* 10800263 */
        0x37, 0x5a, 0xa0, 0x11, 0x18, 0x0f, 0x32, 0x30, /* 7Z....20 */
        0x35, 0x31, 0x30, 0x33, 0x32, 0x35, 0x30, 0x30, /* 51032500 */
        0x32, 0x36, 0x33, 0x37, 0x5a, 0xa1, 0x23, 0x30, /* 2637Z.#0 */
        0x21, 0x30, 0x1f, 0x06, 0x09, 0x2b, 0x06, 0x01, /* !0...+.. */
        0x05, 0x05, 0x07, 0x30, 0x01, 0x02, 0x04, 0x12, /* ...0.... */
        0x04, 0x10, 0xdb, 0xbc, 0x2a, 0x76, 0xa0, 0xb4, /* ....*v.. */
        0x1e, 0x5d, 0xf6, 0x2b, 0x8e, 0x38, 0x62, 0xdb, /* .].+.8b. */
        0x90, 0xed, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, /* ..0...*. */
        0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, /* H....... */
        0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x87, 0xde, /* ........ */
        0xfb, 0xf9, 0x3a, 0x90, 0x1f, 0x90, 0xde, 0xcf, /* ..:..... */
        0xfe, 0xad, 0x64, 0x19, 0x34, 0x17, 0xf8, 0x15, /* ..d.4... */
        0x01, 0x22, 0x5f, 0x67, 0x41, 0xa4, 0x18, 0xf7, /* ."_gA... */
        0x16, 0xb7, 0xc9, 0xf3, 0xe1, 0x9f, 0xcd, 0x40, /* .......@ */
        0x56, 0x77, 0x6e, 0x6a, 0xfb, 0x92, 0x6a, 0x6f, /* Vwnj..jo */
        0x28, 0x3e, 0x22, 0x48, 0xa1, 0xc2, 0xd8, 0x1d, /* (>"H.... */
        0xc7, 0xe6, 0x78, 0x7f, 0xb6, 0x09, 0xfe, 0x2c, /* ..x...., */
        0xb5, 0xef, 0x29, 0x7c, 0xc5, 0x51, 0x16, 0x7b, /* ..)|.Q.{ */
        0x8f, 0xfb, 0x44, 0xa8, 0xcd, 0xf5, 0x5c, 0x0f, /* ..D...\. */
        0x46, 0x0e, 0xb1, 0xa4, 0xeb, 0x5b, 0xf5, 0x86, /* F....[.. */
        0x11, 0x0f, 0xcd, 0xe2, 0xe5, 0x3c, 0x91, 0x72, /* .....<.r */
        0x0d, 0x6a, 0xcb, 0x95, 0x99, 0x39, 0x91, 0x48, /* .j...9.H */
        0x65, 0x97, 0xb9, 0x78, 0xb5, 0x88, 0x7f, 0x76, /* e..x...v */
        0xa1, 0x43, 0x2f, 0xf6, 0x1f, 0x49, 0xb7, 0x08, /* .C/..I.. */
        0x36, 0xe4, 0x2e, 0x34, 0x25, 0xda, 0x16, 0x74, /* 6..4%..t */
        0x47, 0x62, 0x56, 0xff, 0x2f, 0x02, 0x03, 0x44, /* GbV./..D */
        0x89, 0x04, 0xe7, 0xb8, 0xde, 0x0a, 0x35, 0x43, /* ......5C */
        0xae, 0xd7, 0x54, 0xbe, 0xc3, 0x7c, 0x95, 0xa5, /* ..T..|.. */
        0xc8, 0xe0, 0x2e, 0x52, 0xb6, 0xea, 0x99, 0x45, /* ...R...E */
        0xfd, 0xda, 0x4b, 0xd5, 0x79, 0x07, 0x64, 0xca, /* ..K.y.d. */
        0x64, 0xba, 0x52, 0x12, 0x62, 0x8c, 0x08, 0x9a, /* d.R.b... */
        0x32, 0xeb, 0x85, 0x65, 0x05, 0x39, 0x07, 0x5d, /* 2..e.9.] */
        0x39, 0x4a, 0xcf, 0xa5, 0x30, 0xf6, 0xd1, 0xf7, /* 9J..0... */
        0x29, 0xaa, 0x23, 0x42, 0xc6, 0x85, 0x16, 0x7f, /* ).#B.... */
        0x64, 0x16, 0xb1, 0xb0, 0x5d, 0xcd, 0x88, 0x2d, /* d...]..- */
        0x06, 0xb0, 0xa9, 0xdf, 0xa3, 0x9f, 0x25, 0x41, /* ......%A */
        0x89, 0x9a, 0x19, 0xe1, 0xaa, 0xcd, 0xdf, 0x51, /* .......Q */
        0xcb, 0xa9, 0xc3, 0x7e, 0x27, 0xbc, 0x7d, 0x9b, /* ...~'.}. */
        0x6f, 0x4d, 0x79, 0x87, 0x09, 0x3f, 0xac, 0xd2, /* oMy..?.. */
        0x4a, 0x3b, 0xbe, 0xf8, 0x7a, 0xa4, 0x93, 0x45, /* J;..z..E */
        0x11, 0x64, 0x40, 0xc5, 0x03, 0xc9, 0x24, 0x5b, /* .d@...$[ */
        0xe9, 0x6d, 0xfc, 0x94, 0x08, 0xbe, 0xa0, 0x82, /* .m...... */
        0x04, 0xc6, 0x30, 0x82, 0x04, 0xc2, 0x30, 0x82, /* ..0...0. */
        0x04, 0xbe, 0x30, 0x82, 0x03, 0xa6, 0xa0, 0x03, /* ..0..... */
        0x02, 0x01, 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, /* ......0. */
        0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, /* ..*.H... */
        0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x97, /* .....0.. */
        0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, /* 1.0...U. */
        0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, /* ...US1.0 */
        0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, /* ...U.... */
        0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, /* Washingt */
        0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, /* on1.0... */
        0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, /* U....Sea */
        0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, /* ttle1.0. */
        0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, /* ..U....w */
        0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, /* olfSSL1. */
        0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, /* 0...U... */
        0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, /* .Enginee */
        0x72, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, 0x16, /* ring1.0. */
        0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, /* ..U....w */
        0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x72, /* olfSSL r */
        0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f, /* oot CA1. */
        0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, /* 0...*.H. */
        0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, /* .......i */
        0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, /* nfo@wolf */
        0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, /* ssl.com0 */
        0x1e, 0x17, 0x0d, 0x32, 0x32, 0x31, 0x32, 0x31, /* ...22121 */
        0x36, 0x32, 0x31, 0x31, 0x37, 0x35, 0x30, 0x5a, /* 6211750Z */
        0x17, 0x0d, 0x32, 0x35, 0x30, 0x39, 0x31, 0x31, /* ..250911 */
        0x32, 0x31, 0x31, 0x37, 0x35, 0x30, 0x5a, 0x30, /* 211750Z0 */
        0x81, 0x9e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, /* ..1.0... */
        0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, /* U....US1 */
        0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, /* .0...U.. */
        0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, /* ..Washin */
        0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, /* gton1.0. */
        0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, /* ..U....S */
        0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, /* eattle1. */
        0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, /* 0...U... */
        0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, /* .wolfSSL */
        0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, /* 1.0...U. */
        0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, /* ...Engin */
        0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x1f, /* eering1. */
        0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, /* 0...U... */
        0x16, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, /* .wolfSSL */
        0x20, 0x4f, 0x43, 0x53, 0x50, 0x20, 0x52, 0x65, /*  OCSP Re */
        0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, /* sponder1 */
        0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, /* .0...*.H */
        0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, /* ........ */
        0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, /* info@wol */
        0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, /* fssl.com */
        0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, /* 0.."0... */
        0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, /* *.H..... */
        0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, /* ........ */
        0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, /* 0....... */
        0x00, 0xb8, 0xba, 0x23, 0xb4, 0xf6, 0xc3, 0x7b, /* ...#...{ */
        0x14, 0xc3, 0xa4, 0xf5, 0x1d, 0x61, 0xa1, 0xf5, /* .....a.. */
        0x1e, 0x63, 0xb9, 0x85, 0x23, 0x34, 0x50, 0x6d, /* .c..#4Pm */
        0xf8, 0x7c, 0xa2, 0x8a, 0x04, 0x8b, 0xd5, 0x75, /* .|.....u */
        0x5c, 0x2d, 0xf7, 0x63, 0x88, 0xd1, 0x07, 0x7a, /* \-.c...z */
        0xea, 0x0b, 0x45, 0x35, 0x2b, 0xeb, 0x1f, 0xb1, /* ..E5+... */
        0x22, 0xb4, 0x94, 0x41, 0x38, 0xe2, 0x9d, 0x74, /* "..A8..t */
        0xd6, 0x8b, 0x30, 0x22, 0x10, 0x51, 0xc5, 0xdb, /* ..0".Q.. */
        0xca, 0x3f, 0x46, 0x2b, 0xfe, 0xe5, 0x5a, 0x3f, /* .?F+..Z? */
        0x41, 0x74, 0x67, 0x75, 0x95, 0xa9, 0x94, 0xd5, /* Atgu.... */
        0xc3, 0xee, 0x42, 0xf8, 0x8d, 0xeb, 0x92, 0x95, /* ..B..... */
        0xe1, 0xd9, 0x65, 0xb7, 0x43, 0xc4, 0x18, 0xde, /* ..e.C... */
        0x16, 0x80, 0x90, 0xce, 0x24, 0x35, 0x21, 0xc4, /* ....$5!. */
        0x55, 0xac, 0x5a, 0x51, 0xe0, 0x2e, 0x2d, 0xb3, /* U.ZQ..-. */
        0x0a, 0x5a, 0x4f, 0x4a, 0x73, 0x31, 0x50, 0xee, /* .ZOJs1P. */
        0x4a, 0x16, 0xbd, 0x39, 0x8b, 0xad, 0x05, 0x48, /* J..9...H */
        0x87, 0xb1, 0x99, 0xe2, 0x10, 0xa7, 0x06, 0x72, /* .......r */
        0x67, 0xca, 0x5c, 0xd1, 0x97, 0xbd, 0xc8, 0xf1, /* g.\..... */
        0x76, 0xf8, 0xe0, 0x4a, 0xec, 0xbc, 0x93, 0xf4, /* v..J.... */
        0x66, 0x4c, 0x28, 0x71, 0xd1, 0xd8, 0x66, 0x03, /* fL(q..f. */
        0xb4, 0x90, 0x30, 0xbb, 0x17, 0xb0, 0xfe, 0x97, /* ..0..... */
        0xf5, 0x1e, 0xe8, 0xc7, 0x5d, 0x9b, 0x8b, 0x11, /* ....]... */
        0x19, 0x12, 0x3c, 0xab, 0x82, 0x71, 0x78, 0xff, /* ..<..qx. */
        0xae, 0x3f, 0x32, 0xb2, 0x08, 0x71, 0xb2, 0x1b, /* .?2..q.. */
        0x8c, 0x27, 0xac, 0x11, 0xb8, 0xd8, 0x43, 0x49, /* .'....CI */
        0xcf, 0xb0, 0x70, 0xb1, 0xf0, 0x8c, 0xae, 0xda, /* ..p..... */
        0x24, 0x87, 0x17, 0x3b, 0xd8, 0x04, 0x65, 0x6c, /* $..;..el */
        0x00, 0x76, 0x50, 0xef, 0x15, 0x08, 0xd7, 0xb4, /* .vP..... */
        0x73, 0x68, 0x26, 0x14, 0x87, 0x95, 0xc3, 0x5f, /* sh&...._ */
        0x6e, 0x61, 0xb8, 0x87, 0x84, 0xfa, 0x80, 0x1a, /* na...... */
        0x0a, 0x8b, 0x98, 0xf3, 0xe3, 0xff, 0x4e, 0x44, /* ......ND */
        0x1c, 0x65, 0x74, 0x7c, 0x71, 0x54, 0x65, 0xe5, /* .et|qTe. */
        0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, /* 9....... */
        0x01, 0x0a, 0x30, 0x82, 0x01, 0x06, 0x30, 0x09, /* ..0...0. */
        0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, /* ..U....0 */
        0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, /* .0...U.. */
        0x04, 0x16, 0x04, 0x14, 0x32, 0x67, 0xe1, 0xb1, /* ....2g.. */
        0x79, 0xd2, 0x81, 0xfc, 0x9f, 0x23, 0x0c, 0x70, /* y....#.p */
        0x40, 0x50, 0xb5, 0x46, 0x56, 0xb8, 0x30, 0x36, /* @P.FV.06 */
        0x30, 0x81, 0xc4, 0x06, 0x03, 0x55, 0x1d, 0x23, /* 0....U.# */
        0x04, 0x81, 0xbc, 0x30, 0x81, 0xb9, 0x80, 0x14, /* ...0.... */
        0x73, 0xb0, 0x1c, 0xa4, 0x2f, 0x82, 0xcb, 0xcf, /* s.../... */
        0x47, 0xa5, 0x38, 0xd7, 0xb0, 0x04, 0x82, 0x3a, /* G.8....: */
        0x7e, 0x72, 0x15, 0x21, 0xa1, 0x81, 0x9d, 0xa4, /* ~r.!.... */
        0x81, 0x9a, 0x30, 0x81, 0x97, 0x31, 0x0b, 0x30, /* ..0..1.0 */
        0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, /* ...U.... */
        0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, /* US1.0... */
        0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, /* U....Was */
        0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, /* hington1 */
        0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, /* .0...U.. */
        0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, /* ..Seattl */
        0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, /* e1.0...U */
        0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, /* ....wolf */
        0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, /* SSL1.0.. */
        0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, /* .U....En */
        0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, /* gineerin */
        0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, /* g1.0...U */
        0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, /* ....wolf */
        0x53, 0x53, 0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, /* SSL root */
        0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, 0x1d, 0x06, /*  CA1.0.. */
        0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, /* .*.H.... */
        0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, /* ....info */
        0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, /* @wolfssl */
        0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x01, 0x63, 0x30, /* .com..c0 */
        0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, /* ...U.%.. */
        0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, /* 0...+... */
        0x05, 0x07, 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09, /* ....0... */
        0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, /* *.H..... */
        0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, /* ........ */
        0x2f, 0xb7, 0x6b, 0xec, 0xb7, 0x12, 0x63, 0xb9, /* /.k...c. */
        0x57, 0xdc, 0x04, 0x4d, 0x9c, 0x67, 0x74, 0x98, /* W..M.gt. */
        0x06, 0x28, 0x68, 0x37, 0x34, 0xc2, 0x50, 0xe9, /* .(h74.P. */
        0x2a, 0xd4, 0x1a, 0xb2, 0x32, 0x1a, 0x9d, 0x2b, /* *...2..+ */
        0x4f, 0x23, 0x50, 0xea, 0xb4, 0x95, 0x86, 0xc3, /* O#P..... */
        0xb9, 0x5f, 0x34, 0x3e, 0x99, 0x91, 0xa7, 0x80, /* ._4>.... */
        0x5f, 0x6e, 0x1b, 0x6e, 0xdb, 0xe9, 0x02, 0x38, /* _n.n...8 */
        0x6f, 0xdf, 0xc5, 0x9b, 0x0d, 0xa3, 0x1c, 0xa9, /* o....... */
        0x15, 0x76, 0x16, 0x66, 0xa8, 0x4e, 0xfb, 0xd3, /* .v.f.N.. */
        0x43, 0x76, 0xf1, 0x72, 0xb7, 0xd1, 0xfa, 0xee, /* Cv.r.... */
        0x39, 0xa6, 0x96, 0xc1, 0xa2, 0x93, 0xa4, 0x9b, /* 9....... */
        0x1e, 0x9f, 0xba, 0x71, 0x8f, 0xba, 0xbd, 0x67, /* ...q...g */
        0x6a, 0xf2, 0x15, 0x5f, 0xf1, 0x64, 0xe7, 0xcf, /* j.._.d.. */
        0x26, 0xb8, 0x4c, 0xc0, 0xeb, 0x85, 0x04, 0x58, /* &.L....X */
        0xd9, 0x4a, 0x6b, 0xd9, 0x86, 0xf5, 0x80, 0x21, /* .Jk....! */
        0xbf, 0x91, 0xc8, 0x4b, 0x9f, 0x04, 0xed, 0x57, /* ...K...W */
        0x7a, 0xd2, 0x58, 0xac, 0x5b, 0x47, 0xaf, 0x4d, /* z.X.[G.M */
        0x7f, 0x5b, 0x1d, 0x6d, 0x68, 0x9b, 0x84, 0x98, /* .[.mh... */
        0x2a, 0x31, 0x02, 0x2c, 0xe9, 0x1b, 0xaf, 0x11, /* *1.,.... */
        0x0b, 0x78, 0x49, 0xbe, 0x68, 0x68, 0xcb, 0x9c, /* .xI.hh.. */
        0x41, 0x56, 0xe8, 0xb5, 0x59, 0xda, 0xff, 0xca, /* AV..Y... */
        0x59, 0x99, 0x17, 0x3e, 0x11, 0x0a, 0x8f, 0x49, /* Y..>...I */
        0x24, 0x0b, 0x81, 0x42, 0x63, 0xcd, 0x4f, 0xf6, /* $..Bc.O. */
        0x2b, 0x9d, 0xd1, 0x79, 0x75, 0xd7, 0x4a, 0xcc, /* +..yu.J. */
        0x4c, 0xb7, 0x2b, 0xd7, 0xe8, 0xe7, 0xd4, 0x48, /* L.+....H */
        0x3c, 0x14, 0x3b, 0x1c, 0x28, 0xe8, 0x46, 0x7a, /* <.;.(.Fz */
        0xdc, 0x11, 0x9d, 0x7f, 0x1c, 0xab, 0x10, 0x95, /* ........ */
        0x17, 0xb2, 0xc7, 0x7a, 0xbb, 0x17, 0x44, 0x59, /* ...z..DY */
        0x69, 0x8e, 0x16, 0x05, 0x94, 0x8c, 0x88, 0xd9, /* i....... */
        0xdc, 0x9a, 0xfd, 0xf2, 0x93, 0xbe, 0x68, 0xba, /* ......h. */
        0x3c, 0xd6, 0x2b, 0x61, 0x3a, 0x8b, 0xf7, 0x66, /* <.+a:..f */
        0xcb, 0x54, 0xe8, 0xe4, 0xdb, 0x9f, 0xcc, 0x9e  /* .T...... */
    };
    OcspEntry entry[1];
    CertStatus status[1];
    OcspRequest* request = NULL;
#ifndef NO_FILESYSTEM
    const char* ca_cert = "./certs/ca-cert.pem";
#endif

    byte serial[] = {0x05};
    byte issuerHash[] = {0x71, 0x4d, 0x82, 0x23, 0x40, 0x59, 0xc0, 0x96, 0xa1, 0x37, 0x43, 0xfa, 0x31, 0xdb, 0xba, 0xb1, 0x43, 0x18, 0xda, 0x04};
    byte issuerKeyHash[] = {0x83, 0xc6, 0x3a, 0x89, 0x2c, 0x81, 0xf4, 0x02, 0xd7, 0x9d, 0x4c, 0xe2, 0x2a, 0xc0, 0x71, 0x82, 0x64, 0x44, 0xda, 0x0e};


    XMEMSET(entry, 0, sizeof(OcspEntry));
    XMEMSET(status, 0, sizeof(CertStatus));

    ExpectNotNull(request = wolfSSL_OCSP_REQUEST_new());
    ExpectNotNull(request->serial = (byte*)XMALLOC(sizeof(serial), NULL,
                                                   DYNAMIC_TYPE_OCSP_REQUEST));

    if ((request != NULL) && (request->serial != NULL)) {
        request->serialSz = sizeof(serial);
        XMEMCPY(request->serial, serial, sizeof(serial));
        XMEMCPY(request->issuerHash, issuerHash, sizeof(issuerHash));
        XMEMCPY(request->issuerKeyHash, issuerKeyHash, sizeof(issuerKeyHash));
    }

    ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
    ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(cm, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm,
        "./certs/ocsp/intermediate1-ca-cert.pem", NULL), WOLFSSL_SUCCESS);

    /* Response should be valid. */
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, (byte *)response,
        sizeof(response), NULL, status, entry, request), WOLFSSL_SUCCESS);

    /* Flip a byte in the request serial number, response should be invalid
     * now. */
    if ((request != NULL) && (request->serial != NULL))
        request->serial[0] ^= request->serial[0];
    ExpectIntNE(wolfSSL_CertManagerCheckOCSPResponse(cm, (byte *)response,
        sizeof(response), NULL, status, entry, request), WOLFSSL_SUCCESS);

#ifndef NO_FILESYSTEM
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, server_cert_der_2048,
        sizeof(server_cert_der_2048)), WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL));
    ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, server_cert_der_2048,
        sizeof(server_cert_der_2048)), 1);
#endif

    wolfSSL_OCSP_REQUEST_free(request);
    wolfSSL_CertManagerFree(cm);
#endif /* OPENSSL_ALL || WOLFSSL_NGINX ||  WOLFSSL_HAPROXY ||
        * WOLFSSL_APACHE_HTTPD || HAVE_LIGHTY */
#endif /* HAVE_OCSP */
    return EXPECT_RESULT();
}

static int test_wolfSSL_CheckOCSPResponse(void)
{
    EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA) && \
    !defined(NO_RSA) && !defined(NO_SHA)
    const char* responseFile = "./certs/ocsp/test-response.der";
    const char* responseMultiFile = "./certs/ocsp/test-multi-response.der";
    const char* responseNoInternFile =
        "./certs/ocsp/test-response-nointern.der";
    const char* caFile = "./certs/ocsp/root-ca-cert.pem";
    OcspResponse* res = NULL;
    byte data[4096];
    const unsigned char* pt;
    int  dataSz = 0; /* initialize to mitigate spurious maybe-uninitialized from
                      * gcc sanitizer with --enable-heapmath.
                      */
    XFILE f = XBADFILE;
    WOLFSSL_OCSP_BASICRESP* bs = NULL;
    WOLFSSL_X509_STORE* st = NULL;
    WOLFSSL_X509* issuer = NULL;


    ExpectTrue((f = XFOPEN(responseFile, "rb")) != XBADFILE);
    ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    pt = data;
    ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz));
    ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caFile,
        SSL_FILETYPE_PEM));
    ExpectNotNull(st = wolfSSL_X509_STORE_new());
    ExpectIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS);
    ExpectNotNull(bs = wolfSSL_OCSP_response_get1_basic(res));
    ExpectIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0), WOLFSSL_SUCCESS);
    wolfSSL_OCSP_BASICRESP_free(bs);
    bs = NULL;
    wolfSSL_OCSP_RESPONSE_free(res);
    res = NULL;
    wolfSSL_X509_STORE_free(st);
    st = NULL;
    wolfSSL_X509_free(issuer);
    issuer = NULL;

    /* check loading a response with optional certs */
    ExpectTrue((f = XFOPEN(responseNoInternFile, "rb")) != XBADFILE);
    ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);
    f = XBADFILE;

    pt = data;
    ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz));
    wolfSSL_OCSP_RESPONSE_free(res);
    res = NULL;

    /* check loading a response with multiple certs */
    {
        WOLFSSL_CERT_MANAGER* cm = NULL;
        OcspEntry *entry = NULL;
        CertStatus* status = NULL;
        OcspRequest* request = NULL;

        byte serial1[] = {0x01};
        byte serial[] = {0x02};

        byte issuerHash[] = {
            0x44, 0xA8, 0xDB, 0xD1, 0xBC, 0x97, 0x0A, 0x83,
            0x3B, 0x5B, 0x31, 0x9A, 0x4C, 0xB8, 0xD2, 0x52,
            0x37, 0x15, 0x8A, 0x88
        };
        byte issuerKeyHash[] = {
            0x73, 0xB0, 0x1C, 0xA4, 0x2F, 0x82, 0xCB, 0xCF,
            0x47, 0xA5, 0x38, 0xD7, 0xB0, 0x04, 0x82, 0x3A,
            0x7E, 0x72, 0x15, 0x21
        };

        ExpectNotNull(entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
             DYNAMIC_TYPE_OPENSSL));

        ExpectNotNull(status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
             DYNAMIC_TYPE_OPENSSL));

        if (entry != NULL)
            XMEMSET(entry, 0, sizeof(OcspEntry));
        if (status != NULL)
            XMEMSET(status, 0, sizeof(CertStatus));

        ExpectNotNull(request = wolfSSL_OCSP_REQUEST_new());
        ExpectNotNull(request->serial = (byte*)XMALLOC(sizeof(serial), NULL,
                                                    DYNAMIC_TYPE_OCSP_REQUEST));

        if (request != NULL && request->serial != NULL) {
             request->serialSz = sizeof(serial);
             XMEMCPY(request->serial, serial, sizeof(serial));
             XMEMCPY(request->issuerHash, issuerHash, sizeof(issuerHash));
             XMEMCPY(request->issuerKeyHash, issuerKeyHash,
                 sizeof(issuerKeyHash));
        }

        ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
        ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(cm, 0), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, caFile, NULL),
            WOLFSSL_SUCCESS);

        ExpectTrue((f = XFOPEN(responseMultiFile, "rb")) != XBADFILE);
        ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0);
        if (f != XBADFILE)
            XFCLOSE(f);
        f = XBADFILE;

        ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data,
            dataSz, NULL, status, entry, request), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data,
            dataSz, NULL, entry->status, entry, request), WOLFSSL_SUCCESS);
        ExpectNotNull(entry->status);

        if (request != NULL && request->serial != NULL)
            XMEMCPY(request->serial, serial1, sizeof(serial1));
        ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data,
            dataSz, NULL, status, entry, request), WOLFSSL_SUCCESS);

        /* store both status's in the entry to check that "next" is not
         * overwritten */
        if (EXPECT_SUCCESS() && status != NULL && entry != NULL) {
            status->next  = entry->status;
            entry->status = status;
        }

        if (request != NULL && request->serial != NULL)
            XMEMCPY(request->serial, serial, sizeof(serial));
        ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data,
            dataSz, NULL, entry->status, entry, request), WOLFSSL_SUCCESS);
        ExpectNotNull(entry->status->next);

        /* compare the status found */
        ExpectIntEQ(status->serialSz, entry->status->serialSz);
        ExpectIntEQ(XMEMCMP(status->serial, entry->status->serial,
            status->serialSz), 0);

        if (status != NULL && entry != NULL && entry->status != status) {
            XFREE(status, NULL, DYNAMIC_TYPE_OPENSSL);
        }
        wolfSSL_OCSP_CERTID_free(entry);
        wolfSSL_OCSP_REQUEST_free(request);
        wolfSSL_CertManagerFree(cm);
    }

#if defined(WC_RSA_PSS)
    {
        const char* responsePssFile = "./certs/ocsp/test-response-rsapss.der";

        /* check loading a response with RSA-PSS signature */
        ExpectTrue((f = XFOPEN(responsePssFile, "rb")) != XBADFILE);
        ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0);
        if (f != XBADFILE)
            XFCLOSE(f);

        pt = data;
        ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz));

        /* try to verify the response */
        ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caFile,
            SSL_FILETYPE_PEM));
        ExpectNotNull(st = wolfSSL_X509_STORE_new());
        ExpectIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS);
        ExpectNotNull(bs = wolfSSL_OCSP_response_get1_basic(res));
        ExpectIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0),
            WOLFSSL_SUCCESS);
        wolfSSL_OCSP_BASICRESP_free(bs);
        wolfSSL_OCSP_RESPONSE_free(res);
        wolfSSL_X509_STORE_free(st);
        wolfSSL_X509_free(issuer);
    }
#endif
#endif /* HAVE_OCSP */
    return EXPECT_RESULT();
}

static int test_wolfSSL_FPKI(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_FPKI) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
    XFILE f = XBADFILE;
    const char* fpkiCert = "./certs/fpki-cert.der";
    DecodedCert cert;
    byte buf[4096];
    byte* uuid = NULL;
    byte* fascn = NULL;
    word32 fascnSz;
    word32 uuidSz;
    int bytes = 0;

    ExpectTrue((f = XFOPEN(fpkiCert, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
    ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, 0, NULL), 0);
    ExpectIntEQ(wc_GetFASCNFromCert(&cert, NULL, &fascnSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectNotNull(fascn = (byte*)XMALLOC(fascnSz, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(wc_GetFASCNFromCert(&cert, fascn, &fascnSz), 0);
    XFREE(fascn, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    ExpectIntEQ(wc_GetUUIDFromCert(&cert, NULL, &uuidSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectNotNull(uuid = (byte*)XMALLOC(uuidSz, NULL, DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(wc_GetUUIDFromCert(&cert, uuid, &uuidSz), 0);
    XFREE(uuid, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    wc_FreeDecodedCert(&cert);
#endif

    return EXPECT_RESULT();
}

/* use RID in confuncture with other names to test parsing of unknown other
 * names */
static int test_wolfSSL_OtherName(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && !defined(NO_FILESYSTEM)
    XFILE f = XBADFILE;
    const char* ridCert = "./certs/rid-cert.der";
    DecodedCert cert;
    byte buf[4096];
    int bytes = 0;

    ExpectTrue((f = XFOPEN(ridCert, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
    ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, 0, NULL), 0);
    wc_FreeDecodedCert(&cert);
#endif

    return EXPECT_RESULT();
}

#ifdef HAVE_CERT_CHAIN_VALIDATION
static int test_wolfSSL_CertRsaPss(void)
{
    EXPECT_DECLS;
/* FIPS v2 and below don't support long salts. */
#if !defined(NO_RSA) && defined(WC_RSA_PSS) && !defined(NO_FILESYSTEM) && \
    (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
     (HAVE_FIPS_VERSION > 2))) && (!defined(HAVE_SELFTEST) || \
     (defined(HAVE_SELFTEST_VERSION) && (HAVE_SELFTEST_VERSION > 2)))
    XFILE f = XBADFILE;
    const char* rsaPssSha256Cert = "./certs/rsapss/ca-rsapss.der";
    const char* rsaPssRootSha256Cert = "./certs/rsapss/root-rsapss.pem";
#if defined(WOLFSSL_SHA384) && defined(WOLFSSL_PSS_LONG_SALT) && \
    RSA_MAX_SIZE >= 3072
    const char* rsaPssSha384Cert = "./certs/rsapss/ca-3072-rsapss.der";
#endif
#if defined(WOLFSSL_SHA384) && RSA_MAX_SIZE >= 3072
    const char* rsaPssRootSha384Cert = "./certs/rsapss/root-3072-rsapss.pem";
#endif
    DecodedCert cert;
    byte buf[4096];
    int bytes = 0;
    WOLFSSL_CERT_MANAGER* cm = NULL;

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CertManagerLoadCA(cm, rsaPssRootSha256Cert, NULL));
#if defined(WOLFSSL_SHA384) && RSA_MAX_SIZE >= 3072
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CertManagerLoadCA(cm, rsaPssRootSha384Cert, NULL));
#endif

    ExpectTrue((f = XFOPEN(rsaPssSha256Cert, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
    ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, VERIFY, cm), 0);
    wc_FreeDecodedCert(&cert);

#if defined(WOLFSSL_SHA384) && defined(WOLFSSL_PSS_LONG_SALT) && \
    RSA_MAX_SIZE >= 3072
    ExpectTrue((f = XFOPEN(rsaPssSha384Cert, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);
    wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
    ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, VERIFY, cm), 0);
    wc_FreeDecodedCert(&cert);
#endif

    wolfSSL_CertManagerFree(cm);
#endif

    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_CTX_load_verify_locations_ex(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX* ctx = NULL;
    const char* ca_cert = "./certs/ca-cert.pem";
    const char* ca_expired_cert = "./certs/test/expired/expired-ca.pem";

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));

    /* test good CA */
    ExpectTrue(WOLFSSL_SUCCESS ==
        wolfSSL_CTX_load_verify_locations_ex(ctx, ca_cert, NULL,
            WOLFSSL_LOAD_FLAG_NONE));

    /* test expired CA */
#if !defined(OPENSSL_COMPATIBLE_DEFAULTS) && !defined(NO_ASN_TIME)
    ExpectIntNE(wolfSSL_CTX_load_verify_locations_ex(ctx, ca_expired_cert, NULL,
            WOLFSSL_LOAD_FLAG_NONE), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, ca_expired_cert, NULL,
            WOLFSSL_LOAD_FLAG_NONE), WOLFSSL_SUCCESS);
#endif
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, ca_expired_cert, NULL,
            WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), WOLFSSL_SUCCESS);

    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_load_verify_buffer_ex(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX* ctx;
    const char* ca_expired_cert_file = "./certs/test/expired/expired-ca.der";
    byte ca_expired_cert[TWOK_BUF];
    word32 sizeof_ca_expired_cert = 0;
    XFILE fp = XBADFILE;

#ifndef NO_WOLFSSL_CLIENT
    ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
#else
    ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
#endif
    ExpectNotNull(ctx);

#if defined(USE_CERT_BUFFERS_2048)
    /* test good CA */
    ExpectTrue(WOLFSSL_SUCCESS ==
        wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_cert_der_2048,
            sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1, 0,
            WOLFSSL_LOAD_FLAG_NONE));
#endif

    /* load expired CA */
    XMEMSET(ca_expired_cert, 0, sizeof(ca_expired_cert));
    ExpectTrue((fp = XFOPEN(ca_expired_cert_file, "rb")) != XBADFILE);
    ExpectIntGT(sizeof_ca_expired_cert = (word32)XFREAD(ca_expired_cert, 1,
        sizeof(ca_expired_cert), fp), 0);
    if (fp != XBADFILE)
        XFCLOSE(fp);

    /* test expired CA failure */


#if !defined(OPENSSL_COMPATIBLE_DEFAULTS) && !defined(NO_ASN_TIME)
    ExpectIntNE(wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_expired_cert,
            sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 0,
            WOLFSSL_LOAD_FLAG_NONE), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_expired_cert,
            sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 0,
            WOLFSSL_LOAD_FLAG_NONE), WOLFSSL_SUCCESS);
#endif
    /* test expired CA success */
    ExpectIntEQ(wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_expired_cert,
            sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 0,
            WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), WOLFSSL_SUCCESS);

    /* Fail when ctx is NULL. */
    ExpectIntEQ(wolfSSL_CTX_load_verify_buffer_ex(NULL, ca_expired_cert,
            sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 0,
            WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Load as modified cert - bad initial length. */
    ca_expired_cert[2] = 0x7f;
    ExpectIntEQ(wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_expired_cert,
            sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 1,
            WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), WC_NO_ERR_TRACE(ASN_PARSE_E));

    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_load_verify_chain_buffer_format(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA) && defined(OPENSSL_EXTRA) && \
    defined(USE_CERT_BUFFERS_2048) && (WOLFSSL_MIN_RSA_BITS <= 1024) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
    WOLFSSL_CTX* ctx = NULL;

  #ifndef NO_WOLFSSL_CLIENT
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
  #else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
  #endif

    /* Public key 140 bytes??? */
    ExpectIntEQ(wolfSSL_CTX_load_verify_chain_buffer_format(ctx,
        ca_cert_chain_der, sizeof_ca_cert_chain_der, WOLFSSL_FILETYPE_ASN1),
        WOLFSSL_SUCCESS);

    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_add1_chain_cert(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && \
    defined(KEEP_OUR_CERT) && !defined(NO_RSA) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX*        ctx;
    WOLFSSL*            ssl = NULL;
    const char *certChain[] = {
            "./certs/intermediate/client-int-cert.pem",
            "./certs/intermediate/ca-int2-cert.pem",
            "./certs/intermediate/ca-int-cert.pem",
            "./certs/ca-cert.pem",
            NULL
    };
    const char** cert;
    WOLFSSL_X509* x509 = NULL;
    WOLF_STACK_OF(X509)* chain = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    ExpectNotNull(x509 = wolfSSL_X509_new());
    ExpectIntEQ(SSL_CTX_add1_chain_cert(ctx, x509), 0);
    ExpectIntEQ(SSL_CTX_add0_chain_cert(ctx, x509), 0);
    ExpectIntEQ(SSL_add1_chain_cert(ssl, x509), 0);
    ExpectIntEQ(SSL_add0_chain_cert(ssl, x509), 0);
    wolfSSL_X509_free(x509);
    x509 = NULL;

    for (cert = certChain; EXPECT_SUCCESS() && *cert != NULL; cert++) {
        ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(*cert,
            WOLFSSL_FILETYPE_PEM));

        /* Do negative tests once */
        if (cert == certChain) {
            /* Negative tests. */
            ExpectIntEQ(SSL_CTX_add1_chain_cert(NULL, NULL), 0);
            ExpectIntEQ(SSL_CTX_add1_chain_cert(ctx, NULL), 0);
            ExpectIntEQ(SSL_CTX_add1_chain_cert(NULL, x509), 0);
            ExpectIntEQ(SSL_CTX_add0_chain_cert(NULL, NULL), 0);
            ExpectIntEQ(SSL_CTX_add0_chain_cert(ctx, NULL), 0);
            ExpectIntEQ(SSL_CTX_add0_chain_cert(NULL, x509), 0);
        }

        ExpectIntEQ(SSL_CTX_add1_chain_cert(ctx, x509), 1);
        X509_free(x509);
        x509 = NULL;
    }
    for (cert = certChain; EXPECT_SUCCESS() && *cert != NULL; cert++) {
        ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(*cert,
            WOLFSSL_FILETYPE_PEM));

        /* Do negative tests once */
        if (cert == certChain) {
            /* Negative tests. */
            ExpectIntEQ(SSL_add1_chain_cert(NULL, NULL), 0);
            ExpectIntEQ(SSL_add1_chain_cert(ssl, NULL), 0);
            ExpectIntEQ(SSL_add1_chain_cert(NULL, x509), 0);
            ExpectIntEQ(SSL_add0_chain_cert(NULL, NULL), 0);
            ExpectIntEQ(SSL_add0_chain_cert(ssl, NULL), 0);
            ExpectIntEQ(SSL_add0_chain_cert(NULL, x509), 0);
        }

        ExpectIntEQ(SSL_add1_chain_cert(ssl, x509), 1);
        X509_free(x509);
        x509 = NULL;
    }

    ExpectIntEQ(SSL_CTX_get0_chain_certs(ctx, &chain), 1);
    ExpectIntEQ(sk_X509_num(chain), 3);
    ExpectIntEQ(SSL_get0_chain_certs(ssl, &chain), 1);
    ExpectIntEQ(sk_X509_num(chain), 3);

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_use_certificate_chain_buffer_format(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    !defined(NO_WOLFSSL_CLIENT) && defined(USE_CERT_BUFFERS_2048)
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL* ssl = NULL;
    const char* cert = "./certs/server-cert.pem";
    unsigned char* buf = NULL;
    size_t len = 0;

    ExpectIntEQ(load_file(cert, &buf, &len), 0);

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    /* Invalid parameters. */
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(NULL,
        NULL, 0, WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(ctx,
        NULL, 0, WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(NULL,
        server_cert_der_2048, sizeof_server_cert_der_2048,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(NULL, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(ctx, NULL, 0),
        WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(NULL, buf, (sword32)len),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(NULL, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(ssl, NULL, 0),
        WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));
    ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(NULL, buf, (sword32)len),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(ctx,
        server_cert_der_2048, sizeof_server_cert_der_2048,
        WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buf,
        (sword32)len, WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(ctx, buf, (sword32)len),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(ctx,
        server_cert_der_2048, sizeof_server_cert_der_2048), WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));

    ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(ssl, buf, (sword32)len),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(ssl, server_cert_der_2048,
        sizeof_server_cert_der_2048), WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    if (buf != NULL) {
        free(buf);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_use_certificate_chain_file_format(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
    const char* server_chain_der = "./certs/server-cert-chain.der";
    const char* client_single_pem = "./certs/client-cert.pem";
    WOLFSSL_CTX* ctx = NULL;

    (void)server_chain_der;
    (void)client_single_pem;
    (void)ctx;

  #ifndef NO_WOLFSSL_CLIENT
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
  #else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
  #endif

    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file_format(ctx,
        server_chain_der, WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file_format(ctx,
        client_single_pem, WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_use_certificate_chain_file(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    !defined(NO_WOLFSSL_CLIENT)
    const char* server_chain_der = "./certs/server-cert-chain.der";
    const char* client_single_pem = "./certs/client-cert.pem";
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL* ssl = NULL;

    (void)server_chain_der;
    (void)client_single_pem;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    /* Invalid parameters. */
    ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(NULL, NULL,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(ssl, NULL,
        WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(NULL,
       server_chain_der, WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_use_certificate_chain_file(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_use_certificate_chain_file(ssl, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_use_certificate_chain_file(NULL, client_single_pem),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_use_certificate_chain_file(ssl, server_chain_der),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(ssl,
        server_chain_der, WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(ssl,
        client_single_pem, WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_use_certificate_chain_file(ssl, client_single_pem),
        WOLFSSL_SUCCESS);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_SetTmpDH_file(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_DH) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
    WOLFSSL_CTX *ctx = NULL;
#if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
    const char* dsaParamFile = "./certs/dsaparams.pem";
#endif

    (void)ctx;

  #ifndef NO_WOLFSSL_CLIENT
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
  #else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
  #endif

    /* invalid context */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(NULL,
                dhParamFile, WOLFSSL_FILETYPE_PEM));

    /* invalid dhParamFile file */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx,
                NULL, WOLFSSL_FILETYPE_PEM));

    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx,
                bogusFile, WOLFSSL_FILETYPE_PEM));

    /* success */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx, dhParamFile,
                WOLFSSL_FILETYPE_PEM));
#if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx, dsaParamFile,
                WOLFSSL_FILETYPE_PEM));
#endif

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_SetTmpDH_buffer(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_DH) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
    WOLFSSL_CTX *ctx = NULL;

  #ifndef NO_WOLFSSL_CLIENT
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
  #else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
  #endif

    /* invalid context */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(NULL,
                dh_key_der_2048, sizeof_dh_key_der_2048,
                WOLFSSL_FILETYPE_ASN1));

    /* invalid dhParamFile file */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(NULL, NULL,
                0, WOLFSSL_FILETYPE_ASN1));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx, NULL,
                0, WOLFSSL_FILETYPE_ASN1));

    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
                dsa_key_der_2048, sizeof_dsa_key_der_2048,
                WOLFSSL_FILETYPE_ASN1));

    /* invalid file format */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
                dh_key_der_2048, sizeof_dh_key_der_2048, -1));

    /* success */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
                dh_key_der_2048, sizeof_dh_key_der_2048,
                WOLFSSL_FILETYPE_ASN1));

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_SetMinMaxDhKey_Sz(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_DH) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
    WOLFSSL_CTX *ctx;

    (void)ctx;

  #ifndef NO_WOLFSSL_CLIENT
    ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
  #else
    ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
  #endif
    ExpectNotNull(ctx);

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMinDhKey_Sz(ctx, 3072));

    ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_key_der_2048,
                sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMinDhKey_Sz(ctx, 2048));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
                dh_key_der_2048, sizeof_dh_key_der_2048,
                WOLFSSL_FILETYPE_ASN1));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMaxDhKey_Sz(ctx, 1024));

    ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_CTX_SetTmpDH_buffer(ctx,
                dh_key_der_2048, sizeof_dh_key_der_2048,
                WOLFSSL_FILETYPE_ASN1));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMaxDhKey_Sz(ctx, 2048));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
                dh_key_der_2048, sizeof_dh_key_der_2048,
                WOLFSSL_FILETYPE_ASN1));

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_der_load_verify_locations(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_DER_LOAD) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
    WOLFSSL_CTX* ctx = NULL;
    const char* derCert = "./certs/server-cert.der";
    const char* nullPath = NULL;
    const char* invalidPath = "./certs/this-cert-does-not-exist.der";
    const char* emptyPath = "";

    /* der load Case 1 ctx NULL */
    ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, derCert,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

  #ifndef NO_WOLFSSL_CLIENT
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
  #else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
  #endif

    /* Case 2 filePath NULL */
    ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, nullPath,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Case 3 invalid format */
    ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, derCert,
                WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Case 4 filePath not valid */
    ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, invalidPath,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Case 5 filePath empty */
    ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, emptyPath,
                WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifndef NO_RSA
    /* Case 6 success case */
    ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, derCert,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif

    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_enable_disable(void)
{
    EXPECT_DECLS;
#ifndef NO_CERTS
    WOLFSSL_CTX* ctx = NULL;

  #ifdef HAVE_CRL
    ExpectIntEQ(wolfSSL_CTX_DisableCRL(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
  #endif

  #ifdef HAVE_OCSP
    ExpectIntEQ(wolfSSL_CTX_DisableOCSP(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
  #endif

  #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
      defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
    ExpectIntEQ(wolfSSL_CTX_DisableOCSPStapling(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_DisableOCSPMustStaple(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_EnableOCSPMustStaple(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
  #endif

  #ifndef NO_WOLFSSL_CLIENT

    #ifdef HAVE_EXTENDED_MASTER
    ExpectIntEQ(wolfSSL_CTX_DisableExtendedMasterSecret(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    #endif
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));

    #ifdef HAVE_EXTENDED_MASTER
    ExpectIntEQ(wolfSSL_CTX_DisableExtendedMasterSecret(ctx), WOLFSSL_SUCCESS);
    #endif

  #elif !defined(NO_WOLFSSL_SERVER)
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
  #endif

  #if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)

    #ifdef HAVE_CRL
        ExpectIntEQ(wolfSSL_CTX_DisableCRL(ctx), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, 0), WOLFSSL_SUCCESS);
    #endif

    #ifdef HAVE_OCSP
        ExpectIntEQ(wolfSSL_CTX_DisableOCSP(ctx), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_URL_OVERRIDE),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL),
                    WOLFSSL_SUCCESS);
    #endif

    #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
        defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
        ExpectIntEQ(wolfSSL_CTX_DisableOCSPStapling(ctx), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_DisableOCSPMustStaple(ctx), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_DisableOCSPMustStaple(ctx), WOLFSSL_SUCCESS);
    #endif
        wolfSSL_CTX_free(ctx);
  #endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* NO_CERTS */

    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_ticket_API(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX* ctx = NULL;
    void *userCtx = (void*)"this is my ctx";

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_set_TicketEncCtx(ctx, userCtx));
    ExpectTrue(userCtx == wolfSSL_CTX_get_TicketEncCtx(ctx));

    wolfSSL_CTX_free(ctx);

    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_set_TicketEncCtx(NULL, userCtx));
    ExpectNull(wolfSSL_CTX_get_TicketEncCtx(NULL));
#endif /* HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER */
    return EXPECT_RESULT();
}

static int test_wolfSSL_set_minmax_proto_version(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL *ssl = NULL;

    (void)ssl;

#ifndef NO_WOLFSSL_CLIENT
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(ctx, 0), SSL_SUCCESS);

    ExpectIntEQ(wolfSSL_set_min_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_set_min_proto_version(ssl, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_set_max_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_set_max_proto_version(ssl, 0), SSL_SUCCESS);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    ctx = NULL;
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, 0), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(ctx, 0), SSL_SUCCESS);

    wolfSSL_CTX_free(ctx);
#endif
#endif

    return EXPECT_RESULT();
}

#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) && \
    defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CTX_set_max_proto_version_on_result(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    ExpectStrEQ(wolfSSL_get_version(ssl), "TLSv1.2");
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_set_max_proto_version_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    /* Set TLS 1.2 */
    ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION),
            WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

/* Test using wolfSSL_CTX_set_max_proto_version to limit the version below
 * what was set at ctx creation. */
static int test_wolfSSL_CTX_set_max_proto_version(void)
{
    EXPECT_DECLS;
    test_ssl_cbf client_cbs;
    test_ssl_cbf server_cbs;

    XMEMSET(&client_cbs, 0, sizeof(client_cbs));
    XMEMSET(&server_cbs, 0, sizeof(server_cbs));

    client_cbs.method = wolfTLS_client_method;
    server_cbs.method = wolfTLS_server_method;

    server_cbs.ctx_ready = test_wolfSSL_CTX_set_max_proto_version_ctx_ready;

    client_cbs.on_result = test_wolfSSL_CTX_set_max_proto_version_on_result;
    server_cbs.on_result = test_wolfSSL_CTX_set_max_proto_version_on_result;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
        &server_cbs, NULL), TEST_SUCCESS);

    return EXPECT_RESULT();
}
#else
static int test_wolfSSL_CTX_set_max_proto_version(void)
{
    return TEST_SKIPPED;
}
#endif

/*----------------------------------------------------------------------------*
 | SSL
 *----------------------------------------------------------------------------*/

static int test_server_wolfSSL_new(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
        !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL_CTX *ctx_nocert = NULL;
    WOLFSSL *ssl = NULL;

    ExpectNotNull(ctx_nocert = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    ExpectNotNull(ctx        = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
        WOLFSSL_FILETYPE_PEM));

    /* invalid context */
    ExpectNull(ssl = wolfSSL_new(NULL));
#if !defined(WOLFSSL_SESSION_EXPORT) && !defined(WOLFSSL_QT) && \
        !defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_INIT_CTX_KEY)
    ExpectNull(ssl = wolfSSL_new(ctx_nocert));
#endif

    /* success */
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    wolfSSL_CTX_free(ctx_nocert);
#endif

    return EXPECT_RESULT();
}


static int test_client_wolfSSL_new(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
        !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL_CTX *ctx_nocert = NULL;
    WOLFSSL *ssl = NULL;

    ExpectNotNull(ctx_nocert = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ctx        = wolfSSL_CTX_new(wolfSSLv23_client_method()));

    ExpectTrue(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0));

    /* invalid context */
    ExpectNull(ssl = wolfSSL_new(NULL));

    /* success */
    ExpectNotNull(ssl = wolfSSL_new(ctx_nocert));
    wolfSSL_free(ssl);
    ssl = NULL;

    /* success */
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    wolfSSL_free(ssl);

    wolfSSL_CTX_free(ctx);
    wolfSSL_CTX_free(ctx_nocert);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_SetTmpDH_file(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_DH) && \
        !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL *ssl = NULL;
    const char* dhX942ParamFile = "./certs/x942dh2048.pem";
#if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
    const char* dsaParamFile = "./certs/dsaparams.pem";
#endif

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#ifndef NO_RSA
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
               WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
               WOLFSSL_FILETYPE_PEM));
#elif defined(HAVE_ECC)
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCertFile,
               WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile,
               WOLFSSL_FILETYPE_PEM));
#elif defined(HAVE_ED25519)
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, edCertFile,
               WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, edKeyFile,
               WOLFSSL_FILETYPE_PEM));
#elif defined(HAVE_ED448)
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, ed448CertFile,
               WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, ed448KeyFile,
               WOLFSSL_FILETYPE_PEM));
#endif
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    /* invalid ssl */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(NULL,
                dhParamFile, WOLFSSL_FILETYPE_PEM));

    /* invalid dhParamFile file */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl,
                NULL, WOLFSSL_FILETYPE_PEM));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl,
                bogusFile, WOLFSSL_FILETYPE_PEM));

    /* success */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl, dhParamFile,
                WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl, dhX942ParamFile,
                WOLFSSL_FILETYPE_PEM));
#if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx, dsaParamFile,
                WOLFSSL_FILETYPE_PEM));
#endif

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_SetTmpDH_buffer(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_DH) && !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL *ssl = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    ExpectTrue(wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048,
               sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048,
               sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1));
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    /* invalid ssl */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(NULL, dh_key_der_2048,
                sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    /* invalid dhParamFile file */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(NULL, NULL,
                0, WOLFSSL_FILETYPE_ASN1));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, NULL, 0,
                WOLFSSL_FILETYPE_ASN1));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, dsa_key_der_2048,
                sizeof_dsa_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    /* success */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
                sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_SetMinMaxDhKey_Sz(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_DH) && !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL_CTX *ctx2 = NULL;
    WOLFSSL *ssl = NULL;
    WOLFSSL *ssl2 = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    ExpectTrue(wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048,
                sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048,
                sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMinDhKey_Sz(ctx, 3072));
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    ExpectNotNull(ctx2 = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    ExpectTrue(wolfSSL_CTX_use_certificate_buffer(ctx2, server_cert_der_2048,
                sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_buffer(ctx2, server_key_der_2048,
                sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMaxDhKey_Sz(ctx, 1024));
    ExpectNotNull(ssl2 = wolfSSL_new(ctx2));

    ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
                sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMinDhKey_Sz(ssl, 2048));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
                sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMinDhKey_Sz(ssl, 3072));
    ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
                sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl2, dh_key_der_2048,
                sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMaxDhKey_Sz(ssl2, 2048));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl2, dh_key_der_2048,
                sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMaxDhKey_Sz(ssl2, 1024));
    ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
                sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));

    wolfSSL_free(ssl2);
    wolfSSL_CTX_free(ctx2);
    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}


/* Test function for wolfSSL_SetMinVersion. Sets the minimum downgrade version
 * allowed.
 * POST: return 1 on success.
 */
static int test_wolfSSL_SetMinVersion(void)
{
    int                 res = TEST_SKIPPED;
#ifndef NO_WOLFSSL_CLIENT
    int                 failFlag = WOLFSSL_SUCCESS;
    WOLFSSL_CTX*        ctx = NULL;
    WOLFSSL*            ssl = NULL;
    int                 itr;

    #ifndef NO_OLD_TLS
        const int versions[]  =  {
                            #ifdef WOLFSSL_ALLOW_TLSV10
                                   WOLFSSL_TLSV1,
                            #endif
                                   WOLFSSL_TLSV1_1,
                                   WOLFSSL_TLSV1_2};
    #elif !defined(WOLFSSL_NO_TLS12)
        const int versions[]  =  { WOLFSSL_TLSV1_2 };
    #else
        const int versions[]  =  { WOLFSSL_TLSV1_3 };
    #endif

    ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
    ssl = wolfSSL_new(ctx);

    for (itr = 0; itr < (int)(sizeof(versions)/sizeof(int)); itr++) {
       if (wolfSSL_SetMinVersion(ssl, *(versions + itr)) != WOLFSSL_SUCCESS) {
            failFlag = WOLFSSL_FAILURE;
        }
    }

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);

    res = TEST_RES_CHECK(failFlag == WOLFSSL_SUCCESS);
#endif
    return res;

} /* END test_wolfSSL_SetMinVersion */


#ifdef OPENSSL_EXTRA
static int test_EC25519(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519) && defined(WOLFSSL_KEY_GEN)
    byte         priv[CURVE25519_KEYSIZE];
    unsigned int privSz = CURVE25519_KEYSIZE;
    byte         pub[CURVE25519_KEYSIZE];
    unsigned int pubSz = CURVE25519_KEYSIZE;
    byte         priv2[CURVE25519_KEYSIZE];
    unsigned int priv2Sz = CURVE25519_KEYSIZE;
    byte         pub2[CURVE25519_KEYSIZE];
    unsigned int pub2Sz = CURVE25519_KEYSIZE;
    byte         shared[CURVE25519_KEYSIZE];
    unsigned int sharedSz = CURVE25519_KEYSIZE;
    byte         shared2[CURVE25519_KEYSIZE];
    unsigned int shared2Sz = CURVE25519_KEYSIZE;

    /* Bad parameter testing of key generation. */
    ExpectIntEQ(wolfSSL_EC25519_generate_key(NULL,    NULL, NULL,   NULL), 0);
    ExpectIntEQ(wolfSSL_EC25519_generate_key(NULL, &privSz, NULL, &pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_generate_key(NULL, &privSz,  pub, &pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_generate_key(priv,    NULL,  pub, &pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_generate_key(priv, &privSz, NULL, &pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_generate_key(priv, &privSz,  pub,   NULL), 0);
    /*   Bad length */
    privSz = 1;
    ExpectIntEQ(wolfSSL_EC25519_generate_key(priv, &privSz, pub, &pubSz), 0);
    privSz = CURVE25519_KEYSIZE;
    pubSz = 1;
    ExpectIntEQ(wolfSSL_EC25519_generate_key(priv, &privSz, pub, &pubSz), 0);
    pubSz = CURVE25519_KEYSIZE;

    /* Good case of generating key. */
    ExpectIntEQ(wolfSSL_EC25519_generate_key(priv, &privSz, pub, &pubSz), 1);
    ExpectIntEQ(wolfSSL_EC25519_generate_key(priv2, &priv2Sz, pub2, &pub2Sz),
        1);
    ExpectIntEQ(privSz, CURVE25519_KEYSIZE);
    ExpectIntEQ(pubSz, CURVE25519_KEYSIZE);

    /* Bad parameter testing of shared key. */
    ExpectIntEQ(wolfSSL_EC25519_shared_key(  NULL,      NULL, NULL, privSz,
        NULL,  pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_shared_key(  NULL, &sharedSz, NULL, privSz,
        NULL, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_shared_key(  NULL, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared, &sharedSz, NULL, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared, &sharedSz, priv, privSz,
        NULL, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_shared_key(  NULL, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared,      NULL, priv, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared, &sharedSz, NULL, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared, &sharedSz, priv, privSz,
        NULL, pubSz), 0);
    /*   Bad length. */
    sharedSz = 1;
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    sharedSz = CURVE25519_KEYSIZE;
    privSz = 1;
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    privSz = CURVE25519_KEYSIZE;
    pubSz = 1;
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    pubSz = CURVE25519_KEYSIZE;

    /* Good case of shared key. */
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared, &sharedSz, priv, privSz,
        pub2, pub2Sz), 1);
    ExpectIntEQ(wolfSSL_EC25519_shared_key(shared2, &shared2Sz, priv2, priv2Sz,
        pub, pubSz), 1);
    ExpectIntEQ(sharedSz, CURVE25519_KEYSIZE);
    ExpectIntEQ(shared2Sz, CURVE25519_KEYSIZE);
    ExpectIntEQ(XMEMCMP(shared, shared2, sharedSz), 0);
#endif /* HAVE_CURVE25519 && WOLFSSL_KEY_GEN */
    return EXPECT_RESULT();
}

static int test_ED25519(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) && \
    defined(WOLFSSL_KEY_GEN)
    byte         priv[ED25519_PRV_KEY_SIZE];
    unsigned int privSz = (unsigned int)sizeof(priv);
    byte         pub[ED25519_PUB_KEY_SIZE];
    unsigned int pubSz = (unsigned int)sizeof(pub);
#if defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_KEY_IMPORT)
    const char*  msg = TEST_STRING;
    unsigned int msglen = (unsigned int)TEST_STRING_SZ;
    byte         sig[ED25519_SIG_SIZE];
    unsigned int sigSz = (unsigned int)sizeof(sig);
#endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_IMPORT */

    /* Bad parameter testing of key generation. */
    ExpectIntEQ(wolfSSL_ED25519_generate_key(NULL,    NULL, NULL,   NULL), 0);
    ExpectIntEQ(wolfSSL_ED25519_generate_key(priv,    NULL, NULL,   NULL), 0);
    ExpectIntEQ(wolfSSL_ED25519_generate_key(NULL, &privSz, NULL,   NULL), 0);
    ExpectIntEQ(wolfSSL_ED25519_generate_key(NULL,    NULL,  pub,   NULL), 0);
    ExpectIntEQ(wolfSSL_ED25519_generate_key(NULL,    NULL, NULL, &pubSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_generate_key(NULL, &privSz,  pub, &pubSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_generate_key(priv,    NULL,  pub, &pubSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_generate_key(priv, &privSz, NULL, &pubSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_generate_key(priv, &privSz,  pub,   NULL), 0);
    /*   Bad length. */
    privSz = 1;
    ExpectIntEQ(wolfSSL_ED25519_generate_key(priv, &privSz, pub, &pubSz), 0);
    privSz = ED25519_PRV_KEY_SIZE;
    pubSz = 1;
    ExpectIntEQ(wolfSSL_ED25519_generate_key(priv, &privSz, pub, &pubSz), 0);
    pubSz = ED25519_PUB_KEY_SIZE;

    /* Good case of generating key. */
    ExpectIntEQ(wolfSSL_ED25519_generate_key(priv, &privSz, pub, &pubSz),
        1);
    ExpectIntEQ(privSz, ED25519_PRV_KEY_SIZE);
    ExpectIntEQ(pubSz, ED25519_PUB_KEY_SIZE);

#if defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_KEY_IMPORT)
    /* Bad parameter testing of signing. */
    ExpectIntEQ(wolfSSL_ED25519_sign(      NULL, msglen, NULL, privSz, NULL,
          NULL), 0);
    ExpectIntEQ(wolfSSL_ED25519_sign((byte*)msg, msglen, NULL, privSz, NULL,
          NULL), 0);
    ExpectIntEQ(wolfSSL_ED25519_sign(      NULL, msglen, priv, privSz, NULL,
          NULL), 0);
    ExpectIntEQ(wolfSSL_ED25519_sign(      NULL, msglen, NULL, privSz, sig,
          NULL), 0);
    ExpectIntEQ(wolfSSL_ED25519_sign(      NULL, msglen, NULL, privSz, NULL,
        &sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_sign(      NULL, msglen, priv, privSz,  sig,
        &sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_sign((byte*)msg, msglen, NULL, privSz,  sig,
        &sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_sign((byte*)msg, msglen, priv, privSz,  NULL,
        &sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_sign((byte*)msg, msglen, priv, privSz,  sig,
          NULL), 0);
    /*   Bad length. */
    privSz = 1;
    ExpectIntEQ(wolfSSL_ED25519_sign((byte*)msg, msglen, priv, privSz, sig,
        &sigSz), 0);
    privSz = ED25519_PRV_KEY_SIZE;
    sigSz = 1;
    ExpectIntEQ(wolfSSL_ED25519_sign((byte*)msg, msglen, priv, privSz, sig,
        &sigSz), 0);
    sigSz = ED25519_SIG_SIZE;

    /* Good case of signing. */
    ExpectIntEQ(wolfSSL_ED25519_sign((byte*)msg, msglen, priv, privSz, sig,
        &sigSz), 1);
    ExpectIntEQ(sigSz, ED25519_SIG_SIZE);

#ifdef HAVE_ED25519_VERIFY
    /* Bad parameter testing of verification. */
    ExpectIntEQ(wolfSSL_ED25519_verify(      NULL, msglen, NULL, pubSz, NULL,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_verify((byte*)msg, msglen, NULL, pubSz, NULL,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_verify(      NULL, msglen,  pub, pubSz, NULL,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_verify(      NULL, msglen, NULL, pubSz,  sig,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_verify(      NULL, msglen,  pub, pubSz,  sig,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_verify((byte*)msg, msglen, NULL, pubSz,  sig,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED25519_verify((byte*)msg, msglen,  pub, pubSz, NULL,
        sigSz), 0);
    /*   Bad length. */
    pubSz = 1;
    ExpectIntEQ(wolfSSL_ED25519_verify((byte*)msg, msglen, pub, pubSz, sig,
        sigSz), 0);
    pubSz = ED25519_PUB_KEY_SIZE;
    sigSz = 1;
    ExpectIntEQ(wolfSSL_ED25519_verify((byte*)msg, msglen, pub, pubSz, sig,
        sigSz), 0);
    sigSz = ED25519_SIG_SIZE;

    /* Good case of verification. */
    ExpectIntEQ(wolfSSL_ED25519_verify((byte*)msg, msglen, pub, pubSz, sig,
        sigSz), 1);
    /* Bad signature. */
    if (EXPECT_SUCCESS()) {
        sig[1] ^= 0x80;
    }
    ExpectIntEQ(wolfSSL_ED25519_verify((byte*)msg, msglen, pub, pubSz, sig,
        sigSz), 0);
#endif /* HAVE_ED25519_VERIFY */
#endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_IMPORT */
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT && WOLFSSL_KEY_GEN */
    return EXPECT_RESULT();
}

static int test_EC448(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448) && defined(WOLFSSL_KEY_GEN)
    byte         priv[CURVE448_KEY_SIZE];
    unsigned int privSz = CURVE448_KEY_SIZE;
    byte         pub[CURVE448_KEY_SIZE];
    unsigned int pubSz = CURVE448_KEY_SIZE;
    byte         priv2[CURVE448_KEY_SIZE];
    unsigned int priv2Sz = CURVE448_KEY_SIZE;
    byte         pub2[CURVE448_KEY_SIZE];
    unsigned int pub2Sz = CURVE448_KEY_SIZE;
    byte         shared[CURVE448_KEY_SIZE];
    unsigned int sharedSz = CURVE448_KEY_SIZE;
    byte         shared2[CURVE448_KEY_SIZE];
    unsigned int shared2Sz = CURVE448_KEY_SIZE;

    /* Bad parameter testing of key generation. */
    ExpectIntEQ(wolfSSL_EC448_generate_key(NULL,    NULL, NULL,   NULL), 0);
    ExpectIntEQ(wolfSSL_EC448_generate_key(NULL, &privSz, NULL, &pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_generate_key(NULL, &privSz,  pub, &pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_generate_key(priv,    NULL,  pub, &pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_generate_key(priv, &privSz, NULL, &pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_generate_key(priv, &privSz,  pub,   NULL), 0);
    /*   Bad length. */
    privSz = 1;
    ExpectIntEQ(wolfSSL_EC448_generate_key(priv, &privSz, pub, &pubSz), 0);
    privSz = CURVE448_KEY_SIZE;
    pubSz = 1;
    ExpectIntEQ(wolfSSL_EC448_generate_key(priv, &privSz, pub, &pubSz), 0);
    pubSz = CURVE448_KEY_SIZE;

    /* Good case of generating key. */
    ExpectIntEQ(wolfSSL_EC448_generate_key(priv, &privSz, pub, &pubSz), 1);
    ExpectIntEQ(wolfSSL_EC448_generate_key(priv2, &priv2Sz, pub2, &pub2Sz), 1);
    ExpectIntEQ(privSz, CURVE448_KEY_SIZE);
    ExpectIntEQ(pubSz, CURVE448_KEY_SIZE);

    /* Bad parameter testing of shared key. */
    ExpectIntEQ(wolfSSL_EC448_shared_key(  NULL,      NULL, NULL, privSz,
        NULL,  pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_shared_key(  NULL, &sharedSz, NULL, privSz,
        NULL, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_shared_key(  NULL, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared, &sharedSz, NULL, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared, &sharedSz, priv, privSz,
        NULL, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_shared_key(  NULL, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared,      NULL, priv, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared, &sharedSz, NULL, privSz,
         pub, pubSz), 0);
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared, &sharedSz, priv, privSz,
        NULL, pubSz), 0);
    /*   Bad length. */
    sharedSz = 1;
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    sharedSz = CURVE448_KEY_SIZE;
    privSz = 1;
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    privSz = CURVE448_KEY_SIZE;
    pubSz = 1;
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared, &sharedSz, priv, privSz,
         pub, pubSz), 0);
    pubSz = CURVE448_KEY_SIZE;

    /* Good case of shared key. */
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared, &sharedSz, priv, privSz,
        pub2, pub2Sz), 1);
    ExpectIntEQ(wolfSSL_EC448_shared_key(shared2, &shared2Sz, priv2, priv2Sz,
        pub, pubSz), 1);
    ExpectIntEQ(sharedSz, CURVE448_KEY_SIZE);
    ExpectIntEQ(shared2Sz, CURVE448_KEY_SIZE);
    ExpectIntEQ(XMEMCMP(shared, shared2, sharedSz), 0);
#endif /* HAVE_CURVE448 && WOLFSSL_KEY_GEN */
    return EXPECT_RESULT();
}

static int test_ED448(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \
    defined(WOLFSSL_KEY_GEN)
    byte         priv[ED448_PRV_KEY_SIZE];
    unsigned int privSz = (unsigned int)sizeof(priv);
    byte         pub[ED448_PUB_KEY_SIZE];
    unsigned int pubSz = (unsigned int)sizeof(pub);
#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_IMPORT)
    const char*  msg = TEST_STRING;
    unsigned int msglen = (unsigned int)TEST_STRING_SZ;
    byte         sig[ED448_SIG_SIZE];
    unsigned int sigSz = (unsigned int)sizeof(sig);
#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_IMPORT */

    /* Bad parameter testing of key generation. */
    ExpectIntEQ(wolfSSL_ED448_generate_key(NULL,    NULL, NULL,   NULL), 0);
    ExpectIntEQ(wolfSSL_ED448_generate_key(priv,    NULL, NULL,   NULL), 0);
    ExpectIntEQ(wolfSSL_ED448_generate_key(NULL, &privSz, NULL,   NULL), 0);
    ExpectIntEQ(wolfSSL_ED448_generate_key(NULL,    NULL,  pub,   NULL), 0);
    ExpectIntEQ(wolfSSL_ED448_generate_key(NULL,    NULL, NULL, &pubSz), 0);
    ExpectIntEQ(wolfSSL_ED448_generate_key(NULL, &privSz,  pub, &pubSz), 0);
    ExpectIntEQ(wolfSSL_ED448_generate_key(priv,    NULL,  pub, &pubSz), 0);
    ExpectIntEQ(wolfSSL_ED448_generate_key(priv, &privSz, NULL, &pubSz), 0);
    ExpectIntEQ(wolfSSL_ED448_generate_key(priv, &privSz,  pub,   NULL), 0);
    /*   Bad length. */
    privSz = 1;
    ExpectIntEQ(wolfSSL_ED448_generate_key(priv, &privSz, pub, &pubSz), 0);
    privSz = ED448_PRV_KEY_SIZE;
    pubSz = 1;
    ExpectIntEQ(wolfSSL_ED448_generate_key(priv, &privSz, pub, &pubSz), 0);
    pubSz = ED448_PUB_KEY_SIZE;

    /* Good case of generating key. */
    ExpectIntEQ(wolfSSL_ED448_generate_key(priv, &privSz, pub, &pubSz), 1);
    ExpectIntEQ(privSz, ED448_PRV_KEY_SIZE);
    ExpectIntEQ(pubSz, ED448_PUB_KEY_SIZE);

#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_IMPORT)
    /* Bad parameter testing of signing. */
    ExpectIntEQ(wolfSSL_ED448_sign(      NULL, msglen, NULL, privSz, NULL,
          NULL), 0);
    ExpectIntEQ(wolfSSL_ED448_sign((byte*)msg, msglen, NULL, privSz, NULL,
          NULL), 0);
    ExpectIntEQ(wolfSSL_ED448_sign(      NULL, msglen, priv, privSz, NULL,
          NULL), 0);
    ExpectIntEQ(wolfSSL_ED448_sign(      NULL, msglen, NULL, privSz, sig,
          NULL), 0);
    ExpectIntEQ(wolfSSL_ED448_sign(      NULL, msglen, NULL, privSz, NULL,
        &sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_sign(      NULL, msglen, priv, privSz,  sig,
        &sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_sign((byte*)msg, msglen, NULL, privSz,  sig,
        &sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_sign((byte*)msg, msglen, priv, privSz,  NULL,
        &sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_sign((byte*)msg, msglen, priv, privSz,  sig,
          NULL), 0);
    /*   Bad length. */
    privSz = 1;
    ExpectIntEQ(wolfSSL_ED448_sign((byte*)msg, msglen, priv, privSz, sig,
        &sigSz), 0);
    privSz = ED448_PRV_KEY_SIZE;
    sigSz = 1;
    ExpectIntEQ(wolfSSL_ED448_sign((byte*)msg, msglen, priv, privSz, sig,
        &sigSz), 0);
    sigSz = ED448_SIG_SIZE;

    /* Good case of signing. */
    ExpectIntEQ(wolfSSL_ED448_sign((byte*)msg, msglen, priv, privSz, sig,
        &sigSz), 1);
    ExpectIntEQ(sigSz, ED448_SIG_SIZE);

#ifdef HAVE_ED448_VERIFY
   /* Bad parameter testing of verification. */
    ExpectIntEQ(wolfSSL_ED448_verify(      NULL, msglen, NULL, pubSz, NULL,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_verify((byte*)msg, msglen, NULL, pubSz, NULL,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_verify(      NULL, msglen,  pub, pubSz, NULL,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_verify(      NULL, msglen, NULL, pubSz,  sig,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_verify(      NULL, msglen,  pub, pubSz,  sig,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_verify((byte*)msg, msglen, NULL, pubSz,  sig,
        sigSz), 0);
    ExpectIntEQ(wolfSSL_ED448_verify((byte*)msg, msglen,  pub, pubSz, NULL,
        sigSz), 0);
    /*   Bad length. */
    pubSz = 1;
    ExpectIntEQ(wolfSSL_ED448_verify((byte*)msg, msglen, pub, pubSz, sig,
        sigSz), 0);
    pubSz = ED448_PUB_KEY_SIZE;
    sigSz = 1;
    ExpectIntEQ(wolfSSL_ED448_verify((byte*)msg, msglen, pub, pubSz, sig,
        sigSz), 0);
    sigSz = ED448_SIG_SIZE;

    /* Good case of verification. */
    ExpectIntEQ(wolfSSL_ED448_verify((byte*)msg, msglen, pub, pubSz, sig,
        sigSz), 1);
    /* Bad signature. */
    if (EXPECT_SUCCESS()) {
        sig[1] ^= 0x80;
    }
    ExpectIntEQ(wolfSSL_ED448_verify((byte*)msg, msglen, pub, pubSz, sig,
        sigSz), 0);
#endif /* HAVE_ED448_VERIFY */
#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_IMPORT */
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT && WOLFSSL_KEY_GEN */
    return EXPECT_RESULT();
}
#endif /* OPENSSL_EXTRA */

#include <wolfssl/openssl/pem.h>
/*----------------------------------------------------------------------------*
 | EVP
 *----------------------------------------------------------------------------*/

static int test_wolfSSL_EVP_PKEY_print_public(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_BIO)
    WOLFSSL_BIO* rbio = NULL;
    WOLFSSL_BIO* wbio = NULL;
    WOLFSSL_EVP_PKEY* pkey = NULL;
    char line[256] = { 0 };
    char line1[256] = { 0 };
    int i = 0;

    /* test error cases */
    ExpectIntEQ( EVP_PKEY_print_public(NULL,NULL,0,NULL),0L);

    /*
     *  test RSA public key print
     *  in this test, pass '3' for indent
     */
#if !defined(NO_RSA) && defined(USE_CERT_BUFFERS_1024)

    ExpectNotNull(rbio = BIO_new_mem_buf( client_keypub_der_1024,
        sizeof_client_keypub_der_1024));

    ExpectNotNull(wolfSSL_d2i_PUBKEY_bio(rbio, &pkey));

    ExpectNotNull(wbio = BIO_new(BIO_s_mem()));

    ExpectIntEQ(EVP_PKEY_print_public(wbio, pkey,3,NULL),1);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "   RSA Public-Key: (1024 bit)\n");
    ExpectIntEQ(XSTRNCMP(line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "   Modulus:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "       00:bc:73:0e:a8:49:f3:74:a2:a9:ef:18:a5:da:55:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);


    /* skip to the end of modulus element*/
    for (i = 0; i < 8 ;i++) {
        ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    }

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "   Exponent: 65537 (0x010001)\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);


    /* should reach EOF */
    ExpectIntLE(BIO_gets(wbio, line, sizeof(line)), 0);

    EVP_PKEY_free(pkey);
    pkey = NULL;
    BIO_free(rbio);
    BIO_free(wbio);
    rbio = NULL;
    wbio = NULL;

#endif  /* !NO_RSA && USE_CERT_BUFFERS_1024*/

    /*
     *  test DSA public key print
     */
#if !defined(NO_DSA) && defined(USE_CERT_BUFFERS_2048)
    ExpectNotNull(rbio = BIO_new_mem_buf( dsa_pub_key_der_2048,
        sizeof_dsa_pub_key_der_2048));

    ExpectNotNull(wolfSSL_d2i_PUBKEY_bio(rbio, &pkey));

    ExpectNotNull(wbio = BIO_new(BIO_s_mem()));

    ExpectIntEQ(EVP_PKEY_print_public(wbio, pkey,0,NULL),1);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "DSA Public-Key: (2048 bit)\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "pub:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1,
        "    00:C2:35:2D:EC:83:83:6C:73:13:9E:52:7C:74:C8:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    /* skip to the end of pub element*/
    for (i = 0; i < 17 ;i++) {
        ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    }

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "P:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    /* skip to the end of P element*/
    for (i = 0; i < 18 ;i++) {
        ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    }

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "Q:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    /* skip to the end of Q element*/
    for (i = 0; i < 3 ;i++) {
        ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    }
    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "G:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    /* skip to the end of G element*/
    for (i = 0; i < 18 ;i++) {
        ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    }
    /* should reach EOF */
    ExpectIntLE(BIO_gets(wbio, line, sizeof(line)), 0);

    EVP_PKEY_free(pkey);
    pkey = NULL;
    BIO_free(rbio);
    BIO_free(wbio);
    rbio = NULL;
    wbio = NULL;

#endif /* !NO_DSA && USE_CERT_BUFFERS_2048 */

    /*
     *  test ECC public key print
     */
#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)

    ExpectNotNull(rbio = BIO_new_mem_buf( ecc_clikeypub_der_256,
        sizeof_ecc_clikeypub_der_256));

    ExpectNotNull(wolfSSL_d2i_PUBKEY_bio(rbio, &pkey));

    ExpectNotNull(wbio = BIO_new(BIO_s_mem()));

    ExpectIntEQ(EVP_PKEY_print_public(wbio, pkey,0,NULL),1);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "Public-Key: (256 bit)\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "pub:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1,
            "    04:55:BF:F4:0F:44:50:9A:3D:CE:9B:B7:F0:C5:4D:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    /* skip to the end of pub element*/
    for (i = 0; i < 4 ;i++) {
        ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    }

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "ASN1 OID: prime256v1\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "NIST CURVE: P-256\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);


    /* should reach EOF */
    ExpectIntLE(BIO_gets(wbio, line, sizeof(line)), 0);

    EVP_PKEY_free(pkey);
    pkey = NULL;
    BIO_free(rbio);
    BIO_free(wbio);
    rbio = NULL;
    wbio = NULL;

#endif /* HAVE_ECC && USE_CERT_BUFFERS_256 */

    /*
     *  test DH public key print
     */
#if defined(WOLFSSL_DH_EXTRA) && defined(USE_CERT_BUFFERS_2048)

    ExpectNotNull(rbio = BIO_new_mem_buf( dh_pub_key_der_2048,
        sizeof_dh_pub_key_der_2048));

    ExpectNotNull(wolfSSL_d2i_PUBKEY_bio(rbio, &pkey));

    ExpectNotNull(wbio = BIO_new(BIO_s_mem()));

    ExpectIntEQ(EVP_PKEY_print_public(wbio, pkey,0,NULL), 1);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "DH Public-Key: (2048 bit)\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "public-key:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1,
        "    34:41:BF:E9:F2:11:BF:05:DB:B2:72:A8:29:CC:BD:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    /* skip to the end of public-key element*/
    for (i = 0; i < 17 ;i++) {
        ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    }

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "prime:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1,
        "    00:D3:B2:99:84:5C:0A:4C:E7:37:CC:FC:18:37:01:\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    /* skip to the end of prime element*/
    for (i = 0; i < 17 ;i++) {
        ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    }

    ExpectIntGT(BIO_gets(wbio, line, sizeof(line)), 0);
    strcpy(line1, "generator: 2 (0x02)\n");
    ExpectIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0);

    /* should reach EOF */
    ExpectIntLE(BIO_gets(wbio, line, sizeof(line)), 0);

    EVP_PKEY_free(pkey);
    pkey = NULL;
    BIO_free(rbio);
    BIO_free(wbio);
    rbio = NULL;
    wbio = NULL;

#endif /* WOLFSSL_DH_EXTRA && USE_CERT_BUFFERS_2048 */

    /* to prevent "unused variable" warning */
    (void)pkey;
    (void)wbio;
    (void)rbio;
    (void)line;
    (void)line1;
    (void)i;
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}
/* Test functions for base64 encode/decode */
static int test_wolfSSL_EVP_ENCODE_CTX_new(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && \
( defined(WOLFSSL_BASE64_ENCODE) || defined(WOLFSSL_BASE64_DECODE))
    EVP_ENCODE_CTX* ctx = NULL;

    ExpectNotNull(ctx = EVP_ENCODE_CTX_new());
    ExpectIntEQ(ctx->remaining,0);
    ExpectIntEQ(ctx->data[0],0);
    ExpectIntEQ(ctx->data[sizeof(ctx->data) -1],0);
    EVP_ENCODE_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && (WOLFSSL_BASE64_ENCODE || WOLFSSL_BASE64_DECODE) */
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_ENCODE_CTX_free(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && \
( defined(WOLFSSL_BASE64_ENCODE) || defined(WOLFSSL_BASE64_DECODE))
    EVP_ENCODE_CTX* ctx = NULL;

    ExpectNotNull(ctx = EVP_ENCODE_CTX_new());
    EVP_ENCODE_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && (WOLFSSL_BASE64_ENCODE || WOLFSSL_BASE64_DECODE) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_EncodeInit(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_ENCODE)
    EVP_ENCODE_CTX* ctx = NULL;

    ExpectNotNull(ctx = EVP_ENCODE_CTX_new());
    ExpectIntEQ(ctx->remaining, 0);
    ExpectIntEQ(ctx->data[0], 0);
    ExpectIntEQ(ctx->data[sizeof(ctx->data) -1], 0);

    if (ctx != NULL) {
        /* make ctx dirty */
        ctx->remaining = 10;
        XMEMSET(ctx->data, 0x77, sizeof(ctx->data));
    }

    EVP_EncodeInit(ctx);

    ExpectIntEQ(ctx->remaining, 0);
    ExpectIntEQ(ctx->data[0], 0);
    ExpectIntEQ(ctx->data[sizeof(ctx->data) -1], 0);

    EVP_ENCODE_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && WOLFSSL_BASE64_ENCODE*/
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_EncodeUpdate(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_ENCODE)
    int outl;
    int total;

    const unsigned char plain0[] = {"Th"};
    const unsigned char plain1[] = {"This is a base64 encodeing test."};
    const unsigned char plain2[] = {"This is additional data."};

    const unsigned char encBlock0[] = {"VGg="};
    const unsigned char enc0[]   = {"VGg=\n"};
    /* expected encoded result for the first output 64 chars plus trailing LF*/
    const unsigned char enc1[]   = {"VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVpbmcgdGVzdC5UaGlzIGlzIGFkZGl0aW9u\n"};

    const unsigned char enc2[]   =
    {"VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVpbmcgdGVzdC5UaGlzIGlzIGFkZGl0aW9u\nYWwgZGF0YS4=\n"};

    unsigned char encOutBuff[300];

    EVP_ENCODE_CTX* ctx = NULL;

    ExpectNotNull(ctx = EVP_ENCODE_CTX_new());

    EVP_EncodeInit(ctx);

    /* illegal parameter test */
    ExpectIntEQ(
        EVP_EncodeUpdate(
            NULL,            /* pass NULL as ctx */
            encOutBuff,
            &outl,
            plain1,
            sizeof(plain1)-1),
        0                    /* expected result code 0: fail */
    );

    ExpectIntEQ(
        EVP_EncodeUpdate(
            ctx,
            NULL,           /* pass NULL as out buff */
            &outl,
            plain1,
            sizeof(plain1)-1),
        0                    /* expected result code 0: fail */
    );

    ExpectIntEQ(
        EVP_EncodeUpdate(
            ctx,
            encOutBuff,
            NULL,            /* pass NULL as outl */
            plain1,
            sizeof(plain1)-1),
        0                    /* expected result code 0: fail */
    );

    ExpectIntEQ(
        EVP_EncodeUpdate(
            ctx,
            encOutBuff,
            &outl,
            NULL,            /* pass NULL as in */
            sizeof(plain1)-1),
        0                    /* expected result code 0: fail */
    );

    ExpectIntEQ(EVP_EncodeBlock(NULL, NULL, 0), -1);

    /* meaningless parameter test */

    ExpectIntEQ(
        EVP_EncodeUpdate(
            ctx,
            encOutBuff,
            &outl,
            plain1,
            0),              /* pass zero input */
        1                    /* expected result code 1: success */
    );

    /* very small data encoding test */

    EVP_EncodeInit(ctx);

    ExpectIntEQ(
        EVP_EncodeUpdate(
            ctx,
            encOutBuff,
            &outl,
            plain0,
            sizeof(plain0)-1),
        1                    /* expected result code 1: success */
    );
    ExpectIntEQ(outl,0);

    if (EXPECT_SUCCESS()) {
        EVP_EncodeFinal(
            ctx,
            encOutBuff + outl,
            &outl);
    }

    ExpectIntEQ( outl, sizeof(enc0)-1);
    ExpectIntEQ(
        XSTRNCMP(
            (const char*)encOutBuff,
            (const char*)enc0,sizeof(enc0) ),
    0);

    XMEMSET( encOutBuff,0, sizeof(encOutBuff));
    ExpectIntEQ(EVP_EncodeBlock(encOutBuff, plain0, sizeof(plain0)-1),
                sizeof(encBlock0)-1);
    ExpectStrEQ(encOutBuff, encBlock0);

    /* pass small size( < 48bytes ) input, then make sure they are not
     * encoded  and just stored in ctx
     */

    EVP_EncodeInit(ctx);

    total = 0;
    outl = 0;
    XMEMSET( encOutBuff,0, sizeof(encOutBuff));

    ExpectIntEQ(
    EVP_EncodeUpdate(
        ctx,
        encOutBuff,         /* buffer for output */
        &outl,              /* size of output */
        plain1,             /* input */
        sizeof(plain1)-1),  /* size of input */
        1);                 /* expected result code 1:success */

    total += outl;

    ExpectIntEQ(outl, 0);  /* no output expected */
    ExpectIntEQ(ctx->remaining, sizeof(plain1) -1);
    ExpectTrue(
        XSTRNCMP((const char*)(ctx->data),
                 (const char*)plain1,
                 ctx->remaining) ==0 );
    ExpectTrue(encOutBuff[0] == 0);

    /* call wolfSSL_EVP_EncodeUpdate again to make it encode
     * the stored data and the new input together
     */
    ExpectIntEQ(
    EVP_EncodeUpdate(
        ctx,
        encOutBuff + outl,  /* buffer for output */
        &outl,              /* size of output */
        plain2,             /* additional input */
        sizeof(plain2) -1), /* size of additional input */
        1);                 /* expected result code 1:success */

    total += outl;

    ExpectIntNE(outl, 0);   /* some output is expected this time*/
    ExpectIntEQ(outl, BASE64_ENCODE_RESULT_BLOCK_SIZE +1); /* 64 bytes and LF */
    ExpectIntEQ(
        XSTRNCMP((const char*)encOutBuff,(const char*)enc1,sizeof(enc1) ),0);

    /* call wolfSSL_EVP_EncodeFinal to flush all the unprocessed input */
    EVP_EncodeFinal(
        ctx,
        encOutBuff + outl,
        &outl);

    total += outl;

    ExpectIntNE(total,0);
    ExpectIntNE(outl,0);
    ExpectIntEQ(XSTRNCMP(
        (const char*)encOutBuff,(const char*)enc2,sizeof(enc2) ),0);

    /* test with illeagal parameters */
    outl = 1;
    EVP_EncodeFinal(NULL, encOutBuff + outl, &outl);
    ExpectIntEQ(outl, 0);
    outl = 1;
    EVP_EncodeFinal(ctx, NULL, &outl);
    ExpectIntEQ(outl, 0);
    EVP_EncodeFinal(ctx, encOutBuff + outl, NULL);
    EVP_EncodeFinal(NULL, NULL, NULL);

    EVP_ENCODE_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && WOLFSSL_BASE64_ENCODE*/
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_EncodeFinal(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_ENCODE)
    /* tests for wolfSSL_EVP_EncodeFinal are included in
     * test_wolfSSL_EVP_EncodeUpdate
     */
    res = TEST_SUCCESS;
#endif /* OPENSSL_EXTRA && WOLFSSL_BASE64_ENCODE*/
    return res;
}


static int test_wolfSSL_EVP_DecodeInit(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_DECODE)
    EVP_ENCODE_CTX* ctx = NULL;

    ExpectNotNull( ctx = EVP_ENCODE_CTX_new());
    ExpectIntEQ( ctx->remaining,0);
    ExpectIntEQ( ctx->data[0],0);
    ExpectIntEQ( ctx->data[sizeof(ctx->data) -1],0);

    if (ctx != NULL) {
        /* make ctx dirty */
        ctx->remaining = 10;
        XMEMSET( ctx->data, 0x77, sizeof(ctx->data));
    }

    EVP_DecodeInit(ctx);

    ExpectIntEQ( ctx->remaining,0);
    ExpectIntEQ( ctx->data[0],0);
    ExpectIntEQ( ctx->data[sizeof(ctx->data) -1],0);

    EVP_ENCODE_CTX_free(ctx);
#endif /* OPENSSL && WOLFSSL_BASE_DECODE */
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_DecodeUpdate(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_DECODE)
    int outl;
    unsigned char decOutBuff[300];

    EVP_ENCODE_CTX* ctx = NULL;

    static const unsigned char enc1[]   =
            {"VGhpcyBpcyBhIGJhc2U2NCBkZWNvZGluZyB0ZXN0Lg==\n"};
/*    const unsigned char plain1[] =
    {"This is a base64 decoding test."} */

    ExpectNotNull(ctx = EVP_ENCODE_CTX_new());

    EVP_DecodeInit(ctx);

    /* illegal parameter tests */

    /* pass NULL as ctx */
    ExpectIntEQ(
        EVP_DecodeUpdate(
            NULL,            /* pass NULL as ctx */
            decOutBuff,
            &outl,
            enc1,
            sizeof(enc1)-1),
        -1                    /* expected result code -1: fail */
    );
    ExpectIntEQ( outl, 0);

    /* pass NULL as output */
    ExpectIntEQ(
        EVP_DecodeUpdate(
            ctx,
            NULL,           /* pass NULL as out buff */
            &outl,
            enc1,
            sizeof(enc1)-1),
        -1                    /* expected result code -1: fail */
    );
    ExpectIntEQ( outl, 0);

    /* pass NULL as outl */
    ExpectIntEQ(
        EVP_DecodeUpdate(
            ctx,
            decOutBuff,
            NULL,            /* pass NULL as outl */
            enc1,
            sizeof(enc1)-1),
        -1                   /* expected result code -1: fail */
    );

    /* pass NULL as input */
    ExpectIntEQ(
        EVP_DecodeUpdate(
            ctx,
            decOutBuff,
            &outl,
            NULL,            /* pass NULL as in */
            sizeof(enc1)-1),
        -1                    /* expected result code -1: fail */
    );
    ExpectIntEQ( outl, 0);

    ExpectIntEQ(EVP_DecodeBlock(NULL, NULL, 0), -1);

    /* pass zero length input */

    ExpectIntEQ(
        EVP_DecodeUpdate(
            ctx,
            decOutBuff,
            &outl,
            enc1,
            0),              /* pass zero as input len */
        1                    /* expected result code 1: success */
    );

    /* decode correct base64 string */

    {
        static const unsigned char enc2[]   =
        {"VGhpcyBpcyBhIGJhc2U2NCBkZWNvZGluZyB0ZXN0Lg==\n"};
        static const unsigned char plain2[] =
        {"This is a base64 decoding test."};

        EVP_EncodeInit(ctx);

        ExpectIntEQ(
            EVP_DecodeUpdate(
                ctx,
                decOutBuff,
                &outl,
                enc2,
                sizeof(enc2)-1),
            0                    /* expected result code 0: success */
            );

        ExpectIntEQ(outl,sizeof(plain2) -1);

        ExpectIntEQ(
            EVP_DecodeFinal(
                ctx,
                decOutBuff + outl,
                &outl),
            1                    /* expected result code 1: success */
            );
        ExpectIntEQ(outl, 0);   /* expected DecodeFinal output no data */

        ExpectIntEQ(XSTRNCMP( (const char*)plain2,(const char*)decOutBuff,
                              sizeof(plain2) -1 ),0);
        ExpectIntEQ(EVP_DecodeBlock(decOutBuff, enc2, sizeof(enc2)),
                    sizeof(plain2)-1);
        ExpectIntEQ(XSTRNCMP( (const char*)plain2,(const char*)decOutBuff,
                              sizeof(plain2) -1 ),0);
    }

    /* decode correct base64 string which does not have '\n' in its last*/

    {
        static const unsigned char enc3[]   =
        {"VGhpcyBpcyBhIGJhc2U2NCBkZWNvZGluZyB0ZXN0Lg=="}; /* 44 chars */
        static const unsigned char plain3[] =
        {"This is a base64 decoding test."}; /* 31 chars */

        EVP_EncodeInit(ctx);

        ExpectIntEQ(
            EVP_DecodeUpdate(
                ctx,
                decOutBuff,
                &outl,
                enc3,
                sizeof(enc3)-1),
            0                    /* expected result code 0: success */
            );

        ExpectIntEQ(outl,sizeof(plain3)-1);   /* 31 chars should be output */

        ExpectIntEQ(XSTRNCMP( (const char*)plain3,(const char*)decOutBuff,
                              sizeof(plain3) -1 ),0);

        ExpectIntEQ(
            EVP_DecodeFinal(
                ctx,
                decOutBuff + outl,
                &outl),
            1                    /* expected result code 1: success */
            );

        ExpectIntEQ(outl,0 );

        ExpectIntEQ(EVP_DecodeBlock(decOutBuff, enc3, sizeof(enc3)-1),
                    sizeof(plain3)-1);
        ExpectIntEQ(XSTRNCMP( (const char*)plain3,(const char*)decOutBuff,
                              sizeof(plain3) -1 ),0);
    }

    /* decode string which has a padding char ('=') in the illegal position*/

    {
        static const unsigned char enc4[]   =
            {"VGhpcyBpcyBhIGJhc2U2N=CBkZWNvZGluZyB0ZXN0Lg==\n"};

        EVP_EncodeInit(ctx);

        ExpectIntEQ(
            EVP_DecodeUpdate(
                ctx,
                decOutBuff,
                &outl,
                enc4,
                sizeof(enc4)-1),
            -1                    /* expected result code -1: error */
            );
        ExpectIntEQ(outl,0);
        ExpectIntEQ(EVP_DecodeBlock(decOutBuff, enc4, sizeof(enc4)-1), -1);
    }

    /* small data decode test */

    {
        static const unsigned char enc00[]   = {"VG"};
        static const unsigned char enc01[]   = {"g=\n"};
        static const unsigned char plain4[]  = {"Th"};

        EVP_EncodeInit(ctx);

        ExpectIntEQ(
            EVP_DecodeUpdate(
                ctx,
                decOutBuff,
                &outl,
                enc00,
                sizeof(enc00)-1),
            1                    /* expected result code 1: success */
            );
        ExpectIntEQ(outl,0);

        ExpectIntEQ(
            EVP_DecodeUpdate(
                ctx,
                decOutBuff + outl,
                &outl,
                enc01,
                sizeof(enc01)-1),
            0                    /* expected result code 0: success */
            );

        ExpectIntEQ(outl,sizeof(plain4)-1);

        /* test with illegal parameters */
        ExpectIntEQ(EVP_DecodeFinal(NULL,decOutBuff + outl,&outl), -1);
        ExpectIntEQ(EVP_DecodeFinal(ctx,NULL,&outl), -1);
        ExpectIntEQ(EVP_DecodeFinal(ctx,decOutBuff + outl, NULL), -1);
        ExpectIntEQ(EVP_DecodeFinal(NULL,NULL, NULL), -1);

        if (EXPECT_SUCCESS()) {
            EVP_DecodeFinal(
                ctx,
                decOutBuff + outl,
                &outl);
        }

        ExpectIntEQ( outl, 0);
        ExpectIntEQ(
            XSTRNCMP(
                (const char*)decOutBuff,
                (const char*)plain4,sizeof(plain4)-1 ),
            0);
    }

    EVP_ENCODE_CTX_free(ctx);
#endif /* OPENSSL && WOLFSSL_BASE_DECODE */
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_DecodeFinal(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_DECODE)
    /* tests for wolfSSL_EVP_DecodeFinal are included in
     * test_wolfSSL_EVP_DecodeUpdate
     */
    res = TEST_SUCCESS;
#endif /* OPENSSL && WOLFSSL_BASE_DECODE */
    return res;
}

/* Test function for wolfSSL_EVP_get_cipherbynid.
 */

#ifdef OPENSSL_EXTRA
static int test_wolfSSL_EVP_get_cipherbynid(void)
{
    EXPECT_DECLS;
#ifndef NO_AES
    const WOLFSSL_EVP_CIPHER* c;

    c = wolfSSL_EVP_get_cipherbynid(419);
    #if (defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)) && \
         defined(WOLFSSL_AES_128)
        ExpectNotNull(c);
        ExpectNotNull(XSTRCMP("EVP_AES_128_CBC", c));
    #else
        ExpectNull(c);
    #endif

    c = wolfSSL_EVP_get_cipherbynid(423);
    #if (defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)) && \
         defined(WOLFSSL_AES_192)
        ExpectNotNull(c);
        ExpectNotNull(XSTRCMP("EVP_AES_192_CBC", c));
    #else
        ExpectNull(c);
    #endif

    c = wolfSSL_EVP_get_cipherbynid(427);
    #if (defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)) && \
         defined(WOLFSSL_AES_256)
        ExpectNotNull(c);
        ExpectNotNull(XSTRCMP("EVP_AES_256_CBC", c));
    #else
        ExpectNull(c);
    #endif

    c = wolfSSL_EVP_get_cipherbynid(904);
    #if defined(WOLFSSL_AES_COUNTER) && defined(WOLFSSL_AES_128)
        ExpectNotNull(c);
        ExpectNotNull(XSTRCMP("EVP_AES_128_CTR", c));
    #else
        ExpectNull(c);
    #endif

    c = wolfSSL_EVP_get_cipherbynid(905);
    #if defined(WOLFSSL_AES_COUNTER) && defined(WOLFSSL_AES_192)
        ExpectNotNull(c);
        ExpectNotNull(XSTRCMP("EVP_AES_192_CTR", c));
    #else
        ExpectNull(c);
    #endif

    c = wolfSSL_EVP_get_cipherbynid(906);
    #if defined(WOLFSSL_AES_COUNTER) && defined(WOLFSSL_AES_256)
        ExpectNotNull(c);
        ExpectNotNull(XSTRCMP("EVP_AES_256_CTR", c));
    #else
        ExpectNull(c);
    #endif

    c = wolfSSL_EVP_get_cipherbynid(418);
    #if defined(HAVE_AES_ECB) && defined(WOLFSSL_AES_128)
        ExpectNotNull(c);
        ExpectNotNull(XSTRCMP("EVP_AES_128_ECB", c));
    #else
        ExpectNull(c);
    #endif

    c = wolfSSL_EVP_get_cipherbynid(422);
    #if defined(HAVE_AES_ECB) && defined(WOLFSSL_AES_192)
        ExpectNotNull(c);
        ExpectNotNull(XSTRCMP("EVP_AES_192_ECB", c));
    #else
        ExpectNull(c);
    #endif

    c = wolfSSL_EVP_get_cipherbynid(426);
    #if defined(HAVE_AES_ECB) && defined(WOLFSSL_AES_256)
        ExpectNotNull(c);
        ExpectNotNull(XSTRCMP("EVP_AES_256_ECB", c));
    #else
        ExpectNull(c);
    #endif
#endif /* !NO_AES */

#ifndef NO_DES3
    ExpectNotNull(XSTRCMP("EVP_DES_CBC", wolfSSL_EVP_get_cipherbynid(31)));
#ifdef WOLFSSL_DES_ECB
    ExpectNotNull(XSTRCMP("EVP_DES_ECB", wolfSSL_EVP_get_cipherbynid(29)));
#endif
    ExpectNotNull(XSTRCMP("EVP_DES_EDE3_CBC", wolfSSL_EVP_get_cipherbynid(44)));
#ifdef WOLFSSL_DES_ECB
    ExpectNotNull(XSTRCMP("EVP_DES_EDE3_ECB", wolfSSL_EVP_get_cipherbynid(33)));
#endif
#endif /* !NO_DES3 */

#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
    ExpectNotNull(XSTRCMP("EVP_CHACHA20_POLY13O5", EVP_get_cipherbynid(1018)));
#endif

    /* test for nid is out of range */
    ExpectNull(wolfSSL_EVP_get_cipherbynid(1));

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_CIPHER_CTX(void)
{
    EXPECT_DECLS;
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    const EVP_CIPHER *init = EVP_aes_128_cbc();
    const EVP_CIPHER *test;
    byte key[AES_BLOCK_SIZE] = {0};
    byte iv[AES_BLOCK_SIZE] = {0};

    ExpectNotNull(ctx);
    wolfSSL_EVP_CIPHER_CTX_init(ctx);
    ExpectIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS);
    test = EVP_CIPHER_CTX_cipher(ctx);
    ExpectTrue(init == test);
    ExpectIntEQ(EVP_CIPHER_nid(test), NID_aes_128_cbc);

    ExpectIntEQ(EVP_CIPHER_CTX_reset(ctx), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_CIPHER_CTX_reset(NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    EVP_CIPHER_CTX_free(ctx);
    /* test EVP_CIPHER_CTX_cleanup with NULL */
    ExpectIntEQ(EVP_CIPHER_CTX_cleanup(NULL), WOLFSSL_SUCCESS);
#endif /* !NO_AES && HAVE_AES_CBC && WOLFSSL_AES_128 */
    return EXPECT_RESULT();
}
#endif /* OPENSSL_EXTRA */

/*----------------------------------------------------------------------------*
 | IO
 *----------------------------------------------------------------------------*/

#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) || \
    defined(HAVE_IO_TESTS_DEPENDENCIES)
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
    #ifdef WC_SHA512_DIGEST_SIZE
        #define MD_MAX_SIZE WC_SHA512_DIGEST_SIZE
    #else
        #define MD_MAX_SIZE WC_SHA256_DIGEST_SIZE
    #endif
    byte server_side_msg1[MD_MAX_SIZE] = {0};/* msg sent by server */
    byte server_side_msg2[MD_MAX_SIZE] = {0};/* msg received from client */
    byte client_side_msg1[MD_MAX_SIZE] = {0};/* msg sent by client */
    byte client_side_msg2[MD_MAX_SIZE] = {0};/* msg received from server */
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */

/* TODO: Expand and enable this when EVP_chacha20_poly1305 is supported */
#if defined(HAVE_SESSION_TICKET) && defined(OPENSSL_EXTRA) && \
    defined(HAVE_AES_CBC)

    typedef struct openssl_key_ctx {
        byte name[WOLFSSL_TICKET_NAME_SZ]; /* server name */
        byte key[WOLFSSL_TICKET_KEY_SZ]; /* cipher key */
        byte hmacKey[WOLFSSL_TICKET_NAME_SZ]; /* hmac key */
        byte iv[WOLFSSL_TICKET_IV_SZ]; /* cipher iv */
    } openssl_key_ctx;

    static THREAD_LS_T openssl_key_ctx myOpenSSLKey_ctx;
    static THREAD_LS_T WC_RNG myOpenSSLKey_rng;

    static WC_INLINE int OpenSSLTicketInit(void)
    {
        int ret = wc_InitRng(&myOpenSSLKey_rng);
        if (ret != 0) return ret;

        ret = wc_RNG_GenerateBlock(&myOpenSSLKey_rng, myOpenSSLKey_ctx.name,
                sizeof(myOpenSSLKey_ctx.name));
        if (ret != 0) return ret;

        ret = wc_RNG_GenerateBlock(&myOpenSSLKey_rng, myOpenSSLKey_ctx.key,
                sizeof(myOpenSSLKey_ctx.key));
        if (ret != 0) return ret;

        ret = wc_RNG_GenerateBlock(&myOpenSSLKey_rng, myOpenSSLKey_ctx.hmacKey,
                sizeof(myOpenSSLKey_ctx.hmacKey));
        if (ret != 0) return ret;

        ret = wc_RNG_GenerateBlock(&myOpenSSLKey_rng, myOpenSSLKey_ctx.iv,
                sizeof(myOpenSSLKey_ctx.iv));
        if (ret != 0) return ret;

        return 0;
    }

    static int myTicketEncCbOpenSSL(WOLFSSL* ssl,
                             byte name[WOLFSSL_TICKET_NAME_SZ],
                             byte iv[WOLFSSL_TICKET_IV_SZ],
                             WOLFSSL_EVP_CIPHER_CTX *ectx,
                             WOLFSSL_HMAC_CTX *hctx, int enc) {
        (void)ssl;
        if (enc) {
            XMEMCPY(name, myOpenSSLKey_ctx.name, sizeof(myOpenSSLKey_ctx.name));
            XMEMCPY(iv, myOpenSSLKey_ctx.iv, sizeof(myOpenSSLKey_ctx.iv));
        }
        else if (XMEMCMP(name, myOpenSSLKey_ctx.name,
                            sizeof(myOpenSSLKey_ctx.name)) != 0 ||
                 XMEMCMP(iv, myOpenSSLKey_ctx.iv,
                            sizeof(myOpenSSLKey_ctx.iv)) != 0) {
            return 0;
        }
        HMAC_Init_ex(hctx, myOpenSSLKey_ctx.hmacKey, WOLFSSL_TICKET_NAME_SZ, EVP_sha256(), NULL);
        if (enc)
            EVP_EncryptInit_ex(ectx, EVP_aes_256_cbc(), NULL, myOpenSSLKey_ctx.key, iv);
        else
            EVP_DecryptInit_ex(ectx, EVP_aes_256_cbc(), NULL, myOpenSSLKey_ctx.key, iv);
        return 1;
    }

    static WC_INLINE void OpenSSLTicketCleanup(void)
    {
        wc_FreeRng(&myOpenSSLKey_rng);
    }
#endif
#endif

/* helper functions */
#ifdef HAVE_SSL_MEMIO_TESTS_DEPENDENCIES
static WC_INLINE int test_ssl_memio_write_cb(WOLFSSL *ssl, char *data, int sz,
    void *ctx)
{
    struct test_ssl_memio_ctx *test_ctx;
    byte *buf;
    int *len;

    test_ctx = (struct test_ssl_memio_ctx*)ctx;

    if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
        buf = test_ctx->c_buff;
        len = &test_ctx->c_len;
    }
    else {
        buf = test_ctx->s_buff;
        len = &test_ctx->s_len;
    }

    if ((unsigned)(*len + sz) > TEST_SSL_MEMIO_BUF_SZ)
        return WOLFSSL_CBIO_ERR_WANT_WRITE;

    XMEMCPY(buf + *len, data, sz);
    *len += sz;

#ifdef WOLFSSL_DUMP_MEMIO_STREAM
    {
        /* This can be imported into Wireshark by transforming the file with
         *   od -Ax -tx1 -v test_output.dump > test_output.dump.hex
         * And then loading test_output.dump.hex into Wireshark using the
         * "Import from Hex Dump..." option ion and selecting the TCP
         * encapsulation option. */
        char dump_file_name[64];
        WOLFSSL_BIO *dump_file;
        sprintf(dump_file_name, "%s/%s.dump", tmpDirName, currentTestName);
        dump_file = wolfSSL_BIO_new_file(dump_file_name, "a");
        if (dump_file != NULL) {
            (void)wolfSSL_BIO_write(dump_file, data, sz);
            wolfSSL_BIO_free(dump_file);
        }
    }
#endif

    return sz;
}

static WC_INLINE int test_ssl_memio_read_cb(WOLFSSL *ssl, char *data, int sz,
    void *ctx)
{
    struct test_ssl_memio_ctx *test_ctx;
    int read_sz;
    byte *buf;
    int *len;

    test_ctx = (struct test_ssl_memio_ctx*)ctx;

    if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
        buf = test_ctx->s_buff;
        len = &test_ctx->s_len;
    }
    else {
        buf = test_ctx->c_buff;
        len = &test_ctx->c_len;
    }

    if (*len == 0)
        return WOLFSSL_CBIO_ERR_WANT_READ;

    read_sz = sz < *len ? sz : *len;

    XMEMCPY(data, buf, read_sz);
    XMEMMOVE(buf, buf + read_sz, *len - read_sz);

    *len -= read_sz;

    return read_sz;
}

static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
{
    EXPECT_DECLS_NO_MSGS(-2000);
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    int c_sharedCtx = 0;
    int s_sharedCtx = 0;
#endif
    const char* clientCertFile = cliCertFile;
    const char* clientKeyFile = cliKeyFile;
    const char* serverCertFile = svrCertFile;
    const char* serverKeyFile = svrKeyFile;

    /********************************
     * Create WOLFSSL_CTX for client.
     ********************************/
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (ctx->c_ctx != NULL) {
        c_sharedCtx = ctx->c_cb.isSharedCtx;
    }
    else
#endif
    {
        WOLFSSL_METHOD* method  = NULL;
        if (ctx->c_cb.method != NULL) {
            method = ctx->c_cb.method();
        }
        else {
            method = wolfSSLv23_client_method();
        }
        ExpectNotNull(ctx->c_ctx = wolfSSL_CTX_new(method));
    }
    wolfSSL_SetIORecv(ctx->c_ctx, test_ssl_memio_read_cb);
    wolfSSL_SetIOSend(ctx->c_ctx, test_ssl_memio_write_cb);
#ifdef WOLFSSL_ENCRYPTED_KEYS
    wolfSSL_CTX_set_default_passwd_cb(ctx->c_ctx, PasswordCallBack);
#endif
    if (ctx->c_cb.caPemFile != NULL)
        ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx,
                ctx->c_cb.caPemFile, 0), WOLFSSL_SUCCESS);
    else
        ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx,
                caCertFile, 0), WOLFSSL_SUCCESS);
    if (ctx->c_cb.certPemFile != NULL) {
        clientCertFile = ctx->c_cb.certPemFile;
    }
    if (ctx->c_cb.keyPemFile != NULL) {
        clientKeyFile = ctx->c_cb.keyPemFile;
    }
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (!c_sharedCtx)
#endif
    {
        ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->c_ctx,
            clientCertFile), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->c_ctx, clientKeyFile,
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    }
#ifdef HAVE_CRL
    if (ctx->c_cb.crlPemFile != NULL) {
        ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx->c_ctx, WOLFSSL_CRL_CHECKALL),
            WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx->c_ctx, ctx->c_cb.crlPemFile,
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    }
#endif
    if (ctx->c_ciphers != NULL) {
        ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx->c_ctx, ctx->c_ciphers),
            WOLFSSL_SUCCESS);
    }
    if (ctx->c_cb.ctx_ready != NULL) {
        ExpectIntEQ(ctx->c_cb.ctx_ready(ctx->c_ctx), TEST_SUCCESS);
    }


    /********************************
     * Create WOLFSSL_CTX for server.
     ********************************/
    if (ctx->s_ctx != NULL) {
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
        s_sharedCtx = 1;
#endif
        ctx->s_cb.isSharedCtx = 1;
    }
    else
    {
        WOLFSSL_METHOD* method  = NULL;
        if (ctx->s_cb.method != NULL) {
            method = ctx->s_cb.method();
        }
        else {
            method = wolfSSLv23_server_method();
        }
        ExpectNotNull(ctx->s_ctx = wolfSSL_CTX_new(method));
        ctx->s_cb.isSharedCtx = 0;
    }
    if (!ctx->s_cb.ticNoInit && (ctx->s_ctx != NULL)) {
#if defined(HAVE_SESSION_TICKET) && \
    ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC)
        OpenSSLTicketInit();
        wolfSSL_CTX_set_tlsext_ticket_key_cb(ctx->s_ctx, myTicketEncCbOpenSSL);
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
        TicketInit();
        wolfSSL_CTX_set_TicketEncCb(ctx->s_ctx, myTicketEncCb);
#endif
#endif
    }
    wolfSSL_SetIORecv(ctx->s_ctx, test_ssl_memio_read_cb);
    wolfSSL_SetIOSend(ctx->s_ctx, test_ssl_memio_write_cb);
    wolfSSL_CTX_set_verify(ctx->s_ctx, WOLFSSL_VERIFY_PEER |
        WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
    if (ctx->s_cb.caPemFile != NULL)
        ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx,
                ctx->s_cb.caPemFile, 0), WOLFSSL_SUCCESS);
    else
        ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx,
                cliCertFile, 0), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ENCRYPTED_KEYS
    wolfSSL_CTX_set_default_passwd_cb(ctx->s_ctx, PasswordCallBack);
#endif
    if (ctx->s_cb.certPemFile != NULL) {
        serverCertFile = ctx->s_cb.certPemFile;
    }
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (!s_sharedCtx)
#endif
    {
        ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->s_ctx,
            serverCertFile), WOLFSSL_SUCCESS);
    }
    if (ctx->s_cb.keyPemFile != NULL) {
        serverKeyFile = ctx->s_cb.keyPemFile;
    }
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (!s_sharedCtx)
#endif
    {
        ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->s_ctx, serverKeyFile,
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    }
    if (ctx->s_ciphers != NULL) {
        ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx->s_ctx, ctx->s_ciphers),
            WOLFSSL_SUCCESS);
    }
    if (ctx->s_cb.ctx_ready != NULL) {
        ExpectIntEQ(ctx->s_cb.ctx_ready(ctx->s_ctx), TEST_SUCCESS);
    }


    /****************************
     * Create WOLFSSL for client.
     ****************************/
    ExpectNotNull(ctx->c_ssl = wolfSSL_new(ctx->c_ctx));
    wolfSSL_SetIOWriteCtx(ctx->c_ssl, ctx);
    wolfSSL_SetIOReadCtx(ctx->c_ssl, ctx);
    if (0
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
     || c_sharedCtx
#endif
        )
    {
        ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->c_ssl,
                clientCertFile), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->c_ssl, clientKeyFile,
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    }
    if (ctx->c_cb.ssl_ready != NULL) {
        ExpectIntEQ(ctx->c_cb.ssl_ready(ctx->c_ssl), TEST_SUCCESS);
    }

    /****************************
     * Create WOLFSSL for server.
     ****************************/
    ExpectNotNull(ctx->s_ssl = wolfSSL_new(ctx->s_ctx));
    wolfSSL_SetIOWriteCtx(ctx->s_ssl, ctx);
    wolfSSL_SetIOReadCtx(ctx->s_ssl, ctx);
    if (0
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
     || s_sharedCtx
#endif
        )
    {
        ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->s_ssl,
                serverCertFile), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->s_ssl, serverKeyFile,
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    }
#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
    wolfSSL_SetTmpDH_file(ctx->s_ssl, dhParamFile, WOLFSSL_FILETYPE_PEM);
#elif !defined(NO_DH)
    /* will repick suites with DHE, higher priority than PSK */
    SetDH(ctx->s_ssl);
#endif
    if (ctx->s_cb.ssl_ready != NULL) {
        ExpectIntEQ(ctx->s_cb.ssl_ready(ctx->s_ssl), TEST_SUCCESS);
    }

    return EXPECT_RESULT();
}

static int test_ssl_memio_do_handshake(test_ssl_memio_ctx* ctx, int max_rounds,
    int* rounds)
{
    int handshake_complete = 0;
    int hs_c = 0;
    int hs_s = 0;
    int failing_s = 0;
    int failing_c = 0;
    int ret;
    int err;

    if (rounds != NULL) {
        *rounds = 0;
    }
    while ((!handshake_complete) && (max_rounds > 0)) {
        if (!hs_c) {
            wolfSSL_SetLoggingPrefix("client");
            ret = wolfSSL_connect(ctx->c_ssl);
            wolfSSL_SetLoggingPrefix(NULL);
            if (ret == WOLFSSL_SUCCESS) {
                hs_c = 1;
            }
            else {
                err = wolfSSL_get_error(ctx->c_ssl, ret);
                if (err != WOLFSSL_ERROR_WANT_READ &&
                    err != WOLFSSL_ERROR_WANT_WRITE) {
                    char buff[WOLFSSL_MAX_ERROR_SZ];
                    fprintf(stderr, "error = %d, %s\n", err,
                        wolfSSL_ERR_error_string((word32)err, buff));
                    failing_c = 1;
                    hs_c = 1;
                    if (failing_c && failing_s) {
                        break;
                    }
                }
            }
        }
        if (!hs_s) {
            wolfSSL_SetLoggingPrefix("server");
            ret = wolfSSL_accept(ctx->s_ssl);
            wolfSSL_SetLoggingPrefix(NULL);
            if (ret == WOLFSSL_SUCCESS) {
                hs_s = 1;
            }
            else {
                err = wolfSSL_get_error(ctx->s_ssl, ret);
                if (err != WOLFSSL_ERROR_WANT_READ &&
                    err != WOLFSSL_ERROR_WANT_WRITE) {
                    char buff[WOLFSSL_MAX_ERROR_SZ];
                    fprintf(stderr, "error = %d, %s\n", err,
                        wolfSSL_ERR_error_string((word32)err, buff));
                    failing_s = 1;
                    hs_s = 1;
                    if (failing_c && failing_s) {
                        break;
                    }
                }
            }
        }
        handshake_complete = hs_c && hs_s;
        max_rounds--;
        if (rounds != NULL) {
            *rounds += 1;
        }
    }

    if (!handshake_complete || failing_c || failing_s) {
        return TEST_FAIL;
    }

    return TEST_SUCCESS;
}

static int test_ssl_memio_read_write(test_ssl_memio_ctx* ctx)
{
    EXPECT_DECLS_NO_MSGS(-3000);
    char input[1024];
    int idx = 0;
    const char* msg_c = "hello wolfssl!";
    int msglen_c = (int)XSTRLEN(msg_c);
    const char* msg_s = "I hear you fa shizzle!";
    int msglen_s = (int)XSTRLEN(msg_s);

    if (ctx->c_msg != NULL) {
        msg_c = ctx->c_msg;
        msglen_c = ctx->c_msglen;
    }
    if (ctx->s_msg != NULL) {
        msg_s = ctx->s_msg;
        msglen_s = ctx->s_msglen;
    }

    wolfSSL_SetLoggingPrefix("client");
    ExpectIntEQ(wolfSSL_write(ctx->c_ssl, msg_c, msglen_c), msglen_c);
    wolfSSL_SetLoggingPrefix("server");
    ExpectIntGT(idx = wolfSSL_read(ctx->s_ssl, input, sizeof(input) - 1), 0);
    if (idx >= 0) {
        input[idx] = '\0';
    }
    ExpectIntGT(fprintf(stderr, "Client message: %s\n", input), 0);
    ExpectIntEQ(wolfSSL_write(ctx->s_ssl, msg_s, msglen_s), msglen_s);
    ctx->s_cb.return_code = EXPECT_RESULT();
    wolfSSL_SetLoggingPrefix("client");
    ExpectIntGT(idx = wolfSSL_read(ctx->c_ssl, input, sizeof(input) - 1), 0);
    wolfSSL_SetLoggingPrefix(NULL);
    if (idx >= 0) {
        input[idx] = '\0';
    }
    ExpectIntGT(fprintf(stderr, "Server response: %s\n", input), 0);
    ctx->c_cb.return_code = EXPECT_RESULT();
    if (ctx->c_cb.on_result != NULL) {
        ExpectIntEQ(ctx->c_cb.on_result(ctx->c_ssl), TEST_SUCCESS);
    }
    if (ctx->s_cb.on_result != NULL) {
        ExpectIntEQ(ctx->s_cb.on_result(ctx->s_ssl), TEST_SUCCESS);
    }

    return EXPECT_RESULT();
}

static void test_ssl_memio_cleanup(test_ssl_memio_ctx* ctx)
{
    ctx->c_cb.last_err = wolfSSL_get_error(ctx->c_ssl, 0);
    ctx->s_cb.last_err = wolfSSL_get_error(ctx->s_ssl, 0);
    if (ctx->c_cb.on_cleanup != NULL) {
        ctx->c_cb.on_cleanup(ctx->c_ssl);
    }
    if (ctx->s_cb.on_cleanup != NULL) {
        ctx->s_cb.on_cleanup(ctx->s_ssl);
    }
    wolfSSL_shutdown(ctx->s_ssl);
    wolfSSL_shutdown(ctx->c_ssl);
    wolfSSL_free(ctx->s_ssl);
    wolfSSL_free(ctx->c_ssl);
    if (ctx->c_cb.on_ctx_cleanup != NULL) {
        ctx->c_cb.on_ctx_cleanup(ctx->c_ctx);
    }
    if (!ctx->c_cb.isSharedCtx) {
        wolfSSL_CTX_free(ctx->c_ctx);
        ctx->c_ctx = NULL;
    }
    if (ctx->s_cb.on_ctx_cleanup != NULL) {
        ctx->s_cb.on_ctx_cleanup(ctx->s_ctx);
    }
    if (!ctx->s_cb.isSharedCtx) {
        wolfSSL_CTX_free(ctx->s_ctx);
        ctx->s_ctx = NULL;
    }

    if (!ctx->s_cb.ticNoInit) {
#if defined(HAVE_SESSION_TICKET) && \
    ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC)
        OpenSSLTicketCleanup();
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
        TicketCleanup();
#endif
#endif
    }
}

int test_wolfSSL_client_server_nofail_memio(test_ssl_cbf* client_cb,
    test_ssl_cbf* server_cb, cbType client_on_handshake)
{
    /* We use EXPECT_DECLS_NO_MSGS() here because this helper routine is used
     * for numerous but varied expected-to-fail scenarios that should not emit
     * error messages on the expected failures.  Instead, we return a distinct
     * code for each failure point, allowing the caller to assert on a
     * particular mode of expected failure.  On success, the usual TEST_SUCCESS
     * is returned.
     */
    EXPECT_DECLS_NO_MSGS(-1000);
    struct test_ssl_memio_ctx test_ctx;
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
    size_t msg_len;
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    XMEMCPY(&test_ctx.c_cb, client_cb, sizeof(test_ssl_cbf));
    XMEMCPY(&test_ctx.s_cb, server_cb, sizeof(test_ssl_cbf));

    test_ctx.c_ctx = client_cb->ctx;
    test_ctx.s_ctx = server_cb->ctx;
    test_ctx.c_cb.return_code = EXPECT_FAILURE_CODEPOINT_ID;
    test_ctx.s_cb.return_code = EXPECT_FAILURE_CODEPOINT_ID;

    ExpectIntEQ(test_ssl_memio_setup(&test_ctx), TEST_SUCCESS);
    ExpectIntEQ(test_ssl_memio_do_handshake(&test_ctx, 10, NULL), TEST_SUCCESS);

    if (client_on_handshake != NULL) {
        ExpectIntEQ(client_on_handshake(test_ctx.c_ctx, test_ctx.c_ssl),
            TEST_SUCCESS);
    }
    if (client_cb->on_handshake != NULL) {
        ExpectIntEQ(client_cb->on_handshake(&test_ctx.c_ctx, &test_ctx.c_ssl),
            TEST_SUCCESS);
    }
    if (server_cb->on_handshake != NULL) {
        ExpectIntEQ(server_cb->on_handshake(&test_ctx.s_ctx, &test_ctx.s_ssl),
            TEST_SUCCESS);
    }
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
    XMEMSET(server_side_msg2, 0, MD_MAX_SIZE);
    msg_len = wolfSSL_get_peer_finished(test_ctx.s_ssl, server_side_msg2,
        MD_MAX_SIZE);
    ExpectIntGE(msg_len, 0);

    XMEMSET(server_side_msg1, 0, MD_MAX_SIZE);
    msg_len = wolfSSL_get_finished(test_ctx.s_ssl, server_side_msg1,
        MD_MAX_SIZE);
    ExpectIntGE(msg_len, 0);
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */

    ExpectIntEQ(test_ssl_memio_read_write(&test_ctx), TEST_SUCCESS);
    test_ssl_memio_cleanup(&test_ctx);

    client_cb->return_code = test_ctx.c_cb.return_code;
    client_cb->last_err = test_ctx.c_cb.last_err;
    server_cb->return_code = test_ctx.s_cb.return_code;
    server_cb->last_err = test_ctx.s_cb.last_err;

    return EXPECT_RESULT();
}
#endif

#ifdef HAVE_IO_TESTS_DEPENDENCIES

#ifdef WOLFSSL_SESSION_EXPORT
#ifdef WOLFSSL_DTLS
/* set up function for sending session information */
static int test_export(WOLFSSL* inSsl, byte* buf, word32 sz, void* userCtx)
{
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;

    AssertNotNull(inSsl);
    AssertNotNull(buf);
    AssertIntNE(0, sz);

    /* Set ctx to DTLS 1.2 */
    ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
    AssertNotNull(ctx);

    ssl = wolfSSL_new(ctx);
    AssertNotNull(ssl);

    AssertIntGE(wolfSSL_dtls_import(ssl, buf, sz), 0);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    (void)userCtx;
    return 0;
}
#endif

/* returns negative value on fail and positive (including 0) on success */
static int nonblocking_accept_read(void* args, WOLFSSL* ssl, SOCKET_T* sockfd)
{
    int ret, err, loop_count, count, timeout = 10;
    char msg[] = "I hear you fa shizzle!";
    char input[1024];

    loop_count = ((func_args*)args)->argc;

    #ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
    #endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_accept(ssl);
        err = wolfSSL_get_error(ssl, 0);

        if (err == WOLFSSL_ERROR_WANT_READ ||
            err == WOLFSSL_ERROR_WANT_WRITE) {
            int select_ret;

            err = WC_PENDING_E;
            select_ret = tcp_select(*sockfd, timeout);
            if (select_ret == TEST_TIMEOUT) {
                return WOLFSSL_FATAL_ERROR;
            }
        }
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    if (ret != WOLFSSL_SUCCESS) {
        char buff[WOLFSSL_MAX_ERROR_SZ];
        fprintf(stderr, "error = %d, %s\n", err,
            wolfSSL_ERR_error_string(err, buff));
        return ret;
    }

    for (count = 0; count < loop_count; count++) {
        int select_ret;

        select_ret = tcp_select(*sockfd, timeout);
        if (select_ret == TEST_TIMEOUT) {
            ret = WOLFSSL_FATAL_ERROR;
            break;
        }

        do {
            ret = wolfSSL_read(ssl, input, sizeof(input)-1);
            if (ret > 0) {
                input[ret] = '\0';
                fprintf(stderr, "Client message: %s\n", input);
            }
        } while (err == WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_SUCCESS);

        do {
            if ((ret = wolfSSL_write(ssl, msg, sizeof(msg))) != sizeof(msg)) {
                return WOLFSSL_FATAL_ERROR;
            }
            err = wolfSSL_get_error(ssl, ret);
        } while (err == WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_SUCCESS);
    }
    return ret;
}
#endif /* WOLFSSL_SESSION_EXPORT */

static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
{
    SOCKET_T sockfd = 0;
    SOCKET_T clientfd = 0;
    word16 port;

    callback_functions* cbf;
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL* ssl = NULL;
    func_args* opts = (func_args*)args;

    char msg[] = "I hear you fa shizzle!";
    char input[1024];
    int idx;
    int ret, err = 0;
    int sharedCtx = 0;
    int doUdp = 0;
    SOCKADDR_IN_T cliAddr;
    socklen_t     cliLen;
    const char* certFile = svrCertFile;
    const char* keyFile = svrKeyFile;

#ifdef WOLFSSL_HAVE_TLS_UNIQUE
    size_t msg_len = 0;
#endif

    wolfSSL_SetLoggingPrefix("server");

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    opts->return_code = TEST_FAIL;
    cbf = opts->callbacks;

    if (cbf != NULL && cbf->ctx) {
        ctx = cbf->ctx;
        sharedCtx = 1;
    }
    else
    {
        WOLFSSL_METHOD* method = NULL;
        if (cbf != NULL && cbf->method != NULL) {
            method = cbf->method();

        }
        else {
            method = wolfSSLv23_server_method();
        }
        ctx = wolfSSL_CTX_new(method);
    }
    if (ctx == NULL) {
        /* Release the wait for TCP ready. */
        signal_ready(opts->signal);
        goto done;
    }

    if (cbf == NULL || !cbf->ticNoInit) {
#if defined(HAVE_SESSION_TICKET) && \
    ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC)
        OpenSSLTicketInit();
        wolfSSL_CTX_set_tlsext_ticket_key_cb(ctx, myTicketEncCbOpenSSL);
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
        TicketInit();
        wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
#endif
#endif
    }

#if defined(USE_WINDOWS_API)
    port = opts->signal->port;
#elif defined(NO_MAIN_DRIVER) && !defined(WOLFSSL_SNIFFER) && \
     !defined(WOLFSSL_MDK_SHELL) && !defined(WOLFSSL_TIRTOS)
    /* Let tcp_listen assign port */
    port = 0;
#else
    /* Use default port */
    port = wolfSSLPort;
#endif

    if (cbf != NULL)
        doUdp = cbf->doUdp;

    /* do it here to detect failure */
    tcp_accept(
        &sockfd, &clientfd, opts, port, 0, doUdp, 0, 0, 1, 0, 0);

    if (doUdp) {
        cliLen = sizeof(cliAddr);

        idx = (int)recvfrom(sockfd, input, sizeof(input), MSG_PEEK,
                  (struct sockaddr*)&cliAddr, &cliLen);

        AssertIntGT(idx, 0);
    }
    else {
        CloseSocket(sockfd);
    }

    wolfSSL_CTX_set_verify(ctx,
                  WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);

#ifdef WOLFSSL_ENCRYPTED_KEYS
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    if (wolfSSL_CTX_load_verify_locations(ctx, cliCertFile, 0)
                                                           != WOLFSSL_SUCCESS) {
        /*err_sys("can't load ca file, Please run from wolfSSL home dir");*/
        goto done;
    }

    if (cbf != NULL && cbf->certPemFile != NULL)
        certFile = cbf->certPemFile;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, certFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#else
    if (wolfSSL_CTX_use_certificate_file(ctx, certFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#endif
        /*err_sys("can't load server cert chain file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }

    if (cbf != NULL && cbf->keyPemFile != NULL)
        keyFile = cbf->keyPemFile;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, keyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#else
    if (wolfSSL_CTX_use_PrivateKey_file(ctx, keyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#endif
        /*err_sys("can't load server key file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }

#ifdef HAVE_CRL
    if (cbf != NULL && cbf->crlPemFile != NULL) {
        if (wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL) != WOLFSSL_SUCCESS)
            goto done;
        if (wolfSSL_CTX_LoadCRLFile(ctx, cbf->crlPemFile, WOLFSSL_FILETYPE_PEM)
                != WOLFSSL_SUCCESS)
            goto done;
    }
#endif

    /* call ctx setup callback */
    if (cbf != NULL && cbf->ctx_ready != NULL) {
        cbf->ctx_ready(ctx);
    }

    ssl = wolfSSL_new(ctx);
    if (ssl == NULL) {
        goto done;
    }

    if (doUdp) {
        err = wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen);
        if (err != WOLFSSL_SUCCESS)
            goto done;
    }

#ifdef WOLFSSL_SESSION_EXPORT
    /* only add in more complex nonblocking case with session export tests */
    if (args && opts->argc > 0) {
        /* set as nonblock and time out for waiting on read/write */
        tcp_set_nonblocking(&clientfd);
        wolfSSL_dtls_set_using_nonblock(ssl, 1);
    }
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (sharedCtx && wolfSSL_use_certificate_file(ssl, certFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#else
    if (wolfSSL_use_certificate_file(ssl, certFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#endif
        /*err_sys("can't load server cert chain file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (sharedCtx && wolfSSL_use_PrivateKey_file(ssl, keyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#else
    if (wolfSSL_use_PrivateKey_file(ssl, keyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#endif
        /*err_sys("can't load server key file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }

    if (wolfSSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS) {
        /*err_sys("SSL_set_fd failed");*/
        goto done;
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
    wolfSSL_SetTmpDH_file(ssl, dhParamFile, WOLFSSL_FILETYPE_PEM);
#elif !defined(NO_DH)
    SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
#endif

    /* call ssl setup callback */
    if (cbf != NULL && cbf->ssl_ready != NULL) {
        cbf->ssl_ready(ssl);
    }

#ifdef WOLFSSL_SESSION_EXPORT
    /* only add in more complex nonblocking case with session export tests */
    if (opts->argc > 0) {
        ret = nonblocking_accept_read(args, ssl, &clientfd);
        if (ret >= 0) {
            opts->return_code = TEST_SUCCESS;
        }
    #ifdef WOLFSSL_TIRTOS
        Task_yield();
    #endif
        goto done;
    }
#endif

    #ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
    #endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_negotiate(ssl);
        err = wolfSSL_get_error(ssl, 0);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    if (ret != WOLFSSL_SUCCESS) {
        char buff[WOLFSSL_MAX_ERROR_SZ];
        fprintf(stderr, "error = %d, %s\n", err,
            wolfSSL_ERR_error_string((word32)err, buff));
        /*err_sys("SSL_accept failed");*/
        goto done;
    }

#ifdef WOLFSSL_HAVE_TLS_UNIQUE
    XMEMSET(server_side_msg2, 0, MD_MAX_SIZE);
    msg_len = wolfSSL_get_peer_finished(ssl, server_side_msg2, MD_MAX_SIZE);
    AssertIntGE(msg_len, 0);

    XMEMSET(server_side_msg1, 0, MD_MAX_SIZE);
    msg_len = wolfSSL_get_finished(ssl, server_side_msg1, MD_MAX_SIZE);
    AssertIntGE(msg_len, 0);
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */

    idx = wolfSSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = '\0';
        fprintf(stderr, "Client message: %s\n", input);
    }
    else if (idx < 0) {
        goto done;
    }

    if (wolfSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) {
        /*err_sys("SSL_write failed");*/
        goto done;
    }

    if (cbf != NULL && cbf->on_result != NULL)
        cbf->on_result(ssl);

#ifdef WOLFSSL_TIRTOS
    Task_yield();
#endif

    opts->return_code = TEST_SUCCESS;

done:
    if (cbf != NULL)
        cbf->last_err = err;
    if (cbf != NULL && cbf->on_cleanup != NULL)
        cbf->on_cleanup(ssl);

    wolfSSL_shutdown(ssl);
    wolfSSL_free(ssl);
    if (!sharedCtx)
        wolfSSL_CTX_free(ctx);

    CloseSocket(clientfd);

#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

    if (cbf == NULL || !cbf->ticNoInit) {
#if defined(HAVE_SESSION_TICKET) && \
    ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC)
        OpenSSLTicketCleanup();
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
        TicketCleanup();
#endif
#endif
    }

    wolfSSL_SetLoggingPrefix(NULL);

    WOLFSSL_RETURN_FROM_THREAD(0);
}

#if defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && \
    !defined(WOLFSSL_NO_TLS12)
static THREAD_RETURN WOLFSSL_THREAD test_server_loop(void* args)
{
    SOCKET_T sockfd;
    SOCKET_T clientfd = -1;
    word16 port;

    callback_functions* cbf;
    WOLFSSL_CTX* ctx = 0;
    WOLFSSL* ssl = 0;

    char msg[] = "I hear you fa shizzle!";
    char input[1024];
    int idx;
    int ret, err = 0;
    int sharedCtx = 0;
    func_args* opts = (func_args*)args;
    int loop_count = opts->argc;
    int count = 0;

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    opts->return_code = TEST_FAIL;
    cbf = opts->callbacks;

#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (cbf != NULL && cbf->ctx) {
        ctx = cbf->ctx;
        sharedCtx = 1;
    }
    else
#endif
    {
        WOLFSSL_METHOD* method = NULL;
        if (cbf != NULL && cbf->method != NULL) {
            method = cbf->method();
        }
        else {
            method = wolfSSLv23_server_method();
        }
        ctx = wolfSSL_CTX_new(method);
    }

#if defined(USE_WINDOWS_API)
    port = opts->signal->port;
#elif defined(NO_MAIN_DRIVER) && !defined(WOLFSSL_SNIFFER) && \
     !defined(WOLFSSL_MDK_SHELL) && !defined(WOLFSSL_TIRTOS)
    /* Let tcp_listen assign port */
    port = 0;
#else
    /* Use default port */
    port = wolfSSLPort;
#endif

    wolfSSL_CTX_set_verify(ctx,
                  WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);

#ifdef WOLFSSL_ENCRYPTED_KEYS
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    if (wolfSSL_CTX_load_verify_locations(ctx, cliCertFile, 0)
                                                           != WOLFSSL_SUCCESS) {
        /*err_sys("can't load ca file, Please run from wolfSSL home dir");*/
        /* Release the wait for TCP ready. */
        signal_ready(opts->signal);
        goto done;
    }
    if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
        /*err_sys("can't load server cert chain file, "
                "Please run from wolfSSL home dir");*/
        /* Release the wait for TCP ready. */
        signal_ready(opts->signal);
        goto done;
    }
    if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
        /*err_sys("can't load server key file, "
                "Please run from wolfSSL home dir");*/
        /* Release the wait for TCP ready. */
        signal_ready(opts->signal);
        goto done;
    }
    /* call ctx setup callback */
    if (cbf != NULL && cbf->ctx_ready != NULL) {
        cbf->ctx_ready(ctx);
    }

    while (count != loop_count) {
        ssl = wolfSSL_new(ctx);
        if (ssl == NULL) {
            signal_ready(opts->signal);
            goto done;
        }
        if (sharedCtx && wolfSSL_use_certificate_file(ssl, svrCertFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            /*err_sys("can't load server cert chain file, "
                    "Please run from wolfSSL home dir");*/
            /* Release the wait for TCP ready. */
            signal_ready(opts->signal);
            goto done;
        }
        if (sharedCtx && wolfSSL_use_PrivateKey_file(ssl, svrKeyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            /*err_sys("can't load server key file, "
                    "Please run from wolfSSL home dir");*/
            /* Release the wait for TCP ready. */
            signal_ready(opts->signal);
            goto done;
        }

#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
        wolfSSL_SetTmpDH_file(ssl, dhParamFile, WOLFSSL_FILETYPE_PEM);
#elif !defined(NO_DH)
        SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
#endif
        /* call ssl setup callback */
        if (cbf != NULL && cbf->ssl_ready != NULL) {
            cbf->ssl_ready(ssl);
        }
        /* do it here to detect failure */
        tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0,
            0);
        CloseSocket(sockfd);
        if (wolfSSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS) {
            /*err_sys("SSL_set_fd failed");*/
            goto done;
        }

        #ifdef WOLFSSL_ASYNC_CRYPT
        err = 0; /* Reset error */
        #endif
        do {
        #ifdef WOLFSSL_ASYNC_CRYPT
            if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
                ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
                if (ret < 0) { break; } else if (ret == 0) { continue; }
            }
        #endif
            ret = wolfSSL_accept(ssl);
            err = wolfSSL_get_error(ssl, 0);
        } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
        if (ret != WOLFSSL_SUCCESS) {
            char buff[WOLFSSL_MAX_ERROR_SZ];
            fprintf(stderr, "error = %d, %s\n", err,
                wolfSSL_ERR_error_string(err, buff));
            /*err_sys("SSL_accept failed");*/
            goto done;
        }

        idx = wolfSSL_read(ssl, input, sizeof(input)-1);
        if (idx > 0) {
            input[idx] = '\0';
            fprintf(stderr, "Client message: %s\n", input);
        }

        if (wolfSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) {
            /*err_sys("SSL_write failed");*/
            goto done;
        }
        /* free ssl for this connection */
        wolfSSL_shutdown(ssl);
        wolfSSL_free(ssl); ssl = NULL;
        CloseSocket(clientfd);
        clientfd = -1;

        count++;
    }
#ifdef WOLFSSL_TIRTOS
    Task_yield();
#endif

    opts->return_code = TEST_SUCCESS;

done:
    if (ssl != NULL) {
        wolfSSL_shutdown(ssl);
        wolfSSL_free(ssl);
    }
    if (!sharedCtx)
        wolfSSL_CTX_free(ctx);

    if (clientfd >= 0)
        CloseSocket(clientfd);

#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

    WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && !defined(WOLFSSL_TLS13) */

static int test_client_nofail(void* args, cbType cb)
{
#if !defined(NO_WOLFSSL_CLIENT)
    SOCKET_T sockfd = 0;
    callback_functions* cbf;

    WOLFSSL_CTX*     ctx     = 0;
    WOLFSSL*         ssl     = 0;
    WOLFSSL_CIPHER*  cipher;

    char msg[64] = "hello wolfssl!";
    char reply[1024];
    int  input;
    int  msgSz = (int)XSTRLEN(msg);
    int  ret, err = 0;
    int  cipherSuite;
    int  sharedCtx = 0;
    int  doUdp = 0;
    const char* cipherName1, *cipherName2;

    wolfSSL_SetLoggingPrefix("client");

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    ((func_args*)args)->return_code = TEST_FAIL;
    cbf = ((func_args*)args)->callbacks;

#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (cbf != NULL && cbf->ctx) {
        ctx = cbf->ctx;
        sharedCtx = cbf->isSharedCtx;
    }
    else
#endif
    {
        WOLFSSL_METHOD* method  = NULL;
        if (cbf != NULL && cbf->method != NULL) {
            method = cbf->method();
        }
        else {
            method = wolfSSLv23_client_method();
        }
        ctx = wolfSSL_CTX_new(method);
    }

    if (cbf != NULL)
        doUdp = cbf->doUdp;

#ifdef WOLFSSL_ENCRYPTED_KEYS
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    /* Do connect here so server detects failures */
    tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port,
                doUdp, 0, NULL);
    /* Connect the socket so that we don't have to set the peer later on */
    if (doUdp)
        udp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port);

    if (wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0) != WOLFSSL_SUCCESS)
    {
        /* err_sys("can't load ca file, Please run from wolfSSL home dir");*/
        goto done;
    }
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, cliCertFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#else
    if (wolfSSL_CTX_use_certificate_file(ctx, cliCertFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#endif
        /*err_sys("can't load client cert file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#else
    if (wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#endif

        /*err_sys("can't load client key file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }

#ifdef HAVE_CRL
    if (cbf != NULL && cbf->crlPemFile != NULL) {
        if (wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL) != WOLFSSL_SUCCESS)
            goto done;
        if (wolfSSL_CTX_LoadCRLFile(ctx, cbf->crlPemFile, WOLFSSL_FILETYPE_PEM)
                != WOLFSSL_SUCCESS)
            goto done;
    }
#endif

    /* call ctx setup callback */
    if (cbf != NULL && cbf->ctx_ready != NULL) {
        cbf->ctx_ready(ctx);
    }

    ssl = wolfSSL_new(ctx);
    if (ssl == NULL) {
        goto done;
    }
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (sharedCtx && wolfSSL_use_certificate_file(ssl, cliCertFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#else
    if (wolfSSL_use_certificate_file(ssl, cliCertFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#endif
        /*err_sys("can't load client cert file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (sharedCtx && wolfSSL_use_PrivateKey_file(ssl, cliKeyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#else
    if (wolfSSL_use_PrivateKey_file(ssl, cliKeyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
#endif
        /*err_sys("can't load client key file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }

    if (!doUdp) {
        if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
            /*err_sys("SSL_set_fd failed");*/
            goto done;
        }
    }
    else {
#ifdef WOLFSSL_DTLS
        if (wolfSSL_set_dtls_fd_connected(ssl, sockfd) != WOLFSSL_SUCCESS) {
            /*err_sys("SSL_set_fd failed");*/
            goto done;
        }
#else
        goto done;
#endif
    }

    /* call ssl setup callback */
    if (cbf != NULL && cbf->ssl_ready != NULL) {
        cbf->ssl_ready(ssl);
    }

    #ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
    #endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_negotiate(ssl);
        err = wolfSSL_get_error(ssl, 0);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    if (ret != WOLFSSL_SUCCESS) {
        char buff[WOLFSSL_MAX_ERROR_SZ];
        fprintf(stderr, "error = %d, %s\n", err,
            wolfSSL_ERR_error_string((word32)err, buff));
        /*err_sys("SSL_connect failed");*/
        goto done;
    }

    /* test the various get cipher methods */
    /* Internal cipher suite names */
    cipherSuite = wolfSSL_get_current_cipher_suite(ssl);
    cipherName1 = wolfSSL_get_cipher_name(ssl);
    cipherName2 = wolfSSL_get_cipher_name_from_suite(
        (byte)(cipherSuite >> 8), cipherSuite & 0xFF);
    AssertStrEQ(cipherName1, cipherName2);

    /* IANA Cipher Suites Names */
    /* Unless WOLFSSL_CIPHER_INTERNALNAME or NO_ERROR_STRINGS,
        then it's the internal cipher suite name */
    cipher = wolfSSL_get_current_cipher(ssl);
    cipherName1 = wolfSSL_CIPHER_get_name(cipher);
    cipherName2 = wolfSSL_get_cipher(ssl);
    AssertStrEQ(cipherName1, cipherName2);
#if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
    !defined(WOLFSSL_QT)
    cipherName1 = wolfSSL_get_cipher_name_iana_from_suite(
            (byte)(cipherSuite >> 8), cipherSuite & 0xFF);
    AssertStrEQ(cipherName1, cipherName2);
#endif

    if (cb != NULL)
        (cb)(ctx, ssl);

    if (wolfSSL_write(ssl, msg, msgSz) != msgSz) {
        /*err_sys("SSL_write failed");*/
        goto done;
    }

    input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
    if (input > 0) {
        reply[input] = '\0';
        fprintf(stderr, "Server response: %s\n", reply);
    }

    if (cbf != NULL && cbf->on_result != NULL)
        cbf->on_result(ssl);

    ((func_args*)args)->return_code = TEST_SUCCESS;

done:
    if (cbf != NULL)
        cbf->last_err = err;
    if (cbf != NULL && cbf->on_cleanup != NULL)
        cbf->on_cleanup(ssl);

    wolfSSL_free(ssl);
    if (!sharedCtx)
        wolfSSL_CTX_free(ctx);

    CloseSocket(sockfd);

#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

#else
    (void)args;
    (void)cb;
#endif /* !NO_WOLFSSL_CLIENT */

    wolfSSL_SetLoggingPrefix(NULL);

    return 0;
}

void test_wolfSSL_client_server_nofail_ex(callback_functions* client_cb,
    callback_functions* server_cb, cbType client_on_handshake)
{
    func_args client_args;
    func_args server_args;
    tcp_ready ready;
    THREAD_TYPE serverThread;

    XMEMSET(&client_args, 0, sizeof(func_args));
    XMEMSET(&server_args, 0, sizeof(func_args));

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    StartTCP();
    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    server_args.signal = &ready;
    server_args.callbacks = server_cb;
    client_args.signal = &ready;
    client_args.callbacks = client_cb;

    start_thread(test_server_nofail, &server_args, &serverThread);
    wait_tcp_ready(&server_args);
    test_client_nofail(&client_args, client_on_handshake);
    join_thread(serverThread);

    client_cb->return_code = client_args.return_code;
    server_cb->return_code = server_args.return_code;

    FreeTcpReady(&ready);

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif
}

void test_wolfSSL_client_server_nofail(callback_functions* client_cb,
    callback_functions* server_cb)
{
    test_wolfSSL_client_server_nofail_ex(client_cb, server_cb, NULL);
}


#if defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && \
   !defined(WOLFSSL_NO_TLS12) && !defined(NO_WOLFSSL_CLIENT)
static void test_client_reuse_WOLFSSLobj(void* args, cbType cb,
                                         void* server_args)
{
    SOCKET_T sockfd = 0;
    callback_functions* cbf;

    WOLFSSL_CTX*     ctx     = 0;
    WOLFSSL*         ssl     = 0;
    WOLFSSL_SESSION* session = NULL;

    char msg[64] = "hello wolfssl!";
    char reply[1024];
    int  input;
    int  msgSz = (int)XSTRLEN(msg);
    int  ret, err = 0;
    int  sharedCtx = 0;

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    ((func_args*)args)->return_code = TEST_FAIL;
    cbf = ((func_args*)args)->callbacks;

#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
    if (cbf != NULL && cbf->ctx) {
        ctx = cbf->ctx;
        sharedCtx = 1;
    }
    else
#endif
    {
        WOLFSSL_METHOD* method  = NULL;
        if (cbf != NULL && cbf->method != NULL) {
            method = cbf->method();
        }
        else {
            method = wolfSSLv23_client_method();
        }
        ctx = wolfSSL_CTX_new(method);
    }

#ifdef WOLFSSL_ENCRYPTED_KEYS
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    /* Do connect here so server detects failures */
    tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port,
                0, 0, NULL);

    if (wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0) !=
                                                              WOLFSSL_SUCCESS) {
        /* err_sys("can't load ca file, Please run from wolfSSL home dir");*/
        goto done;
    }
    if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, cliCertFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
        /*err_sys("can't load client cert file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }
    if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
        /*err_sys("can't load client key file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }

    /* call ctx setup callback */
    if (cbf != NULL && cbf->ctx_ready != NULL) {
        cbf->ctx_ready(ctx);
    }

    ssl = wolfSSL_new(ctx);
    if (ssl == NULL) {
        goto done;
    }
    /* keep handshake resources for re-using WOLFSSL obj */
    wolfSSL_KeepArrays(ssl);
    if (wolfSSL_KeepHandshakeResources(ssl)) {
        /* err_sys("SSL_KeepHandshakeResources failed"); */
        goto done;
    }
    if (sharedCtx && wolfSSL_use_certificate_file(ssl, cliCertFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
        /*err_sys("can't load client cert file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }
    if (sharedCtx && wolfSSL_use_PrivateKey_file(ssl, cliKeyFile,
                                     WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
        /*err_sys("can't load client key file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }

    if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
        /*err_sys("SSL_set_fd failed");*/
        goto done;
    }

    /* call ssl setup callback */
    if (cbf != NULL && cbf->ssl_ready != NULL) {
        cbf->ssl_ready(ssl);
    }

    #ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
    #endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_connect(ssl);
        err = wolfSSL_get_error(ssl, 0);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    if (ret != WOLFSSL_SUCCESS) {
        char buff[WOLFSSL_MAX_ERROR_SZ];
        fprintf(stderr, "error = %d, %s\n", err,
            wolfSSL_ERR_error_string(err, buff));
        /*err_sys("SSL_connect failed");*/
        goto done;
    }
    /* Build first session */
    if (cb != NULL)
        cb(ctx, ssl);

    if (wolfSSL_write(ssl, msg, msgSz) != msgSz) {
        /*err_sys("SSL_write failed");*/
        goto done;
    }

    input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
    if (input > 0) {
        reply[input] = '\0';
        fprintf(stderr, "Server response: %s\n", reply);
    }

    /* Session Resumption by re-using WOLFSSL object */
    wolfSSL_set_quiet_shutdown(ssl, 1);
    if (wolfSSL_shutdown(ssl) != WOLFSSL_SUCCESS) {
        /* err_sys ("SSL shutdown failed"); */
        goto done;
    }
    session = wolfSSL_get1_session(ssl);
    if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
        wolfSSL_SESSION_free(session);
        /* err_sys ("SSL_clear failed"); */
        goto done;
    }
    wolfSSL_set_session(ssl, session);
    wolfSSL_SESSION_free(session);
    session = NULL;
    /* close socket once */
    CloseSocket(sockfd);
    sockfd = 0;
    /* wait until server ready */
    wait_tcp_ready((func_args*)server_args);
    fprintf(stderr, "session resumption\n");
    /* Do re-connect  */
    tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port,
                0, 0, NULL);
    if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
        /*err_sys("SSL_set_fd failed");*/
        goto done;
    }

    #ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
    #endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_connect(ssl);
        err = wolfSSL_get_error(ssl, 0);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    if (ret != WOLFSSL_SUCCESS) {
        char buff[WOLFSSL_MAX_ERROR_SZ];
        fprintf(stderr, "error = %d, %s\n", err,
            wolfSSL_ERR_error_string(err, buff));
        /*err_sys("SSL_connect failed");*/
        goto done;
    }
    /* Build first session */
    if (cb != NULL)
        cb(ctx, ssl);

    if (wolfSSL_write(ssl, msg, msgSz) != msgSz) {
        /*err_sys("SSL_write failed");*/
        goto done;
    }

    input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
    if (input > 0) {
        reply[input] = '\0';
        fprintf(stderr, "Server response: %s\n", reply);
    }

    ((func_args*)args)->return_code = TEST_SUCCESS;

done:
    wolfSSL_free(ssl);
    if (!sharedCtx)
        wolfSSL_CTX_free(ctx);

    CloseSocket(sockfd);

#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

    return;
}
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) &&
         !defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_CLIENT) */

#if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
     defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)) && \
    defined(HAVE_ALPN) && defined(HAVE_SNI) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(NO_BIO)
    #define HAVE_ALPN_PROTOS_SUPPORT
#endif

/* Generic TLS client / server with callbacks for API unit tests
 * Used by SNI / ALPN / crypto callback helper functions */
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && \
    (defined(HAVE_SNI) || defined(HAVE_ALPN) || defined(WOLF_CRYPTO_CB) || \
     defined(HAVE_ALPN_PROTOS_SUPPORT)) || defined(WOLFSSL_STATIC_MEMORY)
    #define ENABLE_TLS_CALLBACK_TEST
#endif

#if defined(ENABLE_TLS_CALLBACK_TEST) || \
    (defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT))
/* TLS server for API unit testing - generic */
static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args)
{
    callback_functions* callbacks = ((func_args*)args)->callbacks;

    WOLFSSL_CTX*    ctx = NULL;
    WOLFSSL*        ssl = NULL;
    SOCKET_T        sfd = 0;
    SOCKET_T        cfd = 0;
    word16          port;

    char msg[] = "I hear you fa shizzle!";
    int  len   = (int) XSTRLEN(msg);
    char input[1024];
    int  idx;
    int  ret, err = 0;

    ((func_args*)args)->return_code = TEST_FAIL;

#if defined(USE_WINDOWS_API)
    port = ((func_args*)args)->signal->port;
#elif defined(NO_MAIN_DRIVER) && !defined(WOLFSSL_SNIFFER) && \
     !defined(WOLFSSL_MDK_SHELL) && !defined(WOLFSSL_TIRTOS)
    /* Let tcp_listen assign port */
    port = 0;
#else
    /* Use default port */
    port = wolfSSLPort;
#endif

#ifdef WOLFSSL_DTLS
    if (callbacks->method == wolfDTLS_server_method
#ifdef WOLFSSL_STATIC_MEMORY
     || callbacks->method_ex == wolfDTLS_server_method_ex
#endif
#ifndef NO_OLD_TLS
     || callbacks->method == wolfDTLSv1_server_method
#ifdef WOLFSSL_STATIC_MEMORY
     || callbacks->method_ex == wolfDTLSv1_server_method_ex
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
     || callbacks->method == wolfDTLSv1_2_server_method
#ifdef WOLFSSL_STATIC_MEMORY
     || callbacks->method_ex == wolfDTLSv1_2_server_method_ex
#endif
#endif
#ifdef WOLFSSL_DTLS13
     || callbacks->method == wolfDTLSv1_3_server_method
#ifdef WOLFSSL_STATIC_MEMORY
     || callbacks->method_ex == wolfDTLSv1_3_server_method_ex
#endif
#endif
        ) {
        tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0, 0, 0, 0);
    }
    else
#endif
    {
        tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0, 0);
    }

#ifdef WOLFSSL_STATIC_MEMORY
    if (callbacks->method_ex != NULL && callbacks->mem != NULL &&
        callbacks->memSz > 0) {
        ret = wolfSSL_CTX_load_static_memory(&ctx, callbacks->method_ex,
            callbacks->mem, callbacks->memSz, 0, 1);
        if (ret != WOLFSSL_SUCCESS) {
            fprintf(stderr, "CTX static new failed %d\n", ret);
            goto cleanup;
        }
    }
#else
    ctx = wolfSSL_CTX_new(callbacks->method());
#endif
    if (ctx == NULL) {
        fprintf(stderr, "CTX new failed\n");
        goto cleanup;
    }

    /* set defaults */
    if (callbacks->caPemFile == NULL)
        callbacks->caPemFile = cliCertFile;
    if (callbacks->certPemFile == NULL)
        callbacks->certPemFile = svrCertFile;
    if (callbacks->keyPemFile == NULL)
        callbacks->keyPemFile = svrKeyFile;

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    wolfSSL_CTX_SetDevId(ctx, callbacks->devId);

    wolfSSL_CTX_set_verify(ctx,
                  WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);

#ifdef WOLFSSL_ENCRYPTED_KEYS
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
#if defined(WOLFSSL_SESSION_EXPORT) && defined(WOLFSSL_DTLS)
    if (callbacks->method == wolfDTLSv1_2_server_method) {
        if (wolfSSL_CTX_dtls_set_export(ctx, test_export) != WOLFSSL_SUCCESS)
            goto cleanup;
    }
#endif


    if (wolfSSL_CTX_load_verify_locations(ctx, callbacks->caPemFile, 0) !=
            WOLFSSL_SUCCESS) {
        goto cleanup;
    }

    if (wolfSSL_CTX_use_certificate_file(ctx, callbacks->certPemFile,
            WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
        goto cleanup;
    }

    if (wolfSSL_CTX_use_PrivateKey_file(ctx, callbacks->keyPemFile,
            WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
        goto cleanup;
    }

#ifdef HAVE_CRL
    if (callbacks->crlPemFile != NULL) {
        if (wolfSSL_CTX_LoadCRLFile(ctx, callbacks->crlPemFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            goto cleanup;
        }
    }
#endif

    if (callbacks->ctx_ready)
        callbacks->ctx_ready(ctx);

    ssl = wolfSSL_new(ctx);
    if (ssl == NULL) {
        fprintf(stderr, "SSL new failed\n");
        goto cleanup;
    }
    if (wolfSSL_dtls(ssl)) {
        SOCKADDR_IN_T cliAddr;
        socklen_t     cliLen;

        cliLen = sizeof(cliAddr);
        idx = (int)recvfrom(sfd, input, sizeof(input), MSG_PEEK,
                (struct sockaddr*)&cliAddr, &cliLen);
        if (idx <= 0) {
            goto cleanup;
        }
        wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen);
    }
    else {
        CloseSocket(sfd);
    }

    if (wolfSSL_set_fd(ssl, cfd) != WOLFSSL_SUCCESS) {
        goto cleanup;
    }

    if (callbacks->loadToSSL) {
        wolfSSL_SetDevId(ssl, callbacks->devId);

        if (wolfSSL_use_certificate_file(ssl, callbacks->certPemFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            goto cleanup;
        }

        if (wolfSSL_use_PrivateKey_file(ssl, callbacks->keyPemFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            goto cleanup;
        }
    }

#ifdef NO_PSK
    #if !defined(NO_FILESYSTEM) && !defined(NO_DH)
        wolfSSL_SetTmpDH_file(ssl, dhParamFile, WOLFSSL_FILETYPE_PEM);
    #elif !defined(NO_DH)
        SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
    #endif
#endif

    if (callbacks->ssl_ready)
        callbacks->ssl_ready(ssl);

#ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
#endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_accept(ssl);
        err = wolfSSL_get_error(ssl, ret);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    if (ret != WOLFSSL_SUCCESS) {
        char buff[WOLFSSL_MAX_ERROR_SZ];
        fprintf(stderr, "accept error = %d, %s\n", err,
            wolfSSL_ERR_error_string((word32)err, buff));
        /*err_sys("SSL_accept failed");*/
    }
    else {
    #ifdef WOLFSSL_ASYNC_CRYPT
        err = 0; /* Reset error */
    #endif
        do {
        #ifdef WOLFSSL_ASYNC_CRYPT
            if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
                ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
                if (ret < 0) { break; } else if (ret == 0) { continue; }
            }
        #endif
            idx = wolfSSL_read(ssl, input, sizeof(input)-1);
            err = wolfSSL_get_error(ssl, idx);
        } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
        if (idx > 0) {
            input[idx] = 0;
            fprintf(stderr, "Client message: %s\n", input);
        }

    #ifdef WOLFSSL_ASYNC_CRYPT
        err = 0; /* Reset error */
    #endif
        do {
        #ifdef WOLFSSL_ASYNC_CRYPT
            if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
                ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
                if (ret < 0) { break; } else if (ret == 0) { continue; }
            }
        #endif
            ret = wolfSSL_write(ssl, msg, len);
            err = wolfSSL_get_error(ssl, ret);
        } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
        if (len != ret) {
            goto cleanup;
        }

#if defined(WOLFSSL_SESSION_EXPORT) && !defined(HAVE_IO_POOL) && \
        defined(WOLFSSL_DTLS)
        if (wolfSSL_dtls(ssl)) {
            byte*  import;
            word32 sz;

            wolfSSL_dtls_export(ssl, NULL, &sz);
            import = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            if (import == NULL) {
                goto cleanup;
            }
            idx = wolfSSL_dtls_export(ssl, import, &sz);
            if (idx < 0) {
                goto cleanup;
            }
            if (wolfSSL_dtls_import(ssl, import, idx) < 0) {
                goto cleanup;
            }
            XFREE(import, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        }
#endif
#ifdef WOLFSSL_TIRTOS
        Task_yield();
#endif
        ((func_args*)args)->return_code = TEST_SUCCESS;
    }

    if (callbacks->on_result)
        callbacks->on_result(ssl);

    wolfSSL_shutdown(ssl);

cleanup:
    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    CloseSocket(cfd);


#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

    WOLFSSL_RETURN_FROM_THREAD(0);
}

/* TLS Client for API unit testing - generic */
static void run_wolfssl_client(void* args)
{
    callback_functions* callbacks = ((func_args*)args)->callbacks;

    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;
    SOCKET_T    sfd = 0;

    char msg[] = "hello wolfssl server!";
    int  len   = (int) XSTRLEN(msg);
    char input[1024];
    int  ret, err = 0;

    ((func_args*)args)->return_code = TEST_FAIL;

    /* set defaults */
    if (callbacks->caPemFile == NULL)
        callbacks->caPemFile = caCertFile;
    if (callbacks->certPemFile == NULL)
        callbacks->certPemFile = cliCertFile;
    if (callbacks->keyPemFile == NULL)
        callbacks->keyPemFile = cliKeyFile;

#ifdef WOLFSSL_STATIC_MEMORY
    if (callbacks->method_ex != NULL && callbacks->mem != NULL &&
        callbacks->memSz > 0) {
        ret = wolfSSL_CTX_load_static_memory(&ctx, callbacks->method_ex,
            callbacks->mem, callbacks->memSz, 0, 1);
        if (ret != WOLFSSL_SUCCESS) {
            fprintf(stderr, "CTX static new failed %d\n", ret);
            goto cleanup;
        }
    }
#else
    ctx = wolfSSL_CTX_new(callbacks->method());
#endif
    if (ctx == NULL) {
        fprintf(stderr, "CTX new failed\n");
        goto cleanup;
    }

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    if (!callbacks->loadToSSL) {
        wolfSSL_CTX_SetDevId(ctx, callbacks->devId);
    }

#ifdef WOLFSSL_ENCRYPTED_KEYS
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    if (wolfSSL_CTX_load_verify_locations(ctx, callbacks->caPemFile, 0) !=
            WOLFSSL_SUCCESS) {
        goto cleanup;
    }

    if (!callbacks->loadToSSL) {
        if (wolfSSL_CTX_use_certificate_file(ctx, callbacks->certPemFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            goto cleanup;
        }

        if (wolfSSL_CTX_use_PrivateKey_file(ctx, callbacks->keyPemFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            goto cleanup;
        }
    }

#ifdef HAVE_CRL
    if (callbacks->crlPemFile != NULL) {
        if (wolfSSL_CTX_LoadCRLFile(ctx, callbacks->crlPemFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            goto cleanup;
        }
    }
#endif

    if (callbacks->ctx_ready)
        callbacks->ctx_ready(ctx);

    ssl = wolfSSL_new(ctx);
    if (wolfSSL_dtls(ssl)) {
        tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port,
                    1, 0, ssl);
    }
    else {
        tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port,
                    0, 0, ssl);
    }
    if (wolfSSL_set_fd(ssl, sfd) != WOLFSSL_SUCCESS) {
        goto cleanup;
    }

    if (callbacks->loadToSSL) {
        wolfSSL_SetDevId(ssl, callbacks->devId);

        if (wolfSSL_use_certificate_file(ssl, callbacks->certPemFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            goto cleanup;
        }

        if (wolfSSL_use_PrivateKey_file(ssl, callbacks->keyPemFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
            goto cleanup;
        }
    }

    if (callbacks->ssl_ready)
        callbacks->ssl_ready(ssl);

    #ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
    #endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_connect(ssl);
        err = wolfSSL_get_error(ssl, ret);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    if (ret != WOLFSSL_SUCCESS) {
        char buff[WOLFSSL_MAX_ERROR_SZ];
        fprintf(stderr, "error = %d, %s\n", err,
            wolfSSL_ERR_error_string((word32)err, buff));
        /*err_sys("SSL_connect failed");*/
    }
    else {
        #ifdef WOLFSSL_ASYNC_CRYPT
        err = 0; /* Reset error */
        #endif
        do {
        #ifdef WOLFSSL_ASYNC_CRYPT
            if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
                ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
                if (ret < 0) { break; } else if (ret == 0) { continue; }
            }
        #endif
            ret = wolfSSL_write(ssl, msg, len);
            err = wolfSSL_get_error(ssl, ret);
        } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
        if (len != ret)
            goto cleanup;

        #ifdef WOLFSSL_ASYNC_CRYPT
        err = 0; /* Reset error */
        #endif
        do {
        #ifdef WOLFSSL_ASYNC_CRYPT
            if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
                ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
                if (ret < 0) { break; } else if (ret == 0) { continue; }
            }
        #endif
            ret = wolfSSL_read(ssl, input, sizeof(input)-1);
            err = wolfSSL_get_error(ssl, ret);
        } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
        if (ret > 0) {
            input[ret] = '\0'; /* null term */
            fprintf(stderr, "Server response: %s\n", input);
        }
        ((func_args*)args)->return_code = TEST_SUCCESS;
    }

    if (callbacks->on_result)
        callbacks->on_result(ssl);

cleanup:
    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    CloseSocket(sfd);

#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif
}

#endif /* ENABLE_TLS_CALLBACK_TEST */


static int test_wolfSSL_read_write(void)
{
    /* The unit testing for read and write shall happen simultaneously, since
     * one can't do anything with one without the other. (Except for a failure
     * test case.) This function will call all the others that will set up,
     * execute, and report their test findings.
     *
     * Set up the success case first. This function will become the template
     * for the other tests. This should eventually be renamed
     *
     * The success case isn't interesting, how can this fail?
     * - Do not give the client context a CA certificate. The connect should
     *   fail. Do not need server for this?
     * - Using NULL for the ssl object on server. Do not need client for this.
     * - Using NULL for the ssl object on client. Do not need server for this.
     * - Good ssl objects for client and server. Client write() without server
     *   read().
     * - Good ssl objects for client and server. Server write() without client
     *   read().
     * - Forgetting the password callback?
    */
    tcp_ready ready;
    func_args client_args;
    func_args server_args;
    THREAD_TYPE serverThread;
    EXPECT_DECLS;

    XMEMSET(&client_args, 0, sizeof(func_args));
    XMEMSET(&server_args, 0, sizeof(func_args));
#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    StartTCP();
    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    server_args.signal = &ready;
    client_args.signal = &ready;

    start_thread(test_server_nofail, &server_args, &serverThread);
    wait_tcp_ready(&server_args);
    test_client_nofail(&client_args, NULL);
    join_thread(serverThread);

    ExpectTrue(client_args.return_code);
    ExpectTrue(server_args.return_code);

    FreeTcpReady(&ready);

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_reuse_WOLFSSLobj(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && \
    !defined(WOLFSSL_NO_TLS12)
    /* The unit test for session resumption by re-using WOLFSSL object.
     * WOLFSSL object is not cleared after first session. It reuse the object
     * for second connection.
    */
    tcp_ready ready;
    func_args client_args;
    func_args server_args;
    THREAD_TYPE serverThread;
    callback_functions client_cbf;
    callback_functions server_cbf;

    XMEMSET(&client_args, 0, sizeof(func_args));
    XMEMSET(&server_args, 0, sizeof(func_args));
    XMEMSET(&client_cbf, 0, sizeof(callback_functions));
    XMEMSET(&server_cbf, 0, sizeof(callback_functions));
#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    StartTCP();
    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    client_cbf.method = wolfTLSv1_2_client_method;
    server_cbf.method = wolfTLSv1_2_server_method;
    client_args.callbacks = &client_cbf;
    server_args.callbacks = &server_cbf;

    server_args.signal = &ready;
    client_args.signal = &ready;
    /* the var is used for loop number */
    server_args.argc = 2;

    start_thread(test_server_loop, &server_args, &serverThread);
    wait_tcp_ready(&server_args);
    test_client_reuse_WOLFSSLobj(&client_args, NULL, &server_args);
    join_thread(serverThread);

    ExpectTrue(client_args.return_code);
    ExpectTrue(server_args.return_code);

    FreeTcpReady(&ready);

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) &&
        * !defined(WOLFSSL_TLS13) */
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CTX_verifyDepth_ServerClient_1_ctx_ready(
    WOLFSSL_CTX* ctx)
{
    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
    myVerifyAction = VERIFY_USE_PREVERFIY;
    wolfSSL_CTX_set_verify_depth(ctx, 2);
    return TEST_SUCCESS;
}
#endif

static int test_wolfSSL_CTX_verifyDepth_ServerClient_1(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;

    XMEMSET(&client_cbf, 0, sizeof(client_cbf));
    XMEMSET(&server_cbf, 0, sizeof(server_cbf));

#ifdef WOLFSSL_TLS13
    client_cbf.method = wolfTLSv1_3_client_method;
#endif /* WOLFSSL_TLS13 */
    client_cbf.ctx_ready =
        test_wolfSSL_CTX_verifyDepth_ServerClient_1_ctx_ready;

    /* test case 1 verify depth is equal to peer chain */
    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
        &server_cbf, NULL), TEST_SUCCESS);

    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
#endif /* OPENSSL_EXTRA && HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */

    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CTX_verifyDepth_ServerClient_2_ctx_ready(
    WOLFSSL_CTX* ctx)
{
    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
    myVerifyAction = VERIFY_OVERRIDE_ERROR;
    wolfSSL_CTX_set_verify_depth(ctx, 0);
    return TEST_SUCCESS;
}
#endif

static int test_wolfSSL_CTX_verifyDepth_ServerClient_2(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;

    XMEMSET(&client_cbf, 0, sizeof(client_cbf));
    XMEMSET(&server_cbf, 0, sizeof(server_cbf));

#ifdef WOLFSSL_TLS13
    client_cbf.method = wolfTLSv1_3_client_method;
#endif /* WOLFSSL_TLS13 */
    client_cbf.ctx_ready =
        test_wolfSSL_CTX_verifyDepth_ServerClient_2_ctx_ready;

    /* test case 2
     * verify depth is zero, number of peer's chain is 2.
     * verify result becomes MAX_CHAIN_ERROR, but it is overridden in
     * callback.
     */
    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
        &server_cbf, NULL), TEST_SUCCESS);

    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
#endif /* OPENSSL_EXTRA && HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */

    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CTX_verifyDepth_ServerClient_3_ctx_ready(
    WOLFSSL_CTX* ctx)
{
    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
    myVerifyAction = VERIFY_USE_PREVERFIY;
    wolfSSL_CTX_set_verify_depth(ctx, 0);
    return TEST_SUCCESS;
}
#endif

static int test_wolfSSL_CTX_verifyDepth_ServerClient_3(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;

    XMEMSET(&client_cbf, 0, sizeof(client_cbf));
    XMEMSET(&server_cbf, 0, sizeof(server_cbf));

#ifdef WOLFSSL_TLS13
    client_cbf.method = wolfTLSv1_3_client_method;
#endif /* WOLFSSL_TLS13 */
    client_cbf.ctx_ready =
        test_wolfSSL_CTX_verifyDepth_ServerClient_3_ctx_ready;

    /* test case 3
     * verify depth is zero, number of peer's chain is 2
     * verify result becomes MAX_CHAIN_ERRO. call-back returns failure.
     * therefore, handshake becomes failure.
     */
    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
        &server_cbf, NULL), -1001);

    ExpectIntEQ(client_cbf.return_code, -1000);
    ExpectIntEQ(server_cbf.return_code, -1000);
    ExpectIntEQ(client_cbf.last_err, WC_NO_ERR_TRACE(MAX_CHAIN_ERROR));
    ExpectIntEQ(server_cbf.last_err, WC_NO_ERR_TRACE(FATAL_ERROR));
#endif /* OPENSSL_EXTRA && HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */

    return EXPECT_RESULT();
}

#if defined(OPENSSL_ALL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    !defined(WOLFSSL_NO_TLS12) && \
    defined(HAVE_ECC) && !defined(NO_AES) && !defined(NO_SHA256)
static int test_wolfSSL_CTX_set_cipher_list_server_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, "DEFAULT:!NULL"));
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_set_cipher_list_client_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-SHA256"));
    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_CTX_set_cipher_list(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(HAVE_ECC) && !defined(NO_AES) && !defined(NO_SHA256)

    #if !defined(WOLFSSL_NO_TLS12)
    WOLFSSL_CTX* ctxClient = NULL;
    WOLFSSL*     sslClient = NULL;
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;

    XMEMSET(&client_cbf, 0, sizeof(client_cbf));
    XMEMSET(&server_cbf, 0, sizeof(server_cbf));

    server_cbf.method = wolfTLSv1_2_server_method;
    server_cbf.ctx_ready = test_wolfSSL_CTX_set_cipher_list_server_ctx_ready;
    client_cbf.method = wolfTLSv1_2_client_method;
    client_cbf.ctx_ready = test_wolfSSL_CTX_set_cipher_list_client_ctx_ready;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
        &server_cbf, NULL), TEST_SUCCESS);

    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);

    /* check with cipher string that has '+' */
    ExpectNotNull((ctxClient = wolfSSL_CTX_new(wolfTLSv1_2_client_method())));
    /* Use trailing : with nothing to test for ASAN */
    ExpectTrue(wolfSSL_CTX_set_cipher_list(ctxClient, "ECDHE+AESGCM:"));
    ExpectNotNull((sslClient = wolfSSL_new(ctxClient)));

    /* check for the existence of an ECDHE ECDSA cipher suite */
    if (EXPECT_SUCCESS()) {
        int i = 0;
        int found = 0;
        const char* suite;

        WOLF_STACK_OF(WOLFSSL_CIPHER)* sk = NULL;
        WOLFSSL_CIPHER* current;

        ExpectNotNull((sk = wolfSSL_get_ciphers_compat(sslClient)));
        do {
            current = wolfSSL_sk_SSL_CIPHER_value(sk, i++);
            if (current) {
                suite = wolfSSL_CIPHER_get_name(current);
                if (suite && XSTRSTR(suite, "ECDSA")) {
                    found = 1;
                    break;
                }
            }
        } while (current);
        ExpectIntEQ(found, 1);
    }

    wolfSSL_free(sslClient);
    wolfSSL_CTX_free(ctxClient);

    #endif /* !WOLFSSL_NO_TLS12 */
#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(WOLFSSL_HAVE_TLS_UNIQUE)
static int test_wolfSSL_get_finished_client_on_handshake(WOLFSSL_CTX* ctx,
    WOLFSSL* ssl)
{
    EXPECT_DECLS;
    size_t msg_len;

    (void)ctx;

    /* get_finished test */
    /* 1. get own sent message */
    XMEMSET(client_side_msg1, 0, MD_MAX_SIZE);
    msg_len = wolfSSL_get_finished(ssl, client_side_msg1, MD_MAX_SIZE);
    ExpectIntGE(msg_len, 0);
    /* 2. get peer message */
    XMEMSET(client_side_msg2, 0, MD_MAX_SIZE);
    msg_len = wolfSSL_get_peer_finished(ssl, client_side_msg2, MD_MAX_SIZE);
    ExpectIntGE(msg_len, 0);

    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_get_finished(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(WOLFSSL_HAVE_TLS_UNIQUE)
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;

    XMEMSET(&client_cbf, 0, sizeof(client_cbf));
    XMEMSET(&server_cbf, 0, sizeof(server_cbf));

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
        &server_cbf, test_wolfSSL_get_finished_client_on_handshake),
        TEST_SUCCESS);

    /* test received msg vs sent msg */
    ExpectIntEQ(0, XMEMCMP(client_side_msg1, server_side_msg2, MD_MAX_SIZE));
    ExpectIntEQ(0, XMEMCMP(client_side_msg2, server_side_msg1, MD_MAX_SIZE));
#endif /* HAVE_SSL_MEMIO_TESTS_DEPENDENCIES && WOLFSSL_HAVE_TLS_UNIQUE */

    return EXPECT_RESULT();
}

#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
    !defined(SINGLE_THREADED) && defined(WOLFSSL_TLS13) && \
    !defined(NO_SESSION_CACHE)

/* Sessions to restore/store */
static WOLFSSL_SESSION* test_wolfSSL_CTX_add_session_client_sess;
static WOLFSSL_SESSION* test_wolfSSL_CTX_add_session_server_sess;
static WOLFSSL_CTX*     test_wolfSSL_CTX_add_session_server_ctx;

static void test_wolfSSL_CTX_add_session_ctx_ready(WOLFSSL_CTX* ctx)
{
    /* Don't store sessions. Lookup is still enabled. */
    AssertIntEQ(wolfSSL_CTX_set_session_cache_mode(ctx,
            WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE), WOLFSSL_SUCCESS);
#ifdef OPENSSL_EXTRA
    AssertIntEQ(wolfSSL_CTX_get_session_cache_mode(ctx) &
            WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE,
            WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE);
#endif
    /* Require both peers to provide certs */
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
}

static void test_wolfSSL_CTX_add_session_on_result(WOLFSSL* ssl)
{
    WOLFSSL_SESSION** sess;
    if (wolfSSL_is_server(ssl))
        sess = &test_wolfSSL_CTX_add_session_server_sess;
    else
        sess = &test_wolfSSL_CTX_add_session_client_sess;
    if (*sess == NULL) {
#ifdef NO_SESSION_CACHE_REF
        AssertNotNull(*sess = wolfSSL_get1_session(ssl));
#else
        /* Test for backwards compatibility */
        if (wolfSSL_is_server(ssl)) {
            AssertNotNull(*sess = wolfSSL_get1_session(ssl));
        }
        else {
            AssertNotNull(*sess = wolfSSL_get_session(ssl));
        }
#endif
        /* Now save the session in the internal store to make it available
         * for lookup. For TLS 1.3, we can't save the session without
         * WOLFSSL_TICKET_HAVE_ID because there is no way to retrieve the
         * session from cache. */
        if (wolfSSL_is_server(ssl)
#ifndef WOLFSSL_TICKET_HAVE_ID
                && wolfSSL_version(ssl) != TLS1_3_VERSION
#endif
                )
            AssertIntEQ(wolfSSL_CTX_add_session(wolfSSL_get_SSL_CTX(ssl),
                    *sess), WOLFSSL_SUCCESS);
    }
    else {
        /* If we have a session retrieved then remaining connections should be
         * resuming on that session */
        AssertIntEQ(wolfSSL_session_reused(ssl), 1);
    }
    /* Save CTX to be able to decrypt tickets */
    if (wolfSSL_is_server(ssl) &&
            test_wolfSSL_CTX_add_session_server_ctx == NULL) {
        AssertNotNull(test_wolfSSL_CTX_add_session_server_ctx
                = wolfSSL_get_SSL_CTX(ssl));
        AssertIntEQ(wolfSSL_CTX_up_ref(wolfSSL_get_SSL_CTX(ssl)),
                WOLFSSL_SUCCESS);
    }
#ifdef SESSION_CERTS
#ifndef WOLFSSL_TICKET_HAVE_ID
    if (wolfSSL_version(ssl) != TLS1_3_VERSION &&
            wolfSSL_session_reused(ssl))
#endif
    {
        /* With WOLFSSL_TICKET_HAVE_ID the peer certs should be available
         * for all connections. TLS 1.3 only has tickets so if we don't
         * include the session id in the ticket then the certificates
         * will not be available on resumption. */
        WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
        AssertNotNull(peer);
        wolfSSL_X509_free(peer);
        AssertNotNull(wolfSSL_SESSION_get_peer_chain(*sess));
    #ifdef OPENSSL_EXTRA
        AssertNotNull(SSL_SESSION_get0_peer(*sess));
    #endif
    }
#endif /* SESSION_CERTS */
}

static void test_wolfSSL_CTX_add_session_ssl_ready(WOLFSSL* ssl)
{
    /* Set the session to reuse for the client */
    AssertIntEQ(wolfSSL_set_session(ssl,
            test_wolfSSL_CTX_add_session_client_sess), WOLFSSL_SUCCESS);
}
#endif

static int test_wolfSSL_CTX_add_session(void)
{
    EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
    !defined(SINGLE_THREADED) && defined(WOLFSSL_TLS13) && \
    !defined(NO_SESSION_CACHE)
    tcp_ready ready;
    func_args client_args;
    func_args server_args;
    THREAD_TYPE serverThread;
    callback_functions client_cb;
    callback_functions server_cb;
    method_provider methods[][2] = {
#if !defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
        !defined(NO_DES3))
        /* Without AES there are almost no ciphersuites available. This leads
         * to no ciphersuites being available and an error. */
        { wolfTLSv1_1_client_method, wolfTLSv1_1_server_method },
#endif
#ifndef WOLFSSL_NO_TLS12
        { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method },
#endif
        /* Needs the default ticket callback since it is tied to the
         * connection context and this makes it easy to carry over the ticket
         * crypto context between connections */
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
    defined(HAVE_SESSION_TICKET)
        { wolfTLSv1_3_client_method, wolfTLSv1_3_server_method },
#endif
    };
    const size_t methodsLen = sizeof(methods)/sizeof(*methods);
    size_t i, j;

    for (i = 0; i < methodsLen; i++) {
        /* First run creates a connection while the second+ run will attempt
         * to resume the connection. The trick is that the internal cache
         * is turned off. wolfSSL_CTX_add_session should put the session in
         * the cache anyway. */
        test_wolfSSL_CTX_add_session_client_sess = NULL;
        test_wolfSSL_CTX_add_session_server_sess = NULL;
        test_wolfSSL_CTX_add_session_server_ctx = NULL;

#ifdef NO_SESSION_CACHE_REF
        for (j = 0; j < 4; j++) {
#else
        /* The session may be overwritten in this case. Do only one resumption
         * to stop this test from failing intermittently. */
        for (j = 0; j < 2; j++) {
#endif
#ifdef WOLFSSL_TIRTOS
            fdOpenSession(Task_self());
#endif

            StartTCP();
            InitTcpReady(&ready);

            XMEMSET(&client_args, 0, sizeof(func_args));
            XMEMSET(&server_args, 0, sizeof(func_args));

            XMEMSET(&client_cb, 0, sizeof(callback_functions));
            XMEMSET(&server_cb, 0, sizeof(callback_functions));
            client_cb.method  = methods[i][0];
            server_cb.method  = methods[i][1];

            server_args.signal    = &ready;
            server_args.callbacks = &server_cb;
            client_args.signal    = &ready;
            client_args.callbacks = &client_cb;

            if (test_wolfSSL_CTX_add_session_server_ctx != NULL) {
                server_cb.ctx = test_wolfSSL_CTX_add_session_server_ctx;
                server_cb.isSharedCtx = 1;
            }
            server_cb.ctx_ready = test_wolfSSL_CTX_add_session_ctx_ready;
            client_cb.ctx_ready = test_wolfSSL_CTX_add_session_ctx_ready;
            if (j != 0)
                client_cb.ssl_ready = test_wolfSSL_CTX_add_session_ssl_ready;
            server_cb.on_result = test_wolfSSL_CTX_add_session_on_result;
            client_cb.on_result = test_wolfSSL_CTX_add_session_on_result;
            server_cb.ticNoInit = 1; /* Use default builtin */

            start_thread(test_server_nofail, &server_args, &serverThread);
            wait_tcp_ready(&server_args);
            test_client_nofail(&client_args, NULL);
            join_thread(serverThread);

            ExpectTrue(client_args.return_code);
            ExpectTrue(server_args.return_code);

            FreeTcpReady(&ready);

            if (EXPECT_FAIL())
                break;
        }
        wolfSSL_SESSION_free(test_wolfSSL_CTX_add_session_client_sess);
        wolfSSL_SESSION_free(test_wolfSSL_CTX_add_session_server_sess);
        wolfSSL_CTX_free(test_wolfSSL_CTX_add_session_server_ctx);

        if (EXPECT_FAIL())
            break;
    }
#endif

    return EXPECT_RESULT();
}
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
     defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
     defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
     defined(HAVE_SESSION_TICKET) && \
    !defined(TITAN_SESSION_CACHE) && \
    !defined(HUGE_SESSION_CACHE) && \
    !defined(BIG_SESSION_CACHE) && \
    !defined(MEDIUM_SESSION_CACHE)

/* twcase - prefix for test_wolfSSL_CTX_add_session_ext */
/* Sessions to restore/store */
static WOLFSSL_SESSION* twcase_server_first_session_ptr;
static WOLFSSL_SESSION* twcase_client_first_session_ptr;
static WOLFSSL_CTX*     twcase_server_current_ctx_ptr;
static int twcase_new_session_called    = 0;
static int twcase_remove_session_called = 0;
static int twcase_get_session_called    = 0;

/* Test default, SESSIONS_PER_ROW*SESSION_ROWS = 3*11, see ssl.c */
#define SESSION_CACHE_SIZE 33

typedef struct {
    const byte* key;  /* key, altSessionID, session ID, NULL if empty */
    WOLFSSL_SESSION* value;
} hashTable_entry;

typedef struct {
    hashTable_entry entries[SESSION_CACHE_SIZE];  /* hash slots */
    size_t capacity;                     /* size of entries */
    size_t length;                       /* number of items in the hash table */
    wolfSSL_Mutex htLock;                /* lock */
}hashTable;

static hashTable server_sessionCache;

static int twcase_new_sessionCb(WOLFSSL *ssl, WOLFSSL_SESSION *sess)
{
    int i;
    unsigned int len;
    (void)ssl;

    /*
     * This example uses a hash table.
     * Steps you should take for a non-demo code:
     * - acquire a lock for the file named according to the session id
     * - open the file
     * - encrypt and write the SSL_SESSION object to the file
     * - release the lock
     *
     * Return:
     *  0: The callback does not wish to hold a reference of the sess
     *  1: The callback wants to hold a reference of the sess. The callback is
     *     now also responsible for calling wolfSSL_SESSION_free() on sess.
     */
    if (sess == NULL)
        return 0;

    if (wc_LockMutex(&server_sessionCache.htLock) != 0) {
        return 0;
    }
    for (i = 0; i < SESSION_CACHE_SIZE; i++) {
        if (server_sessionCache.entries[i].value == NULL) {
            server_sessionCache.entries[i].key = SSL_SESSION_get_id(sess, &len);
            server_sessionCache.entries[i].value = sess;
            server_sessionCache.length++;
            break;
        }
    }
    ++twcase_new_session_called;
    wc_UnLockMutex(&server_sessionCache.htLock);
    fprintf(stderr, "\t\ttwcase_new_session_called %d\n",
            twcase_new_session_called);
    return 1;
}

static void twcase_remove_sessionCb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
{
    int i;
    (void)ctx;
    (void)sess;

    if (sess == NULL)
        return;
    /*
     * This example uses a hash table.
     * Steps you should take for a non-demo code:
     * - acquire a lock for the file named according to the session id
     * - remove the file
     * - release the lock
     */
    if (wc_LockMutex(&server_sessionCache.htLock) != 0) {
        return;
    }
    for (i = 0; i < SESSION_CACHE_SIZE; i++) {
        if (server_sessionCache.entries[i].key != NULL &&
           XMEMCMP(server_sessionCache.entries[i].key,
                   sess->sessionID, SSL_MAX_SSL_SESSION_ID_LENGTH) == 0) {
            wolfSSL_SESSION_free(server_sessionCache.entries[i].value);
            server_sessionCache.entries[i].value = NULL;
            server_sessionCache.entries[i].key = NULL;
            server_sessionCache.length--;
            break;
        }
    }
    ++twcase_remove_session_called;
    wc_UnLockMutex(&server_sessionCache.htLock);
    fprintf(stderr, "\t\ttwcase_remove_session_called %d\n",
            twcase_remove_session_called);
}

static WOLFSSL_SESSION *twcase_get_sessionCb(WOLFSSL *ssl,
                                  const unsigned char *id, int len, int *ref)
{
    int i;
    (void)ssl;
    (void)id;
    (void)len;

    /*
     * This example uses a hash table.
     * Steps you should take for a non-demo code:
     * - acquire a lock for the file named according to the session id in the
     *   2nd arg
     * - read and decrypt contents of file and create a new SSL_SESSION
     * - object release the lock
     * - return the new session object
     */
    fprintf(stderr, "\t\ttwcase_get_session_called %d\n",
            ++twcase_get_session_called);
    /* This callback want to retain a copy of the object. If we want wolfSSL to
     * be responsible for the pointer then set to 0. */
    *ref = 1;

    for (i = 0; i < SESSION_CACHE_SIZE; i++) {
        if (server_sessionCache.entries[i].key != NULL &&
           XMEMCMP(server_sessionCache.entries[i].key, id,
                   SSL_MAX_SSL_SESSION_ID_LENGTH) == 0) {
           return server_sessionCache.entries[i].value;
        }
    }
    return NULL;
}
static int twcase_get_sessionCb_cleanup(void)
{
    int i;
    int cnt = 0;

    /* If  twcase_get_sessionCb sets *ref = 1, the application is responsible
     * for freeing sessions */

    for (i = 0; i < SESSION_CACHE_SIZE; i++) {
        if (server_sessionCache.entries[i].value != NULL) {
            wolfSSL_SESSION_free(server_sessionCache.entries[i].value);
            cnt++;
        }
    }

    fprintf(stderr, "\t\ttwcase_get_sessionCb_cleanup freed %d sessions\n",
            cnt);

    return TEST_SUCCESS;
}

static int twcase_cache_intOff_extOff(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    /* off - Disable internal cache */
    ExpectIntEQ(wolfSSL_CTX_set_session_cache_mode(ctx,
            WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE), WOLFSSL_SUCCESS);
#ifdef OPENSSL_EXTRA
    ExpectIntEQ(wolfSSL_CTX_get_session_cache_mode(ctx) &
            WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE,
            WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE);
#endif
    /* off - Do not setup external cache */

    /* Require both peers to provide certs */
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
    return EXPECT_RESULT();
}

static int twcase_cache_intOn_extOff(WOLFSSL_CTX* ctx)
{
    /* on - internal cache is on by default */
    /* off - Do not setup external cache */
    /* Require both peers to provide certs */
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
    return TEST_SUCCESS;
}

static int twcase_cache_intOff_extOn(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    /* off - Disable internal cache */
    ExpectIntEQ(wolfSSL_CTX_set_session_cache_mode(ctx,
            WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE), WOLFSSL_SUCCESS);
#ifdef OPENSSL_EXTRA
    ExpectIntEQ(wolfSSL_CTX_get_session_cache_mode(ctx) &
            WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE,
            WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE);
#endif
    /* on - Enable external cache */
    wolfSSL_CTX_sess_set_new_cb(ctx, twcase_new_sessionCb);
    wolfSSL_CTX_sess_set_remove_cb(ctx, twcase_remove_sessionCb);
    wolfSSL_CTX_sess_set_get_cb(ctx, twcase_get_sessionCb);

    /* Require both peers to provide certs */
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
    return EXPECT_RESULT();
}

static int twcase_cache_intOn_extOn(WOLFSSL_CTX* ctx)
{
    /* on - internal cache is on by default */
    /* on - Enable external cache */
    wolfSSL_CTX_sess_set_new_cb(ctx, twcase_new_sessionCb);
    wolfSSL_CTX_sess_set_remove_cb(ctx, twcase_remove_sessionCb);
    wolfSSL_CTX_sess_set_get_cb(ctx, twcase_get_sessionCb);

    /* Require both peers to provide certs */
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
    return TEST_SUCCESS;
}
static int twcase_cache_intOn_extOn_noTicket(WOLFSSL_CTX* ctx)
{
    /* on - internal cache is on by default */
    /* on - Enable external cache */
    wolfSSL_CTX_sess_set_new_cb(ctx, twcase_new_sessionCb);
    wolfSSL_CTX_sess_set_remove_cb(ctx, twcase_remove_sessionCb);
    wolfSSL_CTX_sess_set_get_cb(ctx, twcase_get_sessionCb);

    wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TICKET);
    /* Require both peers to provide certs */
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
    return TEST_SUCCESS;
}
static int twcase_server_sess_ctx_pre_shutdown(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    WOLFSSL_SESSION** sess;
    if (wolfSSL_is_server(ssl))
        sess = &twcase_server_first_session_ptr;
    else
        return TEST_SUCCESS;

    if (*sess == NULL) {
        ExpectNotNull(*sess = wolfSSL_get1_session(ssl));
        /* Now save the session in the internal store to make it available
         * for lookup. For TLS 1.3, we can't save the session without
         * WOLFSSL_TICKET_HAVE_ID because there is no way to retrieve the
         * session from cache. */
        if (wolfSSL_is_server(ssl)
#ifndef WOLFSSL_TICKET_HAVE_ID
                && wolfSSL_version(ssl) != TLS1_3_VERSION
                && wolfSSL_version(ssl) != DTLS1_3_VERSION
#endif
                ) {
            ExpectIntEQ(wolfSSL_CTX_add_session(wolfSSL_get_SSL_CTX(ssl),
                    *sess), WOLFSSL_SUCCESS);
        }
    }
    /* Save CTX to be able to decrypt tickets */
    if (twcase_server_current_ctx_ptr == NULL) {
        ExpectNotNull(twcase_server_current_ctx_ptr = wolfSSL_get_SSL_CTX(ssl));
        ExpectIntEQ(wolfSSL_CTX_up_ref(wolfSSL_get_SSL_CTX(ssl)),
                    WOLFSSL_SUCCESS);
    }
#ifdef SESSION_CERTS
#ifndef WOLFSSL_TICKET_HAVE_ID
    if (wolfSSL_version(ssl) != TLS1_3_VERSION &&
            wolfSSL_session_reused(ssl))
#endif
    {
        /* With WOLFSSL_TICKET_HAVE_ID the peer certs should be available
         * for all connections. TLS 1.3 only has tickets so if we don't
         * include the session id in the ticket then the certificates
         * will not be available on resumption. */
        WOLFSSL_X509* peer = NULL;
        ExpectNotNull(peer = wolfSSL_get_peer_certificate(ssl));
        wolfSSL_X509_free(peer);
        ExpectNotNull(wolfSSL_SESSION_get_peer_chain(*sess));
    }
#endif
    return EXPECT_RESULT();
}

static int twcase_client_sess_ctx_pre_shutdown(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    WOLFSSL_SESSION** sess;
    sess = &twcase_client_first_session_ptr;
    if (*sess == NULL) {
        ExpectNotNull(*sess = wolfSSL_get1_session(ssl));
    }
    else {
        /* If we have a session retrieved then remaining connections should be
         * resuming on that session */
        ExpectIntEQ(wolfSSL_session_reused(ssl), 1);
    }

#ifdef SESSION_CERTS
#ifndef WOLFSSL_TICKET_HAVE_ID
    if (wolfSSL_version(ssl) != TLS1_3_VERSION &&
            wolfSSL_session_reused(ssl))
#endif
    {

        WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
        ExpectNotNull(peer);
        wolfSSL_X509_free(peer);
        ExpectNotNull(wolfSSL_SESSION_get_peer_chain(*sess));
#ifdef OPENSSL_EXTRA
        ExpectNotNull(wolfSSL_SESSION_get0_peer(*sess));
#endif
    }
#endif
    return EXPECT_RESULT();
}
static int twcase_client_set_sess_ssl_ready(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    /* Set the session to reuse for the client */
    ExpectNotNull(ssl);
    ExpectNotNull(twcase_client_first_session_ptr);
    ExpectIntEQ(wolfSSL_set_session(ssl,twcase_client_first_session_ptr),
                WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

struct test_add_session_ext_params {
    method_provider client_meth;
    method_provider server_meth;
    const char* tls_version;
};

static int test_wolfSSL_CTX_add_session_ext(
    struct test_add_session_ext_params* param)
{
    EXPECT_DECLS;
    /* Test the default 33 sessions */
    int j;

    /* Clear cache before starting */
    wolfSSL_CTX_flush_sessions(NULL, -1);

    XMEMSET(&server_sessionCache, 0, sizeof(hashTable));
    if (wc_InitMutex(&server_sessionCache.htLock) != 0)
        return BAD_MUTEX_E;
    server_sessionCache.capacity = SESSION_CACHE_SIZE;

    fprintf(stderr, "\tBegin %s\n", param->tls_version);
    for (j = 0; j < 5; j++) {
        int tls13 = XSTRSTR(param->tls_version, "TLSv1_3") != NULL;
        int dtls = XSTRSTR(param->tls_version, "DTLS") != NULL;
        test_ssl_cbf client_cb;
        test_ssl_cbf server_cb;

        (void)dtls;

        /* Test five cache configurations */
        twcase_client_first_session_ptr = NULL;
        twcase_server_first_session_ptr = NULL;
        twcase_server_current_ctx_ptr = NULL;
        twcase_new_session_called    = 0;
        twcase_remove_session_called = 0;
        twcase_get_session_called    = 0;

        /* connection 1 - first connection */
        fprintf(stderr, "\tconnect: %s: j=%d\n", param->tls_version, j);

        XMEMSET(&client_cb, 0, sizeof(client_cb));
        XMEMSET(&server_cb, 0, sizeof(server_cb));
        client_cb.method  = param->client_meth;
        server_cb.method  = param->server_meth;

        if (dtls)
            client_cb.doUdp = server_cb.doUdp = 1;

        /* Setup internal and external cache */
        switch (j) {
            case 0:
                /* SSL_OP_NO_TICKET stateful ticket case */
                server_cb.ctx_ready = twcase_cache_intOn_extOn_noTicket;
                break;
            case 1:
                server_cb.ctx_ready = twcase_cache_intOn_extOn;
                break;
            case 2:
                server_cb.ctx_ready = twcase_cache_intOff_extOn;
                break;
            case 3:
                server_cb.ctx_ready = twcase_cache_intOn_extOff;
                break;
            case 4:
                server_cb.ctx_ready = twcase_cache_intOff_extOff;
                break;
        }
        client_cb.ctx_ready = twcase_cache_intOff_extOff;

        /* Add session to internal cache and save SSL session for testing */
        server_cb.on_result = twcase_server_sess_ctx_pre_shutdown;
        /* Save client SSL session for testing */
        client_cb.on_result = twcase_client_sess_ctx_pre_shutdown;
        server_cb.ticNoInit = 1; /* Use default builtin */
        /* Don't free/release ctx */
        server_cb.ctx = twcase_server_current_ctx_ptr;
        server_cb.isSharedCtx = 1;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
            &server_cb, NULL), TEST_SUCCESS);

        ExpectIntEQ(twcase_get_session_called, 0);
        if (EXPECT_FAIL()) {
            wolfSSL_SESSION_free(twcase_client_first_session_ptr);
            wolfSSL_SESSION_free(twcase_server_first_session_ptr);
            wolfSSL_CTX_free(twcase_server_current_ctx_ptr);
            break;
        }

        switch (j) {
            case 0:
            case 1:
            case 2:
                /* cache cannot be searched with out a connection */
                /* Add a new session */
                ExpectIntEQ(twcase_new_session_called, 1);
                /* In twcase_server_sess_ctx_pre_shutdown
                 * wolfSSL_CTX_add_session which evicts the existing session
                 * in cache and adds it back in */
                ExpectIntLE(twcase_remove_session_called, 1);
                break;
            case 3:
            case 4:
                /* no external cache  */
                ExpectIntEQ(twcase_new_session_called, 0);
                ExpectIntEQ(twcase_remove_session_called, 0);
                break;
        }

        /* connection 2 - session resume */
        fprintf(stderr, "\tresume: %s: j=%d\n", param->tls_version, j);
        twcase_new_session_called    = 0;
        twcase_remove_session_called = 0;
        twcase_get_session_called    = 0;
        server_cb.on_result = 0;
        client_cb.on_result = 0;
        server_cb.ticNoInit = 1; /* Use default builtin */

        server_cb.ctx = twcase_server_current_ctx_ptr;

        /* try session resumption */
        client_cb.ssl_ready = twcase_client_set_sess_ssl_ready;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
            &server_cb, NULL), TEST_SUCCESS);

        /* Clear cache before checking */
        wolfSSL_CTX_flush_sessions(NULL, -1);

        switch (j) {
            case 0:
                if (tls13) {
                    /* (D)TLSv1.3 stateful case */
                    /* cache hit */
                    /* DTLS accesses cache once for stateless parsing and
                     * once for stateful parsing */
                    ExpectIntEQ(twcase_get_session_called, !dtls ? 1 : 2);

                    /* (D)TLSv1.3 creates a new ticket,
                     * updates both internal and external cache */
                    ExpectIntEQ(twcase_new_session_called, 1);
                    /* A new session ID is created for a new ticket */
                    ExpectIntEQ(twcase_remove_session_called, 2);

                }
                else {
                    /* non (D)TLSv1.3 case, no update */
                    /* DTLS accesses cache once for stateless parsing and
                     * once for stateful parsing */
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
                    ExpectIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
#else
                    ExpectIntEQ(twcase_get_session_called, 1);
#endif
                    ExpectIntEQ(twcase_new_session_called, 0);
                    /* Called on session added in
                     * twcase_server_sess_ctx_pre_shutdown */
                    ExpectIntEQ(twcase_remove_session_called, 1);
                }
                break;
            case 1:
                if (tls13) {
                    /* (D)TLSv1.3 case */
                    /* cache hit */
                    ExpectIntEQ(twcase_get_session_called, 1);
                    /* (D)TLSv1.3 creates a new ticket,
                     * updates both internal and external cache */
                    ExpectIntEQ(twcase_new_session_called, 1);
                    /* Called on session added in
                     * twcase_server_sess_ctx_pre_shutdown and by wolfSSL */
                    ExpectIntEQ(twcase_remove_session_called, 1);
                }
                else {
                    /* non (D)TLSv1.3 case */
                    /* cache hit */
                    /* DTLS accesses cache once for stateless parsing and
                     * once for stateful parsing */
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
                    ExpectIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
#else
                    ExpectIntEQ(twcase_get_session_called, 1);
#endif
                    ExpectIntEQ(twcase_new_session_called, 0);
                    /* Called on session added in
                     * twcase_server_sess_ctx_pre_shutdown */
                    ExpectIntEQ(twcase_remove_session_called, 1);
                }
                break;
            case 2:
                if (tls13) {
                    /* (D)TLSv1.3 case */
                    /* cache hit */
                    ExpectIntEQ(twcase_get_session_called, 1);
                    /* (D)TLSv1.3 creates a new ticket,
                     * updates both internal and external cache */
                    ExpectIntEQ(twcase_new_session_called, 1);
                    /* Called on session added in
                     * twcase_server_sess_ctx_pre_shutdown and by wolfSSL */
                    ExpectIntEQ(twcase_remove_session_called, 1);
                }
                else {
                    /* non (D)TLSv1.3 case */
                    /* cache hit */
                    /* DTLS accesses cache once for stateless parsing and
                     * once for stateful parsing */
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
                    ExpectIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
#else
                    ExpectIntEQ(twcase_get_session_called, 1);
#endif
                    ExpectIntEQ(twcase_new_session_called, 0);
                    /* Called on session added in
                     * twcase_server_sess_ctx_pre_shutdown */
                    ExpectIntEQ(twcase_remove_session_called, 1);
                }
                break;
            case 3:
            case 4:
                /* no external cache */
                ExpectIntEQ(twcase_get_session_called, 0);
                ExpectIntEQ(twcase_new_session_called, 0);
                ExpectIntEQ(twcase_remove_session_called, 0);
                break;
        }
        wolfSSL_SESSION_free(twcase_client_first_session_ptr);
        wolfSSL_SESSION_free(twcase_server_first_session_ptr);
        wolfSSL_CTX_free(twcase_server_current_ctx_ptr);

        if (EXPECT_FAIL())
            break;
    }
    twcase_get_sessionCb_cleanup();
    XMEMSET(&server_sessionCache.entries, 0,
            sizeof(server_sessionCache.entries));
    fprintf(stderr, "\tEnd %s\n", param->tls_version);

    wc_FreeMutex(&server_sessionCache.htLock);

    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_CTX_add_session_ext_tls13(void)
{
    EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
     defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
     defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
     defined(HAVE_SESSION_TICKET) && \
    !defined(TITAN_SESSION_CACHE) && \
    !defined(HUGE_SESSION_CACHE) && \
    !defined(BIG_SESSION_CACHE) && \
    !defined(MEDIUM_SESSION_CACHE)
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
    defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_HAVE_ID)
    struct test_add_session_ext_params param[1] =  {
        { wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" }
    };
    ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_dtls13(void)
{
    EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
     defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
     defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
     defined(HAVE_SESSION_TICKET) && \
    !defined(TITAN_SESSION_CACHE) && \
    !defined(HUGE_SESSION_CACHE) && \
    !defined(BIG_SESSION_CACHE) && \
    !defined(MEDIUM_SESSION_CACHE)
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
    defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_HAVE_ID)
#ifdef WOLFSSL_DTLS13
    struct test_add_session_ext_params param[1] =  {
        { wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" }
    };
    ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_tls12(void)
{
    EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
     defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
     defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
     defined(HAVE_SESSION_TICKET) && \
    !defined(TITAN_SESSION_CACHE) && \
    !defined(HUGE_SESSION_CACHE) && \
    !defined(BIG_SESSION_CACHE) && \
    !defined(MEDIUM_SESSION_CACHE)
#ifndef WOLFSSL_NO_TLS12
    struct test_add_session_ext_params param[1] =  {
        { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" }
    };
    ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_dtls12(void)
{
    EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
     defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
     defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
     defined(HAVE_SESSION_TICKET) && \
    !defined(TITAN_SESSION_CACHE) && \
    !defined(HUGE_SESSION_CACHE) && \
    !defined(BIG_SESSION_CACHE) && \
    !defined(MEDIUM_SESSION_CACHE)
#ifndef WOLFSSL_NO_TLS12
#ifdef WOLFSSL_DTLS
    struct test_add_session_ext_params param[1] =  {
        { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" }
    };
    ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_tls11(void)
{
    EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
     defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
     defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
     defined(HAVE_SESSION_TICKET) && \
    !defined(TITAN_SESSION_CACHE) && \
    !defined(HUGE_SESSION_CACHE) && \
    !defined(BIG_SESSION_CACHE) && \
    !defined(MEDIUM_SESSION_CACHE)
#if !defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
        !defined(NO_DES3))
    struct test_add_session_ext_params param[1] =  {
        { wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" }
    };
    ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_dtls1(void)
{
    EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
     defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
     defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
     defined(HAVE_SESSION_TICKET) && \
    !defined(TITAN_SESSION_CACHE) && \
    !defined(HUGE_SESSION_CACHE) && \
    !defined(BIG_SESSION_CACHE) && \
    !defined(MEDIUM_SESSION_CACHE)
#if !defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
        !defined(NO_DES3))
#ifdef WOLFSSL_DTLS
    struct test_add_session_ext_params param[1] =  {
        { wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" }
    };
    ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
#endif
    return EXPECT_RESULT();
}

#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT)
/* canned export of a session using older version 3 */
static unsigned char version_3[] = {
    0xA5, 0xA3, 0x01, 0x88, 0x00, 0x3c, 0x00, 0x01,
    0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x00, 0x00,
    0x00, 0x80, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x30,
    0x05, 0x09, 0x0A, 0x01, 0x01, 0x00, 0x0D, 0x05,
    0xFE, 0xFD, 0x01, 0x25, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00,
    0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x01, 0x01,
    0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3F,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x05,
    0x12, 0xCF, 0x22, 0xA1, 0x9F, 0x1C, 0x39, 0x1D,
    0x31, 0x11, 0x12, 0x1D, 0x11, 0x18, 0x0D, 0x0B,
    0xF3, 0xE1, 0x4D, 0xDC, 0xB1, 0xF1, 0x39, 0x98,
    0x91, 0x6C, 0x48, 0xE5, 0xED, 0x11, 0x12, 0xA0,
    0x00, 0xF2, 0x25, 0x4C, 0x09, 0x26, 0xD1, 0x74,
    0xDF, 0x23, 0x40, 0x15, 0x6A, 0x42, 0x2A, 0x26,
    0xA5, 0xAC, 0x56, 0xD5, 0x4A, 0x20, 0xB7, 0xE9,
    0xEF, 0xEB, 0xAF, 0xA8, 0x1E, 0x23, 0x7C, 0x04,
    0xAA, 0xA1, 0x6D, 0x92, 0x79, 0x7B, 0xFA, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x0C, 0x79, 0x7B, 0xFA, 0x80, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA1, 0x6D,
    0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x04, 0x00,
    0x10, 0x00, 0x10, 0x08, 0x02, 0x05, 0x08, 0x01,
    0x30, 0x28, 0x00, 0x00, 0x0F, 0x00, 0x02, 0x00,
    0x09, 0x31, 0x32, 0x37, 0x2E, 0x30, 0x2E, 0x30,
    0x2E, 0x31, 0xED, 0x4F
};
#endif /* defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT) */

static int test_wolfSSL_dtls_export(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT)
    tcp_ready ready;
    func_args client_args;
    func_args server_args;
    THREAD_TYPE serverThread;
    callback_functions server_cbf;
    callback_functions client_cbf;
#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    /* set using dtls */
    XMEMSET(&client_args, 0, sizeof(func_args));
    XMEMSET(&server_args, 0, sizeof(func_args));
    XMEMSET(&server_cbf, 0, sizeof(callback_functions));
    XMEMSET(&client_cbf, 0, sizeof(callback_functions));
    server_cbf.method = wolfDTLSv1_2_server_method;
    client_cbf.method = wolfDTLSv1_2_client_method;
    server_args.callbacks = &server_cbf;
    client_args.callbacks = &client_cbf;

    server_args.signal = &ready;
    client_args.signal = &ready;

    start_thread(run_wolfssl_server, &server_args, &serverThread);
    wait_tcp_ready(&server_args);
    run_wolfssl_client(&client_args);
    join_thread(serverThread);

    ExpectTrue(client_args.return_code);
    ExpectTrue(server_args.return_code);

    FreeTcpReady(&ready);

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    if (EXPECT_SUCCESS()) {
        SOCKET_T sockfd = 0;
        WOLFSSL_CTX* ctx = NULL;
        WOLFSSL*     ssl = NULL;
        char msg[64] = "hello wolfssl!";
        char reply[1024];
        int  msgSz = (int)XSTRLEN(msg);
        byte *session, *window;
        unsigned int sessionSz = 0;
        unsigned int windowSz = 0;

#ifndef TEST_IPV6
        struct sockaddr_in peerAddr;
#else
        struct sockaddr_in6 peerAddr;
#endif /* TEST_IPV6 */

        int i;


        /* Set ctx to DTLS 1.2 */
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()));
        ExpectNotNull(ssl = wolfSSL_new(ctx));

        /* test importing version 3 */
        ExpectIntGE(wolfSSL_dtls_import(ssl, version_3, sizeof(version_3)), 0);

        /* test importing bad length and bad version */
        version_3[2] += 1;
        ExpectIntLT(wolfSSL_dtls_import(ssl, version_3, sizeof(version_3)), 0);
        version_3[2] -= 1; version_3[1] = 0XA0;
        ExpectIntLT(wolfSSL_dtls_import(ssl, version_3, sizeof(version_3)), 0);
        wolfSSL_free(ssl);
        wolfSSL_CTX_free(ctx);


    /* check storing client state after connection and storing window only */
#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    /* set using dtls */
    XMEMSET(&server_args, 0, sizeof(func_args));
    XMEMSET(&server_cbf, 0, sizeof(callback_functions));
    server_cbf.method = wolfDTLSv1_2_server_method;
    server_cbf.doUdp = 1;
    server_args.callbacks = &server_cbf;
    server_args.argc = 3; /* set loop_count to 3 */


    server_args.signal = &ready;
    start_thread(test_server_nofail, &server_args, &serverThread);
    wait_tcp_ready(&server_args);

    /* create and connect with client */
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method()));
    ExpectIntEQ(WOLFSSL_SUCCESS,
            wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0));
    ExpectIntEQ(WOLFSSL_SUCCESS,
          wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM));
    ExpectIntEQ(WOLFSSL_SUCCESS,
            wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));
    tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 1, 0, NULL);
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);

    /* store server information connected too */
    XMEMSET(&peerAddr, 0, sizeof(peerAddr));
#ifndef TEST_IPV6
    peerAddr.sin_family = AF_INET;
    ExpectIntEQ(XINET_PTON(AF_INET, wolfSSLIP, &peerAddr.sin_addr),1);
    peerAddr.sin_port = XHTONS(server_args.signal->port);
#else
    peerAddr.sin6_family = AF_INET6;
    ExpectIntEQ(
        XINET_PTON(AF_INET6, wolfSSLIP, &peerAddr.sin6_addr),1);
    peerAddr.sin6_port = XHTONS(server_args.signal->port);
#endif

    ExpectIntEQ(wolfSSL_dtls_set_peer(ssl, &peerAddr, sizeof(peerAddr)),
                    WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_dtls_export(ssl, NULL, &sessionSz), 0);
    session = (byte*)XMALLOC(sessionSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectIntGT(wolfSSL_dtls_export(ssl, session, &sessionSz), 0);
    ExpectIntEQ(wolfSSL_write(ssl, msg, msgSz), msgSz);
    ExpectIntGT(wolfSSL_read(ssl, reply, sizeof(reply)), 0);
    ExpectIntEQ(wolfSSL_dtls_export_state_only(ssl, NULL, &windowSz), 0);
    window = (byte*)XMALLOC(windowSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectIntGT(wolfSSL_dtls_export_state_only(ssl, window, &windowSz), 0);
    wolfSSL_free(ssl);

    for (i = 1; EXPECT_SUCCESS() && i < server_args.argc; i++) {
        /* restore state */
        ExpectNotNull(ssl = wolfSSL_new(ctx));
        ExpectIntGT(wolfSSL_dtls_import(ssl, session, sessionSz), 0);
        ExpectIntGT(wolfSSL_dtls_import(ssl, window, windowSz), 0);
        ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_dtls_set_peer(ssl, &peerAddr, sizeof(peerAddr)),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_write(ssl, msg, msgSz), msgSz);
        ExpectIntGE(wolfSSL_read(ssl, reply, sizeof(reply)), 0);
        ExpectIntGT(wolfSSL_dtls_export_state_only(ssl, window, &windowSz), 0);
        wolfSSL_free(ssl);
    }
    XFREE(session, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(window, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    wolfSSL_CTX_free(ctx);

    fprintf(stderr, "done and waiting for server\n");
    join_thread(serverThread);
    ExpectIntEQ(server_args.return_code, TEST_SUCCESS);

    FreeTcpReady(&ready);

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif
    }
#endif

    return EXPECT_RESULT();
}

#if defined(WOLFSSL_SESSION_EXPORT) && !defined(WOLFSSL_NO_TLS12)
#ifdef WOLFSSL_TLS13
static const byte canned_client_tls13_session[] = {
    0xA7, 0xA4, 0x01, 0x18, 0x00, 0x41, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00,
    0x00, 0x80, 0x00, 0x1C, 0x01, 0x00, 0x00, 0x01,
    0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
    0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
    0x01, 0x0A, 0x0F, 0x10, 0x01, 0x02, 0x09, 0x00,
    0x05, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00,
    0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
    0x11, 0x01, 0x01, 0x00, 0x20, 0x84, 0x4F, 0x18,
    0xD8, 0xC1, 0x24, 0xD8, 0xBB, 0x17, 0x9E, 0x31,
    0xA3, 0xF8, 0xA7, 0x3C, 0xBA, 0xEC, 0xFA, 0xB4,
    0x7F, 0xC5, 0x78, 0xEB, 0x6D, 0xE3, 0x2B, 0x7B,
    0x94, 0xBE, 0x20, 0x11, 0x7E, 0x17, 0x10, 0xA7,
    0x10, 0x19, 0xEC, 0x62, 0xCC, 0xBE, 0xF5, 0x01,
    0x35, 0x3C, 0xEA, 0xEF, 0x44, 0x3C, 0x40, 0xA2,
    0xBC, 0x18, 0x43, 0xA1, 0xA1, 0x65, 0x5C, 0x48,
    0xE2, 0xF9, 0x38, 0xEB, 0x11, 0x10, 0x72, 0x7C,
    0x78, 0x22, 0x13, 0x3B, 0x19, 0x40, 0xF0, 0x73,
    0xBE, 0x96, 0x14, 0x78, 0x26, 0xB9, 0x6B, 0x2E,
    0x72, 0x22, 0x0D, 0x90, 0x94, 0xDD, 0x78, 0x77,
    0xFC, 0x0C, 0x2E, 0x63, 0x6E, 0xF0, 0x0C, 0x35,
    0x41, 0xCD, 0xF3, 0x49, 0x31, 0x08, 0xD0, 0x6F,
    0x02, 0x3D, 0xC1, 0xD3, 0xB7, 0xEE, 0x3A, 0xA0,
    0x8E, 0xA1, 0x4D, 0xC3, 0x2E, 0x5E, 0x06, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
    0x35, 0x41, 0xCD, 0xF3, 0x49, 0x31, 0x08, 0xD0,
    0x6F, 0x02, 0x3D, 0xC1, 0xD3, 0xB7, 0xEE, 0x3A,
    0xA0, 0x8E, 0xA1, 0x4D, 0xC3, 0x2E, 0x5E, 0x06,
    0x00, 0x10, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x10,
    0x00, 0x10, 0x07, 0x02, 0x04, 0x00, 0x00, 0x20,
    0x28, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x03
};

static const byte canned_server_tls13_session[] = {
    0xA7, 0xA4, 0x01, 0x18, 0x00, 0x41, 0x01, 0x00,
    0x01, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00,
    0x00, 0x80, 0x00, 0x1C, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
    0x01, 0x0A, 0x0F, 0x10, 0x01, 0x02, 0x00, 0x0F,
    0x05, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00,
    0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
    0x11, 0x01, 0x01, 0x00, 0x20, 0x84, 0x4F, 0x18,
    0xD8, 0xC1, 0x24, 0xD8, 0xBB, 0x17, 0x9E, 0x31,
    0xA3, 0xF8, 0xA7, 0x3C, 0xBA, 0xEC, 0xFA, 0xB4,
    0x7F, 0xC5, 0x78, 0xEB, 0x6D, 0xE3, 0x2B, 0x7B,
    0x94, 0xBE, 0x20, 0x11, 0x7E, 0x17, 0x10, 0xA7,
    0x10, 0x19, 0xEC, 0x62, 0xCC, 0xBE, 0xF5, 0x01,
    0x35, 0x3C, 0xEA, 0xEF, 0x44, 0x3C, 0x40, 0xA2,
    0xBC, 0x18, 0x43, 0xA1, 0xA1, 0x65, 0x5C, 0x48,
    0xE2, 0xF9, 0x38, 0xEB, 0x11, 0x10, 0x72, 0x7C,
    0x78, 0x22, 0x13, 0x3B, 0x19, 0x40, 0xF0, 0x73,
    0xBE, 0x96, 0x14, 0x78, 0x26, 0xB9, 0x6B, 0x2E,
    0x72, 0x22, 0x0D, 0x90, 0x94, 0xDD, 0x78, 0x77,
    0xFC, 0x0C, 0x2E, 0x63, 0x6E, 0xF0, 0x0C, 0x35,
    0x41, 0xCD, 0xF3, 0x49, 0x31, 0x08, 0xD0, 0x6F,
    0x02, 0x3D, 0xC1, 0xD3, 0xB7, 0xEE, 0x3A, 0xA0,
    0x8E, 0xA1, 0x4D, 0xC3, 0x2E, 0x5E, 0x06, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
    0xD3, 0xB7, 0xEE, 0x3A, 0xA0, 0x8E, 0xA1, 0x4D,
    0xC3, 0x2E, 0x5E, 0x06, 0x35, 0x41, 0xCD, 0xF3,
    0x49, 0x31, 0x08, 0xD0, 0x6F, 0x02, 0x3D, 0xC1,
    0x00, 0x10, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x10,
    0x00, 0x10, 0x07, 0x02, 0x04, 0x00, 0x00, 0x20,
    0x28, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x04
};
#endif /* WOLFSSL_TLS13 */

static const byte canned_client_session[] = {
    0xA7, 0xA4, 0x01, 0x40, 0x00, 0x41, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00,
    0x00, 0x80, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x01,
    0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
    0x27, 0x0A, 0x0D, 0x10, 0x01, 0x01, 0x0A, 0x00,
    0x05, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x00,
    0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
    0x0A, 0x01, 0x01, 0x00, 0x20, 0x69, 0x11, 0x6D,
    0x97, 0x15, 0x6E, 0x52, 0x27, 0xD6, 0x1D, 0x1D,
    0xF5, 0x0D, 0x59, 0xA5, 0xAC, 0x2E, 0x8C, 0x0E,
    0xCB, 0x26, 0x1E, 0xE2, 0xCE, 0xBB, 0xCE, 0xE1,
    0x7D, 0xD7, 0xEF, 0xA5, 0x44, 0x80, 0x2A, 0xDE,
    0xBB, 0x75, 0xB0, 0x1D, 0x75, 0x17, 0x20, 0x4C,
    0x08, 0x05, 0x1B, 0xBA, 0x60, 0x1F, 0x6C, 0x91,
    0x8C, 0xAA, 0xBB, 0xE5, 0xA3, 0x0B, 0x12, 0x3E,
    0xC0, 0x35, 0x43, 0x1D, 0xE2, 0x10, 0xE2, 0x02,
    0x92, 0x4B, 0x8F, 0x05, 0xA9, 0x4B, 0xCC, 0x90,
    0xC3, 0x0E, 0xC2, 0x0F, 0xE9, 0x33, 0x85, 0x9B,
    0x3C, 0x19, 0x21, 0xD5, 0x62, 0xE5, 0xE1, 0x17,
    0x8F, 0x8C, 0x19, 0x52, 0xD8, 0x59, 0x10, 0x2D,
    0x20, 0x6F, 0xBA, 0xC1, 0x1C, 0xD1, 0x82, 0xC7,
    0x32, 0x1B, 0xBB, 0xCC, 0x30, 0x03, 0xD7, 0x3A,
    0xC8, 0x18, 0xED, 0x58, 0xC8, 0x11, 0xFE, 0x71,
    0x9C, 0x71, 0xD8, 0x6B, 0xE0, 0x25, 0x64, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
    0x00, 0x00, 0x06, 0x01, 0x04, 0x08, 0x01, 0x20,
    0x28, 0x00, 0x09, 0xE1, 0x50, 0x70, 0x02, 0x2F,
    0x7E, 0xDA, 0xBD, 0x40, 0xC5, 0x58, 0x87, 0xCE,
    0x43, 0xF3, 0xC5, 0x8F, 0xA1, 0x59, 0x93, 0xEF,
    0x7E, 0xD3, 0xD0, 0xB5, 0x87, 0x1D, 0x81, 0x54,
    0x14, 0x63, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x03
};


static const byte canned_server_session[] = {
    0xA7, 0xA4, 0x01, 0x40, 0x00, 0x41, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00,
    0x00, 0x80, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
    0x27, 0x08, 0x0F, 0x10, 0x01, 0x01, 0x00, 0x11,
    0x05, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x00,
    0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
    0x0A, 0x01, 0x01, 0x00, 0x20, 0x69, 0x11, 0x6D,
    0x97, 0x15, 0x6E, 0x52, 0x27, 0xD6, 0x1D, 0x1D,
    0xF5, 0x0D, 0x59, 0xA5, 0xAC, 0x2E, 0x8C, 0x0E,
    0xCB, 0x26, 0x1E, 0xE2, 0xCE, 0xBB, 0xCE, 0xE1,
    0x7D, 0xD7, 0xEF, 0xA5, 0x44, 0x80, 0x2A, 0xDE,
    0xBB, 0x75, 0xB0, 0x1D, 0x75, 0x17, 0x20, 0x4C,
    0x08, 0x05, 0x1B, 0xBA, 0x60, 0x1F, 0x6C, 0x91,
    0x8C, 0xAA, 0xBB, 0xE5, 0xA3, 0x0B, 0x12, 0x3E,
    0xC0, 0x35, 0x43, 0x1D, 0xE2, 0x10, 0xE2, 0x02,
    0x92, 0x4B, 0x8F, 0x05, 0xA9, 0x4B, 0xCC, 0x90,
    0xC3, 0x0E, 0xC2, 0x0F, 0xE9, 0x33, 0x85, 0x9B,
    0x3C, 0x19, 0x21, 0xD5, 0x62, 0xE5, 0xE1, 0x17,
    0x8F, 0x8C, 0x19, 0x52, 0xD8, 0x59, 0x10, 0x2D,
    0x20, 0x6F, 0xBA, 0xC1, 0x1C, 0xD1, 0x82, 0xC7,
    0x32, 0x1B, 0xBB, 0xCC, 0x30, 0x03, 0xD7, 0x3A,
    0xC8, 0x18, 0xED, 0x58, 0xC8, 0x11, 0xFE, 0x71,
    0x9C, 0x71, 0xD8, 0x6B, 0xE0, 0x25, 0x64, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
    0x00, 0x00, 0x06, 0x01, 0x04, 0x08, 0x01, 0x20,
    0x28, 0x00, 0xC5, 0x8F, 0xA1, 0x59, 0x93, 0xEF,
    0x7E, 0xD3, 0xD0, 0xB5, 0x87, 0x1D, 0x81, 0x54,
    0x14, 0x63, 0x09, 0xE1, 0x50, 0x70, 0x02, 0x2F,
    0x7E, 0xDA, 0xBD, 0x40, 0xC5, 0x58, 0x87, 0xCE,
    0x43, 0xF3, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x04
};


static THREAD_RETURN WOLFSSL_THREAD tls_export_server(void* args)
{
    SOCKET_T sockfd = 0;
    SOCKET_T clientfd = 0;
    word16 port;

    callback_functions* cbf;
    WOLFSSL_CTX* ctx = 0;
    WOLFSSL* ssl = 0;

    char msg[] = "I hear you fa shizzle!";
    char input[1024];
    int idx;

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    ((func_args*)args)->return_code = TEST_FAIL;
    cbf = ((func_args*)args)->callbacks;

#if defined(USE_WINDOWS_API)
    port = ((func_args*)args)->signal->port;
#elif defined(NO_MAIN_DRIVER) && !defined(WOLFSSL_SNIFFER) && \
     !defined(WOLFSSL_MDK_SHELL) && !defined(WOLFSSL_TIRTOS)
    /* Let tcp_listen assign port */
    port = 0;
#else
    /* Use default port */
    port = wolfSSLPort;
#endif

    /* do it here to detect failure */
    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0, 0);
    CloseSocket(sockfd);

    {
        WOLFSSL_METHOD* method = NULL;
        if (cbf != NULL && cbf->method != NULL) {
            method = cbf->method();
        }
        else {
            method = wolfTLSv1_2_server_method();
        }
        ctx = wolfSSL_CTX_new(method);
    }
    if (ctx == NULL) {
        goto done;
    }
    wolfSSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-SHA256");

    /* call ctx setup callback */
    if (cbf != NULL && cbf->ctx_ready != NULL) {
        cbf->ctx_ready(ctx);
    }

    ssl = wolfSSL_new(ctx);
    if (ssl == NULL) {
        goto done;
    }
    wolfSSL_set_fd(ssl, clientfd);

    /* call ssl setup callback */
    if (cbf != NULL && cbf->ssl_ready != NULL) {
        cbf->ssl_ready(ssl);
    }
    idx = wolfSSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = '\0';
        fprintf(stderr, "Client message export/import: %s\n", input);
    }
    else {
        fprintf(stderr, "ret = %d error = %d\n", idx,
            wolfSSL_get_error(ssl, idx));
        goto done;
    }

    if (wolfSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) {
        /*err_sys("SSL_write failed");*/
        WOLFSSL_RETURN_FROM_THREAD(0);
    }

#ifdef WOLFSSL_TIRTOS
    Task_yield();
#endif

    ((func_args*)args)->return_code = TEST_SUCCESS;

done:
    wolfSSL_shutdown(ssl);
    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);

    CloseSocket(clientfd);

#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

#if defined(HAVE_SESSION_TICKET) && \
    ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AESGCM)
    OpenSSLTicketCleanup();
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
    TicketCleanup();
#endif
#endif

    WOLFSSL_RETURN_FROM_THREAD(0);
}


static void load_tls12_canned_server(WOLFSSL* ssl)
{
    int clientfd = wolfSSL_get_fd(ssl);
    AssertIntEQ(wolfSSL_tls_import(ssl, canned_server_session,
                sizeof(canned_server_session)), sizeof(canned_server_session));
    wolfSSL_set_fd(ssl, clientfd);
}


#ifdef WOLFSSL_TLS13
static void load_tls13_canned_server(WOLFSSL* ssl)
{
    int clientfd = wolfSSL_get_fd(ssl);
    AssertIntEQ(wolfSSL_tls_import(ssl, canned_server_tls13_session,
            sizeof(canned_server_tls13_session)),
            sizeof(canned_server_tls13_session));
    wolfSSL_set_fd(ssl, clientfd);
}
#endif


/* v is for version WOLFSSL_TLSV1_2 or WOLFSSL_TLSV1_3 */
static int test_wolfSSL_tls_export_run(int v)
{
    EXPECT_DECLS;
    SOCKET_T sockfd = 0;
    WOLFSSL_CTX*     ctx     = 0;
    WOLFSSL*         ssl     = 0;
    char msg[64] = "hello wolfssl!";
    char reply[1024];
    word32 replySz;
    int  msgSz = (int)XSTRLEN(msg);
    const byte* clientSession = NULL;
    int   clientSessionSz = 0;

    tcp_ready ready;
    func_args server_args;
    THREAD_TYPE serverThread;
    callback_functions server_cbf;

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    XMEMSET(&server_args, 0, sizeof(func_args));
    XMEMSET(&server_cbf, 0, sizeof(callback_functions));
    switch (v) {
        case WOLFSSL_TLSV1_2:
            server_cbf.method     = wolfTLSv1_2_server_method;
            server_cbf.ssl_ready  = load_tls12_canned_server;

            /* setup the client side */
            ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
            wolfSSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-SHA256");
            clientSession   = canned_client_session;
            clientSessionSz = sizeof(canned_client_session);
            break;
    #ifdef WOLFSSL_TLS13
        case WOLFSSL_TLSV1_3:
            server_cbf.method     = wolfTLSv1_3_server_method;
            server_cbf.ssl_ready  = load_tls13_canned_server;

            /* setup the client side */
            ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
            clientSession   = canned_client_tls13_session;
            clientSessionSz = sizeof(canned_client_tls13_session);
            break;
    #endif
    }
    server_args.callbacks = &server_cbf;
    server_args.signal    = &ready;

    start_thread(tls_export_server, &server_args, &serverThread);
    wait_tcp_ready(&server_args);


#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    ExpectNotNull(ssl = wolfSSL_new(ctx));
    tcp_connect(&sockfd, wolfSSLIP, ready.port, 0, 0, ssl);
    ExpectIntEQ(wolfSSL_tls_import(ssl, clientSession, clientSessionSz),
                clientSessionSz);
    replySz = sizeof(reply);
    ExpectIntGT(wolfSSL_tls_export(ssl, (byte*)reply, &replySz), 0);
#if !defined(NO_PSK) && defined(HAVE_ANON)
    /* index 20 has is setting if PSK was on and 49 is if anon is allowed */
    ExpectIntEQ(XMEMCMP(reply, clientSession, replySz), 0);
#endif
    wolfSSL_set_fd(ssl, sockfd);

    ExpectIntEQ(wolfSSL_write(ssl, msg, msgSz), msgSz);
    ExpectIntGT(wolfSSL_read(ssl, reply, sizeof(reply)-1), 0);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);

    CloseSocket(sockfd);

#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

    join_thread(serverThread);

    ExpectIntEQ(server_args.return_code, TEST_SUCCESS);
    FreeTcpReady(&ready);

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_tls_export(void)
{
    int res = TEST_SKIPPED;
#if defined(WOLFSSL_SESSION_EXPORT) && !defined(WOLFSSL_NO_TLS12)
    test_wolfSSL_tls_export_run(WOLFSSL_TLSV1_2);
    #ifdef WOLFSSL_TLS13
    test_wolfSSL_tls_export_run(WOLFSSL_TLSV1_3);
    #endif
    res = TEST_RES_CHECK(1);
#endif

    return res;
}

/*----------------------------------------------------------------------------*
 | TLS extensions tests
 *----------------------------------------------------------------------------*/

#ifdef ENABLE_TLS_CALLBACK_TEST
/* Connection test runner - generic */
static void test_wolfSSL_client_server(callback_functions* client_callbacks,
                                       callback_functions* server_callbacks)
{
    tcp_ready ready;
    func_args client_args;
    func_args server_args;
    THREAD_TYPE serverThread;

    XMEMSET(&client_args, 0, sizeof(func_args));
    XMEMSET(&server_args, 0, sizeof(func_args));

    StartTCP();

    client_args.callbacks = client_callbacks;
    server_args.callbacks = server_callbacks;

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    /* RUN Server side */
    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    server_args.signal = &ready;
    client_args.signal = &ready;
    start_thread(run_wolfssl_server, &server_args, &serverThread);
    wait_tcp_ready(&server_args);

    /* RUN Client side */
    run_wolfssl_client(&client_args);
    join_thread(serverThread);

    FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

    client_callbacks->return_code = client_args.return_code;
    server_callbacks->return_code = server_args.return_code;
}
#endif /* ENABLE_TLS_CALLBACK_TEST */


#ifdef HAVE_SNI
static int test_wolfSSL_UseSNI_params(void)
{
    EXPECT_DECLS;
#if !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
    WOLFSSL     *ssl = wolfSSL_new(ctx);

    ExpectNotNull(ctx);
    ExpectNotNull(ssl);

    /* invalid [ctx|ssl] */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSNI(NULL, 0, "ctx", 3));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSNI(    NULL, 0, "ssl", 3));
    /* invalid type */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSNI(ctx, (byte)-1, "ctx", 3));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSNI(    ssl, (byte)-1, "ssl", 3));
    /* invalid data */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSNI(ctx,  0, NULL,  3));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSNI(    ssl,  0, NULL,  3));
    /* success case */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSNI(ctx,  0, "ctx", 3));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSNI(    ssl,  0, "ssl", 3));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT */

    return EXPECT_RESULT();
}

/* BEGIN of connection tests callbacks */
static void use_SNI_at_ctx(WOLFSSL_CTX* ctx)
{
    AssertIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CTX_UseSNI(ctx, WOLFSSL_SNI_HOST_NAME, "www.wolfssl.com", 15));
}

static void use_SNI_at_ssl(WOLFSSL* ssl)
{
    AssertIntEQ(WOLFSSL_SUCCESS,
             wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, "www.wolfssl.com", 15));
}

static void different_SNI_at_ssl(WOLFSSL* ssl)
{
    AssertIntEQ(WOLFSSL_SUCCESS,
             wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, "ww2.wolfssl.com", 15));
}

static void use_SNI_WITH_CONTINUE_at_ssl(WOLFSSL* ssl)
{
    use_SNI_at_ssl(ssl);
    wolfSSL_SNI_SetOptions(ssl, WOLFSSL_SNI_HOST_NAME,
                                              WOLFSSL_SNI_CONTINUE_ON_MISMATCH);
}

static void use_SNI_WITH_FAKE_ANSWER_at_ssl(WOLFSSL* ssl)
{
    use_SNI_at_ssl(ssl);
    wolfSSL_SNI_SetOptions(ssl, WOLFSSL_SNI_HOST_NAME,
                                                WOLFSSL_SNI_ANSWER_ON_MISMATCH);
}

static void use_MANDATORY_SNI_at_ctx(WOLFSSL_CTX* ctx)
{
    use_SNI_at_ctx(ctx);
    wolfSSL_CTX_SNI_SetOptions(ctx, WOLFSSL_SNI_HOST_NAME,
                                                  WOLFSSL_SNI_ABORT_ON_ABSENCE);
}

static void use_MANDATORY_SNI_at_ssl(WOLFSSL* ssl)
{
    use_SNI_at_ssl(ssl);
    wolfSSL_SNI_SetOptions(ssl, WOLFSSL_SNI_HOST_NAME,
                                                  WOLFSSL_SNI_ABORT_ON_ABSENCE);
}

static void use_PSEUDO_MANDATORY_SNI_at_ctx(WOLFSSL_CTX* ctx)
{
    use_SNI_at_ctx(ctx);
    wolfSSL_CTX_SNI_SetOptions(ctx, WOLFSSL_SNI_HOST_NAME,
                 WOLFSSL_SNI_ANSWER_ON_MISMATCH | WOLFSSL_SNI_ABORT_ON_ABSENCE);
}

static void verify_UNKNOWN_SNI_on_server(WOLFSSL* ssl)
{
    AssertIntEQ(WC_NO_ERR_TRACE(UNKNOWN_SNI_HOST_NAME_E),
                wolfSSL_get_error(ssl, 0));
}

static void verify_SNI_ABSENT_on_server(WOLFSSL* ssl)
{
    AssertIntEQ(WC_NO_ERR_TRACE(SNI_ABSENT_ERROR), wolfSSL_get_error(ssl, 0));
}

static void verify_SNI_no_matching(WOLFSSL* ssl)
{
    byte type = WOLFSSL_SNI_HOST_NAME;
    void* request = (void*) &type; /* to be overwritten */

    AssertIntEQ(WOLFSSL_SNI_NO_MATCH, wolfSSL_SNI_Status(ssl, type));
    AssertNotNull(request);
    AssertIntEQ(0, wolfSSL_SNI_GetRequest(ssl, type, &request));
    AssertNull(request);
}

static void verify_SNI_real_matching(WOLFSSL* ssl)
{
    byte type = WOLFSSL_SNI_HOST_NAME;
    void* request = NULL;

    AssertIntEQ(WOLFSSL_SNI_REAL_MATCH, wolfSSL_SNI_Status(ssl, type));
    AssertIntEQ(15, wolfSSL_SNI_GetRequest(ssl, type, &request));
    AssertNotNull(request);
    AssertStrEQ("www.wolfssl.com", (char*)request);
}

static void verify_SNI_fake_matching(WOLFSSL* ssl)
{
    byte type = WOLFSSL_SNI_HOST_NAME;
    void* request = NULL;

    AssertIntEQ(WOLFSSL_SNI_FAKE_MATCH, wolfSSL_SNI_Status(ssl, type));
    AssertIntEQ(15, wolfSSL_SNI_GetRequest(ssl, type, &request));
    AssertNotNull(request);
    AssertStrEQ("ww2.wolfssl.com", (char*)request);
}

static void verify_FATAL_ERROR_on_client(WOLFSSL* ssl)
{
    AssertIntEQ(WC_NO_ERR_TRACE(FATAL_ERROR), wolfSSL_get_error(ssl, 0));
}
/* END of connection tests callbacks */

static int test_wolfSSL_UseSNI_connection(void)
{
    int res = TEST_SKIPPED;
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
    callback_functions client_cb;
    callback_functions server_cb;
    size_t i;
#ifdef WOLFSSL_STATIC_MEMORY
    byte cliMem[TEST_TLS_STATIC_MEMSZ];
    byte svrMem[TEST_TLS_STATIC_MEMSZ];
#endif
    struct {
        method_provider client_meth;
        method_provider server_meth;
    #ifdef WOLFSSL_STATIC_MEMORY
        wolfSSL_method_func client_meth_ex;
        wolfSSL_method_func server_meth_ex;
    #endif
    } methods[] = {
#if defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_TLS13)
        {wolfSSLv23_client_method, wolfSSLv23_server_method
        #ifdef WOLFSSL_STATIC_MEMORY
            ,wolfSSLv23_client_method_ex, wolfSSLv23_server_method_ex
        #endif
        },
#endif
#ifndef WOLFSSL_NO_TLS12
        {wolfTLSv1_2_client_method, wolfTLSv1_2_server_method
        #ifdef WOLFSSL_STATIC_MEMORY
            ,wolfTLSv1_2_client_method_ex, wolfTLSv1_2_server_method_ex
        #endif
        },
#endif
#ifdef WOLFSSL_TLS13
        {wolfTLSv1_3_client_method, wolfTLSv1_3_server_method
        #ifdef WOLFSSL_STATIC_MEMORY
            ,wolfTLSv1_3_client_method_ex, wolfTLSv1_3_server_method_ex
        #endif
        },
#endif
    };
    size_t methodsSz = sizeof(methods) / sizeof(*methods);

    for (i = 0; i < methodsSz; i++) {
        XMEMSET(&client_cb, 0, sizeof(callback_functions));
        XMEMSET(&server_cb, 0, sizeof(callback_functions));
        client_cb.method = methods[i].client_meth;
        server_cb.method = methods[i].server_meth;
        client_cb.devId = testDevId;
        server_cb.devId = testDevId;
    #ifdef WOLFSSL_STATIC_MEMORY
        client_cb.method_ex = methods[i].client_meth_ex;
        server_cb.method_ex = methods[i].server_meth_ex;
        client_cb.mem = cliMem;
        client_cb.memSz = (word32)sizeof(cliMem);
        server_cb.mem = svrMem;
        server_cb.memSz = (word32)sizeof(svrMem);;
    #endif

        /* success case at ctx */
        fprintf(stderr, "\n\tsuccess case at ctx\n");
        client_cb.ctx_ready = use_SNI_at_ctx; client_cb.ssl_ready = NULL; client_cb.on_result = NULL;
        server_cb.ctx_ready = use_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_real_matching;
        test_wolfSSL_client_server(&client_cb, &server_cb);

        /* success case at ssl */
        fprintf(stderr, "\tsuccess case at ssl\n");
        client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_SNI_at_ssl; client_cb.on_result = verify_SNI_real_matching;
        server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_at_ssl; server_cb.on_result = verify_SNI_real_matching;
        test_wolfSSL_client_server(&client_cb, &server_cb);

        /* default mismatch behavior */
        fprintf(stderr, "\tdefault mismatch behavior\n");
        client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = verify_FATAL_ERROR_on_client;
        server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_at_ssl;       server_cb.on_result = verify_UNKNOWN_SNI_on_server;
        test_wolfSSL_client_server(&client_cb, &server_cb);

        /* continue on mismatch */
        fprintf(stderr, "\tcontinue on mismatch\n");
        client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl;         client_cb.on_result = NULL;
        server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_WITH_CONTINUE_at_ssl; server_cb.on_result = verify_SNI_no_matching;
        test_wolfSSL_client_server(&client_cb, &server_cb);

        /* fake answer on mismatch */
        fprintf(stderr, "\tfake answer on mismatch\n");
        client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl;            client_cb.on_result = NULL;
        server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_WITH_FAKE_ANSWER_at_ssl; server_cb.on_result = verify_SNI_fake_matching;
        test_wolfSSL_client_server(&client_cb, &server_cb);

        /* sni abort - success */
        fprintf(stderr, "\tsni abort - success\n");
        client_cb.ctx_ready = use_SNI_at_ctx;           client_cb.ssl_ready = NULL; client_cb.on_result = NULL;
        server_cb.ctx_ready = use_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_real_matching;
        test_wolfSSL_client_server(&client_cb, &server_cb);

        /* sni abort - abort when absent (ctx) */
        fprintf(stderr, "\tsni abort - abort when absent (ctx)\n");
        client_cb.ctx_ready = NULL;                     client_cb.ssl_ready = NULL; client_cb.on_result = verify_FATAL_ERROR_on_client;
        server_cb.ctx_ready = use_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_ABSENT_on_server;
        test_wolfSSL_client_server(&client_cb, &server_cb);

        /* sni abort - abort when absent (ssl) */
        fprintf(stderr, "\tsni abort - abort when absent (ssl)\n");
        client_cb.ctx_ready = NULL; client_cb.ssl_ready = NULL;                     client_cb.on_result = verify_FATAL_ERROR_on_client;
        server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_MANDATORY_SNI_at_ssl; server_cb.on_result = verify_SNI_ABSENT_on_server;
        test_wolfSSL_client_server(&client_cb, &server_cb);

        /* sni abort - success when overwritten */
        fprintf(stderr, "\tsni abort - success when overwritten\n");
        client_cb.ctx_ready = NULL;                     client_cb.ssl_ready = NULL;           client_cb.on_result = NULL;
        server_cb.ctx_ready = use_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = use_SNI_at_ssl; server_cb.on_result = verify_SNI_no_matching;
        test_wolfSSL_client_server(&client_cb, &server_cb);

        /* sni abort - success when allowing mismatches */
        fprintf(stderr, "\tsni abort - success when allowing mismatches\n");
        client_cb.ctx_ready = NULL;                            client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = NULL;
        server_cb.ctx_ready = use_PSEUDO_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = NULL;                 server_cb.on_result = verify_SNI_fake_matching;
        test_wolfSSL_client_server(&client_cb, &server_cb);
    }

    res = TEST_RES_CHECK(1);
#endif /* !NO_WOLFSSL_CLIENT && !NO_WOLFSSL_SERVER */

    return res;
}

static int test_wolfSSL_SNI_GetFromBuffer(void)
{
    EXPECT_DECLS;
    byte buff[] = { /* www.paypal.com */
        0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x60, 0x03, 0x03, 0x5c,
        0xc4, 0xb3, 0x8c, 0x87, 0xef, 0xa4, 0x09, 0xe0, 0x02, 0xab, 0x86, 0xca,
        0x76, 0xf0, 0x9e, 0x01, 0x65, 0xf6, 0xa6, 0x06, 0x13, 0x1d, 0x0f, 0xa5,
        0x79, 0xb0, 0xd4, 0x77, 0x22, 0xeb, 0x1a, 0x00, 0x00, 0x16, 0x00, 0x6b,
        0x00, 0x67, 0x00, 0x39, 0x00, 0x33, 0x00, 0x3d, 0x00, 0x3c, 0x00, 0x35,
        0x00, 0x2f, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x21,
        0x00, 0x00, 0x00, 0x13, 0x00, 0x11, 0x00, 0x00, 0x0e, 0x77, 0x77, 0x77,
        0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00,
        0x0d, 0x00, 0x06, 0x00, 0x04, 0x04, 0x01, 0x02, 0x01
    };

    byte buff2[] = { /* api.textmate.org */
        0x16, 0x03, 0x01, 0x00, 0xc6, 0x01, 0x00, 0x00, 0xc2, 0x03, 0x03, 0x52,
        0x8b, 0x7b, 0xca, 0x69, 0xec, 0x97, 0xd5, 0x08, 0x03, 0x50, 0xfe, 0x3b,
        0x99, 0xc3, 0x20, 0xce, 0xa5, 0xf6, 0x99, 0xa5, 0x71, 0xf9, 0x57, 0x7f,
        0x04, 0x38, 0xf6, 0x11, 0x0b, 0xb8, 0xd3, 0x00, 0x00, 0x5e, 0x00, 0xff,
        0xc0, 0x24, 0xc0, 0x23, 0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x07, 0xc0, 0x08,
        0xc0, 0x28, 0xc0, 0x27, 0xc0, 0x14, 0xc0, 0x13, 0xc0, 0x11, 0xc0, 0x12,
        0xc0, 0x26, 0xc0, 0x25, 0xc0, 0x2a, 0xc0, 0x29, 0xc0, 0x05, 0xc0, 0x04,
        0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x0f, 0xc0, 0x0e, 0xc0, 0x0c, 0xc0, 0x0d,
        0x00, 0x3d, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0x05, 0x00, 0x04, 0x00, 0x35,
        0x00, 0x0a, 0x00, 0x67, 0x00, 0x6b, 0x00, 0x33, 0x00, 0x39, 0x00, 0x16,
        0x00, 0xaf, 0x00, 0xae, 0x00, 0x8d, 0x00, 0x8c, 0x00, 0x8a, 0x00, 0x8b,
        0x00, 0xb1, 0x00, 0xb0, 0x00, 0x2c, 0x00, 0x3b, 0x01, 0x00, 0x00, 0x3b,
        0x00, 0x00, 0x00, 0x15, 0x00, 0x13, 0x00, 0x00, 0x10, 0x61, 0x70, 0x69,
        0x2e, 0x74, 0x65, 0x78, 0x74, 0x6d, 0x61, 0x74, 0x65, 0x2e, 0x6f, 0x72,
        0x67, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00,
        0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x0c, 0x00,
        0x0a, 0x05, 0x01, 0x04, 0x01, 0x02, 0x01, 0x04, 0x03, 0x02, 0x03
    };

    byte buff3[] = { /* no sni extension */
        0x16, 0x03, 0x03, 0x00, 0x4d, 0x01, 0x00, 0x00, 0x49, 0x03, 0x03, 0xea,
        0xa1, 0x9f, 0x60, 0xdd, 0x52, 0x12, 0x13, 0xbd, 0x84, 0x34, 0xd5, 0x1c,
        0x38, 0x25, 0xa8, 0x97, 0xd2, 0xd5, 0xc6, 0x45, 0xaf, 0x1b, 0x08, 0xe4,
        0x1e, 0xbb, 0xdf, 0x9d, 0x39, 0xf0, 0x65, 0x00, 0x00, 0x16, 0x00, 0x6b,
        0x00, 0x67, 0x00, 0x39, 0x00, 0x33, 0x00, 0x3d, 0x00, 0x3c, 0x00, 0x35,
        0x00, 0x2f, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a,
        0x00, 0x0d, 0x00, 0x06, 0x00, 0x04, 0x04, 0x01, 0x02, 0x01
    };

    byte buff4[] = { /* last extension has zero size */
        0x16, 0x03, 0x01, 0x00, 0xba, 0x01, 0x00, 0x00,
        0xb6, 0x03, 0x03, 0x83, 0xa3, 0xe6, 0xdc, 0x16, 0xa1, 0x43, 0xe9, 0x45,
        0x15, 0xbd, 0x64, 0xa9, 0xb6, 0x07, 0xb4, 0x50, 0xc6, 0xdd, 0xff, 0xc2,
        0xd3, 0x0d, 0x4f, 0x36, 0xb4, 0x41, 0x51, 0x61, 0xc1, 0xa5, 0x9e, 0x00,
        0x00, 0x28, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
        0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x07, 0xc0, 0x11,
        0x00, 0x33, 0x00, 0x32, 0x00, 0x39, 0x00, 0x9c, 0x00, 0x2f, 0x00, 0x35,
        0x00, 0x0a, 0x00, 0x05, 0x00, 0x04, 0x01, 0x00, 0x00, 0x65, 0xff, 0x01,
        0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x17, 0x00,
        0x18, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00,
        0x00, 0x33, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1b, 0x00, 0x19, 0x06,
        0x73, 0x70, 0x64, 0x79, 0x2f, 0x33, 0x08, 0x73, 0x70, 0x64, 0x79, 0x2f,
        0x33, 0x2e, 0x31, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31,
        0x75, 0x50, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x10, 0x04, 0x01, 0x05, 0x01, 0x02,
        0x01, 0x04, 0x03, 0x05, 0x03, 0x02, 0x03, 0x04, 0x02, 0x02, 0x02, 0x00,
        0x12, 0x00, 0x00
    };

    byte buff5[] = { /* SSL v2.0 client hello */
        0x00, 0x2b, 0x01, 0x03, 0x01, 0x00, 0x09, 0x00, 0x00,
        /* dummy bytes below, just to pass size check */
        0xb6, 0x03, 0x03, 0x83, 0xa3, 0xe6, 0xdc, 0x16, 0xa1, 0x43, 0xe9, 0x45,
        0x15, 0xbd, 0x64, 0xa9, 0xb6, 0x07, 0xb4, 0x50, 0xc6, 0xdd, 0xff, 0xc2,
        0xd3, 0x0d, 0x4f, 0x36, 0xb4, 0x41, 0x51, 0x61, 0xc1, 0xa5, 0x9e, 0x00,
    };

    byte result[32] = {0};
    word32 length   = 32;

    ExpectIntEQ(0, wolfSSL_SNI_GetFromBuffer(buff4, sizeof(buff4),
                                                           0, result, &length));

    ExpectIntEQ(0, wolfSSL_SNI_GetFromBuffer(buff3, sizeof(buff3),
                                                           0, result, &length));

    ExpectIntEQ(0, wolfSSL_SNI_GetFromBuffer(buff2, sizeof(buff2),
                                                           1, result, &length));

    ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff, sizeof(buff),
                                                           0, result, &length));
    buff[0] = 0x16;

    ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff, sizeof(buff),
                                                           0, result, &length));
    buff[1] = 0x03;

    ExpectIntEQ(WC_NO_ERR_TRACE(SNI_UNSUPPORTED), wolfSSL_SNI_GetFromBuffer(buff,
                                           sizeof(buff), 0, result, &length));
    buff[2] = 0x03;

    ExpectIntEQ(WC_NO_ERR_TRACE(INCOMPLETE_DATA), wolfSSL_SNI_GetFromBuffer(buff,
                                           sizeof(buff), 0, result, &length));
    buff[4] = 0x64;

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SNI_GetFromBuffer(buff, sizeof(buff),
                                                           0, result, &length));
    if (EXPECT_SUCCESS())
        result[length] = 0;
    ExpectStrEQ("www.paypal.com", (const char*) result);

    length = 32;

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SNI_GetFromBuffer(buff2, sizeof(buff2),
                                                           0, result, &length));
    if (EXPECT_SUCCESS())
        result[length] = 0;
    ExpectStrEQ("api.textmate.org", (const char*) result);

    /* SSL v2.0 tests */
    ExpectIntEQ(WC_NO_ERR_TRACE(SNI_UNSUPPORTED), wolfSSL_SNI_GetFromBuffer(buff5,
                                          sizeof(buff5), 0, result, &length));

    buff5[2] = 0x02;
    ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff5,
                                          sizeof(buff5), 0, result, &length));

    buff5[2] = 0x01; buff5[6] = 0x08;
    ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff5,
                                          sizeof(buff5), 0, result, &length));

    buff5[6] = 0x09; buff5[8] = 0x01;
    ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff5,
                                          sizeof(buff5), 0, result, &length));

    return EXPECT_RESULT();
}

#endif /* HAVE_SNI */

#endif /* HAVE_IO_TESTS_DEPENDENCIES */


#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT) && \
    defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
/* Dummy peer functions to satisfy the exporter/importer */
static int test_wolfSSL_dtls_export_peers_get_peer(WOLFSSL* ssl, char* ip,
        int* ipSz, unsigned short* port, int* fam)
{
    (void)ssl;
    ip[0] = -1;
    *ipSz = 1;
    *port = 1;
    *fam = 2;
    return 1;
}

static int test_wolfSSL_dtls_export_peers_set_peer(WOLFSSL* ssl, char* ip,
        int ipSz, unsigned short port, int fam)
{
    (void)ssl;
    if (ip[0] != -1 || ipSz != 1 || port != 1 || fam != 2)
        return 0;
    return 1;
}

static int test_wolfSSL_dtls_export_peers_on_handshake(WOLFSSL_CTX **ctx,
        WOLFSSL **ssl)
{
    EXPECT_DECLS;
    unsigned char* sessionBuf = NULL;
    unsigned int sessionSz = 0;
    void* ioWriteCtx = wolfSSL_GetIOWriteCtx(*ssl);
    void* ioReadCtx = wolfSSL_GetIOReadCtx(*ssl);

    wolfSSL_CTX_SetIOGetPeer(*ctx, test_wolfSSL_dtls_export_peers_get_peer);
    wolfSSL_CTX_SetIOSetPeer(*ctx, test_wolfSSL_dtls_export_peers_set_peer);
    ExpectIntGE(wolfSSL_dtls_export(*ssl, NULL, &sessionSz), 0);
    ExpectNotNull(sessionBuf =
        (unsigned char*)XMALLOC(sessionSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntGE(wolfSSL_dtls_export(*ssl, sessionBuf, &sessionSz), 0);
    wolfSSL_free(*ssl);
    *ssl = NULL;
    ExpectNotNull(*ssl = wolfSSL_new(*ctx));
    ExpectIntGE(wolfSSL_dtls_import(*ssl, sessionBuf, sessionSz), 0);
    wolfSSL_SetIOWriteCtx(*ssl, ioWriteCtx);
    wolfSSL_SetIOReadCtx(*ssl, ioReadCtx);

    XFREE(sessionBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_dtls_export_peers(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT) && \
    defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;
    size_t i, j;
    struct test_params {
        method_provider client_meth;
        method_provider server_meth;
        const char* dtls_version;
    } params[] = {
#ifndef NO_OLD_TLS
        {wolfDTLSv1_client_method, wolfDTLSv1_server_method, "1.0"},
#endif
        {wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "1.2"},
        /* TODO DTLS 1.3 exporting not supported
#ifdef WOLFSSL_DTLS13
        {wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "1.3"},
#endif
         */
    };

    for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
        for (j = 0; j <= 0b11; j++) {
            XMEMSET(&client_cbf, 0, sizeof(client_cbf));
            XMEMSET(&server_cbf, 0, sizeof(server_cbf));

            printf("\n\tTesting DTLS %s connection;", params[i].dtls_version);

            client_cbf.method = params[i].client_meth;
            server_cbf.method = params[i].server_meth;

            if (j & 0b01) {
                client_cbf.on_handshake =
                        test_wolfSSL_dtls_export_peers_on_handshake;
                printf(" With client export;");
            }
            if (j & 0b10) {
                server_cbf.on_handshake =
                        test_wolfSSL_dtls_export_peers_on_handshake;
                printf(" With server export;");
            }

            printf("\n");

            ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
                &server_cbf, NULL), TEST_SUCCESS);
            if (!EXPECT_SUCCESS())
                break;
        }
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_UseTrustedCA(void)
{
    EXPECT_DECLS;
#if defined(HAVE_TRUSTED_CA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \
    && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL     *ssl = NULL;
    byte        id[20];

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull((ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())));
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, WOLFSSL_FILETYPE_PEM));
#else
    ExpectNotNull((ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())));
#endif
    ExpectNotNull((ssl = wolfSSL_new(ctx)));
    XMEMSET(id, 0, sizeof(id));

    /* error cases */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(NULL, 0, NULL, 0));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
                WOLFSSL_TRUSTED_CA_CERT_SHA1+1, NULL, 0));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
                WOLFSSL_TRUSTED_CA_CERT_SHA1, NULL, 0));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
                WOLFSSL_TRUSTED_CA_CERT_SHA1, id, 5));
#ifdef NO_SHA
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
                WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id)));
#endif
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
                WOLFSSL_TRUSTED_CA_X509_NAME, id, 0));

    /* success cases */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
                WOLFSSL_TRUSTED_CA_PRE_AGREED, NULL, 0));
#ifndef NO_SHA
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
                WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id)));
#endif
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
                WOLFSSL_TRUSTED_CA_X509_NAME, id, 5));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* HAVE_TRUSTED_CA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_UseMaxFragment(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MAX_FRAGMENT) && !defined(NO_CERTS) && \
    !defined(NO_FILESYSTEM) && !defined(NO_RSA)

#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
  #ifndef NO_WOLFSSL_SERVER
    WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
  #else
    WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
  #endif
    WOLFSSL     *ssl = NULL;
  #ifdef OPENSSL_EXTRA
    int (*UseMaxFragment)(SSL *s, unsigned char mode);
    int (*CTX_UseMaxFragment)(SSL_CTX *c, unsigned char mode);
  #else
    int (*UseMaxFragment)(WOLFSSL *s, unsigned char mode);
    int (*CTX_UseMaxFragment)(WOLFSSL_CTX *c, unsigned char mode);
  #endif

  #ifndef NO_WOLFSSL_SERVER
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, WOLFSSL_FILETYPE_PEM));
  #endif

    ExpectNotNull(ctx);

    ExpectNotNull(ssl = wolfSSL_new(ctx));

  #ifdef OPENSSL_EXTRA
    CTX_UseMaxFragment = SSL_CTX_set_tlsext_max_fragment_length;
    UseMaxFragment = SSL_set_tlsext_max_fragment_length;
  #else
    UseMaxFragment = wolfSSL_UseMaxFragment;
    CTX_UseMaxFragment = wolfSSL_CTX_UseMaxFragment;
  #endif

    /* error cases */
    ExpectIntNE(WOLFSSL_SUCCESS, CTX_UseMaxFragment(NULL, WOLFSSL_MFL_2_9));
    ExpectIntNE(WOLFSSL_SUCCESS, UseMaxFragment(    NULL, WOLFSSL_MFL_2_9));
    ExpectIntNE(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_MIN-1));
    ExpectIntNE(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_MAX+1));
    ExpectIntNE(WOLFSSL_SUCCESS, UseMaxFragment(ssl, WOLFSSL_MFL_MIN-1));
    ExpectIntNE(WOLFSSL_SUCCESS, UseMaxFragment(ssl, WOLFSSL_MFL_MAX+1));

    /* success case */
  #ifdef OPENSSL_EXTRA
    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), CTX_UseMaxFragment(ctx,  WOLFSSL_MFL_2_8));
  #else
    ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx,  WOLFSSL_MFL_2_8));
  #endif
    ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx,  WOLFSSL_MFL_2_9));
    ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx,  WOLFSSL_MFL_2_10));
    ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx,  WOLFSSL_MFL_2_11));
    ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx,  WOLFSSL_MFL_2_12));
  #ifdef OPENSSL_EXTRA
    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_13));

    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), UseMaxFragment(    ssl,  WOLFSSL_MFL_2_8));
  #else
    ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx,  WOLFSSL_MFL_2_13));

    ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment(    ssl,  WOLFSSL_MFL_2_8));
  #endif
    ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment(    ssl,  WOLFSSL_MFL_2_9));
    ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment(    ssl,  WOLFSSL_MFL_2_10));
    ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment(    ssl,  WOLFSSL_MFL_2_11));
    ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment(    ssl,  WOLFSSL_MFL_2_12));

  #ifdef OPENSSL_EXTRA
    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), UseMaxFragment(    ssl,  WOLFSSL_MFL_2_13));
  #else
    ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment(    ssl,  WOLFSSL_MFL_2_13));
  #endif

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);

#if defined(OPENSSL_EXTRA) && defined(HAVE_MAX_FRAGMENT) && \
    defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
    /* check negotiated max fragment size */
    {
        WOLFSSL *ssl_c = NULL;
        WOLFSSL *ssl_s = NULL;
        struct test_memio_ctx test_ctx;
        WOLFSSL_CTX *ctx_c = NULL;
        WOLFSSL_CTX *ctx_s = NULL;

        XMEMSET(&test_ctx, 0, sizeof(test_ctx));
        ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
        ExpectIntEQ(wolfSSL_UseMaxFragment(ssl_c, WOLFSSL_MFL_2_8),
            WOLFSSL_SUCCESS);
        ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
#ifndef NO_SESSION_CACHE
        ExpectIntEQ(SSL_SESSION_get_max_fragment_length(
            wolfSSL_get_session(ssl_c)), WOLFSSL_MFL_2_8);
#endif

        wolfSSL_free(ssl_c);
        wolfSSL_free(ssl_s);
        wolfSSL_CTX_free(ctx_c);
        wolfSSL_CTX_free(ctx_s);
    }
#endif
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_UseTruncatedHMAC(void)
{
    EXPECT_DECLS;
#if defined(HAVE_TRUNCATED_HMAC) && !defined(NO_CERTS) && \
    !defined(NO_FILESYSTEM) && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
  #ifndef NO_WOLFSSL_SERVER
    WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
  #else
    WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
  #endif
    WOLFSSL     *ssl = NULL;

    ExpectNotNull(ctx);

  #ifndef NO_WOLFSSL_SERVER
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, WOLFSSL_FILETYPE_PEM));
  #endif

    ExpectNotNull(ssl = wolfSSL_new(ctx));

    /* error cases */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTruncatedHMAC(NULL));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTruncatedHMAC(NULL));

    /* success case */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTruncatedHMAC(ctx));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTruncatedHMAC(ssl));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_UseSupportedCurve(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT) && \
    !defined(NO_TLS)
    WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
    WOLFSSL     *ssl = wolfSSL_new(ctx);

    ExpectNotNull(ctx);
    ExpectNotNull(ssl);

    /* error cases */
    ExpectIntNE(WOLFSSL_SUCCESS,
                    wolfSSL_CTX_UseSupportedCurve(NULL, WOLFSSL_ECC_SECP256R1));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSupportedCurve(ctx,  0));

    ExpectIntNE(WOLFSSL_SUCCESS,
                        wolfSSL_UseSupportedCurve(NULL, WOLFSSL_ECC_SECP256R1));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSupportedCurve(ssl,  0));

    /* success case */
    ExpectIntEQ(WOLFSSL_SUCCESS,
                     wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_SECP256R1));
    ExpectIntEQ(WOLFSSL_SUCCESS,
                         wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP256R1));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

#if defined(HAVE_ALPN) && defined(HAVE_IO_TESTS_DEPENDENCIES)

static void verify_ALPN_FATAL_ERROR_on_client(WOLFSSL* ssl)
{
    AssertIntEQ(WC_NO_ERR_TRACE(UNKNOWN_ALPN_PROTOCOL_NAME_E), wolfSSL_get_error(ssl, 0));
}

static void use_ALPN_all(WOLFSSL* ssl)
{
    /* http/1.1,spdy/1,spdy/2,spdy/3 */
    char alpn_list[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x2c,
                        0x73, 0x70, 0x64, 0x79, 0x2f, 0x31, 0x2c,
                        0x73, 0x70, 0x64, 0x79, 0x2f, 0x32, 0x2c,
                        0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, alpn_list, sizeof(alpn_list),
                                             WOLFSSL_ALPN_FAILED_ON_MISMATCH));
}

static void use_ALPN_all_continue(WOLFSSL* ssl)
{
    /* http/1.1,spdy/1,spdy/2,spdy/3 */
    char alpn_list[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x2c,
        0x73, 0x70, 0x64, 0x79, 0x2f, 0x31, 0x2c,
        0x73, 0x70, 0x64, 0x79, 0x2f, 0x32, 0x2c,
        0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, alpn_list, sizeof(alpn_list),
                                             WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));
}

static void use_ALPN_one(WOLFSSL* ssl)
{
    /* spdy/2 */
    char proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};

    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto),
                                             WOLFSSL_ALPN_FAILED_ON_MISMATCH));
}

static void use_ALPN_unknown(WOLFSSL* ssl)
{
    /* http/2.0 */
    char proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x32, 0x2e, 0x30};

    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto),
                                             WOLFSSL_ALPN_FAILED_ON_MISMATCH));
}

static void use_ALPN_unknown_continue(WOLFSSL* ssl)
{
    /* http/2.0 */
    char proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x32, 0x2e, 0x30};

    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto),
                                             WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));
}

static void verify_ALPN_not_matching_spdy3(WOLFSSL* ssl)
{
    /* spdy/3 */
    char nego_proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};

    char *proto = NULL;
    word16 protoSz = 0;

    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));

    /* check value */
    AssertIntNE(1, sizeof(nego_proto) == protoSz);
    if (proto) {
        AssertIntNE(0, XMEMCMP(nego_proto, proto, sizeof(nego_proto)));
    }
}

static void verify_ALPN_not_matching_continue(WOLFSSL* ssl)
{
    char *proto = NULL;
    word16 protoSz = 0;

    AssertIntEQ(WC_NO_ERR_TRACE(WOLFSSL_ALPN_NOT_FOUND),
                wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));

    /* check value */
    AssertIntEQ(1, (0 == protoSz));
    AssertIntEQ(1, (NULL == proto));
}

static void verify_ALPN_matching_http1(WOLFSSL* ssl)
{
    /* http/1.1 */
    char nego_proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31};
    char *proto;
    word16 protoSz = 0;

    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));

    /* check value */
    AssertIntEQ(1, sizeof(nego_proto) == protoSz);
    AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}

static void verify_ALPN_matching_spdy2(WOLFSSL* ssl)
{
    /* spdy/2 */
    char nego_proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};
    char *proto;
    word16 protoSz = 0;

    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));

    /* check value */
    AssertIntEQ(1, sizeof(nego_proto) == protoSz);
    AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}

static void verify_ALPN_client_list(WOLFSSL* ssl)
{
    /* http/1.1,spdy/1,spdy/2,spdy/3 */
    char alpn_list[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x2c,
                        0x73, 0x70, 0x64, 0x79, 0x2f, 0x31, 0x2c,
                        0x73, 0x70, 0x64, 0x79, 0x2f, 0x32, 0x2c,
                        0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
    char    *clist = NULL;
    word16  clistSz = 0;

    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_GetPeerProtocol(ssl, &clist,
                                                          &clistSz));

    /* check value */
    AssertIntEQ(1, sizeof(alpn_list) == clistSz);
    AssertIntEQ(0, XMEMCMP(alpn_list, clist, clistSz));

    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_FreePeerProtocol(ssl, &clist));
}

#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
    defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)

/* ALPN select callback, success with spdy/2 */
static int select_ALPN_spdy2(WOLFSSL *ssl, const unsigned char **out,
    unsigned char *outlen, const unsigned char *in,
    unsigned int inlen, void *arg)
{
    /* spdy/2 */
    const char proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};

    (void)ssl;
    (void)arg;

    /* adding +1 since LEN byte comes first */
    if (inlen < sizeof(proto) + 1) {
        return SSL_TLSEXT_ERR_ALERT_FATAL;
    }

    if (XMEMCMP(in + 1, proto, sizeof(proto)) == 0) {
        *out = in + 1;
        *outlen = (unsigned char)sizeof(proto);
        return SSL_TLSEXT_ERR_OK;
    }

    return SSL_TLSEXT_ERR_ALERT_FATAL;
}

/* ALPN select callback, force failure */
static int select_ALPN_failure(WOLFSSL *ssl, const unsigned char **out,
    unsigned char *outlen, const unsigned char *in,
    unsigned int inlen, void *arg)
{
    (void)ssl;
    (void)out;
    (void)outlen;
    (void)in;
    (void)inlen;
    (void)arg;

    return SSL_TLSEXT_ERR_ALERT_FATAL;
}

static void use_ALPN_spdy2_callback(WOLFSSL* ssl)
{
    wolfSSL_set_alpn_select_cb(ssl, select_ALPN_spdy2, NULL);
}

static void use_ALPN_failure_callback(WOLFSSL* ssl)
{
    wolfSSL_set_alpn_select_cb(ssl, select_ALPN_failure, NULL);
}
#endif /* OPENSSL_ALL | NGINX | HAPROXY | LIGHTY | QUIC */

static int test_wolfSSL_UseALPN_connection(void)
{
    int res = TEST_SKIPPED;
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
    callback_functions client_cb;
    callback_functions server_cb;

    XMEMSET(&client_cb, 0, sizeof(callback_functions));
    XMEMSET(&server_cb, 0, sizeof(callback_functions));
    client_cb.method = wolfSSLv23_client_method;
    server_cb.method = wolfSSLv23_server_method;
    client_cb.devId = testDevId;
    server_cb.devId = testDevId;

    /* success case same list */
    client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all; client_cb.on_result = NULL;
    server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_all; server_cb.on_result = verify_ALPN_matching_http1;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    /* success case only one for server */
    client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all; client_cb.on_result = NULL;
    server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_one; server_cb.on_result = verify_ALPN_matching_spdy2;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    /* success case only one for client */
    client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_one; client_cb.on_result = NULL;
    server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_all; server_cb.on_result = verify_ALPN_matching_spdy2;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    /* success case none for client */
    client_cb.ctx_ready = NULL; client_cb.ssl_ready = NULL;         client_cb.on_result = NULL;
    server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_all; server_cb.on_result = NULL;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    /* success case mismatch behavior but option 'continue' set */
    client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all_continue;     client_cb.on_result = verify_ALPN_not_matching_continue;
    server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_unknown_continue; server_cb.on_result = NULL;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    /* success case read protocol send by client */
    client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all; client_cb.on_result = NULL;
    server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_one; server_cb.on_result = verify_ALPN_client_list;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    /* mismatch behavior with same list
        * the first and only this one must be taken */
    client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all; client_cb.on_result = NULL;
    server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_all; server_cb.on_result = verify_ALPN_not_matching_spdy3;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    /* default mismatch behavior */
    client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all;     client_cb.on_result = NULL;
    server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_unknown; server_cb.on_result = verify_ALPN_FATAL_ERROR_on_client;
    test_wolfSSL_client_server(&client_cb, &server_cb);

#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
    defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)

    /* WOLFSSL-level ALPN select callback tests */
    /* Callback: success (one protocol, spdy/2) */
    client_cb.ctx_ready = NULL;
    client_cb.ssl_ready = use_ALPN_one;
    client_cb.on_result = verify_ALPN_matching_spdy2;
    server_cb.ctx_ready = NULL;
    server_cb.ssl_ready = use_ALPN_spdy2_callback;
    server_cb.on_result = verify_ALPN_matching_spdy2;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    /* Callback: failure (one client protocol, spdy/2) */
    client_cb.ctx_ready = NULL;
    client_cb.ssl_ready = use_ALPN_one;
    client_cb.on_result = NULL;
    server_cb.ctx_ready = NULL;
    server_cb.ssl_ready = use_ALPN_failure_callback;
    server_cb.on_result = verify_ALPN_FATAL_ERROR_on_client;
    test_wolfSSL_client_server(&client_cb, &server_cb);

#endif /* OPENSSL_ALL | NGINX | HAPROXY | LIGHTY */

    res = TEST_RES_CHECK(1);
#endif /* !NO_WOLFSSL_CLIENT && !NO_WOLFSSL_SERVER */
    return res;
}

static int test_wolfSSL_UseALPN_params(void)
{
    EXPECT_DECLS;
#ifndef NO_WOLFSSL_CLIENT
    /* "http/1.1" */
    char http1[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31};
    /* "spdy/1" */
    char spdy1[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x31};
    /* "spdy/2" */
    char spdy2[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};
    /* "spdy/3" */
    char spdy3[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
    char buff[256];
    word32 idx;

    WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
    WOLFSSL     *ssl = wolfSSL_new(ctx);

    ExpectNotNull(ctx);
    ExpectNotNull(ssl);

    /* error cases */
    ExpectIntNE(WOLFSSL_SUCCESS,
                wolfSSL_UseALPN(NULL, http1, sizeof(http1),
                                WOLFSSL_ALPN_FAILED_ON_MISMATCH));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, NULL, 0,
                                              WOLFSSL_ALPN_FAILED_ON_MISMATCH));

    /* success case */
    /* http1 only */
    ExpectIntEQ(WOLFSSL_SUCCESS,
                wolfSSL_UseALPN(ssl, http1, sizeof(http1),
                                WOLFSSL_ALPN_FAILED_ON_MISMATCH));

    /* http1, spdy1 */
    XMEMCPY(buff, http1, sizeof(http1));
    idx = sizeof(http1);
    buff[idx++] = ',';
    XMEMCPY(buff+idx, spdy1, sizeof(spdy1));
    idx += sizeof(spdy1);
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
                                              WOLFSSL_ALPN_FAILED_ON_MISMATCH));

    /* http1, spdy2, spdy1 */
    XMEMCPY(buff, http1, sizeof(http1));
    idx = sizeof(http1);
    buff[idx++] = ',';
    XMEMCPY(buff+idx, spdy2, sizeof(spdy2));
    idx += sizeof(spdy2);
    buff[idx++] = ',';
    XMEMCPY(buff+idx, spdy1, sizeof(spdy1));
    idx += sizeof(spdy1);
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
                                              WOLFSSL_ALPN_FAILED_ON_MISMATCH));

    /* spdy3, http1, spdy2, spdy1 */
    XMEMCPY(buff, spdy3, sizeof(spdy3));
    idx = sizeof(spdy3);
    buff[idx++] = ',';
    XMEMCPY(buff+idx, http1, sizeof(http1));
    idx += sizeof(http1);
    buff[idx++] = ',';
    XMEMCPY(buff+idx, spdy2, sizeof(spdy2));
    idx += sizeof(spdy2);
    buff[idx++] = ',';
    XMEMCPY(buff+idx, spdy1, sizeof(spdy1));
    idx += sizeof(spdy1);
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
                                            WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}
#endif /* HAVE_ALPN  */

#ifdef HAVE_ALPN_PROTOS_SUPPORT
static void CTX_set_alpn_protos(SSL_CTX *ctx)
{
    unsigned char p[] = {
       8, 'h', 't', 't', 'p', '/', '1', '.', '1',
       6, 's', 'p', 'd', 'y', '/', '2',
       6, 's', 'p', 'd', 'y', '/', '1',
    };

    unsigned char p_len = sizeof(p);
    int ret;

    ret = SSL_CTX_set_alpn_protos(ctx, p, p_len);

#ifdef WOLFSSL_ERROR_CODE_OPENSSL
    AssertIntEQ(ret, 0);
#else
    AssertIntEQ(ret, SSL_SUCCESS);
#endif
}

static void set_alpn_protos(SSL* ssl)
{
    unsigned char p[] = {
       6, 's', 'p', 'd', 'y', '/', '3',
       8, 'h', 't', 't', 'p', '/', '1', '.', '1',
       6, 's', 'p', 'd', 'y', '/', '2',
       6, 's', 'p', 'd', 'y', '/', '1',
    };

    unsigned char p_len = sizeof(p);
    int ret;

    ret = SSL_set_alpn_protos(ssl, p, p_len);

#ifdef WOLFSSL_ERROR_CODE_OPENSSL
    AssertIntEQ(ret, 0);
#else
    AssertIntEQ(ret, SSL_SUCCESS);
#endif

}

static void verify_alpn_matching_spdy3(WOLFSSL* ssl)
{
    /* "spdy/3" */
    char nego_proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
    const unsigned char *proto;
    unsigned int protoSz = 0;

    SSL_get0_alpn_selected(ssl, &proto, &protoSz);

    /* check value */
    AssertIntEQ(1, sizeof(nego_proto) == protoSz);
    AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}

static void verify_alpn_matching_http1(WOLFSSL* ssl)
{
    /* "http/1.1" */
    char nego_proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31};
    const unsigned char *proto;
    unsigned int protoSz = 0;

    SSL_get0_alpn_selected(ssl, &proto, &protoSz);

    /* check value */
    AssertIntEQ(1, sizeof(nego_proto) == protoSz);
    AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}

static int test_wolfSSL_set_alpn_protos(void)
{
    int res = TEST_SKIPPED;
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
    callback_functions client_cb;
    callback_functions server_cb;

    XMEMSET(&client_cb, 0, sizeof(callback_functions));
    XMEMSET(&server_cb, 0, sizeof(callback_functions));
    client_cb.method = wolfSSLv23_client_method;
    server_cb.method = wolfSSLv23_server_method;
    client_cb.devId = testDevId;
    server_cb.devId = testDevId;

    /* use CTX_alpn_protos */
    client_cb.ctx_ready = CTX_set_alpn_protos; client_cb.ssl_ready = NULL; client_cb.on_result = NULL;
    server_cb.ctx_ready = CTX_set_alpn_protos; server_cb.ssl_ready = NULL; server_cb.on_result = verify_alpn_matching_http1;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    /* use set_alpn_protos */
    client_cb.ctx_ready = NULL; client_cb.ssl_ready = set_alpn_protos; client_cb.on_result = NULL;
    server_cb.ctx_ready = NULL; server_cb.ssl_ready = set_alpn_protos; server_cb.on_result = verify_alpn_matching_spdy3;
    test_wolfSSL_client_server(&client_cb, &server_cb);

    res = TEST_SUCCESS;
#endif /* !NO_WOLFSSL_CLIENT && !NO_WOLFSSL_SERVER */
    return res;
}

#endif /* HAVE_ALPN_PROTOS_SUPPORT */

static int test_wolfSSL_DisableExtendedMasterSecret(void)
{
    EXPECT_DECLS;
#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
    WOLFSSL     *ssl = wolfSSL_new(ctx);

    ExpectNotNull(ctx);
    ExpectNotNull(ssl);

    /* error cases */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(NULL));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(NULL));

    /* success cases */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(ctx));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(ssl));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_wolfSSL_UseSecureRenegotiation(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SECURE_RENEGOTIATION) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
    WOLFSSL     *ssl = wolfSSL_new(ctx);

    ExpectNotNull(ctx);
    ExpectNotNull(ssl);

    /* error cases */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(NULL));
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(NULL));

    /* success cases */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

/* Test reconnecting with a different ciphersuite after a renegotiation. */
static int test_wolfSSL_SCR_Reconnect(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SECURE_RENEGOTIATION) && \
    defined(BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) && \
    defined(BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) && \
    defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
    byte data;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    test_ctx.c_ciphers = "ECDHE-RSA-AES256-GCM-SHA384";
    test_ctx.s_ciphers =
        "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305";
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx_c));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx_s));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl_c));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl_s));
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
    /* WOLFSSL_FATAL_ERROR since it will block */
    ExpectIntEQ(wolfSSL_Rehandshake(ssl_s), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
                WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(wolfSSL_read(ssl_c, &data, 1), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
                WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
    wolfSSL_free(ssl_c);
    ssl_c = NULL;
    wolfSSL_free(ssl_s);
    ssl_s = NULL;
    wolfSSL_CTX_free(ctx_c);
    ctx_c = NULL;
    test_ctx.c_ciphers = "ECDHE-RSA-CHACHA20-POLY1305";
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
    wolfSSL_free(ssl_s);
    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_s);
    wolfSSL_CTX_free(ctx_c);
#endif
    return EXPECT_RESULT();
}

#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_SERVER) && \
    (!defined(NO_RSA) || defined(HAVE_ECC))
/* Called when writing. */
static int DummySend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
    (void)ssl;
    (void)buf;
    (void)sz;
    (void)ctx;

    /* Force error return from wolfSSL_accept_TLSv13(). */
    return WANT_WRITE;
}
/* Called when reading. */
static int BufferInfoRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
    WOLFSSL_BUFFER_INFO* msg = (WOLFSSL_BUFFER_INFO*)ctx;
    int len = (int)msg->length;

    (void)ssl;
    (void)sz;

    /* Pass back as much of message as will fit in buffer. */
    if (len > sz)
        len = sz;
    XMEMCPY(buf, msg->buffer, len);
    /* Move over returned data. */
    msg->buffer += len;
    msg->length -= (word32)len;

    /* Amount actually copied. */
    return len;
}
#endif

/* Test the detection of duplicate known TLS extensions.
 * Specifically in a ClientHello.
 */
static int test_tls_ext_duplicate(void)
{
    EXPECT_DECLS;
#if !defined(NO_WOLFSSL_SERVER) && (!defined(NO_RSA) || defined(HAVE_ECC)) && \
    !defined(NO_FILESYSTEM)
    const unsigned char clientHelloDupTlsExt[] = {
        0x16, 0x03, 0x03, 0x00, 0x6a, 0x01, 0x00, 0x00,
        0x66, 0x03, 0x03, 0xf4, 0x65, 0xbd, 0x22, 0xfe,
        0x6e, 0xab, 0x66, 0xdd, 0xcf, 0xe9, 0x65, 0x55,
        0xe8, 0xdf, 0xc3, 0x8e, 0x4b, 0x00, 0xbc, 0xf8,
        0x23, 0x57, 0x1b, 0xa0, 0xc8, 0xa9, 0xe2, 0x8c,
        0x91, 0x6e, 0xf9, 0x20, 0xf7, 0x5c, 0xc5, 0x5b,
        0x75, 0x8c, 0x47, 0x0a, 0x0e, 0xc4, 0x1a, 0xda,
        0xef, 0x75, 0xe5, 0x21, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x13, 0x01,
        0x00, 0x9e, 0x01, 0x00,
        /* Extensions - duplicate signature algorithms. */
                                0x00, 0x19, 0x00, 0x0d,
        0x00, 0x04, 0x00, 0x02, 0x04, 0x01, 0x00, 0x0d,
        0x00, 0x04, 0x00, 0x02, 0x04, 0x01,
        /* Supported Versions extension for TLS 1.3. */
                                            0x00, 0x2b,
        0x00, 0x05, 0x04, 0x03, 0x04, 0x03, 0x03
    };
    WOLFSSL_BUFFER_INFO msg;
    const char* testCertFile;
    const char* testKeyFile;
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL     *ssl = NULL;

#ifndef NO_RSA
    testCertFile = svrCertFile;
    testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
    testCertFile = eccCertFile;
    testKeyFile = eccKeyFile;
#endif

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
        WOLFSSL_FILETYPE_PEM));

    /* Read from 'msg'. */
    wolfSSL_SetIORecv(ctx, BufferInfoRecv);
    /* No where to send to - dummy sender. */
    wolfSSL_SetIOSend(ctx, DummySend);

    ssl = wolfSSL_new(ctx);
    ExpectNotNull(ssl);

    msg.buffer = (unsigned char*)clientHelloDupTlsExt;
    msg.length = (unsigned int)sizeof(clientHelloDupTlsExt);
    wolfSSL_SetIOReadCtx(ssl, &msg);

    ExpectIntNE(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
    /* can return duplicate ext error or socket error if the peer closed down
     * while sending alert */
    if (wolfSSL_get_error(ssl, 0) != WC_NO_ERR_TRACE(SOCKET_ERROR_E)) {
        ExpectIntEQ(wolfSSL_get_error(ssl, 0), WC_NO_ERR_TRACE(DUPLICATE_TLS_EXT_E));
    }

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

/*----------------------------------------------------------------------------*
 | X509 Tests
 *----------------------------------------------------------------------------*/
static int test_wolfSSL_X509_NAME_get_entry(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA)
#if defined(OPENSSL_ALL) || \
        (defined(OPENSSL_EXTRA) && \
            (defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)))
    /* use openssl like name to test mapping */
    X509_NAME_ENTRY* ne = NULL;
    X509_NAME* name = NULL;
    X509* x509 = NULL;
#ifndef NO_FILESYSTEM
    ASN1_STRING* asn = NULL;
    char* subCN = NULL;
#endif
    int idx = 0;
    ASN1_OBJECT *object = NULL;
#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || \
    defined(WOLFSSL_NGINX)
#ifndef NO_BIO
    BIO* bio = NULL;
#endif
#endif

#ifndef NO_FILESYSTEM
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = X509_get_subject_name(x509));
    ExpectIntGE(idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1), 0);
    ExpectNotNull(ne = X509_NAME_get_entry(name, idx));
    ExpectNotNull(asn = X509_NAME_ENTRY_get_data(ne));
    ExpectNotNull(subCN = (char*)ASN1_STRING_data(asn));
    wolfSSL_FreeX509(x509);
    x509 = NULL;
#endif

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = X509_get_subject_name(x509));
    ExpectIntGE(idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1), 0);

#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || \
    defined(WOLFSSL_NGINX)
#ifndef NO_BIO
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(X509_NAME_print_ex(bio, name, 4,
                    (XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV)), WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_NAME_print_ex_fp(stderr, name, 4,
                    (XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV)), WOLFSSL_SUCCESS);
    BIO_free(bio);
#endif
#endif

    ExpectNotNull(ne = X509_NAME_get_entry(name, idx));
    ExpectNotNull(object = X509_NAME_ENTRY_get_object(ne));
    wolfSSL_FreeX509(x509);
#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (KEEP_PEER_CERT || SESSION_CERTS) */
#endif /* !NO_CERTS && !NO_RSA */

    return EXPECT_RESULT();
}

/* Testing functions dealing with PKCS12 parsing out X509 certs */
static int test_wolfSSL_PKCS12(void)
{
    EXPECT_DECLS;
    /* .p12 file is encrypted with DES3 */
#ifndef HAVE_FIPS /* Password used in cert "wolfSSL test" is only 12-bytes
                   * (96-bit) FIPS mode requires Minimum of 14-byte (112-bit)
                   * Password Key
                   */
#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) && !defined(NO_FILESYSTEM) && \
    !defined(NO_STDIO_FILESYSTEM) && \
    !defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_RSA) && \
    !defined(NO_SHA) && defined(HAVE_PKCS12) && !defined(NO_BIO)
    byte buf[6000];
    char file[] = "./certs/test-servercert.p12";
    char order[] = "./certs/ecc-rsa-server.p12";
#ifdef WC_RC2
    char rc2p12[] = "./certs/test-servercert-rc2.p12";
#endif
    char pass[] = "a password";
    const char goodPsw[] = "wolfSSL test";
    const char badPsw[] = "bad";
#ifdef HAVE_ECC
    WOLFSSL_X509_NAME *subject = NULL;
    WOLFSSL_X509      *x509 = NULL;
#endif
    XFILE f = XBADFILE;
    int  bytes = 0, ret = 0, goodPswLen = 0, badPswLen = 0;
    WOLFSSL_BIO      *bio = NULL;
    WOLFSSL_EVP_PKEY *pkey = NULL;
    WC_PKCS12        *pkcs12 = NULL;
    WC_PKCS12        *pkcs12_2 = NULL;
    WOLFSSL_X509     *cert = NULL;
    WOLFSSL_X509     *tmp = NULL;
    WOLF_STACK_OF(WOLFSSL_X509) *ca = NULL;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
    || defined(WOLFSSL_NGINX)) && defined(SESSION_CERTS)
    WOLFSSL_CTX      *ctx = NULL;
    WOLFSSL          *ssl = NULL;
    WOLF_STACK_OF(WOLFSSL_X509) *tmp_ca = NULL;
#endif

    ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    goodPswLen = (int)XSTRLEN(goodPsw);
    badPswLen = (int)XSTRLEN(badPsw);

    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));

    ExpectIntEQ(BIO_write(bio, buf, bytes), bytes); /* d2i consumes BIO */
    ExpectNotNull(d2i_PKCS12_bio(bio, &pkcs12));
    ExpectNotNull(pkcs12);
    BIO_free(bio);
    bio = NULL;

    /* check verify MAC directly */
    ExpectIntEQ(ret = PKCS12_verify_mac(pkcs12, goodPsw, goodPswLen), 1);

    /* check verify MAC fail case directly */
    ExpectIntEQ(ret = PKCS12_verify_mac(pkcs12, badPsw, badPswLen), 0);

    /* check verify MAC fail case */
    ExpectIntEQ(ret = PKCS12_parse(pkcs12, "bad", &pkey, &cert, NULL), 0);
    ExpectNull(pkey);
    ExpectNull(cert);

    /* check parse with no extra certs kept */
    ExpectIntEQ(ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, NULL),
        1);
    ExpectNotNull(pkey);
    ExpectNotNull(cert);

    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
    wolfSSL_X509_free(cert);
    cert = NULL;

    /* check parse with extra certs kept */
    ExpectIntEQ(ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, &ca),
        1);
    ExpectNotNull(pkey);
    ExpectNotNull(cert);
    ExpectNotNull(ca);

#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
    || defined(WOLFSSL_NGINX)) && defined(SESSION_CERTS)

    /* Check that SSL_CTX_set0_chain correctly sets the certChain buffer */
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
#if !defined(NO_WOLFSSL_CLIENT) && defined(SESSION_CERTS)
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
    /* Copy stack structure */
    ExpectNotNull(tmp_ca = X509_chain_up_ref(ca));
    ExpectIntEQ(SSL_CTX_set0_chain(ctx, tmp_ca), 1);
    /* CTX now owns the tmp_ca stack structure */
    tmp_ca = NULL;
    ExpectIntEQ(wolfSSL_CTX_get_extra_chain_certs(ctx, &tmp_ca), 1);
    ExpectNotNull(tmp_ca);
    ExpectIntEQ(sk_X509_num(tmp_ca), sk_X509_num(ca));
    /* Check that the main cert is also set */
    ExpectNotNull(SSL_CTX_get0_certificate(ctx));
    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectNotNull(SSL_get_certificate(ssl));
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    ctx = NULL;
#endif
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
    /* should be 2 other certs on stack */
    ExpectNotNull(tmp = sk_X509_pop(ca));
    X509_free(tmp);
    ExpectNotNull(tmp = sk_X509_pop(ca));
    X509_free(tmp);
    ExpectNull(sk_X509_pop(ca));

    EVP_PKEY_free(pkey);
    pkey = NULL;
    X509_free(cert);
    cert = NULL;
    sk_X509_pop_free(ca, X509_free);
    ca = NULL;

    /* check PKCS12_create */
    ExpectNull(PKCS12_create(pass, NULL, NULL, NULL, NULL, -1, -1, -1, -1,0));
    ExpectIntEQ(PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, &ca),
            SSL_SUCCESS);
    ExpectNotNull((pkcs12_2 = PKCS12_create(pass, NULL, pkey, cert, ca,
                    -1, -1, 100, -1, 0)));
    EVP_PKEY_free(pkey);
    pkey = NULL;
    X509_free(cert);
    cert = NULL;
    sk_X509_pop_free(ca, NULL);
    ca = NULL;

    ExpectIntEQ(PKCS12_parse(pkcs12_2, "a password", &pkey, &cert, &ca),
            SSL_SUCCESS);
    PKCS12_free(pkcs12_2);
    pkcs12_2 = NULL;
    ExpectNotNull((pkcs12_2 = PKCS12_create(pass, NULL, pkey, cert, ca,
             NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
             NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
             2000, 1, 0)));
    EVP_PKEY_free(pkey);
    pkey = NULL;
    X509_free(cert);
    cert = NULL;
    sk_X509_pop_free(ca, NULL);
    ca = NULL;

    /* convert to DER then back and parse */
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(i2d_PKCS12_bio(bio, pkcs12_2), SSL_SUCCESS);
    PKCS12_free(pkcs12_2);
    pkcs12_2 = NULL;

    ExpectNotNull(pkcs12_2 = d2i_PKCS12_bio(bio, NULL));
    BIO_free(bio);
    bio = NULL;
    ExpectIntEQ(PKCS12_parse(pkcs12_2, "a password", &pkey, &cert, &ca),
            SSL_SUCCESS);

    /* should be 2 other certs on stack */
    ExpectNotNull(tmp = sk_X509_pop(ca));
    X509_free(tmp);
    ExpectNotNull(tmp = sk_X509_pop(ca));
    X509_free(tmp);
    ExpectNull(sk_X509_pop(ca));


#ifndef NO_RC4
    PKCS12_free(pkcs12_2);
    pkcs12_2 = NULL;
    ExpectNotNull((pkcs12_2 = PKCS12_create(pass, NULL, pkey, cert, NULL,
             NID_pbe_WithSHA1And128BitRC4,
             NID_pbe_WithSHA1And128BitRC4,
             2000, 1, 0)));
    EVP_PKEY_free(pkey);
    pkey = NULL;
    X509_free(cert);
    cert = NULL;
    sk_X509_pop_free(ca, NULL);
    ca = NULL;

    ExpectIntEQ(PKCS12_parse(pkcs12_2, "a password", &pkey, &cert, &ca),
            SSL_SUCCESS);

#endif /* NO_RC4 */

    EVP_PKEY_free(pkey);
    pkey = NULL;
    X509_free(cert);
    cert = NULL;
    PKCS12_free(pkcs12);
    pkcs12 = NULL;
    PKCS12_free(pkcs12_2);
    pkcs12_2 = NULL;
    sk_X509_pop_free(ca, NULL);
    ca = NULL;

#ifdef HAVE_ECC
    /* test order of parsing */
    ExpectTrue((f = XFOPEN(order, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    ExpectNotNull(bio = BIO_new_mem_buf((void*)buf, bytes));
    ExpectNotNull(pkcs12 = d2i_PKCS12_bio(bio, NULL));
    ExpectIntEQ((ret = PKCS12_parse(pkcs12, "", &pkey, &cert, &ca)),
            WOLFSSL_SUCCESS);

    /* check use of pkey after parse */
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
    || defined(WOLFSSL_NGINX)) && defined(SESSION_CERTS)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
#if !defined(NO_WOLFSSL_CLIENT) && defined(SESSION_CERTS)
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
    ExpectIntEQ(SSL_CTX_use_PrivateKey(ctx, pkey), WOLFSSL_SUCCESS);
    SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif

    ExpectNotNull(pkey);
    ExpectNotNull(cert);
    ExpectNotNull(ca);

    /* compare subject lines of certificates */
    ExpectNotNull(subject = wolfSSL_X509_get_subject_name(cert));
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(eccRsaCertFile,
                SSL_FILETYPE_PEM));
    ExpectIntEQ(wolfSSL_X509_NAME_cmp((const WOLFSSL_X509_NAME*)subject,
            (const WOLFSSL_X509_NAME*)wolfSSL_X509_get_subject_name(x509)), 0);
    X509_free(x509);
    x509 = NULL;

    /* test expected fail case */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(eccCertFile,
                SSL_FILETYPE_PEM));
    ExpectIntNE(wolfSSL_X509_NAME_cmp((const WOLFSSL_X509_NAME*)subject,
            (const WOLFSSL_X509_NAME*)wolfSSL_X509_get_subject_name(x509)), 0);
    X509_free(x509);
    x509 = NULL;
    X509_free(cert);
    cert = NULL;

    /* get subject line from ca stack */
    ExpectNotNull(cert = sk_X509_pop(ca));
    ExpectNotNull(subject = wolfSSL_X509_get_subject_name(cert));

    /* compare subject from certificate in ca to expected */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(eccCertFile,
                SSL_FILETYPE_PEM));
    ExpectIntEQ(wolfSSL_X509_NAME_cmp((const WOLFSSL_X509_NAME*)subject,
            (const WOLFSSL_X509_NAME*)wolfSSL_X509_get_subject_name(x509)), 0);

    /* modify case and compare subject from certificate in ca to expected.
     * The first bit of the name is:
     * /C=US/ST=Washington
     * So we'll change subject->name[1] to 'c' (lower case) */
    if (subject != NULL) {
        subject->name[1] = 'c';
        ExpectIntEQ(wolfSSL_X509_NAME_cmp((const WOLFSSL_X509_NAME*)subject,
            (const WOLFSSL_X509_NAME*)wolfSSL_X509_get_subject_name(x509)), 0);
    }

    EVP_PKEY_free(pkey);
    pkey = NULL;
    X509_free(x509);
    x509 = NULL;
    X509_free(cert);
    cert = NULL;
    BIO_free(bio);
    bio = NULL;
    PKCS12_free(pkcs12);
    pkcs12 = NULL;
    sk_X509_pop_free(ca, NULL); /* TEST d2i_PKCS12_fp */
    ca = NULL;

    /* test order of parsing */
    ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
    ExpectNotNull(pkcs12 = d2i_PKCS12_fp(f, NULL));
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    /* check verify MAC fail case */
    ExpectIntEQ(ret = PKCS12_parse(pkcs12, "bad", &pkey, &cert, NULL), 0);
    ExpectNull(pkey);
    ExpectNull(cert);

    /* check parse with no extra certs kept */
    ExpectIntEQ(ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, NULL),
        1);
    ExpectNotNull(pkey);
    ExpectNotNull(cert);

    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
    wolfSSL_X509_free(cert);
    cert = NULL;

    /* check parse with extra certs kept */
    ExpectIntEQ(ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, &ca),
        1);
    ExpectNotNull(pkey);
    ExpectNotNull(cert);
    ExpectNotNull(ca);

    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
    wolfSSL_X509_free(cert);
    cert = NULL;
    sk_X509_pop_free(ca, NULL);
    ca = NULL;

    PKCS12_free(pkcs12);
    pkcs12 = NULL;
#endif /* HAVE_ECC */

#ifdef WC_RC2
    /* test PKCS#12 with RC2 encryption */
    ExpectTrue((f = XFOPEN(rc2p12, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    ExpectNotNull(bio = BIO_new_mem_buf((void*)buf, bytes));
    ExpectNotNull(pkcs12 = d2i_PKCS12_bio(bio, NULL));

    /* check verify MAC fail case */
    ExpectIntEQ(ret = PKCS12_parse(pkcs12, "bad", &pkey, &cert, NULL), 0);
    ExpectNull(pkey);
    ExpectNull(cert);

    /* check parse with not extra certs kept */
    ExpectIntEQ(ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, NULL),
        WOLFSSL_SUCCESS);
    ExpectNotNull(pkey);
    ExpectNotNull(cert);

    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
    wolfSSL_X509_free(cert);
    cert = NULL;

    /* check parse with extra certs kept */
    ExpectIntEQ(ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, &ca),
        WOLFSSL_SUCCESS);
    ExpectNotNull(pkey);
    ExpectNotNull(cert);
    ExpectNotNull(ca);

    wolfSSL_EVP_PKEY_free(pkey);
    wolfSSL_X509_free(cert);
    sk_X509_pop_free(ca, NULL);

    BIO_free(bio);
    bio = NULL;
    PKCS12_free(pkcs12);
    pkcs12 = NULL;
#endif /* WC_RC2 */

    /* Test i2d_PKCS12_bio */
    ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
    ExpectNotNull(pkcs12 = d2i_PKCS12_fp(f, NULL));
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));

    ExpectIntEQ(ret = i2d_PKCS12_bio(bio, pkcs12), 1);

    ExpectIntEQ(ret = i2d_PKCS12_bio(NULL, pkcs12), 0);

    ExpectIntEQ(ret = i2d_PKCS12_bio(bio, NULL), 0);

    PKCS12_free(pkcs12);
    BIO_free(bio);

    (void)order;
#endif /* OPENSSL_EXTRA */
#endif /* HAVE_FIPS */
    return EXPECT_RESULT();
}


#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) && \
    defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && !defined(NO_PWDBASED) && \
    (!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_MD5)
    #define TEST_PKCS8_ENC
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) \
    && defined(HAVE_ECC) && defined(WOLFSSL_ENCRYPTED_KEYS)

/* used to keep track if FailTestCallback was called */
static int failTestCallbackCalled = 0;

static WC_INLINE int FailTestCallBack(char* passwd, int sz, int rw, void* userdata)
{
    (void)passwd;
    (void)sz;
    (void)rw;
    (void)userdata;

    /* mark called, test_wolfSSL_no_password_cb() will check and fail if set */
    failTestCallbackCalled = 1;

    return -1;
}
#endif

static int test_wolfSSL_no_password_cb(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) \
    && defined(HAVE_ECC) && defined(WOLFSSL_ENCRYPTED_KEYS)
    WOLFSSL_CTX* ctx = NULL;
    byte buff[FOURK_BUF];
    const char eccPkcs8PrivKeyDerFile[] = "./certs/ecc-privkeyPkcs8.der";
    const char eccPkcs8PrivKeyPemFile[] = "./certs/ecc-privkeyPkcs8.pem";
    XFILE f = XBADFILE;
    int bytes = 0;

#ifndef NO_WOLFSSL_CLIENT
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLS_client_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLS_server_method()));
#endif
    wolfSSL_CTX_set_default_passwd_cb(ctx, FailTestCallBack);

    ExpectTrue((f = XFOPEN(eccPkcs8PrivKeyDerFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    ExpectIntLE(bytes, sizeof(buff));
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    ExpectTrue((f = XFOPEN(eccPkcs8PrivKeyPemFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);
    ExpectIntLE(bytes, sizeof(buff));
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    wolfSSL_CTX_free(ctx);

    /* Password callback should not be called by default */
    ExpectIntEQ(failTestCallbackCalled, 0);
#endif
    return EXPECT_RESULT();
}

#ifdef TEST_PKCS8_ENC
/* for PKCS8 test case */
static int PKCS8TestCallBack(char* passwd, int sz, int rw, void* userdata)
{
    int flag = 0;

    (void)rw;
    if (userdata != NULL) {
        flag = *((int*)userdata); /* user set data */
    }

    switch (flag) {
        case 1: /* flag set for specific WOLFSSL_CTX structure, note userdata
                 * can be anything the user wishes to be passed to the callback
                 * associated with the WOLFSSL_CTX */
            XSTRNCPY(passwd, "yassl123", sz);
            return 8;

        default:
            return BAD_FUNC_ARG;
    }
}
#endif /* TEST_PKCS8_ENC */

/* Testing functions dealing with PKCS8 */
static int test_wolfSSL_PKCS8(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) && \
    !defined(WOLFCRYPT_ONLY)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    byte buff[FOURK_BUF];
    byte der[FOURK_BUF];
    #ifndef NO_RSA
        const char serverKeyPkcs8PemFile[] = "./certs/server-keyPkcs8.pem";
        const char serverKeyPkcs8DerFile[] = "./certs/server-keyPkcs8.der";
    #endif
    const char eccPkcs8PrivKeyPemFile[] = "./certs/ecc-privkeyPkcs8.pem";
    #ifdef HAVE_ECC
        const char eccPkcs8PrivKeyDerFile[] = "./certs/ecc-privkeyPkcs8.der";
    #endif
    XFILE f = XBADFILE;
    int bytes = 0;
    WOLFSSL_CTX* ctx = NULL;
#if defined(HAVE_ECC) && !defined(NO_CODING) && !defined(WOLFSSL_NO_PEM)
    int ret;
    ecc_key key;
    word32 x = 0;
#endif
#ifdef TEST_PKCS8_ENC
    #if !defined(NO_RSA) && !defined(NO_SHA)
        const char serverKeyPkcs8EncPemFile[] = "./certs/server-keyPkcs8Enc.pem";
        const char serverKeyPkcs8EncDerFile[] = "./certs/server-keyPkcs8Enc.der";
    #endif
    #if defined(HAVE_ECC) && !defined(NO_SHA)
        const char eccPkcs8EncPrivKeyPemFile[] = "./certs/ecc-keyPkcs8Enc.pem";
        const char eccPkcs8EncPrivKeyDerFile[] = "./certs/ecc-keyPkcs8Enc.der";
    #endif
    int flag;
#endif

    (void)der;

#ifndef NO_WOLFSSL_CLIENT
    #ifndef WOLFSSL_NO_TLS12
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
    #endif
#else
    #ifndef WOLFSSL_NO_TLS12
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
    #endif
#endif

#ifdef TEST_PKCS8_ENC
    wolfSSL_CTX_set_default_passwd_cb(ctx, PKCS8TestCallBack);
    wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, (void*)&flag);
    flag = 1; /* used by password callback as return code */

    #if !defined(NO_RSA) && !defined(NO_SHA)
    /* test loading PEM PKCS8 encrypted file */
    ExpectTrue((f = XFOPEN(serverKeyPkcs8EncPemFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    /* this next case should fail because of password callback return code */
    flag = 0; /* used by password callback as return code */
    ExpectIntNE(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    /* decrypt PKCS8 PEM to key in DER format with not using WOLFSSL_CTX */
    ExpectIntGT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der),
        "yassl123"), 0);

    /* test that error value is returned with a bad password */
    ExpectIntLT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der),
        "bad"), 0);

    /* test loading PEM PKCS8 encrypted file */
    ExpectTrue((f = XFOPEN(serverKeyPkcs8EncDerFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    flag = 1; /* used by password callback as return code */
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* this next case should fail because of password callback return code */
    flag = 0; /* used by password callback as return code */
    ExpectIntNE(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    #endif /* !NO_RSA && !NO_SHA */

    #if defined(HAVE_ECC) && !defined(NO_SHA)
    /* test loading PEM PKCS8 encrypted ECC Key file */
    ExpectTrue((f = XFOPEN(eccPkcs8EncPrivKeyPemFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    flag = 1; /* used by password callback as return code */
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    /* this next case should fail because of password callback return code */
    flag = 0; /* used by password callback as return code */
    ExpectIntNE(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    /* decrypt PKCS8 PEM to key in DER format with not using WOLFSSL_CTX */
    ExpectIntGT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der),
        "yassl123"), 0);

    /* test that error value is returned with a bad password */
    ExpectIntLT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der),
        "bad"), 0);

    /* test loading DER PKCS8 encrypted ECC Key file */
    ExpectTrue((f = XFOPEN(eccPkcs8EncPrivKeyDerFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    flag = 1; /* used by password callback as return code */
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* this next case should fail because of password callback return code */
    flag = 0; /* used by password callback as return code */
    ExpectIntNE(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* leave flag as "okay" */
    flag = 1;
    #endif /* HAVE_ECC && !NO_SHA */
#endif /* TEST_PKCS8_ENC */


#ifndef NO_RSA
    /* test loading ASN.1 (DER) PKCS8 private key file (not encrypted) */
    ExpectTrue((f = XFOPEN(serverKeyPkcs8DerFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    /* test loading PEM PKCS8 private key file (not encrypted) */
    ExpectTrue((f = XFOPEN(serverKeyPkcs8PemFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif /* !NO_RSA */

    /* Test PKCS8 PEM ECC key no crypt */
    ExpectTrue((f = XFOPEN(eccPkcs8PrivKeyPemFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
#ifdef HAVE_ECC
    /* Test PKCS8 PEM ECC key no crypt */
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

#if !defined(NO_CODING) && !defined(WOLFSSL_NO_PEM)
    /* decrypt PKCS8 PEM to key in DER format */
    ExpectIntGT((bytes = wc_KeyPemToDer(buff, bytes, der,
        (word32)sizeof(der), NULL)), 0);
    ret = wc_ecc_init(&key);
    if (ret == 0) {
        ret = wc_EccPrivateKeyDecode(der, &x, &key, (word32)bytes);
        wc_ecc_free(&key);
    }
    ExpectIntEQ(ret, 0);
#endif

    /* Test PKCS8 DER ECC key no crypt */
    ExpectTrue((f = XFOPEN(eccPkcs8PrivKeyDerFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    /* Test using a PKCS8 ECC PEM */
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
                WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#else
    /* if HAVE_ECC is not defined then BEGIN EC PRIVATE KEY is not found */
    ExpectIntEQ((bytes = wc_KeyPemToDer(buff, bytes, der,
        (word32)sizeof(der), NULL)), WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));
#endif /* HAVE_ECC */

    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* !NO_FILESYSTEM && !NO_ASN && HAVE_PKCS8 */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PKCS8_ED25519(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && defined(HAVE_PKCS8) && defined(HAVE_AES_CBC) && \
    defined(WOLFSSL_ENCRYPTED_KEYS) && defined(HAVE_ED25519) && \
    defined(HAVE_ED25519_KEY_IMPORT)
    const byte encPrivKey[] = \
    "-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
    "MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAheCGLmWGh7+AICCAAw\n"
    "DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEC4L5P6GappsTyhOOoQfvh8EQJMX\n"
    "OAdlsYKCOcFo4djg6AI1lRdeBRwVFWkha7gBdoCJOzS8wDvTbYcJMPvANu5ft3nl\n"
    "2L9W4v7swXkV+X+a1ww=\n"
    "-----END ENCRYPTED PRIVATE KEY-----\n";
    const char password[] = "abcdefghijklmnopqrstuvwxyz";
    byte der[FOURK_BUF];
    WOLFSSL_CTX* ctx = NULL;
    int bytes;

    XMEMSET(der, 0, sizeof(der));
    ExpectIntGT((bytes = wc_KeyPemToDer(encPrivKey, sizeof(encPrivKey), der,
        (word32)sizeof(der), password)), 0);
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, bytes,
        WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PKCS8_ED448(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && defined(HAVE_PKCS8) && defined(HAVE_AES_CBC) && \
    defined(WOLFSSL_ENCRYPTED_KEYS) && defined(HAVE_ED448) && \
    defined(HAVE_ED448_KEY_IMPORT)
    const byte encPrivKey[] = \
    "-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
    "MIGrMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjSbZKnG4EPggICCAAw\n"
    "DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEFvCFWBBHBlJBsYleBJlJWcEUNC7\n"
    "Tf5pZviT5Btar4D/MNg6BsQHSDf5KW4ix871EsgDY2Zz+euaoWspiMntz7gU+PQu\n"
    "T/JJcbD2Ly8BbE3l5WHMifAQqNLxJBfXrHkfYtAo\n"
    "-----END ENCRYPTED PRIVATE KEY-----\n";
    const char password[] = "abcdefghijklmnopqrstuvwxyz";
    byte der[FOURK_BUF];
    WOLFSSL_CTX* ctx = NULL;
    int bytes;

    XMEMSET(der, 0, sizeof(der));
    ExpectIntGT((bytes = wc_KeyPemToDer(encPrivKey, sizeof(encPrivKey), der,
        (word32)sizeof(der), password)), 0);
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, bytes,
        WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);

    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif
    return EXPECT_RESULT();
}

/* Testing functions dealing with PKCS5 */
static int test_wolfSSL_PKCS5(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SHA) && !defined(NO_PWDBASED)
#ifdef HAVE_FIPS /* Password minimum length is 14 (112-bit) in FIPS MODE */
    const char* passwd = "myfipsPa$$W0rd";
#else
    const char *passwd = "pass1234";
#endif
    const unsigned char *salt = (unsigned char *)"salt1234";
    unsigned char *out = (unsigned char *)XMALLOC(WC_SHA_DIGEST_SIZE, NULL,
                                                  DYNAMIC_TYPE_TMP_BUFFER);
    int ret = 0;

    ExpectNotNull(out);
    ExpectIntEQ(ret = PKCS5_PBKDF2_HMAC_SHA1(passwd,(int)XSTRLEN(passwd), salt,
        (int)XSTRLEN((const char *) salt), 10, WC_SHA_DIGEST_SIZE,out),
        WOLFSSL_SUCCESS);

#ifdef WOLFSSL_SHA512
    ExpectIntEQ(ret = PKCS5_PBKDF2_HMAC(passwd,(int)XSTRLEN(passwd), salt,
        (int)XSTRLEN((const char *) salt), 10, wolfSSL_EVP_sha512(),
        WC_SHA_DIGEST_SIZE, out), SSL_SUCCESS);
#endif

    XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_SHA) */
    return EXPECT_RESULT();
}

/* test parsing URI from certificate */
static int test_wolfSSL_URI(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) \
    && (defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
    defined(OPENSSL_EXTRA))
    WOLFSSL_X509* x509 = NULL;
    const char uri[] = "./certs/client-uri-cert.pem";
    const char urn[] = "./certs/client-absolute-urn.pem";
    const char badUri[] = "./certs/client-relative-uri.pem";

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(uri,
        WOLFSSL_FILETYPE_PEM));
    wolfSSL_FreeX509(x509);
    x509 = NULL;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(urn,
        WOLFSSL_FILETYPE_PEM));
    wolfSSL_FreeX509(x509);
    x509 = NULL;

#if !defined(IGNORE_NAME_CONSTRAINTS) && !defined(WOLFSSL_NO_ASN_STRICT) \
    && !defined(WOLFSSL_FPKI)
    ExpectNull(x509 = wolfSSL_X509_load_certificate_file(badUri,
        WOLFSSL_FILETYPE_PEM));
#else
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(badUri,
        WOLFSSL_FILETYPE_PEM));
#endif
    wolfSSL_FreeX509(x509);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_TBS(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) \
    && defined(OPENSSL_EXTRA)
    WOLFSSL_X509* x509 = NULL;
    const unsigned char* tbs;
    int tbsSz;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(caCertFile,
        WOLFSSL_FILETYPE_PEM));

    ExpectNull(tbs = wolfSSL_X509_get_tbs(NULL, &tbsSz));
    ExpectNull(tbs = wolfSSL_X509_get_tbs(x509, NULL));
    ExpectNotNull(tbs = wolfSSL_X509_get_tbs(x509, &tbsSz));
    ExpectIntEQ(tbsSz, 1003);

    wolfSSL_FreeX509(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_verify(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \
    defined(OPENSSL_EXTRA)
    WOLFSSL_X509* ca = NULL;
    WOLFSSL_X509* serv = NULL;
    WOLFSSL_EVP_PKEY* pkey = NULL;
    unsigned char buf[2048];
    const unsigned char* pt = NULL;
    int bufSz;

    ExpectNotNull(ca = wolfSSL_X509_load_certificate_file(caCertFile,
        WOLFSSL_FILETYPE_PEM));

    ExpectIntNE(wolfSSL_X509_get_pubkey_buffer(NULL, buf, &bufSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_get_pubkey_buffer(ca, NULL, &bufSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(bufSz, 294);

    bufSz = 2048;
    ExpectIntEQ(wolfSSL_X509_get_pubkey_buffer(ca, buf, &bufSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_get_pubkey_type(NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_X509_get_pubkey_type(ca), RSAk);


    ExpectNotNull(serv = wolfSSL_X509_load_certificate_file(svrCertFile,
        WOLFSSL_FILETYPE_PEM));

    /* success case */
    pt = buf;
    ExpectNotNull(pkey = wolfSSL_d2i_PUBKEY(NULL, &pt, bufSz));

    ExpectIntEQ(i2d_PUBKEY(pkey, NULL), bufSz);

    ExpectIntEQ(wolfSSL_X509_verify(serv, pkey), WOLFSSL_SUCCESS);
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;

    /* fail case */
    bufSz = 2048;
    ExpectIntEQ(wolfSSL_X509_get_pubkey_buffer(serv, buf, &bufSz),
        WOLFSSL_SUCCESS);
    pt = buf;
    ExpectNotNull(pkey = wolfSSL_d2i_PUBKEY(NULL, &pt, bufSz));
    ExpectIntEQ(wolfSSL_X509_verify(serv, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(wolfSSL_X509_verify(NULL, pkey), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(wolfSSL_X509_verify(serv, NULL), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    wolfSSL_EVP_PKEY_free(pkey);

    wolfSSL_FreeX509(ca);
    wolfSSL_FreeX509(serv);
#endif
    return EXPECT_RESULT();
}

#if defined(WOLFSSL_ACERT) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
/* Given acert file and its pubkey file, read them and then
 * attempt to verify signed acert.
 *
 * If expect_pass is true, then verification should pass.
 * If expect_pass is false, then verification should fail.
 * */
static int do_acert_verify_test(const char * acert_file,
                                const char * pkey_file,
                                size_t       expect_pass)
{
    X509_ACERT * x509 = NULL;
    EVP_PKEY *   pkey = NULL;
    BIO *        bp = NULL;
    int          verify_rc = 0;

    /* First read the attribute certificate. */
    bp = BIO_new_file(acert_file, "r");
    if (bp == NULL) {
        return -1;
    }

    x509 = PEM_read_bio_X509_ACERT(bp, NULL, NULL, NULL);
    BIO_free(bp);
    bp = NULL;

    if (x509 == NULL) {
        return -1;
    }

    /* Next read the associated pub key. */
    bp = BIO_new_file(pkey_file, "r");

    if (bp == NULL) {
        X509_ACERT_free(x509);
        x509 = NULL;
        return -1;
    }

    pkey = PEM_read_bio_PUBKEY(bp, &pkey, NULL, NULL);
    BIO_free(bp);
    bp = NULL;

    if (pkey == NULL) {
        X509_ACERT_free(x509);
        x509 = NULL;
        return -1;
    }

    /* Finally, do verification. */
    verify_rc = X509_ACERT_verify(x509, pkey);

    X509_ACERT_free(x509);
    x509 = NULL;

    EVP_PKEY_free(pkey);
    pkey = NULL;

    if (expect_pass && verify_rc != 1) {
        return -1;
    }

    if (!expect_pass && verify_rc == 1) {
        return -1;
    }

    return 0;
}
#endif

static int test_wolfSSL_X509_ACERT_verify(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_ACERT) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    defined(WC_RSA_PSS) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
    /* Walk over list of signed ACERTs and their pubkeys.
     * All should load and pass verification. */
    const char * acerts[4] = {"certs/acert/acert.pem",
                              "certs/acert/acert_ietf.pem",
                              "certs/acert/rsa_pss/acert.pem",
                              "certs/acert/rsa_pss/acert_ietf.pem"};
    const char * pkeys[4] =  {"certs/acert/acert_pubkey.pem",
                              "certs/acert/acert_ietf_pubkey.pem",
                              "certs/acert/rsa_pss/acert_pubkey.pem",
                              "certs/acert/rsa_pss/acert_ietf_pubkey.pem"};
    int    rc = 0;
    size_t i = 0;
    size_t j = 0;

    for (i = 0; i < 4; ++i) {
        for (j = i; j < 4; ++j) {
            rc = do_acert_verify_test(acerts[i], pkeys[j], i == j);

            if (rc) {
                fprintf(stderr, "error: %s: i = %zu, j = %zu, rc = %d\n",
                        "do_acert_verify_test", i, j, rc);
                break;
            }
        }

        if (rc) { break; }
    }

    ExpectIntEQ(rc, 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_ACERT_misc_api(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_ACERT) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
    const char * acerts[4] = {"certs/acert/acert.pem",
                              "certs/acert/acert_ietf.pem",
                              "certs/acert/rsa_pss/acert.pem",
                              "certs/acert/rsa_pss/acert_ietf.pem"};
    int          rc = 0;
    X509_ACERT * x509 = NULL;
    BIO *        bp = NULL;
    long         ver_long = 0;
    int          ver = 0;
    int          nid = 0;
    const byte * raw_attr = NULL;
    word32       attr_len = 0;
    size_t       i = 0;
    int          buf_len = 0;
    byte         ietf_serial[] = {0x03, 0xb5, 0x90, 0x59, 0x02,
                                  0xa2, 0xaa, 0xb5, 0x40, 0x21,
                                  0x44, 0xb8, 0x2c, 0x4f, 0xd9,
                                  0x80, 0x1b, 0x5f, 0x57, 0xc2};

    for (i = 0; i < 4; ++i) {
        const char * acert_file = acerts[i];
        int          is_rsa_pss = 0;
        int          is_ietf_acert = 0;
        byte         serial[64];
        int          serial_len = sizeof(serial);

        XMEMSET(serial, 0, sizeof(serial));

        is_rsa_pss = XSTRSTR(acert_file, "rsa_pss") != NULL ? 1 : 0;
        is_ietf_acert = XSTRSTR(acert_file, "ietf.pem") != NULL ? 1 : 0;

        /* First read the attribute certificate. */
        bp = BIO_new_file(acert_file, "r");
        ExpectNotNull(bp);

        x509 = PEM_read_bio_X509_ACERT(bp, NULL, NULL, NULL);
        ExpectNotNull(x509);

        /* We're done with the bio for now. */
        if (bp != NULL) {
            BIO_free(bp);
            bp = NULL;
        }

        /* Check version and signature NID. */
        ver_long = X509_ACERT_get_version(x509);
        ExpectIntEQ(ver_long, 1);

        ver = wolfSSL_X509_ACERT_version(x509);
        ExpectIntEQ(ver, 2);

        nid = X509_ACERT_get_signature_nid(x509);

        if (is_rsa_pss) {
            ExpectIntEQ(nid, NID_rsassaPss);
        }
        else {
            ExpectIntEQ(nid, NID_sha256WithRSAEncryption);
        }

        /* Get the serial number buffer.
         * The ietf acert example has a 20 byte serial number. */
        rc = wolfSSL_X509_ACERT_get_serial_number(x509, serial, &serial_len);
        ExpectIntEQ(rc, SSL_SUCCESS);

        if (is_ietf_acert) {
            ExpectIntEQ(serial_len, 20);
            ExpectIntEQ(XMEMCMP(serial, ietf_serial, sizeof(ietf_serial)), 0);
        }
        else {
            ExpectIntEQ(serial_len, 1);
            ExpectTrue(serial[0] == 0x01);
        }

        /* Repeat the same but with null serial buffer. This is ok. */
        rc = wolfSSL_X509_ACERT_get_serial_number(x509, NULL, &serial_len);
        ExpectIntEQ(rc, SSL_SUCCESS);

        if (is_ietf_acert) {
            ExpectIntEQ(serial_len, 20);
        }
        else {
            ExpectIntEQ(serial_len, 1);
            ExpectTrue(serial[0] == 0x01);
        }

        /* Get the attributes buffer. */
        rc = wolfSSL_X509_ACERT_get_attr_buf(x509, &raw_attr, &attr_len);
        ExpectIntEQ(rc, SSL_SUCCESS);

        if (is_ietf_acert) {
            /* This cert has a 65 byte attributes field. */
            ExpectNotNull(raw_attr);
            ExpectIntEQ(attr_len, 65);
        }
        else {
            /* This cert has a 237 byte attributes field. */
            ExpectNotNull(raw_attr);
            ExpectIntEQ(attr_len, 237);
        }

        /* Test printing acert to memory bio. */
        ExpectNotNull(bp = BIO_new(BIO_s_mem()));
        rc = X509_ACERT_print(bp, x509);
        ExpectIntEQ(rc, SSL_SUCCESS);

        /* Now do a bunch of invalid stuff with partially valid inputs. */
        rc = wolfSSL_X509_ACERT_get_attr_buf(x509, &raw_attr, NULL);
        ExpectIntEQ(rc, BAD_FUNC_ARG);

        rc = wolfSSL_X509_ACERT_get_attr_buf(x509, NULL, &attr_len);
        ExpectIntEQ(rc, BAD_FUNC_ARG);

        rc = wolfSSL_X509_ACERT_get_attr_buf(NULL, &raw_attr, &attr_len);
        ExpectIntEQ(rc, BAD_FUNC_ARG);

        ver_long = X509_ACERT_get_version(NULL);
        ExpectIntEQ(ver_long, 0);

        ver = wolfSSL_X509_ACERT_version(NULL);
        ExpectIntEQ(ver, 0);

        rc = wolfSSL_X509_ACERT_get_signature(x509, NULL, NULL);
        ExpectIntEQ(rc, WOLFSSL_FATAL_ERROR);

        rc = wolfSSL_X509_ACERT_get_signature(x509, NULL, &buf_len);
        ExpectIntEQ(rc, SSL_SUCCESS);
        ExpectIntEQ(buf_len, 256);

        rc = wolfSSL_X509_ACERT_get_serial_number(x509, serial, NULL);
        ExpectIntEQ(rc, BAD_FUNC_ARG);

        rc = X509_ACERT_print(bp, NULL);
        ExpectIntEQ(rc, WOLFSSL_FAILURE);

        rc = X509_ACERT_print(NULL, x509);
        ExpectIntEQ(rc, WOLFSSL_FAILURE);

        /* Finally free the acert and bio, we're done with them. */
        if (x509 != NULL) {
            X509_ACERT_free(x509);
            x509 = NULL;
        }

        if (bp != NULL) {
            BIO_free(bp);
            bp = NULL;
        }
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_ACERT_buffer(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_ACERT) && !defined(NO_CERTS) && \
    !defined(NO_RSA) && defined(WC_RSA_PSS) && \
    (defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA))
    const byte acert_ietf[] = \
    "-----BEGIN ATTRIBUTE CERTIFICATE-----\n"
    "MIICPTCCASUCAQEwN6AWMBGkDzANMQswCQYDVQQDDAJDQQIBAqEdpBswGTEXMBUG\n"
    "A1UEAwwOc2VydmVyLmV4YW1wbGWgLTArpCkwJzElMCMGA1UEAwwcQXR0cmlidXRl\n"
    "IENlcnRpZmljYXRlIElzc3VlcjANBgkqhkiG9w0BAQsFAAIUA7WQWQKiqrVAIUS4\n"
    "LE/ZgBtfV8IwIhgPMjAyMTA2MTUxMjM1MDBaGA8yMDMxMDYxMzEyMzUwMFowQTAj\n"
    "BggrBgEFBQcKBDEXMBWgCYYHVGVzdHZhbDAIDAZncm91cDEwGgYDVQRIMRMwEaEP\n"
    "gw1hZG1pbmlzdHJhdG9yMCwwHwYDVR0jBBgwFoAUYm7JaGdsZLtTgt0tqoCK2MrI\n"
    "i10wCQYDVR04BAIFADANBgkqhkiG9w0BAQsFAAOCAQEAlIOJ2Dj3TEUj6BIv6vUs\n"
    "GqFWms05i+d10XSzWrunlUTQPoJcUjYkifOWp/7RpZ2XnRl+6hH+nIbmwSmXWwBn\n"
    "ERw2bQMmw/""/nWuN4Qv9t7ltuovWC0pJX6VMT1IRTuTV4SxuZpFL37vkmnFlPBlb+\n"
    "mn3ESSxLTjThWFIq1tip4IaxE/i5Uh32GlJglatFHM1PCGoJtyLtYb6KHDlvknw6\n"
    "coDyjIcj0FZwtQw41jLwxI8jWNmrpt978wdpprB/URrRs+m02HmeQoiHFi/qvdv8\n"
    "d+5vHf3Pi/ulhz/+dvr0p1vEQSoFnYxLXuty2p5m3PJPZCFmT3gURgmgR3BN9d7A\n"
    "Bw==\n"
    "-----END ATTRIBUTE CERTIFICATE-----\n";
    X509_ACERT * x509 = NULL;
    int          rc = 0;
    byte         ietf_serial[] = {0x03, 0xb5, 0x90, 0x59, 0x02,
                                  0xa2, 0xaa, 0xb5, 0x40, 0x21,
                                  0x44, 0xb8, 0x2c, 0x4f, 0xd9,
                                  0x80, 0x1b, 0x5f, 0x57, 0xc2};
    byte         serial[64];
    int          serial_len = sizeof(serial);
    const byte * raw_attr = NULL;
    word32       attr_len = 0;

    x509 = wolfSSL_X509_ACERT_load_certificate_buffer_ex(acert_ietf,
                                                         sizeof(acert_ietf),
                                                         WOLFSSL_FILETYPE_PEM,
                                                         HEAP_HINT);

    rc = wolfSSL_X509_ACERT_get_serial_number(x509, serial, &serial_len);
    ExpectIntEQ(rc, SSL_SUCCESS);

    ExpectIntEQ(serial_len, 20);
    ExpectIntEQ(XMEMCMP(serial, ietf_serial, sizeof(ietf_serial)), 0);

    /* Get the attributes buffer. */
    rc = wolfSSL_X509_ACERT_get_attr_buf(x509, &raw_attr, &attr_len);
    ExpectIntEQ(rc, SSL_SUCCESS);

    /* This cert has a 65 byte attributes field. */
    ExpectNotNull(raw_attr);
    ExpectIntEQ(attr_len, 65);

    ExpectNotNull(x509);

    if (x509 != NULL) {
        wolfSSL_X509_ACERT_free(x509);
        x509 = NULL;
    }
#endif
    return EXPECT_RESULT();
}

/* Test ACERT support, but with ASN functions only.
 * */
static int test_wolfSSL_X509_ACERT_asn(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_ACERT) && !defined(NO_CERTS)
    const byte acert_ietf[] = \
    "-----BEGIN ATTRIBUTE CERTIFICATE-----\n"
    "MIICPTCCASUCAQEwN6AWMBGkDzANMQswCQYDVQQDDAJDQQIBAqEdpBswGTEXMBUG\n"
    "A1UEAwwOc2VydmVyLmV4YW1wbGWgLTArpCkwJzElMCMGA1UEAwwcQXR0cmlidXRl\n"
    "IENlcnRpZmljYXRlIElzc3VlcjANBgkqhkiG9w0BAQsFAAIUA7WQWQKiqrVAIUS4\n"
    "LE/ZgBtfV8IwIhgPMjAyMTA2MTUxMjM1MDBaGA8yMDMxMDYxMzEyMzUwMFowQTAj\n"
    "BggrBgEFBQcKBDEXMBWgCYYHVGVzdHZhbDAIDAZncm91cDEwGgYDVQRIMRMwEaEP\n"
    "gw1hZG1pbmlzdHJhdG9yMCwwHwYDVR0jBBgwFoAUYm7JaGdsZLtTgt0tqoCK2MrI\n"
    "i10wCQYDVR04BAIFADANBgkqhkiG9w0BAQsFAAOCAQEAlIOJ2Dj3TEUj6BIv6vUs\n"
    "GqFWms05i+d10XSzWrunlUTQPoJcUjYkifOWp/7RpZ2XnRl+6hH+nIbmwSmXWwBn\n"
    "ERw2bQMmw/""/nWuN4Qv9t7ltuovWC0pJX6VMT1IRTuTV4SxuZpFL37vkmnFlPBlb+\n"
    "mn3ESSxLTjThWFIq1tip4IaxE/i5Uh32GlJglatFHM1PCGoJtyLtYb6KHDlvknw6\n"
    "coDyjIcj0FZwtQw41jLwxI8jWNmrpt978wdpprB/URrRs+m02HmeQoiHFi/qvdv8\n"
    "d+5vHf3Pi/ulhz/+dvr0p1vEQSoFnYxLXuty2p5m3PJPZCFmT3gURgmgR3BN9d7A\n"
    "Bw==\n"
    "-----END ATTRIBUTE CERTIFICATE-----\n";
    int            rc = 0;
    byte           ietf_serial[] = {0x03, 0xb5, 0x90, 0x59, 0x02,
                                    0xa2, 0xaa, 0xb5, 0x40, 0x21,
                                    0x44, 0xb8, 0x2c, 0x4f, 0xd9,
                                    0x80, 0x1b, 0x5f, 0x57, 0xc2};
    DerBuffer *    der = NULL;
    #ifdef WOLFSSL_SMALL_STACK
    DecodedAcert * acert = NULL;
    #else
    DecodedAcert   acert[1];
    #endif

    rc = wc_PemToDer(acert_ietf, sizeof(acert_ietf), ACERT_TYPE, &der,
                     HEAP_HINT, NULL, NULL);

    ExpectIntEQ(rc, 0);
    ExpectNotNull(der);

    if (der != NULL) {
        ExpectNotNull(der->buffer);
    }

    #ifdef WOLFSSL_SMALL_STACK
    acert = (DecodedAcert*)XMALLOC(sizeof(DecodedAcert), HEAP_HINT,
                                   DYNAMIC_TYPE_DCERT);
    ExpectNotNull(acert);
    #endif

    #ifdef WOLFSSL_SMALL_STACK
    if (acert != NULL)
    #endif
    {
        if (der != NULL && der->buffer != NULL) {
            wc_InitDecodedAcert(acert, der->buffer, der->length, HEAP_HINT);
            rc = wc_ParseX509Acert(acert, VERIFY_SKIP_DATE);
            ExpectIntEQ(rc, 0);
        }

        ExpectIntEQ(acert->serialSz, 20);
        ExpectIntEQ(XMEMCMP(acert->serial, ietf_serial, sizeof(ietf_serial)),
                    0);

        /* This cert has a 65 byte attributes field. */
        ExpectNotNull(acert->rawAttr);
        ExpectIntEQ(acert->rawAttrLen, 65);

        wc_FreeDecodedAcert(acert);
    }

    #ifdef WOLFSSL_SMALL_STACK
    if (acert != NULL) {
        XFREE(acert, HEAP_HINT, DYNAMIC_TYPE_DCERT);
        acert = NULL;
    }
    #endif

    if (der != NULL) {
        wc_FreeDer(&der);
    }

#endif
    return EXPECT_RESULT();
}

#if !defined(NO_DH) && !defined(NO_AES) && defined(WOLFSSL_CERT_GEN) && \
         defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
         defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
/* create certificate with version 2 */
static int test_set_x509_badversion(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    WOLFSSL_X509 *x509 = NULL, *x509v2 = NULL;
    WOLFSSL_EVP_PKEY *priv = NULL, *pub = NULL;
    unsigned char *der = NULL, *key = NULL, *pt;
    char *header = NULL, *name = NULL;
    int derSz;
    long keySz;
    XFILE fp = XBADFILE;
    WOLFSSL_ASN1_TIME *notBefore = NULL, *notAfter = NULL;
    time_t t;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
                WOLFSSL_FILETYPE_PEM));

    ExpectTrue((fp = XFOPEN(cliKeyFile, "rb")) != XBADFILE);
    ExpectIntEQ(wolfSSL_PEM_read(fp, &name, &header, &key, &keySz),
            WOLFSSL_SUCCESS);
    if (fp != XBADFILE)
        XFCLOSE(fp);
    pt = key;
    ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
                (const unsigned char**)&pt, keySz));


    /* create the version 2 certificate */
    ExpectNotNull(x509v2 = X509_new());
    ExpectIntEQ(wolfSSL_X509_set_version(x509v2, 1), WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_X509_set_subject_name(x509v2,
                wolfSSL_X509_get_subject_name(x509)), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509v2,
                wolfSSL_X509_get_issuer_name(x509)), WOLFSSL_SUCCESS);
    ExpectNotNull(pub = wolfSSL_X509_get_pubkey(x509));
    ExpectIntEQ(X509_set_pubkey(x509v2, pub), WOLFSSL_SUCCESS);

    t = time(NULL);
    ExpectNotNull(notBefore = wolfSSL_ASN1_TIME_adj(NULL, t, 0, 0));
    ExpectNotNull(notAfter = wolfSSL_ASN1_TIME_adj(NULL, t, 365, 0));
    ExpectTrue(wolfSSL_X509_set_notBefore(x509v2, notBefore));
    ExpectTrue(wolfSSL_X509_set_notAfter(x509v2, notAfter));

    ExpectIntGT(wolfSSL_X509_sign(x509v2, priv, EVP_sha256()), 0);
    derSz = wolfSSL_i2d_X509(x509v2, &der);
    ExpectIntGT(derSz, 0);
    ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx, der, derSz,
                                     WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
    /* TODO: Replace with API call */
    XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
    XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(name, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(header, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    wolfSSL_X509_free(x509);
    wolfSSL_X509_free(x509v2);
    wolfSSL_EVP_PKEY_free(priv);
    wolfSSL_EVP_PKEY_free(pub);
    wolfSSL_ASN1_TIME_free(notBefore);
    wolfSSL_ASN1_TIME_free(notAfter);

    return EXPECT_RESULT();
}


/* override certificate version error */
static int test_override_x509(int preverify, WOLFSSL_X509_STORE_CTX* store)
{
    EXPECT_DECLS;
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
    ExpectIntEQ(store->error, WC_NO_ERR_TRACE(ASN_VERSION_E));
#else
    ExpectIntEQ(store->error, 0);
#endif
    ExpectIntEQ((int)wolfSSL_X509_get_version(store->current_cert), 1);
    (void)preverify;
    return EXPECT_RESULT() == TEST_SUCCESS;
}


/* set verify callback that will override bad certificate version */
static int test_set_override_x509(WOLFSSL_CTX* ctx)
{
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, test_override_x509);
    return TEST_SUCCESS;
}
#endif


static int test_wolfSSL_X509_TLS_version_test_1(void)
{
    EXPECT_DECLS;
#if !defined(NO_DH) && !defined(NO_AES) && defined(WOLFSSL_CERT_GEN) && \
         defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
         defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
    test_ssl_cbf func_cb_client;
    test_ssl_cbf func_cb_server;

    /* test server rejects a client certificate that is not version 3 */
    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

    func_cb_client.ctx_ready = &test_set_x509_badversion;
#ifndef WOLFSSL_NO_TLS12
    func_cb_client.method = wolfTLSv1_2_client_method;
#else
    func_cb_client.method = wolfTLSv1_3_client_method;
#endif

#ifndef WOLFSSL_NO_TLS12
    func_cb_server.method = wolfTLSv1_2_server_method;
#else
    func_cb_server.method = wolfTLSv1_3_server_method;
#endif

#ifndef OPENSSL_COMPATIBLE_DEFAULTS
    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
        &func_cb_server, NULL), -1001);
#else
    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
        &func_cb_server, NULL), TEST_SUCCESS);
#endif
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_TLS_version_test_2(void)
{
    EXPECT_DECLS;
#if !defined(NO_DH) && !defined(NO_AES) && defined(WOLFSSL_CERT_GEN) && \
         defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
         defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
    test_ssl_cbf func_cb_client;
    test_ssl_cbf func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

    func_cb_client.ctx_ready = &test_set_x509_badversion;
    func_cb_server.ctx_ready = &test_set_override_x509;
#ifndef WOLFSSL_NO_TLS12
    func_cb_client.method = wolfTLSv1_2_client_method;
#else
    func_cb_client.method = wolfTLSv1_3_client_method;
#endif

#ifndef WOLFSSL_NO_TLS12
    func_cb_server.method = wolfTLSv1_2_server_method;
#else
    func_cb_server.method = wolfTLSv1_3_server_method;
#endif

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
        &func_cb_server, NULL), TEST_SUCCESS);
#endif

    return EXPECT_RESULT();
}

/* Testing function  wolfSSL_CTX_SetMinVersion; sets the minimum downgrade
 * version allowed.
 * POST: 1 on success.
 */
static int test_wolfSSL_CTX_SetMinVersion(void)
{
    int                     res = TEST_SKIPPED;
#ifndef NO_WOLFSSL_CLIENT
    int                     failFlag = WOLFSSL_SUCCESS;
    WOLFSSL_CTX*            ctx;
    int                     itr;

    #ifndef NO_OLD_TLS
        const int versions[]  = {
                            #ifdef WOLFSSL_ALLOW_TLSV10
                                  WOLFSSL_TLSV1,
                            #endif
                                  WOLFSSL_TLSV1_1,
                                  WOLFSSL_TLSV1_2 };
    #elif !defined(WOLFSSL_NO_TLS12)
        const int versions[]  = { WOLFSSL_TLSV1_2 };
    #elif defined(WOLFSSL_TLS13)
        const int versions[]  = { WOLFSSL_TLSV1_3 };
    #else
        const int versions[0];
    #endif

    ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());

    for (itr = 0; itr < (int)(sizeof(versions)/sizeof(int)); itr++) {
        if (wolfSSL_CTX_SetMinVersion(ctx, *(versions + itr))
                != WOLFSSL_SUCCESS) {
            failFlag = WOLFSSL_FAILURE;
        }
    }

    wolfSSL_CTX_free(ctx);

    res = TEST_RES_CHECK(failFlag == WOLFSSL_SUCCESS);
#endif
    return res;

} /* END test_wolfSSL_CTX_SetMinVersion */


/*----------------------------------------------------------------------------*
 | OCSP Stapling
 *----------------------------------------------------------------------------*/


/* Testing wolfSSL_UseOCSPStapling function. OCSP stapling eliminates the need
 * need to contact the CA, lowering the cost of cert revocation checking.
 * PRE: HAVE_OCSP and HAVE_CERTIFICATE_STATUS_REQUEST
 * POST: 1 returned for success.
 */
static int test_wolfSSL_UseOCSPStapling(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && defined(HAVE_OCSP) && \
        !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX*    ctx = NULL;
    WOLFSSL*        ssl = NULL;

#ifndef NO_WOLFSSL_CLIENT
    #ifndef WOLFSSL_NO_TLS12
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
    #endif
#else
    #ifndef WOLFSSL_NO_TLS12
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
    #endif
#endif
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    ExpectIntEQ(wolfSSL_UseOCSPStapling(NULL, WOLFSSL_CSR2_OCSP,
        WOLFSSL_CSR2_OCSP_USE_NONCE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR2_OCSP,
        WOLFSSL_CSR2_OCSP_USE_NONCE), 1);
#else
    ExpectIntEQ(wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR2_OCSP,
        WOLFSSL_CSR2_OCSP_USE_NONCE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
} /* END test_wolfSSL_UseOCSPStapling */


/* Testing OCSP stapling version 2, wolfSSL_UseOCSPStaplingV2 function. OCSP
 * stapling eliminates the need to contact the CA and lowers cert revocation
 * check.
 * PRE: HAVE_CERTIFICATE_STATUS_REQUEST_V2 and HAVE_OCSP defined.
 */
static int test_wolfSSL_UseOCSPStaplingV2(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && defined(HAVE_OCSP) && \
        !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX*        ctx = NULL;
    WOLFSSL*            ssl = NULL;

#ifndef NO_WOLFSSL_CLIENT
    #ifndef WOLFSSL_NO_TLS12
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
    #endif
#else
    #ifndef WOLFSSL_NO_TLS12
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
    #endif
#endif
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    ExpectIntEQ(wolfSSL_UseOCSPStaplingV2(NULL, WOLFSSL_CSR2_OCSP,
        WOLFSSL_CSR2_OCSP_USE_NONCE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_UseOCSPStaplingV2(ssl, WOLFSSL_CSR2_OCSP,
        WOLFSSL_CSR2_OCSP_USE_NONCE), 1);
#else
    ExpectIntEQ(wolfSSL_UseOCSPStaplingV2(ssl, WOLFSSL_CSR2_OCSP,
        WOLFSSL_CSR2_OCSP_USE_NONCE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();

} /* END test_wolfSSL_UseOCSPStaplingV2 */

/*----------------------------------------------------------------------------*
 | Multicast Tests
 *----------------------------------------------------------------------------*/
static int test_wolfSSL_mcast(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_MULTICAST) && \
    (defined(WOLFSSL_TLS13) || defined(WOLFSSL_SNIFFER))
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL* ssl = NULL;
    byte preMasterSecret[512];
    byte clientRandom[32];
    byte serverRandom[32];
    byte suite[2] = {0, 0xfe};  /* WDM_WITH_NULL_SHA256 */
    byte buf[256];
    word16 newId;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method()));

    ExpectIntEQ(wolfSSL_CTX_mcast_set_member_id(ctx, 0), WOLFSSL_SUCCESS);

    ExpectNotNull(ssl = wolfSSL_new(ctx));

    XMEMSET(preMasterSecret, 0x23, sizeof(preMasterSecret));
    XMEMSET(clientRandom, 0xA5, sizeof(clientRandom));
    XMEMSET(serverRandom, 0x5A, sizeof(serverRandom));
    ExpectIntEQ(wolfSSL_set_secret(ssl, 23, preMasterSecret,
        sizeof(preMasterSecret), clientRandom, serverRandom, suite),
        WOLFSSL_SUCCESS);

    ExpectIntLE(wolfSSL_mcast_read(ssl, &newId, buf, sizeof(buf)), 0);
    ExpectIntLE(newId, 100);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif /* WOLFSSL_DTLS && WOLFSSL_MULTICAST && (WOLFSSL_TLS13 ||
        * WOLFSSL_SNIFFER) */
    return EXPECT_RESULT();
}


/*----------------------------------------------------------------------------*
 |  Wolfcrypt
 *----------------------------------------------------------------------------*/

/*
 * Unit test for the wc_InitBlake2b()
 */
static int test_wc_InitBlake2b(void)
{
    EXPECT_DECLS;
#ifdef HAVE_BLAKE2
    Blake2b blake;

    /* Test good arg. */
    ExpectIntEQ(wc_InitBlake2b(&blake, 64), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitBlake2b(NULL, 64), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitBlake2b(NULL, 128), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitBlake2b(&blake, 128), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitBlake2b(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitBlake2b(&blake, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
}     /* END test_wc_InitBlake2b*/

/*
 * Unit test for the wc_InitBlake2b_WithKey()
 */
static int test_wc_InitBlake2b_WithKey(void)
{
    EXPECT_DECLS;
#ifdef HAVE_BLAKE2
    Blake2b     blake;
    word32      digestSz = BLAKE2B_KEYBYTES;
    byte        key[BLAKE2B_KEYBYTES];
    word32      keylen = BLAKE2B_KEYBYTES;

    XMEMSET(key, 0, sizeof(key));

    /* Test good arg. */
    ExpectIntEQ(wc_InitBlake2b_WithKey(&blake, digestSz, key, keylen), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_InitBlake2b_WithKey(NULL, digestSz, key, keylen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitBlake2b_WithKey(&blake, digestSz, key, 256),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitBlake2b_WithKey(&blake, digestSz, NULL, keylen), 0);
#endif
    return EXPECT_RESULT();
}     /* END wc_InitBlake2b_WithKey*/

/*
 * Unit test for the wc_InitBlake2s_WithKey()
 */
static int test_wc_InitBlake2s_WithKey(void)
{
    EXPECT_DECLS;
#ifdef HAVE_BLAKE2S
    Blake2s     blake;
    word32      digestSz = BLAKE2S_KEYBYTES;
    byte        *key = (byte*)"01234567890123456789012345678901";
    word32      keylen = BLAKE2S_KEYBYTES;

    /* Test good arg. */
    ExpectIntEQ(wc_InitBlake2s_WithKey(&blake, digestSz, key, keylen), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_InitBlake2s_WithKey(NULL, digestSz, key, keylen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitBlake2s_WithKey(&blake, digestSz, key, 256),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitBlake2s_WithKey(&blake, digestSz, NULL, keylen), 0);
#endif
    return EXPECT_RESULT();
}     /* END wc_InitBlake2s_WithKey*/

/*
 * Unit test for the wc_InitMd5()
 */
static int test_wc_InitMd5(void)
{
    EXPECT_DECLS;
#ifndef NO_MD5
    wc_Md5 md5;

    /* Test good arg. */
    ExpectIntEQ(wc_InitMd5(&md5), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitMd5(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Md5Free(&md5);
#endif
    return EXPECT_RESULT();
}     /* END test_wc_InitMd5 */


/*
 * Testing wc_UpdateMd5()
 */
static int test_wc_Md5Update(void)
{
    EXPECT_DECLS;
#ifndef NO_MD5
    wc_Md5 md5;
    byte hash[WC_MD5_DIGEST_SIZE];
    testVector a, b, c;

    ExpectIntEQ(wc_InitMd5(&md5), 0);

    /* Input */
    a.input = "a";
    a.inLen = XSTRLEN(a.input);
    ExpectIntEQ(wc_Md5Update(&md5, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_Md5Final(&md5, hash), 0);

    /* Update input. */
    a.input = "abc";
    a.output = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f"
               "\x72";
    a.inLen = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);
    ExpectIntEQ(wc_Md5Update(&md5, (byte*) a.input, (word32) a.inLen), 0);
    ExpectIntEQ(wc_Md5Final(&md5, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_MD5_DIGEST_SIZE), 0);

    /* Pass in bad values. */
    b.input = NULL;
    b.inLen = 0;
    ExpectIntEQ(wc_Md5Update(&md5, (byte*)b.input, (word32)b.inLen), 0);
    c.input = NULL;
    c.inLen = WC_MD5_DIGEST_SIZE;
    ExpectIntEQ(wc_Md5Update(&md5, (byte*)c.input, (word32)c.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Md5Update(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Md5Free(&md5);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Md5Update()  */


/*
 *  Unit test on wc_Md5Final() in wolfcrypt/src/md5.c
 */
static int test_wc_Md5Final(void)
{
    EXPECT_DECLS;
#ifndef NO_MD5
    /* Instantiate */
    wc_Md5 md5;
    byte* hash_test[3];
    byte hash1[WC_MD5_DIGEST_SIZE];
    byte hash2[2*WC_MD5_DIGEST_SIZE];
    byte hash3[5*WC_MD5_DIGEST_SIZE];
    int times, i;

    /* Initialize */
    ExpectIntEQ(wc_InitMd5(&md5), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test)/sizeof(byte*);
    for (i = 0; i < times; i++) {
        ExpectIntEQ(wc_Md5Final(&md5, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_Md5Final(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Md5Final(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Md5Final(&md5, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Md5Free(&md5);
#endif
    return EXPECT_RESULT();
}

/*
 * Unit test for the wc_InitSha()
 */
static int test_wc_InitSha(void)
{
    EXPECT_DECLS;
#ifndef NO_SHA
    wc_Sha sha;

    /* Test good arg. */
    ExpectIntEQ(wc_InitSha(&sha), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitSha(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_ShaFree(&sha);
#endif
    return EXPECT_RESULT();
} /* END test_wc_InitSha */

/*
 *  Tesing wc_ShaUpdate()
 */
static int test_wc_ShaUpdate(void)
{
    EXPECT_DECLS;
#ifndef NO_SHA
    wc_Sha sha;
    byte hash[WC_SHA_DIGEST_SIZE];
    testVector a, b, c;

    ExpectIntEQ(wc_InitSha(&sha), 0);

    /* Input. */
    a.input = "a";
    a.inLen = XSTRLEN(a.input);

    ExpectIntEQ(wc_ShaUpdate(&sha, NULL, 0), 0);
    ExpectIntEQ(wc_ShaUpdate(&sha, (byte*)a.input, 0), 0);
    ExpectIntEQ(wc_ShaUpdate(&sha, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_ShaFinal(&sha, hash), 0);

    /* Update input. */
    a.input = "abc";
    a.output = "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2"
               "\x6C\x9C\xD0\xD8\x9D";
    a.inLen = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);

    ExpectIntEQ(wc_ShaUpdate(&sha, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_ShaFinal(&sha, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA_DIGEST_SIZE), 0);

    /* Try passing in bad values. */
    b.input = NULL;
    b.inLen = 0;
    ExpectIntEQ(wc_ShaUpdate(&sha, (byte*)b.input, (word32)b.inLen), 0);
    c.input = NULL;
    c.inLen = WC_SHA_DIGEST_SIZE;
    ExpectIntEQ(wc_ShaUpdate(&sha, (byte*)c.input, (word32)c.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ShaUpdate(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_ShaFree(&sha);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ShaUpdate() */


/*
 * Unit test on wc_ShaFinal
 */
static int test_wc_ShaFinal(void)
{
    EXPECT_DECLS;
#ifndef NO_SHA
    wc_Sha sha;
    byte* hash_test[3];
    byte hash1[WC_SHA_DIGEST_SIZE];
    byte hash2[2*WC_SHA_DIGEST_SIZE];
    byte hash3[5*WC_SHA_DIGEST_SIZE];
    int times, i;

    /* Initialize*/
    ExpectIntEQ(wc_InitSha(&sha), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test)/sizeof(byte*);
    for (i = 0; i < times; i++) {
        ExpectIntEQ(wc_ShaFinal(&sha, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_ShaFinal(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ShaFinal(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ShaFinal(&sha, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_ShaFree(&sha);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ShaFinal */


/*
 * Unit test for wc_InitSha256()
 */
static int test_wc_InitSha256(void)
{
    EXPECT_DECLS;
#ifndef NO_SHA256
    wc_Sha256 sha256;

    /* Test good arg. */
    ExpectIntEQ(wc_InitSha256(&sha256), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitSha256(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha256Free(&sha256);
#endif
    return EXPECT_RESULT();
} /* END test_wc_InitSha256 */


/*
 * Unit test for wc_Sha256Update()
 */
static int test_wc_Sha256Update(void)
{
    EXPECT_DECLS;
#ifndef NO_SHA256
    wc_Sha256 sha256;
    byte hash[WC_SHA256_DIGEST_SIZE];
    byte hash_unaligned[WC_SHA256_DIGEST_SIZE+1];
    testVector a, b, c;

    ExpectIntEQ(wc_InitSha256(&sha256), 0);

    /*  Input. */
    a.input = "a";
    a.inLen = XSTRLEN(a.input);
    ExpectIntEQ(wc_Sha256Update(&sha256, NULL, 0), 0);
    ExpectIntEQ(wc_Sha256Update(&sha256, (byte*)a.input, 0), 0);
    ExpectIntEQ(wc_Sha256Update(&sha256, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_Sha256Final(&sha256, hash), 0);

    /* Update input. */
    a.input = "abc";
    a.output = "\xBA\x78\x16\xBF\x8F\x01\xCF\xEA\x41\x41\x40\xDE\x5D\xAE\x22"
               "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00"
               "\x15\xAD";
    a.inLen = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);
    ExpectIntEQ(wc_Sha256Update(&sha256, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_Sha256Final(&sha256, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA256_DIGEST_SIZE), 0);

    /* Unaligned check. */
    ExpectIntEQ(wc_Sha256Update(&sha256, (byte*)a.input+1, (word32)a.inLen-1),
        0);
    ExpectIntEQ(wc_Sha256Final(&sha256, hash_unaligned + 1), 0);

    /* Try passing in bad values */
    b.input = NULL;
    b.inLen = 0;
    ExpectIntEQ(wc_Sha256Update(&sha256, (byte*)b.input, (word32)b.inLen), 0);
    c.input = NULL;
    c.inLen = WC_SHA256_DIGEST_SIZE;
    ExpectIntEQ(wc_Sha256Update(&sha256, (byte*)c.input, (word32)c.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256Update(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha256Free(&sha256);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha256Update */


/*
 * Unit test function for wc_Sha256Final()
 */
static int test_wc_Sha256Final(void)
{
    EXPECT_DECLS;
#ifndef NO_SHA256
    wc_Sha256 sha256;
    byte* hash_test[3];
    byte hash1[WC_SHA256_DIGEST_SIZE];
    byte hash2[2*WC_SHA256_DIGEST_SIZE];
    byte hash3[5*WC_SHA256_DIGEST_SIZE];
    int times, i;

    /* Initialize */
    ExpectIntEQ(wc_InitSha256(&sha256), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test) / sizeof(byte*);
    for (i = 0; i < times; i++) {
        ExpectIntEQ(wc_Sha256Final(&sha256, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_Sha256Final(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256Final(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256Final(&sha256, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha256Free(&sha256);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha256Final */
/*
 * Unit test function for wc_Sha256FinalRaw()
 */
static int test_wc_Sha256FinalRaw(void)
{
    EXPECT_DECLS;
#if !defined(NO_SHA256) && !defined(HAVE_SELFTEST) && !defined(WOLFSSL_DEVCRYPTO) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 3))) && \
    !defined(WOLFSSL_NO_HASH_RAW)
    wc_Sha256 sha256;
    byte* hash_test[3];
    byte hash1[WC_SHA256_DIGEST_SIZE];
    byte hash2[2*WC_SHA256_DIGEST_SIZE];
    byte hash3[5*WC_SHA256_DIGEST_SIZE];
    int times, i;

    /* Initialize */
    ExpectIntEQ(wc_InitSha256(&sha256), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test) / sizeof(byte*);
    for (i = 0; i < times; i++) {
        ExpectIntEQ(wc_Sha256FinalRaw(&sha256, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_Sha256FinalRaw(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256FinalRaw(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256FinalRaw(&sha256, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha256Free(&sha256);
#endif
    return EXPECT_RESULT();

} /* END test_wc_Sha256FinalRaw */
/*
 * Unit test function for wc_Sha256GetFlags()
 */
static int test_wc_Sha256GetFlags(void)
{
    EXPECT_DECLS;
#if !defined(NO_SHA256) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sha256 sha256;
    word32 flags = 0;

    /* Initialize */
    ExpectIntEQ(wc_InitSha256(&sha256), 0);

    ExpectIntEQ(wc_Sha256GetFlags(&sha256, &flags), 0);
    ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == 0);

    wc_Sha256Free(&sha256);
#endif
    return EXPECT_RESULT();

} /* END test_wc_Sha256GetFlags */
/*
 * Unit test function for wc_Sha256Free()
 */
static int test_wc_Sha256Free(void)
{
    EXPECT_DECLS;
#ifndef NO_SHA256
    wc_Sha256Free(NULL);
    /* Set result to SUCCESS. */
    ExpectTrue(1);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha256Free */
/*
 * Unit test function for wc_Sha256GetHash()
 */
static int test_wc_Sha256GetHash(void)
{
    EXPECT_DECLS;
#ifndef NO_SHA256
    wc_Sha256 sha256;
    byte hash1[WC_SHA256_DIGEST_SIZE];

    /* Initialize */
    ExpectIntEQ(wc_InitSha256(&sha256), 0);

    ExpectIntEQ(wc_Sha256GetHash(&sha256, hash1), 0);

    /* test bad arguments*/
    ExpectIntEQ(wc_Sha256GetHash(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256GetHash(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256GetHash(&sha256, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha256Free(&sha256);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha256GetHash */
/*
 * Unit test function for wc_Sha256Copy()
 */
static int test_wc_Sha256Copy(void)
{
    EXPECT_DECLS;
#ifndef NO_SHA256
    wc_Sha256 sha256;
    wc_Sha256 temp;

    XMEMSET(&sha256, 0, sizeof(sha256));
    XMEMSET(&temp, 0, sizeof(temp));

    /* Initialize */
    ExpectIntEQ(wc_InitSha256(&sha256), 0);
    ExpectIntEQ(wc_InitSha256(&temp), 0);

    ExpectIntEQ(wc_Sha256Copy(&sha256, &temp), 0);

    /* test bad arguments*/
    ExpectIntEQ(wc_Sha256Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256Copy(NULL, &temp), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256Copy(&sha256, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha256Free(&sha256);
    wc_Sha256Free(&temp);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha256Copy */
/*
 * Testing wc_InitSha512()
 */
static int test_wc_InitSha512(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA512
    wc_Sha512 sha512;

    /* Test good arg. */
    ExpectIntEQ(wc_InitSha512(&sha512), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitSha512(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512Free(&sha512);
#endif
    return EXPECT_RESULT();
} /* END test_wc_InitSha512 */


/*
 *  wc_Sha512Update() test.
 */
static int test_wc_Sha512Update(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA512
    wc_Sha512 sha512;
    byte hash[WC_SHA512_DIGEST_SIZE];
    byte hash_unaligned[WC_SHA512_DIGEST_SIZE + 1];
    testVector a, b, c;

    ExpectIntEQ(wc_InitSha512(&sha512), 0);

    /* Input. */
    a.input = "a";
    a.inLen = XSTRLEN(a.input);
    ExpectIntEQ(wc_Sha512Update(&sha512, NULL, 0), 0);
    ExpectIntEQ(wc_Sha512Update(&sha512,(byte*)a.input, 0), 0);
    ExpectIntEQ(wc_Sha512Update(&sha512, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_Sha512Final(&sha512, hash), 0);

    /* Update input. */
    a.input = "abc";
    a.output = "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41"
               "\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b"
               "\x55\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c"
               "\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a"
               "\x9a\xc9\x4f\xa5\x4c\xa4\x9f";
    a.inLen = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);
    ExpectIntEQ(wc_Sha512Update(&sha512, (byte*) a.input, (word32) a.inLen), 0);
    ExpectIntEQ(wc_Sha512Final(&sha512, hash), 0);

    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA512_DIGEST_SIZE), 0);

    /* Unaligned check. */
    ExpectIntEQ(wc_Sha512Update(&sha512, (byte*)a.input+1, (word32)a.inLen-1),
        0);
    ExpectIntEQ(wc_Sha512Final(&sha512, hash_unaligned+1), 0);

    /* Try passing in bad values */
    b.input = NULL;
    b.inLen = 0;
    ExpectIntEQ(wc_Sha512Update(&sha512, (byte*)b.input, (word32)b.inLen), 0);
    c.input = NULL;
    c.inLen = WC_SHA512_DIGEST_SIZE;
    ExpectIntEQ(wc_Sha512Update(&sha512, (byte*)c.input, (word32)c.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512Update(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512Free(&sha512);
#endif
    return EXPECT_RESULT();

} /* END test_wc_Sha512Update  */

#ifdef WOLFSSL_SHA512
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
        (!defined(WOLFSSL_NOSHA512_224) || !defined(WOLFSSL_NOSHA512_256))
/* Performs test for
 * - wc_Sha512Final/wc_Sha512FinalRaw
 * - wc_Sha512_224Final/wc_Sha512_224Final
 * - wc_Sha512_256Final/wc_Sha512_256Final
 * parameter:
 * - type : must be one of WC_HASH_TYPE_SHA512, WC_HASH_TYPE_SHA512_224 or
 *          WC_HASH_TYPE_SHA512_256
 * - isRaw: if is non-zero, xxxFinalRaw function will be tested
 *return 0 on success
 */
static int test_Sha512_Family_Final(int type, int isRaw)
{
    EXPECT_DECLS;
    wc_Sha512 sha512;
    byte* hash_test[3];
    byte hash1[WC_SHA512_DIGEST_SIZE];
    byte hash2[2*WC_SHA512_DIGEST_SIZE];
    byte hash3[5*WC_SHA512_DIGEST_SIZE];
    int times, i;

    int(*initFp)(wc_Sha512*);
    int(*finalFp)(wc_Sha512*, byte*);
    void(*freeFp)(wc_Sha512*);

    if (type == WC_HASH_TYPE_SHA512) {
        initFp  = wc_InitSha512;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
    !defined(WOLFSSL_NO_HASH_RAW)
        finalFp = (isRaw)? wc_Sha512FinalRaw : wc_Sha512Final;
#else
        finalFp = (isRaw)? NULL : wc_Sha512Final;
#endif
        freeFp  = wc_Sha512Free;
    }
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if !defined(WOLFSSL_NOSHA512_224)
    else if (type == WC_HASH_TYPE_SHA512_224) {
        initFp  = wc_InitSha512_224;
    #if !defined(WOLFSSL_NO_HASH_RAW)
        finalFp = (isRaw)? wc_Sha512_224FinalRaw : wc_Sha512_224Final;
    #else
        finalFp = (isRaw)? NULL : wc_Sha512_224Final;
    #endif
        freeFp  = wc_Sha512_224Free;
    }
#endif
#if !defined(WOLFSSL_NOSHA512_256)
    else if (type == WC_HASH_TYPE_SHA512_256) {
        initFp  = wc_InitSha512_256;
    #if !defined(WOLFSSL_NO_HASH_RAW)
        finalFp = (isRaw)? wc_Sha512_256FinalRaw : wc_Sha512_256Final;
    #else
        finalFp = (isRaw)? NULL : wc_Sha512_256Final;
    #endif
        freeFp  = wc_Sha512_256Free;
    }
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    else
        return TEST_FAIL;

    /* Initialize  */
    ExpectIntEQ(initFp(&sha512), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test) / sizeof(byte *);

#if defined(HAVE_FIPS) || defined(HAVE_SELFTEST) || \
        defined(WOLFSSL_NO_HASH_RAW)
    if (finalFp != NULL)
#endif
    {
        /* Good test args. */
        for (i = 0; i < times; i++) {
            ExpectIntEQ(finalFp(&sha512, hash_test[i]), 0);
        }
        /* Test bad args. */
        ExpectIntEQ(finalFp(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(finalFp(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(finalFp(&sha512, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    }

    freeFp(&sha512);

    return EXPECT_RESULT();
}
#endif /* !HAVE_FIPS && !HAVE_SELFTEST &&
                        (!WOLFSSL_NOSHA512_224 || !WOLFSSL_NOSHA512_256) */
#endif /* WOLFSSL_SHA512 */
/*
 * Unit test function for wc_Sha512Final()
 */
static int test_wc_Sha512Final(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA512
    wc_Sha512 sha512;
    byte* hash_test[3];
    byte hash1[WC_SHA512_DIGEST_SIZE];
    byte hash2[2*WC_SHA512_DIGEST_SIZE];
    byte hash3[5*WC_SHA512_DIGEST_SIZE];
    int times, i;

    /* Initialize  */
    ExpectIntEQ(wc_InitSha512(&sha512), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test) / sizeof(byte *);
    for (i = 0; i < times; i++) {
         ExpectIntEQ(wc_Sha512Final(&sha512, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_Sha512Final(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512Final(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512Final(&sha512, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512Free(&sha512);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha512Final */
/*
 * Unit test function for wc_Sha512GetFlags()
 */
static int test_wc_Sha512GetFlags(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA512) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sha512 sha512;
    word32 flags = 0;

    /* Initialize */
    ExpectIntEQ(wc_InitSha512(&sha512), 0);

    ExpectIntEQ(wc_Sha512GetFlags(&sha512, &flags), 0);
    ExpectIntEQ((flags & WC_HASH_FLAG_ISCOPY), 0);

    wc_Sha512Free(&sha512);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha512GetFlags */
/*
 * Unit test function for wc_Sha512FinalRaw()
 */
static int test_wc_Sha512FinalRaw(void)
{
    EXPECT_DECLS;
#if (defined(WOLFSSL_SHA512) && !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 3)))) && \
    !defined(WOLFSSL_NO_HASH_RAW)
    wc_Sha512 sha512;
    byte* hash_test[3];
    byte hash1[WC_SHA512_DIGEST_SIZE];
    byte hash2[2*WC_SHA512_DIGEST_SIZE];
    byte hash3[5*WC_SHA512_DIGEST_SIZE];
    int times, i;

    /* Initialize */
    ExpectIntEQ(wc_InitSha512(&sha512), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test) / sizeof(byte*);
    /* Good test args. */
    for (i = 0; i < times; i++) {
         ExpectIntEQ(wc_Sha512FinalRaw(&sha512, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_Sha512FinalRaw(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512FinalRaw(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512FinalRaw(&sha512, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512Free(&sha512);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha512FinalRaw */

/*
 * Unit test function for wc_Sha512Free()
 */
static int test_wc_Sha512Free(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA512
    wc_Sha512Free(NULL);
    /* Set result to SUCCESS. */
    ExpectTrue(1);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha512Free */
#ifdef WOLFSSL_SHA512

#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
        (!defined(WOLFSSL_NOSHA512_224) || !defined(WOLFSSL_NOSHA512_256))
static int test_Sha512_Family_GetHash(int type )
{
    EXPECT_DECLS;
    int(*initFp)(wc_Sha512*);
    int(*ghashFp)(wc_Sha512*, byte*);
    wc_Sha512 sha512;
    byte hash1[WC_SHA512_DIGEST_SIZE];

    if (type == WC_HASH_TYPE_SHA512) {
        initFp  = wc_InitSha512;
        ghashFp = wc_Sha512GetHash;
    }
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if !defined(WOLFSSL_NOSHA512_224)
    else if (type == WC_HASH_TYPE_SHA512_224) {
        initFp  = wc_InitSha512_224;
        ghashFp = wc_Sha512_224GetHash;
    }
#endif
#if !defined(WOLFSSL_NOSHA512_256)
    else if (type == WC_HASH_TYPE_SHA512_256) {
        initFp  = wc_InitSha512_256;
        ghashFp = wc_Sha512_256GetHash;
    }
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    else {
        initFp  = NULL;
        ghashFp = NULL;
    }

    if (initFp == NULL || ghashFp == NULL)
        return TEST_FAIL;

    ExpectIntEQ(initFp(&sha512), 0);
    ExpectIntEQ(ghashFp(&sha512, hash1), 0);

    /* test bad arguments*/
    ExpectIntEQ(ghashFp(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(ghashFp(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(ghashFp(&sha512, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512Free(&sha512);
    return EXPECT_RESULT();
}
#endif /* !HAVE_FIPS && !HAVE_SELFTEST &&
                        (!WOLFSSL_NOSHA512_224 || !WOLFSSL_NOSHA512_256) */
#endif /* WOLFSSL_SHA512 */
/*
 * Unit test function for wc_Sha512GetHash()
 */
static int test_wc_Sha512GetHash(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA512
    wc_Sha512 sha512;
    byte hash1[WC_SHA512_DIGEST_SIZE];

    /* Initialize */
    ExpectIntEQ(wc_InitSha512(&sha512), 0);

    ExpectIntEQ(wc_Sha512GetHash(&sha512, hash1), 0);

    /* test bad arguments*/
    ExpectIntEQ(wc_Sha512GetHash(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512GetHash(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512GetHash(&sha512, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512Free(&sha512);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha512GetHash */

/*
 * Unit test function for wc_Sha512Copy()
 */
static int test_wc_Sha512Copy(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA512
    wc_Sha512 sha512;
    wc_Sha512 temp;

    XMEMSET(&sha512, 0, sizeof(wc_Sha512));
    XMEMSET(&temp, 0, sizeof(wc_Sha512));

    /* Initialize */
    ExpectIntEQ(wc_InitSha512(&sha512), 0);
    ExpectIntEQ(wc_InitSha512(&temp), 0);

    ExpectIntEQ(wc_Sha512Copy(&sha512, &temp), 0);

    /* test bad arguments*/
    ExpectIntEQ(wc_Sha512Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512Copy(NULL, &temp), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512Copy(&sha512, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512Free(&sha512);
    wc_Sha512Free(&temp);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha512Copy */

static int test_wc_InitSha512_224(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224)
    wc_Sha512 sha512;

    /* Test good arg. */
    ExpectIntEQ(wc_InitSha512_224(&sha512), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitSha512_224(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512_224Free(&sha512);
#endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_224 */
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_224Update(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224)
    wc_Sha512 sha512;
    byte hash[WC_SHA512_DIGEST_SIZE];
    testVector a, c;

    ExpectIntEQ(wc_InitSha512_224(&sha512), 0);

    /* Input. */
    a.input = "a";
    a.inLen = XSTRLEN(a.input);
    ExpectIntEQ(wc_Sha512_224Update(&sha512, NULL, 0), 0);
    ExpectIntEQ(wc_Sha512_224Update(&sha512,(byte*)a.input, 0), 0);
    ExpectIntEQ(wc_Sha512_224Update(&sha512, (byte*)a.input, (word32)a.inLen),
        0);
    ExpectIntEQ(wc_Sha512_224Final(&sha512, hash), 0);

    /* Update input. */
    a.input = "abc";
    a.output = "\x46\x34\x27\x0f\x70\x7b\x6a\x54\xda\xae\x75\x30\x46\x08"
               "\x42\xe2\x0e\x37\xed\x26\x5c\xee\xe9\xa4\x3e\x89\x24\xaa";
    a.inLen = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);
    ExpectIntEQ(wc_Sha512_224Update(&sha512, (byte*) a.input, (word32) a.inLen),
        0);
    ExpectIntEQ(wc_Sha512_224Final(&sha512, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA512_224_DIGEST_SIZE), 0);

    c.input = NULL;
    c.inLen = WC_SHA512_224_DIGEST_SIZE;
    ExpectIntEQ(wc_Sha512_224Update(&sha512, (byte*)c.input, (word32)c.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_224Update(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512_224Free(&sha512);
#endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_224 */
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_224Final(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224)
    ExpectIntEQ(test_Sha512_Family_Final(WC_HASH_TYPE_SHA512_224, 0),
        TEST_SUCCESS);
#endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_224 */
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_224GetFlags(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sha512 sha512;
    wc_Sha512 copy;
    word32 flags = 0;

    XMEMSET(&sha512, 0, sizeof(wc_Sha512));
    XMEMSET(&copy, 0, sizeof(wc_Sha512));

    /* Initialize */
    ExpectIntEQ(wc_InitSha512_224(&sha512), 0);
    ExpectIntEQ(wc_InitSha512_224(&copy), 0);

    ExpectIntEQ(wc_Sha512_224GetFlags(&sha512, &flags), 0);
    ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == 0);

    ExpectIntEQ(wc_Sha512_224Copy(&sha512, &copy), 0);
    ExpectIntEQ(wc_Sha512_224GetFlags(&copy, &flags), 0);
    ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == WC_HASH_FLAG_ISCOPY);

    wc_Sha512_224Free(&copy);
    wc_Sha512_224Free(&sha512);
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_224FinalRaw(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
    defined(WOLFSSL_SHA512) &&  !defined(WOLFSSL_NOSHA512_224) && \
    !defined(WOLFSSL_NO_HASH_RAW)
    ExpectIntEQ(test_Sha512_Family_Final(WC_HASH_TYPE_SHA512_224, 1),
        TEST_SUCCESS);
#endif
    return EXPECT_RESULT();
}

static int test_wc_Sha512_224Free(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224)
    wc_Sha512_224Free(NULL);
    /* Set result to SUCCESS. */
    ExpectTrue(1);
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_224GetHash(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224)
    ExpectIntEQ(test_Sha512_Family_GetHash(WC_HASH_TYPE_SHA512_224),
        TEST_SUCCESS);
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}
static int test_wc_Sha512_224Copy(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224)
    wc_Sha512 sha512;
    wc_Sha512 temp;

    XMEMSET(&sha512, 0, sizeof(wc_Sha512));
    XMEMSET(&temp, 0, sizeof(wc_Sha512));

    /* Initialize */
    ExpectIntEQ(wc_InitSha512_224(&sha512), 0);
    ExpectIntEQ(wc_InitSha512_224(&temp), 0);

    ExpectIntEQ(wc_Sha512_224Copy(&sha512, &temp), 0);
    /* test bad arguments*/
    ExpectIntEQ(wc_Sha512_224Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_224Copy(NULL, &temp), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_224Copy(&sha512, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512_224Free(&sha512);
    wc_Sha512_224Free(&temp);
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_InitSha512_256(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256)
    wc_Sha512 sha512;

    /* Test good arg. */
    ExpectIntEQ(wc_InitSha512_256(&sha512), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitSha512_256(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512_256Free(&sha512);
#endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_256 */
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_256Update(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256)
    wc_Sha512 sha512;
    byte hash[WC_SHA512_DIGEST_SIZE];
    testVector a, c;

    ExpectIntEQ(wc_InitSha512_256(&sha512), 0);

    /* Input. */
    a.input = "a";
    a.inLen = XSTRLEN(a.input);
    ExpectIntEQ(wc_Sha512_256Update(&sha512, NULL, 0), 0);
    ExpectIntEQ(wc_Sha512_256Update(&sha512,(byte*)a.input, 0), 0);
    ExpectIntEQ(wc_Sha512_256Update(&sha512, (byte*)a.input, (word32)a.inLen),
        0);
    ExpectIntEQ(wc_Sha512_256Final(&sha512, hash), 0);

    /* Update input. */
    a.input = "abc";
    a.output = "\x53\x04\x8e\x26\x81\x94\x1e\xf9\x9b\x2e\x29\xb7\x6b\x4c"
               "\x7d\xab\xe4\xc2\xd0\xc6\x34\xfc\x6d\x46\xe0\xe2\xf1\x31"
               "\x07\xe7\xaf\x23";
    a.inLen = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);
    ExpectIntEQ(wc_Sha512_256Update(&sha512, (byte*) a.input, (word32) a.inLen),
        0);
    ExpectIntEQ(wc_Sha512_256Final(&sha512, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA512_256_DIGEST_SIZE), 0);

    c.input = NULL;
    c.inLen = WC_SHA512_256_DIGEST_SIZE;
    ExpectIntEQ(wc_Sha512_256Update(&sha512, (byte*)c.input, (word32)c.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_256Update(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512_256Free(&sha512);
#endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_256 */
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_256Final(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256)
    ExpectIntEQ(test_Sha512_Family_Final(WC_HASH_TYPE_SHA512_256, 0),
        TEST_SUCCESS);
#endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_256 */
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_256GetFlags(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sha512 sha512, copy;
    word32 flags = 0;

    XMEMSET(&sha512, 0, sizeof(wc_Sha512));
    XMEMSET(&copy, 0, sizeof(wc_Sha512));

    /* Initialize */
    ExpectIntEQ(wc_InitSha512_256(&sha512), 0);
    ExpectIntEQ(wc_InitSha512_256(&copy), 0);

    ExpectIntEQ(wc_Sha512_256GetFlags(&sha512, &flags), 0);
    ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == 0);

    ExpectIntEQ(wc_Sha512_256Copy(&sha512, &copy), 0);
    ExpectIntEQ(wc_Sha512_256GetFlags(&copy, &flags), 0);
    ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == WC_HASH_FLAG_ISCOPY);

    wc_Sha512_256Free(&sha512);
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_256FinalRaw(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
    defined(WOLFSSL_SHA512) &&  !defined(WOLFSSL_NOSHA512_256) && \
    !defined(WOLFSSL_NO_HASH_RAW)
    ExpectIntEQ(test_Sha512_Family_Final(WC_HASH_TYPE_SHA512_256, 1),
        TEST_SUCCESS);
#endif
    return EXPECT_RESULT();
}

static int test_wc_Sha512_256Free(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256)
    wc_Sha512_256Free(NULL);
    /* Set result to SUCCESS. */
    ExpectTrue(1);
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wc_Sha512_256GetHash(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256)
    ExpectIntEQ(test_Sha512_Family_GetHash(WC_HASH_TYPE_SHA512_256),
        TEST_SUCCESS);
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();

}
static int test_wc_Sha512_256Copy(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256)
    wc_Sha512 sha512;
    wc_Sha512 temp;

    XMEMSET(&sha512, 0, sizeof(wc_Sha512));
    XMEMSET(&temp, 0, sizeof(wc_Sha512));

    /* Initialize */
    ExpectIntEQ(wc_InitSha512_256(&sha512), 0);
    ExpectIntEQ(wc_InitSha512_256(&temp), 0);

    ExpectIntEQ(wc_Sha512_256Copy(&sha512, &temp), 0);
    /* test bad arguments*/
    ExpectIntEQ(wc_Sha512_256Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_256Copy(NULL, &temp), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_256Copy(&sha512, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha512_256Free(&sha512);
    wc_Sha512_256Free(&temp);
#endif
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}



/*
 * Testing wc_InitSha384()
 */
static int test_wc_InitSha384(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA384
    wc_Sha384 sha384;

    /* Test good arg. */
    ExpectIntEQ(wc_InitSha384(&sha384), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitSha384(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha384Free(&sha384);
#endif
    return EXPECT_RESULT();
} /* END test_wc_InitSha384 */


/*
 * test wc_Sha384Update()
 */
static int test_wc_Sha384Update(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA384
    wc_Sha384 sha384;
    byte hash[WC_SHA384_DIGEST_SIZE];
    testVector a, b, c;

    ExpectIntEQ(wc_InitSha384(&sha384), 0);

    /* Input */
    a.input = "a";
    a.inLen = XSTRLEN(a.input);
    ExpectIntEQ(wc_Sha384Update(&sha384, NULL, 0), 0);
    ExpectIntEQ(wc_Sha384Update(&sha384, (byte*)a.input, 0), 0);
    ExpectIntEQ(wc_Sha384Update(&sha384, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_Sha384Final(&sha384, hash), 0);

    /* Update input. */
    a.input = "abc";
    a.output = "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50"
               "\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff"
               "\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34"
               "\xc8\x25\xa7";
    a.inLen = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);
    ExpectIntEQ(wc_Sha384Update(&sha384, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_Sha384Final(&sha384, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA384_DIGEST_SIZE), 0);

    /* Pass in bad values. */
    b.input = NULL;
    b.inLen = 0;
    ExpectIntEQ(wc_Sha384Update(&sha384, (byte*)b.input, (word32)b.inLen), 0);
    c.input = NULL;
    c.inLen = WC_SHA384_DIGEST_SIZE;
    ExpectIntEQ( wc_Sha384Update(&sha384, (byte*)c.input, (word32)c.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha384Update(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha384Free(&sha384);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha384Update */

/*
 * Unit test function for wc_Sha384Final();
 */
static int test_wc_Sha384Final(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA384
    wc_Sha384 sha384;
    byte* hash_test[3];
    byte hash1[WC_SHA384_DIGEST_SIZE];
    byte hash2[2*WC_SHA384_DIGEST_SIZE];
    byte hash3[5*WC_SHA384_DIGEST_SIZE];
    int times, i;

    /* Initialize */
    ExpectIntEQ(wc_InitSha384(&sha384), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test) / sizeof(byte*);
    /* Good test args. */
    for (i = 0; i < times; i++) {
         ExpectIntEQ(wc_Sha384Final(&sha384, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_Sha384Final(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha384Final(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha384Final(&sha384, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha384Free(&sha384);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha384Final */
/*
 * Unit test function for wc_Sha384GetFlags()
 */
static int test_wc_Sha384GetFlags(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA384) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sha384 sha384;
    word32 flags = 0;

    /* Initialize */
    ExpectIntEQ(wc_InitSha384(&sha384), 0);
    ExpectIntEQ(wc_Sha384GetFlags(&sha384, &flags), 0);
    ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == 0);

    wc_Sha384Free(&sha384);
#endif
    return EXPECT_RESULT();

} /* END test_wc_Sha384GetFlags */
/*
 * Unit test function for wc_Sha384FinalRaw()
 */
static int test_wc_Sha384FinalRaw(void)
{
    EXPECT_DECLS;
#if (defined(WOLFSSL_SHA384) && !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 3)))) && \
    !defined(WOLFSSL_NO_HASH_RAW)
    wc_Sha384 sha384;
    byte* hash_test[3];
    byte hash1[WC_SHA384_DIGEST_SIZE];
    byte hash2[2*WC_SHA384_DIGEST_SIZE];
    byte hash3[5*WC_SHA384_DIGEST_SIZE];
    int times, i;

    /* Initialize */
    ExpectIntEQ(wc_InitSha384(&sha384), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test) / sizeof(byte*);
    /* Good test args. */
    for (i = 0; i < times; i++) {
         ExpectIntEQ(wc_Sha384FinalRaw(&sha384, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_Sha384FinalRaw(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha384FinalRaw(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha384FinalRaw(&sha384, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha384Free(&sha384);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha384FinalRaw */
/*
 * Unit test function for wc_Sha384Free()
 */
static int test_wc_Sha384Free(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA384
    wc_Sha384Free(NULL);
    /* Set result to SUCCESS. */
    ExpectTrue(1);
#endif
    return EXPECT_RESULT();

} /* END test_wc_Sha384Free */
/*
 * Unit test function for wc_Sha384GetHash()
 */
static int test_wc_Sha384GetHash(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA384
    wc_Sha384 sha384;
    byte hash1[WC_SHA384_DIGEST_SIZE];

    /* Initialize */
    ExpectIntEQ(wc_InitSha384(&sha384), 0);

    ExpectIntEQ(wc_Sha384GetHash(&sha384, hash1), 0);
    /* test bad arguments*/
    ExpectIntEQ(wc_Sha384GetHash(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha384GetHash(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha384GetHash(&sha384, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha384Free(&sha384);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha384GetHash */
/*
 * Unit test function for wc_Sha384Copy()
 */
static int test_wc_Sha384Copy(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA384
    wc_Sha384 sha384;
    wc_Sha384 temp;

    XMEMSET(&sha384, 0, sizeof(wc_Sha384));
    XMEMSET(&temp, 0, sizeof(wc_Sha384));

    /* Initialize */
    ExpectIntEQ(wc_InitSha384(&sha384), 0);
    ExpectIntEQ(wc_InitSha384(&temp), 0);

    ExpectIntEQ(wc_Sha384Copy(&sha384, &temp), 0);
    /* test bad arguments*/
    ExpectIntEQ(wc_Sha384Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha384Copy(NULL, &temp), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha384Copy(&sha384, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha384Free(&sha384);
    wc_Sha384Free(&temp);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha384Copy */

/*
 * Testing wc_InitSha224();
 */
static int test_wc_InitSha224(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA224
    wc_Sha224 sha224;

    /* Test good arg. */
    ExpectIntEQ(wc_InitSha224(&sha224), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitSha224(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha224Free(&sha224);
#endif
    return EXPECT_RESULT();
} /* END test_wc_InitSha224 */

/*
 * Unit test on wc_Sha224Update
 */
static int test_wc_Sha224Update(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA224
    wc_Sha224 sha224;
    byte hash[WC_SHA224_DIGEST_SIZE];
    testVector a, b, c;

    ExpectIntEQ(wc_InitSha224(&sha224), 0);

    /* Input. */
    a.input = "a";
    a.inLen = XSTRLEN(a.input);
    ExpectIntEQ(wc_Sha224Update(&sha224, NULL, 0), 0);
    ExpectIntEQ(wc_Sha224Update(&sha224, (byte*)a.input, 0), 0);
    ExpectIntEQ(wc_Sha224Update(&sha224, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_Sha224Final(&sha224, hash), 0);

    /* Update input. */
    a.input = "abc";
    a.output = "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2"
               "\x55\xb3\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7";
    a.inLen = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);
    ExpectIntEQ(wc_Sha224Update(&sha224, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_Sha224Final(&sha224, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA224_DIGEST_SIZE), 0);

    /* Pass in bad values. */
    b.input = NULL;
    b.inLen = 0;
    ExpectIntEQ(wc_Sha224Update(&sha224, (byte*)b.input, (word32)b.inLen), 0);
    c.input = NULL;
    c.inLen = WC_SHA224_DIGEST_SIZE;
    ExpectIntEQ(wc_Sha224Update(&sha224, (byte*)c.input, (word32)c.inLen),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha224Update(NULL, (byte*)a.input, (word32)a.inLen),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha224Free(&sha224);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha224Update */

/*
 * Unit test for wc_Sha224Final();
 */
static int test_wc_Sha224Final(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA224
    wc_Sha224 sha224;
    byte* hash_test[3];
    byte hash1[WC_SHA224_DIGEST_SIZE];
    byte hash2[2*WC_SHA224_DIGEST_SIZE];
    byte hash3[5*WC_SHA224_DIGEST_SIZE];
    int times, i;

    /* Initialize */
    ExpectIntEQ(wc_InitSha224(&sha224), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test) / sizeof(byte*);
    /* Good test args. */
    /* Testing oversized buffers. */
    for (i = 0; i < times; i++) {
        ExpectIntEQ(wc_Sha224Final(&sha224, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_Sha224Final(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha224Final(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha224Final(&sha224, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha224Free(&sha224);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha224Final */

/*
 * Unit test function for wc_Sha224SetFlags()
 */
static int test_wc_Sha224SetFlags(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA224) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sha224 sha224;
    word32 flags = WC_HASH_FLAG_WILLCOPY;

    /* Initialize */
    ExpectIntEQ(wc_InitSha224(&sha224), 0);

    ExpectIntEQ(wc_Sha224SetFlags(&sha224, flags), 0);
    flags = 0;
    ExpectIntEQ(wc_Sha224GetFlags(&sha224, &flags), 0);
    ExpectTrue(flags == WC_HASH_FLAG_WILLCOPY);

    wc_Sha224Free(&sha224);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha224SetFlags */

/*
 * Unit test function for wc_Sha224GetFlags()
 */
static int test_wc_Sha224GetFlags(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA224) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sha224 sha224;
    word32 flags = 0;

    /* Initialize */
    ExpectIntEQ(wc_InitSha224(&sha224), 0);

    ExpectIntEQ(wc_Sha224GetFlags(&sha224, &flags), 0);
    ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == 0);

    wc_Sha224Free(&sha224);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha224GetFlags */
/*
 * Unit test function for wc_Sha224Free()
 */
static int test_wc_Sha224Free(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA224
    wc_Sha224Free(NULL);
    /* Set result to SUCCESS. */
    ExpectTrue(1);
#endif
    return EXPECT_RESULT();

} /* END test_wc_Sha224Free */

/*
 * Unit test function for wc_Sha224GetHash()
 */
static int test_wc_Sha224GetHash(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA224
    wc_Sha224 sha224;
    byte hash1[WC_SHA224_DIGEST_SIZE];

    /* Initialize */
    ExpectIntEQ(wc_InitSha224(&sha224), 0);

    ExpectIntEQ(wc_Sha224GetHash(&sha224, hash1), 0);
    /* test bad arguments*/
    ExpectIntEQ(wc_Sha224GetHash(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha224GetHash(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha224GetHash(&sha224, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha224Free(&sha224);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha224GetHash */

/*
 * Unit test function for wc_Sha224Copy()
 */
static int test_wc_Sha224Copy(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA224
    wc_Sha224 sha224;
    wc_Sha224 temp;

    XMEMSET(&sha224, 0, sizeof(wc_Sha224));
    XMEMSET(&temp, 0, sizeof(wc_Sha224));

    /* Initialize */
    ExpectIntEQ(wc_InitSha224(&sha224), 0);
    ExpectIntEQ(wc_InitSha224(&temp), 0);

    ExpectIntEQ(wc_Sha224Copy(&sha224, &temp), 0);
    /* test bad arguments*/
    ExpectIntEQ(wc_Sha224Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha224Copy(NULL, &temp), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha224Copy(&sha224, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha224Free(&sha224);
    wc_Sha224Free(&temp);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha224Copy */


/*
 * Testing wc_InitRipeMd()
 */
static int test_wc_InitRipeMd(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_RIPEMD
    RipeMd ripemd;

    /* Test good arg. */
    ExpectIntEQ(wc_InitRipeMd(&ripemd), 0);
    /* Test bad arg. */
    ExpectIntEQ(wc_InitRipeMd(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();

} /* END test_wc_InitRipeMd */

/*
 * Testing wc_RipeMdUpdate()
 */
static int test_wc_RipeMdUpdate(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_RIPEMD
    RipeMd ripemd;
    byte hash[RIPEMD_DIGEST_SIZE];
    testVector a, b, c;

    ExpectIntEQ(wc_InitRipeMd(&ripemd), 0);

    /* Input */
    a.input = "a";
    a.inLen = XSTRLEN(a.input);
    ExpectIntEQ(wc_RipeMdUpdate(&ripemd, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_RipeMdFinal(&ripemd, hash), 0);

    /* Update input. */
    a.input = "abc";
    a.output = "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04\x4a\x8e\x98\xc6"
               "\xb0\x87\xf1\x5a\x0b\xfc";
    a.inLen = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);
    ExpectIntEQ(wc_RipeMdUpdate(&ripemd, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_RipeMdFinal(&ripemd, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, RIPEMD_DIGEST_SIZE), 0);

    /* Pass in bad values. */
    b.input = NULL;
    b.inLen = 0;
    ExpectIntEQ(wc_RipeMdUpdate(&ripemd, (byte*)b.input, (word32)b.inLen), 0);
    c.input = NULL;
    c.inLen = RIPEMD_DIGEST_SIZE;
    ExpectIntEQ(wc_RipeMdUpdate(&ripemd, (byte*)c.input, (word32)c.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RipeMdUpdate(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_RipeMdUdpate */

/*
 * Unit test function for wc_RipeMdFinal()
 */
static int test_wc_RipeMdFinal(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_RIPEMD
    RipeMd ripemd;
    byte* hash_test[3];
    byte hash1[RIPEMD_DIGEST_SIZE];
    byte hash2[2*RIPEMD_DIGEST_SIZE];
    byte hash3[5*RIPEMD_DIGEST_SIZE];
    int times, i;

    /* Initialize */
    ExpectIntEQ(wc_InitRipeMd(&ripemd), 0);

    hash_test[0] = hash1;
    hash_test[1] = hash2;
    hash_test[2] = hash3;
    times = sizeof(hash_test) / sizeof(byte*);
    /* Testing oversized buffers. */
    for (i = 0; i < times; i++) {
         ExpectIntEQ(wc_RipeMdFinal(&ripemd, hash_test[i]), 0);
    }

    /* Test bad args. */
    ExpectIntEQ(wc_RipeMdFinal(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RipeMdFinal(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RipeMdFinal(&ripemd, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_RipeMdFinal */


/*
 * Testing wc_InitSha3_224, wc_InitSha3_256, wc_InitSha3_384, and
 * wc_InitSha3_512
 */
static int test_wc_InitSha3(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3)
    wc_Sha3 sha3;

    (void)sha3;

#if !defined(WOLFSSL_NOSHA3_224)
    ExpectIntEQ(wc_InitSha3_224(&sha3, HEAP_HINT, testDevId), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_InitSha3_224(NULL, HEAP_HINT, testDevId), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_Sha3_224_Free(&sha3);
#endif /* NOSHA3_224 */
#if !defined(WOLFSSL_NOSHA3_256)
    ExpectIntEQ(wc_InitSha3_256(&sha3, HEAP_HINT, testDevId), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_InitSha3_256(NULL, HEAP_HINT, testDevId), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_Sha3_256_Free(&sha3);
#endif /* NOSHA3_256 */
#if !defined(WOLFSSL_NOSHA3_384)
    ExpectIntEQ(wc_InitSha3_384(&sha3, HEAP_HINT, testDevId), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_InitSha3_384(NULL, HEAP_HINT, testDevId),  WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_Sha3_384_Free(&sha3);
#endif /* NOSHA3_384 */
#if !defined(WOLFSSL_NOSHA3_512)
    ExpectIntEQ(wc_InitSha3_512(&sha3, HEAP_HINT, testDevId), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_InitSha3_512(NULL, HEAP_HINT, testDevId), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_Sha3_512_Free(&sha3);
#endif /* NOSHA3_512 */
#endif
    return EXPECT_RESULT();
} /* END test_wc_InitSha3 */


/*
 * Testing wc_Sha3_Update()
 */
static int testing_wc_Sha3_Update(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_XILINX_CRYPT) && \
   !defined(WOLFSSL_AFALG_XILINX)
    wc_Sha3 sha3;
    byte    msg[] = "Everybody's working for the weekend.";
    byte    msg2[] = "Everybody gets Friday off.";
    byte    msgCmp[] = "\x45\x76\x65\x72\x79\x62\x6f\x64\x79\x27\x73\x20"
                    "\x77\x6f\x72\x6b\x69\x6e\x67\x20\x66\x6f\x72\x20\x74"
                    "\x68\x65\x20\x77\x65\x65\x6b\x65\x6e\x64\x2e\x45\x76"
                    "\x65\x72\x79\x62\x6f\x64\x79\x20\x67\x65\x74\x73\x20"
                    "\x46\x72\x69\x64\x61\x79\x20\x6f\x66\x66\x2e";
    word32  msglen = sizeof(msg) - 1;
    word32  msg2len = sizeof(msg2);
    word32  msgCmplen = sizeof(msgCmp);

    #if !defined(WOLFSSL_NOSHA3_224)
        ExpectIntEQ(wc_InitSha3_224(&sha3, HEAP_HINT, testDevId), 0);
        ExpectIntEQ(wc_Sha3_224_Update(&sha3, msg, msglen), 0);
        ExpectIntEQ(XMEMCMP(msg, sha3.t, msglen), 0);
        ExpectTrue(sha3.i == msglen);

        ExpectIntEQ(wc_Sha3_224_Update(&sha3, msg2, msg2len), 0);
        ExpectIntEQ(XMEMCMP(sha3.t, msgCmp, msgCmplen), 0);

        /* Pass bad args. */
        ExpectIntEQ(wc_Sha3_224_Update(NULL, msg2, msg2len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_Sha3_224_Update(&sha3, NULL, 5), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        wc_Sha3_224_Free(&sha3);

        ExpectIntEQ(wc_InitSha3_224(&sha3, HEAP_HINT, testDevId), 0);
        ExpectIntEQ(wc_Sha3_224_Update(&sha3, NULL, 0), 0);
        ExpectIntEQ(wc_Sha3_224_Update(&sha3, msg2, msg2len), 0);
        ExpectIntEQ(XMEMCMP(msg2, sha3.t, msg2len), 0);
        wc_Sha3_224_Free(&sha3);
    #endif /* SHA3_224 */

    #if !defined(WOLFSSL_NOSHA3_256)
        ExpectIntEQ(wc_InitSha3_256(&sha3, HEAP_HINT, testDevId), 0);
        ExpectIntEQ(wc_Sha3_256_Update(&sha3, msg, msglen), 0);
        ExpectIntEQ(XMEMCMP(msg, sha3.t, msglen), 0);
        ExpectTrue(sha3.i == msglen);

        ExpectIntEQ(wc_Sha3_256_Update(&sha3, msg2, msg2len), 0);
        ExpectIntEQ(XMEMCMP(sha3.t, msgCmp, msgCmplen), 0);

        /* Pass bad args. */
        ExpectIntEQ(wc_Sha3_256_Update(NULL, msg2, msg2len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_Sha3_256_Update(&sha3, NULL, 5), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        wc_Sha3_256_Free(&sha3);

        ExpectIntEQ(wc_InitSha3_256(&sha3, HEAP_HINT, testDevId), 0);
        ExpectIntEQ(wc_Sha3_256_Update(&sha3, NULL, 0), 0);
        ExpectIntEQ(wc_Sha3_256_Update(&sha3, msg2, msg2len), 0);
        ExpectIntEQ(XMEMCMP(msg2, sha3.t, msg2len), 0);
        wc_Sha3_256_Free(&sha3);
    #endif /* SHA3_256 */

    #if !defined(WOLFSSL_NOSHA3_384)
        ExpectIntEQ(wc_InitSha3_384(&sha3, HEAP_HINT, testDevId), 0);
        ExpectIntEQ(wc_Sha3_384_Update(&sha3, msg, msglen), 0);
        ExpectIntEQ(XMEMCMP(msg, sha3.t, msglen), 0);
        ExpectTrue(sha3.i == msglen);

        ExpectIntEQ(wc_Sha3_384_Update(&sha3, msg2, msg2len), 0);
        ExpectIntEQ(XMEMCMP(sha3.t, msgCmp, msgCmplen), 0);

        /* Pass bad args. */
        ExpectIntEQ(wc_Sha3_384_Update(NULL, msg2, msg2len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_Sha3_384_Update(&sha3, NULL, 5), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        wc_Sha3_384_Free(&sha3);

        ExpectIntEQ(wc_InitSha3_384(&sha3, HEAP_HINT, testDevId), 0);
        ExpectIntEQ(wc_Sha3_384_Update(&sha3, NULL, 0), 0);
        ExpectIntEQ(wc_Sha3_384_Update(&sha3, msg2, msg2len), 0);
        ExpectIntEQ(XMEMCMP(msg2, sha3.t, msg2len), 0);
        wc_Sha3_384_Free(&sha3);
    #endif /* SHA3_384 */

    #if !defined(WOLFSSL_NOSHA3_512)
        ExpectIntEQ(wc_InitSha3_512(&sha3, HEAP_HINT, testDevId), 0);
        ExpectIntEQ(wc_Sha3_512_Update(&sha3, msg, msglen), 0);
        ExpectIntEQ(XMEMCMP(msg, sha3.t, msglen), 0);
        ExpectTrue(sha3.i == msglen);

        ExpectIntEQ(wc_Sha3_512_Update(&sha3, msg2, msg2len), 0);
        ExpectIntEQ(XMEMCMP(sha3.t, msgCmp, msgCmplen), 0);

        /* Pass bad args. */
        ExpectIntEQ(wc_Sha3_512_Update(NULL, msg2, msg2len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_Sha3_512_Update(&sha3, NULL, 5), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        wc_Sha3_512_Free(&sha3);

        ExpectIntEQ(wc_InitSha3_512(&sha3, HEAP_HINT, testDevId), 0);
        ExpectIntEQ(wc_Sha3_512_Update(&sha3, NULL, 0), 0);
        ExpectIntEQ(wc_Sha3_512_Update(&sha3, msg2, msg2len), 0);
        ExpectIntEQ(XMEMCMP(msg2, sha3.t, msg2len), 0);
        wc_Sha3_512_Free(&sha3);
    #endif /* SHA3_512 */
#endif /* WOLFSSL_SHA3 */
    return EXPECT_RESULT();
} /* END testing_wc_Sha3_Update */

/*
 *  Testing wc_Sha3_224_Final()
 */
static int test_wc_Sha3_224_Final(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
    wc_Sha3     sha3;
    const char* msg    = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnom"
                         "nopnopq";
    const char* expOut = "\x8a\x24\x10\x8b\x15\x4a\xda\x21\xc9\xfd\x55"
                         "\x74\x49\x44\x79\xba\x5c\x7e\x7a\xb7\x6e\xf2"
                         "\x64\xea\xd0\xfc\xce\x33";
    byte        hash[WC_SHA3_224_DIGEST_SIZE];
    byte        hashRet[WC_SHA3_224_DIGEST_SIZE];

    /* Init stack variables. */
    XMEMSET(hash, 0, sizeof(hash));

    ExpectIntEQ(wc_InitSha3_224(&sha3, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Sha3_224_Update(&sha3, (byte*)msg, (word32)XSTRLEN(msg)), 0);
    ExpectIntEQ(wc_Sha3_224_Final(&sha3, hash), 0);
    ExpectIntEQ(XMEMCMP(expOut, hash, WC_SHA3_224_DIGEST_SIZE), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_224_Final(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_224_Final(&sha3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_Sha3_224_Free(&sha3);

    ExpectIntEQ(wc_InitSha3_224(&sha3, HEAP_HINT, testDevId), 0);
    /* Init stack variables. */
    XMEMSET(hash, 0, sizeof(hash));
    XMEMSET(hashRet, 0, sizeof(hashRet));
    ExpectIntEQ(wc_Sha3_224_Update(&sha3, (byte*)msg, (word32)XSTRLEN(msg)), 0);
    ExpectIntEQ(wc_Sha3_224_GetHash(&sha3, hashRet), 0);
    ExpectIntEQ(wc_Sha3_224_Final(&sha3, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, hashRet, WC_SHA3_224_DIGEST_SIZE), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_224_GetHash(NULL, hashRet), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_224_GetHash(&sha3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha3_224_Free(&sha3);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha3_224_Final */


/*
 *  Testing wc_Sha3_256_Final()
 */
static int test_wc_Sha3_256_Final(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
    wc_Sha3     sha3;
    const char* msg    = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnom"
                         "nopnopq";
    const char* expOut = "\x41\xc0\xdb\xa2\xa9\xd6\x24\x08\x49\x10\x03\x76\xa8"
                        "\x23\x5e\x2c\x82\xe1\xb9\x99\x8a\x99\x9e\x21\xdb\x32"
                        "\xdd\x97\x49\x6d\x33\x76";
    byte        hash[WC_SHA3_256_DIGEST_SIZE];
    byte        hashRet[WC_SHA3_256_DIGEST_SIZE];

    /* Init stack variables. */
    XMEMSET(hash, 0, sizeof(hash));

    ExpectIntEQ(wc_InitSha3_256(&sha3, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Sha3_256_Update(&sha3, (byte*)msg, (word32)XSTRLEN(msg)), 0);
    ExpectIntEQ(wc_Sha3_256_Final(&sha3, hash), 0);
    ExpectIntEQ(XMEMCMP(expOut, hash, WC_SHA3_256_DIGEST_SIZE), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_256_Final(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_256_Final(&sha3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_Sha3_256_Free(&sha3);

    ExpectIntEQ(wc_InitSha3_256(&sha3, HEAP_HINT, testDevId), 0);
    /* Init stack variables. */
    XMEMSET(hash, 0, sizeof(hash));
    XMEMSET(hashRet, 0, sizeof(hashRet));
    ExpectIntEQ(wc_Sha3_256_Update(&sha3, (byte*)msg, (word32)XSTRLEN(msg)), 0);
    ExpectIntEQ(wc_Sha3_256_GetHash(&sha3, hashRet), 0);
    ExpectIntEQ(wc_Sha3_256_Final(&sha3, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, hashRet, WC_SHA3_256_DIGEST_SIZE), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_256_GetHash(NULL, hashRet), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_256_GetHash(&sha3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha3_256_Free(&sha3);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha3_256_Final */


/*
 *  Testing wc_Sha3_384_Final()
 */
static int test_wc_Sha3_384_Final(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
    wc_Sha3        sha3;
    const char* msg    = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnom"
                         "nopnopq";
    const char* expOut = "\x99\x1c\x66\x57\x55\xeb\x3a\x4b\x6b\xbd\xfb\x75\xc7"
                         "\x8a\x49\x2e\x8c\x56\xa2\x2c\x5c\x4d\x7e\x42\x9b\xfd"
                         "\xbc\x32\xb9\xd4\xad\x5a\xa0\x4a\x1f\x07\x6e\x62\xfe"
                         "\xa1\x9e\xef\x51\xac\xd0\x65\x7c\x22";
    byte        hash[WC_SHA3_384_DIGEST_SIZE];
    byte        hashRet[WC_SHA3_384_DIGEST_SIZE];

    /* Init stack variables. */
    XMEMSET(hash, 0, sizeof(hash));

    ExpectIntEQ(wc_InitSha3_384(&sha3, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Sha3_384_Update(&sha3, (byte*)msg, (word32)XSTRLEN(msg)), 0);
    ExpectIntEQ(wc_Sha3_384_Final(&sha3, hash), 0);
    ExpectIntEQ(XMEMCMP(expOut, hash, WC_SHA3_384_DIGEST_SIZE), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_384_Final(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_384_Final(&sha3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_Sha3_384_Free(&sha3);

    ExpectIntEQ(wc_InitSha3_384(&sha3, HEAP_HINT, testDevId), 0);
    /* Init stack variables. */
    XMEMSET(hash, 0, sizeof(hash));
    XMEMSET(hashRet, 0, sizeof(hashRet));
    ExpectIntEQ(wc_Sha3_384_Update(&sha3, (byte*)msg, (word32)XSTRLEN(msg)), 0);
    ExpectIntEQ(wc_Sha3_384_GetHash(&sha3, hashRet), 0);
    ExpectIntEQ(wc_Sha3_384_Final(&sha3, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, hashRet, WC_SHA3_384_DIGEST_SIZE), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_384_GetHash(NULL, hashRet), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_384_GetHash(&sha3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha3_384_Free(&sha3);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha3_384_Final */



/*
 *  Testing wc_Sha3_512_Final()
 */
static int test_wc_Sha3_512_Final(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512) && \
   !defined(WOLFSSL_NOSHA3_384)
    wc_Sha3     sha3;
    const char* msg    = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnom"
                         "nopnopq";
    const char* expOut = "\x04\xa3\x71\xe8\x4e\xcf\xb5\xb8\xb7\x7c\xb4\x86\x10"
                         "\xfc\xa8\x18\x2d\xd4\x57\xce\x6f\x32\x6a\x0f\xd3\xd7"
                         "\xec\x2f\x1e\x91\x63\x6d\xee\x69\x1f\xbe\x0c\x98\x53"
                         "\x02\xba\x1b\x0d\x8d\xc7\x8c\x08\x63\x46\xb5\x33\xb4"
                         "\x9c\x03\x0d\x99\xa2\x7d\xaf\x11\x39\xd6\xe7\x5e";
    byte        hash[WC_SHA3_512_DIGEST_SIZE];
    byte        hashRet[WC_SHA3_512_DIGEST_SIZE];

    /* Init stack variables. */
    XMEMSET(hash, 0, sizeof(hash));

    ExpectIntEQ(wc_InitSha3_512(&sha3, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Sha3_512_Update(&sha3, (byte*)msg, (word32)XSTRLEN(msg)), 0);
    ExpectIntEQ(wc_Sha3_512_Final(&sha3, hash), 0);
    ExpectIntEQ(XMEMCMP(expOut, hash, WC_SHA3_512_DIGEST_SIZE), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_512_Final(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_512_Final(&sha3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_Sha3_512_Free(&sha3);

    ExpectIntEQ(wc_InitSha3_512(&sha3, HEAP_HINT, testDevId), 0);
    /* Init stack variables. */
    XMEMSET(hash, 0, sizeof(hash));
    XMEMSET(hashRet, 0, sizeof(hashRet));
    ExpectIntEQ(wc_Sha3_512_Update(&sha3, (byte*)msg, (word32)XSTRLEN(msg)), 0);
    ExpectIntEQ(wc_Sha3_512_GetHash(&sha3, hashRet), 0);
    ExpectIntEQ(wc_Sha3_512_Final(&sha3, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, hashRet, WC_SHA3_512_DIGEST_SIZE), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_512_GetHash(NULL, hashRet), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_512_GetHash(&sha3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha3_512_Free(&sha3);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha3_512_Final */


/*
 *  Testing wc_Sha3_224_Copy()
 */
static int test_wc_Sha3_224_Copy(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
    wc_Sha3     sha3, sha3Cpy;
    const char* msg = TEST_STRING;
    word32      msglen = (word32)TEST_STRING_SZ;
    byte        hash[WC_SHA3_224_DIGEST_SIZE];
    byte        hashCpy[WC_SHA3_224_DIGEST_SIZE];

    XMEMSET(hash, 0, sizeof(hash));
    XMEMSET(hashCpy, 0, sizeof(hashCpy));
    XMEMSET(&sha3, 0, sizeof(wc_Sha3));
    XMEMSET(&sha3Cpy, 0, sizeof(wc_Sha3));

    ExpectIntEQ(wc_InitSha3_224(&sha3, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_InitSha3_224(&sha3Cpy, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Sha3_224_Update(&sha3, (byte*)msg, msglen), 0);
    ExpectIntEQ(wc_Sha3_224_Copy(&sha3Cpy, &sha3), 0);
    ExpectIntEQ(wc_Sha3_224_Final(&sha3, hash), 0);
    ExpectIntEQ(wc_Sha3_224_Final(&sha3Cpy, hashCpy), 0);
    ExpectIntEQ(XMEMCMP(hash, hashCpy, sizeof(hash)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_224_Copy(NULL, &sha3), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_224_Copy(&sha3Cpy, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha3_224_Free(&sha3);
    wc_Sha3_224_Free(&sha3Cpy);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha3_224_Copy */



/*
 *  Testing wc_Sha3_256_Copy()
 */
static int test_wc_Sha3_256_Copy(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
    wc_Sha3     sha3, sha3Cpy;
    const char* msg = TEST_STRING;
    word32      msglen = (word32)TEST_STRING_SZ;
    byte        hash[WC_SHA3_256_DIGEST_SIZE];
    byte        hashCpy[WC_SHA3_256_DIGEST_SIZE];

    XMEMSET(hash, 0, sizeof(hash));
    XMEMSET(hashCpy, 0, sizeof(hashCpy));
    XMEMSET(&sha3, 0, sizeof(wc_Sha3));
    XMEMSET(&sha3Cpy, 0, sizeof(wc_Sha3));

    ExpectIntEQ(wc_InitSha3_256(&sha3, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_InitSha3_256(&sha3Cpy, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Sha3_256_Update(&sha3, (byte*)msg, msglen), 0);
    ExpectIntEQ(wc_Sha3_256_Copy(&sha3Cpy, &sha3), 0);
    ExpectIntEQ(wc_Sha3_256_Final(&sha3, hash), 0);
    ExpectIntEQ(wc_Sha3_256_Final(&sha3Cpy, hashCpy), 0);
    ExpectIntEQ(XMEMCMP(hash, hashCpy, sizeof(hash)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_256_Copy(NULL, &sha3), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_256_Copy(&sha3Cpy, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha3_256_Free(&sha3);
    wc_Sha3_256_Free(&sha3Cpy);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha3_256_Copy */



/*
 *  Testing wc_Sha3_384_Copy()
 */
static int test_wc_Sha3_384_Copy(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
    wc_Sha3     sha3, sha3Cpy;
    const char* msg = TEST_STRING;
    word32      msglen = (word32)TEST_STRING_SZ;
    byte        hash[WC_SHA3_384_DIGEST_SIZE];
    byte        hashCpy[WC_SHA3_384_DIGEST_SIZE];

    XMEMSET(hash, 0, sizeof(hash));
    XMEMSET(hashCpy, 0, sizeof(hashCpy));
    XMEMSET(&sha3, 0, sizeof(wc_Sha3));
    XMEMSET(&sha3Cpy, 0, sizeof(wc_Sha3));

    ExpectIntEQ(wc_InitSha3_384(&sha3, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_InitSha3_384(&sha3Cpy, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Sha3_384_Update(&sha3, (byte*)msg, msglen), 0);
    ExpectIntEQ(wc_Sha3_384_Copy(&sha3Cpy, &sha3), 0);
    ExpectIntEQ(wc_Sha3_384_Final(&sha3, hash), 0);
    ExpectIntEQ(wc_Sha3_384_Final(&sha3Cpy, hashCpy), 0);
    ExpectIntEQ(XMEMCMP(hash, hashCpy, sizeof(hash)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_384_Copy(NULL, &sha3), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_384_Copy(&sha3Cpy, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha3_384_Free(&sha3);
    wc_Sha3_384_Free(&sha3Cpy);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha3_384_Copy */


/*
 *  Testing wc_Sha3_512_Copy()
 */
static int test_wc_Sha3_512_Copy(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
    wc_Sha3     sha3, sha3Cpy;
    const char* msg = TEST_STRING;
    word32      msglen = (word32)TEST_STRING_SZ;
    byte        hash[WC_SHA3_512_DIGEST_SIZE];
    byte        hashCpy[WC_SHA3_512_DIGEST_SIZE];

    XMEMSET(hash, 0, sizeof(hash));
    XMEMSET(hashCpy, 0, sizeof(hashCpy));
    XMEMSET(&sha3, 0, sizeof(wc_Sha3));
    XMEMSET(&sha3Cpy, 0, sizeof(wc_Sha3));

    ExpectIntEQ(wc_InitSha3_512(&sha3, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_InitSha3_512(&sha3Cpy, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Sha3_512_Update(&sha3, (byte*)msg, msglen), 0);
    ExpectIntEQ(wc_Sha3_512_Copy(&sha3Cpy, &sha3), 0);
    ExpectIntEQ(wc_Sha3_512_Final(&sha3, hash), 0);
    ExpectIntEQ(wc_Sha3_512_Final(&sha3Cpy, hashCpy), 0);
    ExpectIntEQ(XMEMCMP(hash, hashCpy, sizeof(hash)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Sha3_512_Copy(NULL, &sha3), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha3_512_Copy(&sha3Cpy, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Sha3_512_Free(&sha3);
    wc_Sha3_512_Free(&sha3Cpy);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha3_512_Copy */
/*
 * Unit test function for wc_Sha3_GetFlags()
 */
static int test_wc_Sha3_GetFlags(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sha3 sha3;
    word32  flags = 0;

    /* Initialize */
    ExpectIntEQ(wc_InitSha3_224(&sha3, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Sha3_GetFlags(&sha3, &flags), 0);
    ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == 0);
    wc_Sha3_224_Free(&sha3);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha3_GetFlags */


static int test_wc_InitShake256(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    wc_Shake shake;

    ExpectIntEQ(wc_InitShake256(&shake, HEAP_HINT, testDevId), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_InitShake256(NULL, HEAP_HINT, testDevId), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Shake256_Free(&shake);
#endif
    return EXPECT_RESULT();
}


static int testing_wc_Shake256_Update(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    wc_Shake shake;
    byte     msg[] = "Everybody's working for the weekend.";
    byte     msg2[] = "Everybody gets Friday off.";
    byte     msgCmp[] = "\x45\x76\x65\x72\x79\x62\x6f\x64\x79\x27\x73\x20"
                        "\x77\x6f\x72\x6b\x69\x6e\x67\x20\x66\x6f\x72\x20\x74"
                        "\x68\x65\x20\x77\x65\x65\x6b\x65\x6e\x64\x2e\x45\x76"
                        "\x65\x72\x79\x62\x6f\x64\x79\x20\x67\x65\x74\x73\x20"
                        "\x46\x72\x69\x64\x61\x79\x20\x6f\x66\x66\x2e";
    word32   msglen = sizeof(msg) - 1;
    word32   msg2len = sizeof(msg2);
    word32   msgCmplen = sizeof(msgCmp);

    ExpectIntEQ(wc_InitShake256(&shake, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Shake256_Update(&shake, msg, msglen), 0);
    ExpectIntEQ(XMEMCMP(msg, shake.t, msglen), 0);
    ExpectTrue(shake.i == msglen);

    ExpectIntEQ(wc_Shake256_Update(&shake, msg2, msg2len), 0);
    ExpectIntEQ(XMEMCMP(shake.t, msgCmp, msgCmplen), 0);

    /* Pass bad args. */
    ExpectIntEQ(wc_Shake256_Update(NULL, msg2, msg2len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake256_Update(&shake, NULL, 5), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_Shake256_Free(&shake);

    ExpectIntEQ(wc_InitShake256(&shake, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Shake256_Update(&shake, NULL, 0), 0);
    ExpectIntEQ(wc_Shake256_Update(&shake, msg2, msg2len), 0);
    ExpectIntEQ(XMEMCMP(msg2, shake.t, msg2len), 0);
    wc_Shake256_Free(&shake);
#endif /* WOLFSSL_SHAKE256 */
    return EXPECT_RESULT();
}

static int test_wc_Shake256_Final(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    wc_Shake    shake;
    const char* msg    = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnom"
                         "nopnopq";
    const char* expOut = "\x4d\x8c\x2d\xd2\x43\x5a\x01\x28\xee\xfb\xb8\xc3\x6f"
                         "\x6f\x87\x13\x3a\x79\x11\xe1\x8d\x97\x9e\xe1\xae\x6b"
                         "\xe5\xd4\xfd\x2e\x33\x29\x40\xd8\x68\x8a\x4e\x6a\x59"
                         "\xaa\x80\x60\xf1\xf9\xbc\x99\x6c\x05\xac\xa3\xc6\x96"
                         "\xa8\xb6\x62\x79\xdc\x67\x2c\x74\x0b\xb2\x24\xec\x37"
                         "\xa9\x2b\x65\xdb\x05\x39\xc0\x20\x34\x55\xf5\x1d\x97"
                         "\xcc\xe4\xcf\xc4\x91\x27\xd7\x26\x0a\xfc\x67\x3a\xf2"
                         "\x08\xba\xf1\x9b\xe2\x12\x33\xf3\xde\xbe\x78\xd0\x67"
                         "\x60\xcf\xa5\x51\xee\x1e\x07\x91\x41\xd4";
    byte        hash[114];

    /* Init stack variables. */
    XMEMSET(hash, 0, sizeof(hash));

    ExpectIntEQ(wc_InitShake256(&shake, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_Shake256_Update(&shake, (byte*)msg, (word32)XSTRLEN(msg)),
        0);
    ExpectIntEQ(wc_Shake256_Final(&shake, hash, (word32)sizeof(hash)), 0);
    ExpectIntEQ(XMEMCMP(expOut, hash, (word32)sizeof(hash)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Shake256_Final(NULL, hash, (word32)sizeof(hash)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake256_Final(&shake, NULL, (word32)sizeof(hash)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Shake256_Free(&shake);
#endif
    return EXPECT_RESULT();
}
/*
 *  Testing wc_Shake256_Copy()
 */
static int test_wc_Shake256_Copy(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    wc_Shake    shake, shakeCpy;
    const char* msg = TEST_STRING;
    word32      msglen = (word32)TEST_STRING_SZ;
    byte        hash[144];
    byte        hashCpy[144];
    word32      hashLen = sizeof(hash);
    word32      hashLenCpy = sizeof(hashCpy);

    XMEMSET(hash, 0, sizeof(hash));
    XMEMSET(hashCpy, 0, sizeof(hashCpy));

    ExpectIntEQ(wc_InitShake256(&shake, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_InitShake256(&shakeCpy, HEAP_HINT, testDevId), 0);

    ExpectIntEQ(wc_Shake256_Update(&shake, (byte*)msg, msglen), 0);
    ExpectIntEQ(wc_Shake256_Copy(&shakeCpy, &shake), 0);
    ExpectIntEQ(wc_Shake256_Final(&shake, hash, hashLen), 0);
    ExpectIntEQ(wc_Shake256_Final(&shakeCpy, hashCpy, hashLenCpy), 0);
    ExpectIntEQ(XMEMCMP(hash, hashCpy, sizeof(hash)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Shake256_Copy(NULL, &shake), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake256_Copy(&shakeCpy, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Shake256_Free(&shake);
    wc_Shake256_Free(&shakeCpy);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Shake256_Copy */
/*
 * Unit test function for wc_Shake256Hash()
 */
static int test_wc_Shake256Hash(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    const byte data[] = { /* Hello World */
        0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
        0x72,0x6c,0x64
    };
    word32     len = sizeof(data);
    byte       hash[144];
    word32     hashLen = sizeof(hash);

    ExpectIntEQ(wc_Shake256Hash(data, len, hash, hashLen), 0);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_Shake256Hash */


/*
 *  Testing wc_InitSm3(), wc_Sm3Free()
 */
static int test_wc_InitSm3Free(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SM3
    wc_Sm3 sm3;

    /* Invalid Parameters */
    ExpectIntEQ(wc_InitSm3(NULL, NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid Parameters */
    ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0);

    wc_Sm3Free(NULL);
    wc_Sm3Free(&sm3);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_InitSm3 */

/*
 *  Testing wc_Sm3Update(), wc_Sm3Final()
 */
static int test_wc_Sm3UpdateFinal(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SM3
    wc_Sm3 sm3;
    byte data[WC_SM3_BLOCK_SIZE * 4];
    byte hash[WC_SM3_DIGEST_SIZE];
    byte calcHash[WC_SM3_DIGEST_SIZE];
    byte expHash[WC_SM3_DIGEST_SIZE] = {
        0x38, 0x48, 0x15, 0xa7, 0x0e, 0xae, 0x0b, 0x27,
        0x5c, 0xde, 0x9d, 0xa5, 0xd1, 0xa4, 0x30, 0xa1,
        0xca, 0xd4, 0x54, 0x58, 0x44, 0xa2, 0x96, 0x1b,
        0xd7, 0x14, 0x80, 0x3f, 0x80, 0x1a, 0x07, 0xb6
    };
    word32 chunk;
    word32 i;

    XMEMSET(data, 0, sizeof(data));

    ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0);

    /* Invalid Parameters */
    ExpectIntEQ(wc_Sm3Update(NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3Update(&sm3, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3Update(NULL, data, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid Parameters */
    ExpectIntEQ(wc_Sm3Update(&sm3, NULL, 0), 0);
    ExpectIntEQ(wc_Sm3Update(&sm3, data, 1), 0);
    ExpectIntEQ(wc_Sm3Update(&sm3, data, 1), 0);
    ExpectIntEQ(wc_Sm3Update(&sm3, data, WC_SM3_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_Sm3Update(&sm3, data, WC_SM3_BLOCK_SIZE - 2), 0);
    ExpectIntEQ(wc_Sm3Update(&sm3, data, WC_SM3_BLOCK_SIZE * 2), 0);
    /* Ensure too many bytes for lengths. */
    ExpectIntEQ(wc_Sm3Update(&sm3, data, WC_SM3_PAD_SIZE), 0);

    /* Invalid Parameters */
    ExpectIntEQ(wc_Sm3Final(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3Final(&sm3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3Final(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid Parameters */
    ExpectIntEQ(wc_Sm3Final(&sm3, hash), 0);
    ExpectBufEQ(hash, expHash, WC_SM3_DIGEST_SIZE);

    /* Chunk tests. */
    ExpectIntEQ(wc_Sm3Update(&sm3, data, sizeof(data)), 0);
    ExpectIntEQ(wc_Sm3Final(&sm3, calcHash), 0);
    for (chunk = 1; chunk <= WC_SM3_BLOCK_SIZE + 1; chunk++) {
        for (i = 0; i + chunk <= (word32)sizeof(data); i += chunk) {
            ExpectIntEQ(wc_Sm3Update(&sm3, data + i, chunk), 0);
        }
        if (i < (word32)sizeof(data)) {
            ExpectIntEQ(wc_Sm3Update(&sm3, data + i, (word32)sizeof(data) - i),
                0);
        }
        ExpectIntEQ(wc_Sm3Final(&sm3, hash), 0);
        ExpectBufEQ(hash, calcHash, WC_SM3_DIGEST_SIZE);
    }

    /* Not testing when the low 32-bit length overflows. */

    wc_Sm3Free(&sm3);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_Sm3Update */

/*
 *  Testing wc_Sm3GetHash()
 */
static int test_wc_Sm3GetHash(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SM3
    wc_Sm3 sm3;
    byte hash[WC_SM3_DIGEST_SIZE];
    byte calcHash[WC_SM3_DIGEST_SIZE];
    byte data[WC_SM3_BLOCK_SIZE];

    XMEMSET(data, 0, sizeof(data));

    ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_Sm3Final(&sm3, calcHash), 0);

    /* Invalid Parameters */
    ExpectIntEQ(wc_Sm3GetHash(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3GetHash(&sm3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3GetHash(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid Parameters */
    ExpectIntEQ(wc_Sm3GetHash(&sm3, hash), 0);
    ExpectBufEQ(hash, calcHash, WC_SM3_DIGEST_SIZE);

    /* With update. */
    ExpectIntEQ(wc_Sm3Update(&sm3, data, sizeof(data)), 0);
    ExpectIntEQ(wc_Sm3GetHash(&sm3, hash), 0);
    ExpectIntEQ(wc_Sm3Final(&sm3, calcHash), 0);
    ExpectBufEQ(hash, calcHash, WC_SM3_DIGEST_SIZE);

    wc_Sm3Free(&sm3);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_Sm3Update */

/*
 *  Testing wc_Sm3Copy()
 */
static int test_wc_Sm3Copy(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SM3) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sm3 sm3;
    wc_Sm3 sm3Copy;
    byte hash[WC_SM3_DIGEST_SIZE];
    byte hashCopy[WC_SM3_DIGEST_SIZE];
    byte data[WC_SM3_BLOCK_SIZE + 1];
    int i;

    ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_InitSm3(&sm3Copy, NULL, INVALID_DEVID), 0);

    /* Invalid Parameters */
    ExpectIntEQ(wc_Sm3Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3Copy(&sm3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3Copy(NULL, &sm3Copy), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid Parameters */
    ExpectIntEQ(wc_Sm3Copy(&sm3, &sm3Copy), 0);

    /* Ensure all parts of data updated during hashing are copied. */
    for (i = 0; i < WC_SM3_BLOCK_SIZE + 1; i++) {
        ExpectIntEQ(wc_Sm3Update(&sm3, data, i), 0);
        ExpectIntEQ(wc_Sm3Copy(&sm3, &sm3Copy), 0);
        ExpectIntEQ(wc_Sm3Update(&sm3, data, 1), 0);
        ExpectIntEQ(wc_Sm3Update(&sm3Copy, data, 1), 0);
        ExpectIntEQ(wc_Sm3Final(&sm3, hash), 0);
        ExpectIntEQ(wc_Sm3Final(&sm3Copy, hashCopy), 0);
        ExpectBufEQ(hash, hashCopy, WC_SM3_DIGEST_SIZE);
    }

    wc_Sm3Free(&sm3Copy);
    wc_Sm3Free(&sm3);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_Sm3Copy */

/*
 * Testing wc_Sm3FinalRaw()
 */
static int test_wc_Sm3FinalRaw(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SM3) && !defined(HAVE_SELFTEST) && \
    !defined(WOLFSSL_DEVCRYPTO) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 3))) && \
    !defined(WOLFSSL_NO_HASH_RAW)
    wc_Sm3 sm3;
    byte hash1[WC_SM3_DIGEST_SIZE];
    byte hash2[WC_SM3_DIGEST_SIZE];
    byte hash3[WC_SM3_DIGEST_SIZE];
    byte* hash_test[3] = { hash1, hash2, hash3 };
    int times;
    int i;

    XMEMSET(&sm3, 0, sizeof(sm3));

    /* Initialize */
    ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0);

    /* Invalid Parameters */
    ExpectIntEQ(wc_Sm3FinalRaw(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3FinalRaw(&sm3, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3FinalRaw(NULL, hash1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    times = sizeof(hash_test) / sizeof(byte*);
    for (i = 0; i < times; i++) {
        ExpectIntEQ(wc_Sm3FinalRaw(&sm3, hash_test[i]), 0);
    }

    wc_Sm3Free(&sm3);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sm3FinalRaw */
/*
 *  Testing wc_Sm3GetFlags, wc_Sm3SetFlags()
 */
static int test_wc_Sm3GetSetFlags(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SM3) && defined(WOLFSSL_HASH_FLAGS)
    wc_Sm3 sm3;
    wc_Sm3 sm3Copy;
    word32 flags = 0;

    ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_InitSm3(&sm3Copy, NULL, INVALID_DEVID), 0);

    ExpectIntEQ(wc_Sm3GetFlags(NULL, &flags), 0);
    ExpectIntEQ(flags, 0);
    ExpectIntEQ(wc_Sm3SetFlags(NULL, WC_HASH_FLAG_WILLCOPY), 0);
    ExpectIntEQ(wc_Sm3GetFlags(NULL, &flags), 0);
    ExpectIntEQ(flags, 0);
    ExpectIntEQ(wc_Sm3GetFlags(&sm3, &flags), 0);
    ExpectIntEQ(flags, 0);
    ExpectIntEQ(wc_Sm3SetFlags(&sm3, WC_HASH_FLAG_WILLCOPY), 0);
    ExpectIntEQ(wc_Sm3GetFlags(&sm3, &flags), 0);
    ExpectIntEQ(flags, WC_HASH_FLAG_WILLCOPY);

    ExpectIntEQ(wc_Sm3Copy(&sm3, &sm3Copy), 0);
    ExpectIntEQ(wc_Sm3GetFlags(&sm3Copy, &flags), 0);
    ExpectIntEQ(flags, WC_HASH_FLAG_ISCOPY | WC_HASH_FLAG_WILLCOPY);

    wc_Sm3Free(&sm3Copy);
    wc_Sm3Free(&sm3);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_Sm3Update */

/*
 *  Testing wc_Sm3Hash()
 */
static int test_wc_Sm3Hash(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SM3) && defined(WOLFSSL_HASH_FLAGS)
    byte data[WC_SM3_BLOCK_SIZE];
    byte hash[WC_SM3_DIGEST_SIZE];

    /* Invalid parameters. */
    ExpectIntEQ(wc_Sm3Hash(NULL, sizeof(data), hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm3Hash(data, sizeof(data), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid parameters. */
    ExpectIntEQ(wc_Sm3Hash(data, sizeof(data), hash), 0);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_Sm3Hash */

/*
 * Test function for wc_HmacSetKey
 */
static int test_wc_Md5HmacSetKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_MD5)
    Hmac hmac;
    int ret, times, itr;

    const char* keys[]=
    {
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
#ifndef HAVE_FIPS
        "Jefe", /* smaller than minimum FIPS key size */
#endif
        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    };
    times = sizeof(keys) / sizeof(char*);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);

    for (itr = 0; itr < times; itr++) {
        ret = wc_HmacSetKey(&hmac, WC_MD5, (byte*)keys[itr],
            (word32)XSTRLEN(keys[itr]));
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5)
        wc_HmacFree(&hmac);
        ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#else
        ExpectIntEQ(ret, 0);
#endif
    }

    /* Bad args. */
    ExpectIntEQ(wc_HmacSetKey(NULL, WC_MD5, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_MD5, NULL, (word32)XSTRLEN(keys[0])),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ret = wc_HmacSetKey(&hmac, WC_MD5, (byte*)keys[0], 0);
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#elif defined(HAVE_FIPS)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(HMAC_MIN_KEYLEN_E));
#else
    ExpectIntEQ(ret, 0);
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Md5HmacSetKey */


/*
 * testing wc_HmacSetKey() on wc_Sha hash.
 */
static int test_wc_ShaHmacSetKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_SHA)
    Hmac hmac;
    int ret, times, itr;

    const char* keys[]=
    {
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
                                                                "\x0b\x0b\x0b",
#ifndef HAVE_FIPS
        "Jefe", /* smaller than minimum FIPS key size */
#endif
        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
                                                                "\xAA\xAA\xAA"
    };

    times = sizeof(keys) / sizeof(char*);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);

    for (itr = 0; itr < times; itr++) {
        ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA, (byte*)keys[itr],
            (word32)XSTRLEN(keys[itr])), 0);
    }

    /* Bad args. */
    ExpectIntEQ(wc_HmacSetKey(NULL, WC_SHA, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA, NULL, (word32)XSTRLEN(keys[0])),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ret = wc_HmacSetKey(&hmac, WC_SHA, (byte*)keys[0], 0);
#ifdef HAVE_FIPS
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(HMAC_MIN_KEYLEN_E));
#else
    ExpectIntEQ(ret, 0);
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ShaHmacSetKey() */

/*
 * testing wc_HmacSetKey() on Sha224 hash.
 */
static int test_wc_Sha224HmacSetKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA224)
    Hmac hmac;
    int ret, times, itr;

    const char* keys[]=
    {
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
                                                                "\x0b\x0b\x0b",
#ifndef HAVE_FIPS
        "Jefe", /* smaller than minimum FIPS key size */
#endif
        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
                                                                "\xAA\xAA\xAA"
    };
    times = sizeof(keys) / sizeof(char*);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);

    for (itr = 0; itr < times; itr++) {
        ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA224, (byte*)keys[itr],
            (word32)XSTRLEN(keys[itr])), 0);
    }

    /* Bad args. */
    ExpectIntEQ(wc_HmacSetKey(NULL, WC_SHA224, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA224, NULL, (word32)XSTRLEN(keys[0])),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ret = wc_HmacSetKey(&hmac, WC_SHA224, (byte*)keys[0], 0);
#ifdef HAVE_FIPS
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(HMAC_MIN_KEYLEN_E));
#else
    ExpectIntEQ(ret, 0);
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha224HmacSetKey() */

 /*
  * testing wc_HmacSetKey() on Sha256 hash
  */
static int test_wc_Sha256HmacSetKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_SHA256)
    Hmac hmac;
    int ret, times, itr;

    const char* keys[]=
    {
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
                                                                "\x0b\x0b\x0b",
#ifndef HAVE_FIPS
        "Jefe", /* smaller than minimum FIPS key size */
#endif
        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
                                                                "\xAA\xAA\xAA"
    };
    times = sizeof(keys) / sizeof(char*);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);

    for (itr = 0; itr < times; itr++) {
        ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA256, (byte*)keys[itr],
            (word32)XSTRLEN(keys[itr])), 0);
    }

    /* Bad args. */
    ExpectIntEQ(wc_HmacSetKey(NULL, WC_SHA256, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA256, NULL, (word32)XSTRLEN(keys[0])),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ret = wc_HmacSetKey(&hmac, WC_SHA256, (byte*)keys[0], 0);
#ifdef HAVE_FIPS
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(HMAC_MIN_KEYLEN_E));
#else
    ExpectIntEQ(ret, 0);
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha256HmacSetKey() */


/*
 * testing wc_HmacSetKey on Sha384 hash.
 */
static int test_wc_Sha384HmacSetKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA384)
    Hmac hmac;
    int ret, times, itr;

    const char* keys[]=
    {
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
                                                                "\x0b\x0b\x0b",
#ifndef HAVE_FIPS
        "Jefe", /* smaller than minimum FIPS key size */
#endif
        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
                                                                "\xAA\xAA\xAA"
    };
    times = sizeof(keys) / sizeof(char*);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);

    for (itr = 0; itr < times; itr++) {
        ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA384, (byte*)keys[itr],
            (word32)XSTRLEN(keys[itr])), 0);
    }

    /* Bad args. */
    ExpectIntEQ(wc_HmacSetKey(NULL, WC_SHA384, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA384, NULL, (word32)XSTRLEN(keys[0])),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0],
        (word32)XSTRLEN(keys[0])), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ret = wc_HmacSetKey(&hmac, WC_SHA384, (byte*)keys[0], 0);
#ifdef HAVE_FIPS
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(HMAC_MIN_KEYLEN_E));
#else
    ExpectIntEQ(ret, 0);
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha384HmacSetKey() */


/*
 * testing wc_HmacUpdate on wc_Md5 hash.
 */
static int test_wc_Md5HmacUpdate(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_MD5) && !(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5))
    Hmac hmac;
    testVector a, b;
#ifdef HAVE_FIPS
    const char* keys =
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
#else
    const char* keys = "Jefe";
#endif

    a.input = "what do ya want for nothing?";
    a.inLen  = XSTRLEN(a.input);
    b.input = "Hi There";
    b.inLen = XSTRLEN(b.input);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_MD5, (byte*)keys,
        (word32)XSTRLEN(keys)), 0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)b.input, (word32)b.inLen), 0);
    /* Update Hmac. */
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_HmacUpdate(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacUpdate(&hmac, NULL, (word32)a.inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, 0), 0);

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Md5HmacUpdate */

/*
 * testing wc_HmacUpdate on SHA hash.
 */
static int test_wc_ShaHmacUpdate(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_SHA)
    Hmac hmac;
    testVector a, b;
#ifdef HAVE_FIPS
    const char* keys =
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
#else
    const char* keys = "Jefe";
#endif

    a.input = "what do ya want for nothing?";
    a.inLen  = XSTRLEN(a.input);
    b.input = "Hi There";
    b.inLen = XSTRLEN(b.input);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA, (byte*)keys,
        (word32)XSTRLEN(keys)), 0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)b.input, (word32)b.inLen), 0);
    /* Update Hmac. */
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_HmacUpdate(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacUpdate(&hmac, NULL, (word32)a.inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, 0), 0);

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ShaHmacUpdate */

/*
 * testing wc_HmacUpdate on SHA224 hash.
 */
static int test_wc_Sha224HmacUpdate(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA224)
    Hmac hmac;
    testVector a, b;
#ifdef HAVE_FIPS
    const char* keys =
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
#else
    const char* keys = "Jefe";
#endif

    a.input = "what do ya want for nothing?";
    a.inLen  = XSTRLEN(a.input);
    b.input = "Hi There";
    b.inLen = XSTRLEN(b.input);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA224, (byte*)keys,
        (word32)XSTRLEN(keys)), 0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)b.input, (word32)b.inLen), 0);
    /* Update Hmac. */
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_HmacUpdate(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacUpdate(&hmac, NULL, (word32)a.inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, 0), 0);

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha224HmacUpdate */

/*
 * testing wc_HmacUpdate on SHA256 hash.
 */
static int test_wc_Sha256HmacUpdate(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_SHA256)
    Hmac hmac;
    testVector a, b;
#ifdef HAVE_FIPS
    const char* keys =
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
#else
    const char* keys = "Jefe";
#endif

    a.input = "what do ya want for nothing?";
    a.inLen  = XSTRLEN(a.input);
    b.input = "Hi There";
    b.inLen = XSTRLEN(b.input);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA256, (byte*)keys,
        (word32)XSTRLEN(keys)), 0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)b.input, (word32)b.inLen), 0);
    /* Update Hmac. */
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_HmacUpdate(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacUpdate(&hmac, NULL, (word32)a.inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, 0), 0);

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha256HmacUpdate */

/*
 * testing wc_HmacUpdate on SHA384  hash.
 */
static int test_wc_Sha384HmacUpdate(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA384)
    Hmac hmac;
    testVector a, b;
#ifdef HAVE_FIPS
    const char* keys =
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
#else
    const char* keys = "Jefe";
#endif

    a.input = "what do ya want for nothing?";
    a.inLen  = XSTRLEN(a.input);
    b.input = "Hi There";
    b.inLen = XSTRLEN(b.input);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA384, (byte*)keys,
        (word32)XSTRLEN(keys)), 0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)b.input, (word32)b.inLen), 0);
    /* Update Hmac. */
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_HmacUpdate(NULL, (byte*)a.input, (word32)a.inLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_HmacUpdate(&hmac, NULL, (word32)a.inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, 0), 0);

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha384HmacUpdate */

/*
 * Testing wc_HmacFinal() with MD5
 */

static int test_wc_Md5HmacFinal(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_MD5) && !(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5))
    Hmac hmac;
    byte hash[WC_MD5_DIGEST_SIZE];
    testVector a;
    const char* key;

    key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
    a.input = "Hi There";
    a.output = "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc"
               "\x9d";
    a.inLen  = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_MD5, (byte*)key, (word32)XSTRLEN(key)),
        0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_HmacFinal(&hmac, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_MD5_DIGEST_SIZE), 0);

    /* Try bad parameters. */
    ExpectIntEQ(wc_HmacFinal(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef HAVE_FIPS
    ExpectIntEQ(wc_HmacFinal(&hmac, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Md5HmacFinal */

/*
 * Testing wc_HmacFinal() with SHA
 */
static int test_wc_ShaHmacFinal(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_SHA)
    Hmac hmac;
    byte hash[WC_SHA_DIGEST_SIZE];
    testVector a;
    const char* key;

    key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
                                                                "\x0b\x0b\x0b";
    a.input = "Hi There";
    a.output = "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c"
               "\x8e\xf1\x46\xbe\x00";
    a.inLen  = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA, (byte*)key, (word32)XSTRLEN(key)),
        0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_HmacFinal(&hmac, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA_DIGEST_SIZE), 0);

    /* Try bad parameters. */
    ExpectIntEQ(wc_HmacFinal(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef HAVE_FIPS
    ExpectIntEQ(wc_HmacFinal(&hmac, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ShaHmacFinal */


/*
 * Testing wc_HmacFinal() with SHA224
 */
static int test_wc_Sha224HmacFinal(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA224)
    Hmac hmac;
    byte hash[WC_SHA224_DIGEST_SIZE];
    testVector a;
    const char* key;

    key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
                                                                "\x0b\x0b\x0b";
    a.input = "Hi There";
    a.output = "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3"
               "\x3f\x47\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22";
    a.inLen  = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA224, (byte*)key,
        (word32)XSTRLEN(key)), 0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_HmacFinal(&hmac, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA224_DIGEST_SIZE), 0);

    /* Try bad parameters. */
    ExpectIntEQ(wc_HmacFinal(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef HAVE_FIPS
    ExpectIntEQ(wc_HmacFinal(&hmac, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha224HmacFinal */

/*
 * Testing wc_HmacFinal() with SHA256
 */
static int test_wc_Sha256HmacFinal(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_SHA256)
    Hmac hmac;
    byte hash[WC_SHA256_DIGEST_SIZE];
    testVector a;
    const char* key;

    key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
                                                                "\x0b\x0b\x0b";
    a.input = "Hi There";
    a.output = "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1"
               "\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32"
               "\xcf\xf7";
    a.inLen  = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA256, (byte*)key,
        (word32)XSTRLEN(key)), 0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_HmacFinal(&hmac, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA256_DIGEST_SIZE), 0);

    /* Try bad parameters. */
    ExpectIntEQ(wc_HmacFinal(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef HAVE_FIPS
    ExpectIntEQ(wc_HmacFinal(&hmac, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha256HmacFinal */

/*
 * Testing wc_HmacFinal() with SHA384
 */
static int test_wc_Sha384HmacFinal(void)
{
    EXPECT_DECLS;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA384)
    Hmac hmac;
    byte hash[WC_SHA384_DIGEST_SIZE];
    testVector a;
    const char* key;

    key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
                                                                "\x0b\x0b\x0b";
    a.input = "Hi There";
    a.output = "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90"
               "\x7f\x15\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb"
               "\xc5\x9c\xfa\xea\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2"
               "\xfa\x9c\xb6";
    a.inLen  = XSTRLEN(a.input);
    a.outLen = XSTRLEN(a.output);

    ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA384, (byte*)key,
        (word32)XSTRLEN(key)), 0);
    ExpectIntEQ(wc_HmacUpdate(&hmac, (byte*)a.input, (word32)a.inLen), 0);
    ExpectIntEQ(wc_HmacFinal(&hmac, hash), 0);
    ExpectIntEQ(XMEMCMP(hash, a.output, WC_SHA384_DIGEST_SIZE), 0);

    /* Try bad parameters. */
    ExpectIntEQ(wc_HmacFinal(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef HAVE_FIPS
    ExpectIntEQ(wc_HmacFinal(&hmac, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    wc_HmacFree(&hmac);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Sha384HmacFinal */



/*
 * Testing wc_InitCmac()
 */
static int test_wc_InitCmac(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CMAC) && !defined(NO_AES)
    Cmac        cmac1;
    Cmac        cmac2;
    Cmac        cmac3;
    /* AES 128 key. */
    byte        key1[] = "\x01\x02\x03\x04\x05\x06\x07\x08"
                         "\x09\x10\x11\x12\x13\x14\x15\x16";
    /* AES 192 key. */
    byte        key2[] = "\x01\x02\x03\x04\x05\x06\x07\x08"
                         "\x09\x01\x11\x12\x13\x14\x15\x16"
                         "\x01\x02\x03\x04\x05\x06\x07\x08";
    /* AES 256 key. */
    byte        key3[] = "\x01\x02\x03\x04\x05\x06\x07\x08"
                         "\x09\x01\x11\x12\x13\x14\x15\x16"
                         "\x01\x02\x03\x04\x05\x06\x07\x08"
                         "\x09\x01\x11\x12\x13\x14\x15\x16";
    word32      key1Sz = (word32)sizeof(key1) - 1;
    word32      key2Sz = (word32)sizeof(key2) - 1;
    word32      key3Sz = (word32)sizeof(key3) - 1;
    int         type   = WC_CMAC_AES;

    (void)key1;
    (void)key1Sz;
    (void)key2;
    (void)key2Sz;

    XMEMSET(&cmac1, 0, sizeof(Cmac));
    XMEMSET(&cmac2, 0, sizeof(Cmac));
    XMEMSET(&cmac3, 0, sizeof(Cmac));

#ifdef WOLFSSL_AES_128
    ExpectIntEQ(wc_InitCmac(&cmac1, key1, key1Sz, type, NULL), 0);
#endif
#ifdef WOLFSSL_AES_192
    wc_AesFree(&cmac1.aes);
    ExpectIntEQ(wc_InitCmac(&cmac2, key2, key2Sz, type, NULL), 0);
#endif
#ifdef WOLFSSL_AES_256
    wc_AesFree(&cmac2.aes);
    ExpectIntEQ(wc_InitCmac(&cmac3, key3, key3Sz, type, NULL), 0);
#endif

    wc_AesFree(&cmac3.aes);
    /* Test bad args. */
    ExpectIntEQ(wc_InitCmac(NULL, key3, key3Sz, type, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitCmac(&cmac3, NULL, key3Sz, type, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitCmac(&cmac3, key3, 0, type, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_InitCmac(&cmac3, key3, key3Sz, 0, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_InitCmac */


/*
 * Testing wc_CmacUpdate()
 */
static int test_wc_CmacUpdate(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_128)
    Cmac        cmac;
    byte        key[] = {
        0x64, 0x4c, 0xbf, 0x12, 0x85, 0x9d, 0xf0, 0x55,
        0x7e, 0xa9, 0x1f, 0x08, 0xe0, 0x51, 0xff, 0x27
    };
    byte        in[] = "\xe2\xb4\xb6\xf9\x48\x44\x02\x64"
                       "\x5c\x47\x80\x9e\xd5\xa8\x3a\x17"
                       "\xb3\x78\xcf\x85\x22\x41\x74\xd9"
                       "\xa0\x97\x39\x71\x62\xf1\x8e\x8f"
                       "\xf4";
    word32      inSz  = (word32)sizeof(in) - 1;
    word32      keySz = (word32)sizeof(key);
    int         type  = WC_CMAC_AES;

    XMEMSET(&cmac, 0, sizeof(Cmac));

    ExpectIntEQ(wc_InitCmac(&cmac, key, keySz, type, NULL), 0);
    ExpectIntEQ(wc_CmacUpdate(&cmac, in, inSz), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_CmacUpdate(NULL, in, inSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CmacUpdate(&cmac, NULL, 30), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_AesFree(&cmac.aes);
#endif
    return EXPECT_RESULT();
} /* END test_wc_CmacUpdate */


/*
 * Testing wc_CmacFinal()
 */
static int test_wc_CmacFinal(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_128)
    Cmac        cmac;
    byte        key[] = {
        0x64, 0x4c, 0xbf, 0x12, 0x85, 0x9d, 0xf0, 0x55,
        0x7e, 0xa9, 0x1f, 0x08, 0xe0, 0x51, 0xff, 0x27
    };
    byte        msg[] = {
        0xe2, 0xb4, 0xb6, 0xf9, 0x48, 0x44, 0x02, 0x64,
        0x5c, 0x47, 0x80, 0x9e, 0xd5, 0xa8, 0x3a, 0x17,
        0xb3, 0x78, 0xcf, 0x85, 0x22, 0x41, 0x74, 0xd9,
        0xa0, 0x97, 0x39, 0x71, 0x62, 0xf1, 0x8e, 0x8f,
        0xf4
    };
    /* Test vectors from CMACGenAES128.rsp from
     * http://csrc.nist.gov/groups/STM/cavp/block-cipher-modes.html#cmac
     * Per RFC4493 truncation of lsb is possible.
     */
    byte        expMac[] = {
        0x4e, 0x6e, 0xc5, 0x6f, 0xf9, 0x5d, 0x0e, 0xae,
        0x1c, 0xf8, 0x3e, 0xfc, 0xf4, 0x4b, 0xeb
    };
    byte        mac[AES_BLOCK_SIZE];
    word32      msgSz    = (word32)sizeof(msg);
    word32      keySz    = (word32)sizeof(key);
    word32      macSz    = sizeof(mac);
    word32      badMacSz = 17;
    int         expMacSz = sizeof(expMac);
    int         type     = WC_CMAC_AES;

    XMEMSET(&cmac, 0, sizeof(Cmac));
    XMEMSET(mac, 0, macSz);

    ExpectIntEQ(wc_InitCmac(&cmac, key, keySz, type, NULL), 0);
    ExpectIntEQ(wc_CmacUpdate(&cmac, msg, msgSz), 0);

#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
    /* Pass in bad args. */
    ExpectIntEQ(wc_CmacFinalNoFree(NULL, mac, &macSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CmacFinalNoFree(&cmac, NULL, &macSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CmacFinalNoFree(&cmac, mac, &badMacSz), WC_NO_ERR_TRACE(BUFFER_E));

    /* For the last call, use the API with implicit wc_CmacFree(). */
    ExpectIntEQ(wc_CmacFinal(&cmac, mac, &macSz), 0);
    ExpectIntEQ(XMEMCMP(mac, expMac, expMacSz), 0);
#else /* !HAVE_FIPS || FIPS>=5.3 */
    ExpectIntEQ(wc_CmacFinal(&cmac, mac, &macSz), 0);
    ExpectIntEQ(XMEMCMP(mac, expMac, expMacSz), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_CmacFinal(NULL, mac, &macSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CmacFinal(&cmac, NULL, &macSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CmacFinal(&cmac, mac, &badMacSz), WC_NO_ERR_TRACE(BUFFER_E));
#endif /* !HAVE_FIPS || FIPS>=5.3 */
#endif
    return EXPECT_RESULT();
} /* END test_wc_CmacFinal */


/*
 * Testing wc_AesCmacGenerate() && wc_AesCmacVerify()
 */
static int test_wc_AesCmacGenerate(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_128)
    byte        key[] = {
        0x26, 0xef, 0x8b, 0x40, 0x34, 0x11, 0x7d, 0x9e,
        0xbe, 0xc0, 0xc7, 0xfc, 0x31, 0x08, 0x54, 0x69
    };
    byte        msg[]    = "\x18\x90\x49\xef\xfd\x7c\xf9\xc8"
                           "\xf3\x59\x65\xbc\xb0\x97\x8f\xd4";
    byte        expMac[] = "\x29\x5f\x2f\x71\xfc\x58\xe6\xf6"
                           "\x3d\x32\x65\x4c\x66\x23\xc5";
    byte        mac[AES_BLOCK_SIZE];
    word32      keySz    = sizeof(key);
    word32      macSz    = sizeof(mac);
    word32      msgSz    = sizeof(msg) - 1;
    word32      expMacSz = sizeof(expMac) - 1;

    XMEMSET(mac, 0, macSz);

    ExpectIntEQ(wc_AesCmacGenerate(mac, &macSz, msg, msgSz, key, keySz), 0);
    ExpectIntEQ(XMEMCMP(mac, expMac, expMacSz), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_AesCmacGenerate(NULL, &macSz, msg, msgSz, key, keySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCmacGenerate(mac, &macSz, msg, msgSz, NULL, keySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCmacGenerate(mac, &macSz, msg, msgSz, key, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCmacGenerate(mac, &macSz, NULL, msgSz, key, keySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_AesCmacVerify(mac, macSz, msg, msgSz, key, keySz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_AesCmacVerify(NULL, macSz, msg, msgSz, key, keySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCmacVerify(mac, 0, msg, msgSz, key, keySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCmacVerify(mac, macSz, msg, msgSz, NULL, keySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCmacVerify(mac, macSz, msg, msgSz, key, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCmacVerify(mac, macSz, NULL, msgSz, key, keySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();

} /* END test_wc_AesCmacGenerate */


/*
 * Testing streaming AES-GCM API.
 */
static int test_wc_AesGcmStream(void)
{
    EXPECT_DECLS;
#if !defined(NO_AES) && defined(WOLFSSL_AES_128) && defined(HAVE_AESGCM) && \
    defined(WOLFSSL_AESGCM_STREAM)
    int i;
    WC_RNG rng[1];
    Aes aesEnc[1];
    Aes aesDec[1];
    byte tag[AES_BLOCK_SIZE];
    byte in[AES_BLOCK_SIZE * 3 + 2] = { 0, };
    byte out[AES_BLOCK_SIZE * 3 + 2];
    byte plain[AES_BLOCK_SIZE * 3 + 2];
    byte aad[AES_BLOCK_SIZE * 3 + 2] = { 0, };
    byte key[AES_128_KEY_SIZE] = { 0, };
    byte iv[AES_IV_SIZE] = { 1, };
    byte ivOut[AES_IV_SIZE];
    static const byte expTagAAD1[AES_BLOCK_SIZE] = {
        0x6c, 0x35, 0xe6, 0x7f, 0x59, 0x9e, 0xa9, 0x2f,
        0x27, 0x2d, 0x5f, 0x8e, 0x7e, 0x42, 0xd3, 0x05
    };
    static const byte expTagPlain1[AES_BLOCK_SIZE] = {
        0x24, 0xba, 0x57, 0x95, 0xd0, 0x27, 0x9e, 0x78,
        0x3a, 0x88, 0x4c, 0x0a, 0x5d, 0x50, 0x23, 0xd1
    };
    static const byte expTag[AES_BLOCK_SIZE] = {
        0x22, 0x91, 0x70, 0xad, 0x42, 0xc3, 0xad, 0x96,
        0xe0, 0x31, 0x57, 0x60, 0xb7, 0x92, 0xa3, 0x6d
    };

    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(&aesEnc, 0, sizeof(Aes));
    XMEMSET(&aesDec, 0, sizeof(Aes));

    /* Create a random for generating IV/nonce. */
    ExpectIntEQ(wc_InitRng(rng), 0);

    /* Initialize data structures. */
    ExpectIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0);

    /* BadParameters to streaming init. */
    ExpectIntEQ(wc_AesGcmEncryptInit(NULL, NULL, 0, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptInit(NULL, NULL, 0, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptInit(aesEnc, NULL, AES_128_KEY_SIZE, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptInit(aesEnc, NULL, 0, NULL, GCM_NONCE_MID_SZ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Bad parameters to encrypt update. */
    ExpectIntEQ(wc_AesGcmEncryptUpdate(NULL, NULL, NULL, 0, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 1, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, in, 1, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out, NULL, 1, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, NULL, 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Bad parameters to decrypt update. */
    ExpectIntEQ(wc_AesGcmDecryptUpdate(NULL, NULL, NULL, 0, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 1, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, in, 1, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, out, NULL, 1, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, NULL, 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Bad parameters to encrypt final. */
    ExpectIntEQ(wc_AesGcmEncryptFinal(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncryptFinal(NULL, tag, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncryptFinal(NULL, NULL, AES_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, NULL, AES_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE + 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Bad parameters to decrypt final. */
    ExpectIntEQ(wc_AesGcmDecryptFinal(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptFinal(NULL, tag, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptFinal(NULL, NULL, AES_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, NULL, AES_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE + 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Check calling final before setting key fails. */
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, sizeof(tag)), WC_NO_ERR_TRACE(MISSING_KEY));
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesDec, tag, sizeof(tag)), WC_NO_ERR_TRACE(MISSING_KEY));
    /* Check calling update before setting key else fails. */
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, aad, 1),
        WC_NO_ERR_TRACE(MISSING_KEY));
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, aad, 1),
        WC_NO_ERR_TRACE(MISSING_KEY));

    /* Set key but not IV. */
    ExpectIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), NULL, 0), 0);
    ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), NULL, 0), 0);
    /* Check calling final before setting IV fails. */
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, sizeof(tag)), WC_NO_ERR_TRACE(MISSING_IV));
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesDec, tag, sizeof(tag)), WC_NO_ERR_TRACE(MISSING_IV));
    /* Check calling update before setting IV else fails. */
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, aad, 1),
        WC_NO_ERR_TRACE(MISSING_IV));
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, aad, 1),
        WC_NO_ERR_TRACE(MISSING_IV));

    /* Set IV using fixed part IV and external IV APIs. */
    ExpectIntEQ(wc_AesGcmSetIV(aesEnc, GCM_NONCE_MID_SZ, iv, AES_IV_FIXED_SZ,
        rng), 0);
    ExpectIntEQ(wc_AesGcmEncryptInit_ex(aesEnc, NULL, 0, ivOut,
        GCM_NONCE_MID_SZ), 0);
    ExpectIntEQ(wc_AesGcmSetExtIV(aesDec, ivOut, GCM_NONCE_MID_SZ), 0);
    ExpectIntEQ(wc_AesGcmInit(aesDec, NULL, 0, NULL, 0), 0);
    /* Encrypt and decrypt data. */
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out, in, 1, aad, 1), 0);
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, plain, out, 1, aad, 1), 0);
    ExpectIntEQ(XMEMCMP(plain, in, 1), 0);
    /* Finalize and check tag matches. */
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);

    /* Set key and IV through streaming init API. */
    wc_AesFree(aesEnc);
    wc_AesFree(aesDec);
    ExpectIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0);
    ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0);
    /* Encrypt/decrypt one block and AAD of one block. */
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out, in, AES_BLOCK_SIZE, aad,
        AES_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, plain, out, AES_BLOCK_SIZE, aad,
        AES_BLOCK_SIZE), 0);
    ExpectIntEQ(XMEMCMP(plain, in, AES_BLOCK_SIZE), 0);
    /* Finalize and check tag matches. */
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);

    /* Set key and IV through streaming init API. */
    wc_AesFree(aesEnc);
    wc_AesFree(aesDec);
    ExpectIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0);
    ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0);
    /* No data to encrypt/decrypt one byte of AAD. */
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, aad, 1), 0);
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, aad, 1), 0);
    /* Finalize and check tag matches. */
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
    ExpectIntEQ(XMEMCMP(tag, expTagAAD1, AES_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);

    /* Set key and IV through streaming init API. */
    wc_AesFree(aesEnc);
    wc_AesFree(aesDec);
    ExpectIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0);
    ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0);
    /* Encrypt/decrypt one byte and no AAD. */
    ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out, in, 1, NULL, 0), 0);
    ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, plain, out, 1, NULL, 0), 0);
    ExpectIntEQ(XMEMCMP(plain, in, 1), 0);
    /* Finalize and check tag matches. */
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
    ExpectIntEQ(XMEMCMP(tag, expTagPlain1, AES_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);

    /* Set key and IV through streaming init API. */
    wc_AesFree(aesEnc);
    wc_AesFree(aesDec);
    ExpectIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0);
    ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0);
    /* Encryption AES is one byte at a time */
    for (i = 0; i < (int)sizeof(aad); i++) {
        ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, aad + i, 1),
            0);
    }
    for (i = 0; i < (int)sizeof(in); i++) {
        ExpectIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out + i, in + i, 1, NULL, 0),
            0);
    }
    /* Decryption AES is two bytes at a time */
    for (i = 0; i < (int)sizeof(aad); i += 2) {
        ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, aad + i, 2),
            0);
    }
    for (i = 0; i < (int)sizeof(aad); i += 2) {
        ExpectIntEQ(wc_AesGcmDecryptUpdate(aesDec, plain + i, out + i, 2, NULL,
            0), 0);
    }
    ExpectIntEQ(XMEMCMP(plain, in, sizeof(in)), 0);
    /* Finalize and check tag matches. */
    ExpectIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
    ExpectIntEQ(XMEMCMP(tag, expTag, AES_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);

    /* Check streaming encryption can be decrypted with one shot. */
    wc_AesFree(aesDec);
    ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0);
    ExpectIntEQ(wc_AesGcmSetKey(aesDec, key, sizeof(key)), 0);
    ExpectIntEQ(wc_AesGcmDecrypt(aesDec, plain, out, sizeof(in), iv,
        AES_IV_SIZE, tag, AES_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(XMEMCMP(plain, in, sizeof(in)), 0);

    wc_AesFree(aesEnc);
    wc_AesFree(aesDec);
    wc_FreeRng(rng);
#endif
    return EXPECT_RESULT();
} /* END test_wc_AesGcmStream */


/*
 * Testing streaming SM4 API.
 */
static int test_wc_Sm4(void)
{
    int res = TEST_SKIPPED;
#ifdef WOLFSSL_SM4
    EXPECT_DECLS;
    wc_Sm4 sm4;
#if defined(WOLFSSL_SM4_ECB) || defined(WOLFSSL_SM4_CBC) || \
    defined(WOLFSSL_SM4_CTR) || defined(WOLFSSL_SM4_CCM)
    unsigned char key[SM4_KEY_SIZE];
#endif
#if defined(WOLFSSL_SM4_CBC) || defined(WOLFSSL_SM4_CTR)
    unsigned char iv[SM4_IV_SIZE];
#endif

    /* Invalid parameters - wc_Sm4Init */
    ExpectIntEQ(wc_Sm4Init(NULL, NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid cases - wc_Sm4Init */
    ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0);

#if defined(WOLFSSL_SM4_ECB) || defined(WOLFSSL_SM4_CBC) || \
    defined(WOLFSSL_SM4_CTR) || defined(WOLFSSL_SM4_CCM)
    XMEMSET(key, 0, sizeof(key));

    /* Invalid parameters - wc_Sm4SetKey. */
    ExpectIntEQ(wc_Sm4SetKey(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetKey(&sm4, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetKey(NULL, key, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetKey(NULL, NULL, SM4_KEY_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetKey(&sm4, key, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetKey(&sm4, NULL, SM4_KEY_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetKey(NULL, key, SM4_KEY_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE-1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE+1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid cases - wc_Sm4SetKey. */
    ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0);
#endif

#if defined(WOLFSSL_SM4_CBC) || defined(WOLFSSL_SM4_CTR)
    XMEMSET(iv, 0, sizeof(iv));

    /* Invalid parameters - wc_Sm4SetIV. */
    ExpectIntEQ(wc_Sm4SetIV(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetIV(&sm4, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4SetIV(NULL, iv), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid cases - wc_Sm4SetIV. */
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
#endif

    /* Valid cases - wc_Sm4Free */
    wc_Sm4Free(NULL);
    wc_Sm4Free(&sm4);

    res = EXPECT_RESULT();
#endif
    return res;
} /* END test_wc_Sm4 */

/*
 * Testing block based SM4-ECB API.
 */
static int test_wc_Sm4Ecb(void)
{
    int res = TEST_SKIPPED;
#ifdef WOLFSSL_SM4_ECB
    EXPECT_DECLS;
    wc_Sm4 sm4;
    unsigned char key[SM4_KEY_SIZE];
    unsigned char in[SM4_BLOCK_SIZE * 2];
    unsigned char out[SM4_BLOCK_SIZE * 2];
    unsigned char out2[SM4_BLOCK_SIZE];

    XMEMSET(key, 0, sizeof(key));
    XMEMSET(in, 0, sizeof(in));

    ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, in, 0), WC_NO_ERR_TRACE(MISSING_KEY));
    ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, in, 0), WC_NO_ERR_TRACE(MISSING_KEY));

    /* Tested in test_wc_Sm4. */
    ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0);

    /* Invalid parameters - wc_Sm4EcbEncrypt. */
    ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, out, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, NULL, in, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, out, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, NULL, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, in, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid cases - wc_Sm4EcbEncrypt. */
    ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, in, 0), 0);
    ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0);
    /*   In and out are same pointer. */
    ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, in, in, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0);

    /* Invalid parameters - wc_Sm4EcbDecrypt. */
    ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, out, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, NULL, in, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, out, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, NULL, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, in, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid cases - wc_Sm4EcbDecrypt. */
    ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, in, 0), 0);
    ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0);
    /*   In and out are same pointer. */
    ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, in, in, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0);

    wc_Sm4Free(&sm4);

    res = EXPECT_RESULT();
#endif
    return res;
} /* END test_wc_Sm4Ecb */

/*
 * Testing block based SM4-CBC API.
 */
static int test_wc_Sm4Cbc(void)
{
    int res = TEST_SKIPPED;
#ifdef WOLFSSL_SM4_CBC
    EXPECT_DECLS;
    wc_Sm4 sm4;
    unsigned char key[SM4_KEY_SIZE];
    unsigned char iv[SM4_IV_SIZE];
    unsigned char in[SM4_BLOCK_SIZE * 2];
    unsigned char out[SM4_BLOCK_SIZE * 2];
    unsigned char out2[SM4_BLOCK_SIZE];

    XMEMSET(key, 0, sizeof(key));
    XMEMSET(iv, 0, sizeof(iv));
    XMEMSET(in, 0, sizeof(in));

    ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, 0), WC_NO_ERR_TRACE(MISSING_KEY));
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, 0), WC_NO_ERR_TRACE(MISSING_KEY));
    /* Tested in test_wc_Sm4. */
    ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0);
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, 0), WC_NO_ERR_TRACE(MISSING_IV));
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, 0), WC_NO_ERR_TRACE(MISSING_IV));
    /* Tested in test_wc_Sm4. */
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);

    /* Invalid parameters - wc_Sm4CbcEncrypt. */
    ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, out, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, NULL, in, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, out, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, NULL, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid cases - wc_Sm4CbcEncrypt. */
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, 0), 0);
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0);
    /*   In and out are same pointer. */
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, in, in, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0);

    /* Invalid parameters - wc_Sm4CbcDecrypt. */
    ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, NULL, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, out, NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, NULL, in, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, out, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, NULL, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    /* Valid cases - wc_Sm4CbcDecrypt. */
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, 0), 0);
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0);
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0);
    /*   In and out are same pointer. */
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, in, in, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0);

    wc_Sm4Free(&sm4);

    res = EXPECT_RESULT();
#endif
    return res;
} /* END test_wc_Sm4Cbc */

/*
 * Testing streaming SM4-CTR API.
 */
static int test_wc_Sm4Ctr(void)
{
    int res = TEST_SKIPPED;
#ifdef WOLFSSL_SM4_CTR
    EXPECT_DECLS;
    wc_Sm4 sm4;
    unsigned char key[SM4_KEY_SIZE];
    unsigned char iv[SM4_IV_SIZE];
    unsigned char in[SM4_BLOCK_SIZE * 4];
    unsigned char out[SM4_BLOCK_SIZE * 4];
    unsigned char out2[SM4_BLOCK_SIZE * 4];
    word32 chunk;
    word32 i;

    XMEMSET(key, 0, sizeof(key));
    XMEMSET(iv, 0, sizeof(iv));
    XMEMSET(in, 0, sizeof(in));

    ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, 0), WC_NO_ERR_TRACE(MISSING_KEY));
    /* Tested in test_wc_Sm4. */
    ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0);
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, 0), WC_NO_ERR_TRACE(MISSING_IV));
    /* Tested in test_wc_Sm4. */
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);

    /* Invalid parameters - wc_Sm4CtrEncrypt. */
    ExpectIntEQ(wc_Sm4CtrEncrypt(NULL, NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CtrEncrypt(NULL, out, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CtrEncrypt(NULL, NULL, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, NULL, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CtrEncrypt(NULL, out, in, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid cases - wc_Sm4CtrEncrypt. */
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, 0), 0);
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out2, in, 1), 0);
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, 2), 0);
    ExpectIntEQ(XMEMCMP(out, out2, 1), 0);
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0);
    ExpectIntEQ(XMEMCMP(out2, out, 2), 0);
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0);
    /*   In and out are same pointer. Also check encrypt of cipher text produces
     *   plaintext.
     */
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, out, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0);

    /* Chunking tests. */
    ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
    ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out2, in, (word32)sizeof(in)), 0);
    for (chunk = 1; chunk <= SM4_BLOCK_SIZE + 1; chunk++) {
        ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
        for (i = 0; i + chunk <= (word32)sizeof(in); i += chunk) {
             ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out + i, in + i, chunk), 0);
        }
        if (i < (word32)sizeof(in)) {
             ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out + i, in + i,
                 (word32)sizeof(in) - i), 0);
        }
        ExpectIntEQ(XMEMCMP(out, out2, (word32)sizeof(out)), 0);
    }

    for (i = 0; i < (word32)sizeof(iv); i++) {
        iv[i] = 0xff;
        ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
        ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0);
        ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0);
        ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out2, out, SM4_BLOCK_SIZE * 2), 0);
        ExpectIntEQ(XMEMCMP(out2, in, SM4_BLOCK_SIZE * 2), 0);
    }

    wc_Sm4Free(&sm4);

    res = EXPECT_RESULT();
#endif
    return res;
} /* END test_wc_Sm4Ctr */

/*
 * Testing stream SM4-GCM API.
 */
static int test_wc_Sm4Gcm(void)
{
    int res = TEST_SKIPPED;
#ifdef WOLFSSL_SM4_GCM
    EXPECT_DECLS;
    wc_Sm4 sm4;
    unsigned char key[SM4_KEY_SIZE];
    unsigned char nonce[GCM_NONCE_MAX_SZ];
    unsigned char in[SM4_BLOCK_SIZE * 2];
    unsigned char in2[SM4_BLOCK_SIZE * 2];
    unsigned char out[SM4_BLOCK_SIZE * 2];
    unsigned char out2[SM4_BLOCK_SIZE * 2];
    unsigned char dec[SM4_BLOCK_SIZE * 2];
    unsigned char tag[SM4_BLOCK_SIZE];
    unsigned char aad[SM4_BLOCK_SIZE * 2];
    word32 i;

    XMEMSET(key, 0, sizeof(key));
    XMEMSET(nonce, 0, sizeof(nonce));
    XMEMSET(in, 0, sizeof(in));
    XMEMSET(in2, 0, sizeof(in2));
    XMEMSET(aad, 0, sizeof(aad));

    ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 0, nonce, GCM_NONCE_MID_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(MISSING_KEY));
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 0, nonce, GCM_NONCE_MID_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(MISSING_KEY));

    /* Invalid parameters - wc_Sm4GcmSetKey. */
    ExpectIntEQ(wc_Sm4GcmSetKey(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmSetKey(&sm4, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmSetKey(NULL, key, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmSetKey(NULL, NULL, SM4_KEY_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmSetKey(&sm4, key, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmSetKey(&sm4, NULL, SM4_KEY_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmSetKey(NULL, key, SM4_KEY_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid parameters - wc_Sm4GcmSetKey. */
    ExpectIntEQ(wc_Sm4GcmSetKey(&sm4, key, SM4_KEY_SIZE), 0);

    /* Invalid parameters - wc_Sm4GcmEncrypt. */
    ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, NULL, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, NULL, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, out, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, NULL, in, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, NULL, NULL, 1, nonce, GCM_NONCE_MID_SZ,
        NULL, 0, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, NULL, NULL, 1, NULL, 0, tag,
        SM4_BLOCK_SIZE, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, NULL, in, 1, nonce, GCM_NONCE_MID_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, NULL, 1, nonce, GCM_NONCE_MID_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, NULL, GCM_NONCE_MID_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce, 0, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ,
        NULL, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag,
        WOLFSSL_MIN_AUTH_TAG_SZ-1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag,
        SM4_BLOCK_SIZE+1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Invalid parameters - wc_Sm4GcmDecrypt. */
    ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, NULL, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, NULL, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, out, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, NULL, in, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, NULL, NULL, 1, nonce, GCM_NONCE_MID_SZ,
        NULL, 0, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, NULL, NULL, 1, NULL, 0, tag,
        SM4_BLOCK_SIZE, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, NULL, in, 1, nonce, GCM_NONCE_MID_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, NULL, 1, nonce, GCM_NONCE_MID_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, NULL, GCM_NONCE_MID_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, nonce, 0, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ,
        NULL, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag,
        WOLFSSL_MIN_AUTH_TAG_SZ-1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag,
        SM4_BLOCK_SIZE+1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid cases - wc_Sm4GcmEncrypt/wc_Sm4GcmDecrypt. */
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, NULL, NULL, 0, nonce, GCM_NONCE_MID_SZ,
        tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, NULL, NULL, 0, nonce, GCM_NONCE_MID_SZ,
        tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, NULL, NULL, 0, nonce, GCM_NONCE_MID_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, NULL, NULL, 0, nonce, GCM_NONCE_MID_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 1), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 1), 0);
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE * 2, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, in2, in2, SM4_BLOCK_SIZE * 2, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(XMEMCMP(in2, out, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in2, in2, SM4_BLOCK_SIZE * 2, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(XMEMCMP(in2, in, SM4_BLOCK_SIZE * 2), 0);

    /* Check vald values of nonce - wc_Sm4GcmEncrypt/wc_Sm4GcmDecrypt. */
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
        GCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
        GCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2, nonce,
        GCM_NONCE_MIN_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE * 2, nonce,
        GCM_NONCE_MIN_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE * 2, nonce,
        GCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)),
        WC_NO_ERR_TRACE(SM4_GCM_AUTH_E));

    /* Check valid values of tag size - wc_Sm4GcmEncrypt/wc_Sm4GcmDecrypt. */
    for (i = WOLFSSL_MIN_AUTH_TAG_SZ; i < SM4_BLOCK_SIZE; i++) {
        ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
            GCM_NONCE_MID_SZ, tag, i, aad, sizeof(aad)), 0);
        ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
            GCM_NONCE_MID_SZ, tag, i, aad, sizeof(aad)), 0);
    }

    /* Check different in/out sizes. */
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 0, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 0, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce,
        GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    for (i = 2; i <= SM4_BLOCK_SIZE * 2; i++) {
        XMEMCPY(out2, out, i - 1);
        ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, i, nonce, GCM_NONCE_MID_SZ,
            tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
        ExpectIntEQ(XMEMCMP(out, out2, i - 1), 0);
        ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, dec, out, i, nonce, GCM_NONCE_MID_SZ,
            tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
        ExpectIntEQ(XMEMCMP(in, dec, i), 0);
    }

    /* Force the counter to roll over in first byte. */
    {
        static unsigned char largeIn[256 * SM4_BLOCK_SIZE];
        static unsigned char largeOut[256 * SM4_BLOCK_SIZE];

        ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, largeOut, largeIn, sizeof(largeIn),
            nonce, GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
        ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, largeOut, largeOut, sizeof(largeIn),
            nonce, GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
        ExpectIntEQ(XMEMCMP(largeOut, largeIn, sizeof(largeIn)), 0);
    }

    wc_Sm4Free(&sm4);

    res = EXPECT_RESULT();
#endif
    return res;
} /* END test_wc_Sm4Gcm */

/*
 * Testing stream SM4-CCM API.
 */
static int test_wc_Sm4Ccm(void)
{
    int res = TEST_SKIPPED;
#ifdef WOLFSSL_SM4_CCM
    EXPECT_DECLS;
    wc_Sm4 sm4;
    unsigned char key[SM4_KEY_SIZE];
    unsigned char nonce[CCM_NONCE_MAX_SZ];
    unsigned char in[SM4_BLOCK_SIZE * 2];
    unsigned char in2[SM4_BLOCK_SIZE * 2];
    unsigned char out[SM4_BLOCK_SIZE * 2];
    unsigned char out2[SM4_BLOCK_SIZE * 2];
    unsigned char dec[SM4_BLOCK_SIZE * 2];
    unsigned char tag[SM4_BLOCK_SIZE];
    unsigned char aad[SM4_BLOCK_SIZE * 2];
    word32 i;

    XMEMSET(key, 0, sizeof(key));
    XMEMSET(nonce, 0, sizeof(nonce));
    XMEMSET(in, 0, sizeof(in));
    XMEMSET(in2, 0, sizeof(in2));
    XMEMSET(aad, 0, sizeof(aad));

    ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 0, nonce, CCM_NONCE_MAX_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(MISSING_KEY));
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 0, nonce, CCM_NONCE_MAX_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(MISSING_KEY));
    ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0);

    /* Invalid parameters - wc_Sm4CcmEncrypt. */
    ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, NULL, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, NULL, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, out, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, NULL, in, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, NULL, NULL, 1, nonce, CCM_NONCE_MAX_SZ,
        NULL, 0, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, NULL, NULL, 1, NULL, 0, tag,
        SM4_BLOCK_SIZE, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, NULL, in, 1, nonce, CCM_NONCE_MAX_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, NULL, 1, nonce, CCM_NONCE_MAX_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, NULL, CCM_NONCE_MAX_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce, 0, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ,
        NULL, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag,
        WOLFSSL_MIN_AUTH_TAG_SZ-1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag,
        SM4_BLOCK_SIZE+1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Invalid parameters - wc_Sm4CcmDecrypt. */
    ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, NULL, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, NULL, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, out, NULL, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, NULL, in, 1, NULL, 0, NULL, 0, NULL,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, NULL, NULL, 1, nonce, CCM_NONCE_MAX_SZ,
        NULL, 0, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, NULL, NULL, 1, NULL, 0, tag,
        SM4_BLOCK_SIZE, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, NULL, in, 1, nonce, CCM_NONCE_MAX_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, NULL, 1, nonce, CCM_NONCE_MAX_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, NULL, CCM_NONCE_MAX_SZ, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, nonce, 0, tag,
        SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ,
        NULL, SM4_BLOCK_SIZE, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag,
        WOLFSSL_MIN_AUTH_TAG_SZ - 1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag,
        SM4_BLOCK_SIZE + 1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Valid cases - wc_Sm4CcmEncrypt/wc_Sm4CcmDecrypt. */
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, NULL, NULL, 0, nonce, CCM_NONCE_MAX_SZ,
        tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, NULL, NULL, 0, nonce, CCM_NONCE_MAX_SZ,
        tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, NULL, NULL, 0, nonce, CCM_NONCE_MAX_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, NULL, NULL, 0, nonce, CCM_NONCE_MAX_SZ,
        tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 1), 0);
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 1), 0);
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE * 2, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, in2, in2, SM4_BLOCK_SIZE * 2, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(XMEMCMP(in2, out, SM4_BLOCK_SIZE * 2), 0);
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in2, in2, SM4_BLOCK_SIZE * 2, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    ExpectIntEQ(XMEMCMP(in2, in, SM4_BLOCK_SIZE * 2), 0);

    /* Check vald values of nonce - wc_Sm4CcmEncrypt/wc_Sm4CcmDecrypt. */
    for (i = CCM_NONCE_MIN_SZ; i <= CCM_NONCE_MAX_SZ; i++) {
        ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
            i, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
        ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
            i, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
    }
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
        CCM_NONCE_MIN_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)),
        WC_NO_ERR_TRACE(SM4_CCM_AUTH_E));

    /* Check invalid values of tag size - wc_Sm4CcmEncrypt/wc_Sm4CcmDecrypt. */
    for (i = 0; i < 4; i++) {
        ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
            CCM_NONCE_MAX_SZ, tag, i * 2 + 1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
            CCM_NONCE_MAX_SZ, tag, i * 2 + 1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    }
    /*   Odd values in range 4..SM4_BLOCK_SIZE. */
    for (i = 2; i < SM4_BLOCK_SIZE / 2; i++) {
        ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
            CCM_NONCE_MAX_SZ, tag, i * 2 + 1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
            CCM_NONCE_MAX_SZ, tag, i * 2 + 1, aad, sizeof(aad)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    }
    /* Check valid values of tag size - wc_Sm4CcmEncrypt/wc_Sm4CcmDecrypt.
     * Even values in range 4..SM4_BLOCK_SIZE.
     */
    for (i = 2; i < SM4_BLOCK_SIZE / 2; i++) {
        ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce,
            CCM_NONCE_MAX_SZ, tag, i * 2, aad, sizeof(aad)), 0);
        ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce,
            CCM_NONCE_MAX_SZ, tag, i * 2, aad, sizeof(aad)), 0);
    }

    /* Check different in/out sizes. */
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 0, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 0, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce,
        CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0);
    for (i = 2; i <= SM4_BLOCK_SIZE * 2; i++) {
        XMEMCPY(out2, out, i - 1);
        ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, i, nonce, CCM_NONCE_MAX_SZ,
            tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
        ExpectIntEQ(XMEMCMP(out, out2, i - 1), 0);
        ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, dec, out, i, nonce, CCM_NONCE_MAX_SZ,
            tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
        ExpectIntEQ(XMEMCMP(in, dec, i), 0);
    }

    /* Force the counter to roll over in first byte. */
    {
        static unsigned char largeIn[256 * SM4_BLOCK_SIZE];
        static unsigned char largeOut[256 * SM4_BLOCK_SIZE];

        ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, largeOut, largeIn, sizeof(largeIn),
            nonce, CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
        ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, largeOut, largeOut, sizeof(largeIn),
            nonce, CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0);
        ExpectIntEQ(XMEMCMP(largeOut, largeIn, sizeof(largeIn)), 0);
    }

    wc_Sm4Free(&sm4);

    res = EXPECT_RESULT();
#endif
    return res;
} /* END test_wc_Sm4Ccm */


/*
 * unit test for wc_Des3_SetIV()
 */
static int test_wc_Des3_SetIV(void)
{
    EXPECT_DECLS;
#ifndef NO_DES3
    Des3 des;
    const byte key[] = {
        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
        0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
        0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
    };
    const byte iv[] = {
        0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
        0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
        0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
    };

    XMEMSET(&des, 0, sizeof(Des3));

    ExpectIntEQ(wc_Des3Init(&des, NULL, INVALID_DEVID), 0);

    /* DES_ENCRYPTION or DES_DECRYPTION */
    ExpectIntEQ(wc_Des3_SetKey(&des, key, iv, DES_ENCRYPTION), 0);
    ExpectIntEQ(XMEMCMP(iv, des.reg, DES_BLOCK_SIZE), 0);

#ifndef HAVE_FIPS /* no sanity checks with FIPS wrapper */
    /* Test explicitly wc_Des3_SetIV()  */
    ExpectIntEQ(wc_Des3_SetIV(NULL, iv), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_SetIV(&des, NULL), 0);
#endif
    wc_Des3Free(&des);
#endif
    return EXPECT_RESULT();

} /* END test_wc_Des3_SetIV */

/*
 * unit test for wc_Des3_SetKey()
 */
static int test_wc_Des3_SetKey(void)
{
    EXPECT_DECLS;
#ifndef NO_DES3
    Des3 des;
    const byte key[] = {
        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
        0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
        0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
    };
    const byte iv[] = {
        0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
        0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
        0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
    };

    XMEMSET(&des, 0, sizeof(Des3));

    ExpectIntEQ(wc_Des3Init(&des, NULL, INVALID_DEVID), 0);

    /* DES_ENCRYPTION or DES_DECRYPTION */
    ExpectIntEQ(wc_Des3_SetKey(&des, key, iv, DES_ENCRYPTION), 0);
    ExpectIntEQ(XMEMCMP(iv, des.reg, DES_BLOCK_SIZE), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Des3_SetKey(NULL, key, iv, DES_ENCRYPTION), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_SetKey(&des, NULL, iv, DES_ENCRYPTION), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_SetKey(&des, key, iv, -1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Default case. Should return 0. */
    ExpectIntEQ(wc_Des3_SetKey(&des, key, NULL, DES_ENCRYPTION), 0);

    wc_Des3Free(&des);
#endif
    return EXPECT_RESULT();

} /* END test_wc_Des3_SetKey */


/*
 * Test function for wc_Des3_CbcEncrypt and wc_Des3_CbcDecrypt
 */
static int test_wc_Des3_CbcEncryptDecrypt(void)
{
    EXPECT_DECLS;
#ifndef NO_DES3
    Des3 des;
    byte cipher[24];
    byte plain[24];
    const byte key[] = {
        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
        0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
        0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
    };
    const byte iv[] = {
        0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
        0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
        0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
    };
    const byte vector[] = { /* "Now is the time for all " w/o trailing 0 */
        0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
        0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
        0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
    };

    XMEMSET(&des, 0, sizeof(Des3));

    ExpectIntEQ(wc_Des3Init(&des, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_Des3_SetKey(&des, key, iv, DES_ENCRYPTION), 0);

    ExpectIntEQ(wc_Des3_CbcEncrypt(&des, cipher, vector, 24), 0);
    ExpectIntEQ(wc_Des3_SetKey(&des, key, iv, DES_DECRYPTION), 0);
    ExpectIntEQ(wc_Des3_CbcDecrypt(&des, plain, cipher, 24), 0);
    ExpectIntEQ(XMEMCMP(plain, vector, 24), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_Des3_CbcEncrypt(NULL, cipher, vector, 24), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcEncrypt(&des, NULL, vector, 24), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcEncrypt(&des, cipher, NULL, sizeof(vector)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_Des3_CbcDecrypt(NULL, plain, cipher, 24), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcDecrypt(&des, NULL, cipher, 24), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcDecrypt(&des, plain, NULL, 24), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Des3Free(&des);
#endif
    return EXPECT_RESULT();

} /* END wc_Des3_CbcEncrypt */

/*
 *  Unit test for wc_Des3_CbcEncryptWithKey and wc_Des3_CbcDecryptWithKey
 */
static int test_wc_Des3_CbcEncryptDecryptWithKey(void)
{
    EXPECT_DECLS;
#ifndef NO_DES3
    word32 vectorSz, cipherSz;
    byte cipher[24];
    byte plain[24];
    byte vector[] = { /* Now is the time for all w/o trailing 0 */
        0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
        0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
        0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
    };
    byte key[] = {
        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
        0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
        0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
    };
    byte iv[] = {
        0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
        0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
        0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
    };

    vectorSz = sizeof(byte) * 24;
    cipherSz = sizeof(byte) * 24;

    ExpectIntEQ(wc_Des3_CbcEncryptWithKey(cipher, vector, vectorSz, key, iv),
        0);
    ExpectIntEQ(wc_Des3_CbcDecryptWithKey(plain, cipher, cipherSz, key, iv), 0);
    ExpectIntEQ(XMEMCMP(plain, vector, 24), 0);

    /* pass in bad args. */
    ExpectIntEQ(wc_Des3_CbcEncryptWithKey(NULL, vector, vectorSz, key, iv),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcEncryptWithKey(cipher, NULL, vectorSz, key, iv),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcEncryptWithKey(cipher, vector, vectorSz, NULL, iv),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcEncryptWithKey(cipher, vector, vectorSz, key, NULL),
        0);

    ExpectIntEQ(wc_Des3_CbcDecryptWithKey(NULL, cipher, cipherSz, key, iv),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcDecryptWithKey(plain, NULL, cipherSz, key, iv),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcDecryptWithKey(plain, cipher, cipherSz, NULL, iv),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_CbcDecryptWithKey(plain, cipher, cipherSz, key, NULL),
        0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Des3_CbcEncryptDecryptWithKey */
/*
 *  Unit test for wc_Des3_EcbEncrypt
 */
static int test_wc_Des3_EcbEncrypt(void)
{
    EXPECT_DECLS;
#if !defined(NO_DES3) && defined(WOLFSSL_DES_ECB)
    Des3    des;
    byte    cipher[24];
    word32  cipherSz = sizeof(cipher);
    const byte key[] = {
        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
        0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
        0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
    };
    const byte iv[] = {
        0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
        0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
        0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
    };
    const byte vector[] = { /* "Now is the time for all " w/o trailing 0 */
        0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
        0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
        0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
    };

    XMEMSET(&des, 0, sizeof(Des3));

    ExpectIntEQ(wc_Des3Init(&des, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_Des3_SetKey(&des, key, iv, DES_ENCRYPTION), 0);

    /* Bad Cases */
    ExpectIntEQ(wc_Des3_EcbEncrypt(NULL, 0, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_EcbEncrypt(NULL, cipher, vector, cipherSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_EcbEncrypt(&des, 0, vector, cipherSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_EcbEncrypt(&des, cipher, NULL, cipherSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Des3_EcbEncrypt(&des, cipher, vector, 0), 0);

    /* Good Cases */
    ExpectIntEQ(wc_Des3_EcbEncrypt(&des, cipher, vector, cipherSz), 0);

    wc_Des3Free(&des);
#endif
    return EXPECT_RESULT();
} /* END test_wc_Des3_EcbEncrypt */

/*
 * Testing wc_Chacha_SetKey() and wc_Chacha_SetIV()
 */
static int test_wc_Chacha_SetKey(void)
{
    EXPECT_DECLS;
#ifdef HAVE_CHACHA
    ChaCha     ctx;
    const byte key[] = {
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
    };
    word32 keySz = (word32)(sizeof(key)/sizeof(byte));
    byte       cipher[128];

    XMEMSET(cipher, 0, sizeof(cipher));
    ExpectIntEQ(wc_Chacha_SetKey(&ctx, key, keySz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_Chacha_SetKey(NULL, key, keySz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Chacha_SetKey(&ctx, key, 18), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_Chacha_SetIV(&ctx, cipher, 0), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_Chacha_SetIV(NULL, cipher, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_Chacha_SetKey */

/*
 * unit test for wc_Poly1305SetKey()
 */
static int test_wc_Poly1305SetKey(void)
{
    EXPECT_DECLS;
#ifdef HAVE_POLY1305
    Poly1305    ctx;
    const byte  key[] =
    {
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
    };
    word32 keySz = (word32)(sizeof(key)/sizeof(byte));

    ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, keySz), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_Poly1305SetKey(NULL, key,keySz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Poly1305SetKey(&ctx, NULL, keySz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, 18), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_Poly1305_SetKey() */

/*
 * Testing wc_Chacha_Process()
 */
static int test_wc_Chacha_Process(void)
{
    EXPECT_DECLS;
#ifdef HAVE_CHACHA
    ChaCha      enc, dec;
    byte        cipher[128];
    byte        plain[128];
    const byte  key[] =
    {
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
    };
    const char* input = "Everybody gets Friday off.";
    word32      keySz = sizeof(key)/sizeof(byte);
    unsigned long int inlen = XSTRLEN(input);

    /* Initialize stack variables. */
    XMEMSET(cipher, 0, 128);
    XMEMSET(plain, 0, 128);

    ExpectIntEQ(wc_Chacha_SetKey(&enc, key, keySz), 0);
    ExpectIntEQ(wc_Chacha_SetKey(&dec, key, keySz), 0);
    ExpectIntEQ(wc_Chacha_SetIV(&enc, cipher, 0), 0);
    ExpectIntEQ(wc_Chacha_SetIV(&dec, cipher, 0), 0);

    ExpectIntEQ(wc_Chacha_Process(&enc, cipher, (byte*)input, (word32)inlen),
        0);
    ExpectIntEQ(wc_Chacha_Process(&dec, plain, cipher, (word32)inlen), 0);
    ExpectIntEQ(XMEMCMP(input, plain, inlen), 0);

#if !defined(USE_INTEL_CHACHA_SPEEDUP) && !defined(WOLFSSL_ARMASM)
    /* test checking and using leftovers, currently just in C code */
    ExpectIntEQ(wc_Chacha_SetIV(&enc, cipher, 0), 0);
    ExpectIntEQ(wc_Chacha_SetIV(&dec, cipher, 0), 0);

    ExpectIntEQ(wc_Chacha_Process(&enc, cipher, (byte*)input,
        (word32)inlen - 2), 0);
    ExpectIntEQ(wc_Chacha_Process(&enc, cipher + (inlen - 2),
        (byte*)input + (inlen - 2), 2), 0);
    ExpectIntEQ(wc_Chacha_Process(&dec, plain, (byte*)cipher,
        (word32)inlen - 2), 0);
    ExpectIntEQ(wc_Chacha_Process(&dec, cipher + (inlen - 2),
        (byte*)input + (inlen - 2), 2), 0);
    ExpectIntEQ(XMEMCMP(input, plain, inlen), 0);

    /* check edge cases with counter increment */
    {
        /* expected results collected from wolfSSL 4.3.0 encrypted in one call*/
        const byte expected[] = {
            0x54,0xB1,0xE2,0xD4,0xA2,0x4D,0x52,0x5F,
            0x42,0x04,0x89,0x7C,0x6E,0x2D,0xFC,0x2D,
            0x10,0x25,0xB6,0x92,0x71,0xD5,0xC3,0x20,
            0xE3,0x0E,0xEC,0xF4,0xD8,0x10,0x70,0x29,
            0x2D,0x4C,0x2A,0x56,0x21,0xE1,0xC7,0x37,
            0x0B,0x86,0xF5,0x02,0x8C,0xB8,0xB8,0x38,
            0x41,0xFD,0xDF,0xD9,0xC3,0xE6,0xC8,0x88,
            0x06,0x82,0xD4,0x80,0x6A,0x50,0x69,0xD5,
            0xB9,0xB0,0x2F,0x44,0x36,0x5D,0xDA,0x5E,
            0xDE,0xF6,0xF5,0xFC,0x44,0xDC,0x07,0x51,
            0xA7,0x32,0x42,0xDB,0xCC,0xBD,0xE2,0xE5,
            0x0B,0xB1,0x14,0xFF,0x12,0x80,0x16,0x43,
            0xE7,0x40,0xD5,0xEA,0xC7,0x3F,0x69,0x07,
            0x64,0xD4,0x86,0x6C,0xE2,0x1F,0x8F,0x6E,
            0x35,0x41,0xE7,0xD3,0xB5,0x5D,0xD6,0xD4,
            0x9F,0x00,0xA9,0xAE,0x3D,0x28,0xA5,0x37,
            0x80,0x3D,0x11,0x25,0xE2,0xB6,0x99,0xD9,
            0x9B,0x98,0xE9,0x37,0xB9,0xF8,0xA0,0x04,
            0xDF,0x13,0x49,0x3F,0x19,0x6A,0x45,0x06,
            0x21,0xB4,0xC7,0x3B,0x49,0x45,0xB4,0xC8,
            0x03,0x5B,0x43,0x89,0xBD,0xB3,0x96,0x4B,
            0x17,0x6F,0x85,0xC6,0xCF,0xA6,0x05,0x35,
            0x1E,0x25,0x03,0xBB,0x55,0x0A,0xD5,0x54,
            0x41,0xEA,0xEB,0x50,0x40,0x1B,0x43,0x19,
            0x59,0x1B,0x0E,0x12,0x3E,0xA2,0x71,0xC3,
            0x1A,0xA7,0x11,0x50,0x43,0x9D,0x56,0x3B,
            0x63,0x2F,0x63,0xF1,0x8D,0xAE,0xF3,0x23,
            0xFA,0x1E,0xD8,0x6A,0xE1,0xB2,0x4B,0xF3,
            0xB9,0x13,0x7A,0x72,0x2B,0x6D,0xCC,0x41,
            0x1C,0x69,0x7C,0xCD,0x43,0x6F,0xE4,0xE2,
            0x38,0x99,0xFB,0xC3,0x38,0x92,0x62,0x35,
            0xC0,0x1D,0x60,0xE4,0x4B,0xDD,0x0C,0x14
        };
        const byte iv2[] = {
            0x9D,0xED,0xE7,0x0F,0xEC,0x81,0x51,0xD9,
            0x77,0x39,0x71,0xA6,0x21,0xDF,0xB8,0x93
        };
        byte input2[256];
        int i;

        for (i = 0; i < 256; i++)
            input2[i] = (byte)i;

        ExpectIntEQ(wc_Chacha_SetIV(&enc, iv2, 0), 0);

        ExpectIntEQ(wc_Chacha_Process(&enc, cipher, input2, 64), 0);
        ExpectIntEQ(XMEMCMP(expected, cipher, 64), 0);

        ExpectIntEQ(wc_Chacha_Process(&enc, cipher, input2 + 64, 128), 0);
        ExpectIntEQ(XMEMCMP(expected + 64, cipher, 128), 0);

        /* partial */
        ExpectIntEQ(wc_Chacha_Process(&enc, cipher, input2 + 192, 32), 0);
        ExpectIntEQ(XMEMCMP(expected + 192, cipher, 32), 0);

        ExpectIntEQ(wc_Chacha_Process(&enc, cipher, input2 + 224, 32), 0);
        ExpectIntEQ(XMEMCMP(expected + 224, cipher, 32), 0);
    }
#endif

    /* Test bad args. */
    ExpectIntEQ(wc_Chacha_Process(NULL, cipher, (byte*)input, (word32)inlen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_Chacha_Process */

/*
 * Testing wc_ChaCha20Poly1305_Encrypt() and wc_ChaCha20Poly1305_Decrypt()
 */
static int test_wc_ChaCha20Poly1305_aead(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
    const byte  key[] = {
        0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
        0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
        0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
        0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
    };
    const byte  plaintext[] = {
        0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,
        0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
        0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
        0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
        0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
        0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
        0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
        0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
        0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
        0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
        0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,
        0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
        0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
        0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
        0x74, 0x2e
    };
    const byte  iv[] = {
        0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43,
        0x44, 0x45, 0x46, 0x47
    };
    const byte  aad[] = { /* additional data */
        0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
        0xc4, 0xc5, 0xc6, 0xc7
    };
    const byte  cipher[] = { /* expected output from operation */
        0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb,
        0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
        0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
        0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
        0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12,
        0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
        0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,
        0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
        0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
        0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
        0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94,
        0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
        0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,
        0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
        0x61, 0x16
    };
    const byte  authTag[] = { /* expected output from operation */
        0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
        0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
    };
    byte        generatedCiphertext[272];
    byte        generatedPlaintext[272];
    byte        generatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE];

    /* Initialize stack variables. */
    XMEMSET(generatedCiphertext, 0, 272);
    XMEMSET(generatedPlaintext, 0, 272);

    /* Test Encrypt */
    ExpectIntEQ(wc_ChaCha20Poly1305_Encrypt(key, iv, aad, sizeof(aad),
        plaintext, sizeof(plaintext), generatedCiphertext, generatedAuthTag),
        0);
    ExpectIntEQ(XMEMCMP(generatedCiphertext, cipher,
        sizeof(cipher)/sizeof(byte)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_ChaCha20Poly1305_Encrypt(NULL, iv, aad, sizeof(aad),
        plaintext, sizeof(plaintext), generatedCiphertext, generatedAuthTag),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Encrypt(key, NULL, aad, sizeof(aad),
        plaintext, sizeof(plaintext), generatedCiphertext, generatedAuthTag),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Encrypt(key, iv, aad, sizeof(aad), NULL,
        sizeof(plaintext), generatedCiphertext, generatedAuthTag),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Encrypt(key, iv, aad, sizeof(aad),
        NULL, sizeof(plaintext), generatedCiphertext, generatedAuthTag),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Encrypt(key, iv, aad, sizeof(aad),
        plaintext, sizeof(plaintext), NULL, generatedAuthTag), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Encrypt(key, iv, aad, sizeof(aad),
        plaintext, sizeof(plaintext), generatedCiphertext, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad), cipher,
        sizeof(cipher), authTag, generatedPlaintext), 0);
    ExpectIntEQ(XMEMCMP(generatedPlaintext, plaintext,
        sizeof(plaintext)/sizeof(byte)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_ChaCha20Poly1305_Decrypt(NULL, iv, aad, sizeof(aad), cipher,
        sizeof(cipher), authTag, generatedPlaintext),  WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Decrypt(key, NULL, aad, sizeof(aad),
        cipher, sizeof(cipher), authTag, generatedPlaintext), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad), NULL,
        sizeof(cipher), authTag, generatedPlaintext), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad), cipher,
        sizeof(cipher), NULL, generatedPlaintext), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad), cipher,
        sizeof(cipher), authTag, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad), NULL,
        sizeof(cipher), authTag, generatedPlaintext), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_ChaCha20Poly1305_aead */


/*
 * Testing function for wc_Rc2SetKey().
 */
static int test_wc_Rc2SetKey(void)
{
    EXPECT_DECLS;
#ifdef WC_RC2
    Rc2  rc2;
    byte key40[] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
    byte iv[]    = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

    /* valid key and IV */
    ExpectIntEQ(wc_Rc2SetKey(&rc2, key40, (word32) sizeof(key40) / sizeof(byte),
        iv, 40), 0);
    /* valid key, no IV */
    ExpectIntEQ(wc_Rc2SetKey(&rc2, key40, (word32) sizeof(key40) / sizeof(byte),
        NULL, 40), 0);

    /* bad arguments  */
    /* null Rc2 struct */
    ExpectIntEQ(wc_Rc2SetKey(NULL, key40, (word32) sizeof(key40) / sizeof(byte),
        iv, 40), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null key */
    ExpectIntEQ(wc_Rc2SetKey(&rc2, NULL, (word32) sizeof(key40) / sizeof(byte),
        iv, 40), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* key size == 0 */
    ExpectIntEQ(wc_Rc2SetKey(&rc2, key40, 0, iv, 40), WC_NO_ERR_TRACE(WC_KEY_SIZE_E));
    /* key size > 128 */
    ExpectIntEQ(wc_Rc2SetKey(&rc2, key40, 129, iv, 40), WC_NO_ERR_TRACE(WC_KEY_SIZE_E));
    /* effective bits == 0 */
    ExpectIntEQ(wc_Rc2SetKey(&rc2, key40, (word32)sizeof(key40) / sizeof(byte),
        iv, 0), WC_NO_ERR_TRACE(WC_KEY_SIZE_E));
    /* effective bits > 1024 */
    ExpectIntEQ(wc_Rc2SetKey(&rc2, key40, (word32)sizeof(key40) / sizeof(byte),
        iv, 1025), WC_NO_ERR_TRACE(WC_KEY_SIZE_E));
#endif
    return EXPECT_RESULT();
} /* END test_wc_Rc2SetKey */

/*
 * Testing function for wc_Rc2SetIV().
 */
static int test_wc_Rc2SetIV(void)
{
    EXPECT_DECLS;
#ifdef WC_RC2
    Rc2  rc2;
    byte iv[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

    /* valid IV */
    ExpectIntEQ(wc_Rc2SetIV(&rc2, iv), 0);
    /* valid NULL IV */
    ExpectIntEQ(wc_Rc2SetIV(&rc2, NULL), 0);

    /* bad arguments */
    ExpectIntEQ(wc_Rc2SetIV(NULL, iv), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Rc2SetIV(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_Rc2SetIV */

/*
 * Testing function for wc_Rc2EcbEncrypt() and wc_Rc2EcbDecrypt().
 */
static int test_wc_Rc2EcbEncryptDecrypt(void)
{
    EXPECT_DECLS;
#ifdef WC_RC2
    Rc2 rc2;
    int effectiveKeyBits = 63;
    byte cipher[RC2_BLOCK_SIZE];
    byte plain[RC2_BLOCK_SIZE];
    byte key[]    = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    byte input[]  = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    byte output[] = { 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff };

    XMEMSET(cipher, 0, sizeof(cipher));
    XMEMSET(plain, 0, sizeof(plain));

    ExpectIntEQ(wc_Rc2SetKey(&rc2, key, (word32) sizeof(key) / sizeof(byte),
        NULL, effectiveKeyBits), 0);
    ExpectIntEQ(wc_Rc2EcbEncrypt(&rc2, cipher, input, RC2_BLOCK_SIZE), 0);
    ExpectIntEQ(XMEMCMP(cipher, output, RC2_BLOCK_SIZE), 0);

    ExpectIntEQ(wc_Rc2EcbDecrypt(&rc2, plain, cipher, RC2_BLOCK_SIZE), 0);
    ExpectIntEQ(XMEMCMP(plain, input, RC2_BLOCK_SIZE), 0);

    /* Rc2EcbEncrypt bad arguments */
    /* null Rc2 struct */
    ExpectIntEQ(wc_Rc2EcbEncrypt(NULL, cipher, input, RC2_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null out buffer */
    ExpectIntEQ(wc_Rc2EcbEncrypt(&rc2, NULL, input, RC2_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null input buffer */
    ExpectIntEQ(wc_Rc2EcbEncrypt(&rc2, cipher, NULL, RC2_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* output buffer sz != RC2_BLOCK_SIZE (8) */
    ExpectIntEQ(wc_Rc2EcbEncrypt(&rc2, cipher, input, 7), WC_NO_ERR_TRACE(BUFFER_E));

    /* Rc2EcbDecrypt bad arguments */
    /* null Rc2 struct */
    ExpectIntEQ(wc_Rc2EcbDecrypt(NULL, plain, output, RC2_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null out buffer */
    ExpectIntEQ(wc_Rc2EcbDecrypt(&rc2, NULL, output, RC2_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null input buffer */
    ExpectIntEQ(wc_Rc2EcbDecrypt(&rc2, plain, NULL, RC2_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* output buffer sz != RC2_BLOCK_SIZE (8) */
    ExpectIntEQ(wc_Rc2EcbDecrypt(&rc2, plain, output, 7), WC_NO_ERR_TRACE(BUFFER_E));
#endif
    return EXPECT_RESULT();
} /* END test_wc_Rc2EcbEncryptDecrypt */

/*
 * Testing function for wc_Rc2CbcEncrypt() and wc_Rc2CbcDecrypt().
 */
static int test_wc_Rc2CbcEncryptDecrypt(void)
{
    EXPECT_DECLS;
#ifdef WC_RC2
    Rc2 rc2;
    int effectiveKeyBits = 63;
    byte cipher[RC2_BLOCK_SIZE*2];
    byte plain[RC2_BLOCK_SIZE*2];
    /* vector taken from test.c */
    byte key[] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    byte iv[] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    byte input[] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    byte output[] = {
        0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff,
        0xf0, 0x51, 0x77, 0x8b, 0x65, 0xdb, 0x13, 0x57
    };

    XMEMSET(cipher, 0, sizeof(cipher));
    XMEMSET(plain, 0, sizeof(plain));

    ExpectIntEQ(wc_Rc2SetKey(&rc2, key, (word32) sizeof(key) / sizeof(byte),
        iv, effectiveKeyBits), 0);
    ExpectIntEQ(wc_Rc2CbcEncrypt(&rc2, cipher, input, sizeof(input)), 0);
    ExpectIntEQ(XMEMCMP(cipher, output, sizeof(output)), 0);

    /* reset IV for decrypt */
    ExpectIntEQ(wc_Rc2SetIV(&rc2, iv), 0);
    ExpectIntEQ(wc_Rc2CbcDecrypt(&rc2, plain, cipher, sizeof(cipher)), 0);
    ExpectIntEQ(XMEMCMP(plain, input, sizeof(input)), 0);

    /* Rc2CbcEncrypt bad arguments */
    /* null Rc2 struct */
    ExpectIntEQ(wc_Rc2CbcEncrypt(NULL, cipher, input, sizeof(input)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null out buffer */
    ExpectIntEQ(wc_Rc2CbcEncrypt(&rc2, NULL, input, sizeof(input)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null input buffer */
    ExpectIntEQ(wc_Rc2CbcEncrypt(&rc2, cipher, NULL, sizeof(input)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Rc2CbcDecrypt bad arguments */
    /* in size is 0 */
    ExpectIntEQ(wc_Rc2CbcDecrypt(&rc2, plain, output, 0), 0);
    /* null Rc2 struct */
    ExpectIntEQ(wc_Rc2CbcDecrypt(NULL, plain, output, sizeof(output)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null out buffer */
    ExpectIntEQ(wc_Rc2CbcDecrypt(&rc2, NULL, output, sizeof(output)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null input buffer */
    ExpectIntEQ(wc_Rc2CbcDecrypt(&rc2, plain, NULL, sizeof(output)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_Rc2CbcEncryptDecrypt */


/*
 * Testing function for wc_AesSetIV
 */
static int test_wc_AesSetIV(void)
{
    int res = TEST_SKIPPED;
#if !defined(NO_AES) && defined(WOLFSSL_AES_128)
    Aes     aes;
    int     ret = 0;
    byte    key16[] =
    {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
    byte    iv1[]    = "1234567890abcdef";
    byte    iv2[]    = "0987654321fedcba";

    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
    if (ret != 0)
        return ret;

    ret = wc_AesSetKey(&aes, key16, (word32) sizeof(key16) / sizeof(byte),
                                                     iv1, AES_ENCRYPTION);
    if (ret == 0) {
        ret = wc_AesSetIV(&aes, iv2);
    }
    /* Test bad args. */
    if (ret == 0) {
        ret = wc_AesSetIV(NULL, iv1);
        if (ret == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
            /* NULL iv should return 0. */
            ret = wc_AesSetIV(&aes, NULL);
        }
        else {
            ret = WOLFSSL_FATAL_ERROR;
        }
    }

    wc_AesFree(&aes);

    res = TEST_RES_CHECK(ret == 0);
#endif
    return res;
} /* test_wc_AesSetIV */


/*
 * Testing function for wc_AesSetKey().
 */
static int test_wc_AesSetKey(void)
{
    EXPECT_DECLS;
#ifndef NO_AES
    Aes  aes;
    byte key16[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
#ifdef WOLFSSL_AES_192
    byte key24[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
    };
#endif
#ifdef WOLFSSL_AES_256
    byte key32[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
#endif
    byte badKey16[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65
    };
    byte iv[] = "1234567890abcdef";

    XMEMSET(&aes, 0, sizeof(Aes));

    ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);

#ifdef WOLFSSL_AES_128
    ExpectIntEQ(wc_AesSetKey(&aes, key16, (word32)sizeof(key16) / sizeof(byte),
        iv, AES_ENCRYPTION), 0);
#endif
#ifdef WOLFSSL_AES_192
    ExpectIntEQ(wc_AesSetKey(&aes, key24, (word32)sizeof(key24) / sizeof(byte),
        iv, AES_ENCRYPTION), 0);
#endif
#ifdef WOLFSSL_AES_256
    ExpectIntEQ(wc_AesSetKey(&aes, key32, (word32)sizeof(key32) / sizeof(byte),
        iv, AES_ENCRYPTION), 0);
#endif

    /* Pass in bad args. */
    ExpectIntEQ(wc_AesSetKey(NULL, key16, (word32)sizeof(key16) / sizeof(byte),
        iv, AES_ENCRYPTION), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesSetKey(&aes, badKey16,
        (word32)sizeof(badKey16) / sizeof(byte), iv, AES_ENCRYPTION),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_AesFree(&aes);
#endif
    return EXPECT_RESULT();
} /* END test_wc_AesSetKey */



/*
 * test function for wc_AesCbcEncrypt(), wc_AesCbcDecrypt(),
 * and wc_AesCbcDecryptWithKey()
 */
static int test_wc_AesCbcEncryptDecrypt(void)
{
    EXPECT_DECLS;
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT)&& \
    defined(WOLFSSL_AES_256)
    Aes  aes;
    byte key32[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
    byte vector[] = { /* Now is the time for all good men w/o trailing 0 */
        0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
        0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
        0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20,
        0x67, 0x6f, 0x6f, 0x64, 0x20, 0x6d, 0x65, 0x6e
    };
    byte    iv[]   = "1234567890abcdef";
    byte    enc[sizeof(vector)];
    byte    dec[sizeof(vector)];
    byte    dec2[sizeof(vector)];

    /* Init stack variables. */
    XMEMSET(&aes, 0, sizeof(Aes));
    XMEMSET(enc, 0, sizeof(enc));
    XMEMSET(dec, 0, sizeof(vector));
    XMEMSET(dec2, 0, sizeof(vector));

    ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv,
        AES_ENCRYPTION), 0);
    ExpectIntEQ(wc_AesCbcEncrypt(&aes, enc, vector, sizeof(vector)), 0);

    /* Re init for decrypt and set flag. */
    ExpectIntEQ(wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv,
        AES_DECRYPTION), 0);
    ExpectIntEQ(wc_AesCbcDecrypt(&aes, dec, enc, sizeof(vector)), 0);
    ExpectIntEQ(XMEMCMP(vector, dec, sizeof(vector)), 0);

    ExpectIntEQ(wc_AesCbcDecryptWithKey(dec2, enc, AES_BLOCK_SIZE, key32,
        sizeof(key32)/sizeof(byte), iv), 0);
    ExpectIntEQ(XMEMCMP(vector, dec2, AES_BLOCK_SIZE), 0);

    /* Pass in bad args */
    ExpectIntEQ(wc_AesCbcEncrypt(NULL, enc, vector, sizeof(vector)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCbcEncrypt(&aes, NULL, vector, sizeof(vector)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCbcEncrypt(&aes, enc, NULL, sizeof(vector)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
    ExpectIntEQ(wc_AesCbcEncrypt(&aes, enc, vector, sizeof(vector) - 1),
        WC_NO_ERR_TRACE(BAD_LENGTH_E));
#endif
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
    (HAVE_FIPS_VERSION == 2) && defined(WOLFSSL_AESNI)
    fprintf(stderr, "Zero length inputs not supported with AESNI in FIPS "
                    "mode (v2), skip test");
#else
    /* Test passing in size of 0  */
    XMEMSET(enc, 0, sizeof(enc));
    ExpectIntEQ(wc_AesCbcEncrypt(&aes, enc, vector, 0), 0);
    /* Check enc was not modified */
    {
        int i;
        for (i = 0; i < (int)sizeof(enc); i++)
            ExpectIntEQ(enc[i], 0);
    }
#endif

    ExpectIntEQ(wc_AesCbcDecrypt(NULL, dec, enc, AES_BLOCK_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCbcDecrypt(&aes, NULL, enc, AES_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCbcDecrypt(&aes, dec, NULL, AES_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
    ExpectIntEQ(wc_AesCbcDecrypt(&aes, dec, enc, AES_BLOCK_SIZE * 2 - 1),
        WC_NO_ERR_TRACE(BAD_LENGTH_E));
#else
    ExpectIntEQ(wc_AesCbcDecrypt(&aes, dec, enc, AES_BLOCK_SIZE * 2 - 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    /* Test passing in size of 0  */
    XMEMSET(dec, 0, sizeof(dec));
    ExpectIntEQ(wc_AesCbcDecrypt(&aes, dec, enc, 0), 0);
    /* Check dec was not modified */
    {
        int i;
        for (i = 0; i < (int)sizeof(dec); i++)
            ExpectIntEQ(dec[i], 0);
    }

    ExpectIntEQ(wc_AesCbcDecryptWithKey(NULL, enc, AES_BLOCK_SIZE,
        key32, sizeof(key32)/sizeof(byte), iv), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCbcDecryptWithKey(dec2, NULL, AES_BLOCK_SIZE,
        key32, sizeof(key32)/sizeof(byte), iv), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCbcDecryptWithKey(dec2, enc, AES_BLOCK_SIZE,
        NULL, sizeof(key32)/sizeof(byte), iv), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCbcDecryptWithKey(dec2, enc, AES_BLOCK_SIZE,
        key32, sizeof(key32)/sizeof(byte), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_AesFree(&aes);
#endif
    return EXPECT_RESULT();
} /* END test_wc_AesCbcEncryptDecrypt */

/*
 * Testing wc_AesCtrEncrypt and wc_AesCtrDecrypt
 */
static int test_wc_AesCtrEncryptDecrypt(void)
{
    EXPECT_DECLS;
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) && defined(WOLFSSL_AES_256)
    Aes aesEnc;
    Aes aesDec;
    byte key32[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
    byte vector[] = { /* Now is the time for all w/o trailing 0 */
        0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
        0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
        0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
    };
    byte iv[] = "1234567890abcdef";
    byte enc[AES_BLOCK_SIZE * 2];
    byte dec[AES_BLOCK_SIZE * 2];

    /* Init stack variables. */
    XMEMSET(&aesEnc, 0, sizeof(Aes));
    XMEMSET(&aesDec, 0, sizeof(Aes));
    XMEMSET(enc, 0, AES_BLOCK_SIZE * 2);
    XMEMSET(dec, 0, AES_BLOCK_SIZE * 2);

    ExpectIntEQ(wc_AesInit(&aesEnc, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesInit(&aesDec, NULL, INVALID_DEVID), 0);

    ExpectIntEQ(wc_AesSetKey(&aesEnc, key32, AES_BLOCK_SIZE * 2, iv,
        AES_ENCRYPTION), 0);
    ExpectIntEQ(wc_AesCtrEncrypt(&aesEnc, enc, vector,
        sizeof(vector)/sizeof(byte)), 0);
    /* Decrypt with wc_AesCtrEncrypt() */
    ExpectIntEQ(wc_AesSetKey(&aesDec, key32, AES_BLOCK_SIZE * 2, iv,
        AES_ENCRYPTION), 0);
    ExpectIntEQ(wc_AesCtrEncrypt(&aesDec, dec, enc, sizeof(enc)/sizeof(byte)),
        0);
    ExpectIntEQ(XMEMCMP(vector, dec, sizeof(vector)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_AesCtrEncrypt(NULL, dec, enc, sizeof(enc)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCtrEncrypt(&aesDec, NULL, enc, sizeof(enc)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCtrEncrypt(&aesDec, dec, NULL, sizeof(enc)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_AesFree(&aesEnc);
    wc_AesFree(&aesDec);
#endif
    return EXPECT_RESULT();
} /* END test_wc_AesCtrEncryptDecrypt */

/*
 * test function for wc_AesGcmSetKey()
 */
static int test_wc_AesGcmSetKey(void)
{
    EXPECT_DECLS;
#if  !defined(NO_AES) && defined(HAVE_AESGCM)
    Aes aes;
#ifdef WOLFSSL_AES_128
    byte key16[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
#endif
#ifdef WOLFSSL_AES_192
    byte key24[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
    };
#endif
#ifdef WOLFSSL_AES_256
    byte key32[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
#endif
    byte badKey16[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65
    };
    byte badKey24[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36
    };
    byte badKey32[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x37, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65
    };

    ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);

#ifdef WOLFSSL_AES_128
    ExpectIntEQ(wc_AesGcmSetKey(&aes, key16, sizeof(key16)/sizeof(byte)), 0);
#endif
#ifdef WOLFSSL_AES_192
    ExpectIntEQ(wc_AesGcmSetKey(&aes, key24, sizeof(key24)/sizeof(byte)), 0);
#endif
#ifdef WOLFSSL_AES_256
    ExpectIntEQ(wc_AesGcmSetKey(&aes, key32, sizeof(key32)/sizeof(byte)), 0);
#endif

    /* Pass in bad args. */
    ExpectIntEQ(wc_AesGcmSetKey(&aes, badKey16, sizeof(badKey16)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmSetKey(&aes, badKey24, sizeof(badKey24)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmSetKey(&aes, badKey32, sizeof(badKey32)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_AesFree(&aes);
#endif
    return EXPECT_RESULT();
} /* END test_wc_AesGcmSetKey */

/*
 * test function for wc_AesGcmEncrypt and wc_AesGcmDecrypt
 */
static int test_wc_AesGcmEncryptDecrypt(void)
{
    EXPECT_DECLS;
    /* WOLFSSL_AFALG requires 12 byte IV */
#if !defined(NO_AES) && defined(HAVE_AESGCM) && defined(WOLFSSL_AES_256) && \
    !defined(WOLFSSL_AFALG) && !defined(WOLFSSL_DEVCRYPTO_AES)
    Aes  aes;
    byte key32[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
    byte vector[] = { /* Now is the time for all w/o trailing 0 */
        0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
        0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
        0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
    };
    const byte a[] = {
        0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
        0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
        0xab, 0xad, 0xda, 0xd2
    };
    byte iv[] = "1234567890a";
    byte longIV[] = "1234567890abcdefghij";
    byte enc[sizeof(vector)];
    byte resultT[AES_BLOCK_SIZE];
    byte dec[sizeof(vector)];

    /* Init stack variables. */
    XMEMSET(&aes, 0, sizeof(Aes));
    XMEMSET(enc, 0, sizeof(vector));
    XMEMSET(dec, 0, sizeof(vector));
    XMEMSET(resultT, 0, AES_BLOCK_SIZE);

    ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);

    ExpectIntEQ(wc_AesGcmSetKey(&aes, key32, sizeof(key32)/sizeof(byte)), 0);
    ExpectIntEQ(wc_AesGcmEncrypt(&aes, enc, vector, sizeof(vector), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT), a, sizeof(a)), 0);
    ExpectIntEQ(wc_AesGcmDecrypt(&aes, dec, enc, sizeof(vector), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT), a, sizeof(a)), 0);
    ExpectIntEQ(XMEMCMP(vector, dec, sizeof(vector)), 0);

    /* Test bad args for wc_AesGcmEncrypt and wc_AesGcmDecrypt */
    ExpectIntEQ(wc_AesGcmEncrypt(NULL, enc, vector, sizeof(vector), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT), a, sizeof(a)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncrypt(&aes, enc, vector, sizeof(vector), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT) + 1, a, sizeof(a)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmEncrypt(&aes, enc, vector, sizeof(vector), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT) - 5, a, sizeof(a)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#if (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
        (HAVE_FIPS_VERSION == 2)) || defined(HAVE_SELFTEST) || \
        defined(WOLFSSL_AES_GCM_FIXED_IV_AAD)
        /* FIPS does not check the lower bound of ivSz */
#else
        ExpectIntEQ(wc_AesGcmEncrypt(&aes, enc, vector, sizeof(vector), iv, 0,
            resultT, sizeof(resultT), a, sizeof(a)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    /* This case is now considered good. Long IVs are now allowed.
     * Except for the original FIPS release, it still has an upper
     * bound on the IV length. */
#if (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))) && \
    !defined(WOLFSSL_AES_GCM_FIXED_IV_AAD)
    ExpectIntEQ(wc_AesGcmEncrypt(&aes, enc, vector, sizeof(vector), longIV,
        sizeof(longIV)/sizeof(byte), resultT, sizeof(resultT), a, sizeof(a)),
        0);
#else
    (void)longIV;
#endif /* Old FIPS */
    /* END wc_AesGcmEncrypt */

#ifdef HAVE_AES_DECRYPT
    ExpectIntEQ(wc_AesGcmDecrypt(NULL, dec, enc, sizeof(enc)/sizeof(byte), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT), a, sizeof(a)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecrypt(&aes, NULL, enc, sizeof(enc)/sizeof(byte), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT), a, sizeof(a)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecrypt(&aes, dec, NULL, sizeof(enc)/sizeof(byte), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT), a, sizeof(a)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecrypt(&aes, dec, enc, sizeof(enc)/sizeof(byte), NULL,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT), a, sizeof(a)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesGcmDecrypt(&aes, dec, enc, sizeof(enc)/sizeof(byte), iv,
        sizeof(iv)/sizeof(byte), NULL, sizeof(resultT), a, sizeof(a)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    #if (defined(HAVE_FIPS) && FIPS_VERSION_LE(2,0) && defined(WOLFSSL_ARMASM))
    ExpectIntEQ(wc_AesGcmDecrypt(&aes, dec, enc, sizeof(enc)/sizeof(byte), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT) + 1, a, sizeof(a)),
        WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
    #else
    ExpectIntEQ(wc_AesGcmDecrypt(&aes, dec, enc, sizeof(enc)/sizeof(byte), iv,
        sizeof(iv)/sizeof(byte), resultT, sizeof(resultT) + 1, a, sizeof(a)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    #endif
    #if ((defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
            (HAVE_FIPS_VERSION == 2)) || defined(HAVE_SELFTEST)) && \
            !defined(WOLFSSL_AES_GCM_FIXED_IV_AAD)
            /* FIPS does not check the lower bound of ivSz */
    #else
        ExpectIntEQ(wc_AesGcmDecrypt(&aes, dec, enc, sizeof(enc)/sizeof(byte),
            iv, 0, resultT, sizeof(resultT), a, sizeof(a)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    #endif
#endif /* HAVE_AES_DECRYPT */

    wc_AesFree(&aes);
#endif
    return EXPECT_RESULT();

} /* END test_wc_AesGcmEncryptDecrypt */

/*
 * test function for mixed (one-shot encrpytion + stream decryption) AES GCM
 * using a long IV (older FIPS does NOT support long IVs).  Relates to zd15423
 */
static int test_wc_AesGcmMixedEncDecLongIV(void)
{
    EXPECT_DECLS;
#if  (!defined(HAVE_FIPS) || \
      (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))) && \
     !defined(NO_AES) && defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM)
    const byte key[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
    const byte in[] = {
        0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
        0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
        0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
    };
    const byte aad[] = {
        0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
        0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
        0xab, 0xad, 0xda, 0xd2
    };
    Aes aesEnc;
    Aes aesDec;
    byte iv[] = "1234567890abcdefghij";
    byte out[sizeof(in)];
    byte plain[sizeof(in)];
    byte tag[AES_BLOCK_SIZE];

    XMEMSET(&aesEnc, 0, sizeof(Aes));
    XMEMSET(&aesDec, 0, sizeof(Aes));
    XMEMSET(out, 0, sizeof(out));
    XMEMSET(plain, 0, sizeof(plain));
    XMEMSET(tag, 0, sizeof(tag));

    /* Perform one-shot encryption using long IV */
    ExpectIntEQ(wc_AesInit(&aesEnc, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesGcmSetKey(&aesEnc, key, sizeof(key)), 0);
    ExpectIntEQ(wc_AesGcmEncrypt(&aesEnc, out, in, sizeof(in), iv, sizeof(iv),
        tag, sizeof(tag), aad, sizeof(aad)), 0);

    /* Perform streaming decryption using long IV */
    ExpectIntEQ(wc_AesInit(&aesDec, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesGcmInit(&aesDec, key, sizeof(key), iv, sizeof(iv)), 0);
    ExpectIntEQ(wc_AesGcmDecryptUpdate(&aesDec, plain, out, sizeof(out), aad,
        sizeof(aad)), 0);
    ExpectIntEQ(wc_AesGcmDecryptFinal(&aesDec, tag, sizeof(tag)), 0);
    ExpectIntEQ(XMEMCMP(plain, in, sizeof(in)), 0);

    /* Free resources */
    wc_AesFree(&aesEnc);
    wc_AesFree(&aesDec);
#endif
    return EXPECT_RESULT();

} /* END wc_AesGcmMixedEncDecLongIV */

/*
 * unit test for wc_GmacSetKey()
 */
static int test_wc_GmacSetKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_AES) && defined(HAVE_AESGCM)
    Gmac gmac;
    byte key16[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
#ifdef WOLFSSL_AES_192
    byte key24[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
    };
#endif
#ifdef WOLFSSL_AES_256
    byte key32[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
#endif
    byte badKey16[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x66
    };
    byte badKey24[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
    };
    byte badKey32[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };

    XMEMSET(&gmac, 0, sizeof(Gmac));

    ExpectIntEQ(wc_AesInit(&gmac.aes, NULL, INVALID_DEVID), 0);

#ifdef WOLFSSL_AES_128
    ExpectIntEQ(wc_GmacSetKey(&gmac, key16, sizeof(key16)/sizeof(byte)), 0);
#endif
#ifdef WOLFSSL_AES_192
    ExpectIntEQ(wc_GmacSetKey(&gmac, key24, sizeof(key24)/sizeof(byte)), 0);
#endif
#ifdef WOLFSSL_AES_256
    ExpectIntEQ(wc_GmacSetKey(&gmac, key32, sizeof(key32)/sizeof(byte)), 0);
#endif

    /* Pass in bad args. */
    ExpectIntEQ(wc_GmacSetKey(NULL, key16, sizeof(key16)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_GmacSetKey(&gmac, NULL, sizeof(key16)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_GmacSetKey(&gmac, badKey16, sizeof(badKey16)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_GmacSetKey(&gmac, badKey24, sizeof(badKey24)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_GmacSetKey(&gmac, badKey32, sizeof(badKey32)/sizeof(byte)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_AesFree(&gmac.aes);
#endif
    return EXPECT_RESULT();
} /* END test_wc_GmacSetKey */

/*
 * unit test for wc_GmacUpdate
 */
static int test_wc_GmacUpdate(void)
{
    EXPECT_DECLS;
#if !defined(NO_AES) && defined(HAVE_AESGCM)
    Gmac gmac;
#ifdef WOLFSSL_AES_128
    const byte key16[] = {
        0x89, 0xc9, 0x49, 0xe9, 0xc8, 0x04, 0xaf, 0x01,
        0x4d, 0x56, 0x04, 0xb3, 0x94, 0x59, 0xf2, 0xc8
    };
#endif
#ifdef WOLFSSL_AES_192
    byte key24[] = {
        0x41, 0xc5, 0xda, 0x86, 0x67, 0xef, 0x72, 0x52,
        0x20, 0xff, 0xe3, 0x9a, 0xe0, 0xac, 0x59, 0x0a,
        0xc9, 0xfc, 0xa7, 0x29, 0xab, 0x60, 0xad, 0xa0
    };
#endif
#ifdef WOLFSSL_AES_256
   byte key32[] = {
        0x78, 0xdc, 0x4e, 0x0a, 0xaf, 0x52, 0xd9, 0x35,
        0xc3, 0xc0, 0x1e, 0xea, 0x57, 0x42, 0x8f, 0x00,
        0xca, 0x1f, 0xd4, 0x75, 0xf5, 0xda, 0x86, 0xa4,
        0x9c, 0x8d, 0xd7, 0x3d, 0x68, 0xc8, 0xe2, 0x23
    };
#endif
#ifdef WOLFSSL_AES_128
    const byte authIn[] = {
        0x82, 0xad, 0xcd, 0x63, 0x8d, 0x3f, 0xa9, 0xd9,
        0xf3, 0xe8, 0x41, 0x00, 0xd6, 0x1e, 0x07, 0x77
    };
#endif
#ifdef WOLFSSL_AES_192
    const byte authIn2[] = {
       0x8b, 0x5c, 0x12, 0x4b, 0xef, 0x6e, 0x2f, 0x0f,
       0xe4, 0xd8, 0xc9, 0x5c, 0xd5, 0xfa, 0x4c, 0xf1
    };
#endif
    const byte authIn3[] = {
        0xb9, 0x6b, 0xaa, 0x8c, 0x1c, 0x75, 0xa6, 0x71,
        0xbf, 0xb2, 0xd0, 0x8d, 0x06, 0xbe, 0x5f, 0x36
    };
#ifdef WOLFSSL_AES_128
    const byte tag1[] = { /* Known. */
        0x88, 0xdb, 0x9d, 0x62, 0x17, 0x2e, 0xd0, 0x43,
        0xaa, 0x10, 0xf1, 0x6d, 0x22, 0x7d, 0xc4, 0x1b
    };
#endif
#ifdef WOLFSSL_AES_192
    const byte tag2[] = { /* Known */
        0x20, 0x4b, 0xdb, 0x1b, 0xd6, 0x21, 0x54, 0xbf,
        0x08, 0x92, 0x2a, 0xaa, 0x54, 0xee, 0xd7, 0x05
    };
#endif
    const byte tag3[] = { /* Known */
        0x3e, 0x5d, 0x48, 0x6a, 0xa2, 0xe3, 0x0b, 0x22,
        0xe0, 0x40, 0xb8, 0x57, 0x23, 0xa0, 0x6e, 0x76
    };
#ifdef WOLFSSL_AES_128
    const byte iv[] = {
        0xd1, 0xb1, 0x04, 0xc8, 0x15, 0xbf, 0x1e, 0x94,
        0xe2, 0x8c, 0x8f, 0x16
    };
#endif
#ifdef WOLFSSL_AES_192
    const byte iv2[] = {
        0x05, 0xad, 0x13, 0xa5, 0xe2, 0xc2, 0xab, 0x66,
        0x7e, 0x1a, 0x6f, 0xbc
    };
#endif
    const byte iv3[] = {
        0xd7, 0x9c, 0xf2, 0x2d, 0x50, 0x4c, 0xc7, 0x93,
        0xc3, 0xfb, 0x6c, 0x8a
    };
    byte tagOut[16];
    byte tagOut2[24];
    byte tagOut3[32];

    /* Init stack variables. */
    XMEMSET(&gmac, 0, sizeof(Gmac));
    XMEMSET(tagOut, 0, sizeof(tagOut));
    XMEMSET(tagOut2, 0, sizeof(tagOut2));
    XMEMSET(tagOut3, 0, sizeof(tagOut3));

#ifdef WOLFSSL_AES_128
    ExpectIntEQ(wc_AesInit(&gmac.aes, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_GmacSetKey(&gmac, key16, sizeof(key16)), 0);
    ExpectIntEQ(wc_GmacUpdate(&gmac, iv, sizeof(iv), authIn, sizeof(authIn),
        tagOut, sizeof(tag1)), 0);
    ExpectIntEQ(XMEMCMP(tag1, tagOut, sizeof(tag1)), 0);
    wc_AesFree(&gmac.aes);
#endif

#ifdef WOLFSSL_AES_192
    ExpectNotNull(XMEMSET(&gmac, 0, sizeof(Gmac)));
    ExpectIntEQ(wc_AesInit(&gmac.aes, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_GmacSetKey(&gmac, key24, sizeof(key24)/sizeof(byte)), 0);
    ExpectIntEQ(wc_GmacUpdate(&gmac, iv2, sizeof(iv2), authIn2, sizeof(authIn2),
        tagOut2, sizeof(tag2)), 0);
    ExpectIntEQ(XMEMCMP(tagOut2, tag2, sizeof(tag2)), 0);
    wc_AesFree(&gmac.aes);
#endif

#ifdef WOLFSSL_AES_256
    ExpectNotNull(XMEMSET(&gmac, 0, sizeof(Gmac)));
    ExpectIntEQ(wc_AesInit(&gmac.aes, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_GmacSetKey(&gmac, key32, sizeof(key32)/sizeof(byte)), 0);
    ExpectIntEQ(wc_GmacUpdate(&gmac, iv3, sizeof(iv3), authIn3, sizeof(authIn3),
        tagOut3, sizeof(tag3)), 0);
    ExpectIntEQ(XMEMCMP(tag3, tagOut3, sizeof(tag3)), 0);
    wc_AesFree(&gmac.aes);
#endif

    /* Pass bad args. */
    ExpectIntEQ(wc_AesInit(&gmac.aes, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_GmacUpdate(NULL, iv3, sizeof(iv3), authIn3, sizeof(authIn3),
        tagOut3, sizeof(tag3)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_GmacUpdate(&gmac, iv3, sizeof(iv3), authIn3, sizeof(authIn3),
        tagOut3, sizeof(tag3) - 5), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_GmacUpdate(&gmac, iv3, sizeof(iv3), authIn3, sizeof(authIn3),
        tagOut3, sizeof(tag3) + 1),  WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_AesFree(&gmac.aes);

#endif
    return EXPECT_RESULT();
} /* END test_wc_GmacUpdate */


/*
 * testing wc_CamelliaSetKey
 */
static int test_wc_CamelliaSetKey(void)
{
    EXPECT_DECLS;
#ifdef HAVE_CAMELLIA
    Camellia camellia;
    /*128-bit key*/
    static const byte key16[] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10
    };
    /* 192-bit key */
    static const byte key24[] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
    };
    /* 256-bit key */
    static const byte key32[] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
    };
    static const byte iv[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
    };

    ExpectIntEQ(wc_CamelliaSetKey(&camellia, key16, (word32)sizeof(key16), iv),
        0);
    ExpectIntEQ(wc_CamelliaSetKey(&camellia, key16, (word32)sizeof(key16),
        NULL), 0);
    ExpectIntEQ(wc_CamelliaSetKey(&camellia, key24, (word32)sizeof(key24), iv),
        0);
    ExpectIntEQ(wc_CamelliaSetKey(&camellia, key24, (word32)sizeof(key24),
        NULL), 0);
    ExpectIntEQ(wc_CamelliaSetKey(&camellia, key32, (word32)sizeof(key32), iv),
        0);
    ExpectIntEQ(wc_CamelliaSetKey(&camellia, key32, (word32)sizeof(key32),
        NULL), 0);

    /* Bad args. */
    ExpectIntEQ(wc_CamelliaSetKey(NULL, key32, (word32)sizeof(key32), iv),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_CammeliaSetKey */

/*
 * Testing wc_CamelliaSetIV()
 */
static int test_wc_CamelliaSetIV(void)
{
    EXPECT_DECLS;
#ifdef HAVE_CAMELLIA
    Camellia    camellia;
    static const byte iv[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
    };

    ExpectIntEQ(wc_CamelliaSetIV(&camellia, iv), 0);
    ExpectIntEQ(wc_CamelliaSetIV(&camellia, NULL), 0);

    /* Bad args. */
    ExpectIntEQ(wc_CamelliaSetIV(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CamelliaSetIV(NULL, iv), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_CamelliaSetIV*/

/*
 * Test wc_CamelliaEncryptDirect and wc_CamelliaDecryptDirect
 */
static int test_wc_CamelliaEncryptDecryptDirect(void)
{
    EXPECT_DECLS;
#ifdef HAVE_CAMELLIA
    Camellia camellia;
    static const byte key24[] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
    };
    static const byte iv[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
    };
    static const byte plainT[] = {
        0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
        0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A
    };
    byte    enc[sizeof(plainT)];
    byte    dec[sizeof(enc)];

    /* Init stack variables.*/
    XMEMSET(enc, 0, 16);
    XMEMSET(enc, 0, 16);

    ExpectIntEQ(wc_CamelliaSetKey(&camellia, key24, (word32)sizeof(key24), iv),
        0);
    ExpectIntEQ(wc_CamelliaEncryptDirect(&camellia, enc, plainT), 0);
    ExpectIntEQ(wc_CamelliaDecryptDirect(&camellia, dec, enc), 0);
    ExpectIntEQ(XMEMCMP(plainT, dec, CAMELLIA_BLOCK_SIZE), 0);

    /* Pass bad args. */
    ExpectIntEQ(wc_CamelliaEncryptDirect(NULL, enc, plainT), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CamelliaEncryptDirect(&camellia, NULL, plainT),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CamelliaEncryptDirect(&camellia, enc, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_CamelliaDecryptDirect(NULL, dec, enc), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CamelliaDecryptDirect(&camellia, NULL, enc), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CamelliaDecryptDirect(&camellia, dec, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test-wc_CamelliaEncryptDecryptDirect */

/*
 * Testing wc_CamelliaCbcEncrypt and wc_CamelliaCbcDecrypt
 */
static int test_wc_CamelliaCbcEncryptDecrypt(void)
{
    EXPECT_DECLS;
#ifdef HAVE_CAMELLIA
    Camellia camellia;
    static const byte key24[] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
    };
    static const byte plainT[] = {
        0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
        0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A
    };
    byte    enc[CAMELLIA_BLOCK_SIZE];
    byte    dec[CAMELLIA_BLOCK_SIZE];

    /* Init stack variables. */
    XMEMSET(enc, 0, CAMELLIA_BLOCK_SIZE);
    XMEMSET(enc, 0, CAMELLIA_BLOCK_SIZE);

    ExpectIntEQ(wc_CamelliaSetKey(&camellia, key24, (word32)sizeof(key24),
        NULL), 0);
    ExpectIntEQ(wc_CamelliaCbcEncrypt(&camellia, enc, plainT,
        CAMELLIA_BLOCK_SIZE), 0);

    ExpectIntEQ(wc_CamelliaSetKey(&camellia, key24, (word32)sizeof(key24),
        NULL), 0);
    ExpectIntEQ(wc_CamelliaCbcDecrypt(&camellia, dec, enc, CAMELLIA_BLOCK_SIZE),
        0);
    ExpectIntEQ(XMEMCMP(plainT, dec, CAMELLIA_BLOCK_SIZE), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_CamelliaCbcEncrypt(NULL, enc, plainT, CAMELLIA_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CamelliaCbcEncrypt(&camellia, NULL, plainT,
        CAMELLIA_BLOCK_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CamelliaCbcEncrypt(&camellia, enc, NULL,
        CAMELLIA_BLOCK_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_CamelliaCbcDecrypt(NULL, dec, enc, CAMELLIA_BLOCK_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CamelliaCbcDecrypt(&camellia, NULL, enc,
        CAMELLIA_BLOCK_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CamelliaCbcDecrypt(&camellia, dec, NULL,
        CAMELLIA_BLOCK_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();
} /* END test_wc_CamelliaCbcEncryptDecrypt */


/*
 * Testing wc_Arc4SetKey()
 */
static int test_wc_Arc4SetKey(void)
{
    EXPECT_DECLS;
#ifndef NO_RC4
    Arc4 arc;
    const char* key = "\x01\x23\x45\x67\x89\xab\xcd\xef";
    int keyLen = 8;

    ExpectIntEQ(wc_Arc4SetKey(&arc, (byte*)key, (word32)keyLen), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_Arc4SetKey(NULL, (byte*)key, (word32)keyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Arc4SetKey(&arc, NULL      , (word32)keyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Arc4SetKey(&arc, (byte*)key, 0     ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    return EXPECT_RESULT();

} /* END test_wc_Arc4SetKey */

/*
 * Testing wc_Arc4Process for ENC/DEC.
 */
static int test_wc_Arc4Process(void)
{
    EXPECT_DECLS;
#ifndef NO_RC4
    Arc4 enc;
    Arc4 dec;
    const char* key = "\x01\x23\x45\x67\x89\xab\xcd\xef";
    int keyLen = 8;
    const char* input = "\x01\x23\x45\x67\x89\xab\xcd\xef";
    byte cipher[8];
    byte plain[8];

    /* Init stack variables */
    XMEMSET(&enc, 0, sizeof(Arc4));
    XMEMSET(&dec, 0, sizeof(Arc4));
    XMEMSET(cipher, 0, sizeof(cipher));
    XMEMSET(plain, 0, sizeof(plain));

    /* Use for async. */
    ExpectIntEQ(wc_Arc4Init(&enc, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_Arc4Init(&dec, NULL, INVALID_DEVID), 0);

    ExpectIntEQ(wc_Arc4SetKey(&enc, (byte*)key, (word32)keyLen), 0);
    ExpectIntEQ(wc_Arc4SetKey(&dec, (byte*)key, (word32)keyLen), 0);

    ExpectIntEQ(wc_Arc4Process(&enc, cipher, (byte*)input, (word32)keyLen), 0);
    ExpectIntEQ(wc_Arc4Process(&dec, plain, cipher, (word32)keyLen), 0);
    ExpectIntEQ(XMEMCMP(plain, input, keyLen), 0);

    /* Bad args. */
    ExpectIntEQ(wc_Arc4Process(NULL, plain, cipher, (word32)keyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Arc4Process(&dec, NULL, cipher, (word32)keyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Arc4Process(&dec, plain, NULL, (word32)keyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_Arc4Free(&enc);
    wc_Arc4Free(&dec);
#endif
    return EXPECT_RESULT();

} /* END test_wc_Arc4Process */


/*
 * Testing wc_Init RsaKey()
 */
static int test_wc_InitRsaKey(void)
{
    EXPECT_DECLS;
#ifndef NO_RSA
    RsaKey key;

    XMEMSET(&key, 0, sizeof(RsaKey));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_InitRsaKey(NULL, HEAP_HINT), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_InitRsaKey */


/*
 * Testing wc_RsaPrivateKeyDecode()
 */
static int test_wc_RsaPrivateKeyDecode(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && (defined(USE_CERT_BUFFERS_1024)\
        || defined(USE_CERT_BUFFERS_2048)) && !defined(HAVE_FIPS)
    RsaKey key;
    byte*  tmp = NULL;
    word32 idx = 0;
    int    bytes = 0;

    XMEMSET(&key, 0, sizeof(RsaKey));

    ExpectNotNull(tmp = (byte*)XMALLOC(FOURK_BUF, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    if (tmp != NULL) {
    #ifdef USE_CERT_BUFFERS_1024
        XMEMCPY(tmp, client_key_der_1024, sizeof_client_key_der_1024);
        bytes = sizeof_client_key_der_1024;
    #else
        XMEMCPY(tmp, client_key_der_2048, sizeof_client_key_der_2048);
        bytes = sizeof_client_key_der_2048;
    #endif /* Use cert buffers. */
    }

    ExpectIntEQ(wc_RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_RsaPrivateKeyDecode(NULL, &idx, &key, (word32)bytes),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecode(tmp, NULL, &key, (word32)bytes),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecode(tmp, &idx, NULL, (word32)bytes),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
#endif
    return EXPECT_RESULT();

} /* END test_wc_RsaPrivateKeyDecode */

/*
 * Testing wc_RsaPublicKeyDecode()
 */
static int test_wc_RsaPublicKeyDecode(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && (defined(USE_CERT_BUFFERS_1024)\
        || defined(USE_CERT_BUFFERS_2048)) && !defined(HAVE_FIPS)
    RsaKey keyPub;
    byte*  tmp = NULL;
    word32 idx = 0;
    int    bytes = 0;
    word32 keySz = 0;
    word32 tstKeySz = 0;
#if defined(WC_RSA_PSS) && !defined(NO_FILESYSTEM)
    XFILE f = XBADFILE;
    const char* rsaPssPubKey = "./certs/rsapss/ca-rsapss-key.der";
    const char* rsaPssPubKeyNoParams = "./certs/rsapss/ca-3072-rsapss-key.der";
    byte buf[4096];
#endif

    XMEMSET(&keyPub, 0, sizeof(RsaKey));

    ExpectNotNull(tmp = (byte*)XMALLOC(GEN_BUF, NULL, DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(wc_InitRsaKey(&keyPub, HEAP_HINT), 0);
    if (tmp != NULL) {
    #ifdef USE_CERT_BUFFERS_1024
        XMEMCPY(tmp, client_keypub_der_1024, sizeof_client_keypub_der_1024);
        bytes = sizeof_client_keypub_der_1024;
        keySz = 1024;
    #else
        XMEMCPY(tmp, client_keypub_der_2048, sizeof_client_keypub_der_2048);
        bytes = sizeof_client_keypub_der_2048;
        keySz = 2048;
    #endif
    }

    ExpectIntEQ(wc_RsaPublicKeyDecode(tmp, &idx, &keyPub, (word32)bytes), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_RsaPublicKeyDecode(NULL, &idx, &keyPub, (word32)bytes),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPublicKeyDecode(tmp, NULL, &keyPub, (word32)bytes),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPublicKeyDecode(tmp, &idx, NULL, (word32)bytes),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRsaKey(&keyPub), 0);

    /* Test for getting modulus key size */
    idx = 0;
    ExpectIntEQ(wc_RsaPublicKeyDecode_ex(tmp, &idx, (word32)bytes, NULL,
        &tstKeySz, NULL, NULL), 0);
    ExpectIntEQ(tstKeySz, keySz/8);

#if defined(WC_RSA_PSS) && !defined(NO_FILESYSTEM)
    ExpectTrue((f = XFOPEN(rsaPssPubKey, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    idx = 0;
    ExpectIntEQ(wc_RsaPublicKeyDecode_ex(buf, &idx, (word32)bytes, NULL, NULL, NULL,
        NULL), 0);
    ExpectTrue((f = XFOPEN(rsaPssPubKeyNoParams, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);
    idx = 0;
    ExpectIntEQ(wc_RsaPublicKeyDecode_ex(buf, &idx, (word32)bytes, NULL, NULL, NULL,
        NULL), 0);
#endif

    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_RsaPublicKeyDecode */

/*
 * Testing wc_RsaPublicKeyDecodeRaw()
 */
static int test_wc_RsaPublicKeyDecodeRaw(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA)
    RsaKey     key;
    const byte n = 0x23;
    const byte e = 0x03;
    word32     nSz = sizeof(n);
    word32     eSz = sizeof(e);

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_RsaPublicKeyDecodeRaw(&n, nSz, &e, eSz, &key), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_RsaPublicKeyDecodeRaw(NULL, nSz, &e, eSz, &key),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPublicKeyDecodeRaw(&n, nSz, NULL, eSz, &key),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPublicKeyDecodeRaw(&n, nSz, &e, eSz, NULL),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));


    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
#endif
    return EXPECT_RESULT();

} /* END test_wc_RsaPublicKeyDecodeRaw */


/*
 * Testing wc_RsaPrivateKeyDecodeRaw()
 */
static int test_wc_RsaPrivateKeyDecodeRaw(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) \
    && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
    RsaKey key;
    const byte n = 33;
    const byte e = 3;
    const byte d = 7;
    const byte u = 2;
    const byte p = 3;
    const byte q = 11;
    const byte dp = 1;
    const byte dq = 7;

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), NULL, 0,
                NULL, 0, &key), 0);
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                NULL, 0, &key), 0);
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), NULL, 0,
                &dq, sizeof(dq), &key), 0);
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(NULL, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, 0,
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                NULL, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, 0, &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), NULL, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, 0, &u, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                NULL, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, 0, &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), NULL, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
                &p, sizeof(p), &q, 0, &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, 0,
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), NULL, sizeof(u),
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
                &e, sizeof(e), &d, sizeof(d), &u, 0,
                &p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
                &dq, sizeof(dq), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
#endif
    return EXPECT_RESULT();
} /* END  test_wc_RsaPrivateKeyDecodeRaw */


#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    /* In FIPS builds, wc_MakeRsaKey() will return an error if it cannot find
     * a probable prime in 5*(modLen/2) attempts. In non-FIPS builds, it keeps
     * trying until it gets a probable prime. */
    #ifdef HAVE_FIPS
        static int MakeRsaKeyRetry(RsaKey* key, int size, long e, WC_RNG* rng)
        {
            int ret;

            for (;;) {
                ret = wc_MakeRsaKey(key, size, e, rng);
                if (ret != WC_NO_ERR_TRACE(PRIME_GEN_E)) break;
                fprintf(stderr, "MakeRsaKey couldn't find prime; "
                                "trying again.\n");
            }

            return ret;
        }
        #define MAKE_RSA_KEY(a, b, c, d) MakeRsaKeyRetry(a, b, c, d)
    #else
        #define MAKE_RSA_KEY(a, b, c, d) wc_MakeRsaKey(a, b, c, d)
    #endif
#endif


/*
 * Testing wc_MakeRsaKey()
 */
static int test_wc_MakeRsaKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)

    RsaKey genKey;
    WC_RNG rng;
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4)) && \
    (defined(RSA_MIN_SIZE) && (RSA_MIN_SIZE <= 1024))
    int bits = 1024;
#else
    int bits = 2048;
#endif

    XMEMSET(&genKey, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRsaKey(&genKey, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(MAKE_RSA_KEY(&genKey, bits, WC_RSA_EXPONENT, &rng), 0);
    DoExpectIntEQ(wc_FreeRsaKey(&genKey), 0);

    /* Test bad args. */
    ExpectIntEQ(MAKE_RSA_KEY(NULL, bits, WC_RSA_EXPONENT, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(MAKE_RSA_KEY(&genKey, bits, WC_RSA_EXPONENT, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* e < 3 */
    ExpectIntEQ(MAKE_RSA_KEY(&genKey, bits, 2, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* e & 1 == 0 */
    ExpectIntEQ(MAKE_RSA_KEY(&genKey, bits, 6, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_MakeRsaKey */

/*
 * Test the bounds checking on the cipher text versus the key modulus.
 * 1. Make a new RSA key.
 * 2. Set c to 1.
 * 3. Decrypt c into k. (error)
 * 4. Copy the key modulus to c and sub 1 from the copy.
 * 5. Decrypt c into k. (error)
 * Valid bounds test cases are covered by all the other RSA tests.
 */
static int test_RsaDecryptBoundsCheck(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WC_RSA_NO_PADDING) && \
    (defined(USE_CERT_BUFFERS_1024) || defined(USE_CERT_BUFFERS_2048)) && \
    defined(WOLFSSL_PUBLIC_MP) && !defined(NO_RSA_BOUNDS_CHECK)
    WC_RNG rng;
    RsaKey key;
    byte flatC[256];
    word32 flatCSz = 0;
    byte out[256];
    word32 outSz = sizeof(out);

    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    if (EXPECT_SUCCESS()) {
        const byte* derKey;
        word32 derKeySz;
        word32 idx = 0;

        #ifdef USE_CERT_BUFFERS_1024
            derKey = server_key_der_1024;
            derKeySz = (word32)sizeof_server_key_der_1024;
            flatCSz = 128;
        #else
            derKey = server_key_der_2048;
            derKeySz = (word32)sizeof_server_key_der_2048;
            flatCSz = 256;
        #endif

        ExpectIntEQ(wc_RsaPrivateKeyDecode(derKey, &idx, &key, derKeySz), 0);
    }

    if (EXPECT_SUCCESS()) {
        XMEMSET(flatC, 0, flatCSz);
        flatC[flatCSz-1] = 1;

        ExpectIntEQ(wc_RsaDirect(flatC, flatCSz, out, &outSz, &key,
            RSA_PRIVATE_DECRYPT, &rng), WC_NO_ERR_TRACE(RSA_OUT_OF_RANGE_E));
        if (EXPECT_SUCCESS()) {
            mp_int c;
            ExpectIntEQ(mp_init_copy(&c, &key.n), 0);
            ExpectIntEQ(mp_sub_d(&c, 1, &c), 0);
            ExpectIntEQ(mp_to_unsigned_bin(&c, flatC), 0);
            ExpectIntEQ(wc_RsaDirect(flatC, flatCSz, out, &outSz, &key,
                RSA_PRIVATE_DECRYPT, NULL), WC_NO_ERR_TRACE(RSA_OUT_OF_RANGE_E));
            mp_clear(&c);
        }
    }

    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_RsaDecryptBoundsCheck */

/*
 * Testing wc_SetKeyUsage()
 */
static int test_wc_SetKeyUsage(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) && !defined(HAVE_FIPS)
    Cert myCert;

    ExpectIntEQ(wc_InitCert(&myCert), 0);

    ExpectIntEQ(wc_SetKeyUsage(&myCert, "keyEncipherment,keyAgreement"), 0);
    ExpectIntEQ(wc_SetKeyUsage(&myCert, "digitalSignature,nonRepudiation"), 0);
    ExpectIntEQ(wc_SetKeyUsage(&myCert, "contentCommitment,encipherOnly"), 0);
    ExpectIntEQ(wc_SetKeyUsage(&myCert, "decipherOnly"), 0);
    ExpectIntEQ(wc_SetKeyUsage(&myCert, "cRLSign,keyCertSign"), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_SetKeyUsage(NULL, "decipherOnly"), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_SetKeyUsage(&myCert, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_SetKeyUsage(&myCert, ""), WC_NO_ERR_TRACE(KEYUSAGE_E));
    ExpectIntEQ(wc_SetKeyUsage(&myCert, ","), WC_NO_ERR_TRACE(KEYUSAGE_E));
    ExpectIntEQ(wc_SetKeyUsage(&myCert, "digitalSignature, cRLSign"),
        WC_NO_ERR_TRACE(KEYUSAGE_E));
#endif
    return EXPECT_RESULT();
} /* END  test_wc_SetKeyUsage */

/*
 * Testing wc_CheckProbablePrime()
 */
static int test_wc_CheckProbablePrime(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST) && \
 !defined(HAVE_FIPS) && defined(WC_RSA_BLINDING)
#define CHECK_PROBABLE_PRIME_KEY_BITS 2048
    RsaKey key;
    WC_RNG rng;
    byte   e[3];
    word32 eSz = (word32)sizeof(e);
    byte   n[CHECK_PROBABLE_PRIME_KEY_BITS / 8];
    word32 nSz = (word32)sizeof(n);
    byte   d[CHECK_PROBABLE_PRIME_KEY_BITS / 8];
    word32 dSz = (word32)sizeof(d);
    byte   p[CHECK_PROBABLE_PRIME_KEY_BITS / 8 / 2];
    word32 pSz = (word32)sizeof(p);
    byte   q[CHECK_PROBABLE_PRIME_KEY_BITS / 8 / 2];
    word32 qSz = (word32)sizeof(q);
    int    nlen = CHECK_PROBABLE_PRIME_KEY_BITS;
    int*   isPrime;
    int    test[5];
    isPrime = test;

    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_RsaSetRNG(&key, &rng), 0);
    ExpectIntEQ(wc_MakeRsaKey(&key, CHECK_PROBABLE_PRIME_KEY_BITS,
        WC_RSA_EXPONENT, &rng), 0);
    PRIVATE_KEY_UNLOCK();
    ExpectIntEQ(wc_RsaExportKey(&key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q,
        &qSz), 0);
    PRIVATE_KEY_LOCK();

    /* Bad cases */
    ExpectIntEQ(wc_CheckProbablePrime(NULL, pSz, q, qSz, e, eSz, nlen, isPrime),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CheckProbablePrime(p, 0, q, qSz, e, eSz, nlen, isPrime),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CheckProbablePrime(p, pSz, NULL, qSz, e, eSz, nlen, isPrime),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CheckProbablePrime(p, pSz, q, 0, e, eSz, nlen, isPrime),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CheckProbablePrime(p, pSz, q, qSz, NULL, eSz, nlen, isPrime),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CheckProbablePrime(p, pSz, q, qSz, e, 0, nlen, isPrime),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CheckProbablePrime(NULL, 0, NULL, 0, NULL, 0, nlen, isPrime),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Good case */
    ExpectIntEQ(wc_CheckProbablePrime(p, pSz, q, qSz, e, eSz, nlen, isPrime),
        0);

    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    wc_FreeRng(&rng);
#undef CHECK_PROBABLE_PRIME_KEY_BITS
#endif
    return EXPECT_RESULT();
} /* END  test_wc_CheckProbablePrime */
/*
 * Testing wc_RsaPSS_Verify()
 */
static int test_wc_RsaPSS_Verify(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST) && \
 !defined(HAVE_FIPS) && defined(WC_RSA_BLINDING) && defined(WC_RSA_PSS)
    RsaKey        key;
    WC_RNG        rng;
    int           sz = 256;
    const char*   szMessage = "This is the string to be signed";
    unsigned char pSignature[2048/8]; /* 2048 is RSA_KEY_SIZE */
    unsigned char pDecrypted[2048/8];
    byte*         pt = pDecrypted;
    word32        outLen = sizeof(pDecrypted);

    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_RsaSetRNG(&key, &rng), 0);
    ExpectIntEQ(wc_MakeRsaKey(&key, 2048, WC_RSA_EXPONENT, &rng), 0);

    ExpectIntGT(sz = wc_RsaPSS_Sign((byte*)szMessage,
        (word32)XSTRLEN(szMessage)+1, pSignature, sizeof(pSignature),
        WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key, &rng), 0);

    /* Bad cases */
    ExpectIntEQ(wc_RsaPSS_Verify(NULL, (word32)sz, pt, outLen,
        WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPSS_Verify(pSignature, 0, pt, outLen,
        WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPSS_Verify(pSignature, (word32)sz, NULL, outLen,
        WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPSS_Verify(NULL, 0, NULL, outLen,
        WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Good case */
    ExpectIntGT(wc_RsaPSS_Verify(pSignature, (word32)sz, pt, outLen,
        WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), 0);

    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    wc_FreeRng(&rng);
#endif
    return EXPECT_RESULT();
} /* END  test_wc_RsaPSS_Verify */
/*
 * Testing wc_RsaPSS_VerifyCheck()
 */
static int test_wc_RsaPSS_VerifyCheck(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST) && \
 !defined(HAVE_FIPS) && defined(WC_RSA_BLINDING) && defined(WC_RSA_PSS)
    RsaKey        key;
    WC_RNG        rng;
    int           sz = 256; /* 2048/8 */
    byte          digest[32];
    word32        digestSz = sizeof(digest);
    unsigned char pSignature[2048/8]; /* 2048 is RSA_KEY_SIZE */
    word32        pSignatureSz = sizeof(pSignature);
    unsigned char pDecrypted[2048/8];
    byte*         pt = pDecrypted;
    word32        outLen = sizeof(pDecrypted);

    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    XMEMSET(digest, 0, sizeof(digest));
    XMEMSET(pSignature, 0, sizeof(pSignature));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_RsaSetRNG(&key, &rng), 0);
    ExpectIntEQ(wc_MakeRsaKey(&key, 2048, WC_RSA_EXPONENT, &rng), 0);
    ExpectTrue((digestSz = (word32)wc_HashGetDigestSize(WC_HASH_TYPE_SHA256)) > 0);
    ExpectIntEQ(wc_Hash(WC_HASH_TYPE_SHA256, pSignature, (word32)sz, digest, digestSz),
        0);

    ExpectIntGT(sz = wc_RsaPSS_Sign(digest, digestSz, pSignature, pSignatureSz,
        WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key, &rng), 0);

    /* Bad cases */
    ExpectIntEQ(wc_RsaPSS_VerifyCheck(NULL, (word32)sz, pt, outLen, digest,
        digestSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPSS_VerifyCheck(pSignature, 0, pt, outLen, digest,
        digestSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPSS_VerifyCheck(pSignature, (word32)sz, NULL, outLen, digest,
        digestSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPSS_VerifyCheck(NULL, 0, NULL, outLen, digest,
        digestSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Good case */
    ExpectIntGT(wc_RsaPSS_VerifyCheck(pSignature, (word32)sz, pt, outLen, digest,
        digestSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), 0);

    ExpectIntEQ(wc_FreeRsaKey(&key), 0);
    wc_FreeRng(&rng);
#endif
    return EXPECT_RESULT();
} /* END  test_wc_RsaPSS_VerifyCheck */
/*
 * Testing wc_RsaPSS_VerifyCheckInline()
 */
static int test_wc_RsaPSS_VerifyCheckInline(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST) && \
 !defined(HAVE_FIPS) && defined(WC_RSA_BLINDING) && defined(WC_RSA_PSS)
    RsaKey        key;
    WC_RNG        rng;
    int           sz = 256;
    byte          digest[32];
    word32        digestSz = sizeof(digest);
    unsigned char pSignature[2048/8]; /* 2048 is RSA_KEY_SIZE */
    unsigned char pDecrypted[2048/8];
    byte*         pt = pDecrypted;

    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    XMEMSET(digest, 0, sizeof(digest));
    XMEMSET(pSignature, 0, sizeof(pSignature));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_RsaSetRNG(&key, &rng), 0);
    ExpectIntEQ(wc_MakeRsaKey(&key, 2048, WC_RSA_EXPONENT, &rng), 0);
    ExpectTrue((digestSz = (word32)wc_HashGetDigestSize(WC_HASH_TYPE_SHA256)) > 0);
    ExpectIntEQ(wc_Hash(WC_HASH_TYPE_SHA256, pSignature, (word32)sz, digest, digestSz),
        0);

    ExpectIntGT(sz = wc_RsaPSS_Sign(digest, digestSz, pSignature,
        sizeof(pSignature), WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key, &rng), 0);

    /* Bad Cases */
    ExpectIntEQ(wc_RsaPSS_VerifyCheckInline(NULL, (word32)sz, &pt, digest,
        digestSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPSS_VerifyCheckInline(pSignature, 0, NULL, digest,
        digestSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPSS_VerifyCheckInline(NULL, 0, &pt, digest,
        digestSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaPSS_VerifyCheckInline(pSignature, (word32)sz, &pt, digest,
        digestSz, WC_HASH_TYPE_SHA, WC_MGF1SHA256, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Good case */
    ExpectIntGT(wc_RsaPSS_VerifyCheckInline(pSignature, (word32)sz, &pt, digest,
        digestSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), 0);

    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    wc_FreeRng(&rng);
#endif
    return EXPECT_RESULT();
} /* END  test_wc_RsaPSS_VerifyCheckInline */

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
static void sample_mutex_cb (int flag, int type, const char* file, int line)
{
    (void)flag;
    (void)type;
    (void)file;
    (void)line;
}
#endif
/*
 * Testing wc_LockMutex_ex
 */
static int test_wc_LockMutex_ex(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    int flag = CRYPTO_LOCK;
    int type = 0;
    const char* file = "./test-LockMutex_ex.txt";
    int line = 0;

    /* without SetMutexCb */
    ExpectIntEQ(wc_LockMutex_ex(flag, type, file, line), WC_NO_ERR_TRACE(BAD_STATE_E));
    /* with SetMutexCb */
    ExpectIntEQ(wc_SetMutexCb(sample_mutex_cb), 0);
    ExpectIntEQ(wc_LockMutex_ex(flag, type, file, line), 0);
    ExpectIntEQ(wc_SetMutexCb(NULL), 0);
#endif
    return EXPECT_RESULT();
} /* End test_wc_LockMutex_ex*/
/*
 * Testing wc_SetMutexCb
 */
static int test_wc_SetMutexCb(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    ExpectIntEQ(wc_SetMutexCb(sample_mutex_cb), 0);
    ExpectIntEQ(wc_SetMutexCb(NULL), 0);
#endif
    return EXPECT_RESULT();
} /* End test_wc_SetMutexCb*/

/*
 * Testing wc_RsaKeyToDer()
 */
static int test_wc_RsaKeyToDer(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    RsaKey genKey;
    WC_RNG rng;
    byte*  der = NULL;
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4)) && \
    (defined(RSA_MIN_SIZE) && (RSA_MIN_SIZE <= 1024))
    int     bits = 1024;
    word32  derSz = 611;
    /* (2 x 128) + 2 (possible leading 00) + (5 x 64) + 5 (possible leading 00)
       + 3 (e) + 8 (ASN tag) + 10 (ASN length) + 4 seqSz + 3 version */
#else
    int     bits = 2048;
    word32  derSz = 1196;
    /* (2 x 256) + 2 (possible leading 00) + (5 x 128) + 5 (possible leading 00)
       + 3 (e) + 8 (ASN tag) + 17 (ASN length) + 4 seqSz + 3 version */
#endif

    XMEMSET(&rng, 0, sizeof(rng));
    XMEMSET(&genKey, 0, sizeof(genKey));

    ExpectNotNull(der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER));
    /* Init structures. */
    ExpectIntEQ(wc_InitRsaKey(&genKey, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    /* Make key. */
    ExpectIntEQ(MAKE_RSA_KEY(&genKey, bits, WC_RSA_EXPONENT, &rng), 0);

    ExpectIntGT(wc_RsaKeyToDer(&genKey, der, derSz), 0);

    /* Pass good/bad args. */
    ExpectIntEQ(wc_RsaKeyToDer(NULL, der, FOURK_BUF), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Get just the output length */
    ExpectIntGT(wc_RsaKeyToDer(&genKey, NULL, 0), 0);
    /* Try Public Key. */
    genKey.type = 0;
    ExpectIntEQ(wc_RsaKeyToDer(&genKey, der, FOURK_BUF), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    #ifdef WOLFSSL_CHECK_MEM_ZERO
        /* Put back to Private Key */
        genKey.type = 1;
    #endif

    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    DoExpectIntEQ(wc_FreeRsaKey(&genKey), 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_RsaKeyToDer */

/*
 *  Testing wc_RsaKeyToPublicDer()
 */
static int test_wc_RsaKeyToPublicDer(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    RsaKey key;
    WC_RNG rng;
    byte*  der = NULL;
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4)) && \
    (defined(RSA_MIN_SIZE) && (RSA_MIN_SIZE <= 1024))
    int    bits = 1024;
    word32 derLen = 162;
#else
    int    bits = 2048;
    word32 derLen = 294;
#endif
    int    ret = 0;

    XMEMSET(&rng, 0, sizeof(rng));
    XMEMSET(&key, 0, sizeof(key));

    ExpectNotNull(der = (byte*)XMALLOC(derLen, NULL, DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(MAKE_RSA_KEY(&key, bits, WC_RSA_EXPONENT, &rng), 0);

    /* test getting size only */
    ExpectIntGT(wc_RsaKeyToPublicDer(&key, NULL, derLen), 0);
    ExpectIntGT(wc_RsaKeyToPublicDer(&key, der, derLen), 0);

    /* test getting size only */
    ExpectIntGT(wc_RsaKeyToPublicDer_ex(&key, NULL, derLen, 0), 0);
    ExpectIntGT(wc_RsaKeyToPublicDer_ex(&key, der, derLen, 0), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_RsaKeyToPublicDer(NULL, der, derLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntLT(ret = wc_RsaKeyToPublicDer(&key, der, -1), 0);
    ExpectTrue((ret == WC_NO_ERR_TRACE(BUFFER_E)) || (ret == WC_NO_ERR_TRACE(BAD_FUNC_ARG)));

    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();

} /* END test_wc_RsaKeyToPublicDer */

/*
 *  Testing wc_RsaPublicEncrypt() and wc_RsaPrivateDecrypt()
 */
static int test_wc_RsaPublicEncryptDecrypt(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    RsaKey key;
    WC_RNG rng;
    const char inStr[] = TEST_STRING;
    const word32 plainLen = (word32)TEST_STRING_SZ;
    const word32 inLen = (word32)TEST_STRING_SZ;
    int          bits = TEST_RSA_BITS;
    const word32 cipherLen = TEST_RSA_BYTES;
    word32 cipherLenResult = cipherLen;
    WC_DECLARE_VAR(in, byte, TEST_STRING_SZ, NULL);
    WC_DECLARE_VAR(plain, byte, TEST_STRING_SZ, NULL);
    WC_DECLARE_VAR(cipher, byte, TEST_RSA_BYTES, NULL);

    WC_ALLOC_VAR(in, byte, TEST_STRING_SZ, NULL);
    WC_ALLOC_VAR(plain, byte, TEST_STRING_SZ, NULL);
    WC_ALLOC_VAR(cipher, byte, TEST_RSA_BYTES, NULL);

#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC
    ExpectNotNull(in);
    ExpectNotNull(plain);
    ExpectNotNull(cipher);
#endif
    ExpectNotNull(XMEMCPY(in, inStr, inLen));

    /* Initialize stack structures. */
    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(MAKE_RSA_KEY(&key, bits, WC_RSA_EXPONENT, &rng), 0);

    /* Encrypt. */
    ExpectIntGT(cipherLenResult = (word32)wc_RsaPublicEncrypt(in, inLen, cipher,
        cipherLen, &key, &rng), 0);
    /* Pass bad args - tested in another testing function.*/

    /* Decrypt */
#if defined(WC_RSA_BLINDING) && !defined(HAVE_FIPS)
    /* Bind rng */
    ExpectIntEQ(wc_RsaSetRNG(&key, &rng), 0);
#endif
    ExpectIntGE(wc_RsaPrivateDecrypt(cipher, cipherLenResult, plain, plainLen,
        &key), 0);
    ExpectIntEQ(XMEMCMP(plain, inStr, plainLen), 0);
    /* Pass bad args - tested in another testing function.*/

    WC_FREE_VAR(in, NULL);
    WC_FREE_VAR(plain, NULL);
    WC_FREE_VAR(cipher, NULL);
    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();

} /* END test_wc_RsaPublicEncryptDecrypt */

/*
 * Testing wc_RsaPrivateDecrypt_ex() and wc_RsaPrivateDecryptInline_ex()
 */
static int test_wc_RsaPublicEncryptDecrypt_ex(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(HAVE_FIPS)\
        && !defined(WC_NO_RSA_OAEP) && !defined(NO_SHA256)
    RsaKey  key;
    WC_RNG  rng;
    const char inStr[] = TEST_STRING;
    const word32 inLen = (word32)TEST_STRING_SZ;
    const word32 plainSz = (word32)TEST_STRING_SZ;
    byte*   res = NULL;
    int     idx = 0;
    int          bits = TEST_RSA_BITS;
    const word32 cipherSz = TEST_RSA_BYTES;

    WC_DECLARE_VAR(in, byte, TEST_STRING_SZ, NULL);
    WC_DECLARE_VAR(plain, byte, TEST_STRING_SZ, NULL);
    WC_DECLARE_VAR(cipher, byte, TEST_RSA_BYTES, NULL);

    WC_ALLOC_VAR(in, byte, TEST_STRING_SZ, NULL);
    WC_ALLOC_VAR(plain, byte, TEST_STRING_SZ, NULL);
    WC_ALLOC_VAR(cipher, byte, TEST_RSA_BYTES, NULL);

#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC
    ExpectNotNull(in);
    ExpectNotNull(plain);
    ExpectNotNull(cipher);
#endif
    ExpectNotNull(XMEMCPY(in, inStr, inLen));

    /* Initialize stack structures. */
    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRsaKey_ex(&key, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(MAKE_RSA_KEY(&key, bits, WC_RSA_EXPONENT, &rng), 0);

    /* Encrypt */
    ExpectIntGE(idx = wc_RsaPublicEncrypt_ex(in, inLen, cipher, cipherSz, &key,
        &rng, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0), 0);
    /* Pass bad args - tested in another testing function.*/

#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    /* Decrypt */
    #if defined(WC_RSA_BLINDING) && !defined(HAVE_FIPS)
        ExpectIntEQ(wc_RsaSetRNG(&key, &rng), 0);
    #endif
    ExpectIntGE(wc_RsaPrivateDecrypt_ex(cipher, (word32)idx, plain, plainSz,
        &key, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0), 0);
    ExpectIntEQ(XMEMCMP(plain, inStr, plainSz), 0);
    /* Pass bad args - tested in another testing function.*/

    ExpectIntGE(wc_RsaPrivateDecryptInline_ex(cipher, (word32)idx, &res, &key,
        WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0), 0);
    ExpectIntEQ(XMEMCMP(inStr, res, plainSz), 0);
#endif

    WC_FREE_VAR(in, NULL);
    WC_FREE_VAR(plain, NULL);
    WC_FREE_VAR(cipher, NULL);
    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();

} /* END test_wc_RsaPublicEncryptDecrypt_ex */

/*
 * Tesing wc_RsaSSL_Sign() and wc_RsaSSL_Verify()
 */
static int test_wc_RsaSSL_SignVerify(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    RsaKey key;
    WC_RNG rng;
    const char inStr[] = TEST_STRING;
    const word32 plainSz = (word32)TEST_STRING_SZ;
    const word32 inLen = (word32)TEST_STRING_SZ;
    word32 idx = 0;
    int    bits = TEST_RSA_BITS;
    const word32 outSz = TEST_RSA_BYTES;

    WC_DECLARE_VAR(in, byte, TEST_STRING_SZ, NULL);
    WC_DECLARE_VAR(out, byte, TEST_RSA_BYTES, NULL);
    WC_DECLARE_VAR(plain, byte, TEST_STRING_SZ, NULL);

    WC_ALLOC_VAR(in, byte, TEST_STRING_SZ, NULL);
    WC_ALLOC_VAR(out, byte, TEST_RSA_BYTES, NULL);
    WC_ALLOC_VAR(plain, byte, TEST_STRING_SZ, NULL);

#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC
    ExpectNotNull(in);
    ExpectNotNull(out);
    ExpectNotNull(plain);
#endif
    ExpectNotNull(XMEMCPY(in, inStr, inLen));

    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(MAKE_RSA_KEY(&key, bits, WC_RSA_EXPONENT, &rng), 0);

    /* Sign. */
    ExpectIntEQ(wc_RsaSSL_Sign(in, inLen, out, outSz, &key, &rng), (int)outSz);
    idx = (int)outSz;

    /* Test bad args. */
    ExpectIntEQ(wc_RsaSSL_Sign(NULL, inLen, out, outSz, &key, &rng),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaSSL_Sign(in, 0, out, outSz, &key, &rng),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaSSL_Sign(in, inLen, NULL, outSz, &key, &rng),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaSSL_Sign(in, inLen, out, outSz, NULL, &rng),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Verify. */
    ExpectIntEQ(wc_RsaSSL_Verify(out, idx, plain, plainSz, &key), (int)inLen);

    /* Pass bad args. */
    ExpectIntEQ(wc_RsaSSL_Verify(NULL, idx, plain, plainSz, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaSSL_Verify(out, 0, plain, plainSz, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaSSL_Verify(out, idx, NULL, plainSz, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaSSL_Verify(out, idx, plain, plainSz, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    WC_FREE_VAR(in, NULL);
    WC_FREE_VAR(out, NULL);
    WC_FREE_VAR(plain, NULL);
    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();

} /* END test_wc_RsaSSL_SignVerify */

/*
 * Testing wc_RsaEncryptSize()
 */
static int test_wc_RsaEncryptSize(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    RsaKey key;
    WC_RNG rng;

    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4)) && \
    (defined(RSA_MIN_SIZE) && (RSA_MIN_SIZE <= 1024))
    ExpectIntEQ(MAKE_RSA_KEY(&key, 1024, WC_RSA_EXPONENT, &rng), 0);

    ExpectIntEQ(wc_RsaEncryptSize(&key), 128);
    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
#endif

    ExpectIntEQ(MAKE_RSA_KEY(&key, 2048, WC_RSA_EXPONENT, &rng), 0);
    ExpectIntEQ(wc_RsaEncryptSize(&key), 256);

    /* Pass in bad arg. */
    ExpectIntEQ(wc_RsaEncryptSize(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();

} /* END test_wc_RsaEncryptSize*/

/*
 * Testing wc_RsaFlattenPublicKey()
 */
static int test_wc_RsaFlattenPublicKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    RsaKey key;
    WC_RNG rng;
    byte   e[256];
    byte   n[256];
    word32 eSz = sizeof(e);
    word32 nSz = sizeof(n);
    #if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
        (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4)) && \
        (defined(RSA_MIN_SIZE) && (RSA_MIN_SIZE <= 1024))
    int    bits = 1024;
    #else
    int    bits = 2048;
    #endif

    XMEMSET(&key, 0, sizeof(RsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(MAKE_RSA_KEY(&key, bits, WC_RSA_EXPONENT, &rng), 0);

    ExpectIntEQ(wc_RsaFlattenPublicKey(&key, e, &eSz, n, &nSz), 0);

    /* Pass bad args. */
    ExpectIntEQ(wc_RsaFlattenPublicKey(NULL, e, &eSz, n, &nSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaFlattenPublicKey(&key, NULL, &eSz, n, &nSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaFlattenPublicKey(&key, e, NULL, n, &nSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaFlattenPublicKey(&key, e, &eSz, NULL, &nSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_RsaFlattenPublicKey(&key, e, &eSz, n, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();

} /* END test_wc_RsaFlattenPublicKey */



/*
 * unit test for wc_AesCcmSetKey
 */
static int test_wc_AesCcmSetKey(void)
{
    EXPECT_DECLS;
#ifdef HAVE_AESCCM
    Aes aes;
    const byte key16[] = {
        0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
        0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf
    };
    const byte key24[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
    };
    const byte key32[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };

    XMEMSET(&aes, 0, sizeof(Aes));

    ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);

#ifdef WOLFSSL_AES_128
    ExpectIntEQ(wc_AesCcmSetKey(&aes, key16, sizeof(key16)), 0);
#endif
#ifdef WOLFSSL_AES_192
    ExpectIntEQ(wc_AesCcmSetKey(&aes, key24, sizeof(key24)), 0);
#endif
#ifdef WOLFSSL_AES_256
    ExpectIntEQ(wc_AesCcmSetKey(&aes, key32, sizeof(key32)), 0);
#endif

    /* Test bad args. */
   ExpectIntEQ(wc_AesCcmSetKey(&aes, key16, sizeof(key16) - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
   ExpectIntEQ(wc_AesCcmSetKey(&aes, key24, sizeof(key24) - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
   ExpectIntEQ(wc_AesCcmSetKey(&aes, key32, sizeof(key32) - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_AesFree(&aes);
#endif
    return EXPECT_RESULT();

} /* END test_wc_AesCcmSetKey */

/*
 * Unit test function for wc_AesCcmEncrypt and wc_AesCcmDecrypt
 */
static int test_wc_AesCcmEncryptDecrypt(void)
{
    EXPECT_DECLS;
#if defined(HAVE_AESCCM) && defined(WOLFSSL_AES_128)
    Aes aes;
    const byte key16[] = {
        0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
        0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf
    };
    /* plaintext */
    const byte plainT[] = {
        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
    };
    /* nonce */
    const byte iv[] = {
        0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0,
        0xa1, 0xa2, 0xa3, 0xa4, 0xa5
    };
    const byte c[] = { /* cipher text. */
        0x58, 0x8c, 0x97, 0x9a, 0x61, 0xc6, 0x63, 0xd2,
        0xf0, 0x66, 0xd0, 0xc2, 0xc0, 0xf9, 0x89, 0x80,
        0x6d, 0x5f, 0x6b, 0x61, 0xda, 0xc3, 0x84
    };
    const byte t[] = { /* Auth tag */
        0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0
    };
    const byte authIn[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
    };
    byte cipherOut[sizeof(plainT)];
    byte authTag[sizeof(t)];
#ifdef HAVE_AES_DECRYPT
    byte plainOut[sizeof(cipherOut)];
#endif

    XMEMSET(&aes, 0, sizeof(Aes));

    ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_AesCcmSetKey(&aes, key16, sizeof(key16)), 0);

    ExpectIntEQ(wc_AesCcmEncrypt(&aes, cipherOut, plainT, sizeof(cipherOut),
        iv, sizeof(iv), authTag, sizeof(authTag), authIn , sizeof(authIn)), 0);
    ExpectIntEQ(XMEMCMP(cipherOut, c, sizeof(c)), 0);
    ExpectIntEQ(XMEMCMP(t, authTag, sizeof(t)), 0);
#ifdef HAVE_AES_DECRYPT
    ExpectIntEQ(wc_AesCcmDecrypt(&aes, plainOut, cipherOut, sizeof(plainOut),
        iv, sizeof(iv), authTag, sizeof(authTag), authIn, sizeof(authIn)), 0);
    ExpectIntEQ(XMEMCMP(plainOut, plainT, sizeof(plainT)), 0);
#endif

    /* Pass in bad args. Encrypt*/
    ExpectIntEQ(wc_AesCcmEncrypt(NULL, cipherOut, plainT, sizeof(cipherOut),
        iv, sizeof(iv), authTag, sizeof(authTag), authIn , sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmEncrypt(&aes, NULL, plainT, sizeof(cipherOut),
        iv, sizeof(iv), authTag, sizeof(authTag), authIn , sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmEncrypt(&aes, cipherOut, NULL, sizeof(cipherOut),
        iv, sizeof(iv), authTag, sizeof(authTag), authIn , sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmEncrypt(&aes, cipherOut, plainT, sizeof(cipherOut),
        NULL, sizeof(iv), authTag, sizeof(authTag), authIn , sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmEncrypt(&aes, cipherOut, plainT, sizeof(cipherOut),
        iv, sizeof(iv), NULL, sizeof(authTag), authIn , sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmEncrypt(&aes, cipherOut, plainT, sizeof(cipherOut),
        iv, sizeof(iv) + 1, authTag, sizeof(authTag), authIn , sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmEncrypt(&aes, cipherOut, plainT, sizeof(cipherOut),
        iv, sizeof(iv) - 7, authTag, sizeof(authTag), authIn , sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#ifdef HAVE_AES_DECRYPT
    /* Pass in bad args. Decrypt*/
    ExpectIntEQ(wc_AesCcmDecrypt(NULL, plainOut, cipherOut, sizeof(plainOut),
        iv, sizeof(iv), authTag, sizeof(authTag), authIn, sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmDecrypt(&aes, NULL, cipherOut, sizeof(plainOut),
        iv, sizeof(iv), authTag, sizeof(authTag), authIn, sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmDecrypt(&aes, plainOut, NULL, sizeof(plainOut),
        iv, sizeof(iv), authTag, sizeof(authTag), authIn, sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmDecrypt(&aes, plainOut, cipherOut, sizeof(plainOut),
        NULL, sizeof(iv), authTag, sizeof(authTag), authIn, sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmDecrypt(&aes, plainOut, cipherOut, sizeof(plainOut),
        iv, sizeof(iv), NULL, sizeof(authTag), authIn, sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmDecrypt(&aes, plainOut, cipherOut, sizeof(plainOut),
        iv, sizeof(iv) + 1, authTag, sizeof(authTag), authIn, sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesCcmDecrypt(&aes, plainOut, cipherOut, sizeof(plainOut),
        iv, sizeof(iv) - 7, authTag, sizeof(authTag), authIn, sizeof(authIn)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    #endif

    wc_AesFree(&aes);
#endif  /* HAVE_AESCCM */
    return EXPECT_RESULT();
} /* END test_wc_AesCcmEncryptDecrypt */


#if defined(WOLFSSL_AES_EAX) && \
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)

/*
 * Testing test_wc_AesEaxVectors()
 */
static int test_wc_AesEaxVectors(void)
{
    EXPECT_DECLS;

    typedef struct {
        byte key[AES_256_KEY_SIZE];
        int key_length;
        byte iv[AES_BLOCK_SIZE];
        int iv_length;
        byte aad[AES_BLOCK_SIZE * 2];
        int aad_length;
        byte msg[AES_BLOCK_SIZE * 5];
        int msg_length;
        byte ct[AES_BLOCK_SIZE * 5];
        int ct_length;
        byte tag[AES_BLOCK_SIZE];
        int tag_length;
        int valid;
    } AadVector;

    /*  Test vectors obtained from Google wycheproof project
     *  https://github.com/google/wycheproof
     *  from testvectors/aes_eax_test.json
     */
    const AadVector vectors[] = {
        {
            /* key, key length  */
            {0x23, 0x39, 0x52, 0xde, 0xe4, 0xd5, 0xed, 0x5f,
             0x9b, 0x9c, 0x6d, 0x6f, 0xf8, 0x0f, 0xf4, 0x78}, 16,
            /* iv, iv length  */
            {0x62, 0xec, 0x67, 0xf9, 0xc3, 0xa4, 0xa4, 0x07,
             0xfc, 0xb2, 0xa8, 0xc4, 0x90, 0x31, 0xa8, 0xb3}, 16,
            /* aad, aad length  */
            {0x6b, 0xfb, 0x91, 0x4f, 0xd0, 0x7e, 0xae, 0x6b}, 8,
            /* msg, msg length  */
            {0x00}, 0,
            /* ct, ct length  */
            {0x00}, 0,
            /* tag, tag length  */
            {0xe0, 0x37, 0x83, 0x0e, 0x83, 0x89, 0xf2, 0x7b,
             0x02, 0x5a, 0x2d, 0x65, 0x27, 0xe7, 0x9d, 0x01}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x91, 0x94, 0x5d, 0x3f, 0x4d, 0xcb, 0xee, 0x0b,
             0xf4, 0x5e, 0xf5, 0x22, 0x55, 0xf0, 0x95, 0xa4}, 16,
            /* iv, iv length  */
            {0xbe, 0xca, 0xf0, 0x43, 0xb0, 0xa2, 0x3d, 0x84,
             0x31, 0x94, 0xba, 0x97, 0x2c, 0x66, 0xde, 0xbd}, 16,
            /* aad, aad length  */
            {0xfa, 0x3b, 0xfd, 0x48, 0x06, 0xeb, 0x53, 0xfa}, 8,
            /* msg, msg length  */
            {0xf7, 0xfb}, 2,
            /* ct, ct length  */
            {0x19, 0xdd}, 2,
            /* tag, tag length  */
            {0x5c, 0x4c, 0x93, 0x31, 0x04, 0x9d, 0x0b, 0xda,
             0xb0, 0x27, 0x74, 0x08, 0xf6, 0x79, 0x67, 0xe5}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x01, 0xf7, 0x4a, 0xd6, 0x40, 0x77, 0xf2, 0xe7,
             0x04, 0xc0, 0xf6, 0x0a, 0xda, 0x3d, 0xd5, 0x23}, 16,
            /* iv, iv length  */
            {0x70, 0xc3, 0xdb, 0x4f, 0x0d, 0x26, 0x36, 0x84,
             0x00, 0xa1, 0x0e, 0xd0, 0x5d, 0x2b, 0xff, 0x5e}, 16,
            /* aad, aad length  */
            {0x23, 0x4a, 0x34, 0x63, 0xc1, 0x26, 0x4a, 0xc6}, 8,
            /* msg, msg length  */
            {0x1a, 0x47, 0xcb, 0x49, 0x33}, 5,
            /* ct, ct length  */
            {0xd8, 0x51, 0xd5, 0xba, 0xe0}, 5,
            /* tag, tag length  */
            {0x3a, 0x59, 0xf2, 0x38, 0xa2, 0x3e, 0x39, 0x19,
             0x9d, 0xc9, 0x26, 0x66, 0x26, 0xc4, 0x0f, 0x80}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0xd0, 0x7c, 0xf6, 0xcb, 0xb7, 0xf3, 0x13, 0xbd,
             0xde, 0x66, 0xb7, 0x27, 0xaf, 0xd3, 0xc5, 0xe8}, 16,
            /* iv, iv length  */
            {0x84, 0x08, 0xdf, 0xff, 0x3c, 0x1a, 0x2b, 0x12,
             0x92, 0xdc, 0x19, 0x9e, 0x46, 0xb7, 0xd6, 0x17}, 16,
            /* aad, aad length  */
            {0x33, 0xcc, 0xe2, 0xea, 0xbf, 0xf5, 0xa7, 0x9d}, 8,
            /* msg, msg length  */
            {0x48, 0x1c, 0x9e, 0x39, 0xb1}, 5,
            /* ct, ct length  */
            {0x63, 0x2a, 0x9d, 0x13, 0x1a}, 5,
            /* tag, tag length  */
            {0xd4, 0xc1, 0x68, 0xa4, 0x22, 0x5d, 0x8e, 0x1f,
             0xf7, 0x55, 0x93, 0x99, 0x74, 0xa7, 0xbe, 0xde}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x35, 0xb6, 0xd0, 0x58, 0x00, 0x05, 0xbb, 0xc1,
             0x2b, 0x05, 0x87, 0x12, 0x45, 0x57, 0xd2, 0xc2}, 16,
            /* iv, iv length  */
            {0xfd, 0xb6, 0xb0, 0x66, 0x76, 0xee, 0xdc, 0x5c,
             0x61, 0xd7, 0x42, 0x76, 0xe1, 0xf8, 0xe8, 0x16}, 16,
            /* aad, aad length  */
            {0xae, 0xb9, 0x6e, 0xae, 0xbe, 0x29, 0x70, 0xe9}, 8,
            /* msg, msg length  */
            {0x40, 0xd0, 0xc0, 0x7d, 0xa5, 0xe4}, 6,
            /* ct, ct length  */
            {0x07, 0x1d, 0xfe, 0x16, 0xc6, 0x75}, 6,
            /* tag, tag length  */
            {0xcb, 0x06, 0x77, 0xe5, 0x36, 0xf7, 0x3a, 0xfe,
             0x6a, 0x14, 0xb7, 0x4e, 0xe4, 0x98, 0x44, 0xdd}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0xbd, 0x8e, 0x6e, 0x11, 0x47, 0x5e, 0x60, 0xb2,
             0x68, 0x78, 0x4c, 0x38, 0xc6, 0x2f, 0xeb, 0x22}, 16,
            /* iv, iv length  */
            {0x6e, 0xac, 0x5c, 0x93, 0x07, 0x2d, 0x8e, 0x85,
             0x13, 0xf7, 0x50, 0x93, 0x5e, 0x46, 0xda, 0x1b}, 16,
            /* aad, aad length  */
            {0xd4, 0x48, 0x2d, 0x1c, 0xa7, 0x8d, 0xce, 0x0f}, 8,
            /* msg, msg length  */
            {0x4d, 0xe3, 0xb3, 0x5c, 0x3f, 0xc0, 0x39, 0x24,
             0x5b, 0xd1, 0xfb, 0x7d}, 12,
            /* ct, ct length  */
            {0x83, 0x5b, 0xb4, 0xf1, 0x5d, 0x74, 0x3e, 0x35,
             0x0e, 0x72, 0x84, 0x14}, 12,
            /* tag, tag length  */
            {0xab, 0xb8, 0x64, 0x4f, 0xd6, 0xcc, 0xb8, 0x69,
             0x47, 0xc5, 0xe1, 0x05, 0x90, 0x21, 0x0a, 0x4f}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x7c, 0x77, 0xd6, 0xe8, 0x13, 0xbe, 0xd5, 0xac,
             0x98, 0xba, 0xa4, 0x17, 0x47, 0x7a, 0x2e, 0x7d}, 16,
            /* iv, iv length  */
            {0x1a, 0x8c, 0x98, 0xdc, 0xd7, 0x3d, 0x38, 0x39,
             0x3b, 0x2b, 0xf1, 0x56, 0x9d, 0xee, 0xfc, 0x19}, 16,
            /* aad, aad length  */
            {0x65, 0xd2, 0x01, 0x79, 0x90, 0xd6, 0x25, 0x28}, 8,
            /* msg, msg length  */
            {0x8b, 0x0a, 0x79, 0x30, 0x6c, 0x9c, 0xe7, 0xed,
             0x99, 0xda, 0xe4, 0xf8, 0x7f, 0x8d, 0xd6, 0x16,
             0x36}, 17,
            /* ct, ct length  */
            {0x02, 0x08, 0x3e, 0x39, 0x79, 0xda, 0x01, 0x48,
             0x12, 0xf5, 0x9f, 0x11, 0xd5, 0x26, 0x30, 0xda,
             0x30}, 17,
            /* tag, tag length  */
            {0x13, 0x73, 0x27, 0xd1, 0x06, 0x49, 0xb0, 0xaa,
             0x6e, 0x1c, 0x18, 0x1d, 0xb6, 0x17, 0xd7, 0xf2}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x5f, 0xff, 0x20, 0xca, 0xfa, 0xb1, 0x19, 0xca,
             0x2f, 0xc7, 0x35, 0x49, 0xe2, 0x0f, 0x5b, 0x0d}, 16,
            /* iv, iv length  */
            {0xdd, 0xe5, 0x9b, 0x97, 0xd7, 0x22, 0x15, 0x6d,
             0x4d, 0x9a, 0xff, 0x2b, 0xc7, 0x55, 0x98, 0x26}, 16,
            /* aad, aad length  */
            {0x54, 0xb9, 0xf0, 0x4e, 0x6a, 0x09, 0x18, 0x9a}, 8,
            /* msg, msg length  */
            {0x1b, 0xda, 0x12, 0x2b, 0xce, 0x8a, 0x8d, 0xba,
             0xf1, 0x87, 0x7d, 0x96, 0x2b, 0x85, 0x92, 0xdd,
             0x2d, 0x56}, 18,
            /* ct, ct length  */
            {0x2e, 0xc4, 0x7b, 0x2c, 0x49, 0x54, 0xa4, 0x89,
             0xaf, 0xc7, 0xba, 0x48, 0x97, 0xed, 0xcd, 0xae,
             0x8c, 0xc3}, 18,
            /* tag, tag length  */
            {0x3b, 0x60, 0x45, 0x05, 0x99, 0xbd, 0x02, 0xc9,
             0x63, 0x82, 0x90, 0x2a, 0xef, 0x7f, 0x83, 0x2a}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0xa4, 0xa4, 0x78, 0x2b, 0xcf, 0xfd, 0x3e, 0xc5,
             0xe7, 0xef, 0x6d, 0x8c, 0x34, 0xa5, 0x61, 0x23}, 16,
            /* iv, iv length  */
            {0xb7, 0x81, 0xfc, 0xf2, 0xf7, 0x5f, 0xa5, 0xa8,
             0xde, 0x97, 0xa9, 0xca, 0x48, 0xe5, 0x22, 0xec}, 16,
            /* aad, aad length  */
            {0x89, 0x9a, 0x17, 0x58, 0x97, 0x56, 0x1d, 0x7e}, 8,
            /* msg, msg length  */
            {0x6c, 0xf3, 0x67, 0x20, 0x87, 0x2b, 0x85, 0x13,
             0xf6, 0xea, 0xb1, 0xa8, 0xa4, 0x44, 0x38, 0xd5,
             0xef, 0x11}, 18,
            /* ct, ct length  */
            {0x0d, 0xe1, 0x8f, 0xd0, 0xfd, 0xd9, 0x1e, 0x7a,
             0xf1, 0x9f, 0x1d, 0x8e, 0xe8, 0x73, 0x39, 0x38,
             0xb1, 0xe8}, 18,
            /* tag, tag length  */
            {0xe7, 0xf6, 0xd2, 0x23, 0x16, 0x18, 0x10, 0x2f,
             0xdb, 0x7f, 0xe5, 0x5f, 0xf1, 0x99, 0x17, 0x00}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x83, 0x95, 0xfc, 0xf1, 0xe9, 0x5b, 0xeb, 0xd6,
             0x97, 0xbd, 0x01, 0x0b, 0xc7, 0x66, 0xaa, 0xc3}, 16,
            /* iv, iv length  */
            {0x22, 0xe7, 0xad, 0xd9, 0x3c, 0xfc, 0x63, 0x93,
             0xc5, 0x7e, 0xc0, 0xb3, 0xc1, 0x7d, 0x6b, 0x44}, 16,
            /* aad, aad length  */
            {0x12, 0x67, 0x35, 0xfc, 0xc3, 0x20, 0xd2, 0x5a}, 8,
            /* msg, msg length  */
            {0xca, 0x40, 0xd7, 0x44, 0x6e, 0x54, 0x5f, 0xfa,
             0xed, 0x3b, 0xd1, 0x2a, 0x74, 0x0a, 0x65, 0x9f,
             0xfb, 0xbb, 0x3c, 0xea, 0xb7}, 21,
            /* ct, ct length  */
            {0xcb, 0x89, 0x20, 0xf8, 0x7a, 0x6c, 0x75, 0xcf,
             0xf3, 0x96, 0x27, 0xb5, 0x6e, 0x3e, 0xd1, 0x97,
             0xc5, 0x52, 0xd2, 0x95, 0xa7}, 21,
            /* tag, tag length  */
            {0xcf, 0xc4, 0x6a, 0xfc, 0x25, 0x3b, 0x46, 0x52,
             0xb1, 0xaf, 0x37, 0x95, 0xb1, 0x24, 0xab, 0x6e}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x3c, 0x8c, 0xc2, 0x97, 0x0a, 0x00, 0x8f, 0x75,
             0xcc, 0x5b, 0xea, 0xe2, 0x84, 0x72, 0x58, 0xc2}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 32,
            /* ct, ct length  */
            {0x3c, 0x44, 0x1f, 0x32, 0xce, 0x07, 0x82, 0x23,
             0x64, 0xd7, 0xa2, 0x99, 0x0e, 0x50, 0xbb, 0x13,
             0xd7, 0xb0, 0x2a, 0x26, 0x96, 0x9e, 0x4a, 0x93,
             0x7e, 0x5e, 0x90, 0x73, 0xb0, 0xd9, 0xc9, 0x68}, 32,
            /* tag, tag length  */
            {0xdb, 0x90, 0xbd, 0xb3, 0xda, 0x3d, 0x00, 0xaf,
             0xd0, 0xfc, 0x6a, 0x83, 0x55, 0x1d, 0xa9, 0x5e}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0xae, 0xf0, 0x3d, 0x00, 0x59, 0x84, 0x94, 0xe9,
             0xfb, 0x03, 0xcd, 0x7d, 0x8b, 0x59, 0x08, 0x66}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 32,
            /* ct, ct length  */
            {0xd1, 0x9a, 0xc5, 0x98, 0x49, 0x02, 0x6a, 0x91,
             0xaa, 0x1b, 0x9a, 0xec, 0x29, 0xb1, 0x1a, 0x20,
             0x2a, 0x4d, 0x73, 0x9f, 0xd8, 0x6c, 0x28, 0xe3,
             0xae, 0x3d, 0x58, 0x8e, 0xa2, 0x1d, 0x70, 0xc6}, 32,
            /* tag, tag length  */
            {0xc3, 0x0f, 0x6c, 0xd9, 0x20, 0x20, 0x74, 0xed,
             0x6e, 0x2a, 0x2a, 0x36, 0x0e, 0xac, 0x8c, 0x47}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x55, 0xd1, 0x25, 0x11, 0xc6, 0x96, 0xa8, 0x0d,
             0x05, 0x14, 0xd1, 0xff, 0xba, 0x49, 0xca, 0xda}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 32,
            /* ct, ct length  */
            {0x21, 0x08, 0x55, 0x8a, 0xc4, 0xb2, 0xc2, 0xd5,
             0xcc, 0x66, 0xce, 0xa5, 0x1d, 0x62, 0x10, 0xe0,
             0x46, 0x17, 0x7a, 0x67, 0x63, 0x1c, 0xd2, 0xdd,
             0x8f, 0x09, 0x46, 0x97, 0x33, 0xac, 0xb5, 0x17}, 32,
            /* tag, tag length  */
            {0xfc, 0x35, 0x5e, 0x87, 0xa2, 0x67, 0xbe, 0x3a,
             0xe3, 0xe4, 0x4c, 0x0b, 0xf3, 0xf9, 0x9b, 0x2b}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x79, 0x42, 0x2d, 0xdd, 0x91, 0xc4, 0xee, 0xe2,
             0xde, 0xae, 0xf1, 0xf9, 0x68, 0x30, 0x53, 0x04}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 32,
            /* ct, ct length  */
            {0x4d, 0x2c, 0x15, 0x24, 0xca, 0x4b, 0xaa, 0x4e,
             0xef, 0xcc, 0xe6, 0xb9, 0x1b, 0x22, 0x7e, 0xe8,
             0x3a, 0xba, 0xff, 0x81, 0x05, 0xdc, 0xaf, 0xa2,
             0xab, 0x19, 0x1f, 0x5d, 0xf2, 0x57, 0x50, 0x35}, 32,
            /* tag, tag length  */
            {0xe2, 0xc8, 0x65, 0xce, 0x2d, 0x7a, 0xbd, 0xac,
             0x02, 0x4c, 0x6f, 0x99, 0x1a, 0x84, 0x83, 0x90}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x0a, 0xf5, 0xaa, 0x7a, 0x76, 0x76, 0xe2, 0x83,
             0x06, 0x30, 0x6b, 0xcd, 0x9b, 0xf2, 0x00, 0x3a}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 32,
            /* ct, ct length  */
            {0x8e, 0xb0, 0x1e, 0x62, 0x18, 0x5d, 0x78, 0x2e,
             0xb9, 0x28, 0x7a, 0x34, 0x1a, 0x68, 0x62, 0xac,
             0x52, 0x57, 0xd6, 0xf9, 0xad, 0xc9, 0x9e, 0xe0,
             0xa2, 0x4d, 0x9c, 0x22, 0xb3, 0xe9, 0xb3, 0x8a}, 32,
            /* tag, tag length  */
            {0x39, 0xc3, 0x39, 0xbc, 0x8a, 0x74, 0xc7, 0x5e,
             0x2c, 0x65, 0xc6, 0x11, 0x95, 0x44, 0xd6, 0x1e}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0xaf, 0x5a, 0x03, 0xae, 0x7e, 0xdd, 0x73, 0x47,
             0x1b, 0xdc, 0xdf, 0xac, 0x5e, 0x19, 0x4a, 0x60}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 32,
            /* ct, ct length  */
            {0x94, 0xc5, 0xd2, 0xac, 0xa6, 0xdb, 0xbc, 0xe8,
             0xc2, 0x45, 0x13, 0xa2, 0x5e, 0x09, 0x5c, 0x0e,
             0x54, 0xa9, 0x42, 0x86, 0x0d, 0x32, 0x7a, 0x22,
             0x2a, 0x81, 0x5c, 0xc7, 0x13, 0xb1, 0x63, 0xb4}, 32,
            /* tag, tag length  */
            {0xf5, 0x0b, 0x30, 0x30, 0x4e, 0x45, 0xc9, 0xd4,
             0x11, 0xe8, 0xdf, 0x45, 0x08, 0xa9, 0x86, 0x12}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0xb3, 0x70, 0x87, 0x68, 0x0f, 0x0e, 0xdd, 0x5a,
             0x52, 0x22, 0x8b, 0x8c, 0x7a, 0xae, 0xa6, 0x64}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
             0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
             0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
             0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33}, 64,
            /* ct, ct length  */
            {0x3b, 0xb6, 0x17, 0x3e, 0x37, 0x72, 0xd4, 0xb6,
             0x2e, 0xef, 0x37, 0xf9, 0xef, 0x07, 0x81, 0xf3,
             0x60, 0xb6, 0xc7, 0x4b, 0xe3, 0xbf, 0x6b, 0x37,
             0x10, 0x67, 0xbc, 0x1b, 0x09, 0x0d, 0x9d, 0x66,
             0x22, 0xa1, 0xfb, 0xec, 0x6a, 0xc4, 0x71, 0xb3,
             0x34, 0x9c, 0xd4, 0x27, 0x7a, 0x10, 0x1d, 0x40,
             0x89, 0x0f, 0xbf, 0x27, 0xdf, 0xdc, 0xd0, 0xb4,
             0xe3, 0x78, 0x1f, 0x98, 0x06, 0xda, 0xab, 0xb6}, 64,
            /* tag, tag length  */
            {0xa0, 0x49, 0x87, 0x45, 0xe5, 0x99, 0x99, 0xdd,
             0xc3, 0x2d, 0x5b, 0x14, 0x02, 0x41, 0x12, 0x4e}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x4f, 0x80, 0x2d, 0xa6, 0x2a, 0x38, 0x45, 0x55,
             0xa1, 0x9b, 0xc2, 0xb3, 0x82, 0xeb, 0x25, 0xaf}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
             0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
             0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
             0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
             0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
             0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
             0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44}, 80,
            /* ct, ct length  */
            {0xe9, 0xb0, 0xbb, 0x88, 0x57, 0x81, 0x8c, 0xe3,
             0x20, 0x1c, 0x36, 0x90, 0xd2, 0x1d, 0xaa, 0x7f,
             0x26, 0x4f, 0xb8, 0xee, 0x93, 0xcc, 0x7a, 0x46,
             0x74, 0xea, 0x2f, 0xc3, 0x2b, 0xf1, 0x82, 0xfb,
             0x2a, 0x7e, 0x8a, 0xd5, 0x15, 0x07, 0xad, 0x4f,
             0x31, 0xce, 0xfc, 0x23, 0x56, 0xfe, 0x79, 0x36,
             0xa7, 0xf6, 0xe1, 0x9f, 0x95, 0xe8, 0x8f, 0xdb,
             0xf1, 0x76, 0x20, 0x91, 0x6d, 0x3a, 0x6f, 0x3d,
             0x01, 0xfc, 0x17, 0xd3, 0x58, 0x67, 0x2f, 0x77,
             0x7f, 0xd4, 0x09, 0x92, 0x46, 0xe4, 0x36, 0xe1}, 80,
            /* tag, tag length  */
            {0x67, 0x91, 0x0b, 0xe7, 0x44, 0xb8, 0x31, 0x5a,
             0xe0, 0xeb, 0x61, 0x24, 0x59, 0x0c, 0x5d, 0x8b}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0xb6, 0x7b, 0x1a, 0x6e, 0xfd, 0xd4, 0x0d, 0x37,
             0x08, 0x0f, 0xbe, 0x8f, 0x80, 0x47, 0xae, 0xb9}, 16,
            /* iv, iv length  */
            {0xfa, 0x29, 0x4b, 0x12, 0x99, 0x72, 0xf7, 0xfc,
             0x5b, 0xbd, 0x5b, 0x96, 0xbb, 0xa8, 0x37, 0xc9}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x00}, 0,
            /* ct, ct length  */
            {0x00}, 0,
            /* tag, tag length  */
            {0xb1, 0x4b, 0x64, 0xfb, 0x58, 0x98, 0x99, 0x69,
             0x95, 0x70, 0xcc, 0x91, 0x60, 0xe3, 0x98, 0x96}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x20, 0x9e, 0x6d, 0xbf, 0x2a, 0xd2, 0x6a, 0x10,
             0x54, 0x45, 0xfc, 0x02, 0x07, 0xcd, 0x9e, 0x9a}, 16,
            /* iv, iv length  */
            {0x94, 0x77, 0x84, 0x9d, 0x6c, 0xcd, 0xfc, 0xa1,
             0x12, 0xd9, 0x2e, 0x53, 0xfa, 0xe4, 0xa7, 0xca}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x01}, 1,
            /* ct, ct length  */
            {0x1d}, 1,
            /* tag, tag length  */
            {0x52, 0xa5, 0xf6, 0x00, 0xfe, 0x53, 0x38, 0x02,
             0x6a, 0x7c, 0xb0, 0x9c, 0x11, 0x64, 0x00, 0x82}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0xa5, 0x49, 0x44, 0x2e, 0x35, 0x15, 0x40, 0x32,
             0xd0, 0x7c, 0x86, 0x66, 0x00, 0x6a, 0xa6, 0xa2}, 16,
            /* iv, iv length  */
            {0x51, 0x71, 0x52, 0x45, 0x68, 0xe8, 0x1d, 0x97,
             0xe8, 0xc4, 0xde, 0x4b, 0xa5, 0x6c, 0x10, 0xa0}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x11, 0x82, 0xe9, 0x35, 0x96, 0xca, 0xc5, 0x60,
             0x89, 0x46, 0x40, 0x0b, 0xc7, 0x3f, 0x3a}, 15,
            /* ct, ct length  */
            {0xd7, 0xb8, 0xa6, 0xb4, 0x3d, 0x2e, 0x9f, 0x98,
             0xc2, 0xb4, 0x4c, 0xe5, 0xe3, 0xcf, 0xdb}, 15,
            /* tag, tag length  */
            {0x1b, 0xdd, 0x52, 0xfc, 0x98, 0x7d, 0xaf, 0x0e,
             0xe1, 0x92, 0x34, 0xc9, 0x05, 0xea, 0x64, 0x5f}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x95, 0x8b, 0xcd, 0xb6, 0x6a, 0x39, 0x52, 0xb5,
             0x37, 0x01, 0x58, 0x2a, 0x68, 0xa0, 0xe4, 0x74}, 16,
            /* iv, iv length  */
            {0x0e, 0x6e, 0xc8, 0x79, 0xb0, 0x2c, 0x6f, 0x51,
             0x69, 0x76, 0xe3, 0x58, 0x98, 0x42, 0x8d, 0xa7}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x14, 0x04, 0x15, 0x82, 0x3e, 0xcc, 0x89, 0x32,
             0xa0, 0x58, 0x38, 0x4b, 0x73, 0x8e, 0xa6, 0xea,
             0x6d, 0x4d, 0xfe, 0x3b, 0xbe, 0xee}, 22,
            /* ct, ct length  */
            {0x73, 0xe5, 0xc6, 0xf0, 0xe7, 0x03, 0xa5, 0x2d,
             0x02, 0xf7, 0xf7, 0xfa, 0xeb, 0x1b, 0x77, 0xfd,
             0x4f, 0xd0, 0xcb, 0x42, 0x1e, 0xaf}, 22,
            /* tag, tag length  */
            {0x6c, 0x15, 0x4a, 0x85, 0x96, 0x8e, 0xdd, 0x74,
             0x77, 0x65, 0x75, 0xa4, 0x45, 0x0b, 0xd8, 0x97}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x96, 0x5b, 0x75, 0x7b, 0xa5, 0x01, 0x8a, 0x8d,
             0x66, 0xed, 0xc7, 0x8e, 0x0c, 0xee, 0xe8, 0x6b}, 16,
            /* iv, iv length  */
            {0x2e, 0x35, 0x90, 0x1a, 0xe7, 0xd4, 0x91, 0xee,
             0xcc, 0x88, 0x38, 0xfe, 0xdd, 0x63, 0x14, 0x05}, 16,
            /* aad, aad length  */
            {0xdf, 0x10, 0xd0, 0xd2, 0x12, 0x24, 0x24, 0x50}, 8,
            /* msg, msg length  */
            {0x36, 0xe5, 0x7a, 0x76, 0x39, 0x58, 0xb0, 0x2c,
             0xea, 0x9d, 0x6a, 0x67, 0x6e, 0xbc, 0xe8, 0x1f}, 16,
            /* ct, ct length  */
            {0x93, 0x6b, 0x69, 0xb6, 0xc9, 0x55, 0xad, 0xfd,
             0x15, 0x53, 0x9b, 0x9b, 0xe4, 0x98, 0x9c, 0xb6}, 16,
            /* tag, tag length  */
            {0xee, 0x15, 0xa1, 0x45, 0x4e, 0x88, 0xfa, 0xad,
             0x8e, 0x48, 0xa8, 0xdf, 0x29, 0x83, 0xb4, 0x25}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x88, 0xd0, 0x20, 0x33, 0x78, 0x1c, 0x7b, 0x41,
             0x64, 0x71, 0x1a, 0x05, 0x42, 0x0f, 0x25, 0x6e}, 16,
            /* iv, iv length  */
            {0x7f, 0x29, 0x85, 0x29, 0x63, 0x15, 0x50, 0x7a,
             0xa4, 0xc0, 0xa9, 0x3d, 0x5c, 0x12, 0xbd, 0x77}, 16,
            /* aad, aad length  */
            {0x7c, 0x57, 0x1d, 0x2f, 0xbb, 0x5f, 0x62, 0x52,
             0x3c, 0x0e, 0xb3, 0x38, 0xbe, 0xf9, 0xa9}, 15,
            /* msg, msg length  */
            {0xd9, 0x8a, 0xdc, 0x03, 0xd9, 0xd5, 0x82, 0x73,
             0x2e, 0xb0, 0x7d, 0xf2, 0x3d, 0x7b, 0x9f, 0x74}, 16,
            /* ct, ct length  */
            {0x67, 0xca, 0xac, 0x35, 0x44, 0x3a, 0x31, 0x38,
             0xd2, 0xcb, 0x81, 0x1f, 0x0c, 0xe0, 0x4d, 0xd2}, 16,
            /* tag, tag length  */
            {0xb7, 0x96, 0x8e, 0x0b, 0x56, 0x40, 0xe3, 0xb2,
             0x36, 0x56, 0x96, 0x53, 0x20, 0x8b, 0x9d, 0xeb}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x51, 0x58, 0x40, 0xcf, 0x67, 0xd2, 0xe4, 0x0e,
             0xb6, 0x5e, 0x54, 0xa2, 0x4c, 0x72, 0xcb, 0xf2}, 16,
            /* iv, iv length  */
            {0xbf, 0x47, 0xaf, 0xdf, 0xd4, 0x92, 0x13, 0x7a,
             0x24, 0x23, 0x6b, 0xc3, 0x67, 0x97, 0xa8, 0x8e}, 16,
            /* aad, aad length  */
            {0x16, 0x84, 0x3c, 0x09, 0x1d, 0x43, 0xb0, 0xa1,
             0x91, 0xd0, 0xc7, 0x3d, 0x15, 0x60, 0x1b, 0xe9}, 16,
            /* msg, msg length  */
            {0xc8, 0x34, 0x58, 0x8c, 0xb6, 0xda, 0xf9, 0xf0,
             0x6d, 0xd2, 0x35, 0x19, 0xf4, 0xbe, 0x9f, 0x56}, 16,
            /* ct, ct length  */
            {0x20, 0x0a, 0xc4, 0x51, 0xfb, 0xeb, 0x0f, 0x61,
             0x51, 0xd6, 0x15, 0x83, 0xa4, 0x3b, 0x73, 0x43}, 16,
            /* tag, tag length  */
            {0x2a, 0xd4, 0x3e, 0x4c, 0xaa, 0x51, 0x98, 0x3a,
             0x9d, 0x4d, 0x24, 0x48, 0x1b, 0xf4, 0xc8, 0x39}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x2e, 0x44, 0x92, 0xd4, 0x44, 0xe5, 0xb6, 0xf4,
             0xce, 0xc8, 0xc2, 0xd3, 0x61, 0x5a, 0xc8, 0x58}, 16,
            /* iv, iv length  */
            {0xd0, 0x2b, 0xf0, 0x76, 0x3a, 0x9f, 0xef, 0xbf,
             0x70, 0xc3, 0x3a, 0xee, 0x1e, 0x9d, 0xa1, 0xd6}, 16,
            /* aad, aad length  */
            {0x90, 0x4d, 0x86, 0xf1, 0x33, 0xce, 0xc1, 0x5a,
             0x0c, 0x3c, 0xaf, 0x14, 0xd7, 0xe0, 0x29, 0xc8,
             0x2a, 0x07, 0x70, 0x5a, 0x23, 0xf0, 0xd0, 0x80}, 24,
            /* msg, msg length  */
            {0x9e, 0x62, 0xd6, 0x51, 0x1b, 0x0b, 0xda, 0x7d,
             0xd7, 0x74, 0x0b, 0x61, 0x4d, 0x97, 0xba, 0xe0}, 16,
            /* ct, ct length  */
            {0x27, 0xc6, 0xe9, 0xa6, 0x53, 0xc5, 0x25, 0x3c,
             0xa1, 0xc5, 0x67, 0x3f, 0x97, 0xb9, 0xb3, 0x3e}, 16,
            /* tag, tag length  */
            {0x2d, 0x58, 0x12, 0x71, 0xe1, 0xfa, 0x9e, 0x36,
             0x86, 0x13, 0x6c, 0xaa, 0x8f, 0x4d, 0x6c, 0x8e}, 16,
            /* valid */
            1,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe7, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe4, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0x66, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0f, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0xd0, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x12, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x11, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0x72,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x53, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0xd2, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0xb8, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb0, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9a, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x99, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x1b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa6}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa5}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xe7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0x27}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe7, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0xf2,
             0x53, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0xd0, 0x13, 0xa6, 0xdb, 0x72,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0xa7}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe6, 0x0e, 0x7c, 0x50, 0x13, 0xa6, 0xdb, 0x72,
             0x52, 0x98, 0xb1, 0x92, 0x9b, 0xc3, 0x56, 0x27}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0x19, 0xf1, 0x83, 0xaf, 0xec, 0x59, 0x24, 0x0d,
             0xad, 0x67, 0x4e, 0x6d, 0x64, 0x3c, 0xa9, 0x58}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0x66, 0x8e, 0xfc, 0xd0, 0x93, 0x26, 0x5b, 0x72,
             0xd2, 0x18, 0x31, 0x12, 0x1b, 0x43, 0xd6, 0x27}, 16,
            /* valid */
            0,
        },
        {
            /* key, key length  */
            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, 16,
            /* iv, iv length  */
            {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
             0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}, 16,
            /* aad, aad length  */
            {0x00}, 0,
            /* msg, msg length  */
            {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
             0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}, 16,
            /* ct, ct length  */
            {0x29, 0xa0, 0x91, 0x4f, 0xec, 0x4b, 0xef, 0x54,
             0xba, 0xbf, 0x66, 0x13, 0xa9, 0xf9, 0xcd, 0x70}, 16,
            /* tag, tag length  */
            {0xe7, 0x0f, 0x7d, 0x51, 0x12, 0xa7, 0xda, 0xf3,
             0x53, 0x99, 0xb0, 0x93, 0x9a, 0xc2, 0x57, 0xa6}, 16,
            /* valid */
            0,
        },
    };

    byte ciphertext[sizeof(vectors[0].ct)];
    byte authtag[sizeof(vectors[0].tag)];
    int i;
    int len;
    int ret;


    for (i = 0; i < (int)(sizeof(vectors)/sizeof(vectors[0])); i++) {

        XMEMSET(ciphertext, 0, sizeof(ciphertext));

        len = sizeof(authtag);
        ExpectIntEQ(wc_AesEaxEncryptAuth(vectors[i].key, vectors[i].key_length,
                                         ciphertext,
                                         vectors[i].msg, vectors[i].msg_length,
                                         vectors[i].iv, vectors[i].iv_length,
                                         authtag, len,
                                         vectors[i].aad, vectors[i].aad_length),
                                         0);

        /* check ciphertext matches vector */
        ExpectIntEQ(XMEMCMP(ciphertext, vectors[i].ct, vectors[i].ct_length),
                    0);

        /* check that computed tag matches vector only for vectors marked as valid */
        ret = XMEMCMP(authtag, vectors[i].tag, len);
        if (vectors[i].valid) {
            ExpectIntEQ(ret, 0);
        }
        else {
            ExpectIntNE(ret, 0);
        }

        XMEMSET(ciphertext, 0, sizeof(ciphertext));

        /* Decrypt, checking that the computed auth tags match */
        ExpectIntEQ(wc_AesEaxDecryptAuth(vectors[i].key, vectors[i].key_length,
                                         ciphertext,
                                         vectors[i].ct, vectors[i].ct_length,
                                         vectors[i].iv, vectors[i].iv_length,
                                         authtag, len,
                                         vectors[i].aad, vectors[i].aad_length),
                                         0);

        /* check decrypted ciphertext matches vector plaintext */
        ExpectIntEQ(XMEMCMP(ciphertext, vectors[i].msg, vectors[i].msg_length),
                    0);
    }
    return EXPECT_RESULT();
} /* END test_wc_AesEaxVectors */


/*
 * Testing test_wc_AesEaxEncryptAuth()
 */
static int test_wc_AesEaxEncryptAuth(void)
{
    EXPECT_DECLS;

    const byte key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
    const byte iv[]  = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
    const byte aad[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
    const byte msg[] = {0x00, 0x01, 0x02, 0x03, 0x04};

    byte ciphertext[sizeof(msg)];
    byte authtag[AES_BLOCK_SIZE];
    int i;
    int len;

    len = sizeof(authtag);
    ExpectIntEQ(wc_AesEaxEncryptAuth(key, sizeof(key),
                                     ciphertext,
                                     msg, sizeof(msg),
                                     iv, sizeof(iv),
                                     authtag, (word32)len,
                                     aad, sizeof(aad)),
                                     0);

    /* Test null checking */
    ExpectIntEQ(wc_AesEaxEncryptAuth(NULL, sizeof(key),
                                     ciphertext,
                                     msg, sizeof(msg),
                                     iv, sizeof(iv),
                                     authtag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxEncryptAuth(key, sizeof(key),
                                     NULL,
                                     msg, sizeof(msg),
                                     iv, sizeof(iv),
                                     authtag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxEncryptAuth(key, sizeof(key),
                                     ciphertext,
                                     NULL, sizeof(msg),
                                     iv, sizeof(iv),
                                     authtag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxEncryptAuth(key, sizeof(key),
                                     ciphertext,
                                     msg, sizeof(msg),
                                     NULL, sizeof(iv),
                                     authtag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxEncryptAuth(key, sizeof(key),
                                     ciphertext,
                                     msg, sizeof(msg),
                                     iv, sizeof(iv),
                                     NULL, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxEncryptAuth(key, sizeof(key),
                                     ciphertext,
                                     msg, sizeof(msg),
                                     iv, sizeof(iv),
                                     authtag, (word32)len,
                                     NULL, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Test bad key lengths */
    for (i = 0; i <= 32; i++) {
        int exp_ret;
        if (i == AES_128_KEY_SIZE || i == AES_192_KEY_SIZE
                                  || i == AES_256_KEY_SIZE) {
            exp_ret = 0;
        }
        else {
            exp_ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
        }

        ExpectIntEQ(wc_AesEaxEncryptAuth(key, (word32)i,
                                         ciphertext,
                                         msg, sizeof(msg),
                                         iv, sizeof(iv),
                                         authtag, (word32)len,
                                         aad, sizeof(aad)),
                                         exp_ret);
    }


    /* Test auth tag size out of range */
    len = AES_BLOCK_SIZE + 1;
    ExpectIntEQ(wc_AesEaxEncryptAuth(key, sizeof(key),
                                     ciphertext,
                                     msg, sizeof(msg),
                                     iv, sizeof(iv),
                                     authtag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    return EXPECT_RESULT();
} /* END test_wc_AesEaxEncryptAuth() */


/*
 * Testing test_wc_AesEaxDecryptAuth()
 */
static int test_wc_AesEaxDecryptAuth(void)
{
    EXPECT_DECLS;

    const byte key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
    const byte iv[]  = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
    const byte aad[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
    const byte ct[] =  {0x00, 0x01, 0x02, 0x03, 0x04};
    /* Garbage tag that should always fail for above aad */
    const byte tag[] = {0xFE, 0xED, 0xBE, 0xEF, 0xDE, 0xAD, 0xC0, 0xDE,
                        0xCA, 0xFE, 0xBE, 0xEF, 0xDE, 0xAF, 0xBE, 0xEF};

    byte plaintext[sizeof(ct)];
    int i;
    int len;

    len = sizeof(tag);
    ExpectIntEQ(wc_AesEaxDecryptAuth(key, sizeof(key),
                                     plaintext,
                                     ct, sizeof(ct),
                                     iv, sizeof(iv),
                                     tag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(AES_EAX_AUTH_E));

    /* Test null checking */
    ExpectIntEQ(wc_AesEaxDecryptAuth(NULL, sizeof(key),
                                     plaintext,
                                     ct, sizeof(ct),
                                     iv, sizeof(iv),
                                     tag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxDecryptAuth(key, sizeof(key),
                                     NULL,
                                     ct, sizeof(ct),
                                     iv, sizeof(iv),
                                     tag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxDecryptAuth(key, sizeof(key),
                                     plaintext,
                                     NULL, sizeof(ct),
                                     iv, sizeof(iv),
                                     tag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxDecryptAuth(key, sizeof(key),
                                     plaintext,
                                     ct, sizeof(ct),
                                     NULL, sizeof(iv),
                                     tag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxDecryptAuth(key, sizeof(key),
                                     plaintext,
                                     ct, sizeof(ct),
                                     iv, sizeof(iv),
                                     NULL, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AesEaxDecryptAuth(key, sizeof(key),
                                     plaintext,
                                     ct, sizeof(ct),
                                     iv, sizeof(iv),
                                     tag, (word32)len,
                                     NULL, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Test bad key lengths */
    for (i = 0; i <= 32; i++) {
        int exp_ret;
        if (i == AES_128_KEY_SIZE || i == AES_192_KEY_SIZE
                                  || i == AES_256_KEY_SIZE) {
            exp_ret = WC_NO_ERR_TRACE(AES_EAX_AUTH_E);
        }
        else {
            exp_ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
        }

        ExpectIntEQ(wc_AesEaxDecryptAuth(key, (word32)i,
                                         plaintext,
                                         ct, sizeof(ct),
                                         iv, sizeof(iv),
                                         tag, (word32)len,
                                         aad, sizeof(aad)),
                                         exp_ret);
    }


    /* Test auth tag size out of range */
    len = AES_BLOCK_SIZE + 1;
    ExpectIntEQ(wc_AesEaxDecryptAuth(key, sizeof(key),
                                     plaintext,
                                     ct, sizeof(ct),
                                     iv, sizeof(iv),
                                     tag, (word32)len,
                                     aad, sizeof(aad)),
                                     WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    return EXPECT_RESULT();
} /* END test_wc_AesEaxDecryptAuth() */

#endif /* WOLFSSL_AES_EAX &&
        * (!HAVE_FIPS || FIPS_VERSION_GE(5, 3)) && !HAVE_SELFTEST
        */

/*
 * Testing wc_InitDsaKey()
 */
static int test_wc_InitDsaKey(void)
{
    EXPECT_DECLS;
#ifndef NO_DSA
    DsaKey key;

    XMEMSET(&key, 0, sizeof(DsaKey));

    ExpectIntEQ(wc_InitDsaKey(&key), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_InitDsaKey(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_FreeDsaKey(&key);
#endif
    return EXPECT_RESULT();

} /* END test_wc_InitDsaKey */

/*
 * Testing wc_DsaSign() and wc_DsaVerify()
 */
static int test_wc_DsaSignVerify(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA)
    DsaKey key;
    WC_RNG rng;
    wc_Sha sha;
    byte   signature[DSA_SIG_SIZE];
    byte   hash[WC_SHA_DIGEST_SIZE];
    word32 idx = 0;
    word32 bytes;
    int    answer = 0;
#ifdef USE_CERT_BUFFERS_1024
    byte   tmp[ONEK_BUF];

    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024);
    bytes = sizeof_dsa_key_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
    byte   tmp[TWOK_BUF];

    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048);
    bytes = sizeof_dsa_key_der_2048;
#else
    byte   tmp[TWOK_BUF];
    XFILE  fp = XBADFILE;

    XMEMSET(tmp, 0, sizeof(tmp));
    ExpectTrue((fp = XFOPEN("./certs/dsa2048.der", "rb")) != XBADFILE);
    ExpectTrue((bytes = (word32)XFREAD(tmp, 1, sizeof(tmp), fp)) > 0);
    if (fp != XBADFILE)
        XFCLOSE(fp);
#endif /* END USE_CERT_BUFFERS_1024 */

    ExpectIntEQ(wc_InitSha(&sha), 0);
    ExpectIntEQ(wc_ShaUpdate(&sha, tmp, bytes), 0);
    ExpectIntEQ(wc_ShaFinal(&sha, hash), 0);
    ExpectIntEQ(wc_InitDsaKey(&key), 0);
    ExpectIntEQ(wc_DsaPrivateKeyDecode(tmp, &idx, &key, bytes), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    /* Sign. */
    ExpectIntEQ(wc_DsaSign(hash, signature, &key, &rng), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_DsaSign(NULL, signature, &key, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaSign(hash, NULL, &key, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaSign(hash, signature, NULL, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaSign(hash, signature, &key, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Verify. */
    ExpectIntEQ(wc_DsaVerify(hash, signature, &key, &answer), 0);
    ExpectIntEQ(answer, 1);
    /* Pass in bad args. */
    ExpectIntEQ(wc_DsaVerify(NULL, signature, &key, &answer), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaVerify(hash, NULL, &key, &answer), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaVerify(hash, signature, NULL, &answer), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaVerify(hash, signature, &key, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#if !defined(HAVE_FIPS) && defined(WOLFSSL_PUBLIC_MP)
    /* hard set q to 0 and test fail case */
    mp_free(&key.q);
    mp_init(&key.q);
    ExpectIntEQ(wc_DsaSign(hash, signature, &key, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    mp_set(&key.q, 1);
    ExpectIntEQ(wc_DsaSign(hash, signature, &key, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    DoExpectIntEQ(wc_FreeRng(&rng),0);
    wc_FreeDsaKey(&key);
    wc_ShaFree(&sha);
#endif
    return EXPECT_RESULT();

} /* END test_wc_DsaSign */

/*
 * Testing wc_DsaPrivateKeyDecode() and wc_DsaPublicKeyDecode()
 */
static int test_wc_DsaPublicPrivateKeyDecode(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA)
    DsaKey key;
    word32 bytes = 0;
    word32 idx  = 0;
    int    ret = 0;
#ifdef USE_CERT_BUFFERS_1024
    byte   tmp[ONEK_BUF];

    XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024);
    bytes = sizeof_dsa_key_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
    byte   tmp[TWOK_BUF];

    XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048);
    bytes = sizeof_dsa_key_der_2048;
#else
    byte   tmp[TWOK_BUF];
    XFILE  fp = XBADFILE;

    XMEMSET(tmp, 0, sizeof(tmp));
    ExpectTrue((fp = XFOPEN("./certs/dsa2048.der", "rb")) != XBADFILE);
    ExpectTrue((bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), fp)) > 0);
    if (fp != XBADFILE)
        XFCLOSE(fp);
#endif /* END USE_CERT_BUFFERS_1024 */

    ExpectIntEQ(wc_InitDsaKey(&key), 0);
    ExpectIntEQ(wc_DsaPrivateKeyDecode(tmp, &idx, &key, bytes), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_DsaPrivateKeyDecode(NULL, &idx, &key, bytes), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaPrivateKeyDecode(tmp, NULL, &key, bytes), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaPrivateKeyDecode(tmp, &idx, NULL, bytes), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntLT(ret = wc_DsaPrivateKeyDecode(tmp, &idx, &key, bytes), 0);
    ExpectTrue((ret == WC_NO_ERR_TRACE(ASN_PARSE_E)) || (ret == WC_NO_ERR_TRACE(BUFFER_E)));
    wc_FreeDsaKey(&key);

    ExpectIntEQ(wc_InitDsaKey(&key), 0);
    idx = 0; /* Reset */
    ExpectIntEQ(wc_DsaPublicKeyDecode(tmp, &idx, &key, bytes), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_DsaPublicKeyDecode(NULL, &idx, &key, bytes), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaPublicKeyDecode(tmp, NULL, &key, bytes), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaPublicKeyDecode(tmp, &idx, NULL, bytes), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntLT(ret = wc_DsaPublicKeyDecode(tmp, &idx, &key, bytes), 0);
    ExpectTrue((ret == WC_NO_ERR_TRACE(ASN_PARSE_E)) || (ret == WC_NO_ERR_TRACE(BUFFER_E)));
    wc_FreeDsaKey(&key);
#endif /* !NO_DSA */
    return EXPECT_RESULT();

} /* END test_wc_DsaPublicPrivateKeyDecode */


/*
 * Testing wc_MakeDsaKey() and wc_MakeDsaParameters()
 */
static int test_wc_MakeDsaKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA) && defined(WOLFSSL_KEY_GEN)
    DsaKey genKey;
    WC_RNG rng;

    XMEMSET(&genKey, 0, sizeof(genKey));
    XMEMSET(&rng, 0, sizeof(rng));

    ExpectIntEQ(wc_InitDsaKey(&genKey), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectIntEQ(wc_MakeDsaParameters(&rng, ONEK_BUF, &genKey), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_MakeDsaParameters(NULL, ONEK_BUF, &genKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_MakeDsaParameters(&rng, ONEK_BUF, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_MakeDsaParameters(&rng, ONEK_BUF + 1, &genKey),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_MakeDsaKey(&rng, &genKey), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_MakeDsaKey(NULL, &genKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_MakeDsaKey(&rng, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_FreeDsaKey(&genKey);
#endif
    return EXPECT_RESULT();
} /* END test_wc_MakeDsaKey */

/*
 * Testing wc_DsaKeyToDer()
 */
static int test_wc_DsaKeyToDer(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA) && defined(WOLFSSL_KEY_GEN)
    DsaKey key;
    word32 bytes;
    word32 idx = 0;
#ifdef USE_CERT_BUFFERS_1024
    byte   tmp[ONEK_BUF];
    byte   der[ONEK_BUF];

    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMSET(der, 0, sizeof(der));
    XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024);
    bytes = sizeof_dsa_key_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
    byte   tmp[TWOK_BUF];
    byte   der[TWOK_BUF];

    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMSET(der, 0, sizeof(der));
    XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048);
    bytes = sizeof_dsa_key_der_2048;
#else
    byte   tmp[TWOK_BUF];
    byte   der[TWOK_BUF];
    XFILE fp = XBADFILE;

    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMSET(der, 0, sizeof(der));
    ExpectTrue((fp = XFOPEN("./certs/dsa2048.der", "rb")) != XBADFILE);
    ExpectTrue((bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), fp)) > 0);
    if (fp != XBADFILE)
        XFCLOSE(fp);
#endif /* END USE_CERT_BUFFERS_1024 */

    XMEMSET(&key, 0, sizeof(DsaKey));

    ExpectIntEQ(wc_InitDsaKey(&key), 0);
    ExpectIntEQ(wc_DsaPrivateKeyDecode(tmp, &idx, &key, bytes), 0);
    ExpectIntGE(wc_DsaKeyToDer(&key, der, bytes), 0);
    ExpectIntEQ(XMEMCMP(der, tmp, bytes), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_DsaKeyToDer(NULL, der, FOURK_BUF), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaKeyToDer(&key, NULL, FOURK_BUF), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_FreeDsaKey(&key);
#endif /* !NO_DSA && WOLFSSL_KEY_GEN */
    return EXPECT_RESULT();

} /* END test_wc_DsaKeyToDer */

/*
 *  Testing wc_DsaKeyToPublicDer()
 *  (indirectly testing setDsaPublicKey())
 */
static int test_wc_DsaKeyToPublicDer(void)
{
    EXPECT_DECLS;
#ifndef HAVE_SELFTEST
#if !defined(NO_DSA) && defined(WOLFSSL_KEY_GEN)
    DsaKey key;
    WC_RNG rng;
    byte*  der = NULL;
    word32 sz = 0;
    word32 idx = 0;

    XMEMSET(&key, 0, sizeof(DsaKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectNotNull(der = (byte*)XMALLOC(ONEK_BUF, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(wc_InitDsaKey(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_MakeDsaParameters(&rng, ONEK_BUF, &key), 0);
    ExpectIntEQ(wc_MakeDsaKey(&rng, &key), 0);

    ExpectIntGE(sz = (word32)wc_DsaKeyToPublicDer(&key, der, ONEK_BUF), 0);
    wc_FreeDsaKey(&key);

    idx = 0;
    ExpectIntEQ(wc_DsaPublicKeyDecode(der, &idx, &key, sz), 0);

    /* Test without the SubjectPublicKeyInfo header */
    ExpectIntGE(sz = (word32)wc_SetDsaPublicKey(der, &key, ONEK_BUF, 0), 0);
    wc_FreeDsaKey(&key);
    idx = 0;
    ExpectIntEQ(wc_DsaPublicKeyDecode(der, &idx, &key, sz), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_DsaKeyToPublicDer(NULL, der, FOURK_BUF), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DsaKeyToPublicDer(&key, NULL, FOURK_BUF), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_FreeDsaKey(&key);
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* !NO_DSA && WOLFSSL_KEY_GEN */
#endif /* !HAVE_SELFTEST */
    return EXPECT_RESULT();

} /* END test_wc_DsaKeyToPublicDer */

/*
 * Testing wc_DsaImportParamsRaw()
 */
static int test_wc_DsaImportParamsRaw(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA)
    DsaKey key;
    /* [mod = L=1024, N=160], from CAVP KeyPair */
    const char* p = "d38311e2cd388c3ed698e82fdf88eb92b5a9a483dc88005d"
                    "4b725ef341eabb47cf8a7a8a41e792a156b7ce97206c4f9c"
                    "5ce6fc5ae7912102b6b502e59050b5b21ce263dddb2044b6"
                    "52236f4d42ab4b5d6aa73189cef1ace778d7845a5c1c1c71"
                    "47123188f8dc551054ee162b634d60f097f719076640e209"
                    "80a0093113a8bd73";
    const char* q = "96c5390a8b612c0e422bb2b0ea194a3ec935a281";
    const char* g = "06b7861abbd35cc89e79c52f68d20875389b127361ca66822"
                    "138ce4991d2b862259d6b4548a6495b195aa0e0b6137ca37e"
                    "b23b94074d3c3d300042bdf15762812b6333ef7b07ceba786"
                    "07610fcc9ee68491dbc1e34cd12615474e52b18bc934fb00c"
                    "61d39e7da8902291c4434a4e2224c3f4fd9f93cd6f4f17fc0"
                    "76341a7e7d9";
    /* invalid p and q parameters */
    const char* invalidP = "d38311e2cd388c3ed698e82fdf88eb92b5a9a483dc88005d";
    const char* invalidQ = "96c5390a";

    XMEMSET(&key, 0, sizeof(DsaKey));

    ExpectIntEQ(wc_InitDsaKey(&key), 0);
    ExpectIntEQ(wc_DsaImportParamsRaw(&key, p, q, g), 0);

    /* test bad args */
    /* null key struct */
    ExpectIntEQ(wc_DsaImportParamsRaw(NULL, p, q, g), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null param pointers */
    ExpectIntEQ(wc_DsaImportParamsRaw(&key, NULL, NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* illegal p length */
    ExpectIntEQ(wc_DsaImportParamsRaw(&key, invalidP, q, g), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* illegal q length */
    ExpectIntEQ(wc_DsaImportParamsRaw(&key, p, invalidQ, g), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_FreeDsaKey(&key);
#endif
    return EXPECT_RESULT();

} /* END test_wc_DsaImportParamsRaw */

/*
 * Testing wc_DsaImportParamsRawCheck()
 */
static int test_wc_DsaImportParamsRawCheck(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
    DsaKey key;
    int    trusted = 0;
    /* [mod = L=1024, N=160], from CAVP KeyPair */
    const char* p = "d38311e2cd388c3ed698e82fdf88eb92b5a9a483dc88005d"
                    "4b725ef341eabb47cf8a7a8a41e792a156b7ce97206c4f9c"
                    "5ce6fc5ae7912102b6b502e59050b5b21ce263dddb2044b6"
                    "52236f4d42ab4b5d6aa73189cef1ace778d7845a5c1c1c71"
                    "47123188f8dc551054ee162b634d60f097f719076640e209"
                    "80a0093113a8bd73";
    const char* q = "96c5390a8b612c0e422bb2b0ea194a3ec935a281";
    const char* g = "06b7861abbd35cc89e79c52f68d20875389b127361ca66822"
                    "138ce4991d2b862259d6b4548a6495b195aa0e0b6137ca37e"
                    "b23b94074d3c3d300042bdf15762812b6333ef7b07ceba786"
                    "07610fcc9ee68491dbc1e34cd12615474e52b18bc934fb00c"
                    "61d39e7da8902291c4434a4e2224c3f4fd9f93cd6f4f17fc0"
                    "76341a7e7d9";
    /* invalid p and q parameters */
    const char* invalidP = "d38311e2cd388c3ed698e82fdf88eb92b5a9a483dc88005d";
    const char* invalidQ = "96c5390a";

    ExpectIntEQ(wc_InitDsaKey(&key), 0);
    ExpectIntEQ(wc_DsaImportParamsRawCheck(&key, p, q, g, trusted, NULL), 0);

    /* test bad args */
    /* null key struct */
    ExpectIntEQ(wc_DsaImportParamsRawCheck(NULL, p, q, g, trusted, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null param pointers */
    ExpectIntEQ(wc_DsaImportParamsRawCheck(&key, NULL, NULL, NULL, trusted,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* illegal p length */
    ExpectIntEQ(wc_DsaImportParamsRawCheck(&key, invalidP, q, g, trusted, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* illegal q length */
    ExpectIntEQ(wc_DsaImportParamsRawCheck(&key, p, invalidQ, g, trusted, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_FreeDsaKey(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_DsaImportParamsRawCheck */

/*
 * Testing wc_DsaExportParamsRaw()
 */
static int test_wc_DsaExportParamsRaw(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA)
    DsaKey key;
    /* [mod = L=1024, N=160], from CAVP KeyPair */
    const char* p = "d38311e2cd388c3ed698e82fdf88eb92b5a9a483dc88005d"
                    "4b725ef341eabb47cf8a7a8a41e792a156b7ce97206c4f9c"
                    "5ce6fc5ae7912102b6b502e59050b5b21ce263dddb2044b6"
                    "52236f4d42ab4b5d6aa73189cef1ace778d7845a5c1c1c71"
                    "47123188f8dc551054ee162b634d60f097f719076640e209"
                    "80a0093113a8bd73";
    const char* q = "96c5390a8b612c0e422bb2b0ea194a3ec935a281";
    const char* g = "06b7861abbd35cc89e79c52f68d20875389b127361ca66822"
                    "138ce4991d2b862259d6b4548a6495b195aa0e0b6137ca37e"
                    "b23b94074d3c3d300042bdf15762812b6333ef7b07ceba786"
                    "07610fcc9ee68491dbc1e34cd12615474e52b18bc934fb00c"
                    "61d39e7da8902291c4434a4e2224c3f4fd9f93cd6f4f17fc0"
                    "76341a7e7d9";
    const char* pCompare = "\xd3\x83\x11\xe2\xcd\x38\x8c\x3e\xd6\x98\xe8\x2f"
                           "\xdf\x88\xeb\x92\xb5\xa9\xa4\x83\xdc\x88\x00\x5d"
                           "\x4b\x72\x5e\xf3\x41\xea\xbb\x47\xcf\x8a\x7a\x8a"
                           "\x41\xe7\x92\xa1\x56\xb7\xce\x97\x20\x6c\x4f\x9c"
                           "\x5c\xe6\xfc\x5a\xe7\x91\x21\x02\xb6\xb5\x02\xe5"
                           "\x90\x50\xb5\xb2\x1c\xe2\x63\xdd\xdb\x20\x44\xb6"
                           "\x52\x23\x6f\x4d\x42\xab\x4b\x5d\x6a\xa7\x31\x89"
                           "\xce\xf1\xac\xe7\x78\xd7\x84\x5a\x5c\x1c\x1c\x71"
                           "\x47\x12\x31\x88\xf8\xdc\x55\x10\x54\xee\x16\x2b"
                           "\x63\x4d\x60\xf0\x97\xf7\x19\x07\x66\x40\xe2\x09"
                           "\x80\xa0\x09\x31\x13\xa8\xbd\x73";
    const char* qCompare = "\x96\xc5\x39\x0a\x8b\x61\x2c\x0e\x42\x2b\xb2\xb0"
                           "\xea\x19\x4a\x3e\xc9\x35\xa2\x81";
    const char* gCompare = "\x06\xb7\x86\x1a\xbb\xd3\x5c\xc8\x9e\x79\xc5\x2f"
                           "\x68\xd2\x08\x75\x38\x9b\x12\x73\x61\xca\x66\x82"
                           "\x21\x38\xce\x49\x91\xd2\xb8\x62\x25\x9d\x6b\x45"
                           "\x48\xa6\x49\x5b\x19\x5a\xa0\xe0\xb6\x13\x7c\xa3"
                           "\x7e\xb2\x3b\x94\x07\x4d\x3c\x3d\x30\x00\x42\xbd"
                           "\xf1\x57\x62\x81\x2b\x63\x33\xef\x7b\x07\xce\xba"
                           "\x78\x60\x76\x10\xfc\xc9\xee\x68\x49\x1d\xbc\x1e"
                           "\x34\xcd\x12\x61\x54\x74\xe5\x2b\x18\xbc\x93\x4f"
                           "\xb0\x0c\x61\xd3\x9e\x7d\xa8\x90\x22\x91\xc4\x43"
                           "\x4a\x4e\x22\x24\xc3\xf4\xfd\x9f\x93\xcd\x6f\x4f"
                           "\x17\xfc\x07\x63\x41\xa7\xe7\xd9";
    byte pOut[MAX_DSA_PARAM_SIZE];
    byte qOut[MAX_DSA_PARAM_SIZE];
    byte gOut[MAX_DSA_PARAM_SIZE];
    word32 pOutSz;
    word32 qOutSz;
    word32 gOutSz;

    XMEMSET(&key, 0, sizeof(DsaKey));

    ExpectIntEQ(wc_InitDsaKey(&key), 0);
    /* first test using imported raw parameters, for expected */
    ExpectIntEQ(wc_DsaImportParamsRaw(&key, p, q, g), 0);
    pOutSz = sizeof(pOut);
    qOutSz = sizeof(qOut);
    gOutSz = sizeof(gOut);
    ExpectIntEQ(wc_DsaExportParamsRaw(&key, pOut, &pOutSz, qOut, &qOutSz, gOut,
        &gOutSz), 0);
    /* validate exported parameters are correct */
    ExpectIntEQ(XMEMCMP(pOut, pCompare, pOutSz), 0);
    ExpectIntEQ(XMEMCMP(qOut, qCompare, qOutSz), 0);
    ExpectIntEQ(XMEMCMP(gOut, gCompare, gOutSz), 0);

    /* test bad args */
    /* null key struct */
    ExpectIntEQ(wc_DsaExportParamsRaw(NULL, pOut, &pOutSz, qOut, &qOutSz, gOut,
        &gOutSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null output pointers */
    ExpectIntEQ(wc_DsaExportParamsRaw(&key, NULL, &pOutSz, NULL, &qOutSz, NULL,
        &gOutSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    /* null output size pointers */
    ExpectIntEQ( wc_DsaExportParamsRaw(&key, pOut, NULL, qOut, NULL, gOut,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* p output buffer size too small */
    pOutSz = 1;
    ExpectIntEQ(wc_DsaExportParamsRaw(&key, pOut, &pOutSz, qOut, &qOutSz, gOut,
        &gOutSz), WC_NO_ERR_TRACE(BUFFER_E));
    pOutSz = sizeof(pOut);
    /* q output buffer size too small */
    qOutSz = 1;
    ExpectIntEQ(wc_DsaExportParamsRaw(&key, pOut, &pOutSz, qOut, &qOutSz, gOut,
        &gOutSz), WC_NO_ERR_TRACE(BUFFER_E));
    qOutSz = sizeof(qOut);
    /* g output buffer size too small */
    gOutSz = 1;
    ExpectIntEQ(wc_DsaExportParamsRaw(&key, pOut, &pOutSz, qOut, &qOutSz, gOut,
        &gOutSz), WC_NO_ERR_TRACE(BUFFER_E));

    wc_FreeDsaKey(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_DsaExportParamsRaw */

/*
 * Testing wc_DsaExportKeyRaw()
 */
static int test_wc_DsaExportKeyRaw(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA) && defined(WOLFSSL_KEY_GEN)
    DsaKey key;
    WC_RNG rng;
    byte xOut[MAX_DSA_PARAM_SIZE];
    byte yOut[MAX_DSA_PARAM_SIZE];
    word32 xOutSz, yOutSz;

    XMEMSET(&key, 0, sizeof(key));
    XMEMSET(&rng, 0, sizeof(rng));

    ExpectIntEQ(wc_InitDsaKey(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_MakeDsaParameters(&rng, 1024, &key), 0);
    ExpectIntEQ(wc_MakeDsaKey(&rng, &key), 0);

    /* try successful export */
    xOutSz = sizeof(xOut);
    yOutSz = sizeof(yOut);
    ExpectIntEQ(wc_DsaExportKeyRaw(&key, xOut, &xOutSz, yOut, &yOutSz), 0);

    /* test bad args */
    /* null key struct */
    ExpectIntEQ(wc_DsaExportKeyRaw(NULL, xOut, &xOutSz, yOut, &yOutSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* null output pointers */
    ExpectIntEQ(wc_DsaExportKeyRaw(&key, NULL, &xOutSz, NULL, &yOutSz),
        WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    /* null output size pointers */
    ExpectIntEQ(wc_DsaExportKeyRaw(&key, xOut, NULL, yOut, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* x output buffer size too small */
    xOutSz = 1;
    ExpectIntEQ(wc_DsaExportKeyRaw(&key, xOut, &xOutSz, yOut, &yOutSz),
        WC_NO_ERR_TRACE(BUFFER_E));
    xOutSz = sizeof(xOut);
    /* y output buffer size too small */
    yOutSz = 1;
    ExpectIntEQ(wc_DsaExportKeyRaw(&key, xOut, &xOutSz, yOut, &yOutSz),
        WC_NO_ERR_TRACE(BUFFER_E));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_FreeDsaKey(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_DsaExportParamsRaw */


/*
 * Testing wc_ed25519_make_key().
 */
static int test_wc_ed25519_make_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_MAKE_KEY)
    ed25519_key   key;
    WC_RNG        rng;
    unsigned char pubkey[ED25519_PUB_KEY_SIZE+1];
    int           pubkey_sz = ED25519_PUB_KEY_SIZE;

    XMEMSET(&key, 0, sizeof(ed25519_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectIntEQ(wc_ed25519_make_public(&key, pubkey, (word32)pubkey_sz),
        WC_NO_ERR_TRACE(ECC_PRIV_KEY_E));
    ExpectIntEQ(wc_ed25519_make_public(&key, pubkey+1, (word32)pubkey_sz),
        WC_NO_ERR_TRACE(ECC_PRIV_KEY_E));
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_make_key(NULL, ED25519_KEY_SIZE, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE - 1, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE + 1, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed25519_make_key */

/*
 * Testing wc_ed25519_init()
 */
static int test_wc_ed25519_init(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519)
    ed25519_key key;

    XMEMSET(&key, 0, sizeof(ed25519_key));

    ExpectIntEQ(wc_ed25519_init(&key), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_ed25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed25519_init */

/*
 * Test wc_ed25519_sign_msg() and wc_ed25519_verify_msg()
 */
static int test_wc_ed25519_sign_msg(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_SIGN)
    WC_RNG      rng;
    ed25519_key key;
    byte        msg[] = "Everybody gets Friday off.\n";
    byte        sig[ED25519_SIG_SIZE+1];
    word32      msglen = sizeof(msg);
    word32      siglen = ED25519_SIG_SIZE;
    word32      badSigLen = ED25519_SIG_SIZE - 1;
#ifdef HAVE_ED25519_VERIFY
    int         verify_ok = 0; /*1 = Verify success.*/
#endif

    /* Initialize stack variables. */
    XMEMSET(&key, 0, sizeof(ed25519_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(sig, 0, sizeof(sig));

    /* Initialize key. */
    ExpectIntEQ(wc_ed25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0);

    ExpectIntEQ(wc_ed25519_sign_msg(msg, msglen, sig, &siglen, &key), 0);
    ExpectIntEQ(siglen, ED25519_SIG_SIZE);
    ExpectIntEQ(wc_ed25519_sign_msg(msg, msglen, sig+1, &siglen, &key), 0);
    ExpectIntEQ(siglen, ED25519_SIG_SIZE);

    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_sign_msg(NULL, msglen, sig, &siglen, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_sign_msg(msg, msglen, NULL, &siglen, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_sign_msg(msg, msglen, sig, NULL, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_sign_msg(msg, msglen, sig, &siglen, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_sign_msg(msg, msglen, sig, &badSigLen, &key),
        WC_NO_ERR_TRACE(BUFFER_E));
    ExpectIntEQ(badSigLen, ED25519_SIG_SIZE);
    badSigLen -= 1;

#ifdef HAVE_ED25519_VERIFY
    ExpectIntEQ(wc_ed25519_verify_msg(sig+1, siglen, msg, msglen, &verify_ok,
        &key), 0);
    ExpectIntEQ(verify_ok, 1);

    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_verify_msg(sig+1, siglen - 1, msg, msglen,
        &verify_ok, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_verify_msg(sig+1, siglen + 1, msg, msglen,
        &verify_ok, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_verify_msg(NULL, siglen, msg, msglen, &verify_ok,
        &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_verify_msg(sig+1, siglen, NULL, msglen, &verify_ok,
        &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_verify_msg(sig+1, siglen, msg, msglen, NULL, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_verify_msg(sig+1, siglen, msg, msglen, &verify_ok,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_verify_msg(sig+1, badSigLen, msg, msglen, &verify_ok,
        &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif /* Verify. */

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed25519_free(&key);
#endif
    return EXPECT_RESULT();

} /* END test_wc_ed25519_sign_msg */

/*
 * Testing wc_ed25519_import_public()
 */
static int test_wc_ed25519_import_public(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
    ed25519_key pubKey;
    WC_RNG      rng;
    const byte  in[] = "Ed25519PublicKeyUnitTest......\n";
    word32      inlen = sizeof(in);

    XMEMSET(&pubKey, 0, sizeof(ed25519_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed25519_init(&pubKey), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
#ifdef HAVE_ED25519_MAKE_KEY
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &pubKey), 0);
#endif

    ExpectIntEQ(wc_ed25519_import_public_ex(in, inlen, &pubKey, 1), 0);
    ExpectIntEQ(XMEMCMP(in, pubKey.p, inlen), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_import_public(NULL, inlen, &pubKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_import_public(in, inlen, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_import_public(in, inlen - 1, &pubKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed25519_free(&pubKey);
#endif
    return EXPECT_RESULT();
} /* END wc_ed25519_import_public */

/*
 * Testing wc_ed25519_import_private_key()
 */
static int test_wc_ed25519_import_private_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
    ed25519_key key;
    WC_RNG      rng;
    const byte  privKey[] = "Ed25519PrivateKeyUnitTest.....\n";
    const byte  pubKey[] = "Ed25519PublicKeyUnitTest......\n";
    word32      privKeySz = sizeof(privKey);
    word32      pubKeySz = sizeof(pubKey);
#ifdef HAVE_ED25519_KEY_EXPORT
    byte        bothKeys[sizeof(privKey) + sizeof(pubKey)];
    word32      bothKeysSz = sizeof(bothKeys);
#endif

    XMEMSET(&key, 0, sizeof(ed25519_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
#ifdef HAVE_ED25519_MAKE_KEY
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0);
#endif

    ExpectIntEQ(wc_ed25519_import_private_key_ex(privKey, privKeySz, pubKey,
        pubKeySz, &key, 1), 0);
    ExpectIntEQ(XMEMCMP(pubKey, key.p, privKeySz), 0);
    ExpectIntEQ(XMEMCMP(privKey, key.k, pubKeySz), 0);

#ifdef HAVE_ED25519_KEY_EXPORT
    PRIVATE_KEY_UNLOCK();
    ExpectIntEQ(wc_ed25519_export_private(&key, bothKeys, &bothKeysSz), 0);
    PRIVATE_KEY_LOCK();
    ExpectIntEQ(wc_ed25519_import_private_key_ex(bothKeys, bothKeysSz, NULL, 0,
        &key, 1), 0);
    ExpectIntEQ(XMEMCMP(pubKey, key.p, privKeySz), 0);
    ExpectIntEQ(XMEMCMP(privKey, key.k, pubKeySz), 0);
#endif

    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_import_private_key(NULL, privKeySz, pubKey, pubKeySz,
        &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_import_private_key(privKey, privKeySz, NULL,
        pubKeySz, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_import_private_key(privKey, privKeySz, pubKey,
        pubKeySz, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_import_private_key(privKey, privKeySz - 1, pubKey,
        pubKeySz, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_import_private_key(privKey, privKeySz, pubKey,
        pubKeySz - 1, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_import_private_key(privKey, privKeySz, NULL, 0,
        &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed25519_import_private_key */

/*
 * Testing wc_ed25519_export_public() and wc_ed25519_export_private_only()
 */
static int test_wc_ed25519_export(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
    ed25519_key key;
    WC_RNG      rng;
    byte        priv[ED25519_PRV_KEY_SIZE];
    byte        pub[ED25519_PUB_KEY_SIZE];
    word32      privSz = sizeof(priv);
    word32      pubSz = sizeof(pub);
#ifndef HAVE_ED25519_MAKE_KEY
    const byte  privKey[] = {
        0xf8, 0x55, 0xb7, 0xb6, 0x49, 0x3f, 0x99, 0x9c,
        0x88, 0xe3, 0xc5, 0x42, 0x6a, 0xa4, 0x47, 0x4a,
        0xe4, 0x95, 0xda, 0xdb, 0xbf, 0xf8, 0xa7, 0x42,
        0x9d, 0x0e, 0xe7, 0xd0, 0x57, 0x8f, 0x16, 0x69
    };
    const byte  pubKey[] = {
        0x42, 0x3b, 0x7a, 0xf9, 0x82, 0xcf, 0xf9, 0xdf,
        0x19, 0xdd, 0xf3, 0xf0, 0x32, 0x29, 0x6d, 0xfa,
        0xfd, 0x76, 0x4f, 0x68, 0xc2, 0xc2, 0xe0, 0x6c,
        0x47, 0xae, 0xc2, 0x55, 0x68, 0xac, 0x0d, 0x4d
    };
#endif

    XMEMSET(&key, 0, sizeof(ed25519_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
#ifdef HAVE_ED25519_MAKE_KEY
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0);
#else
    ExpectIntEQ(wc_ed25519_import_private_key_ex(privKey, sizeof(privKey),
        pubKey, sizeof(pubKey), &key, 1), 0);
#endif

    PRIVATE_KEY_UNLOCK();
    ExpectIntEQ(wc_ed25519_export_public(&key, pub, &pubSz), 0);
    ExpectIntEQ(pubSz, ED25519_KEY_SIZE);
    ExpectIntEQ(XMEMCMP(key.p, pub, pubSz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_export_public(NULL, pub, &pubSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_public(&key, NULL, &pubSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_public(&key, pub, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed25519_export_private_only(&key, priv, &privSz), 0);
    ExpectIntEQ(privSz, ED25519_KEY_SIZE);
    ExpectIntEQ(XMEMCMP(key.k, priv, privSz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_export_private_only(NULL, priv, &privSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_private_only(&key, NULL, &privSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_private_only(&key, priv, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    PRIVATE_KEY_LOCK();

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed25519_export */

/*
 *  Testing wc_ed25519_size()
 */
static int test_wc_ed25519_size(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519)
    ed25519_key key;
    WC_RNG      rng;
#ifndef HAVE_ED25519_MAKE_KEY
    const byte  privKey[] = {
        0xf8, 0x55, 0xb7, 0xb6, 0x49, 0x3f, 0x99, 0x9c,
        0x88, 0xe3, 0xc5, 0x42, 0x6a, 0xa4, 0x47, 0x4a,
        0xe4, 0x95, 0xda, 0xdb, 0xbf, 0xf8, 0xa7, 0x42,
        0x9d, 0x0e, 0xe7, 0xd0, 0x57, 0x8f, 0x16, 0x69
    };
    const byte  pubKey[] = {
        0x42, 0x3b, 0x7a, 0xf9, 0x82, 0xcf, 0xf9, 0xdf,
        0x19, 0xdd, 0xf3, 0xf0, 0x32, 0x29, 0x6d, 0xfa,
        0xfd, 0x76, 0x4f, 0x68, 0xc2, 0xc2, 0xe0, 0x6c,
        0x47, 0xae, 0xc2, 0x55, 0x68, 0xac, 0x0d, 0x4d
    };
#endif

    XMEMSET(&key, 0, sizeof(ed25519_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
#ifdef HAVE_ED25519_MAKE_KEY
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0);
#else
    ExpectIntEQ(wc_ed25519_import_private_key_ex(privKey, sizeof(privKey),
        pubKey, sizeof(pubKey), &key, 1), 0);
#endif

    ExpectIntEQ(wc_ed25519_size(&key), ED25519_KEY_SIZE);
    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed25519_sig_size(&key), ED25519_SIG_SIZE);
    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_sig_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed25519_pub_size(&key), ED25519_PUB_KEY_SIZE);
    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_pub_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed25519_priv_size(&key), ED25519_PRV_KEY_SIZE);
    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_priv_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed25519_size */

/*
 * Testing wc_ed25519_export_private() and wc_ed25519_export_key()
 */
static int test_wc_ed25519_exportKey(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
    WC_RNG      rng;
    ed25519_key key;
    byte        priv[ED25519_PRV_KEY_SIZE];
    byte        pub[ED25519_PUB_KEY_SIZE];
    byte        privOnly[ED25519_PRV_KEY_SIZE];
    word32      privSz      = sizeof(priv);
    word32      pubSz       = sizeof(pub);
    word32      privOnlySz  = sizeof(privOnly);
#ifndef HAVE_ED25519_MAKE_KEY
    const byte  privKey[] = {
        0xf8, 0x55, 0xb7, 0xb6, 0x49, 0x3f, 0x99, 0x9c,
        0x88, 0xe3, 0xc5, 0x42, 0x6a, 0xa4, 0x47, 0x4a,
        0xe4, 0x95, 0xda, 0xdb, 0xbf, 0xf8, 0xa7, 0x42,
        0x9d, 0x0e, 0xe7, 0xd0, 0x57, 0x8f, 0x16, 0x69
    };
    const byte  pubKey[] = {
        0x42, 0x3b, 0x7a, 0xf9, 0x82, 0xcf, 0xf9, 0xdf,
        0x19, 0xdd, 0xf3, 0xf0, 0x32, 0x29, 0x6d, 0xfa,
        0xfd, 0x76, 0x4f, 0x68, 0xc2, 0xc2, 0xe0, 0x6c,
        0x47, 0xae, 0xc2, 0x55, 0x68, 0xac, 0x0d, 0x4d
    };
#endif

    XMEMSET(&key, 0, sizeof(ed25519_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
#ifdef HAVE_ED25519_MAKE_KEY
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0);
#else
    ExpectIntEQ(wc_ed25519_import_private_key_ex(privKey, sizeof(privKey),
        pubKey, sizeof(pubKey), &key, 1), 0);
#endif

    PRIVATE_KEY_UNLOCK();
    ExpectIntEQ(wc_ed25519_export_private(&key, privOnly, &privOnlySz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_export_private(NULL, privOnly, &privOnlySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_private(&key, NULL, &privOnlySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_private(&key, privOnly, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed25519_export_key(&key, priv, &privSz, pub, &pubSz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed25519_export_key(NULL, priv, &privSz, pub, &pubSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_key(&key, NULL, &privSz, pub, &pubSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_key(&key, priv, NULL, pub, &pubSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_key(&key, priv, &privSz, NULL, &pubSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_export_key(&key, priv, &privSz, pub, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    PRIVATE_KEY_LOCK();

    /* Cross check output. */
    ExpectIntEQ(XMEMCMP(priv, privOnly, privSz), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed25519_exportKey */

/*
 * Testing wc_Ed25519PublicKeyToDer
 */
static int test_wc_Ed25519PublicKeyToDer(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) && \
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
    ed25519_key key;
    byte        derBuf[1024];

    XMEMSET(&key, 0, sizeof(ed25519_key));

    /* Test bad args */
    ExpectIntEQ(wc_Ed25519PublicKeyToDer(NULL, NULL, 0, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed25519_init(&key), 0);
    ExpectIntEQ(wc_Ed25519PublicKeyToDer(&key, derBuf, 0, 0), WC_NO_ERR_TRACE(BUFFER_E));
    wc_ed25519_free(&key);

    /*  Test good args */
    if (EXPECT_SUCCESS()) {
        WC_RNG rng;

        XMEMSET(&rng, 0, sizeof(WC_RNG));

        ExpectIntEQ(wc_ed25519_init(&key), 0);
        ExpectIntEQ(wc_InitRng(&rng), 0);
        ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0);
        /* length only */
        ExpectIntGT(wc_Ed25519PublicKeyToDer(&key, NULL, 0, 0), 0);
        ExpectIntGT(wc_Ed25519PublicKeyToDer(&key, NULL, 0, 1), 0);
        ExpectIntGT(wc_Ed25519PublicKeyToDer(&key, derBuf,
                    (word32)sizeof(derBuf), 1), 0);

        DoExpectIntEQ(wc_FreeRng(&rng), 0);
        wc_ed25519_free(&key);
    }
#endif
    return EXPECT_RESULT();
} /* END testing wc_Ed25519PublicKeyToDer */

/*
 * Testing wc_curve25519_init and wc_curve25519_free.
 */
static int test_wc_curve25519_init(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519)
    curve25519_key key;

    ExpectIntEQ(wc_curve25519_init(&key), 0);
    /* Test bad args for wc_curve25519_init */
    ExpectIntEQ(wc_curve25519_init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Test good args for wc_curve_25519_free */
    wc_curve25519_free(&key);
    /* Test bad args for wc_curve25519 free. */
    wc_curve25519_free(NULL);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve25519_init and wc_curve_25519_free*/
/*
 * Testing test_wc_curve25519_size.
 */
static int test_wc_curve25519_size(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519)
    curve25519_key key;

    ExpectIntEQ(wc_curve25519_init(&key), 0);

    /* Test good args for wc_curve25519_size */
    ExpectIntEQ(wc_curve25519_size(&key), CURVE25519_KEYSIZE);
    /* Test bad args for wc_curve25519_size */
    ExpectIntEQ(wc_curve25519_size(NULL), 0);

    wc_curve25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve25519_size*/

/*
 * Testing test_wc_curve25519_export_key_raw().
 */
static int test_wc_curve25519_export_key_raw(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)
    curve25519_key key;
    WC_RNG         rng;
    byte           privateKey[CURVE25519_KEYSIZE];
    byte           publicKey[CURVE25519_KEYSIZE];
    word32         prvkSz;
    word32         pubkSz;
    byte           prik[CURVE25519_KEYSIZE];
    byte           pubk[CURVE25519_KEYSIZE];
    word32         prksz;
    word32         pbksz;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key), 0);

    /* bad-argument-test cases - target function should return BAD_FUNC_ARG */
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw(NULL, privateKey, &prvkSz,
        publicKey, &pubkSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw(&key, NULL, &prvkSz, publicKey,
        &pubkSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw(&key, privateKey, NULL,
        publicKey, &pubkSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* prvkSz = CURVE25519_KEYSIZE; */
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw(&key, privateKey, &prvkSz,
        NULL, &pubkSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw(&key, privateKey, &prvkSz,
        publicKey, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* cross-testing */
    prksz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_private_raw(&key, prik, &prksz), 0);
    pbksz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_public(&key, pubk, &pbksz), 0);
    prvkSz = CURVE25519_KEYSIZE;
    /* pubkSz = CURVE25519_KEYSIZE; */
    ExpectIntEQ(wc_curve25519_export_key_raw(&key, privateKey, &prvkSz,
        publicKey,  &pubkSz), 0);
    ExpectIntEQ(prksz, CURVE25519_KEYSIZE);
    ExpectIntEQ(pbksz, CURVE25519_KEYSIZE);
    ExpectIntEQ(prvkSz, CURVE25519_KEYSIZE);
    ExpectIntEQ(pubkSz, CURVE25519_KEYSIZE);
    ExpectIntEQ(XMEMCMP(privateKey, prik, CURVE25519_KEYSIZE), 0);
    ExpectIntEQ(XMEMCMP(publicKey,  pubk, CURVE25519_KEYSIZE), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* end of test_wc_curve25519_export_key_raw */

/*
 * Testing test_wc_curve25519_export_key_raw_ex().
 */
static int test_wc_curve25519_export_key_raw_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)
    curve25519_key key;
    WC_RNG         rng;
    byte           privateKey[CURVE25519_KEYSIZE];
    byte           publicKey[CURVE25519_KEYSIZE];
    word32         prvkSz;
    word32         pubkSz;
    byte           prik[CURVE25519_KEYSIZE];
    byte           pubk[CURVE25519_KEYSIZE];
    word32         prksz;
    word32         pbksz;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key), 0);

    /* bad-argument-test cases - target function should return BAD_FUNC_ARG */
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(NULL, privateKey,
        &prvkSz, publicKey, &pubkSz, EC25519_LITTLE_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, NULL,
        &prvkSz, publicKey, &pubkSz, EC25519_LITTLE_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, privateKey,
        NULL, publicKey, &pubkSz, EC25519_LITTLE_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* prvkSz = CURVE25519_KEYSIZE; */
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, privateKey,
        &prvkSz, NULL, &pubkSz, EC25519_LITTLE_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, privateKey,
        &prvkSz, publicKey, NULL, EC25519_LITTLE_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    /* pubkSz = CURVE25519_KEYSIZE; */
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(NULL, privateKey,
        &prvkSz, publicKey, &pubkSz, EC25519_BIG_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, NULL,
        &prvkSz, publicKey, &pubkSz, EC25519_BIG_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, privateKey,
        NULL, publicKey, &pubkSz, EC25519_BIG_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* prvkSz = CURVE25519_KEYSIZE; */
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, privateKey,
        &prvkSz, NULL, &pubkSz, EC25519_BIG_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, privateKey,
        &prvkSz, publicKey, NULL, EC25519_BIG_ENDIAN), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* illegal value for endian */
    prvkSz = CURVE25519_KEYSIZE;
    /* pubkSz = CURVE25519_KEYSIZE; */
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, privateKey, &prvkSz,
        publicKey, NULL, EC25519_BIG_ENDIAN + 10), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* cross-testing */
    prksz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_private_raw( &key, prik, &prksz), 0);
    pbksz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_public( &key, pubk, &pbksz), 0);
    prvkSz = CURVE25519_KEYSIZE;
    /* pubkSz = CURVE25519_KEYSIZE; */
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, privateKey, &prvkSz,
        publicKey, &pubkSz, EC25519_BIG_ENDIAN), 0);
    ExpectIntEQ(prksz, CURVE25519_KEYSIZE);
    ExpectIntEQ(pbksz, CURVE25519_KEYSIZE);
    ExpectIntEQ(prvkSz, CURVE25519_KEYSIZE);
    ExpectIntEQ(pubkSz, CURVE25519_KEYSIZE);
    ExpectIntEQ(XMEMCMP(privateKey, prik, CURVE25519_KEYSIZE), 0);
    ExpectIntEQ(XMEMCMP(publicKey,  pubk, CURVE25519_KEYSIZE), 0);
    ExpectIntEQ(wc_curve25519_export_key_raw_ex(&key, privateKey, &prvkSz,
        publicKey, &pubkSz, EC25519_LITTLE_ENDIAN), 0);
    ExpectIntEQ(prvkSz, CURVE25519_KEYSIZE);
    ExpectIntEQ(pubkSz, CURVE25519_KEYSIZE);

    /* try once with another endian */
    prvkSz = CURVE25519_KEYSIZE;
    pubkSz = CURVE25519_KEYSIZE;
    ExpectIntEQ(wc_curve25519_export_key_raw_ex( &key, privateKey, &prvkSz,
        publicKey, &pubkSz, EC25519_BIG_ENDIAN), 0);
    ExpectIntEQ(prvkSz, CURVE25519_KEYSIZE);
    ExpectIntEQ(pubkSz, CURVE25519_KEYSIZE);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* end of test_wc_curve25519_export_key_raw_ex */

/*
 * Testing wc_curve25519_make_key
 */
static int test_wc_curve25519_make_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519)
    curve25519_key key;
    WC_RNG         rng;
    int            keysize = 0;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key), 0);
    ExpectIntEQ(keysize = wc_curve25519_size(&key), CURVE25519_KEYSIZE);
    ExpectIntEQ(wc_curve25519_make_key(&rng, keysize, &key), 0);
    /* test bad cases*/
    ExpectIntEQ(wc_curve25519_make_key(NULL, 0, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_make_key(&rng, keysize, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_make_key(NULL, keysize, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_make_key(&rng, 0, &key), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve25519_make_key*/

/*
 * Testing wc_curve25519_shared_secret_ex
 */
static int test_wc_curve25519_shared_secret_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519)
    curve25519_key private_key;
    curve25519_key public_key;
    WC_RNG         rng;
    byte           out[CURVE25519_KEYSIZE];
    word32         outLen = sizeof(out);
    int            endian = EC25519_BIG_ENDIAN;

    ExpectIntEQ(wc_curve25519_init(&private_key), 0);
    ExpectIntEQ(wc_curve25519_init(&public_key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &private_key),
        0);
    ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &public_key),
        0);

    ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, out,
        &outLen, endian), 0);

    /* test bad cases*/
    ExpectIntEQ(wc_curve25519_shared_secret_ex(NULL, NULL, NULL, 0, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_shared_secret_ex(NULL, &public_key, out, &outLen,
        endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, NULL, out, &outLen,
        endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, NULL,
        &outLen, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, out,
        NULL, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* curve25519.c is checking for public_key size less than or equal to 0x7f,
     * increasing to 0x8f checks for error being returned*/
    public_key.p.point[CURVE25519_KEYSIZE-1] = 0x8F;
    ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, out,
        &outLen, endian), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    outLen = outLen - 2;
    ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, out,
        &outLen, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve25519_free(&private_key);
    wc_curve25519_free(&public_key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve25519_shared_secret_ex*/

/*
 * Testing wc_curve25519_make_pub
 */
static int test_wc_curve25519_make_pub(void)
{
    EXPECT_DECLS;
#ifdef HAVE_CURVE25519
    curve25519_key key;
    WC_RNG         rng;
    byte           out[CURVE25519_KEYSIZE];

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key), 0);

    ExpectIntEQ(wc_curve25519_make_pub((int)sizeof(out), out,
        (int)sizeof(key.k), key.k), 0);
    /* test bad cases*/
    ExpectIntEQ(wc_curve25519_make_pub((int)sizeof(key.k) - 1, key.k,
        (int)sizeof out, out), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof(key.k),
        NULL), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_curve25519_make_pub((int)sizeof out - 1, out,
        (int)sizeof(key.k), key.k), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_curve25519_make_pub((int)sizeof out, NULL,
        (int)sizeof(key.k), key.k), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    /* verify clamping test */
    key.k[0] |= ~248;
    ExpectIntEQ(wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof(key.k),
        key.k), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    key.k[0] &= 248;
    /* repeat the expected-to-succeed test. */
    ExpectIntEQ(wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof(key.k),
        key.k), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve25519_make_pub */

/*
 * Testing test_wc_curve25519_export_public_ex
 */
static int test_wc_curve25519_export_public_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519)
    curve25519_key key;
    WC_RNG         rng;
    byte           out[CURVE25519_KEYSIZE];
    word32         outLen = sizeof(out);
    int            endian = EC25519_BIG_ENDIAN;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key), 0);

    ExpectIntEQ(wc_curve25519_export_public(&key, out, &outLen), 0);
    ExpectIntEQ(wc_curve25519_export_public_ex(&key, out, &outLen, endian), 0);
    /* test bad cases*/
    ExpectIntEQ(wc_curve25519_export_public_ex(NULL, NULL, NULL, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_export_public_ex(NULL, out, &outLen, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_export_public_ex(&key, NULL, &outLen, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_export_public_ex(&key, out, NULL, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    outLen = outLen - 2;
    ExpectIntEQ(wc_curve25519_export_public_ex(&key, out, &outLen, endian),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve25519_export_public_ex*/
/*
 * Testing test_wc_curve25519_import_private_raw_ex
 */
static int test_wc_curve25519_import_private_raw_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519)
    curve25519_key key;
    WC_RNG         rng;
    byte           priv[CURVE25519_KEYSIZE];
    byte           pub[CURVE25519_KEYSIZE];
    word32         privSz = sizeof(priv);
    word32         pubSz = sizeof(pub);
    int            endian = EC25519_BIG_ENDIAN;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key), 0);

    ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, priv, &privSz,
        endian), 0);
    ExpectIntEQ(wc_curve25519_export_public(&key, pub, &pubSz), 0);
    ExpectIntEQ(wc_curve25519_import_private_raw_ex(priv, privSz, pub, pubSz,
        &key, endian), 0);
    /* test bad cases*/
    ExpectIntEQ(wc_curve25519_import_private_raw_ex(NULL, 0, NULL, 0, NULL,
        endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_import_private_raw_ex(NULL, privSz, pub, pubSz,
        &key, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_import_private_raw_ex(priv, privSz, NULL, pubSz,
        &key, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_import_private_raw_ex(priv, privSz, pub, pubSz,
        NULL, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_import_private_raw_ex(priv, 0, pub, pubSz,
        &key, endian), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_curve25519_import_private_raw_ex(priv, privSz, pub, 0,
        &key, endian), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_curve25519_import_private_raw_ex(priv, privSz, pub, pubSz,
        &key, EC25519_LITTLE_ENDIAN), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve25519_import_private_raw_ex*/

/*
 * Testing test_wc_curve25519_import_private
 */
static int test_wc_curve25519_import_private(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519)
    curve25519_key key;
    WC_RNG         rng;
    byte           priv[CURVE25519_KEYSIZE];
    word32         privSz = sizeof(priv);

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve25519_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key), 0);

    ExpectIntEQ(wc_curve25519_export_private_raw(&key, priv, &privSz), 0);
    ExpectIntEQ(wc_curve25519_import_private(priv, privSz, &key), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve25519_import*/

/*
 * Testing test_wc_curve25519_export_private_raw_ex
 */
static int test_wc_curve25519_export_private_raw_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE25519)
    curve25519_key key;
    byte           out[CURVE25519_KEYSIZE];
    word32         outLen = sizeof(out);
    int            endian = EC25519_BIG_ENDIAN;

    ExpectIntEQ(wc_curve25519_init(&key), 0);

    ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, out, &outLen, endian),
        0);
    /* test bad cases*/
    ExpectIntEQ(wc_curve25519_export_private_raw_ex(NULL, NULL, NULL, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_export_private_raw_ex(NULL, out, &outLen, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, NULL, &outLen,
        endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, out, NULL, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, out, &outLen,
        EC25519_LITTLE_ENDIAN), 0);
    outLen = outLen - 2;
    ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, out, &outLen, endian),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    wc_curve25519_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve25519_export_private_raw_ex*/

/*
 * Testing wc_ed448_make_key().
 */
static int test_wc_ed448_make_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448)
    ed448_key     key;
    WC_RNG        rng;
    unsigned char pubkey[ED448_PUB_KEY_SIZE];

    XMEMSET(&key, 0, sizeof(ed448_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectIntEQ(wc_ed448_make_public(&key, pubkey, sizeof(pubkey)),
        WC_NO_ERR_TRACE(ECC_PRIV_KEY_E));
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_make_key(NULL, ED448_KEY_SIZE, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE - 1, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE + 1, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed448_make_key */


/*
 * Testing wc_ed448_init()
 */
static int test_wc_ed448_init(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448)
    ed448_key key;

    XMEMSET(&key, 0, sizeof(ed448_key));

    ExpectIntEQ(wc_ed448_init(&key), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_ed448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed448_init */

/*
 * Test wc_ed448_sign_msg() and wc_ed448_verify_msg()
 */
static int test_wc_ed448_sign_msg(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448) && defined(HAVE_ED448_SIGN)
    ed448_key key;
    WC_RNG    rng;
    byte      msg[] = "Everybody gets Friday off.\n";
    byte      sig[ED448_SIG_SIZE];
    word32    msglen = sizeof(msg);
    word32    siglen = sizeof(sig);
    word32    badSigLen = sizeof(sig) - 1;
#ifdef HAVE_ED448_VERIFY
    int       verify_ok = 0; /*1 = Verify success.*/
#endif

    /* Initialize stack variables. */
    XMEMSET(&key, 0, sizeof(ed448_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(sig, 0, siglen);

    /* Initialize key. */
    ExpectIntEQ(wc_ed448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0);

    ExpectIntEQ(wc_ed448_sign_msg(msg, msglen, sig, &siglen, &key, NULL, 0), 0);
    ExpectIntEQ(siglen, ED448_SIG_SIZE);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_sign_msg(NULL, msglen, sig, &siglen, &key, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_sign_msg(msg, msglen, NULL, &siglen, &key, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_sign_msg(msg, msglen, sig, NULL, &key, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_sign_msg(msg, msglen, sig, &siglen, NULL, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_sign_msg(msg, msglen, sig, &badSigLen, &key, NULL, 0),
        WC_NO_ERR_TRACE(BUFFER_E));
    ExpectIntEQ(badSigLen, ED448_SIG_SIZE);
    badSigLen -= 1;

#ifdef HAVE_ED448_VERIFY
    ExpectIntEQ(wc_ed448_verify_msg(sig, siglen, msg, msglen, &verify_ok, &key,
        NULL, 0), 0);
    ExpectIntEQ(verify_ok, 1);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_verify_msg(sig, siglen - 1, msg, msglen, &verify_ok,
        &key, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_verify_msg(sig, siglen + 1, msg, msglen, &verify_ok,
        &key, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_verify_msg(NULL, siglen, msg, msglen, &verify_ok,
        &key, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_verify_msg(sig, siglen, NULL, msglen, &verify_ok,
        &key, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_verify_msg(sig, siglen, msg, msglen, NULL,
        &key, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_verify_msg(sig, siglen, msg, msglen, &verify_ok,
        NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_verify_msg(sig, badSigLen, msg, msglen, &verify_ok,
        &key, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif /* Verify. */

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed448_sign_msg */

/*
 * Testing wc_ed448_import_public()
 */
static int test_wc_ed448_import_public(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
    ed448_key  pubKey;
    WC_RNG     rng;
    const byte in[] =
                    "Ed448PublicKeyUnitTest.................................\n";
    word32     inlen = sizeof(in);

    XMEMSET(&pubKey, 0, sizeof(ed448_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed448_init(&pubKey), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &pubKey), 0);

    ExpectIntEQ(wc_ed448_import_public_ex(in, inlen, &pubKey, 1), 0);
    ExpectIntEQ(XMEMCMP(in, pubKey.p, inlen), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_import_public(NULL, inlen, &pubKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_import_public(in, inlen, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_import_public(in, inlen - 1, &pubKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed448_free(&pubKey);
#endif
    return EXPECT_RESULT();
} /* END wc_ed448_import_public */

/*
 * Testing wc_ed448_import_private_key()
 */
static int test_wc_ed448_import_private_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
    ed448_key  key;
    WC_RNG     rng;
    const byte privKey[] =
        "Ed448PrivateKeyUnitTest................................\n";
    const byte pubKey[] =
        "Ed448PublicKeyUnitTest.................................\n";
    word32     privKeySz = sizeof(privKey);
    word32     pubKeySz = sizeof(pubKey);
#ifdef HAVE_ED448_KEY_EXPORT
    byte       bothKeys[sizeof(privKey) + sizeof(pubKey)];
    word32     bothKeysSz = sizeof(bothKeys);
#endif

    XMEMSET(&key, 0, sizeof(ed448_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0);

    ExpectIntEQ(wc_ed448_import_private_key_ex(privKey, privKeySz, pubKey,
        pubKeySz, &key, 1), 0);
    ExpectIntEQ(XMEMCMP(pubKey, key.p, privKeySz), 0);
    ExpectIntEQ(XMEMCMP(privKey, key.k, pubKeySz), 0);

#ifdef HAVE_ED448_KEY_EXPORT
    PRIVATE_KEY_UNLOCK();
    ExpectIntEQ(wc_ed448_export_private(&key, bothKeys, &bothKeysSz), 0);
    PRIVATE_KEY_LOCK();
    ExpectIntEQ(wc_ed448_import_private_key_ex(bothKeys, bothKeysSz, NULL, 0,
        &key, 1), 0);
    ExpectIntEQ(XMEMCMP(pubKey, key.p, privKeySz), 0);
    ExpectIntEQ(XMEMCMP(privKey, key.k, pubKeySz), 0);
#endif

    /* Test bad args. */
    ExpectIntEQ(wc_ed448_import_private_key(NULL, privKeySz, pubKey, pubKeySz,
        &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_import_private_key(privKey, privKeySz, NULL, pubKeySz,
        &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_import_private_key(privKey, privKeySz, pubKey,
        pubKeySz, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_import_private_key(privKey, privKeySz - 1, pubKey,
        pubKeySz, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_import_private_key(privKey, privKeySz, pubKey,
        pubKeySz - 1, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_import_private_key(privKey, privKeySz, NULL, 0, &key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed448_import_private_key */

/*
 * Testing wc_ed448_export_public() and wc_ed448_export_private_only()
 */
static int test_wc_ed448_export(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
    ed448_key key;
    WC_RNG    rng;
    byte      priv[ED448_PRV_KEY_SIZE];
    byte      pub[ED448_PUB_KEY_SIZE];
    word32    privSz = sizeof(priv);
    word32    pubSz = sizeof(pub);

    XMEMSET(&key, 0, sizeof(ed448_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0);

    ExpectIntEQ(wc_ed448_export_public(&key, pub, &pubSz), 0);
    ExpectIntEQ(pubSz, ED448_KEY_SIZE);
    ExpectIntEQ(XMEMCMP(key.p, pub, pubSz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_export_public(NULL, pub, &pubSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_public(&key, NULL, &pubSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_public(&key, pub, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    PRIVATE_KEY_UNLOCK();
    ExpectIntEQ(wc_ed448_export_private_only(&key, priv, &privSz), 0);
    ExpectIntEQ(privSz, ED448_KEY_SIZE);
    ExpectIntEQ(XMEMCMP(key.k, priv, privSz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_export_private_only(NULL, priv, &privSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_private_only(&key, NULL, &privSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_private_only(&key, priv, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    PRIVATE_KEY_LOCK();

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed448_export */

/*
 *  Testing wc_ed448_size()
 */
static int test_wc_ed448_size(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448)
    ed448_key key;
    WC_RNG    rng;

    XMEMSET(&key, 0, sizeof(ed448_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0);

    ExpectIntEQ(wc_ed448_size(&key), ED448_KEY_SIZE);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed448_sig_size(&key), ED448_SIG_SIZE);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_sig_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed448_pub_size(&key), ED448_PUB_KEY_SIZE);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_pub_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed448_priv_size(&key), ED448_PRV_KEY_SIZE);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_priv_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed448_size */

/*
 * Testing wc_ed448_export_private() and wc_ed448_export_key()
 */
static int test_wc_ed448_exportKey(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
    ed448_key key;
    WC_RNG    rng;
    byte      priv[ED448_PRV_KEY_SIZE];
    byte      pub[ED448_PUB_KEY_SIZE];
    byte      privOnly[ED448_PRV_KEY_SIZE];
    word32    privSz      = sizeof(priv);
    word32    pubSz       = sizeof(pub);
    word32    privOnlySz  = sizeof(privOnly);

    XMEMSET(&key, 0, sizeof(ed448_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0);

    PRIVATE_KEY_UNLOCK();
    ExpectIntEQ(wc_ed448_export_private(&key, privOnly, &privOnlySz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_export_private(NULL, privOnly, &privOnlySz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_private(&key, NULL, &privOnlySz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_private(&key, privOnly, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed448_export_key(&key, priv, &privSz, pub, &pubSz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ed448_export_key(NULL, priv, &privSz, pub, &pubSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_key(&key, NULL, &privSz, pub, &pubSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_key(&key, priv, NULL, pub, &pubSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_key(&key, priv, &privSz, NULL, &pubSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ed448_export_key(&key, priv, &privSz, pub, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    PRIVATE_KEY_LOCK();

    /* Cross check output. */
    ExpectIntEQ(XMEMCMP(priv, privOnly, privSz), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ed448_exportKey */

/*
 * Testing wc_Ed448PublicKeyToDer
 */
static int test_wc_Ed448PublicKeyToDer(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
    ed448_key key;
    byte      derBuf[1024];

    XMEMSET(&key, 0, sizeof(ed448_key));

    /* Test bad args */
    ExpectIntEQ(wc_Ed448PublicKeyToDer(NULL, NULL, 0, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ed448_init(&key), 0);
    ExpectIntEQ(wc_Ed448PublicKeyToDer(&key, derBuf, 0, 0), WC_NO_ERR_TRACE(BUFFER_E));
    wc_ed448_free(&key);

    /*  Test good args */
    if (EXPECT_SUCCESS()) {
        WC_RNG rng;

        XMEMSET(&rng, 0, sizeof(WC_RNG));

        ExpectIntEQ(wc_ed448_init(&key), 0);
        ExpectIntEQ(wc_InitRng(&rng), 0);
        ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0);
        /* length only */
        ExpectIntGT(wc_Ed448PublicKeyToDer(&key, NULL, 0, 0), 0);
        ExpectIntGT(wc_Ed448PublicKeyToDer(&key, NULL, 0, 1), 0);
        ExpectIntGT(wc_Ed448PublicKeyToDer(&key, derBuf,
                    (word32)sizeof(derBuf), 1), 0);

        DoExpectIntEQ(wc_FreeRng(&rng), 0);
        wc_ed448_free(&key);
    }
#endif
    return EXPECT_RESULT();
} /* END testing wc_Ed448PublicKeyToDer */

/*
 * Testing wc_curve448_init and wc_curve448_free.
 */
static int test_wc_curve448_init(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448)
    curve448_key key;

    /* Test bad args for wc_curve448_init */
    ExpectIntEQ(wc_curve448_init(&key), 0);
    /* Test bad args for wc_curve448_init */
    ExpectIntEQ(wc_curve448_init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Test good args for wc_curve_448_free */
    wc_curve448_free(&key);
    /* Test bad args for wc_curve448_free */
    wc_curve448_free(NULL);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve448_init and wc_curve_448_free*/

/*
 * Testing wc_curve448_make_key
 */
static int test_wc_curve448_make_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448)
    curve448_key key;
    WC_RNG       rng;
    int          keysize = 0;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &key), 0);
    ExpectIntEQ(keysize = wc_curve448_size(&key), CURVE448_KEY_SIZE);
    ExpectIntEQ(wc_curve448_make_key(&rng, keysize, &key), 0);

    /* test bad cases */
    ExpectIntEQ(wc_curve448_make_key(NULL, 0, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_make_key(&rng, keysize, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_make_key(NULL, keysize, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_make_key(&rng, 0, &key), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve448_make_key*/
/*
 * Testing test_wc_curve448_shared_secret_ex
 */
static int test_wc_curve448_shared_secret_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448)
    curve448_key private_key;
    curve448_key public_key;
    WC_RNG       rng;
    byte         out[CURVE448_KEY_SIZE];
    word32       outLen = sizeof(out);
    int          endian = EC448_BIG_ENDIAN;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve448_init(&private_key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &private_key), 0);

    ExpectIntEQ(wc_curve448_init(&public_key), 0);
    ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &public_key), 0);
    ExpectIntEQ(wc_curve448_shared_secret_ex(&private_key, &public_key, out,
        &outLen, endian), 0);

    /* test bad cases */
    ExpectIntEQ(wc_curve448_shared_secret_ex(NULL, NULL, NULL, 0, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_shared_secret_ex(NULL, &public_key, out, &outLen,
        endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_shared_secret_ex(&private_key, NULL, out, &outLen,
        endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_shared_secret_ex(&private_key, &public_key, NULL,
        &outLen, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_shared_secret_ex(&private_key, &public_key, out,
        NULL, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    outLen = outLen - 2;
    ExpectIntEQ(wc_curve448_shared_secret_ex(&private_key, &public_key, out,
        &outLen, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve448_free(&private_key);
    wc_curve448_free(&public_key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve448_shared_secret_ex*/

/*
 * Testing test_wc_curve448_export_public_ex
 */
static int test_wc_curve448_export_public_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448)
    WC_RNG        rng;
    curve448_key  key;
    byte          out[CURVE448_KEY_SIZE];
    word32        outLen = sizeof(out);
    int           endian = EC448_BIG_ENDIAN;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &key), 0);

    ExpectIntEQ(wc_curve448_export_public(&key, out, &outLen), 0);
    ExpectIntEQ(wc_curve448_export_public_ex(&key, out, &outLen, endian), 0);
    /* test bad cases*/
    ExpectIntEQ(wc_curve448_export_public_ex(NULL, NULL, NULL, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_export_public_ex(NULL, out, &outLen, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_export_public_ex(&key, NULL, &outLen, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_export_public_ex(&key, out, NULL, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    outLen = outLen - 2;
    ExpectIntEQ(wc_curve448_export_public_ex(&key, out, &outLen, endian),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve448_export_public_ex*/

/*
 * Testing test_wc_curve448_export_private_raw_ex
 */
static int test_wc_curve448_export_private_raw_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448)
    curve448_key key;
    byte         out[CURVE448_KEY_SIZE];
    word32       outLen = sizeof(out);
    int          endian = EC448_BIG_ENDIAN;

    ExpectIntEQ(wc_curve448_init(&key), 0);
    ExpectIntEQ(wc_curve448_export_private_raw_ex(&key, out, &outLen, endian),
        0);
    /* test bad cases*/
    ExpectIntEQ(wc_curve448_export_private_raw_ex(NULL, NULL, NULL, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_export_private_raw_ex(NULL, out, &outLen, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_export_private_raw_ex(&key, NULL, &outLen, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_export_private_raw_ex(&key, out, NULL, endian),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_export_private_raw_ex(&key, out, &outLen,
        EC448_LITTLE_ENDIAN), 0);
    outLen = outLen - 2;
    ExpectIntEQ(wc_curve448_export_private_raw_ex(&key, out, &outLen, endian),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    wc_curve448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve448_export_private_raw_ex*/

/*
 * Testing test_wc_curve448_import_private_raw_ex
 */
static int test_wc_curve448_import_private_raw_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448)
    curve448_key key;
    WC_RNG       rng;
    byte         priv[CURVE448_KEY_SIZE];
    byte         pub[CURVE448_KEY_SIZE];
    word32       privSz = sizeof(priv);
    word32       pubSz = sizeof(pub);
    int          endian = EC448_BIG_ENDIAN;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &key), 0);

    ExpectIntEQ(wc_curve448_export_private_raw(&key, priv, &privSz), 0);
    ExpectIntEQ(wc_curve448_export_public(&key, pub, &pubSz), 0);
    ExpectIntEQ(wc_curve448_import_private_raw_ex(priv, privSz, pub, pubSz,
        &key, endian), 0);
    /* test bad cases */
    ExpectIntEQ(wc_curve448_import_private_raw_ex(NULL, 0, NULL, 0, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_import_private_raw_ex(NULL, privSz, pub, pubSz,
        &key, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_import_private_raw_ex(priv, privSz, NULL, pubSz,
        &key, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_import_private_raw_ex(priv, privSz, pub, pubSz,
        NULL, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_curve448_import_private_raw_ex(priv, 0, pub, pubSz,
        &key, endian), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_curve448_import_private_raw_ex(priv, privSz, pub, 0,
        &key, endian), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_curve448_import_private_raw_ex(priv, privSz, pub, pubSz,
        &key, EC448_LITTLE_ENDIAN), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve448_import_private_raw_ex*/
/*
 * Testing test_curve448_export_key_raw
 */
static int test_wc_curve448_export_key_raw(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448)
    curve448_key key;
    WC_RNG       rng;
    byte         priv[CURVE448_KEY_SIZE];
    byte         pub[CURVE448_KEY_SIZE];
    word32       privSz = sizeof(priv);
    word32       pubSz = sizeof(pub);

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &key), 0);

    ExpectIntEQ(wc_curve448_export_private_raw(&key, priv, &privSz), 0);
    ExpectIntEQ(wc_curve448_export_public(&key, pub, &pubSz), 0);
    ExpectIntEQ(wc_curve448_export_key_raw(&key, priv, &privSz, pub, &pubSz),
        0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve448_import_private_raw_ex*/

/*
 * Testing test_wc_curve448_import_private
 */
static int test_wc_curve448_import_private(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448)
    curve448_key key;
    WC_RNG       rng;
    byte         priv[CURVE448_KEY_SIZE];
    word32       privSz = sizeof(priv);

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve448_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &key), 0);

    ExpectIntEQ(wc_curve448_export_private_raw(&key, priv, &privSz), 0);
    ExpectIntEQ(wc_curve448_import_private(priv, privSz, &key), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve448_import*/
/*
 * Testing test_wc_curve448_size.
 */
static int test_wc_curve448_size(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448)
    curve448_key key;

    ExpectIntEQ(wc_curve448_init(&key), 0);

    /*  Test good args for wc_curve448_size */
    ExpectIntEQ(wc_curve448_size(&key), CURVE448_KEY_SIZE);
    /* Test bad args for wc_curve448_size */
    ExpectIntEQ(wc_curve448_size(NULL), 0);

    wc_curve448_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_curve448_size*/

/*
 * Testing wc_ecc_make_key.
 */
static int test_wc_ecc_make_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(WC_NO_RNG)
    ecc_key key;
    WC_RNG  rng;
    int     ret;

    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, KEY14, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_ecc_make_key(NULL, KEY14, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_make_key(&rng, KEY14, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_make_key */


/*
 * Testing wc_ecc_init()
 */
static int test_wc_ecc_init(void)
{
    EXPECT_DECLS;
#ifdef HAVE_ECC
    ecc_key key;

    XMEMSET(&key, 0, sizeof(ecc_key));

    ExpectIntEQ(wc_ecc_init(&key), 0);
    /* Pass in bad args. */
    ExpectIntEQ(wc_ecc_init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_ecc_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_init */

/*
 * Testing wc_ecc_check_key()
 */
static int test_wc_ecc_check_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(WC_NO_RNG)
    ecc_key key;
    WC_RNG  rng;
    int     ret;

    XMEMSET(&rng, 0, sizeof(rng));
    XMEMSET(&key, 0, sizeof(key));

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, KEY14, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntEQ(wc_ecc_check_key(&key), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_ecc_check_key(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_check_key */

/*
 * Testing wc_ecc_get_generator()
 */
static int test_wc_ecc_get_generator(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(WC_NO_RNG) && !defined(HAVE_SELFTEST) && \
    !defined(HAVE_FIPS) && defined(OPENSSL_EXTRA)
    ecc_point* pt = NULL;

    ExpectNotNull(pt = wc_ecc_new_point());

    ExpectIntEQ(wc_ecc_get_generator(pt, wc_ecc_get_curve_idx(ECC_SECP256R1)),
        MP_OKAY);

    /* Test bad args. */
    /* Returns Zero for bad arg. */
    ExpectIntNE(wc_ecc_get_generator(pt, -1), MP_OKAY);
    ExpectIntNE(wc_ecc_get_generator(NULL, wc_ecc_get_curve_idx(ECC_SECP256R1)),
        MP_OKAY);
    /* If we ever get to 1000 curves increase this number */
    ExpectIntNE(wc_ecc_get_generator(pt, 1000), MP_OKAY);
    ExpectIntNE(wc_ecc_get_generator(NULL, -1), MP_OKAY);

    wc_ecc_del_point(pt);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_get_generator */

/*
 * Testing wc_ecc_size()
 */
static int test_wc_ecc_size(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(WC_NO_RNG)
    WC_RNG      rng;
    ecc_key     key;
    int         ret;

    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, KEY14, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntEQ(wc_ecc_size(&key), KEY14);
    /* Test bad args. */
    /* Returns Zero for bad arg. */
    ExpectIntEQ(wc_ecc_size(NULL), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_size */

static int test_wc_ecc_params(void)
{
    EXPECT_DECLS;
    /* FIPS/CAVP self-test modules do not have `wc_ecc_get_curve_params`.
        It was added after certifications */
#if defined(HAVE_ECC) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
    const ecc_set_type* ecc_set = NULL;
#if !defined(NO_ECC256) && !defined(NO_ECC_SECP)
    /* Test for SECP256R1 curve */
    int curve_id = ECC_SECP256R1;
    int curve_idx = 0;

    ExpectIntNE(curve_idx = wc_ecc_get_curve_idx(curve_id), ECC_CURVE_INVALID);
    ExpectNotNull(ecc_set = wc_ecc_get_curve_params(curve_idx));
    ExpectIntEQ(ecc_set->id, curve_id);
#endif
    /* Test case when SECP256R1 is not enabled */
    /* Test that we get curve params for index 0 */
    ExpectNotNull(ecc_set = wc_ecc_get_curve_params(0));
#endif /* HAVE_ECC && !HAVE_FIPS && !HAVE_SELFTEST */
    return EXPECT_RESULT();
}

/*
 * Testing wc_ecc_sign_hash() and wc_ecc_verify_hash()
 */
static int test_wc_ecc_signVerify_hash(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) && !defined(NO_ASN) && !defined(WC_NO_RNG)
    ecc_key key;
    WC_RNG  rng;
    int     ret;
#ifdef HAVE_ECC_VERIFY
    int     verify = 0;
#endif
    word32  siglen = ECC_BUFSIZE;
    byte    sig[ECC_BUFSIZE];
    byte    adjustedSig[ECC_BUFSIZE+1];
    byte    digest[] = TEST_STRING;
    word32  digestlen = (word32)TEST_STRING_SZ;

    /* Init stack var */
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(sig, 0, siglen);
    XMEMSET(adjustedSig, 0, ECC_BUFSIZE+1);

    /* Init structs. */
    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, KEY14, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntEQ(wc_ecc_sign_hash(digest, digestlen, sig, &siglen, &rng, &key),
        0);

    /* Check bad args. */
    ExpectIntEQ(wc_ecc_sign_hash(NULL, digestlen, sig, &siglen, &rng, &key),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sign_hash(digest, digestlen, NULL, &siglen, &rng, &key),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sign_hash(digest, digestlen, sig, NULL, &rng, &key),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sign_hash(digest, digestlen, sig, &siglen, NULL, &key),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sign_hash(digest, digestlen, sig, &siglen, &rng, NULL),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

#ifdef HAVE_ECC_VERIFY
    ExpectIntEQ(wc_ecc_verify_hash(sig, siglen, digest, digestlen, &verify,
        &key), 0);
    ExpectIntEQ(verify, 1);

    /* test check on length of signature passed in */
    XMEMCPY(adjustedSig, sig, siglen);
    adjustedSig[1] = adjustedSig[1] + 1; /* add 1 to length for extra byte*/
#ifndef NO_STRICT_ECDSA_LEN
    ExpectIntNE(wc_ecc_verify_hash(adjustedSig, siglen+1, digest, digestlen,
        &verify, &key), 0);
#else
    /* if NO_STRICT_ECDSA_LEN is set then extra bytes after the signature
     * is allowed */
    ExpectIntEQ(wc_ecc_verify_hash(adjustedSig, siglen+1, digest, digestlen,
        &verify, &key), 0);
#endif

    /* Test bad args. */
    ExpectIntEQ(wc_ecc_verify_hash(NULL, siglen, digest, digestlen, &verify,
        &key), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_verify_hash(sig, siglen, NULL, digestlen, &verify, &key),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_verify_hash(sig, siglen, digest, digestlen, NULL, &key),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_verify_hash(sig, siglen, digest, digestlen, &verify,
        NULL), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
#endif /* HAVE_ECC_VERIFY */

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif
    return EXPECT_RESULT();
} /*  END test_wc_ecc_sign_hash */


/*
 * Testing wc_ecc_shared_secret()
 */
static int test_wc_ecc_shared_secret(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_DHE) && !defined(WC_NO_RNG)
    ecc_key     key;
    ecc_key     pubKey;
    WC_RNG      rng;
#if defined(NO_ECC256)
    int         ret;
#endif
    byte        out[KEY32];
    int         keySz = sizeof(out);
    word32      outlen = (word32)sizeof(out);

#if defined(HAVE_ECC) && !defined(NO_ECC256)
    const char* qx =
        "bb33ac4c27504ac64aa504c33cde9f36db722dce94ea2bfacb2009392c16e861";
    const char* qy =
        "02e9af4dd302939a315b9792217ff0cf18da9111023486e82058330b803489d8";
    const char* d  =
        "45b66902739c6c85a1385b72e8e8c7acc4038d533504fa6c28dc348de1a8098c";
    const char* curveName = "SECP256R1";
    const byte expected_shared_secret[] =
        {
            0x65, 0xc0, 0xd4, 0x61, 0x17, 0xe6, 0x09, 0x75,
            0xf0, 0x12, 0xa0, 0x4d, 0x0b, 0x41, 0x30, 0x7a,
            0x51, 0xf0, 0xb3, 0xaf, 0x23, 0x8f, 0x0f, 0xdf,
            0xf1, 0xff, 0x23, 0x64, 0x28, 0xca, 0xf8, 0x06
        };
#endif

    PRIVATE_KEY_UNLOCK();

    /* Initialize variables. */
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&pubKey, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(out, 0, keySz);

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_ecc_init(&pubKey), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);

#if !defined(NO_ECC256)
    ExpectIntEQ(wc_ecc_import_raw(&key, qx, qy, d, curveName), 0);
    ExpectIntEQ(wc_ecc_import_raw(&pubKey, qx, qy, NULL, curveName), 0);
#else
    ret = wc_ecc_make_key(&rng, keySz, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);
    ret = wc_ecc_make_key(&rng, keySz, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);
#endif

#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
    !defined(HAVE_SELFTEST)
    ExpectIntEQ(wc_ecc_set_rng(&key, &rng), 0);
#endif

    ExpectIntEQ(wc_ecc_shared_secret(&key, &pubKey, out, &outlen), 0);

#if !defined(NO_ECC256)
    ExpectIntEQ(XMEMCMP(out, expected_shared_secret, outlen), 0);
#endif

    /* Test bad args. */
    ExpectIntEQ(wc_ecc_shared_secret(NULL, &pubKey, out, &outlen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_shared_secret(&key, NULL, out, &outlen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_shared_secret(&key, &pubKey, NULL, &outlen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_shared_secret(&key, &pubKey, out, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Invalid length */
    outlen = 1;
    ExpectIntEQ(wc_ecc_shared_secret(&key, &pubKey, out, &outlen),
        WC_NO_ERR_TRACE(BUFFER_E));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&pubKey);
    wc_ecc_free(&key);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif

    PRIVATE_KEY_LOCK();
#endif
    return EXPECT_RESULT();
} /* END tests_wc_ecc_shared_secret */

/*
 * testint wc_ecc_export_x963()
 */
static int test_wc_ecc_export_x963(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG)
    ecc_key key;
    WC_RNG  rng;
    byte    out[ECC_ASN963_MAX_BUF_SZ];
    word32  outlen = sizeof(out);
    int     ret;

    PRIVATE_KEY_UNLOCK();

    /* Initialize variables. */
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(out, 0, outlen);

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, KEY20, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntEQ(wc_ecc_export_x963(&key, out, &outlen), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_ecc_export_x963(NULL, out, &outlen), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_export_x963(&key, NULL, &outlen), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectIntEQ(wc_ecc_export_x963(&key, out, NULL), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    key.idx = -4;
    ExpectIntEQ(wc_ecc_export_x963(&key, out, &outlen), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif

    PRIVATE_KEY_LOCK();
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_export_x963 */

/*
 * Testing wc_ecc_export_x963_ex()
 * compile with --enable-compkey will use compression.
 */
static int test_wc_ecc_export_x963_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG)
    ecc_key key;
    WC_RNG  rng;
    int     ret;
    byte    out[ECC_ASN963_MAX_BUF_SZ];
    word32  outlen = sizeof(out);
    #ifdef HAVE_COMP_KEY
        word32  badOutLen = 5;
    #endif

    /* Init stack variables. */
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(out, 0, outlen);
    PRIVATE_KEY_UNLOCK();

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, KEY64, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

#ifdef HAVE_COMP_KEY
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, out, &outlen, COMP), 0);
#else
    ExpectIntEQ(ret = wc_ecc_export_x963_ex(&key, out, &outlen, NOCOMP), 0);
#endif

    /* Test bad args. */
#ifdef HAVE_COMP_KEY
    ExpectIntEQ(wc_ecc_export_x963_ex(NULL, out, &outlen, COMP), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, NULL, &outlen, COMP), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, out, NULL, COMP), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#if defined(HAVE_FIPS) && (!defined(FIPS_VERSION_LT) || FIPS_VERSION_LT(5,3))
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, out, &badOutLen, COMP), WC_NO_ERR_TRACE(BUFFER_E));
#else
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, out, &badOutLen, COMP),
        WC_NO_ERR_TRACE(LENGTH_ONLY_E));
#endif
    key.idx = -4;
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, out, &outlen, COMP), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
#else
    ExpectIntEQ(wc_ecc_export_x963_ex(NULL, out, &outlen, NOCOMP),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, NULL, &outlen, NOCOMP),
        WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, out, &outlen, 1), WC_NO_ERR_TRACE(NOT_COMPILED_IN));
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, out, NULL, NOCOMP),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    key.idx = -4;
    ExpectIntEQ(wc_ecc_export_x963_ex(&key, out, &outlen, NOCOMP),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
#endif
    PRIVATE_KEY_LOCK();

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_export_x963_ex */

/*
 * testing wc_ecc_import_x963()
 */
static int test_wc_ecc_import_x963(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_IMPORT) && \
    defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG)
    ecc_key pubKey;
    ecc_key key;
    WC_RNG  rng;
    byte    x963[ECC_ASN963_MAX_BUF_SZ];
    word32  x963Len = (word32)sizeof(x963);
    int     ret;

    /* Init stack variables. */
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&pubKey, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(x963, 0, x963Len);

    ExpectIntEQ(wc_ecc_init(&pubKey), 0);
    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
#if FIPS_VERSION3_GE(6,0,0)
    ret = wc_ecc_make_key(&rng, KEY32, &key);
#else
    ret = wc_ecc_make_key(&rng, KEY24, &key);
#endif
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif

    ExpectIntEQ(ret, 0);

    PRIVATE_KEY_UNLOCK();
    ExpectIntEQ(wc_ecc_export_x963(&key, x963, &x963Len), 0);
    PRIVATE_KEY_LOCK();

    ExpectIntEQ(wc_ecc_import_x963(x963, x963Len, &pubKey), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_ecc_import_x963(NULL, x963Len, &pubKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_import_x963(x963, x963Len, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_import_x963(x963, x963Len + 1, &pubKey), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);
    wc_ecc_free(&pubKey);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif
    return EXPECT_RESULT();
} /* END wc_ecc_import_x963 */

/*
 * testing wc_ecc_import_private_key()
 */
static int test_wc_ecc_import_private_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_IMPORT) && \
    defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG)
    ecc_key key;
    ecc_key keyImp;
    WC_RNG  rng;
    byte    privKey[ECC_PRIV_KEY_BUF]; /* Raw private key.*/
    byte    x963Key[ECC_ASN963_MAX_BUF_SZ];
    word32  privKeySz = (word32)sizeof(privKey);
    word32  x963KeySz = (word32)sizeof(x963Key);
    int     ret;

    /* Init stack variables. */
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&keyImp, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(privKey, 0, privKeySz);
    XMEMSET(x963Key, 0, x963KeySz);
    PRIVATE_KEY_UNLOCK();

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_ecc_init(&keyImp), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, KEY48, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    PRIVATE_KEY_UNLOCK();
    ExpectIntEQ(wc_ecc_export_x963(&key, x963Key, &x963KeySz), 0);
    PRIVATE_KEY_LOCK();
    ExpectIntEQ(wc_ecc_export_private_only(&key, privKey, &privKeySz), 0);

    ExpectIntEQ(wc_ecc_import_private_key(privKey, privKeySz, x963Key,
        x963KeySz, &keyImp), 0);
    /* Pass in bad args. */
    ExpectIntEQ(wc_ecc_import_private_key(privKey, privKeySz, x963Key,
        x963KeySz, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_import_private_key(NULL, privKeySz, x963Key, x963KeySz,
        &keyImp), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    PRIVATE_KEY_LOCK();

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&keyImp);
    wc_ecc_free(&key);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_import_private_key */


/*
 * Testing wc_ecc_export_private_only()
 */
static int test_wc_ecc_export_private_only(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG)
    ecc_key key;
    WC_RNG  rng;
    byte    out[ECC_PRIV_KEY_BUF];
    word32  outlen = sizeof(out);
    int     ret;

    /* Init stack variables. */
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(out, 0, outlen);
    PRIVATE_KEY_UNLOCK();

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, KEY32, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntEQ(wc_ecc_export_private_only(&key, out, &outlen), 0);
    /* Pass in bad args. */
    ExpectIntEQ(wc_ecc_export_private_only(NULL, out, &outlen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_export_private_only(&key, NULL, &outlen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_export_private_only(&key, out, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    PRIVATE_KEY_LOCK();

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_export_private_only */


/*
 * Testing wc_ecc_rs_to_sig()
 */
static int test_wc_ecc_rs_to_sig(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(NO_ASN)
    /* first [P-192,SHA-1] vector from FIPS 186-3 NIST vectors */
    const char* R = "6994d962bdd0d793ffddf855ec5bf2f91a9698b46258a63e";
    const char* S = "02ba6465a234903744ab02bc8521405b73cf5fc00e1a9f41";
    const char* zeroStr = "0";
    byte        sig[ECC_MAX_SIG_SIZE];
    word32      siglen = (word32)sizeof(sig);
    /* R and S max size is the order of curve. 2^192.*/
    int         keySz = KEY24;
    byte        r[KEY24];
    byte        s[KEY24];
    word32      rlen = (word32)sizeof(r);
    word32      slen = (word32)sizeof(s);

    /* Init stack variables. */
    XMEMSET(sig, 0, ECC_MAX_SIG_SIZE);
    XMEMSET(r, 0, keySz);
    XMEMSET(s, 0, keySz);

    ExpectIntEQ(wc_ecc_rs_to_sig(R, S, sig, &siglen), 0);
    ExpectIntEQ(wc_ecc_sig_to_rs(sig, siglen, r, &rlen, s, &slen), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_rs_to_sig(NULL, S, sig, &siglen), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_rs_to_sig(R, NULL, sig, &siglen), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_rs_to_sig(R, S, sig, NULL), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_rs_to_sig(R, S, NULL, &siglen), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_rs_to_sig(R, zeroStr, sig, &siglen), WC_NO_ERR_TRACE(MP_ZERO_E));
    ExpectIntEQ(wc_ecc_rs_to_sig(zeroStr, S, sig, &siglen), WC_NO_ERR_TRACE(MP_ZERO_E));
    ExpectIntEQ(wc_ecc_sig_to_rs(NULL, siglen, r, &rlen, s, &slen),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sig_to_rs(sig, siglen, NULL, &rlen, s, &slen),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sig_to_rs(sig, siglen, r, NULL, s, &slen),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sig_to_rs(sig, siglen, r, &rlen, NULL, &slen),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sig_to_rs(sig, siglen, r, &rlen, s, NULL),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_rs_to_sig */

static int test_wc_ecc_import_raw(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(NO_ECC256)
    ecc_key     key;
    const char* qx =
        "bb33ac4c27504ac64aa504c33cde9f36db722dce94ea2bfacb2009392c16e861";
    const char* qy =
        "02e9af4dd302939a315b9792217ff0cf18da9111023486e82058330b803489d8";
    const char* d  =
        "45b66902739c6c85a1385b72e8e8c7acc4038d533504fa6c28dc348de1a8098c";
    const char* curveName = "SECP256R1";
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
    const char* kNullStr = "";
    int ret;
#endif

    XMEMSET(&key, 0, sizeof(ecc_key));

    ExpectIntEQ(wc_ecc_init(&key), 0);

    /* Test good import */
    ExpectIntEQ(wc_ecc_import_raw(&key, qx, qy, d, curveName), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_ecc_import_raw(NULL, qx, qy, d, curveName), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_import_raw(&key, NULL, qy, d, curveName), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_import_raw(&key, qx, NULL, d, curveName), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_import_raw(&key, qx, qy, d, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
    #if !defined(USE_FAST_MATH) && !defined(WOLFSSL_SP_MATH)
        wc_ecc_free(&key);
    #endif
    ExpectIntLT(ret = wc_ecc_import_raw(&key, kNullStr, kNullStr, kNullStr,
        curveName), 0);
    ExpectTrue((ret == WC_NO_ERR_TRACE(ECC_INF_E)) || (ret == WC_NO_ERR_TRACE(BAD_FUNC_ARG)));
#endif
#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
    #if !defined(USE_FAST_MATH) && !defined(WOLFSSL_SP_MATH)
        wc_ecc_free(&key);
    #endif
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
    ExpectIntLT(ret = wc_ecc_import_raw(&key, "0", qy, d, curveName), 0);
    ExpectTrue((ret == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) || (ret == WC_NO_ERR_TRACE(MP_VAL)));
#else
    ExpectIntEQ(wc_ecc_import_raw(&key, "0", qy, d, curveName), 0);
#endif
    #if !defined(USE_FAST_MATH) && !defined(WOLFSSL_SP_MATH)
        wc_ecc_free(&key);
    #endif
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
    ExpectIntLT(ret = wc_ecc_import_raw(&key, qx, "0", d, curveName), 0);
    ExpectTrue((ret == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) || (ret == WC_NO_ERR_TRACE(MP_VAL)));
#else
    ExpectIntEQ(wc_ecc_import_raw(&key, qx, "0", d, curveName), 0);
#endif
    #if !defined(USE_FAST_MATH) && !defined(WOLFSSL_SP_MATH)
        wc_ecc_free(&key);
    #endif
    ExpectIntEQ(wc_ecc_import_raw(&key, "0", "0", d, curveName), WC_NO_ERR_TRACE(ECC_INF_E));
#endif

    wc_ecc_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_import_raw */

static int test_wc_ecc_import_unsigned(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(NO_ECC256) && !defined(HAVE_SELFTEST) && \
    (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
     HAVE_FIPS_VERSION >= 2))
    ecc_key    key;
    const byte qx[] = {
        0xbb, 0x33, 0xac, 0x4c, 0x27, 0x50, 0x4a, 0xc6,
        0x4a, 0xa5, 0x04, 0xc3, 0x3c, 0xde, 0x9f, 0x36,
        0xdb, 0x72, 0x2d, 0xce, 0x94, 0xea, 0x2b, 0xfa,
        0xcb, 0x20, 0x09, 0x39, 0x2c, 0x16, 0xe8, 0x61
    };
    const byte qy[] = {
        0x02, 0xe9, 0xaf, 0x4d, 0xd3, 0x02, 0x93, 0x9a,
        0x31, 0x5b, 0x97, 0x92, 0x21, 0x7f, 0xf0, 0xcf,
        0x18, 0xda, 0x91, 0x11, 0x02, 0x34, 0x86, 0xe8,
        0x20, 0x58, 0x33, 0x0b, 0x80, 0x34, 0x89, 0xd8
    };
    const byte d[] = {
        0x45, 0xb6, 0x69, 0x02, 0x73, 0x9c, 0x6c, 0x85,
        0xa1, 0x38, 0x5b, 0x72, 0xe8, 0xe8, 0xc7, 0xac,
        0xc4, 0x03, 0x8d, 0x53, 0x35, 0x04, 0xfa, 0x6c,
        0x28, 0xdc, 0x34, 0x8d, 0xe1, 0xa8, 0x09, 0x8c
    };
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
    const byte nullBytes[32] = {0};
    int ret;
#endif
    int        curveId = ECC_SECP256R1;

    XMEMSET(&key, 0, sizeof(ecc_key));

    ExpectIntEQ(wc_ecc_init(&key), 0);

    ExpectIntEQ(wc_ecc_import_unsigned(&key, (byte*)qx, (byte*)qy, (byte*)d,
        curveId), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_import_unsigned(NULL, (byte*)qx, (byte*)qy, (byte*)d,
        curveId), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_import_unsigned(&key, NULL, (byte*)qy, (byte*)d,
        curveId), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_import_unsigned(&key, (byte*)qx, NULL, (byte*)d,
        curveId), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_import_unsigned(&key, (byte*)qx, (byte*)qy, (byte*)d,
        ECC_CURVE_INVALID), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
    ExpectIntLT(ret = wc_ecc_import_unsigned(&key, (byte*)nullBytes,
        (byte*)nullBytes, (byte*)nullBytes, curveId), 0);
    ExpectTrue((ret == WC_NO_ERR_TRACE(ECC_INF_E)) || (ret == WC_NO_ERR_TRACE(BAD_FUNC_ARG)));
#endif

    wc_ecc_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_import_unsigned */


/*
 * Testing wc_ecc_sig_size()
 */
static int test_wc_ecc_sig_size(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(WC_NO_RNG)
    ecc_key key;
    WC_RNG  rng;
    int     keySz = KEY16;
    int     ret;

    XMEMSET(&rng, 0, sizeof(rng));
    XMEMSET(&key, 0, sizeof(key));

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, keySz, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntLE(wc_ecc_sig_size(&key),
         (2 * keySz + SIG_HEADER_SZ + ECC_MAX_PAD_SZ));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_sig_size */

/*
 * Testing wc_ecc_ctx_new()
 */
static int test_wc_ecc_ctx_new(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_ENCRYPT) && !defined(WC_NO_RNG)
    WC_RNG    rng;
    ecEncCtx* cli = NULL;
    ecEncCtx* srv = NULL;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectNotNull(cli = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng));
    ExpectNotNull(srv = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng));
    wc_ecc_ctx_free(cli);
    cli = NULL;
    wc_ecc_ctx_free(srv);

    /* Test bad args. */
    /* wc_ecc_ctx_new_ex() will free if returned NULL. */
    ExpectNull(cli = wc_ecc_ctx_new(0, &rng));
    ExpectNull(cli = wc_ecc_ctx_new(REQ_RESP_CLIENT, NULL));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_ctx_free(cli);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_ctx_new */

/*
 * Tesing wc_ecc_reset()
 */
static int test_wc_ecc_ctx_reset(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_ENCRYPT) && !defined(WC_NO_RNG)
    ecEncCtx* ctx = NULL;
    WC_RNG    rng;

    XMEMSET(&rng, 0, sizeof(rng));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectNotNull(ctx = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng));

    ExpectIntEQ(wc_ecc_ctx_reset(ctx, &rng), 0);

    /* Pass in bad args. */
    ExpectIntEQ(wc_ecc_ctx_reset(NULL, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_ctx_reset(ctx, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_ecc_ctx_free(ctx);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_ctx_reset */

/*
 * Testing wc_ecc_ctx_set_peer_salt() and wc_ecc_ctx_get_own_salt()
 */
static int test_wc_ecc_ctx_set_peer_salt(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_ENCRYPT) && !defined(WC_NO_RNG)
    WC_RNG      rng;
    ecEncCtx*   cliCtx      = NULL;
    ecEncCtx*   servCtx     = NULL;
    const byte* cliSalt     = NULL;
    const byte* servSalt    = NULL;

    XMEMSET(&rng, 0, sizeof(rng));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectNotNull(cliCtx = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng));
    ExpectNotNull(servCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng));

    /* Test bad args. */
    ExpectNull(cliSalt = wc_ecc_ctx_get_own_salt(NULL));

    ExpectNotNull(cliSalt = wc_ecc_ctx_get_own_salt(cliCtx));
    ExpectNotNull(servSalt = wc_ecc_ctx_get_own_salt(servCtx));

    ExpectIntEQ(wc_ecc_ctx_set_peer_salt(cliCtx, servSalt), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_ctx_set_peer_salt(NULL, servSalt), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_ctx_set_peer_salt(cliCtx, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_ecc_ctx_free(cliCtx);
    wc_ecc_ctx_free(servCtx);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();

} /* END test_wc_ecc_ctx_set_peer_salt */

/*
 * Testing wc_ecc_ctx_set_info()
 */
static int test_wc_ecc_ctx_set_info(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_ENCRYPT) && !defined(WC_NO_RNG)
    ecEncCtx*   ctx = NULL;
    WC_RNG      rng;
    const char* optInfo = "Optional Test Info.";
    int         optInfoSz = (int)XSTRLEN(optInfo);
    const char* badOptInfo = NULL;

    XMEMSET(&rng, 0, sizeof(rng));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectNotNull(ctx = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng));

    ExpectIntEQ(wc_ecc_ctx_set_info(ctx, (byte*)optInfo, optInfoSz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_ctx_set_info(NULL, (byte*)optInfo, optInfoSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_ctx_set_info(ctx, (byte*)badOptInfo, optInfoSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_ctx_set_info(ctx, (byte*)optInfo, -1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_ecc_ctx_free(ctx);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_ctx_set_info */

/*
 * Testing wc_ecc_encrypt() and wc_ecc_decrypt()
 */
static int test_wc_ecc_encryptDecrypt(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_ENCRYPT) && !defined(WC_NO_RNG) && \
    defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
    ecc_key     srvKey;
    ecc_key     cliKey;
    ecc_key     tmpKey;
    WC_RNG      rng;
    int         ret;
    const char* msg   = "EccBlock Size 16";
    word32      msgSz = (word32)XSTRLEN("EccBlock Size 16");
#ifdef WOLFSSL_ECIES_OLD
    byte        out[(sizeof("EccBlock Size 16") - 1) + WC_SHA256_DIGEST_SIZE];
#elif defined(WOLFSSL_ECIES_GEN_IV)
    byte        out[KEY20 * 2 + 1 + AES_BLOCK_SIZE +
                    (sizeof("EccBlock Size 16") - 1) + WC_SHA256_DIGEST_SIZE];
#else
    byte        out[KEY20 * 2 + 1 + (sizeof("EccBlock Size 16") - 1) +
                    WC_SHA256_DIGEST_SIZE];
#endif
    word32      outSz = (word32)sizeof(out);
    byte        plain[sizeof("EccBlock Size 16")];
    word32      plainSz = (word32)sizeof(plain);
    int         keySz = KEY20;

    /* Init stack variables. */
    XMEMSET(out, 0, outSz);
    XMEMSET(plain, 0, plainSz);
    XMEMSET(&rng, 0, sizeof(rng));
    XMEMSET(&srvKey, 0, sizeof(ecc_key));
    XMEMSET(&cliKey, 0, sizeof(ecc_key));
    XMEMSET(&tmpKey, 0, sizeof(ecc_key));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ecc_init(&cliKey), 0);
    ret = wc_ecc_make_key(&rng, keySz, &cliKey);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &cliKey.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntEQ(wc_ecc_init(&srvKey), 0);
    ret = wc_ecc_make_key(&rng, keySz, &srvKey);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &srvKey.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntEQ(wc_ecc_init(&tmpKey), 0);

#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
    !defined(HAVE_SELFTEST)
    ExpectIntEQ(wc_ecc_set_rng(&srvKey, &rng), 0);
    ExpectIntEQ(wc_ecc_set_rng(&cliKey, &rng), 0);
#endif

    ExpectIntEQ(wc_ecc_encrypt(&cliKey, &srvKey, (byte*)msg, msgSz, out,
        &outSz, NULL), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_encrypt(NULL, &srvKey, (byte*)msg, msgSz, out, &outSz,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_encrypt(&cliKey, NULL, (byte*)msg, msgSz, out, &outSz,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_encrypt(&cliKey, &srvKey, NULL, msgSz, out, &outSz,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_encrypt(&cliKey, &srvKey, (byte*)msg, msgSz, NULL,
        &outSz, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_encrypt(&cliKey, &srvKey, (byte*)msg, msgSz, out, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#ifdef WOLFSSL_ECIES_OLD
    tmpKey.dp = cliKey.dp;
    ExpectIntEQ(wc_ecc_copy_point(&cliKey.pubkey, &tmpKey.pubkey), 0);
#endif

    ExpectIntEQ(wc_ecc_decrypt(&srvKey, &tmpKey, out, outSz, plain, &plainSz,
         NULL), 0);
    ExpectIntEQ(wc_ecc_decrypt(NULL, &tmpKey, out, outSz, plain, &plainSz,
         NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_ECIES_OLD
    /* NULL parameter allowed in new implementations - public key comes from
     * the message. */
    ExpectIntEQ(wc_ecc_decrypt(&srvKey, NULL, out, outSz, plain, &plainSz,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wc_ecc_decrypt(&srvKey, &tmpKey, NULL, outSz, plain, &plainSz,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_decrypt(&srvKey, &tmpKey, out, outSz, NULL, &plainSz,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_decrypt(&srvKey, &tmpKey, out, outSz, plain, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(XMEMCMP(msg, plain, msgSz), 0);

    wc_ecc_free(&tmpKey);
    wc_ecc_free(&srvKey);
    wc_ecc_free(&cliKey);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_encryptDecrypt */

/*
 * Testing wc_ecc_del_point() and wc_ecc_new_point()
 */
static int test_wc_ecc_del_point(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC)
    ecc_point* pt = NULL;

    ExpectNotNull(pt = wc_ecc_new_point());
    wc_ecc_del_point(pt);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_del_point */

/*
 * Testing wc_ecc_point_is_at_infinity(), wc_ecc_export_point_der(),
 * wc_ecc_import_point_der(), wc_ecc_copy_point(), wc_ecc_point_is_on_curve(),
 * and wc_ecc_cmp_point()
 */
static int test_wc_ecc_pointFns(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
    !defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A) && \
    !defined(WOLFSSL_ATECC608A)
    ecc_key    key;
    WC_RNG     rng;
    int        ret;
    ecc_point* point = NULL;
    ecc_point* cpypt = NULL;
    int        idx = 0;
    int        keySz = KEY32;
    byte       der[DER_SZ(KEY32)];
    word32     derlenChk = 0;
    word32     derSz = DER_SZ(KEY32);

    /* Init stack variables. */
    XMEMSET(der, 0, derSz);
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ecc_init(&key), 0);
    ret = wc_ecc_make_key(&rng, keySz, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectNotNull(point = wc_ecc_new_point());
    ExpectNotNull(cpypt = wc_ecc_new_point());

    /* Export */
    ExpectIntEQ(wc_ecc_export_point_der((idx = key.idx), &key.pubkey, NULL,
        &derlenChk), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    /* Check length value. */
    ExpectIntEQ(derSz, derlenChk);
    ExpectIntEQ(wc_ecc_export_point_der((idx = key.idx), &key.pubkey, der,
        &derSz), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_export_point_der(-2, &key.pubkey, der, &derSz),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_export_point_der((idx = key.idx), NULL, der, &derSz),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_export_point_der((idx = key.idx), &key.pubkey, der,
        NULL), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    /* Import */
    ExpectIntEQ(wc_ecc_import_point_der(der, derSz, idx, point), 0);
    ExpectIntEQ(wc_ecc_cmp_point(&key.pubkey, point), 0);
    /* Test bad args. */
    ExpectIntEQ( wc_ecc_import_point_der(NULL, derSz, idx, point),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_import_point_der(der, derSz, idx, NULL), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_import_point_der(der, derSz, -1, point), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_import_point_der(der, derSz + 1, idx, point),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    /* Copy */
    ExpectIntEQ(wc_ecc_copy_point(point, cpypt), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_copy_point(NULL, cpypt), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_copy_point(point, NULL), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    /* Compare point */
    ExpectIntEQ(wc_ecc_cmp_point(point, cpypt), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_cmp_point(NULL, cpypt), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_cmp_point(point, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* At infinity if return == 1, otherwise return == 0. */
    ExpectIntEQ(wc_ecc_point_is_at_infinity(point), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_point_is_at_infinity(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)))
#ifdef USE_ECC_B_PARAM
    /* On curve if ret == 0 */
    ExpectIntEQ(wc_ecc_point_is_on_curve(point, idx), 0);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_point_is_on_curve(NULL, idx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_point_is_on_curve(point, 1000), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
#endif /* USE_ECC_B_PARAM */
#endif /* !HAVE_SELFTEST && (!HAVE_FIPS || HAVE_FIPS_VERSION > 2) */

    /* Free */
    wc_ecc_del_point(point);
    wc_ecc_del_point(cpypt);
    wc_ecc_free(&key);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_pointFns */


/*
 * Testing wc_ecc_shared_secret_ssh()
 */
static int test_wc_ecc_shared_secret_ssh(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_DHE) && \
    !defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A) && \
    !defined(WOLFSSL_ATECC608A) && !defined(PLUTON_CRYPTO_ECC) && \
    !defined(WOLFSSL_CRYPTOCELL)
    ecc_key key;
    ecc_key key2;
    WC_RNG  rng;
    int     ret;
    int     keySz = KEY32;
#if FIPS_VERSION3_GE(6,0,0)
    int     key2Sz = KEY28;
#else
    int     key2Sz = KEY24;
#endif
    byte    secret[KEY32];
    word32  secretLen = (word32)keySz;

    /* Init stack variables. */
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&key2, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(secret, 0, secretLen);
    PRIVATE_KEY_UNLOCK();

    /* Make keys */
    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, keySz, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);

    ExpectIntEQ(wc_ecc_init(&key2), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, key2Sz, &key2);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key2.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
    !defined(HAVE_SELFTEST)
    ExpectIntEQ(wc_ecc_set_rng(&key, &rng), 0);
#endif

    ExpectIntEQ(wc_ecc_shared_secret_ssh(&key, &key2.pubkey, secret,
        &secretLen), 0);
    /* Pass in bad args. */
    ExpectIntEQ(wc_ecc_shared_secret_ssh(NULL, &key2.pubkey, secret,
        &secretLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_shared_secret_ssh(&key, NULL, secret, &secretLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_shared_secret_ssh(&key, &key2.pubkey, NULL, &secretLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_shared_secret_ssh(&key, &key2.pubkey, secret, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    key.type = ECC_PUBLICKEY;
    ExpectIntEQ(wc_ecc_shared_secret_ssh(&key, &key2.pubkey, secret,
        &secretLen), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    PRIVATE_KEY_LOCK();

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);
    wc_ecc_free(&key2);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_shared_secret_ssh */

/*
 * Testing wc_ecc_verify_hash_ex() and wc_ecc_verify_hash_ex()
 */
static int test_wc_ecc_verify_hash_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) && defined(WOLFSSL_PUBLIC_MP) \
    && !defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A) && \
       !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_KCAPI_ECC)
    ecc_key       key;
    WC_RNG        rng;
    int           ret;
    mp_int        r;
    mp_int        s;
    mp_int        z;
    unsigned char hash[] = "Everyone gets Friday off.EccSig";
    unsigned char iHash[] = "Everyone gets Friday off.......";
    unsigned char shortHash[] = TEST_STRING;
    word32        hashlen = sizeof(hash);
    word32        iHashLen = sizeof(iHash);
    word32        shortHashLen = sizeof(shortHash);
    int           keySz = KEY32;
    int           verify_ok = 0;

    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(&r, 0, sizeof(mp_int));
    XMEMSET(&s, 0, sizeof(mp_int));
    XMEMSET(&z, 0, sizeof(mp_int));

    /* Initialize r, s and z. */
    ExpectIntEQ(mp_init_multi(&r, &s, &z, NULL, NULL, NULL), MP_OKAY);

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, keySz, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntEQ(wc_ecc_sign_hash_ex(hash, hashlen, &rng, &key, &r, &s), 0);
    /* verify_ok should be 1. */
    ExpectIntEQ(wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, &verify_ok, &key),
        0);
    ExpectIntEQ(verify_ok, 1);

    /* verify_ok should be 0 */
    ExpectIntEQ(wc_ecc_verify_hash_ex(&r, &s, iHash, iHashLen, &verify_ok,
        &key), 0);
    ExpectIntEQ(verify_ok, 0);

    /* verify_ok should be 0. */
    ExpectIntEQ(wc_ecc_verify_hash_ex(&r, &s, shortHash, shortHashLen,
        &verify_ok, &key), 0);
    ExpectIntEQ(verify_ok, 0);

    /* Test bad args. */
    ExpectIntEQ(wc_ecc_sign_hash_ex(NULL, hashlen, &rng, &key, &r, &s),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sign_hash_ex(hash, hashlen, NULL, &key, &r, &s),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sign_hash_ex(hash, hashlen, &rng, NULL, &r, &s),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sign_hash_ex(hash, hashlen, &rng, &key, NULL, &s),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_sign_hash_ex(hash, hashlen, &rng, &key, &r, NULL),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_verify_hash_ex(NULL, &s, shortHash, shortHashLen,
        &verify_ok, &key), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_verify_hash_ex(&r, NULL, shortHash, shortHashLen,
        &verify_ok, &key), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_verify_hash_ex(&z, &s, shortHash, shortHashLen,
        &verify_ok, &key), WC_NO_ERR_TRACE(MP_ZERO_E));
    ExpectIntEQ(wc_ecc_verify_hash_ex(&r, &z, shortHash, shortHashLen,
        &verify_ok, &key), WC_NO_ERR_TRACE(MP_ZERO_E));
    ExpectIntEQ(wc_ecc_verify_hash_ex(&z, &z, shortHash, shortHashLen,
        &verify_ok, &key), WC_NO_ERR_TRACE(MP_ZERO_E));
    ExpectIntEQ(wc_ecc_verify_hash_ex(&r, &s, NULL, shortHashLen, &verify_ok,
        &key), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_verify_hash_ex(&r, &s, shortHash, shortHashLen, NULL,
        &key), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_verify_hash_ex(&r, &s, shortHash, shortHashLen,
        &verify_ok, NULL), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    wc_ecc_free(&key);
    mp_free(&r);
    mp_free(&s);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_verify_hash_ex */

/*
 * Testing wc_ecc_mulmod()
 */

static int test_wc_ecc_mulmod(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(WC_NO_RNG) && \
    !(defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
      defined(WOLFSSL_VALIDATE_ECC_IMPORT))
    ecc_key     key1;
    ecc_key     key2;
    ecc_key     key3;
    WC_RNG      rng;
    int         ret;

    XMEMSET(&key1, 0, sizeof(ecc_key));
    XMEMSET(&key2, 0, sizeof(ecc_key));
    XMEMSET(&key3, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ecc_init(&key1), 0);
    ExpectIntEQ(wc_ecc_init(&key2), 0);
    ExpectIntEQ(wc_ecc_init(&key3), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, KEY32, &key1);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key1.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);

    ExpectIntEQ(wc_ecc_import_raw_ex(&key2, key1.dp->Gx, key1.dp->Gy,
        key1.dp->Af, ECC_SECP256R1), 0);
    ExpectIntEQ(wc_ecc_import_raw_ex(&key3, key1.dp->Gx, key1.dp->Gy,
        key1.dp->prime, ECC_SECP256R1), 0);

    ExpectIntEQ(wc_ecc_mulmod(wc_ecc_key_get_priv(&key1), &key2.pubkey,
        &key3.pubkey, wc_ecc_key_get_priv(&key2), wc_ecc_key_get_priv(&key3),
        1), 0);

    /* Test bad args. */
    ExpectIntEQ(ret = wc_ecc_mulmod(NULL, &key2.pubkey, &key3.pubkey,
        wc_ecc_key_get_priv(&key2), wc_ecc_key_get_priv(&key3), 1),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_mulmod(wc_ecc_key_get_priv(&key1), NULL, &key3.pubkey,
        wc_ecc_key_get_priv(&key2), wc_ecc_key_get_priv(&key3), 1),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_mulmod(wc_ecc_key_get_priv(&key1), &key2.pubkey, NULL,
        wc_ecc_key_get_priv(&key2), wc_ecc_key_get_priv(&key3), 1),
        WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
    ExpectIntEQ(wc_ecc_mulmod(wc_ecc_key_get_priv(&key1), &key2.pubkey,
        &key3.pubkey, wc_ecc_key_get_priv(&key2), NULL, 1), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

    wc_ecc_free(&key1);
    wc_ecc_free(&key2);
    wc_ecc_free(&key3);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif /* HAVE_ECC && !WOLFSSL_ATECC508A */
    return EXPECT_RESULT();
} /* END test_wc_ecc_mulmod */

/*
 * Testing wc_ecc_is_valid_idx()
 */
static int test_wc_ecc_is_valid_idx(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(WC_NO_RNG)
    ecc_key key;
    WC_RNG  rng;
    int     ret;
    int     iVal = -2;
    int     iVal2 = 3000;

    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, 32, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    ExpectIntEQ(wc_ecc_is_valid_idx(key.idx), 1);
    /* Test bad args. */
    ExpectIntEQ(wc_ecc_is_valid_idx(iVal), 0);
    ExpectIntEQ(wc_ecc_is_valid_idx(iVal2), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_is_valid_idx */

/*
 * Testing wc_ecc_get_curve_id_from_oid()
 */
static int test_wc_ecc_get_curve_id_from_oid(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(NO_ECC256) && !defined(HAVE_SELFTEST) && \
    !defined(HAVE_FIPS)
    const byte oid[] = {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07};
    word32 len = sizeof(oid);

    /* Bad Cases */
    ExpectIntEQ(wc_ecc_get_curve_id_from_oid(NULL, len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_get_curve_id_from_oid(oid, 0), ECC_CURVE_INVALID);
    /* Good Case */
    ExpectIntEQ(wc_ecc_get_curve_id_from_oid(oid, len), ECC_SECP256R1);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_get_curve_id_from_oid */

/*
 * Testing wc_ecc_sig_size_calc()
 */
static int test_wc_ecc_sig_size_calc(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(WC_NO_RNG) && !defined(HAVE_SELFTEST)
    ecc_key key;
    WC_RNG  rng;
    int     sz = 0;
    int     ret;

    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ret = wc_ecc_make_key(&rng, 16, &key);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
#if FIPS_VERSION3_GE(6,0,0)
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#else
    ExpectIntEQ(ret, 0);
#endif
#if FIPS_VERSION3_LT(6,0,0)
    sz = key.dp->size;
    ExpectIntGT(wc_ecc_sig_size_calc(sz), 0);
#else
    (void) sz;
#endif

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ecc_free(&key);
#endif
    return EXPECT_RESULT();
} /* END test_wc_ecc_sig_size_calc */

/*
 * Testing wc_ecc_sm2_make_key()
 */
static int test_wc_ecc_sm2_make_key(void)
{
    int res = TEST_SKIPPED;
#if defined(HAVE_ECC) && defined(WOLFSSL_SM2)
    EXPECT_DECLS;
    WC_RNG  rng[1];
    ecc_key key[1];

    XMEMSET(rng, 0, sizeof(*rng));
    XMEMSET(key, 0, sizeof(*key));

    ExpectIntEQ(wc_InitRng(rng), 0);
    ExpectIntEQ(wc_ecc_init(key), 0);

    /* Test invalid parameters. */
    ExpectIntEQ(wc_ecc_sm2_make_key(NULL, NULL, WC_ECC_FLAG_NONE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_make_key(rng, NULL, WC_ECC_FLAG_NONE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_make_key(NULL, key, WC_ECC_FLAG_NONE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Test valid parameters. */
    ExpectIntEQ(wc_ecc_sm2_make_key(rng, key, WC_ECC_FLAG_NONE), 0);
    ExpectIntEQ(key->dp->id, ECC_SM2P256V1);

    wc_ecc_free(key);
    wc_FreeRng(rng);
#ifdef FP_ECC
    wc_ecc_fp_free();
#endif

    res = EXPECT_RESULT();
#endif
    return res;
}

/*
 * Testing wc_ecc_sm2_shared_secret()
 */
static int test_wc_ecc_sm2_shared_secret(void)
{
    int res = TEST_SKIPPED;
#if defined(HAVE_ECC) && defined(WOLFSSL_SM2)
    EXPECT_DECLS;
    WC_RNG  rng[1];
    ecc_key keyA[1];
    ecc_key keyB[1];
    byte outA[32];
    byte outB[32];
    word32 outALen = 32;
    word32 outBLen = 32;

    XMEMSET(rng, 0, sizeof(*rng));
    XMEMSET(keyA, 0, sizeof(*keyA));
    XMEMSET(keyB, 0, sizeof(*keyB));

    ExpectIntEQ(wc_InitRng(rng), 0);
    ExpectIntEQ(wc_ecc_init(keyA), 0);
    ExpectIntEQ(wc_ecc_init(keyB), 0);
    ExpectIntEQ(wc_ecc_sm2_make_key(rng, keyA, WC_ECC_FLAG_NONE), 0);
    ExpectIntEQ(wc_ecc_sm2_make_key(rng, keyB, WC_ECC_FLAG_NONE), 0);

#ifdef ECC_TIMING_RESISTANT
    ExpectIntEQ(wc_ecc_set_rng(keyA, rng), 0);
    ExpectIntEQ(wc_ecc_set_rng(keyB, rng), 0);
#endif

    /* Test invalid parameters. */
    ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, NULL, NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, NULL, NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, keyB, NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, NULL, outA, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, NULL, NULL, &outALen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, keyB, outA, &outALen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, NULL, outA, &outALen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, keyB, NULL, &outALen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, keyB, outA, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Test valid parameters. */
    ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, keyB, outA, &outALen), 0);
    ExpectIntLE(outALen, 32);
    ExpectIntEQ(wc_ecc_sm2_shared_secret(keyB, keyA, outB, &outBLen), 0);
    ExpectIntLE(outBLen, 32);
    ExpectIntEQ(outALen, outBLen);
    ExpectBufEQ(outA, outB, outALen);

    wc_ecc_free(keyB);
    wc_ecc_free(keyA);
    wc_FreeRng(rng);
#ifdef FP_ECC
    wc_ecc_fp_free();
#endif

    res = EXPECT_RESULT();
#endif
    return res;
}

/*
 * Testing wc_ecc_sm2_create_digest()
 */
static int test_wc_ecc_sm2_create_digest(void)
{
    int res = TEST_SKIPPED;
#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && !defined(NO_HASH_WRAPPER) && \
    (defined(WOLFSSL_SM3) || !defined(NO_SHA256))
    EXPECT_DECLS;
    ecc_key key[1];
    enum wc_HashType hashType;
    unsigned char pub[] = {
        0x04,
        0x63, 0x7F, 0x1B, 0x13, 0x50, 0x36, 0xC9, 0x33,
        0xDC, 0x3F, 0x7A, 0x8E, 0xBB, 0x1B, 0x7B, 0x2F,
        0xD1, 0xDF, 0xBD, 0x26, 0x8D, 0x4F, 0x89, 0x4B,
        0x5A, 0xD4, 0x7D, 0xBD, 0xBE, 0xCD, 0x55, 0x8F,
        0xE8, 0x81, 0x01, 0xD0, 0x80, 0x48, 0xE3, 0x6C,
        0xCB, 0xF6, 0x1C, 0xA3, 0x8D, 0xDF, 0x7A, 0xBA,
        0x54, 0x2B, 0x44, 0x86, 0xE9, 0x9E, 0x49, 0xF3,
        0xA7, 0x47, 0x0A, 0x85, 0x7A, 0x09, 0x64, 0x33
    };
    unsigned char id[] = {
        0x01, 0x02, 0x03,
    };
    unsigned char msg[] = {
        0x01, 0x02, 0x03,
    };
    unsigned char hash[32];
#ifdef WOLFSSL_SM3
    unsigned char expHash[32] = {
        0xc1, 0xdd, 0x92, 0xc5, 0x60, 0xd3, 0x94, 0x28,
        0xeb, 0x0f, 0x57, 0x79, 0x3f, 0xc9, 0x96, 0xc5,
        0xfa, 0xf5, 0x90, 0xb2, 0x64, 0x2f, 0xaf, 0x9c,
        0xc8, 0x57, 0x21, 0x6a, 0x52, 0x7e, 0xf1, 0x95
    };
#else
    unsigned char expHash[32] = {
        0xea, 0x41, 0x55, 0x21, 0x61, 0x00, 0x5c, 0x9a,
        0x57, 0x35, 0x6b, 0x49, 0xca, 0x8f, 0x65, 0xc2,
        0x0e, 0x29, 0x0c, 0xa0, 0x1d, 0xa7, 0xc4, 0xed,
        0xdd, 0x51, 0x12, 0xf6, 0xe7, 0x55, 0xc5, 0xf4
    };
#endif

#ifdef WOLFSSL_SM3
    hashType = WC_HASH_TYPE_SM3;
#else
    hashType = WC_HASH_TYPE_SHA256;
#endif

    XMEMSET(key, 0, sizeof(*key));

    ExpectIntEQ(wc_ecc_init(key), 0);

    /* Test with no curve set. */
    ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg),
        hashType, hash, sizeof(hash), key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ecc_import_x963_ex(pub, sizeof(pub), key, ECC_SM2P256V1), 0);

    /* Test invalid parameters. */
    ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), NULL, sizeof(msg),
        hashType, NULL, sizeof(hash), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), NULL, sizeof(msg),
        hashType, NULL, sizeof(hash), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), msg, sizeof(msg),
        hashType, NULL, sizeof(hash), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), NULL, sizeof(msg),
        hashType, hash, sizeof(hash), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), NULL, sizeof(msg),
        hashType, NULL, sizeof(hash), key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), msg, sizeof(msg),
        hashType, hash, sizeof(hash), key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), NULL, sizeof(msg),
        hashType, hash, sizeof(hash), key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg),
        hashType, NULL, sizeof(hash), key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg),
        hashType, hash, sizeof(hash), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Bad hash type. */
    /* // NOLINTBEGIN(clang-analyzer-optin.core.EnumCastOutOfRange) */
    ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg),
        -1, hash, 0, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* // NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange) */
    /* Bad hash size. */
    ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg),
        hashType, hash, 0, key), WC_NO_ERR_TRACE(BUFFER_E));

    /* Test valid parameters. */
    ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg),
        hashType, hash, sizeof(hash), key), 0);
    ExpectBufEQ(hash, expHash, sizeof(expHash));

    wc_ecc_free(key);

    res = EXPECT_RESULT();
#endif
    return res;
}
/*
 * Testing wc_ecc_sm2_verify_hash_ex()
 */
static int test_wc_ecc_sm2_verify_hash_ex(void)
{
    int res = TEST_SKIPPED;
#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && defined(HAVE_ECC_VERIFY) && \
    defined(WOLFSSL_PUBLIC_MP)
    EXPECT_DECLS;
    ecc_key key[1];
    mp_int r[1];
    mp_int s[1];
    int verified;
    unsigned char pub[] = {
        0x04,
        0x63, 0x7F, 0x1B, 0x13, 0x50, 0x36, 0xC9, 0x33,
        0xDC, 0x3F, 0x7A, 0x8E, 0xBB, 0x1B, 0x7B, 0x2F,
        0xD1, 0xDF, 0xBD, 0x26, 0x8D, 0x4F, 0x89, 0x4B,
        0x5A, 0xD4, 0x7D, 0xBD, 0xBE, 0xCD, 0x55, 0x8F,
        0xE8, 0x81, 0x01, 0xD0, 0x80, 0x48, 0xE3, 0x6C,
        0xCB, 0xF6, 0x1C, 0xA3, 0x8D, 0xDF, 0x7A, 0xBA,
        0x54, 0x2B, 0x44, 0x86, 0xE9, 0x9E, 0x49, 0xF3,
        0xA7, 0x47, 0x0A, 0x85, 0x7A, 0x09, 0x64, 0x33
    };
    unsigned char hash[] = {
        0x3B, 0xFA, 0x5F, 0xFB, 0xC4, 0x27, 0x8C, 0x9D,
        0x02, 0x3A, 0x19, 0xCB, 0x1E, 0xAA, 0xD2, 0xF1,
        0x50, 0x69, 0x5B, 0x20
    };
    unsigned char rData[] = {
        0xD2, 0xFC, 0xA3, 0x88, 0xE3, 0xDF, 0xA3, 0x00,
        0x73, 0x9B, 0x3C, 0x2A, 0x0D, 0xAD, 0x44, 0xA2,
        0xFC, 0x62, 0xD5, 0x6B, 0x84, 0x54, 0xD8, 0x40,
        0x22, 0x62, 0x3D, 0x5C, 0xA6, 0x61, 0x9B, 0xE7,
    };
    unsigned char sData[] = {
        0x1D,
        0xB5, 0xB5, 0xD9, 0xD8, 0xF1, 0x20, 0xDD, 0x97,
        0x92, 0xBF, 0x7E, 0x9B, 0x3F, 0xE6, 0x3C, 0x4B,
        0x03, 0xD8, 0x80, 0xBD, 0xB7, 0x27, 0x7E, 0x6A,
        0x84, 0x23, 0xDE, 0x61, 0x7C, 0x8D, 0xDC
    };
    unsigned char rBadData[] = {
        0xD2, 0xFC, 0xA3, 0x88, 0xE3, 0xDF, 0xA3, 0x00,
        0x73, 0x9B, 0x3C, 0x2A, 0x0D, 0xAD, 0x44, 0xA2,
        0xFC, 0x62, 0xD5, 0x6B, 0x84, 0x54, 0xD8, 0x40,
        0x22, 0x62, 0x3D, 0x5C, 0xA6, 0x61, 0x9B, 0xE8,
    };

    XMEMSET(key, 0, sizeof(*key));
    XMEMSET(r, 0, sizeof(*r));
    XMEMSET(s, 0, sizeof(*s));

    ExpectIntEQ(mp_init(r), 0);
    ExpectIntEQ(mp_init(s), 0);
    ExpectIntEQ(mp_read_unsigned_bin(r, rData, sizeof(rData)), 0);
    ExpectIntEQ(mp_read_unsigned_bin(s, sData, sizeof(sData)), 0);

    ExpectIntEQ(wc_ecc_init(key), 0);

    /* Test with no curve set. */
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash),
        &verified, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ecc_import_x963_ex(pub, sizeof(pub), key, ECC_SM2P256V1), 0);

    /* Test invalid parameters. */
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, NULL, NULL, sizeof(hash),
        NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, NULL, NULL, sizeof(hash),
        NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, s, NULL, sizeof(hash),
        NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, NULL, hash, sizeof(hash),
        NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, NULL, NULL, sizeof(hash),
        &verified, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, NULL, NULL, sizeof(hash),
        NULL, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, s, hash, sizeof(hash),
        &verified, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, NULL, hash, sizeof(hash),
        &verified, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, NULL, sizeof(hash),
        &verified, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash),
        NULL, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash),
        &verified, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Make key not on the SM2 curve. */
    ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SECP256R1), 0);
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash),
        &verified, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SM2P256V1), 0);

    /* Test valid parameters. */
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash),
        &verified, key), 0);
    ExpectIntEQ(verified, 1);

    ExpectIntEQ(mp_read_unsigned_bin(r, rBadData, sizeof(rBadData)), 0);
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash),
        &verified, key), 0);
    ExpectIntEQ(verified, 0);

    mp_free(s);
    mp_free(r);
    wc_ecc_free(key);
#ifdef FP_ECC
    wc_ecc_fp_free();
#endif

    res = EXPECT_RESULT();
#endif
    return res;
}

/*
 * Testing wc_ecc_sm2_verify_hash()
 */
static int test_wc_ecc_sm2_verify_hash(void)
{
    int res = TEST_SKIPPED;
#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && defined(HAVE_ECC_VERIFY)
    EXPECT_DECLS;
    ecc_key key[1];
    int verified;
    unsigned char pub[] = {
        0x04,
        0x63, 0x7F, 0x1B, 0x13, 0x50, 0x36, 0xC9, 0x33,
        0xDC, 0x3F, 0x7A, 0x8E, 0xBB, 0x1B, 0x7B, 0x2F,
        0xD1, 0xDF, 0xBD, 0x26, 0x8D, 0x4F, 0x89, 0x4B,
        0x5A, 0xD4, 0x7D, 0xBD, 0xBE, 0xCD, 0x55, 0x8F,
        0xE8, 0x81, 0x01, 0xD0, 0x80, 0x48, 0xE3, 0x6C,
        0xCB, 0xF6, 0x1C, 0xA3, 0x8D, 0xDF, 0x7A, 0xBA,
        0x54, 0x2B, 0x44, 0x86, 0xE9, 0x9E, 0x49, 0xF3,
        0xA7, 0x47, 0x0A, 0x85, 0x7A, 0x09, 0x64, 0x33
    };
    unsigned char hash[] = {
        0x3B, 0xFA, 0x5F, 0xFB, 0xC4, 0x27, 0x8C, 0x9D,
        0x02, 0x3A, 0x19, 0xCB, 0x1E, 0xAA, 0xD2, 0xF1,
        0x50, 0x69, 0x5B, 0x20
    };
    unsigned char sig[] = {
        0x30, 0x45, 0x02, 0x21, 0x00, 0xD2, 0xFC, 0xA3,
        0x88, 0xE3, 0xDF, 0xA3, 0x00, 0x73, 0x9B, 0x3C,
        0x2A, 0x0D, 0xAD, 0x44, 0xA2, 0xFC, 0x62, 0xD5,
        0x6B, 0x84, 0x54, 0xD8, 0x40, 0x22, 0x62, 0x3D,
        0x5C, 0xA6, 0x61, 0x9B, 0xE7, 0x02, 0x20, 0x1D,
        0xB5, 0xB5, 0xD9, 0xD8, 0xF1, 0x20, 0xDD, 0x97,
        0x92, 0xBF, 0x7E, 0x9B, 0x3F, 0xE6, 0x3C, 0x4B,
        0x03, 0xD8, 0x80, 0xBD, 0xB7, 0x27, 0x7E, 0x6A,
        0x84, 0x23, 0xDE, 0x61, 0x7C, 0x8D, 0xDC
    };
    unsigned char sigBad[] = {
        0x30, 0x45, 0x02, 0x21, 0x00, 0xD2, 0xFC, 0xA3,
        0x88, 0xE3, 0xDF, 0xA3, 0x00, 0x73, 0x9B, 0x3C,
        0x2A, 0x0D, 0xAD, 0x44, 0xA2, 0xFC, 0x62, 0xD5,
        0x6B, 0x84, 0x54, 0xD8, 0x40, 0x22, 0x62, 0x3D,
        0x5C, 0xA6, 0x61, 0x9B, 0xE7, 0x02, 0x20, 0x1D,
        0xB5, 0xB5, 0xD9, 0xD8, 0xF1, 0x20, 0xDD, 0x97,
        0x92, 0xBF, 0x7E, 0x9B, 0x3F, 0xE6, 0x3C, 0x4B,
        0x03, 0xD8, 0x80, 0xBD, 0xB7, 0x27, 0x7E, 0x6A,
        0x84, 0x23, 0xDE, 0x61, 0x7C, 0x8D, 0xDD
    };


    XMEMSET(key, 0, sizeof(*key));
    ExpectIntEQ(wc_ecc_init(key), 0);

    /* Test with no curve set. */
    ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash),
        &verified, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ecc_import_x963_ex(pub, sizeof(pub), key, ECC_SM2P256V1), 0);

    /* Test invalid parameters. */
    ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), NULL, sizeof(hash),
        NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), NULL, sizeof(hash),
        NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), hash, sizeof(hash),
        NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), NULL, sizeof(hash),
        &verified, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), NULL, sizeof(hash),
        NULL, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), hash, sizeof(hash),
        &verified, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), NULL, sizeof(hash),
        &verified, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash),
        NULL, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash),
        &verified, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Make key not on the SM2 curve. */
    ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SECP256R1), 0);
    ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash),
        &verified, key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SM2P256V1), 0);

    /* Test valid parameters. */
    ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash),
        &verified, key), 0);
    ExpectIntEQ(verified, 1);

    ExpectIntEQ(wc_ecc_sm2_verify_hash(sigBad, sizeof(sigBad), hash,
        sizeof(hash), &verified, key), 0);
    ExpectIntEQ(verified, 0);

    wc_ecc_free(key);
#ifdef FP_ECC
    wc_ecc_fp_free();
#endif

    res = EXPECT_RESULT();
#endif
    return res;
}

/*
 * Testing wc_ecc_sm2_verify_hash_ex()
 */
static int test_wc_ecc_sm2_sign_hash_ex(void)
{
    int res = TEST_SKIPPED;
#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && defined(HAVE_ECC_SIGN) && \
    defined(WOLFSSL_PUBLIC_MP)
    EXPECT_DECLS;
    WC_RNG  rng[1];
    ecc_key key[1];
    mp_int r[1];
    mp_int s[1];
    unsigned char hash[32];
#ifdef HAVE_ECC_VERIFY
    int verified;
#endif

    XMEMSET(rng, 0, sizeof(*rng));
    XMEMSET(key, 0, sizeof(*key));
    XMEMSET(r, 0, sizeof(*r));
    XMEMSET(s, 0, sizeof(*s));

    ExpectIntEQ(wc_InitRng(rng), 0);
    ExpectIntEQ(mp_init(r), 0);
    ExpectIntEQ(mp_init(s), 0);
    ExpectIntEQ(wc_RNG_GenerateBlock(rng, hash, sizeof(hash)), 0);

    ExpectIntEQ(wc_ecc_init(key), 0);

    /* Test with no curve set. */
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, r, s),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ecc_sm2_make_key(rng, key, WC_ECC_FLAG_NONE), 0);

    /* Test invalid parameters. */
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), NULL, NULL, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), NULL, NULL, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), rng, NULL, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), NULL, key, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), NULL, NULL, r,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), NULL, NULL, NULL,
        s), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), rng, key, r, s),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), NULL, key, r, s),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, NULL, r, s),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, NULL, s),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, r, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Make key not on the SM2 curve. */
    ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SECP256R1), 0);
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, r, s),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SM2P256V1), 0);

#ifdef WOLFSSL_SP_MATH_ALL
    {
        mp_int smallR[1];
        sp_init_size(smallR, 1);
        /* Force failure in _ecc_sm2_calc_r_s by r being too small. */
        ExpectIntLT(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key,
            smallR, s), 0);
    }
#endif

    /* Test valid parameters. */
    ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, r, s),
        0);
#ifdef HAVE_ECC_VERIFY
    ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash), &verified,
        key), 0);
    ExpectIntEQ(verified, 1);
#endif

    mp_free(s);
    mp_free(r);
    wc_ecc_free(key);
    wc_FreeRng(rng);
#ifdef FP_ECC
    wc_ecc_fp_free();
#endif

    res = EXPECT_RESULT();
#endif
    return res;
}


/*
 * Testing wc_ecc_sm2_verify_hash()
 */
static int test_wc_ecc_sm2_sign_hash(void)
{
    int res = TEST_SKIPPED;
#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && defined(HAVE_ECC_SIGN)
    EXPECT_DECLS;
    WC_RNG  rng[1];
    ecc_key key[1];
    unsigned char hash[32];
    unsigned char sig[72];
    word32 sigSz = sizeof(sig);
#ifdef HAVE_ECC_VERIFY
    int verified;
#endif

    XMEMSET(rng, 0, sizeof(*rng));
    XMEMSET(key, 0, sizeof(*key));

    ExpectIntEQ(wc_InitRng(rng), 0);
    ExpectIntEQ(wc_RNG_GenerateBlock(rng, hash, sizeof(hash)), 0);

    ExpectIntEQ(wc_ecc_init(key), 0);

    /* Test with no curve set. */
    ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_ecc_sm2_make_key(rng, key, WC_ECC_FLAG_NONE), 0);

    /* Test invalid parameters. */
    ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), NULL, NULL, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), NULL, NULL, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), sig, NULL, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), NULL, &sigSz, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), NULL, NULL, rng,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), NULL, NULL, NULL,
        key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), sig, &sigSz, rng,
        key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), NULL, &sigSz, rng,
        key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, NULL, rng,
        key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, NULL,
        key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, rng,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Make key not on the SM2 curve. */
    ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SECP256R1), 0);
    ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, key),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SM2P256V1), 0);

    /* Test valid parameters. */
    ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, key),
        0);
#ifdef HAVE_ECC_VERIFY
    ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sigSz, hash, sizeof(hash),
        &verified, key), 0);
    ExpectIntEQ(verified, 1);
#endif

    wc_ecc_free(key);
    wc_FreeRng(rng);
#ifdef FP_ECC
    wc_ecc_fp_free();
#endif

    res = EXPECT_RESULT();
#endif
    return res;
}


/*
 * Testing ToTraditional
 */
static int test_ToTraditional(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && (defined(HAVE_PKCS8) || defined(HAVE_PKCS12)) && \
    (defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \
     defined(OPENSSL_EXTRA_X509_SMALL)) && !defined(NO_FILESYSTEM)
    XFILE  f = XBADFILE;
    byte   input[TWOK_BUF];
    word32 sz = 0;

    ExpectTrue((f = XFOPEN("./certs/server-keyPkcs8.der", "rb")) != XBADFILE);
    ExpectTrue((sz = (word32)XFREAD(input, 1, sizeof(input), f)) > 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    /* Good case */
    ExpectIntGT(ToTraditional(input, sz), 0);
    /* Bad cases */
    ExpectIntEQ(ToTraditional(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(ToTraditional(NULL, sz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_ASN_TEMPLATE
    ExpectIntEQ(ToTraditional(input, 0), WC_NO_ERR_TRACE(BUFFER_E));
#else
    ExpectIntEQ(ToTraditional(input, 0), WC_NO_ERR_TRACE(ASN_PARSE_E));
#endif
#endif
    return EXPECT_RESULT();
} /* End test_ToTraditional*/

/*
 * Testing wc_EccPrivateKeyToDer
 */
static int test_wc_EccPrivateKeyToDer(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG)
    byte    output[ONEK_BUF];
    ecc_key eccKey;
    WC_RNG  rng;
    word32  inLen = 0;
    word32  outLen = 0;
    int     ret;

    XMEMSET(&eccKey, 0, sizeof(ecc_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    PRIVATE_KEY_UNLOCK();

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ecc_init(&eccKey), 0);
    ret = wc_ecc_make_key(&rng, KEY14, &eccKey);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &eccKey.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);

    /* Bad Cases */
    ExpectIntEQ(wc_EccPrivateKeyToDer(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_EccPrivateKeyToDer(NULL, output, inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    inLen = wc_EccPrivateKeyToDer(&eccKey, NULL, 0);
    ExpectIntGT(inLen, 0);
    ExpectIntEQ(wc_EccPrivateKeyToDer(&eccKey, output, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Good Case */
    ExpectIntGT(outLen = (word32)wc_EccPrivateKeyToDer(&eccKey, output, inLen), 0);

    wc_ecc_free(&eccKey);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);

#if defined(OPENSSL_EXTRA) && defined(HAVE_ALL_CURVES)
    {
        /* test importing private only into a PKEY struct */
        EC_KEY*   ec = NULL;
        EVP_PKEY* pkey = NULL;
        const unsigned char* der;

        der = output;
        ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_EC, NULL, &der, outLen));

        der = output;
        ExpectNotNull(ec = d2i_ECPrivateKey(NULL, &der, outLen));
        ExpectIntEQ(EVP_PKEY_assign_EC_KEY(pkey, ec), SSL_SUCCESS);
        if (EXPECT_FAIL()) {
            EC_KEY_free(ec);
        }
        EVP_PKEY_free(pkey); /* EC_KEY should be free'd by free'ing pkey */
    }
#endif
    PRIVATE_KEY_LOCK();
#endif
    return EXPECT_RESULT();
} /* End test_wc_EccPrivateKeyToDer*/

/*
 * Testing wc_DhPublicKeyDecode
 */
static int test_wc_DhPublicKeyDecode(void)
{
    EXPECT_DECLS;
#ifndef NO_DH
#if defined(WOLFSSL_DH_EXTRA) && defined(USE_CERT_BUFFERS_2048)
    DhKey  key;
    word32 inOutIdx;

    XMEMSET(&key, 0, sizeof(DhKey));

    ExpectIntEQ(wc_InitDhKey(&key), 0);

    ExpectIntEQ(wc_DhPublicKeyDecode(NULL,NULL,NULL,0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,NULL,NULL,0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,NULL,NULL,0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    inOutIdx = 0;
    ExpectIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,&inOutIdx,NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    inOutIdx = 0;
    ExpectIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,&inOutIdx,&key, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    inOutIdx = 0;
    ExpectIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,&inOutIdx,&key,
        sizeof_dh_pub_key_der_2048), 0);
    ExpectIntNE(key.p.used, 0);
    ExpectIntNE(key.g.used, 0);
    ExpectIntEQ(key.q.used, 0);
    ExpectIntNE(key.pub.used, 0);
    ExpectIntEQ(key.priv.used, 0);

    DoExpectIntEQ(wc_FreeDhKey(&key), 0);
#endif
#endif /* !NO_DH */
    return EXPECT_RESULT();
}

/*
 * Testing wc_Ed25519KeyToDer
 */
static int test_wc_Ed25519KeyToDer(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) && \
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
    byte        output[ONEK_BUF];
    ed25519_key ed25519Key;
    WC_RNG      rng;
    word32      inLen;

    XMEMSET(&ed25519Key, 0, sizeof(ed25519_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed25519_init(&ed25519Key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &ed25519Key), 0);
    inLen = (word32)sizeof(output);

    /* Bad Cases */
    ExpectIntEQ(wc_Ed25519KeyToDer(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Ed25519KeyToDer(NULL, output, inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Ed25519KeyToDer(&ed25519Key, output, 0), WC_NO_ERR_TRACE(BUFFER_E));
    /* Good Cases */
    /* length only */
    ExpectIntGT(wc_Ed25519KeyToDer(&ed25519Key, NULL, 0), 0);
    ExpectIntGT(wc_Ed25519KeyToDer(&ed25519Key, NULL, inLen), 0);
    ExpectIntGT(wc_Ed25519KeyToDer(&ed25519Key, output, inLen), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed25519_free(&ed25519Key);
#endif
    return EXPECT_RESULT();
} /* End test_wc_Ed25519KeyToDer*/

/*
 * Testing wc_Ed25519PrivateKeyToDer
 */
static int test_wc_Ed25519PrivateKeyToDer(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) && \
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
    byte        output[ONEK_BUF];
    ed25519_key ed25519PrivKey;
    WC_RNG      rng;
    word32      inLen;

    XMEMSET(&ed25519PrivKey, 0, sizeof(ed25519_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed25519_init(&ed25519PrivKey), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &ed25519PrivKey),
        0);
    inLen = (word32)sizeof(output);

    /* Bad Cases */
    ExpectIntEQ(wc_Ed25519PrivateKeyToDer(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Ed25519PrivateKeyToDer(NULL, output, inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Ed25519PrivateKeyToDer(&ed25519PrivKey, output, 0),
        WC_NO_ERR_TRACE(BUFFER_E));
    /* Good Cases */
    /* length only */
    ExpectIntGT(wc_Ed25519PrivateKeyToDer(&ed25519PrivKey, NULL, 0), 0);
    ExpectIntGT(wc_Ed25519PrivateKeyToDer(&ed25519PrivKey, output, inLen), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed25519_free(&ed25519PrivKey);
#endif
    return EXPECT_RESULT();
} /* End test_wc_Ed25519PrivateKeyToDer*/

/*
 * Testing wc_Ed448KeyToDer
 */
static int test_wc_Ed448KeyToDer(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
    byte      output[ONEK_BUF];
    ed448_key ed448Key;
    WC_RNG    rng;
    word32    inLen;

    XMEMSET(&ed448Key, 0, sizeof(ed448_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed448_init(&ed448Key), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &ed448Key), 0);
    inLen = (word32)sizeof(output);

    /* Bad Cases */
    ExpectIntEQ(wc_Ed448KeyToDer(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Ed448KeyToDer(NULL, output, inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Ed448KeyToDer(&ed448Key, output, 0), WC_NO_ERR_TRACE(BUFFER_E));
    /* Good Cases */
    /* length only */
    ExpectIntGT(wc_Ed448KeyToDer(&ed448Key, NULL, 0), 0);
    ExpectIntGT(wc_Ed448KeyToDer(&ed448Key, output, inLen), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed448_free(&ed448Key);
#endif
    return EXPECT_RESULT();
} /* End test_wc_Ed448KeyToDer*/

/*
 * Testing wc_Ed448PrivateKeyToDer
 */
static int test_wc_Ed448PrivateKeyToDer(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
    byte      output[ONEK_BUF];
    ed448_key ed448PrivKey;
    WC_RNG    rng;
    word32    inLen;

    XMEMSET(&ed448PrivKey, 0, sizeof(ed448_key));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_ed448_init(&ed448PrivKey), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &ed448PrivKey),
        0);
    inLen = (word32)sizeof(output);

    /* Bad Cases */
    ExpectIntEQ(wc_Ed448PrivateKeyToDer(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Ed448PrivateKeyToDer(NULL, output, inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Ed448PrivateKeyToDer(&ed448PrivKey, output, 0),
        WC_NO_ERR_TRACE(BUFFER_E));
    /* Good cases */
    /* length only */
    ExpectIntGT(wc_Ed448PrivateKeyToDer(&ed448PrivKey, NULL, 0), 0);
    ExpectIntGT(wc_Ed448PrivateKeyToDer(&ed448PrivKey, output, inLen), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_ed448_free(&ed448PrivKey);
#endif
    return EXPECT_RESULT();
} /* End test_wc_Ed448PrivateKeyToDer*/

/*
 * Testing wc_Curve448PrivateKeyToDer
 */
static int test_wc_Curve448PrivateKeyToDer(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT) && \
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
    byte      output[ONEK_BUF];
    curve448_key curve448PrivKey;
    WC_RNG    rng;
    word32    inLen;

    XMEMSET(&curve448PrivKey, 0, sizeof(curve448PrivKey));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_curve448_init(&curve448PrivKey), 0);
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &curve448PrivKey),
        0);
    inLen = (word32)sizeof(output);

    /* Bad Cases */
    ExpectIntEQ(wc_Curve448PrivateKeyToDer(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Curve448PrivateKeyToDer(NULL, output, inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Curve448PrivateKeyToDer(&curve448PrivKey, output, 0),
        WC_NO_ERR_TRACE(BUFFER_E));
    /* Good cases */
    /* length only */
    ExpectIntGT(wc_Curve448PrivateKeyToDer(&curve448PrivKey, NULL, 0), 0);
    ExpectIntGT(wc_Curve448PrivateKeyToDer(&curve448PrivKey, output, inLen), 0);

    /* Bad Cases */
    ExpectIntEQ(wc_Curve448PublicKeyToDer(NULL, NULL, 0, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Curve448PublicKeyToDer(NULL, output, inLen, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Curve448PublicKeyToDer(&curve448PrivKey, output, 0, 0),
        WC_NO_ERR_TRACE(BUFFER_E));
    ExpectIntEQ(wc_Curve448PublicKeyToDer(&curve448PrivKey, output, 0, 1),
        WC_NO_ERR_TRACE(BUFFER_E));
    /* Good cases */
    /* length only */
    ExpectIntGT(wc_Curve448PublicKeyToDer(&curve448PrivKey, NULL, 0, 0), 0);
    ExpectIntGT(wc_Curve448PublicKeyToDer(&curve448PrivKey, NULL, 0, 1), 0);
    ExpectIntGT(wc_Curve448PublicKeyToDer(&curve448PrivKey, output, inLen, 0), 0);
    ExpectIntGT(wc_Curve448PublicKeyToDer(&curve448PrivKey, output, inLen, 1), 0);

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
    wc_curve448_free(&curve448PrivKey);
#endif
    return EXPECT_RESULT();
} /* End wc_Curve448PrivateKeyToDer*/

static int test_wc_kyber_make_key_kats(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_HAVE_KYBER) && defined(WOLFSSL_WC_KYBER) && \
    !defined(WOLFSSL_KYBER_ORIGINAL)
    KyberKey* key;
#ifndef WOLFSSL_NO_KYBER512
    static const byte seed_512[KYBER_MAKEKEY_RAND_SZ] = {
        /* d */
        0x2C, 0xB8, 0x43, 0xA0, 0x2E, 0xF0, 0x2E, 0xE1,
        0x09, 0x30, 0x5F, 0x39, 0x11, 0x9F, 0xAB, 0xF4,
        0x9A, 0xB9, 0x0A, 0x57, 0xFF, 0xEC, 0xB3, 0xA0,
        0xE7, 0x5E, 0x17, 0x94, 0x50, 0xF5, 0x27, 0x61,
        /* z */
        0x84, 0xCC, 0x91, 0x21, 0xAE, 0x56, 0xFB, 0xF3,
        0x9E, 0x67, 0xAD, 0xBD, 0x83, 0xAD, 0x2D, 0x3E,
        0x3B, 0xB8, 0x08, 0x43, 0x64, 0x52, 0x06, 0xBD,
        0xD9, 0xF2, 0xF6, 0x29, 0xE3, 0xCC, 0x49, 0xB7
    };
    static const byte ek_512[KYBER512_PUBLIC_KEY_SIZE] = {
        0xA3, 0x24, 0x39, 0xF8, 0x5A, 0x3C, 0x21, 0xD2,
        0x1A, 0x71, 0xB9, 0xB9, 0x2A, 0x9B, 0x64, 0xEA,
        0x0A, 0xB8, 0x43, 0x12, 0xC7, 0x70, 0x23, 0x69,
        0x4F, 0xD6, 0x4E, 0xAA, 0xB9, 0x07, 0xA4, 0x35,
        0x39, 0xDD, 0xB2, 0x7B, 0xA0, 0xA8, 0x53, 0xCC,
        0x90, 0x69, 0xEA, 0xC8, 0x50, 0x8C, 0x65, 0x3E,
        0x60, 0x0B, 0x2A, 0xC0, 0x18, 0x38, 0x1B, 0x4B,
        0xB4, 0xA8, 0x79, 0xAC, 0xDA, 0xD3, 0x42, 0xF9,
        0x11, 0x79, 0xCA, 0x82, 0x49, 0x52, 0x5C, 0xB1,
        0x96, 0x8B, 0xBE, 0x52, 0xF7, 0x55, 0xB7, 0xF5,
        0xB4, 0x3D, 0x66, 0x63, 0xD7, 0xA3, 0xBF, 0x0F,
        0x33, 0x57, 0xD8, 0xA2, 0x1D, 0x15, 0xB5, 0x2D,
        0xB3, 0x81, 0x8E, 0xCE, 0x5B, 0x40, 0x2A, 0x60,
        0xC9, 0x93, 0xE7, 0xCF, 0x43, 0x64, 0x87, 0xB8,
        0xD2, 0xAE, 0x91, 0xE6, 0xC5, 0xB8, 0x82, 0x75,
        0xE7, 0x58, 0x24, 0xB0, 0x00, 0x7E, 0xF3, 0x12,
        0x3C, 0x0A, 0xB5, 0x1B, 0x5C, 0xC6, 0x1B, 0x9B,
        0x22, 0x38, 0x0D, 0xE6, 0x6C, 0x5B, 0x20, 0xB0,
        0x60, 0xCB, 0xB9, 0x86, 0xF8, 0x12, 0x3D, 0x94,
        0x06, 0x00, 0x49, 0xCD, 0xF8, 0x03, 0x68, 0x73,
        0xA7, 0xBE, 0x10, 0x94, 0x44, 0xA0, 0xA1, 0xCD,
        0x87, 0xA4, 0x8C, 0xAE, 0x54, 0x19, 0x24, 0x84,
        0xAF, 0x84, 0x44, 0x29, 0xC1, 0xC5, 0x8C, 0x29,
        0xAC, 0x62, 0x4C, 0xD5, 0x04, 0xF1, 0xC4, 0x4F,
        0x1E, 0x13, 0x47, 0x82, 0x2B, 0x6F, 0x22, 0x13,
        0x23, 0x85, 0x9A, 0x7F, 0x6F, 0x75, 0x4B, 0xFE,
        0x71, 0x0B, 0xDA, 0x60, 0x27, 0x62, 0x40, 0xA4,
        0xFF, 0x2A, 0x53, 0x50, 0x70, 0x37, 0x86, 0xF5,
        0x67, 0x1F, 0x44, 0x9F, 0x20, 0xC2, 0xA9, 0x5A,
        0xE7, 0xC2, 0x90, 0x3A, 0x42, 0xCB, 0x3B, 0x30,
        0x3F, 0xF4, 0xC4, 0x27, 0xC0, 0x8B, 0x11, 0xB4,
        0xCD, 0x31, 0xC4, 0x18, 0xC6, 0xD1, 0x8D, 0x08,
        0x61, 0x87, 0x3B, 0xFA, 0x03, 0x32, 0xF1, 0x12,
        0x71, 0x55, 0x2E, 0xD7, 0xC0, 0x35, 0xF0, 0xE4,
        0xBC, 0x42, 0x8C, 0x43, 0x72, 0x0B, 0x39, 0xA6,
        0x51, 0x66, 0xBA, 0x9C, 0x2D, 0x3D, 0x77, 0x0E,
        0x13, 0x03, 0x60, 0xCC, 0x23, 0x84, 0xE8, 0x30,
        0x95, 0xB1, 0xA1, 0x59, 0x49, 0x55, 0x33, 0xF1,
        0x16, 0xC7, 0xB5, 0x58, 0xB6, 0x50, 0xDB, 0x04,
        0xD5, 0xA2, 0x6E, 0xAA, 0xA0, 0x8C, 0x3E, 0xE5,
        0x7D, 0xE4, 0x5A, 0x7F, 0x88, 0xC6, 0xA3, 0xCE,
        0xB2, 0x4D, 0xC5, 0x39, 0x7B, 0x88, 0xC3, 0xCE,
        0xF0, 0x03, 0x31, 0x9B, 0xB0, 0x23, 0x3F, 0xD6,
        0x92, 0xFD, 0xA1, 0x52, 0x44, 0x75, 0xB3, 0x51,
        0xF3, 0xC7, 0x82, 0x18, 0x2D, 0xEC, 0xF5, 0x90,
        0xB7, 0x72, 0x3B, 0xE4, 0x00, 0xBE, 0x14, 0x80,
        0x9C, 0x44, 0x32, 0x99, 0x63, 0xFC, 0x46, 0x95,
        0x92, 0x11, 0xD6, 0xA6, 0x23, 0x33, 0x95, 0x37,
        0x84, 0x8C, 0x25, 0x16, 0x69, 0x94, 0x1D, 0x90,
        0xB1, 0x30, 0x25, 0x8A, 0xDF, 0x55, 0xA7, 0x20,
        0xA7, 0x24, 0xE8, 0xB6, 0xA6, 0xCA, 0xE3, 0xC2,
        0x26, 0x4B, 0x16, 0x24, 0xCC, 0xBE, 0x7B, 0x45,
        0x6B, 0x30, 0xC8, 0xC7, 0x39, 0x32, 0x94, 0xCA,
        0x51, 0x80, 0xBC, 0x83, 0x7D, 0xD2, 0xE4, 0x5D,
        0xBD, 0x59, 0xB6, 0xE1, 0x7B, 0x24, 0xFE, 0x93,
        0x05, 0x2E, 0xB7, 0xC4, 0x3B, 0x27, 0xAC, 0x3D,
        0xC2, 0x49, 0xCA, 0x0C, 0xBC, 0xA4, 0xFB, 0x58,
        0x97, 0xC0, 0xB7, 0x44, 0x08, 0x8A, 0x8A, 0x07,
        0x79, 0xD3, 0x22, 0x33, 0x82, 0x6A, 0x01, 0xDD,
        0x64, 0x89, 0x95, 0x2A, 0x48, 0x25, 0xE5, 0x35,
        0x8A, 0x70, 0x0B, 0xE0, 0xE1, 0x79, 0xAC, 0x19,
        0x77, 0x10, 0xD8, 0x3E, 0xCC, 0x85, 0x3E, 0x52,
        0x69, 0x5E, 0x9B, 0xF8, 0x7B, 0xB1, 0xF6, 0xCB,
        0xD0, 0x5B, 0x02, 0xD4, 0xE6, 0x79, 0xE3, 0xB8,
        0x8D, 0xD4, 0x83, 0xB0, 0x74, 0x9B, 0x11, 0xBD,
        0x37, 0xB3, 0x83, 0xDC, 0xCA, 0x71, 0xF9, 0x09,
        0x18, 0x34, 0xA1, 0x69, 0x55, 0x02, 0xC4, 0xB9,
        0x5F, 0xC9, 0x11, 0x8C, 0x1C, 0xFC, 0x34, 0xC8,
        0x4C, 0x22, 0x65, 0xBB, 0xBC, 0x56, 0x3C, 0x28,
        0x26, 0x66, 0xB6, 0x0A, 0xE5, 0xC7, 0xF3, 0x85,
        0x1D, 0x25, 0xEC, 0xBB, 0x50, 0x21, 0xCC, 0x38,
        0xCB, 0x73, 0xEB, 0x6A, 0x34, 0x11, 0xB1, 0xC2,
        0x90, 0x46, 0xCA, 0x66, 0x54, 0x06, 0x67, 0xD1,
        0x36, 0x95, 0x44, 0x60, 0xC6, 0xFC, 0xBC, 0x4B,
        0xC7, 0xC0, 0x49, 0xBB, 0x04, 0x7F, 0xA6, 0x7A,
        0x63, 0xB3, 0xCC, 0x11, 0x11, 0xC1, 0xD8, 0xAC,
        0x27, 0xE8, 0x05, 0x8B, 0xCC, 0xA4, 0xA1, 0x54,
        0x55, 0x85, 0x8A, 0x58, 0x35, 0x8F, 0x7A, 0x61,
        0x02, 0x0B, 0xC9, 0xC4, 0xC1, 0x7F, 0x8B, 0x95,
        0xC2, 0x68, 0xCC, 0xB4, 0x04, 0xB9, 0xAA, 0xB4,
        0xA2, 0x72, 0xA2, 0x1A, 0x70, 0xDA, 0xF6, 0xB6,
        0xF1, 0x51, 0x21, 0xEE, 0x01, 0xC1, 0x56, 0xA3,
        0x54, 0xAA, 0x17, 0x08, 0x7E, 0x07, 0x70, 0x2E,
        0xAB, 0x38, 0xB3, 0x24, 0x1F, 0xDB, 0x55, 0x3F,
        0x65, 0x73, 0x39, 0xD5, 0xE2, 0x9D, 0xC5, 0xD9,
        0x1B, 0x7A, 0x5A, 0x82, 0x8E, 0xE9, 0x59, 0xFE,
        0xBB, 0x90, 0xB0, 0x72, 0x29, 0xF6, 0xE4, 0x9D,
        0x23, 0xC3, 0xA1, 0x90, 0x29, 0x70, 0x42, 0xFB,
        0x43, 0x98, 0x69, 0x55, 0xB6, 0x9C, 0x28, 0xE1,
        0x01, 0x6F, 0x77, 0xA5, 0x8B, 0x43, 0x15, 0x14,
        0xD2, 0x1B, 0x88, 0x88, 0x99, 0xC3, 0x60, 0x82,
        0x76, 0x08, 0x1B, 0x75, 0xF5, 0x68, 0x09, 0x7C,
        0xDC, 0x17, 0x48, 0xF3, 0x23, 0x07, 0x88, 0x58,
        0x15, 0xF3, 0xAE, 0xC9, 0x65, 0x18, 0x19, 0xAA,
        0x68, 0x73, 0xD1, 0xA4, 0xEB, 0x83, 0xB1, 0x95,
        0x38, 0x43, 0xB9, 0x34, 0x22, 0x51, 0x94, 0x83,
        0xFE, 0xF0, 0x05, 0x9D, 0x36, 0xBB, 0x2D, 0xB1,
        0xF3, 0xD4, 0x68, 0xFB, 0x06, 0x8C, 0x86, 0xE8,
        0x97, 0x37, 0x33, 0xC3, 0x98, 0xEA, 0xF0, 0x0E,
        0x17, 0x02, 0xC6, 0x73, 0x4A, 0xD8, 0xEB, 0x3B
    };
    static const byte dk_512[KYBER512_PRIVATE_KEY_SIZE] = {
        0x7F, 0xE4, 0x20, 0x6F, 0x26, 0xBE, 0xDB, 0x64,
        0xC1, 0xED, 0x00, 0x09, 0x61, 0x52, 0x45, 0xDC,
        0x98, 0x48, 0x3F, 0x66, 0x3A, 0xCC, 0x61, 0x7E,
        0x65, 0x89, 0x8D, 0x59, 0x6A, 0x88, 0x36, 0xC4,
        0x9F, 0xBD, 0x3B, 0x4A, 0x84, 0x97, 0x59, 0xAA,
        0x15, 0x46, 0xBD, 0xA8, 0x35, 0xCA, 0xF1, 0x75,
        0x64, 0x2C, 0x28, 0x28, 0x08, 0x92, 0xA7, 0x87,
        0x8C, 0xC3, 0x18, 0xBC, 0xC7, 0x5B, 0x83, 0x4C,
        0xB2, 0x9F, 0xDF, 0x53, 0x60, 0xD7, 0xF9, 0x82,
        0xA5, 0x2C, 0x88, 0xAE, 0x91, 0x4D, 0xBF, 0x02,
        0xB5, 0x8B, 0xEB, 0x8B, 0xA8, 0x87, 0xAE, 0x8F,
        0xAB, 0x5E, 0xB7, 0x87, 0x31, 0xC6, 0x75, 0x78,
        0x05, 0x47, 0x1E, 0xBC, 0xEC, 0x2E, 0x38, 0xDB,
        0x1F, 0x4B, 0x83, 0x10, 0xD2, 0x88, 0x92, 0x0D,
        0x8A, 0x49, 0x27, 0x95, 0xA3, 0x90, 0xA7, 0x4B,
        0xCD, 0x55, 0xCD, 0x85, 0x57, 0xB4, 0xDA, 0xAB,
        0xA8, 0x2C, 0x28, 0xCB, 0x3F, 0x15, 0x2C, 0x52,
        0x31, 0x19, 0x61, 0x93, 0xA6, 0x6A, 0x8C, 0xCF,
        0x34, 0xB8, 0x0E, 0x1F, 0x69, 0x42, 0xC3, 0x2B,
        0xCF, 0xF9, 0x6A, 0x6E, 0x3C, 0xF3, 0x93, 0x9B,
        0x7B, 0x94, 0x24, 0x98, 0xCC, 0x5E, 0x4C, 0xB8,
        0xE8, 0x46, 0x8E, 0x70, 0x27, 0x59, 0x85, 0x2A,
        0xA2, 0x29, 0xC0, 0x25, 0x7F, 0x02, 0x98, 0x20,
        0x97, 0x33, 0x86, 0x07, 0xC0, 0xF0, 0xF4, 0x54,
        0x46, 0xFA, 0xB4, 0x26, 0x79, 0x93, 0xB8, 0xA5,
        0x90, 0x8C, 0xAB, 0x9C, 0x46, 0x78, 0x01, 0x34,
        0x80, 0x4A, 0xE1, 0x88, 0x15, 0xB1, 0x02, 0x05,
        0x27, 0xA2, 0x22, 0xEC, 0x4B, 0x39, 0xA3, 0x19,
        0x4E, 0x66, 0x17, 0x37, 0x79, 0x17, 0x14, 0x12,
        0x26, 0x62, 0xD8, 0xB9, 0x76, 0x9F, 0x6C, 0x67,
        0xDE, 0x62, 0x5C, 0x0D, 0x48, 0x3C, 0x3D, 0x42,
        0x0F, 0xF1, 0xBB, 0x88, 0x9A, 0x72, 0x7E, 0x75,
        0x62, 0x81, 0x51, 0x3A, 0x70, 0x04, 0x76, 0x48,
        0xD2, 0x9C, 0x0C, 0x30, 0xF9, 0xBE, 0x52, 0xEC,
        0x0D, 0xEB, 0x97, 0x7C, 0xF0, 0xF3, 0x4F, 0xC2,
        0x07, 0x84, 0x83, 0x45, 0x69, 0x64, 0x74, 0x34,
        0x10, 0x63, 0x8C, 0x57, 0xB5, 0x53, 0x95, 0x77,
        0xBF, 0x85, 0x66, 0x90, 0x78, 0xC3, 0x56, 0xB3,
        0x46, 0x2E, 0x9F, 0xA5, 0x80, 0x7D, 0x49, 0x59,
        0x1A, 0xFA, 0x41, 0xC1, 0x96, 0x9F, 0x65, 0xE3,
        0x40, 0x5C, 0xB6, 0x4D, 0xDF, 0x16, 0x3F, 0x26,
        0x73, 0x4C, 0xE3, 0x48, 0xB9, 0xCF, 0x45, 0x67,
        0xA3, 0x3A, 0x59, 0x69, 0xEB, 0x32, 0x6C, 0xFB,
        0x5A, 0xDC, 0x69, 0x5D, 0xCA, 0x0C, 0x8B, 0x2A,
        0x7B, 0x1F, 0x4F, 0x40, 0x4C, 0xC7, 0xA0, 0x98,
        0x1E, 0x2C, 0xC2, 0x4C, 0x1C, 0x23, 0xD1, 0x6A,
        0xA9, 0xB4, 0x39, 0x24, 0x15, 0xE2, 0x6C, 0x22,
        0xF4, 0xA9, 0x34, 0xD7, 0x94, 0xC1, 0xFB, 0x4E,
        0x5A, 0x67, 0x05, 0x11, 0x23, 0xCC, 0xD1, 0x53,
        0x76, 0x4D, 0xEC, 0x99, 0xD5, 0x53, 0x52, 0x90,
        0x53, 0xC3, 0xDA, 0x55, 0x0B, 0xCE, 0xA3, 0xAC,
        0x54, 0x13, 0x6A, 0x26, 0xA6, 0x76, 0xD2, 0xBA,
        0x84, 0x21, 0x06, 0x70, 0x68, 0xC6, 0x38, 0x1C,
        0x2A, 0x62, 0xA7, 0x27, 0xC9, 0x33, 0x70, 0x2E,
        0xE5, 0x80, 0x4A, 0x31, 0xCA, 0x86, 0x5A, 0x45,
        0x58, 0x8F, 0xB7, 0x4D, 0xE7, 0xE2, 0x22, 0x3D,
        0x88, 0xC0, 0x60, 0x8A, 0x16, 0xBF, 0xEC, 0x4F,
        0xAD, 0x67, 0x52, 0xDB, 0x56, 0xB4, 0x8B, 0x88,
        0x72, 0xBF, 0x26, 0xBA, 0x2F, 0xFA, 0x0C, 0xED,
        0xE5, 0x34, 0x3B, 0xE8, 0x14, 0x36, 0x89, 0x26,
        0x5E, 0x06, 0x5F, 0x41, 0xA6, 0x92, 0x5B, 0x86,
        0xC8, 0x92, 0xE6, 0x2E, 0xB0, 0x77, 0x27, 0x34,
        0xF5, 0xA3, 0x57, 0xC7, 0x5C, 0xA1, 0xAC, 0x6D,
        0xF7, 0x8A, 0xB1, 0xB8, 0x88, 0x5A, 0xD0, 0x81,
        0x96, 0x15, 0x37, 0x6D, 0x33, 0xEB, 0xB9, 0x8F,
        0x87, 0x33, 0xA6, 0x75, 0x58, 0x03, 0xD9, 0x77,
        0xBF, 0x51, 0xC1, 0x27, 0x40, 0x42, 0x4B, 0x2B,
        0x49, 0xC2, 0x83, 0x82, 0xA6, 0x91, 0x7C, 0xBF,
        0xA0, 0x34, 0xC3, 0xF1, 0x26, 0xA3, 0x8C, 0x21,
        0x6C, 0x03, 0xC3, 0x57, 0x70, 0xAD, 0x48, 0x1B,
        0x90, 0x84, 0xB5, 0x58, 0x8D, 0xA6, 0x5F, 0xF1,
        0x18, 0xA7, 0x4F, 0x93, 0x2C, 0x7E, 0x53, 0x7A,
        0xBE, 0x58, 0x63, 0xFB, 0x29, 0xA1, 0x0C, 0x09,
        0x70, 0x1B, 0x44, 0x1F, 0x83, 0x99, 0xC1, 0xF8,
        0xA6, 0x37, 0x82, 0x5A, 0xCE, 0xA3, 0xE9, 0x31,
        0x80, 0x57, 0x4F, 0xDE, 0xB8, 0x80, 0x76, 0x66,
        0x1A, 0xB4, 0x69, 0x51, 0x71, 0x6A, 0x50, 0x01,
        0x84, 0xA0, 0x40, 0x55, 0x72, 0x66, 0x59, 0x8C,
        0xAF, 0x76, 0x10, 0x5E, 0x1C, 0x18, 0x70, 0xB4,
        0x39, 0x69, 0xC3, 0xBC, 0xC1, 0xA0, 0x49, 0x27,
        0x63, 0x80, 0x17, 0x49, 0x8B, 0xB6, 0x2C, 0xAF,
        0xD3, 0xA6, 0xB0, 0x82, 0xB7, 0xBF, 0x7A, 0x23,
        0x45, 0x0E, 0x19, 0x17, 0x99, 0x61, 0x9B, 0x92,
        0x51, 0x12, 0xD0, 0x72, 0x02, 0x5C, 0xA8, 0x88,
        0x54, 0x8C, 0x79, 0x1A, 0xA4, 0x22, 0x51, 0x50,
        0x4D, 0x5D, 0x1C, 0x1C, 0xDD, 0xB2, 0x13, 0x30,
        0x3B, 0x04, 0x9E, 0x73, 0x46, 0xE8, 0xD8, 0x3A,
        0xD5, 0x87, 0x83, 0x6F, 0x35, 0x28, 0x4E, 0x10,
        0x97, 0x27, 0xE6, 0x6B, 0xBC, 0xC9, 0x52, 0x1F,
        0xE0, 0xB1, 0x91, 0x63, 0x00, 0x47, 0xD1, 0x58,
        0xF7, 0x56, 0x40, 0xFF, 0xEB, 0x54, 0x56, 0x07,
        0x27, 0x40, 0x02, 0x1A, 0xFD, 0x15, 0xA4, 0x54,
        0x69, 0xC5, 0x83, 0x82, 0x9D, 0xAA, 0xC8, 0xA7,
        0xDE, 0xB0, 0x5B, 0x24, 0xF0, 0x56, 0x7E, 0x43,
        0x17, 0xB3, 0xE3, 0xB3, 0x33, 0x89, 0xB5, 0xC5,
        0xF8, 0xB0, 0x4B, 0x09, 0x9F, 0xB4, 0xD1, 0x03,
        0xA3, 0x24, 0x39, 0xF8, 0x5A, 0x3C, 0x21, 0xD2,
        0x1A, 0x71, 0xB9, 0xB9, 0x2A, 0x9B, 0x64, 0xEA,
        0x0A, 0xB8, 0x43, 0x12, 0xC7, 0x70, 0x23, 0x69,
        0x4F, 0xD6, 0x4E, 0xAA, 0xB9, 0x07, 0xA4, 0x35,
        0x39, 0xDD, 0xB2, 0x7B, 0xA0, 0xA8, 0x53, 0xCC,
        0x90, 0x69, 0xEA, 0xC8, 0x50, 0x8C, 0x65, 0x3E,
        0x60, 0x0B, 0x2A, 0xC0, 0x18, 0x38, 0x1B, 0x4B,
        0xB4, 0xA8, 0x79, 0xAC, 0xDA, 0xD3, 0x42, 0xF9,
        0x11, 0x79, 0xCA, 0x82, 0x49, 0x52, 0x5C, 0xB1,
        0x96, 0x8B, 0xBE, 0x52, 0xF7, 0x55, 0xB7, 0xF5,
        0xB4, 0x3D, 0x66, 0x63, 0xD7, 0xA3, 0xBF, 0x0F,
        0x33, 0x57, 0xD8, 0xA2, 0x1D, 0x15, 0xB5, 0x2D,
        0xB3, 0x81, 0x8E, 0xCE, 0x5B, 0x40, 0x2A, 0x60,
        0xC9, 0x93, 0xE7, 0xCF, 0x43, 0x64, 0x87, 0xB8,
        0xD2, 0xAE, 0x91, 0xE6, 0xC5, 0xB8, 0x82, 0x75,
        0xE7, 0x58, 0x24, 0xB0, 0x00, 0x7E, 0xF3, 0x12,
        0x3C, 0x0A, 0xB5, 0x1B, 0x5C, 0xC6, 0x1B, 0x9B,
        0x22, 0x38, 0x0D, 0xE6, 0x6C, 0x5B, 0x20, 0xB0,
        0x60, 0xCB, 0xB9, 0x86, 0xF8, 0x12, 0x3D, 0x94,
        0x06, 0x00, 0x49, 0xCD, 0xF8, 0x03, 0x68, 0x73,
        0xA7, 0xBE, 0x10, 0x94, 0x44, 0xA0, 0xA1, 0xCD,
        0x87, 0xA4, 0x8C, 0xAE, 0x54, 0x19, 0x24, 0x84,
        0xAF, 0x84, 0x44, 0x29, 0xC1, 0xC5, 0x8C, 0x29,
        0xAC, 0x62, 0x4C, 0xD5, 0x04, 0xF1, 0xC4, 0x4F,
        0x1E, 0x13, 0x47, 0x82, 0x2B, 0x6F, 0x22, 0x13,
        0x23, 0x85, 0x9A, 0x7F, 0x6F, 0x75, 0x4B, 0xFE,
        0x71, 0x0B, 0xDA, 0x60, 0x27, 0x62, 0x40, 0xA4,
        0xFF, 0x2A, 0x53, 0x50, 0x70, 0x37, 0x86, 0xF5,
        0x67, 0x1F, 0x44, 0x9F, 0x20, 0xC2, 0xA9, 0x5A,
        0xE7, 0xC2, 0x90, 0x3A, 0x42, 0xCB, 0x3B, 0x30,
        0x3F, 0xF4, 0xC4, 0x27, 0xC0, 0x8B, 0x11, 0xB4,
        0xCD, 0x31, 0xC4, 0x18, 0xC6, 0xD1, 0x8D, 0x08,
        0x61, 0x87, 0x3B, 0xFA, 0x03, 0x32, 0xF1, 0x12,
        0x71, 0x55, 0x2E, 0xD7, 0xC0, 0x35, 0xF0, 0xE4,
        0xBC, 0x42, 0x8C, 0x43, 0x72, 0x0B, 0x39, 0xA6,
        0x51, 0x66, 0xBA, 0x9C, 0x2D, 0x3D, 0x77, 0x0E,
        0x13, 0x03, 0x60, 0xCC, 0x23, 0x84, 0xE8, 0x30,
        0x95, 0xB1, 0xA1, 0x59, 0x49, 0x55, 0x33, 0xF1,
        0x16, 0xC7, 0xB5, 0x58, 0xB6, 0x50, 0xDB, 0x04,
        0xD5, 0xA2, 0x6E, 0xAA, 0xA0, 0x8C, 0x3E, 0xE5,
        0x7D, 0xE4, 0x5A, 0x7F, 0x88, 0xC6, 0xA3, 0xCE,
        0xB2, 0x4D, 0xC5, 0x39, 0x7B, 0x88, 0xC3, 0xCE,
        0xF0, 0x03, 0x31, 0x9B, 0xB0, 0x23, 0x3F, 0xD6,
        0x92, 0xFD, 0xA1, 0x52, 0x44, 0x75, 0xB3, 0x51,
        0xF3, 0xC7, 0x82, 0x18, 0x2D, 0xEC, 0xF5, 0x90,
        0xB7, 0x72, 0x3B, 0xE4, 0x00, 0xBE, 0x14, 0x80,
        0x9C, 0x44, 0x32, 0x99, 0x63, 0xFC, 0x46, 0x95,
        0x92, 0x11, 0xD6, 0xA6, 0x23, 0x33, 0x95, 0x37,
        0x84, 0x8C, 0x25, 0x16, 0x69, 0x94, 0x1D, 0x90,
        0xB1, 0x30, 0x25, 0x8A, 0xDF, 0x55, 0xA7, 0x20,
        0xA7, 0x24, 0xE8, 0xB6, 0xA6, 0xCA, 0xE3, 0xC2,
        0x26, 0x4B, 0x16, 0x24, 0xCC, 0xBE, 0x7B, 0x45,
        0x6B, 0x30, 0xC8, 0xC7, 0x39, 0x32, 0x94, 0xCA,
        0x51, 0x80, 0xBC, 0x83, 0x7D, 0xD2, 0xE4, 0x5D,
        0xBD, 0x59, 0xB6, 0xE1, 0x7B, 0x24, 0xFE, 0x93,
        0x05, 0x2E, 0xB7, 0xC4, 0x3B, 0x27, 0xAC, 0x3D,
        0xC2, 0x49, 0xCA, 0x0C, 0xBC, 0xA4, 0xFB, 0x58,
        0x97, 0xC0, 0xB7, 0x44, 0x08, 0x8A, 0x8A, 0x07,
        0x79, 0xD3, 0x22, 0x33, 0x82, 0x6A, 0x01, 0xDD,
        0x64, 0x89, 0x95, 0x2A, 0x48, 0x25, 0xE5, 0x35,
        0x8A, 0x70, 0x0B, 0xE0, 0xE1, 0x79, 0xAC, 0x19,
        0x77, 0x10, 0xD8, 0x3E, 0xCC, 0x85, 0x3E, 0x52,
        0x69, 0x5E, 0x9B, 0xF8, 0x7B, 0xB1, 0xF6, 0xCB,
        0xD0, 0x5B, 0x02, 0xD4, 0xE6, 0x79, 0xE3, 0xB8,
        0x8D, 0xD4, 0x83, 0xB0, 0x74, 0x9B, 0x11, 0xBD,
        0x37, 0xB3, 0x83, 0xDC, 0xCA, 0x71, 0xF9, 0x09,
        0x18, 0x34, 0xA1, 0x69, 0x55, 0x02, 0xC4, 0xB9,
        0x5F, 0xC9, 0x11, 0x8C, 0x1C, 0xFC, 0x34, 0xC8,
        0x4C, 0x22, 0x65, 0xBB, 0xBC, 0x56, 0x3C, 0x28,
        0x26, 0x66, 0xB6, 0x0A, 0xE5, 0xC7, 0xF3, 0x85,
        0x1D, 0x25, 0xEC, 0xBB, 0x50, 0x21, 0xCC, 0x38,
        0xCB, 0x73, 0xEB, 0x6A, 0x34, 0x11, 0xB1, 0xC2,
        0x90, 0x46, 0xCA, 0x66, 0x54, 0x06, 0x67, 0xD1,
        0x36, 0x95, 0x44, 0x60, 0xC6, 0xFC, 0xBC, 0x4B,
        0xC7, 0xC0, 0x49, 0xBB, 0x04, 0x7F, 0xA6, 0x7A,
        0x63, 0xB3, 0xCC, 0x11, 0x11, 0xC1, 0xD8, 0xAC,
        0x27, 0xE8, 0x05, 0x8B, 0xCC, 0xA4, 0xA1, 0x54,
        0x55, 0x85, 0x8A, 0x58, 0x35, 0x8F, 0x7A, 0x61,
        0x02, 0x0B, 0xC9, 0xC4, 0xC1, 0x7F, 0x8B, 0x95,
        0xC2, 0x68, 0xCC, 0xB4, 0x04, 0xB9, 0xAA, 0xB4,
        0xA2, 0x72, 0xA2, 0x1A, 0x70, 0xDA, 0xF6, 0xB6,
        0xF1, 0x51, 0x21, 0xEE, 0x01, 0xC1, 0x56, 0xA3,
        0x54, 0xAA, 0x17, 0x08, 0x7E, 0x07, 0x70, 0x2E,
        0xAB, 0x38, 0xB3, 0x24, 0x1F, 0xDB, 0x55, 0x3F,
        0x65, 0x73, 0x39, 0xD5, 0xE2, 0x9D, 0xC5, 0xD9,
        0x1B, 0x7A, 0x5A, 0x82, 0x8E, 0xE9, 0x59, 0xFE,
        0xBB, 0x90, 0xB0, 0x72, 0x29, 0xF6, 0xE4, 0x9D,
        0x23, 0xC3, 0xA1, 0x90, 0x29, 0x70, 0x42, 0xFB,
        0x43, 0x98, 0x69, 0x55, 0xB6, 0x9C, 0x28, 0xE1,
        0x01, 0x6F, 0x77, 0xA5, 0x8B, 0x43, 0x15, 0x14,
        0xD2, 0x1B, 0x88, 0x88, 0x99, 0xC3, 0x60, 0x82,
        0x76, 0x08, 0x1B, 0x75, 0xF5, 0x68, 0x09, 0x7C,
        0xDC, 0x17, 0x48, 0xF3, 0x23, 0x07, 0x88, 0x58,
        0x15, 0xF3, 0xAE, 0xC9, 0x65, 0x18, 0x19, 0xAA,
        0x68, 0x73, 0xD1, 0xA4, 0xEB, 0x83, 0xB1, 0x95,
        0x38, 0x43, 0xB9, 0x34, 0x22, 0x51, 0x94, 0x83,
        0xFE, 0xF0, 0x05, 0x9D, 0x36, 0xBB, 0x2D, 0xB1,
        0xF3, 0xD4, 0x68, 0xFB, 0x06, 0x8C, 0x86, 0xE8,
        0x97, 0x37, 0x33, 0xC3, 0x98, 0xEA, 0xF0, 0x0E,
        0x17, 0x02, 0xC6, 0x73, 0x4A, 0xD8, 0xEB, 0x3B,
        0x62, 0x01, 0x30, 0xD6, 0xC2, 0xB8, 0xC9, 0x04,
        0xA3, 0xBB, 0x93, 0x07, 0xBE, 0x51, 0x03, 0xF8,
        0xD8, 0x14, 0x50, 0x5F, 0xB6, 0xA6, 0x0A, 0xF7,
        0x93, 0x7E, 0xA6, 0xCA, 0xA1, 0x17, 0x31, 0x5E,
        0x84, 0xCC, 0x91, 0x21, 0xAE, 0x56, 0xFB, 0xF3,
        0x9E, 0x67, 0xAD, 0xBD, 0x83, 0xAD, 0x2D, 0x3E,
        0x3B, 0xB8, 0x08, 0x43, 0x64, 0x52, 0x06, 0xBD,
        0xD9, 0xF2, 0xF6, 0x29, 0xE3, 0xCC, 0x49, 0xB7
    };
#endif
#ifndef WOLFSSL_NO_KYBER768
    static const byte seed_768[KYBER_MAKEKEY_RAND_SZ] = {
        /* d */
        0xE3, 0x4A, 0x70, 0x1C, 0x4C, 0x87, 0x58, 0x2F,
        0x42, 0x26, 0x4E, 0xE4, 0x22, 0xD3, 0xC6, 0x84,
        0xD9, 0x76, 0x11, 0xF2, 0x52, 0x3E, 0xFE, 0x0C,
        0x99, 0x8A, 0xF0, 0x50, 0x56, 0xD6, 0x93, 0xDC,
        /* z */
        0xA8, 0x57, 0x68, 0xF3, 0x48, 0x6B, 0xD3, 0x2A,
        0x01, 0xBF, 0x9A, 0x8F, 0x21, 0xEA, 0x93, 0x8E,
        0x64, 0x8E, 0xAE, 0x4E, 0x54, 0x48, 0xC3, 0x4C,
        0x3E, 0xB8, 0x88, 0x20, 0xB1, 0x59, 0xEE, 0xDD
    };
    static const byte ek_768[KYBER768_PUBLIC_KEY_SIZE] = {
        0x6D, 0x14, 0xA0, 0x71, 0xF7, 0xCC, 0x45, 0x25,
        0x58, 0xD5, 0xE7, 0x1A, 0x7B, 0x08, 0x70, 0x62,
        0xEC, 0xB1, 0x38, 0x68, 0x44, 0x58, 0x82, 0x46,
        0x12, 0x64, 0x02, 0xB1, 0xFA, 0x16, 0x37, 0x73,
        0x3C, 0xD5, 0xF6, 0x0C, 0xC8, 0x4B, 0xCB, 0x64,
        0x6A, 0x78, 0x92, 0x61, 0x4D, 0x7C, 0x51, 0xB1,
        0xC7, 0xF1, 0xA2, 0x79, 0x91, 0x32, 0xF1, 0x34,
        0x27, 0xDC, 0x48, 0x21, 0x58, 0xDA, 0x25, 0x44,
        0x70, 0xA5, 0x9E, 0x00, 0xA4, 0xE4, 0x96, 0x86,
        0xFD, 0xC0, 0x77, 0x55, 0x93, 0x67, 0x27, 0x0C,
        0x21, 0x53, 0xF1, 0x10, 0x07, 0x59, 0x2C, 0x9C,
        0x43, 0x10, 0xCF, 0x8A, 0x12, 0xC6, 0xA8, 0x71,
        0x3B, 0xD6, 0xBB, 0x51, 0xF3, 0x12, 0x4F, 0x98,
        0x9B, 0xA0, 0xD5, 0x40, 0x73, 0xCC, 0x24, 0x2E,
        0x09, 0x68, 0x78, 0x0B, 0x87, 0x5A, 0x86, 0x9E,
        0xFB, 0x85, 0x15, 0x86, 0xB9, 0xA8, 0x68, 0xA3,
        0x84, 0xB9, 0xE6, 0x82, 0x1B, 0x20, 0x1B, 0x93,
        0x2C, 0x45, 0x53, 0x69, 0xA7, 0x39, 0xEC, 0x22,
        0x56, 0x9C, 0x97, 0x7C, 0x21, 0x2B, 0x38, 0x18,
        0x71, 0x81, 0x36, 0x56, 0xAF, 0x5B, 0x56, 0x7E,
        0xF8, 0x93, 0xB5, 0x84, 0x62, 0x4C, 0x86, 0x3A,
        0x25, 0x90, 0x00, 0xF1, 0x7B, 0x25, 0x4B, 0x98,
        0xB1, 0x85, 0x09, 0x7C, 0x50, 0xEB, 0xB6, 0x8B,
        0x24, 0x43, 0x42, 0xE0, 0x5D, 0x4D, 0xE5, 0x20,
        0x12, 0x5B, 0x8E, 0x10, 0x33, 0xB1, 0x43, 0x60,
        0x93, 0xAC, 0xE7, 0xCE, 0x8E, 0x71, 0xB4, 0x58,
        0xD5, 0x25, 0x67, 0x33, 0x63, 0x04, 0x5A, 0x3B,
        0x3E, 0xEA, 0x94, 0x55, 0x42, 0x8A, 0x39, 0x87,
        0x05, 0xA4, 0x23, 0x27, 0xAD, 0xB3, 0x77, 0x4B,
        0x70, 0x57, 0xF4, 0x2B, 0x01, 0x7E, 0xC0, 0x73,
        0x9A, 0x98, 0x3F, 0x19, 0xE8, 0x21, 0x4D, 0x09,
        0x19, 0x5F, 0xA2, 0x4D, 0x2D, 0x57, 0x1D, 0xB7,
        0x3C, 0x19, 0xA6, 0xF8, 0x46, 0x0E, 0x50, 0x83,
        0x0D, 0x41, 0x5F, 0x62, 0x7B, 0x88, 0xE9, 0x4A,
        0x7B, 0x15, 0x37, 0x91, 0xA0, 0xC0, 0xC7, 0xE9,
        0x48, 0x4C, 0x74, 0xD5, 0x3C, 0x71, 0x48, 0x89,
        0xF0, 0xE3, 0x21, 0xB6, 0x66, 0x0A, 0x53, 0x2A,
        0x5B, 0xC0, 0xE5, 0x57, 0xFB, 0xCA, 0x35, 0xE2,
        0x9B, 0xC6, 0x11, 0x20, 0x0E, 0xD3, 0xC6, 0x33,
        0x07, 0x7A, 0x4D, 0x87, 0x3C, 0x5C, 0xC6, 0x70,
        0x06, 0xB7, 0x53, 0xBF, 0x6D, 0x6B, 0x7A, 0xF6,
        0xCA, 0x40, 0x2A, 0xB6, 0x18, 0x23, 0x6C, 0x0A,
        0xFF, 0xBC, 0x80, 0x1F, 0x82, 0x22, 0xFB, 0xC3,
        0x6C, 0xE0, 0x98, 0x4E, 0x2B, 0x18, 0xC9, 0x44,
        0xBB, 0xCB, 0xEF, 0x03, 0xB1, 0xE1, 0x36, 0x1C,
        0x1F, 0x44, 0xB0, 0xD7, 0x34, 0xAF, 0xB1, 0x56,
        0x6C, 0xFF, 0x87, 0x44, 0xDA, 0x8B, 0x99, 0x43,
        0xD6, 0xB4, 0x5A, 0x3C, 0x09, 0x03, 0x07, 0x02,
        0xCA, 0x20, 0x1F, 0xFE, 0x20, 0xCB, 0x7E, 0xC5,
        0xB0, 0xD4, 0x14, 0x9E, 0xE2, 0xC2, 0x8E, 0x8B,
        0x23, 0x37, 0x4F, 0x47, 0x1B, 0x57, 0x15, 0x0D,
        0x0E, 0xC9, 0x33, 0x62, 0x61, 0xA2, 0xD5, 0xCB,
        0x84, 0xA3, 0xAC, 0xAC, 0xC4, 0x28, 0x94, 0x73,
        0xA4, 0xC0, 0xAB, 0xC6, 0x17, 0xC9, 0xAB, 0xC1,
        0x78, 0x73, 0x44, 0x34, 0xC8, 0x2E, 0x16, 0x85,
        0x58, 0x8A, 0x5C, 0x2E, 0xA2, 0x67, 0x8F, 0x6B,
        0x3C, 0x22, 0x28, 0x73, 0x31, 0x30, 0xC4, 0x66,
        0xE5, 0xB8, 0x6E, 0xF4, 0x91, 0x15, 0x3E, 0x48,
        0x66, 0x22, 0x47, 0xB8, 0x75, 0xD2, 0x01, 0x02,
        0x0B, 0x56, 0x6B, 0x81, 0xB6, 0x4D, 0x83, 0x9A,
        0xB4, 0x63, 0x3B, 0xAA, 0x8A, 0xCE, 0x20, 0x2B,
        0xAA, 0xB4, 0x49, 0x62, 0x97, 0xF9, 0x80, 0x7A,
        0xDB, 0xBB, 0x1E, 0x33, 0x2C, 0x6F, 0x80, 0x22,
        0xB2, 0xA1, 0x8C, 0xFD, 0xD4, 0xA8, 0x25, 0x30,
        0xB6, 0xD3, 0xF0, 0x07, 0xC3, 0x35, 0x38, 0x98,
        0xD9, 0x66, 0xCC, 0x2C, 0x21, 0xCB, 0x42, 0x44,
        0xBD, 0x00, 0x44, 0x3F, 0x20, 0x98, 0x70, 0xAC,
        0xC4, 0x2B, 0xC3, 0x30, 0x68, 0xC7, 0x24, 0xEC,
        0x17, 0x22, 0x36, 0x19, 0xC1, 0x09, 0x3C, 0xCA,
        0x6A, 0xEB, 0x29, 0x50, 0x06, 0x64, 0xD1, 0x22,
        0x50, 0x36, 0xB4, 0xB8, 0x10, 0x91, 0x90, 0x69,
        0x69, 0x48, 0x1F, 0x1C, 0x72, 0x3C, 0x14, 0x0B,
        0x9D, 0x6C, 0x16, 0x8F, 0x5B, 0x64, 0xBE, 0xA6,
        0x9C, 0x5F, 0xD6, 0x38, 0x5D, 0xF7, 0x36, 0x4B,
        0x87, 0x23, 0xBC, 0xC8, 0x5E, 0x03, 0x8C, 0x7E,
        0x46, 0x4A, 0x90, 0x0D, 0x68, 0xA2, 0x12, 0x78,
        0x18, 0x99, 0x42, 0x17, 0xAE, 0xC8, 0xBD, 0xB3,
        0x9A, 0x97, 0x0A, 0x99, 0x63, 0xDE, 0x93, 0x68,
        0x8E, 0x2A, 0xC8, 0x2A, 0xBC, 0xC2, 0x2F, 0xB9,
        0x27, 0x7B, 0xA2, 0x20, 0x09, 0xE8, 0x78, 0x38,
        0x1A, 0x38, 0x16, 0x39, 0x01, 0xC7, 0xD4, 0xC8,
        0x50, 0x19, 0x53, 0x8D, 0x35, 0xCA, 0xAE, 0x9C,
        0x41, 0xAF, 0x8C, 0x92, 0x9E, 0xE2, 0x0B, 0xB0,
        0x8C, 0xA6, 0x19, 0xE7, 0x2C, 0x2F, 0x22, 0x62,
        0xC1, 0xC9, 0x93, 0x85, 0x72, 0x55, 0x1A, 0xC0,
        0x2D, 0xC9, 0x26, 0x8F, 0xBC, 0xC3, 0x5D, 0x79,
        0x01, 0x1C, 0x3C, 0x09, 0x0A, 0xD4, 0x0A, 0x4F,
        0x11, 0x1C, 0x9B, 0xE5, 0x5C, 0x42, 0x7E, 0xB7,
        0x96, 0xC1, 0x93, 0x2D, 0x86, 0x73, 0x57, 0x9A,
        0xF1, 0xB4, 0xC6, 0x38, 0xB0, 0x94, 0x44, 0x89,
        0x01, 0x2A, 0x25, 0x59, 0xA3, 0xB0, 0x24, 0x81,
        0xB0, 0x1A, 0xC3, 0x0B, 0xA8, 0x96, 0x0F, 0x80,
        0xC0, 0xC2, 0xB3, 0x94, 0x7D, 0x36, 0xA1, 0x2C,
        0x08, 0x04, 0x98, 0xBE, 0xE4, 0x48, 0x71, 0x6C,
        0x97, 0x34, 0x16, 0xC8, 0x24, 0x28, 0x04, 0xA3,
        0xDA, 0x09, 0x9E, 0xE1, 0x37, 0xB0, 0xBA, 0x90,
        0xFE, 0x4A, 0x5C, 0x6A, 0x89, 0x20, 0x02, 0x76,
        0xA0, 0xCF, 0xB6, 0x43, 0xEC, 0x2C, 0x56, 0xA2,
        0xD7, 0x08, 0xD7, 0xB4, 0x37, 0x3E, 0x44, 0xC1,
        0x50, 0x2A, 0x76, 0x3A, 0x60, 0x05, 0x86, 0xE6,
        0xCD, 0xA6, 0x27, 0x38, 0x97, 0xD4, 0x44, 0x48,
        0x28, 0x7D, 0xC2, 0xE6, 0x02, 0xDC, 0x39, 0x20,
        0x0B, 0xF6, 0x16, 0x62, 0x36, 0x55, 0x9F, 0xD1,
        0x2A, 0x60, 0x89, 0x2A, 0xEB, 0x15, 0x3D, 0xD6,
        0x51, 0xBB, 0x46, 0x99, 0x10, 0xB4, 0xB3, 0x46,
        0x69, 0xF9, 0x1D, 0xA8, 0x65, 0x4D, 0x1E, 0xB7,
        0x2E, 0xB6, 0xE0, 0x28, 0x00, 0xB3, 0xB0, 0xA7,
        0xD0, 0xA4, 0x8C, 0x83, 0x68, 0x54, 0xD3, 0xA8,
        0x3E, 0x65, 0x56, 0x9C, 0xB7, 0x23, 0x0B, 0xB4,
        0x4F, 0x3F, 0x14, 0x3A, 0x6D, 0xEC, 0x5F, 0x2C,
        0x39, 0xAB, 0x90, 0xF2, 0x74, 0xF2, 0x08, 0x8B,
        0xD3, 0xD6, 0xA6, 0xFC, 0xA0, 0x07, 0x02, 0x73,
        0xBE, 0xDC, 0x84, 0x77, 0x7F, 0xB5, 0x2E, 0x3C,
        0x55, 0x8B, 0x0A, 0xE0, 0x61, 0x83, 0xD5, 0xA4,
        0x8D, 0x45, 0x2F, 0x68, 0xE1, 0x52, 0x07, 0xF8,
        0x61, 0x62, 0x7A, 0xCA, 0x14, 0x27, 0x96, 0x30,
        0xF8, 0x2E, 0xC3, 0xA0, 0xCA, 0x07, 0x86, 0x33,
        0xB6, 0x00, 0xAF, 0xA7, 0x97, 0x43, 0xA6, 0x00,
        0x21, 0x5B, 0xE5, 0x63, 0x74, 0x58, 0xCE, 0x2C,
        0xE8, 0xAF, 0xF5, 0xA0, 0x8E, 0xB5, 0x01, 0x7B,
        0x2C, 0x76, 0x65, 0x77, 0x47, 0x9F, 0x8D, 0xC6,
        0xBF, 0x9F, 0x5C, 0xC7, 0x50, 0x89, 0x93, 0x21,
        0x61, 0xB9, 0x6C, 0xEA, 0x40, 0x66, 0x20, 0xAE,
        0xDB, 0x63, 0x04, 0x07, 0xF7, 0x68, 0x7E, 0xBB,
        0xB4, 0x81, 0x4C, 0x79, 0x81, 0x63, 0x7A, 0x48,
        0xA9, 0x0D, 0xE6, 0x80, 0x31, 0xE0, 0x62, 0xA7,
        0xAF, 0x76, 0x12, 0xB4, 0xF5, 0xC7, 0xA6, 0xDA,
        0x86, 0xBD, 0x13, 0x65, 0x29, 0xE6, 0x42, 0x95,
        0xA5, 0x61, 0x3E, 0xA7, 0x3B, 0xD3, 0xD4, 0x44,
        0x8C, 0xB8, 0x1F, 0x24, 0x31, 0x35, 0xC0, 0xA6,
        0x60, 0xBE, 0xB9, 0xC1, 0x7E, 0x65, 0x1D, 0xEF,
        0x46, 0x9A, 0x7D, 0x90, 0xA1, 0x5D, 0x34, 0x81,
        0x09, 0x0B, 0xCB, 0xF2, 0x27, 0x01, 0x23, 0x28,
        0x94, 0x1F, 0xA4, 0x6F, 0x39, 0xC5, 0x00, 0x6A,
        0xD9, 0x3D, 0x45, 0x8A, 0xA6, 0xAD, 0xD6, 0x55,
        0x86, 0x2B, 0x41, 0x8C, 0x30, 0x94, 0xF5, 0x51,
        0x46, 0x0D, 0xF2, 0x15, 0x3A, 0x58, 0x10, 0xA7,
        0xDA, 0x74, 0xF0, 0x61, 0x4C, 0x25, 0x88, 0xBE,
        0x49, 0xDC, 0x6F, 0x5E, 0x88, 0x15, 0x46, 0x42,
        0xBD, 0x1D, 0x37, 0x62, 0x56, 0x33, 0x26, 0x43,
        0x35, 0x07, 0x15, 0x6A, 0x57, 0xC5, 0x76, 0x94,
        0xBD, 0xD2, 0x6E, 0x7A, 0x24, 0x6F, 0xEB, 0x72,
        0x3A, 0xED, 0x67, 0xB0, 0x48, 0x87, 0xC8, 0xE4,
        0x76, 0xB4, 0x8C, 0xAB, 0x59, 0xE5, 0x36, 0x2F,
        0x26, 0xA9, 0xEF, 0x50, 0xC2, 0xBC, 0x80, 0xBA,
        0x14, 0x62, 0x26, 0x21, 0x6F, 0xE6, 0x29, 0x68,
        0xA6, 0x0D, 0x04, 0xE8, 0xC1, 0x70, 0xD7, 0x41,
        0xC7, 0xA2, 0xB0, 0xE1, 0xAB, 0xDA, 0xC9, 0x68
    };
    static const byte dk_768[KYBER768_PRIVATE_KEY_SIZE] = {
        0x98, 0xA1, 0xB2, 0xDA, 0x4A, 0x65, 0xCF, 0xB5,
        0x84, 0x5E, 0xA7, 0x31, 0x1E, 0x6A, 0x06, 0xDB,
        0x73, 0x1F, 0x15, 0x90, 0xC4, 0x1E, 0xE7, 0x4B,
        0xA1, 0x07, 0x82, 0x71, 0x5B, 0x35, 0xA3, 0x10,
        0x2D, 0xF6, 0x37, 0x87, 0x2B, 0xE6, 0x5B, 0xAB,
        0x37, 0xA1, 0xDE, 0x25, 0x11, 0xD7, 0x03, 0xC7,
        0x02, 0x47, 0xB3, 0x5E, 0xF2, 0x74, 0x35, 0x48,
        0x50, 0x24, 0xD9, 0x3F, 0xD9, 0xE7, 0x7C, 0x43,
        0x80, 0x4F, 0x37, 0x17, 0x49, 0xBA, 0x00, 0xB2,
        0x0A, 0x8C, 0x5C, 0x58, 0x8B, 0xC9, 0xAB, 0xE0,
        0x68, 0xAE, 0xAA, 0xA9, 0x38, 0x51, 0x7E, 0xBF,
        0xE5, 0x3B, 0x6B, 0x66, 0x32, 0x82, 0x90, 0x3D,
        0xCD, 0x18, 0x97, 0x36, 0xD7, 0x29, 0x68, 0x16,
        0xC7, 0x33, 0xA1, 0xC7, 0x7C, 0x63, 0x75, 0xE5,
        0x39, 0x7C, 0x0F, 0x18, 0x9B, 0xBF, 0xE4, 0x76,
        0x43, 0xA6, 0x1F, 0x58, 0xF8, 0xA3, 0xC6, 0x91,
        0x1B, 0xE4, 0x61, 0x1A, 0x8C, 0x7B, 0xC0, 0x50,
        0x02, 0x11, 0x63, 0xD0, 0xA4, 0x04, 0xDC, 0x14,
        0x06, 0x57, 0x48, 0xFF, 0x29, 0xBE, 0x60, 0xD2,
        0xB9, 0xFD, 0xCC, 0x8F, 0xFD, 0x98, 0xC5, 0x87,
        0xF3, 0x8C, 0x67, 0x11, 0x57, 0x86, 0x46, 0x4B,
        0xDB, 0x34, 0x2B, 0x17, 0xE8, 0x97, 0xD6, 0x46,
        0x17, 0xCB, 0xFB, 0x11, 0x79, 0x73, 0xA5, 0x45,
        0x89, 0x77, 0xA7, 0xD7, 0x61, 0x7A, 0x1B, 0x4D,
        0x83, 0xBA, 0x03, 0xC6, 0x11, 0x13, 0x8A, 0x46,
        0x73, 0xB1, 0xEB, 0x34, 0xB0, 0x78, 0x03, 0x3F,
        0x97, 0xCF, 0xFE, 0x80, 0xC1, 0x46, 0xA2, 0x69,
        0x43, 0xF8, 0x42, 0xB9, 0x76, 0x32, 0x7B, 0xF1,
        0xCB, 0xC6, 0x01, 0x19, 0x52, 0x5B, 0xB9, 0xA3,
        0xC0, 0x34, 0x93, 0x34, 0x90, 0x00, 0xDD, 0x8F,
        0x51, 0xBA, 0x21, 0xA2, 0xE9, 0x23, 0x61, 0x76,
        0x23, 0x24, 0x60, 0x0E, 0x0C, 0x13, 0xAA, 0xA6,
        0xCB, 0x69, 0xBF, 0xB2, 0x42, 0x76, 0x48, 0x3F,
        0x6B, 0x02, 0x42, 0x12, 0x59, 0xB7, 0x58, 0x52,
        0x63, 0xC1, 0xA0, 0x28, 0xD6, 0x82, 0xC5, 0x08,
        0xBB, 0xC2, 0x80, 0x1A, 0x56, 0xE9, 0x8B, 0x8F,
        0x62, 0x0B, 0x04, 0x83, 0xD7, 0x9B, 0x5A, 0xD8,
        0x58, 0x5A, 0xC0, 0xA4, 0x75, 0xBA, 0xC7, 0x78,
        0x65, 0x19, 0x41, 0x96, 0x33, 0x87, 0x91, 0xB7,
        0x98, 0x5A, 0x05, 0xD1, 0x09, 0x39, 0x5C, 0xCA,
        0x89, 0x32, 0x72, 0x2A, 0x91, 0x95, 0x0D, 0x37,
        0xE1, 0x2B, 0x89, 0x14, 0x20, 0xA5, 0x2B, 0x62,
        0xCB, 0xFA, 0x81, 0x5D, 0xF6, 0x17, 0x4C, 0xE0,
        0x0E, 0x68, 0xBC, 0xA7, 0x5D, 0x48, 0x38, 0xCA,
        0x28, 0x0F, 0x71, 0x3C, 0x7E, 0x69, 0x24, 0xAF,
        0xD9, 0x5B, 0xAA, 0x0D, 0x01, 0xAD, 0xA6, 0x37,
        0xB1, 0x58, 0x34, 0x70, 0x34, 0xC0, 0xAB, 0x1A,
        0x71, 0x83, 0x33, 0x1A, 0x82, 0x0A, 0xCB, 0xCB,
        0x83, 0x19, 0x3A, 0x1A, 0x94, 0xC8, 0xF7, 0xE3,
        0x84, 0xAE, 0xD0, 0xC3, 0x5E, 0xD3, 0xCB, 0x33,
        0x97, 0xBB, 0x63, 0x80, 0x86, 0xE7, 0xA3, 0x5A,
        0x64, 0x08, 0xA3, 0xA4, 0xB9, 0x0C, 0xE9, 0x53,
        0x70, 0x7C, 0x19, 0xBC, 0x46, 0xC3, 0xB2, 0xDA,
        0x3B, 0x2E, 0xE3, 0x23, 0x19, 0xC5, 0x6B, 0x92,
        0x80, 0x32, 0xB5, 0xED, 0x12, 0x56, 0xD0, 0x75,
        0x3D, 0x34, 0x14, 0x23, 0xE9, 0xDB, 0x13, 0x9D,
        0xE7, 0x71, 0x4F, 0xF0, 0x75, 0xCA, 0xF5, 0x8F,
        0xD9, 0xF5, 0x7D, 0x1A, 0x54, 0x01, 0x9B, 0x59,
        0x26, 0x40, 0x68, 0x30, 0xDA, 0xE2, 0x9A, 0x87,
        0x53, 0x02, 0xA8, 0x12, 0x56, 0xF4, 0xD6, 0xCF,
        0x5E, 0x74, 0x03, 0x4E, 0xA6, 0x14, 0xBF, 0x70,
        0xC2, 0x76, 0x4B, 0x20, 0xC9, 0x58, 0x9C, 0xDB,
        0x5C, 0x25, 0x76, 0x1A, 0x04, 0xE5, 0x82, 0x92,
        0x90, 0x7C, 0x57, 0x8A, 0x94, 0xA3, 0x58, 0x36,
        0xBE, 0xE3, 0x11, 0x2D, 0xC2, 0xC3, 0xAE, 0x21,
        0x92, 0xC9, 0xDE, 0xAA, 0x30, 0x4B, 0x29, 0xC7,
        0xFE, 0xA1, 0xBD, 0xF4, 0x7B, 0x3B, 0x6B, 0xCB,
        0xA2, 0xC0, 0xE5, 0x5C, 0x9C, 0xDB, 0x6D, 0xE7,
        0x14, 0x9E, 0x9C, 0xB1, 0x79, 0x17, 0x71, 0x8F,
        0x12, 0xC8, 0x03, 0x2D, 0xE1, 0xAD, 0xE0, 0x64,
        0x8D, 0x40, 0x55, 0x19, 0xC7, 0x07, 0x19, 0xBE,
        0xCC, 0x70, 0x18, 0x45, 0xCF, 0x9F, 0x4B, 0x91,
        0x2F, 0xE7, 0x19, 0x83, 0xCA, 0x34, 0xF9, 0x01,
        0x8C, 0x7C, 0xA7, 0xBB, 0x2F, 0x6C, 0x5D, 0x7F,
        0x8C, 0x5B, 0x29, 0x73, 0x59, 0xEC, 0x75, 0x20,
        0x9C, 0x25, 0x43, 0xFF, 0x11, 0xC4, 0x24, 0x49,
        0x77, 0xC5, 0x96, 0x95, 0x24, 0xEC, 0x45, 0x4D,
        0x44, 0xC3, 0x23, 0xFC, 0xCA, 0x94, 0xAC, 0xAC,
        0x27, 0x3A, 0x0E, 0xC4, 0x9B, 0x4A, 0x8A, 0x58,
        0x5B, 0xCE, 0x7A, 0x5B, 0x30, 0x5C, 0x04, 0xC3,
        0x50, 0x64, 0x22, 0x58, 0x03, 0x57, 0x01, 0x6A,
        0x85, 0x0C, 0x3F, 0x7E, 0xE1, 0x72, 0x05, 0xA7,
        0x7B, 0x29, 0x1C, 0x77, 0x31, 0xC9, 0x83, 0x6C,
        0x02, 0xAE, 0xE5, 0x40, 0x6F, 0x63, 0xC6, 0xA0,
        0x7A, 0x21, 0x43, 0x82, 0xAA, 0x15, 0x33, 0x6C,
        0x05, 0xD1, 0x04, 0x55, 0x88, 0x10, 0x76, 0x45,
        0xEA, 0x7D, 0xE6, 0x87, 0x0F, 0xC0, 0xE5, 0x5E,
        0x15, 0x40, 0x97, 0x43, 0x01, 0xC4, 0x2E, 0xC1,
        0x41, 0x05, 0x51, 0x86, 0x80, 0xF6, 0x88, 0xAB,
        0xE4, 0xCE, 0x45, 0x37, 0x38, 0xFE, 0x47, 0x1B,
        0x87, 0xFC, 0x31, 0xF5, 0xC6, 0x8A, 0x39, 0xE6,
        0x8A, 0xF5, 0x1B, 0x02, 0x40, 0xB9, 0x0E, 0x03,
        0x64, 0xB0, 0x4B, 0xAC, 0x43, 0xD6, 0xFB, 0x68,
        0xAB, 0x65, 0xAE, 0x02, 0x8B, 0x62, 0xBD, 0x68,
        0x3B, 0x7D, 0x28, 0xAD, 0x38, 0x80, 0x6B, 0xEE,
        0x72, 0x5B, 0x5B, 0x24, 0x16, 0xA8, 0xD7, 0x9C,
        0x16, 0xEC, 0x2A, 0x99, 0xEA, 0x4A, 0x8D, 0x92,
        0xA2, 0xF5, 0x05, 0x2E, 0x67, 0xF9, 0x73, 0x52,
        0x28, 0x97, 0x61, 0xC5, 0xC3, 0x9F, 0xC5, 0xC7,
        0x42, 0xE9, 0xC0, 0xA7, 0x40, 0xCA, 0x59, 0xFC,
        0x01, 0x82, 0xF7, 0x09, 0xD0, 0x1B, 0x51, 0x87,
        0xF0, 0x00, 0x63, 0xDA, 0xAB, 0x39, 0x75, 0x96,
        0xEE, 0xA4, 0xA3, 0x1B, 0xDB, 0xCB, 0xD4, 0xC1,
        0xBB, 0x0C, 0x55, 0xBE, 0x7C, 0x68, 0x50, 0xFD,
        0xA9, 0x32, 0x6B, 0x35, 0x3E, 0x28, 0x8C, 0x50,
        0x13, 0x22, 0x6C, 0x3C, 0x39, 0x23, 0xA7, 0x91,
        0x60, 0x9E, 0x80, 0x02, 0xE7, 0x3A, 0x5F, 0x7B,
        0x6B, 0xB4, 0xA8, 0x77, 0xB1, 0xFD, 0xF5, 0x3B,
        0xB2, 0xBA, 0xB3, 0xDD, 0x42, 0x4D, 0x31, 0xBB,
        0xB4, 0x48, 0xE6, 0x09, 0xA6, 0x6B, 0x0E, 0x34,
        0x3C, 0x28, 0x6E, 0x87, 0x60, 0x31, 0x2B, 0x6D,
        0x37, 0xAA, 0x52, 0x01, 0xD2, 0x1F, 0x53, 0x50,
        0x3D, 0x88, 0x38, 0x9A, 0xDC, 0xA2, 0x1C, 0x70,
        0xFB, 0x6C, 0x0F, 0xC9, 0xC6, 0x9D, 0x66, 0x16,
        0xC9, 0xEA, 0x37, 0x80, 0xE3, 0x55, 0x65, 0xC0,
        0xC9, 0x7C, 0x15, 0x17, 0x9C, 0x95, 0x34, 0x3E,
        0xCC, 0x5E, 0x1C, 0x2A, 0x24, 0xDE, 0x46, 0x99,
        0xF6, 0x87, 0x5E, 0xA2, 0xFA, 0x2D, 0xD3, 0xE3,
        0x57, 0xBC, 0x43, 0x91, 0x47, 0x95, 0x20, 0x7E,
        0x02, 0x6B, 0x85, 0x0A, 0x22, 0x37, 0x95, 0x0C,
        0x10, 0x8A, 0x51, 0x2F, 0xC8, 0x8C, 0x22, 0x48,
        0x81, 0x12, 0x60, 0x70, 0x88, 0x18, 0x5F, 0xB0,
        0xE0, 0x9C, 0x2C, 0x41, 0x97, 0xA8, 0x36, 0x87,
        0x26, 0x6B, 0xAB, 0x2E, 0x58, 0x3E, 0x21, 0xC4,
        0x0F, 0x4C, 0xC0, 0x08, 0xFE, 0x65, 0x28, 0x04,
        0xD8, 0x22, 0x3F, 0x15, 0x20, 0xA9, 0x0B, 0x0D,
        0x53, 0x85, 0xC7, 0x55, 0x3C, 0xC7, 0x67, 0xC5,
        0x8D, 0x12, 0x0C, 0xCD, 0x3E, 0xF5, 0xB5, 0xD1,
        0xA6, 0xCD, 0x7B, 0xC0, 0x0D, 0xFF, 0x13, 0x21,
        0xB2, 0xF2, 0xC4, 0x32, 0xB6, 0x4E, 0xFB, 0x8A,
        0x3F, 0x5D, 0x00, 0x64, 0xB3, 0xF3, 0x42, 0x93,
        0x02, 0x6C, 0x85, 0x1C, 0x2D, 0xED, 0x68, 0xB9,
        0xDF, 0xF4, 0xA2, 0x8F, 0x6A, 0x8D, 0x22, 0x55,
        0x35, 0xE0, 0x47, 0x70, 0x84, 0x43, 0x0C, 0xFF,
        0xDA, 0x0A, 0xC0, 0x55, 0x2F, 0x9A, 0x21, 0x27,
        0x85, 0xB7, 0x49, 0x91, 0x3A, 0x06, 0xFA, 0x22,
        0x74, 0xC0, 0xD1, 0x5B, 0xAD, 0x32, 0x54, 0x58,
        0xD3, 0x23, 0xEF, 0x6B, 0xAE, 0x13, 0xC0, 0x01,
        0x0D, 0x52, 0x5C, 0x1D, 0x52, 0x69, 0x97, 0x3A,
        0xC2, 0x9B, 0xDA, 0x7C, 0x98, 0x37, 0x46, 0x91,
        0x8B, 0xA0, 0xE0, 0x02, 0x58, 0x8E, 0x30, 0x37,
        0x5D, 0x78, 0x32, 0x9E, 0x6B, 0x8B, 0xA8, 0xC4,
        0x46, 0x2A, 0x69, 0x2F, 0xB6, 0x08, 0x38, 0x42,
        0xB8, 0xC8, 0xC9, 0x2C, 0x60, 0xF2, 0x52, 0x72,
        0x6D, 0x14, 0xA0, 0x71, 0xF7, 0xCC, 0x45, 0x25,
        0x58, 0xD5, 0xE7, 0x1A, 0x7B, 0x08, 0x70, 0x62,
        0xEC, 0xB1, 0x38, 0x68, 0x44, 0x58, 0x82, 0x46,
        0x12, 0x64, 0x02, 0xB1, 0xFA, 0x16, 0x37, 0x73,
        0x3C, 0xD5, 0xF6, 0x0C, 0xC8, 0x4B, 0xCB, 0x64,
        0x6A, 0x78, 0x92, 0x61, 0x4D, 0x7C, 0x51, 0xB1,
        0xC7, 0xF1, 0xA2, 0x79, 0x91, 0x32, 0xF1, 0x34,
        0x27, 0xDC, 0x48, 0x21, 0x58, 0xDA, 0x25, 0x44,
        0x70, 0xA5, 0x9E, 0x00, 0xA4, 0xE4, 0x96, 0x86,
        0xFD, 0xC0, 0x77, 0x55, 0x93, 0x67, 0x27, 0x0C,
        0x21, 0x53, 0xF1, 0x10, 0x07, 0x59, 0x2C, 0x9C,
        0x43, 0x10, 0xCF, 0x8A, 0x12, 0xC6, 0xA8, 0x71,
        0x3B, 0xD6, 0xBB, 0x51, 0xF3, 0x12, 0x4F, 0x98,
        0x9B, 0xA0, 0xD5, 0x40, 0x73, 0xCC, 0x24, 0x2E,
        0x09, 0x68, 0x78, 0x0B, 0x87, 0x5A, 0x86, 0x9E,
        0xFB, 0x85, 0x15, 0x86, 0xB9, 0xA8, 0x68, 0xA3,
        0x84, 0xB9, 0xE6, 0x82, 0x1B, 0x20, 0x1B, 0x93,
        0x2C, 0x45, 0x53, 0x69, 0xA7, 0x39, 0xEC, 0x22,
        0x56, 0x9C, 0x97, 0x7C, 0x21, 0x2B, 0x38, 0x18,
        0x71, 0x81, 0x36, 0x56, 0xAF, 0x5B, 0x56, 0x7E,
        0xF8, 0x93, 0xB5, 0x84, 0x62, 0x4C, 0x86, 0x3A,
        0x25, 0x90, 0x00, 0xF1, 0x7B, 0x25, 0x4B, 0x98,
        0xB1, 0x85, 0x09, 0x7C, 0x50, 0xEB, 0xB6, 0x8B,
        0x24, 0x43, 0x42, 0xE0, 0x5D, 0x4D, 0xE5, 0x20,
        0x12, 0x5B, 0x8E, 0x10, 0x33, 0xB1, 0x43, 0x60,
        0x93, 0xAC, 0xE7, 0xCE, 0x8E, 0x71, 0xB4, 0x58,
        0xD5, 0x25, 0x67, 0x33, 0x63, 0x04, 0x5A, 0x3B,
        0x3E, 0xEA, 0x94, 0x55, 0x42, 0x8A, 0x39, 0x87,
        0x05, 0xA4, 0x23, 0x27, 0xAD, 0xB3, 0x77, 0x4B,
        0x70, 0x57, 0xF4, 0x2B, 0x01, 0x7E, 0xC0, 0x73,
        0x9A, 0x98, 0x3F, 0x19, 0xE8, 0x21, 0x4D, 0x09,
        0x19, 0x5F, 0xA2, 0x4D, 0x2D, 0x57, 0x1D, 0xB7,
        0x3C, 0x19, 0xA6, 0xF8, 0x46, 0x0E, 0x50, 0x83,
        0x0D, 0x41, 0x5F, 0x62, 0x7B, 0x88, 0xE9, 0x4A,
        0x7B, 0x15, 0x37, 0x91, 0xA0, 0xC0, 0xC7, 0xE9,
        0x48, 0x4C, 0x74, 0xD5, 0x3C, 0x71, 0x48, 0x89,
        0xF0, 0xE3, 0x21, 0xB6, 0x66, 0x0A, 0x53, 0x2A,
        0x5B, 0xC0, 0xE5, 0x57, 0xFB, 0xCA, 0x35, 0xE2,
        0x9B, 0xC6, 0x11, 0x20, 0x0E, 0xD3, 0xC6, 0x33,
        0x07, 0x7A, 0x4D, 0x87, 0x3C, 0x5C, 0xC6, 0x70,
        0x06, 0xB7, 0x53, 0xBF, 0x6D, 0x6B, 0x7A, 0xF6,
        0xCA, 0x40, 0x2A, 0xB6, 0x18, 0x23, 0x6C, 0x0A,
        0xFF, 0xBC, 0x80, 0x1F, 0x82, 0x22, 0xFB, 0xC3,
        0x6C, 0xE0, 0x98, 0x4E, 0x2B, 0x18, 0xC9, 0x44,
        0xBB, 0xCB, 0xEF, 0x03, 0xB1, 0xE1, 0x36, 0x1C,
        0x1F, 0x44, 0xB0, 0xD7, 0x34, 0xAF, 0xB1, 0x56,
        0x6C, 0xFF, 0x87, 0x44, 0xDA, 0x8B, 0x99, 0x43,
        0xD6, 0xB4, 0x5A, 0x3C, 0x09, 0x03, 0x07, 0x02,
        0xCA, 0x20, 0x1F, 0xFE, 0x20, 0xCB, 0x7E, 0xC5,
        0xB0, 0xD4, 0x14, 0x9E, 0xE2, 0xC2, 0x8E, 0x8B,
        0x23, 0x37, 0x4F, 0x47, 0x1B, 0x57, 0x15, 0x0D,
        0x0E, 0xC9, 0x33, 0x62, 0x61, 0xA2, 0xD5, 0xCB,
        0x84, 0xA3, 0xAC, 0xAC, 0xC4, 0x28, 0x94, 0x73,
        0xA4, 0xC0, 0xAB, 0xC6, 0x17, 0xC9, 0xAB, 0xC1,
        0x78, 0x73, 0x44, 0x34, 0xC8, 0x2E, 0x16, 0x85,
        0x58, 0x8A, 0x5C, 0x2E, 0xA2, 0x67, 0x8F, 0x6B,
        0x3C, 0x22, 0x28, 0x73, 0x31, 0x30, 0xC4, 0x66,
        0xE5, 0xB8, 0x6E, 0xF4, 0x91, 0x15, 0x3E, 0x48,
        0x66, 0x22, 0x47, 0xB8, 0x75, 0xD2, 0x01, 0x02,
        0x0B, 0x56, 0x6B, 0x81, 0xB6, 0x4D, 0x83, 0x9A,
        0xB4, 0x63, 0x3B, 0xAA, 0x8A, 0xCE, 0x20, 0x2B,
        0xAA, 0xB4, 0x49, 0x62, 0x97, 0xF9, 0x80, 0x7A,
        0xDB, 0xBB, 0x1E, 0x33, 0x2C, 0x6F, 0x80, 0x22,
        0xB2, 0xA1, 0x8C, 0xFD, 0xD4, 0xA8, 0x25, 0x30,
        0xB6, 0xD3, 0xF0, 0x07, 0xC3, 0x35, 0x38, 0x98,
        0xD9, 0x66, 0xCC, 0x2C, 0x21, 0xCB, 0x42, 0x44,
        0xBD, 0x00, 0x44, 0x3F, 0x20, 0x98, 0x70, 0xAC,
        0xC4, 0x2B, 0xC3, 0x30, 0x68, 0xC7, 0x24, 0xEC,
        0x17, 0x22, 0x36, 0x19, 0xC1, 0x09, 0x3C, 0xCA,
        0x6A, 0xEB, 0x29, 0x50, 0x06, 0x64, 0xD1, 0x22,
        0x50, 0x36, 0xB4, 0xB8, 0x10, 0x91, 0x90, 0x69,
        0x69, 0x48, 0x1F, 0x1C, 0x72, 0x3C, 0x14, 0x0B,
        0x9D, 0x6C, 0x16, 0x8F, 0x5B, 0x64, 0xBE, 0xA6,
        0x9C, 0x5F, 0xD6, 0x38, 0x5D, 0xF7, 0x36, 0x4B,
        0x87, 0x23, 0xBC, 0xC8, 0x5E, 0x03, 0x8C, 0x7E,
        0x46, 0x4A, 0x90, 0x0D, 0x68, 0xA2, 0x12, 0x78,
        0x18, 0x99, 0x42, 0x17, 0xAE, 0xC8, 0xBD, 0xB3,
        0x9A, 0x97, 0x0A, 0x99, 0x63, 0xDE, 0x93, 0x68,
        0x8E, 0x2A, 0xC8, 0x2A, 0xBC, 0xC2, 0x2F, 0xB9,
        0x27, 0x7B, 0xA2, 0x20, 0x09, 0xE8, 0x78, 0x38,
        0x1A, 0x38, 0x16, 0x39, 0x01, 0xC7, 0xD4, 0xC8,
        0x50, 0x19, 0x53, 0x8D, 0x35, 0xCA, 0xAE, 0x9C,
        0x41, 0xAF, 0x8C, 0x92, 0x9E, 0xE2, 0x0B, 0xB0,
        0x8C, 0xA6, 0x19, 0xE7, 0x2C, 0x2F, 0x22, 0x62,
        0xC1, 0xC9, 0x93, 0x85, 0x72, 0x55, 0x1A, 0xC0,
        0x2D, 0xC9, 0x26, 0x8F, 0xBC, 0xC3, 0x5D, 0x79,
        0x01, 0x1C, 0x3C, 0x09, 0x0A, 0xD4, 0x0A, 0x4F,
        0x11, 0x1C, 0x9B, 0xE5, 0x5C, 0x42, 0x7E, 0xB7,
        0x96, 0xC1, 0x93, 0x2D, 0x86, 0x73, 0x57, 0x9A,
        0xF1, 0xB4, 0xC6, 0x38, 0xB0, 0x94, 0x44, 0x89,
        0x01, 0x2A, 0x25, 0x59, 0xA3, 0xB0, 0x24, 0x81,
        0xB0, 0x1A, 0xC3, 0x0B, 0xA8, 0x96, 0x0F, 0x80,
        0xC0, 0xC2, 0xB3, 0x94, 0x7D, 0x36, 0xA1, 0x2C,
        0x08, 0x04, 0x98, 0xBE, 0xE4, 0x48, 0x71, 0x6C,
        0x97, 0x34, 0x16, 0xC8, 0x24, 0x28, 0x04, 0xA3,
        0xDA, 0x09, 0x9E, 0xE1, 0x37, 0xB0, 0xBA, 0x90,
        0xFE, 0x4A, 0x5C, 0x6A, 0x89, 0x20, 0x02, 0x76,
        0xA0, 0xCF, 0xB6, 0x43, 0xEC, 0x2C, 0x56, 0xA2,
        0xD7, 0x08, 0xD7, 0xB4, 0x37, 0x3E, 0x44, 0xC1,
        0x50, 0x2A, 0x76, 0x3A, 0x60, 0x05, 0x86, 0xE6,
        0xCD, 0xA6, 0x27, 0x38, 0x97, 0xD4, 0x44, 0x48,
        0x28, 0x7D, 0xC2, 0xE6, 0x02, 0xDC, 0x39, 0x20,
        0x0B, 0xF6, 0x16, 0x62, 0x36, 0x55, 0x9F, 0xD1,
        0x2A, 0x60, 0x89, 0x2A, 0xEB, 0x15, 0x3D, 0xD6,
        0x51, 0xBB, 0x46, 0x99, 0x10, 0xB4, 0xB3, 0x46,
        0x69, 0xF9, 0x1D, 0xA8, 0x65, 0x4D, 0x1E, 0xB7,
        0x2E, 0xB6, 0xE0, 0x28, 0x00, 0xB3, 0xB0, 0xA7,
        0xD0, 0xA4, 0x8C, 0x83, 0x68, 0x54, 0xD3, 0xA8,
        0x3E, 0x65, 0x56, 0x9C, 0xB7, 0x23, 0x0B, 0xB4,
        0x4F, 0x3F, 0x14, 0x3A, 0x6D, 0xEC, 0x5F, 0x2C,
        0x39, 0xAB, 0x90, 0xF2, 0x74, 0xF2, 0x08, 0x8B,
        0xD3, 0xD6, 0xA6, 0xFC, 0xA0, 0x07, 0x02, 0x73,
        0xBE, 0xDC, 0x84, 0x77, 0x7F, 0xB5, 0x2E, 0x3C,
        0x55, 0x8B, 0x0A, 0xE0, 0x61, 0x83, 0xD5, 0xA4,
        0x8D, 0x45, 0x2F, 0x68, 0xE1, 0x52, 0x07, 0xF8,
        0x61, 0x62, 0x7A, 0xCA, 0x14, 0x27, 0x96, 0x30,
        0xF8, 0x2E, 0xC3, 0xA0, 0xCA, 0x07, 0x86, 0x33,
        0xB6, 0x00, 0xAF, 0xA7, 0x97, 0x43, 0xA6, 0x00,
        0x21, 0x5B, 0xE5, 0x63, 0x74, 0x58, 0xCE, 0x2C,
        0xE8, 0xAF, 0xF5, 0xA0, 0x8E, 0xB5, 0x01, 0x7B,
        0x2C, 0x76, 0x65, 0x77, 0x47, 0x9F, 0x8D, 0xC6,
        0xBF, 0x9F, 0x5C, 0xC7, 0x50, 0x89, 0x93, 0x21,
        0x61, 0xB9, 0x6C, 0xEA, 0x40, 0x66, 0x20, 0xAE,
        0xDB, 0x63, 0x04, 0x07, 0xF7, 0x68, 0x7E, 0xBB,
        0xB4, 0x81, 0x4C, 0x79, 0x81, 0x63, 0x7A, 0x48,
        0xA9, 0x0D, 0xE6, 0x80, 0x31, 0xE0, 0x62, 0xA7,
        0xAF, 0x76, 0x12, 0xB4, 0xF5, 0xC7, 0xA6, 0xDA,
        0x86, 0xBD, 0x13, 0x65, 0x29, 0xE6, 0x42, 0x95,
        0xA5, 0x61, 0x3E, 0xA7, 0x3B, 0xD3, 0xD4, 0x44,
        0x8C, 0xB8, 0x1F, 0x24, 0x31, 0x35, 0xC0, 0xA6,
        0x60, 0xBE, 0xB9, 0xC1, 0x7E, 0x65, 0x1D, 0xEF,
        0x46, 0x9A, 0x7D, 0x90, 0xA1, 0x5D, 0x34, 0x81,
        0x09, 0x0B, 0xCB, 0xF2, 0x27, 0x01, 0x23, 0x28,
        0x94, 0x1F, 0xA4, 0x6F, 0x39, 0xC5, 0x00, 0x6A,
        0xD9, 0x3D, 0x45, 0x8A, 0xA6, 0xAD, 0xD6, 0x55,
        0x86, 0x2B, 0x41, 0x8C, 0x30, 0x94, 0xF5, 0x51,
        0x46, 0x0D, 0xF2, 0x15, 0x3A, 0x58, 0x10, 0xA7,
        0xDA, 0x74, 0xF0, 0x61, 0x4C, 0x25, 0x88, 0xBE,
        0x49, 0xDC, 0x6F, 0x5E, 0x88, 0x15, 0x46, 0x42,
        0xBD, 0x1D, 0x37, 0x62, 0x56, 0x33, 0x26, 0x43,
        0x35, 0x07, 0x15, 0x6A, 0x57, 0xC5, 0x76, 0x94,
        0xBD, 0xD2, 0x6E, 0x7A, 0x24, 0x6F, 0xEB, 0x72,
        0x3A, 0xED, 0x67, 0xB0, 0x48, 0x87, 0xC8, 0xE4,
        0x76, 0xB4, 0x8C, 0xAB, 0x59, 0xE5, 0x36, 0x2F,
        0x26, 0xA9, 0xEF, 0x50, 0xC2, 0xBC, 0x80, 0xBA,
        0x14, 0x62, 0x26, 0x21, 0x6F, 0xE6, 0x29, 0x68,
        0xA6, 0x0D, 0x04, 0xE8, 0xC1, 0x70, 0xD7, 0x41,
        0xC7, 0xA2, 0xB0, 0xE1, 0xAB, 0xDA, 0xC9, 0x68,
        0xE2, 0x90, 0x20, 0x83, 0x9D, 0x05, 0x2F, 0xA3,
        0x72, 0x58, 0x56, 0x27, 0xF8, 0xB5, 0x9E, 0xE3,
        0x12, 0xAE, 0x41, 0x4C, 0x97, 0x9D, 0x82, 0x5F,
        0x06, 0xA6, 0x92, 0x9A, 0x79, 0x62, 0x57, 0x18,
        0xA8, 0x57, 0x68, 0xF3, 0x48, 0x6B, 0xD3, 0x2A,
        0x01, 0xBF, 0x9A, 0x8F, 0x21, 0xEA, 0x93, 0x8E,
        0x64, 0x8E, 0xAE, 0x4E, 0x54, 0x48, 0xC3, 0x4C,
        0x3E, 0xB8, 0x88, 0x20, 0xB1, 0x59, 0xEE, 0xDD
    };
#endif
#ifndef WOLFSSL_NO_KYBER1024
    static const byte seed_1024[KYBER_MAKEKEY_RAND_SZ] = {
        /* d */
        0x49, 0xAC, 0x8B, 0x99, 0xBB, 0x1E, 0x6A, 0x8E,
        0xA8, 0x18, 0x26, 0x1F, 0x8B, 0xE6, 0x8B, 0xDE,
        0xAA, 0x52, 0x89, 0x7E, 0x7E, 0xC6, 0xC4, 0x0B,
        0x53, 0x0B, 0xC7, 0x60, 0xAB, 0x77, 0xDC, 0xE3,
        /* z */
        0x99, 0xE3, 0x24, 0x68, 0x84, 0x18, 0x1F, 0x8E,
        0x1D, 0xD4, 0x4E, 0x0C, 0x76, 0x29, 0x09, 0x33,
        0x30, 0x22, 0x1F, 0xD6, 0x7D, 0x9B, 0x7D, 0x6E,
        0x15, 0x10, 0xB2, 0xDB, 0xAD, 0x87, 0x62, 0xF7
    };
    static const byte ek_1024[KYBER1024_PUBLIC_KEY_SIZE] = {
        0xA0, 0x41, 0x84, 0xD4, 0xBC, 0x7B, 0x53, 0x2A,
        0x0F, 0x70, 0xA5, 0x4D, 0x77, 0x57, 0xCD, 0xE6,
        0x17, 0x5A, 0x68, 0x43, 0xB8, 0x61, 0xCB, 0x2B,
        0xC4, 0x83, 0x0C, 0x00, 0x12, 0x55, 0x4C, 0xFC,
        0x5D, 0x2C, 0x8A, 0x20, 0x27, 0xAA, 0x3C, 0xD9,
        0x67, 0x13, 0x0E, 0x9B, 0x96, 0x24, 0x1B, 0x11,
        0xC4, 0x32, 0x0C, 0x76, 0x49, 0xCC, 0x23, 0xA7,
        0x1B, 0xAF, 0xE6, 0x91, 0xAF, 0xC0, 0x8E, 0x68,
        0x0B, 0xCE, 0xF4, 0x29, 0x07, 0x00, 0x07, 0x18,
        0xE4, 0xEA, 0xCE, 0x8D, 0xA2, 0x82, 0x14, 0x19,
        0x7B, 0xE1, 0xC2, 0x69, 0xDA, 0x9C, 0xB5, 0x41,
        0xE1, 0xA3, 0xCE, 0x97, 0xCF, 0xAD, 0xF9, 0xC6,
        0x05, 0x87, 0x80, 0xFE, 0x67, 0x93, 0xDB, 0xFA,
        0x82, 0x18, 0xA2, 0x76, 0x0B, 0x80, 0x2B, 0x8D,
        0xA2, 0xAA, 0x27, 0x1A, 0x38, 0x77, 0x25, 0x23,
        0xA7, 0x67, 0x36, 0xA7, 0xA3, 0x1B, 0x9D, 0x30,
        0x37, 0xAD, 0x21, 0xCE, 0xBB, 0x11, 0xA4, 0x72,
        0xB8, 0x79, 0x2E, 0xB1, 0x75, 0x58, 0xB9, 0x40,
        0xE7, 0x08, 0x83, 0xF2, 0x64, 0x59, 0x2C, 0x68,
        0x9B, 0x24, 0x0B, 0xB4, 0x3D, 0x54, 0x08, 0xBF,
        0x44, 0x64, 0x32, 0xF4, 0x12, 0xF4, 0xB9, 0xA5,
        0xF6, 0x86, 0x5C, 0xC2, 0x52, 0xA4, 0x3C, 0xF4,
        0x0A, 0x32, 0x03, 0x91, 0x55, 0x55, 0x91, 0xD6,
        0x75, 0x61, 0xFD, 0xD0, 0x53, 0x53, 0xAB, 0x6B,
        0x01, 0x9B, 0x3A, 0x08, 0xA7, 0x33, 0x53, 0xD5,
        0x1B, 0x61, 0x13, 0xAB, 0x2F, 0xA5, 0x1D, 0x97,
        0x56, 0x48, 0xEE, 0x25, 0x4A, 0xF8, 0x9A, 0x23,
        0x05, 0x04, 0xA2, 0x36, 0xA4, 0x65, 0x82, 0x57,
        0x74, 0x0B, 0xDC, 0xBB, 0xE1, 0x70, 0x8A, 0xB0,
        0x22, 0xC3, 0xC5, 0x88, 0xA4, 0x10, 0xDB, 0x3B,
        0x9C, 0x30, 0x8A, 0x06, 0x27, 0x5B, 0xDF, 0x5B,
        0x48, 0x59, 0xD3, 0xA2, 0x61, 0x7A, 0x29, 0x5E,
        0x1A, 0x22, 0xF9, 0x01, 0x98, 0xBA, 0xD0, 0x16,
        0x6F, 0x4A, 0x94, 0x34, 0x17, 0xC5, 0xB8, 0x31,
        0x73, 0x6C, 0xB2, 0xC8, 0x58, 0x0A, 0xBF, 0xDE,
        0x57, 0x14, 0xB5, 0x86, 0xAB, 0xEE, 0xC0, 0xA1,
        0x75, 0xA0, 0x8B, 0xC7, 0x10, 0xC7, 0xA2, 0x89,
        0x5D, 0xE9, 0x3A, 0xC4, 0x38, 0x06, 0x1B, 0xF7,
        0x76, 0x5D, 0x0D, 0x21, 0xCD, 0x41, 0x81, 0x67,
        0xCA, 0xF8, 0x9D, 0x1E, 0xFC, 0x34, 0x48, 0xBC,
        0xBB, 0x96, 0xD6, 0x9B, 0x3E, 0x01, 0x0C, 0x82,
        0xD1, 0x5C, 0xAB, 0x6C, 0xAC, 0xC6, 0x79, 0x9D,
        0x36, 0x39, 0x66, 0x9A, 0x5B, 0x21, 0xA6, 0x33,
        0xC8, 0x65, 0xF8, 0x59, 0x3B, 0x5B, 0x7B, 0xC8,
        0x00, 0x26, 0x2B, 0xB8, 0x37, 0xA9, 0x24, 0xA6,
        0xC5, 0x44, 0x0E, 0x4F, 0xC7, 0x3B, 0x41, 0xB2,
        0x30, 0x92, 0xC3, 0x91, 0x2F, 0x4C, 0x6B, 0xEB,
        0xB4, 0xC7, 0xB4, 0xC6, 0x29, 0x08, 0xB0, 0x37,
        0x75, 0x66, 0x6C, 0x22, 0x22, 0x0D, 0xF9, 0xC8,
        0x88, 0x23, 0xE3, 0x44, 0xC7, 0x30, 0x83, 0x32,
        0x34, 0x5C, 0x8B, 0x79, 0x5D, 0x34, 0xE8, 0xC0,
        0x51, 0xF2, 0x1F, 0x5A, 0x21, 0xC2, 0x14, 0xB6,
        0x98, 0x41, 0x35, 0x87, 0x09, 0xB1, 0xC3, 0x05,
        0xB3, 0x2C, 0xC2, 0xC3, 0x80, 0x6A, 0xE9, 0xCC,
        0xD3, 0x81, 0x9F, 0xFF, 0x45, 0x07, 0xFE, 0x52,
        0x0F, 0xBF, 0xC2, 0x71, 0x99, 0xBC, 0x23, 0xBE,
        0x6B, 0x9B, 0x2D, 0x2A, 0xC1, 0x71, 0x75, 0x79,
        0xAC, 0x76, 0x92, 0x79, 0xE2, 0xA7, 0xAA, 0xC6,
        0x8A, 0x37, 0x1A, 0x47, 0xBA, 0x3A, 0x7D, 0xBE,
        0x01, 0x6F, 0x14, 0xE1, 0xA7, 0x27, 0x33, 0x36,
        0x63, 0xC4, 0xA5, 0xCD, 0x1A, 0x0F, 0x88, 0x36,
        0xCF, 0x7B, 0x5C, 0x49, 0xAC, 0x51, 0x48, 0x5C,
        0xA6, 0x03, 0x45, 0xC9, 0x90, 0xE0, 0x68, 0x88,
        0x72, 0x00, 0x03, 0x73, 0x13, 0x22, 0xC5, 0xB8,
        0xCD, 0x5E, 0x69, 0x07, 0xFD, 0xA1, 0x15, 0x7F,
        0x46, 0x8F, 0xD3, 0xFC, 0x20, 0xFA, 0x81, 0x75,
        0xEE, 0xC9, 0x5C, 0x29, 0x1A, 0x26, 0x2B, 0xA8,
        0xC5, 0xBE, 0x99, 0x08, 0x72, 0x41, 0x89, 0x30,
        0x85, 0x23, 0x39, 0xD8, 0x8A, 0x19, 0xB3, 0x7F,
        0xEF, 0xA3, 0xCF, 0xE8, 0x21, 0x75, 0xC2, 0x24,
        0x40, 0x7C, 0xA4, 0x14, 0xBA, 0xEB, 0x37, 0x92,
        0x3B, 0x4D, 0x2D, 0x83, 0x13, 0x4A, 0xE1, 0x54,
        0xE4, 0x90, 0xA9, 0xB4, 0x5A, 0x05, 0x63, 0xB0,
        0x6C, 0x95, 0x3C, 0x33, 0x01, 0x45, 0x0A, 0x21,
        0x76, 0xA0, 0x7C, 0x61, 0x4A, 0x74, 0xE3, 0x47,
        0x8E, 0x48, 0x50, 0x9F, 0x9A, 0x60, 0xAE, 0x94,
        0x5A, 0x8E, 0xBC, 0x78, 0x15, 0x12, 0x1D, 0x90,
        0xA3, 0xB0, 0xE0, 0x70, 0x91, 0xA0, 0x96, 0xCF,
        0x02, 0xC5, 0x7B, 0x25, 0xBC, 0xA5, 0x81, 0x26,
        0xAD, 0x0C, 0x62, 0x9C, 0xE1, 0x66, 0xA7, 0xED,
        0xB4, 0xB3, 0x32, 0x21, 0xA0, 0xD3, 0xF7, 0x2B,
        0x85, 0xD5, 0x62, 0xEC, 0x69, 0x8B, 0x7D, 0x0A,
        0x91, 0x3D, 0x73, 0x80, 0x6F, 0x1C, 0x5C, 0x87,
        0xB3, 0x8E, 0xC0, 0x03, 0xCB, 0x30, 0x3A, 0x3D,
        0xC5, 0x1B, 0x4B, 0x35, 0x35, 0x6A, 0x67, 0x82,
        0x6D, 0x6E, 0xDA, 0xA8, 0xFE, 0xB9, 0x3B, 0x98,
        0x49, 0x3B, 0x2D, 0x1C, 0x11, 0xB6, 0x76, 0xA6,
        0xAD, 0x95, 0x06, 0xA1, 0xAA, 0xAE, 0x13, 0xA8,
        0x24, 0xC7, 0xC0, 0x8D, 0x1C, 0x6C, 0x2C, 0x4D,
        0xBA, 0x96, 0x42, 0xC7, 0x6E, 0xA7, 0xF6, 0xC8,
        0x26, 0x4B, 0x64, 0xA2, 0x3C, 0xCC, 0xA9, 0xA7,
        0x46, 0x35, 0xFC, 0xBF, 0x03, 0xE0, 0x0F, 0x1B,
        0x57, 0x22, 0xB2, 0x14, 0x37, 0x67, 0x90, 0x79,
        0x3B, 0x2C, 0x4F, 0x0A, 0x13, 0xB5, 0xC4, 0x07,
        0x60, 0xB4, 0x21, 0x8E, 0x1D, 0x25, 0x94, 0xDC,
        0xB3, 0x0A, 0x70, 0xD9, 0xC1, 0x78, 0x2A, 0x5D,
        0xD3, 0x05, 0x76, 0xFA, 0x41, 0x44, 0xBF, 0xC8,
        0x41, 0x6E, 0xDA, 0x81, 0x18, 0xFC, 0x64, 0x72,
        0xF5, 0x6A, 0x97, 0x95, 0x86, 0xF3, 0x3B, 0xB0,
        0x70, 0xFB, 0x0F, 0x1B, 0x0B, 0x10, 0xBC, 0x48,
        0x97, 0xEB, 0xE0, 0x1B, 0xCA, 0x38, 0x93, 0xD4,
        0xE1, 0x6A, 0xDB, 0x25, 0x09, 0x3A, 0x74, 0x17,
        0xD0, 0x70, 0x8C, 0x83, 0xA2, 0x63, 0x22, 0xE2,
        0x2E, 0x63, 0x30, 0x09, 0x1E, 0x30, 0x15, 0x2B,
        0xF8, 0x23, 0x59, 0x7C, 0x04, 0xCC, 0xF4, 0xCF,
        0xC7, 0x33, 0x15, 0x78, 0xF4, 0x3A, 0x27, 0x26,
        0xCC, 0xB4, 0x28, 0x28, 0x9A, 0x90, 0xC8, 0x63,
        0x25, 0x9D, 0xD1, 0x80, 0xC5, 0xFF, 0x14, 0x2B,
        0xEF, 0x41, 0xC7, 0x71, 0x70, 0x94, 0xBE, 0x07,
        0x85, 0x6D, 0xA2, 0xB1, 0x40, 0xFA, 0x67, 0x71,
        0x09, 0x67, 0x35, 0x6A, 0xA4, 0x7D, 0xFB, 0xC8,
        0xD2, 0x55, 0xB4, 0x72, 0x2A, 0xB8, 0x6D, 0x43,
        0x9B, 0x7E, 0x0A, 0x60, 0x90, 0x25, 0x1D, 0x2D,
        0x4C, 0x1E, 0xD5, 0xF2, 0x0B, 0xBE, 0x68, 0x07,
        0xBF, 0x65, 0xA9, 0x0B, 0x7C, 0xB2, 0xEC, 0x01,
        0x02, 0xAF, 0x02, 0x80, 0x9D, 0xC9, 0xAC, 0x7D,
        0x0A, 0x3A, 0xBC, 0x69, 0xC1, 0x83, 0x65, 0xBC,
        0xFF, 0x59, 0x18, 0x5F, 0x33, 0x99, 0x68, 0x87,
        0x74, 0x61, 0x85, 0x90, 0x6C, 0x01, 0x91, 0xAE,
        0xD4, 0x40, 0x7E, 0x13, 0x94, 0x46, 0x45, 0x9B,
        0xE2, 0x9C, 0x68, 0x22, 0x71, 0x76, 0x44, 0x35,
        0x3D, 0x24, 0xAB, 0x63, 0x39, 0x15, 0x6A, 0x9C,
        0x42, 0x49, 0x09, 0xF0, 0xA9, 0x02, 0x5B, 0xB7,
        0x47, 0x20, 0x77, 0x9B, 0xE4, 0x3F, 0x16, 0xD8,
        0x1C, 0x8C, 0xC6, 0x66, 0xE9, 0x97, 0x10, 0xD8,
        0xC6, 0x8B, 0xB5, 0xCC, 0x4E, 0x12, 0xF3, 0x14,
        0xE9, 0x25, 0xA5, 0x51, 0xF0, 0x9C, 0xC5, 0x90,
        0x03, 0xA1, 0xF8, 0x81, 0x03, 0xC2, 0x54, 0xBB,
        0x97, 0x8D, 0x75, 0xF3, 0x94, 0xD3, 0x54, 0x0E,
        0x31, 0xE7, 0x71, 0xCD, 0xA3, 0x6E, 0x39, 0xEC,
        0x54, 0xA6, 0x2B, 0x58, 0x32, 0x66, 0x4D, 0x82,
        0x1A, 0x72, 0xF1, 0xE6, 0xAF, 0xBB, 0xA2, 0x7F,
        0x84, 0x29, 0x5B, 0x26, 0x94, 0xC4, 0x98, 0x49,
        0x8E, 0x81, 0x2B, 0xC8, 0xE9, 0x37, 0x8F, 0xE5,
        0x41, 0xCE, 0xC5, 0x89, 0x1B, 0x25, 0x06, 0x29,
        0x01, 0xCB, 0x72, 0x12, 0xE3, 0xCD, 0xC4, 0x61,
        0x79, 0xEC, 0x5B, 0xCE, 0xC1, 0x0B, 0xC0, 0xB9,
        0x31, 0x1D, 0xE0, 0x50, 0x74, 0x29, 0x06, 0x87,
        0xFD, 0x6A, 0x53, 0x92, 0x67, 0x16, 0x54, 0x28,
        0x4C, 0xD9, 0xC8, 0xCC, 0x3E, 0xBA, 0x80, 0xEB,
        0x3B, 0x66, 0x2E, 0xB5, 0x3E, 0xB7, 0x51, 0x16,
        0x70, 0x4A, 0x1F, 0xEB, 0x5C, 0x2D, 0x05, 0x63,
        0x38, 0x53, 0x28, 0x68, 0xDD, 0xF2, 0x4E, 0xB8,
        0x99, 0x2A, 0xB8, 0x56, 0x5D, 0x9E, 0x49, 0x0C,
        0xAD, 0xF1, 0x48, 0x04, 0x36, 0x0D, 0xAA, 0x90,
        0x71, 0x8E, 0xAB, 0x61, 0x6B, 0xAB, 0x07, 0x65,
        0xD3, 0x39, 0x87, 0xB4, 0x7E, 0xFB, 0x65, 0x99,
        0xC5, 0x56, 0x32, 0x35, 0xE6, 0x1E, 0x4B, 0xE6,
        0x70, 0xE9, 0x79, 0x55, 0xAB, 0x29, 0x2D, 0x97,
        0x32, 0xCB, 0x89, 0x30, 0x94, 0x8A, 0xC8, 0x2D,
        0xF2, 0x30, 0xAC, 0x72, 0x29, 0x7A, 0x23, 0x67,
        0x9D, 0x6B, 0x94, 0xC1, 0x7F, 0x13, 0x59, 0x48,
        0x32, 0x54, 0xFE, 0xDC, 0x2F, 0x05, 0x81, 0x9F,
        0x0D, 0x06, 0x9A, 0x44, 0x3B, 0x78, 0xE3, 0xFC,
        0x6C, 0x3E, 0xF4, 0x71, 0x4B, 0x05, 0xA3, 0xFC,
        0xA8, 0x1C, 0xBB, 0xA6, 0x02, 0x42, 0xA7, 0x06,
        0x0C, 0xD8, 0x85, 0xD8, 0xF3, 0x99, 0x81, 0xBB,
        0x18, 0x09, 0x2B, 0x23, 0xDA, 0xA5, 0x9F, 0xD9,
        0x57, 0x83, 0x88, 0x68, 0x8A, 0x09, 0xBB, 0xA0,
        0x79, 0xBC, 0x80, 0x9A, 0x54, 0x84, 0x3A, 0x60,
        0x38, 0x5E, 0x23, 0x10, 0xBB, 0xCB, 0xCC, 0x02,
        0x13, 0xCE, 0x3D, 0xFA, 0xAB, 0x33, 0xB4, 0x7F,
        0x9D, 0x63, 0x05, 0xBC, 0x95, 0xC6, 0x10, 0x78,
        0x13, 0xC5, 0x85, 0xC4, 0xB6, 0x57, 0xBF, 0x30,
        0x54, 0x28, 0x33, 0xB1, 0x49, 0x49, 0xF5, 0x73,
        0xC0, 0x61, 0x2A, 0xD5, 0x24, 0xBA, 0xAE, 0x69,
        0x59, 0x0C, 0x12, 0x77, 0xB8, 0x6C, 0x28, 0x65,
        0x71, 0xBF, 0x66, 0xB3, 0xCF, 0xF4, 0x6A, 0x38,
        0x58, 0xC0, 0x99, 0x06, 0xA7, 0x94, 0xDF, 0x4A,
        0x06, 0xE9, 0xD4, 0xB0, 0xA2, 0xE4, 0x3F, 0x10,
        0xF7, 0x2A, 0x6C, 0x6C, 0x47, 0xE5, 0x64, 0x6E,
        0x2C, 0x79, 0x9B, 0x71, 0xC3, 0x3E, 0xD2, 0xF0,
        0x1E, 0xEB, 0x45, 0x93, 0x8E, 0xB7, 0xA4, 0xE2,
        0xE2, 0x90, 0x8C, 0x53, 0x55, 0x8A, 0x54, 0x0D,
        0x35, 0x03, 0x69, 0xFA, 0x18, 0x9C, 0x61, 0x69,
        0x43, 0xF7, 0x98, 0x1D, 0x76, 0x18, 0xCF, 0x02,
        0xA5, 0xB0, 0xA2, 0xBC, 0xC4, 0x22, 0xE8, 0x57,
        0xD1, 0xA4, 0x78, 0x71, 0x25, 0x3D, 0x08, 0x29,
        0x3C, 0x1C, 0x17, 0x9B, 0xCD, 0xC0, 0x43, 0x70,
        0x69, 0x10, 0x74, 0x18, 0x20, 0x5F, 0xDB, 0x98,
        0x56, 0x62, 0x3B, 0x8C, 0xA6, 0xB6, 0x94, 0xC9,
        0x6C, 0x08, 0x4B, 0x17, 0xF1, 0x3B, 0xB6, 0xDF,
        0x12, 0xB2, 0xCF, 0xBB, 0xC2, 0xB0, 0xE0, 0xC3,
        0x4B, 0x00, 0xD0, 0xFC, 0xD0, 0xAE, 0xCF, 0xB2,
        0x79, 0x24, 0xF6, 0x98, 0x4E, 0x74, 0x7B, 0xE2,
        0xA0, 0x9D, 0x83, 0xA8, 0x66, 0x45, 0x90, 0xA8,
        0x07, 0x73, 0x31, 0x49, 0x1A, 0x4F, 0x7D, 0x72,
        0x08, 0x43, 0xF2, 0x3E, 0x65, 0x2C, 0x6F, 0xA8,
        0x40, 0x30, 0x8D, 0xB4, 0x02, 0x03, 0x37, 0xAA,
        0xD3, 0x79, 0x67, 0x03, 0x4A, 0x9F, 0xB5, 0x23,
        0xB6, 0x7C, 0xA7, 0x03, 0x30, 0xF0, 0x2D, 0x9E,
        0xA2, 0x0C, 0x1E, 0x84, 0xCB, 0x8E, 0x57, 0x57,
        0xC9, 0xE1, 0x89, 0x6B, 0x60, 0x58, 0x14, 0x41,
        0xED, 0x61, 0x8A, 0xA5, 0xB2, 0x6D, 0xA5, 0x6C,
        0x0A, 0x5A, 0x73, 0xC4, 0xDC, 0xFD, 0x75, 0x5E,
        0x61, 0x0B, 0x4F, 0xC8, 0x1F, 0xF8, 0x4E, 0x21
    };
    static const byte dk_1024[KYBER1024_PRIVATE_KEY_SIZE] = {
        0x8C, 0x8B, 0x37, 0x22, 0xA8, 0x2E, 0x55, 0x05,
        0x65, 0x52, 0x16, 0x11, 0xEB, 0xBC, 0x63, 0x07,
        0x99, 0x44, 0xC9, 0xB1, 0xAB, 0xB3, 0xB0, 0x02,
        0x0F, 0xF1, 0x2F, 0x63, 0x18, 0x91, 0xA9, 0xC4,
        0x68, 0xD3, 0xA6, 0x7B, 0xF6, 0x27, 0x12, 0x80,
        0xDA, 0x58, 0xD0, 0x3C, 0xB0, 0x42, 0xB3, 0xA4,
        0x61, 0x44, 0x16, 0x37, 0xF9, 0x29, 0xC2, 0x73,
        0x46, 0x9A, 0xD1, 0x53, 0x11, 0xE9, 0x10, 0xDE,
        0x18, 0xCB, 0x95, 0x37, 0xBA, 0x1B, 0xE4, 0x2E,
        0x98, 0xBB, 0x59, 0xE4, 0x98, 0xA1, 0x3F, 0xD4,
        0x40, 0xD0, 0xE6, 0x9E, 0xE8, 0x32, 0xB4, 0x5C,
        0xD9, 0x5C, 0x38, 0x21, 0x77, 0xD6, 0x70, 0x96,
        0xA1, 0x8C, 0x07, 0xF1, 0x78, 0x16, 0x63, 0x65,
        0x1B, 0xDC, 0xAC, 0x90, 0xDE, 0xDA, 0x3D, 0xDD,
        0x14, 0x34, 0x85, 0x86, 0x41, 0x81, 0xC9, 0x1F,
        0xA2, 0x08, 0x0F, 0x6D, 0xAB, 0x3F, 0x86, 0x20,
        0x4C, 0xEB, 0x64, 0xA7, 0xB4, 0x44, 0x68, 0x95,
        0xC0, 0x39, 0x87, 0xA0, 0x31, 0xCB, 0x4B, 0x6D,
        0x9E, 0x04, 0x62, 0xFD, 0xA8, 0x29, 0x17, 0x2B,
        0x6C, 0x01, 0x2C, 0x63, 0x8B, 0x29, 0xB5, 0xCD,
        0x75, 0xA2, 0xC9, 0x30, 0xA5, 0x59, 0x6A, 0x31,
        0x81, 0xC3, 0x3A, 0x22, 0xD5, 0x74, 0xD3, 0x02,
        0x61, 0x19, 0x6B, 0xC3, 0x50, 0x73, 0x8D, 0x4F,
        0xD9, 0x18, 0x3A, 0x76, 0x33, 0x36, 0x24, 0x3A,
        0xCE, 0xD9, 0x9B, 0x32, 0x21, 0xC7, 0x1D, 0x88,
        0x66, 0x89, 0x5C, 0x4E, 0x52, 0xC1, 0x19, 0xBF,
        0x32, 0x80, 0xDA, 0xF8, 0x0A, 0x95, 0xE1, 0x52,
        0x09, 0xA7, 0x95, 0xC4, 0x43, 0x5F, 0xBB, 0x35,
        0x70, 0xFD, 0xB8, 0xAA, 0x9B, 0xF9, 0xAE, 0xFD,
        0x43, 0xB0, 0x94, 0xB7, 0x81, 0xD5, 0xA8, 0x11,
        0x36, 0xDA, 0xB8, 0x8B, 0x87, 0x99, 0x69, 0x65,
        0x56, 0xFE, 0xC6, 0xAE, 0x14, 0xB0, 0xBB, 0x8B,
        0xE4, 0x69, 0x5E, 0x9A, 0x12, 0x4C, 0x2A, 0xB8,
        0xFF, 0x4A, 0xB1, 0x22, 0x9B, 0x8A, 0xAA, 0x8C,
        0x6F, 0x41, 0xA6, 0x0C, 0x34, 0xC7, 0xB5, 0x61,
        0x82, 0xC5, 0x5C, 0x2C, 0x68, 0x5E, 0x73, 0x7C,
        0x6C, 0xA0, 0x0A, 0x23, 0xFB, 0x8A, 0x68, 0xC1,
        0xCD, 0x61, 0xF3, 0x0D, 0x39, 0x93, 0xA1, 0x65,
        0x3C, 0x16, 0x75, 0xAC, 0x5F, 0x09, 0x01, 0xA7,
        0x16, 0x0A, 0x73, 0x96, 0x64, 0x08, 0xB8, 0x87,
        0x6B, 0x71, 0x53, 0x96, 0xCF, 0xA4, 0x90, 0x3F,
        0xC6, 0x9D, 0x60, 0x49, 0x1F, 0x81, 0x46, 0x80,
        0x8C, 0x97, 0xCD, 0x5C, 0x53, 0x3E, 0x71, 0x01,
        0x79, 0x09, 0xE9, 0x7B, 0x83, 0x5B, 0x86, 0xFF,
        0x84, 0x7B, 0x42, 0xA6, 0x96, 0x37, 0x54, 0x35,
        0xE0, 0x06, 0x06, 0x1C, 0xF7, 0xA4, 0x79, 0x46,
        0x32, 0x72, 0x11, 0x4A, 0x89, 0xEB, 0x3E, 0xAF,
        0x22, 0x46, 0xF0, 0xF8, 0xC1, 0x04, 0xA1, 0x49,
        0x86, 0x82, 0x8E, 0x0A, 0xD2, 0x04, 0x20, 0xC9,
        0xB3, 0x7E, 0xA2, 0x3F, 0x5C, 0x51, 0x49, 0x49,
        0xE7, 0x7A, 0xD9, 0xE9, 0xAD, 0x12, 0x29, 0x0D,
        0xD1, 0x21, 0x5E, 0x11, 0xDA, 0x27, 0x44, 0x57,
        0xAC, 0x86, 0xB1, 0xCE, 0x68, 0x64, 0xB1, 0x22,
        0x67, 0x7F, 0x37, 0x18, 0xAA, 0x31, 0xB0, 0x25,
        0x80, 0xE6, 0x43, 0x17, 0x17, 0x8D, 0x38, 0xF2,
        0x5F, 0x60, 0x9B, 0xC6, 0xC5, 0x5B, 0xC3, 0x74,
        0xA1, 0xBF, 0x78, 0xEA, 0x8E, 0xCC, 0x21, 0x9B,
        0x30, 0xB7, 0x4C, 0xBB, 0x32, 0x72, 0xA5, 0x99,
        0x23, 0x8C, 0x93, 0x98, 0x51, 0x70, 0x04, 0x8F,
        0x17, 0x67, 0x75, 0xFB, 0x19, 0x96, 0x2A, 0xC3,
        0xB1, 0x35, 0xAA, 0x59, 0xDB, 0x10, 0x4F, 0x71,
        0x14, 0xDB, 0xC2, 0xC2, 0xD4, 0x29, 0x49, 0xAD,
        0xEC, 0xA6, 0xA8, 0x5B, 0x32, 0x3E, 0xE2, 0xB2,
        0xB2, 0x3A, 0x77, 0xD9, 0xDB, 0x23, 0x59, 0x79,
        0xA8, 0xE2, 0xD6, 0x7C, 0xF7, 0xD2, 0x13, 0x6B,
        0xBB, 0xA7, 0x1F, 0x26, 0x95, 0x74, 0xB3, 0x88,
        0x88, 0xE1, 0x54, 0x13, 0x40, 0xC1, 0x92, 0x84,
        0x07, 0x4F, 0x9B, 0x7C, 0x8C, 0xF3, 0x7E, 0xB0,
        0x13, 0x84, 0xE6, 0xE3, 0x82, 0x2E, 0xC4, 0x88,
        0x2D, 0xFB, 0xBE, 0xC4, 0xE6, 0x09, 0x8E, 0xF2,
        0xB2, 0xFC, 0x17, 0x7A, 0x1F, 0x0B, 0xCB, 0x65,
        0xA5, 0x7F, 0xDA, 0xA8, 0x93, 0x15, 0x46, 0x1B,
        0xEB, 0x78, 0x85, 0xFB, 0x68, 0xB3, 0xCD, 0x09,
        0x6E, 0xDA, 0x59, 0x6A, 0xC0, 0xE6, 0x1D, 0xD7,
        0xA9, 0xC5, 0x07, 0xBC, 0x63, 0x45, 0xE0, 0x82,
        0x7D, 0xFC, 0xC8, 0xA3, 0xAC, 0x2D, 0xCE, 0x51,
        0xAD, 0x73, 0x1A, 0xA0, 0xEB, 0x93, 0x2A, 0x6D,
        0x09, 0x83, 0x99, 0x23, 0x47, 0xCB, 0xEB, 0x3C,
        0xD0, 0xD9, 0xC9, 0x71, 0x97, 0x97, 0xCC, 0x21,
        0xCF, 0x00, 0x62, 0xB0, 0xAD, 0x94, 0xCA, 0xD7,
        0x34, 0xC6, 0x3E, 0x6B, 0x5D, 0x85, 0x9C, 0xBE,
        0x19, 0xF0, 0x36, 0x82, 0x45, 0x35, 0x1B, 0xF4,
        0x64, 0xD7, 0x50, 0x55, 0x69, 0x79, 0x0D, 0x2B,
        0xB7, 0x24, 0xD8, 0x65, 0x9A, 0x9F, 0xEB, 0x1C,
        0x7C, 0x47, 0x3D, 0xC4, 0xD0, 0x61, 0xE2, 0x98,
        0x63, 0xA2, 0x71, 0x4B, 0xAC, 0x42, 0xAD, 0xCD,
        0x1A, 0x83, 0x72, 0x77, 0x65, 0x56, 0xF7, 0x92,
        0x8A, 0x7A, 0x44, 0xE9, 0x4B, 0x6A, 0x25, 0x32,
        0x2D, 0x03, 0xC0, 0xA1, 0x62, 0x2A, 0x7F, 0xD2,
        0x61, 0x52, 0x2B, 0x73, 0x58, 0xF0, 0x85, 0xBD,
        0xFB, 0x60, 0x75, 0x87, 0x62, 0xCB, 0x90, 0x10,
        0x31, 0x90, 0x1B, 0x5E, 0xEC, 0xF4, 0x92, 0x0C,
        0x81, 0x02, 0x0A, 0x9B, 0x17, 0x81, 0xBC, 0xB9,
        0xDD, 0x19, 0xA9, 0xDF, 0xB6, 0x64, 0x58, 0xE7,
        0x75, 0x7C, 0x52, 0xCE, 0xC7, 0x5B, 0x4B, 0xA7,
        0x40, 0xA2, 0x40, 0x99, 0xCB, 0x56, 0xBB, 0x60,
        0xA7, 0x6B, 0x69, 0x01, 0xAA, 0x3E, 0x01, 0x69,
        0xC9, 0xE8, 0x34, 0x96, 0xD7, 0x3C, 0x4C, 0x99,
        0x43, 0x5A, 0x28, 0xD6, 0x13, 0xE9, 0x7A, 0x11,
        0x77, 0xF5, 0x8B, 0x6C, 0xC5, 0x95, 0xD3, 0xB2,
        0x33, 0x1E, 0x9C, 0xA7, 0xB5, 0x7B, 0x74, 0xDC,
        0x2C, 0x52, 0x77, 0xD2, 0x6F, 0x2F, 0xE1, 0x92,
        0x40, 0xA5, 0x5C, 0x35, 0xD6, 0xCF, 0xCA, 0x26,
        0xC7, 0x3E, 0x9A, 0x2D, 0x7C, 0x98, 0x0D, 0x97,
        0x96, 0x0A, 0xE1, 0xA0, 0x46, 0x98, 0xC1, 0x6B,
        0x39, 0x8A, 0x5F, 0x20, 0xC3, 0x5A, 0x09, 0x14,
        0x14, 0x5C, 0xE1, 0x67, 0x4B, 0x71, 0xAB, 0xC6,
        0x06, 0x6A, 0x90, 0x9A, 0x3E, 0x4B, 0x91, 0x1E,
        0x69, 0xD5, 0xA8, 0x49, 0x43, 0x03, 0x61, 0xF7,
        0x31, 0xB0, 0x72, 0x46, 0xA6, 0x32, 0x9B, 0x52,
        0x36, 0x19, 0x04, 0x22, 0x50, 0x82, 0xD0, 0xAA,
        0xC5, 0xB2, 0x1D, 0x6B, 0x34, 0x86, 0x24, 0x81,
        0xA8, 0x90, 0xC3, 0xC3, 0x60, 0x76, 0x6F, 0x04,
        0x26, 0x36, 0x03, 0xA6, 0xB7, 0x3E, 0x80, 0x2B,
        0x1F, 0x70, 0xB2, 0xEB, 0x00, 0x04, 0x68, 0x36,
        0xB8, 0xF4, 0x93, 0xBF, 0x10, 0xB9, 0x0B, 0x87,
        0x37, 0xC6, 0xC5, 0x48, 0x44, 0x9B, 0x29, 0x4C,
        0x47, 0x25, 0x3B, 0xE2, 0x6C, 0xA7, 0x23, 0x36,
        0xA6, 0x32, 0x06, 0x3A, 0xD3, 0xD0, 0xB4, 0x8C,
        0x8B, 0x0F, 0x4A, 0x34, 0x44, 0x7E, 0xF1, 0x3B,
        0x76, 0x40, 0x20, 0xDE, 0x73, 0x9E, 0xB7, 0x9A,
        0xBA, 0x20, 0xE2, 0xBE, 0x19, 0x51, 0x82, 0x5F,
        0x29, 0x3B, 0xED, 0xD1, 0x08, 0x9F, 0xCB, 0x0A,
        0x91, 0xF5, 0x60, 0xC8, 0xE1, 0x7C, 0xDF, 0x52,
        0x54, 0x1D, 0xC2, 0xB8, 0x1F, 0x97, 0x2A, 0x73,
        0x75, 0xB2, 0x01, 0xF1, 0x0C, 0x08, 0xD9, 0xB5,
        0xBC, 0x8B, 0x95, 0x10, 0x00, 0x54, 0xA3, 0xD0,
        0xAA, 0xFF, 0x89, 0xBD, 0x08, 0xD6, 0xA0, 0xE7,
        0xF2, 0x11, 0x5A, 0x43, 0x52, 0x31, 0x29, 0x04,
        0x60, 0xC9, 0xAD, 0x43, 0x5A, 0x3B, 0x3C, 0xF3,
        0x5E, 0x52, 0x09, 0x1E, 0xDD, 0x18, 0x90, 0x04,
        0x7B, 0xCC, 0x0A, 0xAB, 0xB1, 0xAC, 0xEB, 0xC7,
        0x5F, 0x4A, 0x32, 0xBC, 0x14, 0x51, 0xAC, 0xC4,
        0x96, 0x99, 0x40, 0x78, 0x8E, 0x89, 0x41, 0x21,
        0x88, 0x94, 0x6C, 0x91, 0x43, 0xC5, 0x04, 0x6B,
        0xD1, 0xB4, 0x58, 0xDF, 0x61, 0x7C, 0x5D, 0xF5,
        0x33, 0xB0, 0x52, 0xCD, 0x60, 0x38, 0xB7, 0x75,
        0x40, 0x34, 0xA2, 0x3C, 0x2F, 0x77, 0x20, 0x13,
        0x4C, 0x7B, 0x4E, 0xAC, 0xE0, 0x1F, 0xAC, 0x0A,
        0x28, 0x53, 0xA9, 0x28, 0x58, 0x47, 0xAB, 0xBD,
        0x06, 0xA3, 0x34, 0x3A, 0x77, 0x8A, 0xC6, 0x06,
        0x2E, 0x45, 0x8B, 0xC5, 0xE6, 0x1E, 0xCE, 0x1C,
        0x0D, 0xE0, 0x20, 0x6E, 0x6F, 0xE8, 0xA8, 0x40,
        0x34, 0xA7, 0xC5, 0xF1, 0xB0, 0x05, 0xFB, 0x0A,
        0x58, 0x40, 0x51, 0xD3, 0x22, 0x9B, 0x86, 0xC9,
        0x09, 0xAC, 0x56, 0x47, 0xB3, 0xD7, 0x55, 0x69,
        0xE0, 0x5A, 0x88, 0x27, 0x9D, 0x80, 0xE5, 0xC3,
        0x0F, 0x57, 0x4D, 0xC3, 0x27, 0x51, 0x2C, 0x6B,
        0xBE, 0x81, 0x01, 0x23, 0x9E, 0xC6, 0x28, 0x61,
        0xF4, 0xBE, 0x67, 0xB0, 0x5B, 0x9C, 0xDA, 0x9C,
        0x54, 0x5C, 0x13, 0xE7, 0xEB, 0x53, 0xCF, 0xF2,
        0x60, 0xAD, 0x98, 0x70, 0x19, 0x9C, 0x21, 0xF8,
        0xC6, 0x3D, 0x64, 0xF0, 0x45, 0x8A, 0x71, 0x41,
        0x28, 0x50, 0x23, 0xFE, 0xB8, 0x29, 0x29, 0x08,
        0x72, 0x38, 0x96, 0x44, 0xB0, 0xC3, 0xB7, 0x3A,
        0xC2, 0xC8, 0xE1, 0x21, 0xA2, 0x9B, 0xB1, 0xC4,
        0x3C, 0x19, 0xA2, 0x33, 0xD5, 0x6B, 0xED, 0x82,
        0x74, 0x0E, 0xB0, 0x21, 0xC9, 0x7B, 0x8E, 0xBB,
        0xA4, 0x0F, 0xF3, 0x28, 0xB5, 0x41, 0x76, 0x0F,
        0xCC, 0x37, 0x2B, 0x52, 0xD3, 0xBC, 0x4F, 0xCB,
        0xC0, 0x6F, 0x42, 0x4E, 0xAF, 0x25, 0x38, 0x04,
        0xD4, 0xCB, 0x46, 0xF4, 0x1F, 0xF2, 0x54, 0xC0,
        0xC5, 0xBA, 0x48, 0x3B, 0x44, 0xA8, 0x7C, 0x21,
        0x96, 0x54, 0x55, 0x5E, 0xC7, 0xC1, 0x63, 0xC7,
        0x9B, 0x9C, 0xB7, 0x60, 0xA2, 0xAD, 0x9B, 0xB7,
        0x22, 0xB9, 0x3E, 0x0C, 0x28, 0xBD, 0x4B, 0x16,
        0x85, 0x94, 0x9C, 0x49, 0x6E, 0xAB, 0x1A, 0xFF,
        0x90, 0x91, 0x9E, 0x37, 0x61, 0xB3, 0x46, 0x83,
        0x8A, 0xBB, 0x2F, 0x01, 0xA9, 0x1E, 0x55, 0x43,
        0x75, 0xAF, 0xDA, 0xAA, 0xF3, 0x82, 0x6E, 0x6D,
        0xB7, 0x9F, 0xE7, 0x35, 0x3A, 0x7A, 0x57, 0x8A,
        0x7C, 0x05, 0x98, 0xCE, 0x28, 0xB6, 0xD9, 0x91,
        0x52, 0x14, 0x23, 0x6B, 0xBF, 0xFA, 0x6D, 0x45,
        0xB6, 0x37, 0x6A, 0x07, 0x92, 0x4A, 0x39, 0xA7,
        0xBE, 0x81, 0x82, 0x86, 0x71, 0x5C, 0x8A, 0x3C,
        0x11, 0x0C, 0xD7, 0x6C, 0x02, 0xE0, 0x41, 0x7A,
        0xF1, 0x38, 0xBD, 0xB9, 0x5C, 0x3C, 0xCA, 0x79,
        0x8A, 0xC8, 0x09, 0xED, 0x69, 0xCF, 0xB6, 0x72,
        0xB6, 0xFD, 0xDC, 0x24, 0xD8, 0x9C, 0x06, 0xA6,
        0x55, 0x88, 0x14, 0xAB, 0x0C, 0x21, 0xC6, 0x2B,
        0x2F, 0x84, 0xC0, 0xE3, 0xE0, 0x80, 0x3D, 0xB3,
        0x37, 0xA4, 0xE0, 0xC7, 0x12, 0x7A, 0x6B, 0x4C,
        0x8C, 0x08, 0xB1, 0xD1, 0xA7, 0x6B, 0xF0, 0x7E,
        0xB6, 0xE5, 0xB5, 0xBB, 0x47, 0xA1, 0x6C, 0x74,
        0xBC, 0x54, 0x83, 0x75, 0xFB, 0x29, 0xCD, 0x78,
        0x9A, 0x5C, 0xFF, 0x91, 0xBD, 0xBD, 0x07, 0x18,
        0x59, 0xF4, 0x84, 0x6E, 0x35, 0x5B, 0xB0, 0xD2,
        0x94, 0x84, 0xE2, 0x64, 0xDF, 0xF3, 0x6C, 0x91,
        0x77, 0xA7, 0xAC, 0xA7, 0x89, 0x08, 0x87, 0x96,
        0x95, 0xCA, 0x87, 0xF2, 0x54, 0x36, 0xBC, 0x12,
        0x63, 0x07, 0x24, 0xBB, 0x22, 0xF0, 0xCB, 0x64,
        0x89, 0x7F, 0xE5, 0xC4, 0x11, 0x95, 0x28, 0x0D,
        0xA0, 0x41, 0x84, 0xD4, 0xBC, 0x7B, 0x53, 0x2A,
        0x0F, 0x70, 0xA5, 0x4D, 0x77, 0x57, 0xCD, 0xE6,
        0x17, 0x5A, 0x68, 0x43, 0xB8, 0x61, 0xCB, 0x2B,
        0xC4, 0x83, 0x0C, 0x00, 0x12, 0x55, 0x4C, 0xFC,
        0x5D, 0x2C, 0x8A, 0x20, 0x27, 0xAA, 0x3C, 0xD9,
        0x67, 0x13, 0x0E, 0x9B, 0x96, 0x24, 0x1B, 0x11,
        0xC4, 0x32, 0x0C, 0x76, 0x49, 0xCC, 0x23, 0xA7,
        0x1B, 0xAF, 0xE6, 0x91, 0xAF, 0xC0, 0x8E, 0x68,
        0x0B, 0xCE, 0xF4, 0x29, 0x07, 0x00, 0x07, 0x18,
        0xE4, 0xEA, 0xCE, 0x8D, 0xA2, 0x82, 0x14, 0x19,
        0x7B, 0xE1, 0xC2, 0x69, 0xDA, 0x9C, 0xB5, 0x41,
        0xE1, 0xA3, 0xCE, 0x97, 0xCF, 0xAD, 0xF9, 0xC6,
        0x05, 0x87, 0x80, 0xFE, 0x67, 0x93, 0xDB, 0xFA,
        0x82, 0x18, 0xA2, 0x76, 0x0B, 0x80, 0x2B, 0x8D,
        0xA2, 0xAA, 0x27, 0x1A, 0x38, 0x77, 0x25, 0x23,
        0xA7, 0x67, 0x36, 0xA7, 0xA3, 0x1B, 0x9D, 0x30,
        0x37, 0xAD, 0x21, 0xCE, 0xBB, 0x11, 0xA4, 0x72,
        0xB8, 0x79, 0x2E, 0xB1, 0x75, 0x58, 0xB9, 0x40,
        0xE7, 0x08, 0x83, 0xF2, 0x64, 0x59, 0x2C, 0x68,
        0x9B, 0x24, 0x0B, 0xB4, 0x3D, 0x54, 0x08, 0xBF,
        0x44, 0x64, 0x32, 0xF4, 0x12, 0xF4, 0xB9, 0xA5,
        0xF6, 0x86, 0x5C, 0xC2, 0x52, 0xA4, 0x3C, 0xF4,
        0x0A, 0x32, 0x03, 0x91, 0x55, 0x55, 0x91, 0xD6,
        0x75, 0x61, 0xFD, 0xD0, 0x53, 0x53, 0xAB, 0x6B,
        0x01, 0x9B, 0x3A, 0x08, 0xA7, 0x33, 0x53, 0xD5,
        0x1B, 0x61, 0x13, 0xAB, 0x2F, 0xA5, 0x1D, 0x97,
        0x56, 0x48, 0xEE, 0x25, 0x4A, 0xF8, 0x9A, 0x23,
        0x05, 0x04, 0xA2, 0x36, 0xA4, 0x65, 0x82, 0x57,
        0x74, 0x0B, 0xDC, 0xBB, 0xE1, 0x70, 0x8A, 0xB0,
        0x22, 0xC3, 0xC5, 0x88, 0xA4, 0x10, 0xDB, 0x3B,
        0x9C, 0x30, 0x8A, 0x06, 0x27, 0x5B, 0xDF, 0x5B,
        0x48, 0x59, 0xD3, 0xA2, 0x61, 0x7A, 0x29, 0x5E,
        0x1A, 0x22, 0xF9, 0x01, 0x98, 0xBA, 0xD0, 0x16,
        0x6F, 0x4A, 0x94, 0x34, 0x17, 0xC5, 0xB8, 0x31,
        0x73, 0x6C, 0xB2, 0xC8, 0x58, 0x0A, 0xBF, 0xDE,
        0x57, 0x14, 0xB5, 0x86, 0xAB, 0xEE, 0xC0, 0xA1,
        0x75, 0xA0, 0x8B, 0xC7, 0x10, 0xC7, 0xA2, 0x89,
        0x5D, 0xE9, 0x3A, 0xC4, 0x38, 0x06, 0x1B, 0xF7,
        0x76, 0x5D, 0x0D, 0x21, 0xCD, 0x41, 0x81, 0x67,
        0xCA, 0xF8, 0x9D, 0x1E, 0xFC, 0x34, 0x48, 0xBC,
        0xBB, 0x96, 0xD6, 0x9B, 0x3E, 0x01, 0x0C, 0x82,
        0xD1, 0x5C, 0xAB, 0x6C, 0xAC, 0xC6, 0x79, 0x9D,
        0x36, 0x39, 0x66, 0x9A, 0x5B, 0x21, 0xA6, 0x33,
        0xC8, 0x65, 0xF8, 0x59, 0x3B, 0x5B, 0x7B, 0xC8,
        0x00, 0x26, 0x2B, 0xB8, 0x37, 0xA9, 0x24, 0xA6,
        0xC5, 0x44, 0x0E, 0x4F, 0xC7, 0x3B, 0x41, 0xB2,
        0x30, 0x92, 0xC3, 0x91, 0x2F, 0x4C, 0x6B, 0xEB,
        0xB4, 0xC7, 0xB4, 0xC6, 0x29, 0x08, 0xB0, 0x37,
        0x75, 0x66, 0x6C, 0x22, 0x22, 0x0D, 0xF9, 0xC8,
        0x88, 0x23, 0xE3, 0x44, 0xC7, 0x30, 0x83, 0x32,
        0x34, 0x5C, 0x8B, 0x79, 0x5D, 0x34, 0xE8, 0xC0,
        0x51, 0xF2, 0x1F, 0x5A, 0x21, 0xC2, 0x14, 0xB6,
        0x98, 0x41, 0x35, 0x87, 0x09, 0xB1, 0xC3, 0x05,
        0xB3, 0x2C, 0xC2, 0xC3, 0x80, 0x6A, 0xE9, 0xCC,
        0xD3, 0x81, 0x9F, 0xFF, 0x45, 0x07, 0xFE, 0x52,
        0x0F, 0xBF, 0xC2, 0x71, 0x99, 0xBC, 0x23, 0xBE,
        0x6B, 0x9B, 0x2D, 0x2A, 0xC1, 0x71, 0x75, 0x79,
        0xAC, 0x76, 0x92, 0x79, 0xE2, 0xA7, 0xAA, 0xC6,
        0x8A, 0x37, 0x1A, 0x47, 0xBA, 0x3A, 0x7D, 0xBE,
        0x01, 0x6F, 0x14, 0xE1, 0xA7, 0x27, 0x33, 0x36,
        0x63, 0xC4, 0xA5, 0xCD, 0x1A, 0x0F, 0x88, 0x36,
        0xCF, 0x7B, 0x5C, 0x49, 0xAC, 0x51, 0x48, 0x5C,
        0xA6, 0x03, 0x45, 0xC9, 0x90, 0xE0, 0x68, 0x88,
        0x72, 0x00, 0x03, 0x73, 0x13, 0x22, 0xC5, 0xB8,
        0xCD, 0x5E, 0x69, 0x07, 0xFD, 0xA1, 0x15, 0x7F,
        0x46, 0x8F, 0xD3, 0xFC, 0x20, 0xFA, 0x81, 0x75,
        0xEE, 0xC9, 0x5C, 0x29, 0x1A, 0x26, 0x2B, 0xA8,
        0xC5, 0xBE, 0x99, 0x08, 0x72, 0x41, 0x89, 0x30,
        0x85, 0x23, 0x39, 0xD8, 0x8A, 0x19, 0xB3, 0x7F,
        0xEF, 0xA3, 0xCF, 0xE8, 0x21, 0x75, 0xC2, 0x24,
        0x40, 0x7C, 0xA4, 0x14, 0xBA, 0xEB, 0x37, 0x92,
        0x3B, 0x4D, 0x2D, 0x83, 0x13, 0x4A, 0xE1, 0x54,
        0xE4, 0x90, 0xA9, 0xB4, 0x5A, 0x05, 0x63, 0xB0,
        0x6C, 0x95, 0x3C, 0x33, 0x01, 0x45, 0x0A, 0x21,
        0x76, 0xA0, 0x7C, 0x61, 0x4A, 0x74, 0xE3, 0x47,
        0x8E, 0x48, 0x50, 0x9F, 0x9A, 0x60, 0xAE, 0x94,
        0x5A, 0x8E, 0xBC, 0x78, 0x15, 0x12, 0x1D, 0x90,
        0xA3, 0xB0, 0xE0, 0x70, 0x91, 0xA0, 0x96, 0xCF,
        0x02, 0xC5, 0x7B, 0x25, 0xBC, 0xA5, 0x81, 0x26,
        0xAD, 0x0C, 0x62, 0x9C, 0xE1, 0x66, 0xA7, 0xED,
        0xB4, 0xB3, 0x32, 0x21, 0xA0, 0xD3, 0xF7, 0x2B,
        0x85, 0xD5, 0x62, 0xEC, 0x69, 0x8B, 0x7D, 0x0A,
        0x91, 0x3D, 0x73, 0x80, 0x6F, 0x1C, 0x5C, 0x87,
        0xB3, 0x8E, 0xC0, 0x03, 0xCB, 0x30, 0x3A, 0x3D,
        0xC5, 0x1B, 0x4B, 0x35, 0x35, 0x6A, 0x67, 0x82,
        0x6D, 0x6E, 0xDA, 0xA8, 0xFE, 0xB9, 0x3B, 0x98,
        0x49, 0x3B, 0x2D, 0x1C, 0x11, 0xB6, 0x76, 0xA6,
        0xAD, 0x95, 0x06, 0xA1, 0xAA, 0xAE, 0x13, 0xA8,
        0x24, 0xC7, 0xC0, 0x8D, 0x1C, 0x6C, 0x2C, 0x4D,
        0xBA, 0x96, 0x42, 0xC7, 0x6E, 0xA7, 0xF6, 0xC8,
        0x26, 0x4B, 0x64, 0xA2, 0x3C, 0xCC, 0xA9, 0xA7,
        0x46, 0x35, 0xFC, 0xBF, 0x03, 0xE0, 0x0F, 0x1B,
        0x57, 0x22, 0xB2, 0x14, 0x37, 0x67, 0x90, 0x79,
        0x3B, 0x2C, 0x4F, 0x0A, 0x13, 0xB5, 0xC4, 0x07,
        0x60, 0xB4, 0x21, 0x8E, 0x1D, 0x25, 0x94, 0xDC,
        0xB3, 0x0A, 0x70, 0xD9, 0xC1, 0x78, 0x2A, 0x5D,
        0xD3, 0x05, 0x76, 0xFA, 0x41, 0x44, 0xBF, 0xC8,
        0x41, 0x6E, 0xDA, 0x81, 0x18, 0xFC, 0x64, 0x72,
        0xF5, 0x6A, 0x97, 0x95, 0x86, 0xF3, 0x3B, 0xB0,
        0x70, 0xFB, 0x0F, 0x1B, 0x0B, 0x10, 0xBC, 0x48,
        0x97, 0xEB, 0xE0, 0x1B, 0xCA, 0x38, 0x93, 0xD4,
        0xE1, 0x6A, 0xDB, 0x25, 0x09, 0x3A, 0x74, 0x17,
        0xD0, 0x70, 0x8C, 0x83, 0xA2, 0x63, 0x22, 0xE2,
        0x2E, 0x63, 0x30, 0x09, 0x1E, 0x30, 0x15, 0x2B,
        0xF8, 0x23, 0x59, 0x7C, 0x04, 0xCC, 0xF4, 0xCF,
        0xC7, 0x33, 0x15, 0x78, 0xF4, 0x3A, 0x27, 0x26,
        0xCC, 0xB4, 0x28, 0x28, 0x9A, 0x90, 0xC8, 0x63,
        0x25, 0x9D, 0xD1, 0x80, 0xC5, 0xFF, 0x14, 0x2B,
        0xEF, 0x41, 0xC7, 0x71, 0x70, 0x94, 0xBE, 0x07,
        0x85, 0x6D, 0xA2, 0xB1, 0x40, 0xFA, 0x67, 0x71,
        0x09, 0x67, 0x35, 0x6A, 0xA4, 0x7D, 0xFB, 0xC8,
        0xD2, 0x55, 0xB4, 0x72, 0x2A, 0xB8, 0x6D, 0x43,
        0x9B, 0x7E, 0x0A, 0x60, 0x90, 0x25, 0x1D, 0x2D,
        0x4C, 0x1E, 0xD5, 0xF2, 0x0B, 0xBE, 0x68, 0x07,
        0xBF, 0x65, 0xA9, 0x0B, 0x7C, 0xB2, 0xEC, 0x01,
        0x02, 0xAF, 0x02, 0x80, 0x9D, 0xC9, 0xAC, 0x7D,
        0x0A, 0x3A, 0xBC, 0x69, 0xC1, 0x83, 0x65, 0xBC,
        0xFF, 0x59, 0x18, 0x5F, 0x33, 0x99, 0x68, 0x87,
        0x74, 0x61, 0x85, 0x90, 0x6C, 0x01, 0x91, 0xAE,
        0xD4, 0x40, 0x7E, 0x13, 0x94, 0x46, 0x45, 0x9B,
        0xE2, 0x9C, 0x68, 0x22, 0x71, 0x76, 0x44, 0x35,
        0x3D, 0x24, 0xAB, 0x63, 0x39, 0x15, 0x6A, 0x9C,
        0x42, 0x49, 0x09, 0xF0, 0xA9, 0x02, 0x5B, 0xB7,
        0x47, 0x20, 0x77, 0x9B, 0xE4, 0x3F, 0x16, 0xD8,
        0x1C, 0x8C, 0xC6, 0x66, 0xE9, 0x97, 0x10, 0xD8,
        0xC6, 0x8B, 0xB5, 0xCC, 0x4E, 0x12, 0xF3, 0x14,
        0xE9, 0x25, 0xA5, 0x51, 0xF0, 0x9C, 0xC5, 0x90,
        0x03, 0xA1, 0xF8, 0x81, 0x03, 0xC2, 0x54, 0xBB,
        0x97, 0x8D, 0x75, 0xF3, 0x94, 0xD3, 0x54, 0x0E,
        0x31, 0xE7, 0x71, 0xCD, 0xA3, 0x6E, 0x39, 0xEC,
        0x54, 0xA6, 0x2B, 0x58, 0x32, 0x66, 0x4D, 0x82,
        0x1A, 0x72, 0xF1, 0xE6, 0xAF, 0xBB, 0xA2, 0x7F,
        0x84, 0x29, 0x5B, 0x26, 0x94, 0xC4, 0x98, 0x49,
        0x8E, 0x81, 0x2B, 0xC8, 0xE9, 0x37, 0x8F, 0xE5,
        0x41, 0xCE, 0xC5, 0x89, 0x1B, 0x25, 0x06, 0x29,
        0x01, 0xCB, 0x72, 0x12, 0xE3, 0xCD, 0xC4, 0x61,
        0x79, 0xEC, 0x5B, 0xCE, 0xC1, 0x0B, 0xC0, 0xB9,
        0x31, 0x1D, 0xE0, 0x50, 0x74, 0x29, 0x06, 0x87,
        0xFD, 0x6A, 0x53, 0x92, 0x67, 0x16, 0x54, 0x28,
        0x4C, 0xD9, 0xC8, 0xCC, 0x3E, 0xBA, 0x80, 0xEB,
        0x3B, 0x66, 0x2E, 0xB5, 0x3E, 0xB7, 0x51, 0x16,
        0x70, 0x4A, 0x1F, 0xEB, 0x5C, 0x2D, 0x05, 0x63,
        0x38, 0x53, 0x28, 0x68, 0xDD, 0xF2, 0x4E, 0xB8,
        0x99, 0x2A, 0xB8, 0x56, 0x5D, 0x9E, 0x49, 0x0C,
        0xAD, 0xF1, 0x48, 0x04, 0x36, 0x0D, 0xAA, 0x90,
        0x71, 0x8E, 0xAB, 0x61, 0x6B, 0xAB, 0x07, 0x65,
        0xD3, 0x39, 0x87, 0xB4, 0x7E, 0xFB, 0x65, 0x99,
        0xC5, 0x56, 0x32, 0x35, 0xE6, 0x1E, 0x4B, 0xE6,
        0x70, 0xE9, 0x79, 0x55, 0xAB, 0x29, 0x2D, 0x97,
        0x32, 0xCB, 0x89, 0x30, 0x94, 0x8A, 0xC8, 0x2D,
        0xF2, 0x30, 0xAC, 0x72, 0x29, 0x7A, 0x23, 0x67,
        0x9D, 0x6B, 0x94, 0xC1, 0x7F, 0x13, 0x59, 0x48,
        0x32, 0x54, 0xFE, 0xDC, 0x2F, 0x05, 0x81, 0x9F,
        0x0D, 0x06, 0x9A, 0x44, 0x3B, 0x78, 0xE3, 0xFC,
        0x6C, 0x3E, 0xF4, 0x71, 0x4B, 0x05, 0xA3, 0xFC,
        0xA8, 0x1C, 0xBB, 0xA6, 0x02, 0x42, 0xA7, 0x06,
        0x0C, 0xD8, 0x85, 0xD8, 0xF3, 0x99, 0x81, 0xBB,
        0x18, 0x09, 0x2B, 0x23, 0xDA, 0xA5, 0x9F, 0xD9,
        0x57, 0x83, 0x88, 0x68, 0x8A, 0x09, 0xBB, 0xA0,
        0x79, 0xBC, 0x80, 0x9A, 0x54, 0x84, 0x3A, 0x60,
        0x38, 0x5E, 0x23, 0x10, 0xBB, 0xCB, 0xCC, 0x02,
        0x13, 0xCE, 0x3D, 0xFA, 0xAB, 0x33, 0xB4, 0x7F,
        0x9D, 0x63, 0x05, 0xBC, 0x95, 0xC6, 0x10, 0x78,
        0x13, 0xC5, 0x85, 0xC4, 0xB6, 0x57, 0xBF, 0x30,
        0x54, 0x28, 0x33, 0xB1, 0x49, 0x49, 0xF5, 0x73,
        0xC0, 0x61, 0x2A, 0xD5, 0x24, 0xBA, 0xAE, 0x69,
        0x59, 0x0C, 0x12, 0x77, 0xB8, 0x6C, 0x28, 0x65,
        0x71, 0xBF, 0x66, 0xB3, 0xCF, 0xF4, 0x6A, 0x38,
        0x58, 0xC0, 0x99, 0x06, 0xA7, 0x94, 0xDF, 0x4A,
        0x06, 0xE9, 0xD4, 0xB0, 0xA2, 0xE4, 0x3F, 0x10,
        0xF7, 0x2A, 0x6C, 0x6C, 0x47, 0xE5, 0x64, 0x6E,
        0x2C, 0x79, 0x9B, 0x71, 0xC3, 0x3E, 0xD2, 0xF0,
        0x1E, 0xEB, 0x45, 0x93, 0x8E, 0xB7, 0xA4, 0xE2,
        0xE2, 0x90, 0x8C, 0x53, 0x55, 0x8A, 0x54, 0x0D,
        0x35, 0x03, 0x69, 0xFA, 0x18, 0x9C, 0x61, 0x69,
        0x43, 0xF7, 0x98, 0x1D, 0x76, 0x18, 0xCF, 0x02,
        0xA5, 0xB0, 0xA2, 0xBC, 0xC4, 0x22, 0xE8, 0x57,
        0xD1, 0xA4, 0x78, 0x71, 0x25, 0x3D, 0x08, 0x29,
        0x3C, 0x1C, 0x17, 0x9B, 0xCD, 0xC0, 0x43, 0x70,
        0x69, 0x10, 0x74, 0x18, 0x20, 0x5F, 0xDB, 0x98,
        0x56, 0x62, 0x3B, 0x8C, 0xA6, 0xB6, 0x94, 0xC9,
        0x6C, 0x08, 0x4B, 0x17, 0xF1, 0x3B, 0xB6, 0xDF,
        0x12, 0xB2, 0xCF, 0xBB, 0xC2, 0xB0, 0xE0, 0xC3,
        0x4B, 0x00, 0xD0, 0xFC, 0xD0, 0xAE, 0xCF, 0xB2,
        0x79, 0x24, 0xF6, 0x98, 0x4E, 0x74, 0x7B, 0xE2,
        0xA0, 0x9D, 0x83, 0xA8, 0x66, 0x45, 0x90, 0xA8,
        0x07, 0x73, 0x31, 0x49, 0x1A, 0x4F, 0x7D, 0x72,
        0x08, 0x43, 0xF2, 0x3E, 0x65, 0x2C, 0x6F, 0xA8,
        0x40, 0x30, 0x8D, 0xB4, 0x02, 0x03, 0x37, 0xAA,
        0xD3, 0x79, 0x67, 0x03, 0x4A, 0x9F, 0xB5, 0x23,
        0xB6, 0x7C, 0xA7, 0x03, 0x30, 0xF0, 0x2D, 0x9E,
        0xA2, 0x0C, 0x1E, 0x84, 0xCB, 0x8E, 0x57, 0x57,
        0xC9, 0xE1, 0x89, 0x6B, 0x60, 0x58, 0x14, 0x41,
        0xED, 0x61, 0x8A, 0xA5, 0xB2, 0x6D, 0xA5, 0x6C,
        0x0A, 0x5A, 0x73, 0xC4, 0xDC, 0xFD, 0x75, 0x5E,
        0x61, 0x0B, 0x4F, 0xC8, 0x1F, 0xF8, 0x4E, 0x21,
        0xD2, 0xE5, 0x74, 0xDF, 0xD8, 0xCD, 0x0A, 0xE8,
        0x93, 0xAA, 0x7E, 0x12, 0x5B, 0x44, 0xB9, 0x24,
        0xF4, 0x52, 0x23, 0xEC, 0x09, 0xF2, 0xAD, 0x11,
        0x41, 0xEA, 0x93, 0xA6, 0x80, 0x50, 0xDB, 0xF6,
        0x99, 0xE3, 0x24, 0x68, 0x84, 0x18, 0x1F, 0x8E,
        0x1D, 0xD4, 0x4E, 0x0C, 0x76, 0x29, 0x09, 0x33,
        0x30, 0x22, 0x1F, 0xD6, 0x7D, 0x9B, 0x7D, 0x6E,
        0x15, 0x10, 0xB2, 0xDB, 0xAD, 0x87, 0x62, 0xF7
    };
#endif
    static byte pubKey[KYBER_MAX_PUBLIC_KEY_SIZE];
    static byte privKey[KYBER_MAX_PRIVATE_KEY_SIZE];

    key = (KyberKey*)XMALLOC(sizeof(KyberKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);
    if (key != NULL) {
        XMEMSET(key, 0, sizeof(KyberKey));
    }

#ifndef WOLFSSL_NO_KYBER512
    ExpectIntEQ(wc_KyberKey_Init(KYBER512, key, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_KyberKey_MakeKeyWithRandom(key, seed_512, sizeof(seed_512)),
        0);
    ExpectIntEQ(wc_KyberKey_EncodePublicKey(key, pubKey,
        KYBER512_PUBLIC_KEY_SIZE), 0);
    ExpectIntEQ(wc_KyberKey_EncodePrivateKey(key, privKey,
        KYBER512_PRIVATE_KEY_SIZE), 0);
    ExpectIntEQ(XMEMCMP(pubKey, ek_512, KYBER512_PUBLIC_KEY_SIZE), 0);
    ExpectIntEQ(XMEMCMP(privKey, dk_512, KYBER512_PRIVATE_KEY_SIZE), 0);
    wc_KyberKey_Free(key);
#endif
#ifndef WOLFSSL_NO_KYBER768
    ExpectIntEQ(wc_KyberKey_Init(KYBER768, key, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_KyberKey_MakeKeyWithRandom(key, seed_768, sizeof(seed_768)),
        0);
    ExpectIntEQ(wc_KyberKey_EncodePublicKey(key, pubKey,
        KYBER768_PUBLIC_KEY_SIZE), 0);
    ExpectIntEQ(wc_KyberKey_EncodePrivateKey(key, privKey,
        KYBER768_PRIVATE_KEY_SIZE), 0);
    ExpectIntEQ(XMEMCMP(pubKey, ek_768, KYBER768_PUBLIC_KEY_SIZE), 0);
    ExpectIntEQ(XMEMCMP(privKey, dk_768, KYBER768_PRIVATE_KEY_SIZE), 0);
    wc_KyberKey_Free(key);
#endif
#ifndef WOLFSSL_NO_KYBER1024
    ExpectIntEQ(wc_KyberKey_Init(KYBER1024, key, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_KyberKey_MakeKeyWithRandom(key, seed_1024,
        sizeof(seed_1024)), 0);
    ExpectIntEQ(wc_KyberKey_EncodePublicKey(key, pubKey,
        KYBER1024_PUBLIC_KEY_SIZE), 0);
    ExpectIntEQ(wc_KyberKey_EncodePrivateKey(key, privKey,
        KYBER1024_PRIVATE_KEY_SIZE), 0);
    ExpectIntEQ(XMEMCMP(pubKey, ek_1024, KYBER1024_PUBLIC_KEY_SIZE), 0);
    ExpectIntEQ(XMEMCMP(privKey, dk_1024, KYBER1024_PRIVATE_KEY_SIZE), 0);
    wc_KyberKey_Free(key);
#endif

    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_kyber_encapsulate_kats(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_HAVE_KYBER) && defined(WOLFSSL_WC_KYBER) && \
    !defined(WOLFSSL_KYBER_ORIGINAL)
    KyberKey* key;
#ifndef WOLFSSL_NO_KYBER512
    static const byte ek_512[KYBER512_PUBLIC_KEY_SIZE] = {
        0xDD, 0x19, 0x24, 0x93, 0x5A, 0xA8, 0xE6, 0x17,
        0xAF, 0x18, 0xB5, 0xA0, 0x65, 0xAC, 0x45, 0x72,
        0x77, 0x67, 0xEE, 0x89, 0x7C, 0xF4, 0xF9, 0x44,
        0x2B, 0x2A, 0xCE, 0x30, 0xC0, 0x23, 0x7B, 0x30,
        0x7D, 0x3E, 0x76, 0xBF, 0x8E, 0xEB, 0x78, 0xAD,
        0xDC, 0x4A, 0xAC, 0xD1, 0x64, 0x63, 0xD8, 0x60,
        0x2F, 0xD5, 0x48, 0x7B, 0x63, 0xC8, 0x8B, 0xB6,
        0x60, 0x27, 0xF3, 0x7D, 0x0D, 0x61, 0x4D, 0x6F,
        0x9C, 0x24, 0x60, 0x3C, 0x42, 0x94, 0x76, 0x64,
        0xAC, 0x43, 0x98, 0xC6, 0xC5, 0x23, 0x83, 0x46,
        0x9B, 0x4F, 0x97, 0x77, 0xE5, 0xEC, 0x72, 0x06,
        0x21, 0x0F, 0x3E, 0x5A, 0x79, 0x6B, 0xF4, 0x5C,
        0x53, 0x26, 0x8E, 0x25, 0xF3, 0x9A, 0xC2, 0x61,
        0xAF, 0x3B, 0xFA, 0x2E, 0xE7, 0x55, 0xBE, 0xB8,
        0xB6, 0x7A, 0xB3, 0xAC, 0x8D, 0xF6, 0xC6, 0x29,
        0xC1, 0x17, 0x6E, 0x9E, 0x3B, 0x96, 0x5E, 0x93,
        0x69, 0xF9, 0xB3, 0xB9, 0x2A, 0xD7, 0xC2, 0x09,
        0x55, 0x64, 0x1D, 0x99, 0x52, 0x6F, 0xE7, 0xB9,
        0xFE, 0x8C, 0x85, 0x08, 0x20, 0x27, 0x5C, 0xD9,
        0x64, 0x84, 0x92, 0x50, 0x09, 0x07, 0x33, 0xCE,
        0x12, 0x4E, 0xCF, 0x31, 0x66, 0x24, 0x37, 0x4B,
        0xD1, 0x8B, 0x7C, 0x35, 0x8C, 0x06, 0xE9, 0xC1,
        0x36, 0xEE, 0x12, 0x59, 0xA9, 0x24, 0x5A, 0xBC,
        0x55, 0xB9, 0x64, 0xD6, 0x89, 0xF5, 0xA0, 0x82,
        0x92, 0xD2, 0x82, 0x65, 0x65, 0x8E, 0xBB, 0x40,
        0xCB, 0xFE, 0x48, 0x8A, 0x22, 0x28, 0x27, 0x55,
        0x90, 0xAB, 0x9F, 0x32, 0xA3, 0x41, 0x09, 0x70,
        0x9C, 0x1C, 0x29, 0x1D, 0x4A, 0x23, 0x33, 0x72,
        0x74, 0xC7, 0xA5, 0xA5, 0x99, 0x1C, 0x7A, 0x87,
        0xB8, 0x1C, 0x97, 0x4A, 0xB1, 0x8C, 0xE7, 0x78,
        0x59, 0xE4, 0x99, 0x5E, 0x7C, 0x14, 0xF0, 0x37,
        0x17, 0x48, 0xB7, 0x71, 0x2F, 0xB5, 0x2C, 0x59,
        0x66, 0xCD, 0x63, 0x06, 0x3C, 0x4F, 0x3B, 0x81,
        0xB4, 0x7C, 0x45, 0xDD, 0xE8, 0x3F, 0xB3, 0xA2,
        0x72, 0x40, 0x29, 0xB1, 0x0B, 0x32, 0x30, 0x21,
        0x4C, 0x04, 0xFA, 0x05, 0x77, 0xFC, 0x29, 0xAC,
        0x90, 0x86, 0xAE, 0x18, 0xC5, 0x3B, 0x3E, 0xD4,
        0x4E, 0x50, 0x74, 0x12, 0xFC, 0xA0, 0x4B, 0x4F,
        0x53, 0x8A, 0x51, 0x58, 0x8E, 0xC1, 0xF1, 0x02,
        0x9D, 0x15, 0x2D, 0x9A, 0xE7, 0x73, 0x5F, 0x76,
        0xA0, 0x77, 0xAA, 0x94, 0x84, 0x38, 0x0A, 0xED,
        0x91, 0x89, 0xE5, 0x91, 0x24, 0x87, 0xFC, 0xC5,
        0xB7, 0xC7, 0x01, 0x2D, 0x92, 0x23, 0xDD, 0x96,
        0x7E, 0xEC, 0xDA, 0xC3, 0x00, 0x8A, 0x89, 0x31,
        0xB6, 0x48, 0x24, 0x35, 0x37, 0xF5, 0x48, 0xC1,
        0x71, 0x69, 0x8C, 0x5B, 0x38, 0x1D, 0x84, 0x6A,
        0x72, 0xE5, 0xC9, 0x2D, 0x42, 0x26, 0xC5, 0xA8,
        0x90, 0x98, 0x84, 0xF1, 0xC4, 0xA3, 0x40, 0x4C,
        0x17, 0x20, 0xA5, 0x27, 0x94, 0x14, 0xD7, 0xF2,
        0x7B, 0x2B, 0x98, 0x26, 0x52, 0xB6, 0x74, 0x02,
        0x19, 0xC5, 0x6D, 0x21, 0x77, 0x80, 0xD7, 0xA5,
        0xE5, 0xBA, 0x59, 0x83, 0x63, 0x49, 0xF7, 0x26,
        0x88, 0x1D, 0xEA, 0x18, 0xEF, 0x75, 0xC0, 0x77,
        0x2A, 0x8B, 0x92, 0x27, 0x66, 0x95, 0x37, 0x18,
        0xCA, 0xCC, 0x14, 0xCC, 0xBA, 0xCB, 0x5F, 0xC4,
        0x12, 0xA2, 0xD0, 0xBE, 0x52, 0x18, 0x17, 0x64,
        0x5A, 0xB2, 0xBF, 0x6A, 0x47, 0x85, 0xE9, 0x2B,
        0xC9, 0x4C, 0xAF, 0x47, 0x7A, 0x96, 0x78, 0x76,
        0x79, 0x6C, 0x0A, 0x51, 0x90, 0x31, 0x5A, 0xC0,
        0x88, 0x56, 0x71, 0xA4, 0xC7, 0x49, 0x56, 0x4C,
        0x3B, 0x2C, 0x7A, 0xED, 0x90, 0x64, 0xEB, 0xA2,
        0x99, 0xEF, 0x21, 0x4B, 0xA2, 0xF4, 0x04, 0x93,
        0x66, 0x7C, 0x8B, 0xD0, 0x32, 0xAE, 0xC5, 0x62,
        0x17, 0x11, 0xB4, 0x1A, 0x38, 0x52, 0xC5, 0xC2,
        0xBA, 0xB4, 0xA3, 0x49, 0xCE, 0x4B, 0x7F, 0x08,
        0x5A, 0x81, 0x2B, 0xBB, 0xC8, 0x20, 0xB8, 0x1B,
        0xEF, 0xE6, 0x3A, 0x05, 0xB8, 0xBC, 0xDF, 0xE9,
        0xC2, 0xA7, 0x0A, 0x8B, 0x1A, 0xCA, 0x9B, 0xF9,
        0x81, 0x64, 0x81, 0x90, 0x7F, 0xF4, 0x43, 0x24,
        0x61, 0x11, 0x12, 0x87, 0x30, 0x3F, 0x0B, 0xD8,
        0x17, 0xC0, 0x57, 0x26, 0xBF, 0xA1, 0x8A, 0x2E,
        0x24, 0xC7, 0x72, 0x49, 0x21, 0x02, 0x80, 0x32,
        0xF6, 0x22, 0xBD, 0x96, 0x0A, 0x31, 0x7D, 0x83,
        0xB3, 0x56, 0xB5, 0x7F, 0x4A, 0x80, 0x04, 0x49,
        0x9C, 0xBC, 0x73, 0xC9, 0x7D, 0x1E, 0xB7, 0x74,
        0x59, 0x72, 0x63, 0x1C, 0x05, 0x61, 0xC1, 0xA3,
        0xAB, 0x6E, 0xF9, 0x1B, 0xD3, 0x63, 0x28, 0x0A,
        0x10, 0x54, 0x5D, 0xA6, 0x93, 0xE6, 0xD5, 0x8A,
        0xED, 0x68, 0x45, 0xE7, 0xCC, 0x5F, 0x0D, 0x08,
        0xCA, 0x79, 0x05, 0x05, 0x2C, 0x77, 0x36, 0x6D,
        0x19, 0x72, 0xCC, 0xFC, 0xC1, 0xA2, 0x76, 0x10,
        0xCB, 0x54, 0x36, 0x65, 0xAA, 0x79, 0x8E, 0x20,
        0x94, 0x01, 0x28, 0xB9, 0x56, 0x7A, 0x7E, 0xDB,
        0x7A, 0x90, 0x04, 0x07, 0xC7, 0x0D, 0x35, 0x94,
        0x38, 0x43, 0x5E, 0x13, 0x96, 0x16, 0x08, 0xD5,
        0x52, 0xA9, 0x4C, 0x5C, 0xDA, 0x78, 0x59, 0x22,
        0x05, 0x09, 0xB4, 0x83, 0xC5, 0xC5, 0x2A, 0x21,
        0x0E, 0x9C, 0x81, 0x2B, 0xC0, 0xC2, 0x32, 0x8C,
        0xA0, 0x0E, 0x78, 0x9A, 0x56, 0xB2, 0x60, 0x6B,
        0x90, 0x29, 0x2E, 0x35, 0x43, 0xDA, 0xCA, 0xA2,
        0x43, 0x18, 0x41, 0xD6, 0x1A, 0x22, 0xCA, 0x90,
        0xC1, 0xCC, 0xF0, 0xB5, 0xB4, 0xE0, 0xA6, 0xF6,
        0x40, 0x53, 0x6D, 0x1A, 0x26, 0xAB, 0x5B, 0x8D,
        0x21, 0x51, 0x32, 0x79, 0x28, 0xCE, 0x02, 0x90,
        0x4C, 0xF1, 0xD1, 0x5E, 0x32, 0x78, 0x8A, 0x95,
        0xF6, 0x2D, 0x3C, 0x27, 0x0B, 0x6F, 0xA1, 0x50,
        0x8F, 0x97, 0xB9, 0x15, 0x5A, 0x27, 0x26, 0xD8,
        0x0A, 0x1A, 0xFA, 0x3C, 0x53, 0x87, 0xA2, 0x76,
        0xA4, 0xD0, 0x31, 0xA0, 0x8A, 0xBF, 0x4F, 0x2E,
        0x74, 0xF1, 0xA0, 0xBB, 0x8A, 0x0F, 0xD3, 0xCB
    };
    static const byte seed_512[KYBER_ENC_RAND_SZ] = {
        0x6F, 0xF0, 0x2E, 0x1D, 0xC7, 0xFD, 0x91, 0x1B,
        0xEE, 0xE0, 0xC6, 0x92, 0xC8, 0xBD, 0x10, 0x0C,
        0x3E, 0x5C, 0x48, 0x96, 0x4D, 0x31, 0xDF, 0x92,
        0x99, 0x42, 0x18, 0xE8, 0x06, 0x64, 0xA6, 0xCA
    };
    static const byte c_512[KYBER512_CIPHER_TEXT_SIZE] = {
        0x19, 0xC5, 0x92, 0x50, 0x59, 0x07, 0xC2, 0x4C,
        0x5F, 0xA2, 0xEB, 0xFA, 0x93, 0x2D, 0x2C, 0xBB,
        0x48, 0xF3, 0xE4, 0x34, 0x0A, 0x28, 0xF7, 0xEB,
        0xA5, 0xD0, 0x68, 0xFC, 0xAC, 0xAB, 0xED, 0xF7,
        0x77, 0x84, 0xE2, 0xB2, 0x4D, 0x79, 0x61, 0x77,
        0x5F, 0x0B, 0xF1, 0xA9, 0x97, 0xAE, 0x8B, 0xA9,
        0xFC, 0x43, 0x11, 0xBE, 0x63, 0x71, 0x67, 0x79,
        0xC2, 0xB7, 0x88, 0xF8, 0x12, 0xCB, 0xB7, 0x8C,
        0x74, 0xE7, 0x51, 0x7E, 0x22, 0xE9, 0x10, 0xEF,
        0xF5, 0xF3, 0x8D, 0x44, 0x46, 0x9C, 0x50, 0xDE,
        0x16, 0x75, 0xAE, 0x19, 0x8F, 0xD6, 0xA2, 0x89,
        0xAE, 0x7E, 0x6C, 0x30, 0xA9, 0xD4, 0x35, 0x1B,
        0x3D, 0x1F, 0x4C, 0x36, 0xEF, 0xF9, 0xC6, 0x8D,
        0xA9, 0x1C, 0x40, 0xB8, 0x2D, 0xC9, 0xB2, 0x79,
        0x9A, 0x33, 0xA2, 0x6B, 0x60, 0xA4, 0xE7, 0x0D,
        0x71, 0x01, 0x86, 0x27, 0x79, 0x46, 0x9F, 0x3A,
        0x9D, 0xAE, 0xC8, 0xE3, 0xE8, 0xF8, 0xC6, 0xA1,
        0x6B, 0xF0, 0x92, 0xFB, 0xA5, 0x86, 0x61, 0x86,
        0xB8, 0xD2, 0x08, 0xFD, 0xEB, 0x27, 0x4A, 0xC1,
        0xF8, 0x29, 0x65, 0x9D, 0xC2, 0xBE, 0x4A, 0xC4,
        0xF3, 0x06, 0xCB, 0x55, 0x84, 0xBA, 0xD1, 0x93,
        0x6A, 0x92, 0xC9, 0xB7, 0x68, 0x19, 0x23, 0x42,
        0x81, 0xBB, 0x39, 0x58, 0x41, 0xC2, 0x57, 0x56,
        0x08, 0x6E, 0xA5, 0x64, 0xCA, 0x3E, 0x22, 0x7E,
        0x3D, 0x9F, 0x10, 0x52, 0xC0, 0x76, 0x6D, 0x2E,
        0xB7, 0x9A, 0x47, 0xC1, 0x50, 0x72, 0x1E, 0x0D,
        0xEA, 0x7C, 0x00, 0x69, 0xD5, 0x51, 0xB2, 0x64,
        0x80, 0x1B, 0x77, 0x27, 0xEC, 0xAF, 0x82, 0xEE,
        0xCB, 0x99, 0xA8, 0x76, 0xFD, 0xA0, 0x90, 0xBF,
        0x6C, 0x3F, 0xC6, 0xB1, 0x09, 0xF1, 0x70, 0x14,
        0x85, 0xF0, 0x3C, 0xE6, 0x62, 0x74, 0xB8, 0x43,
        0x5B, 0x0A, 0x01, 0x4C, 0xFB, 0x3E, 0x79, 0xCC,
        0xED, 0x67, 0x05, 0x7B, 0x5A, 0xE2, 0xAD, 0x7F,
        0x52, 0x79, 0xEB, 0x71, 0x49, 0x42, 0xE4, 0xC1,
        0xCC, 0xFF, 0x7E, 0x85, 0xC0, 0xDB, 0x43, 0xE5,
        0xD4, 0x12, 0x89, 0x20, 0x73, 0x63, 0xB4, 0x44,
        0xBB, 0x51, 0xBB, 0x8A, 0xB0, 0x37, 0x1E, 0x70,
        0xCB, 0xD5, 0x5F, 0x0F, 0x3D, 0xAD, 0x40, 0x3E,
        0x10, 0x51, 0x76, 0xE3, 0xE8, 0xA2, 0x25, 0xD8,
        0x4A, 0xC8, 0xBE, 0xE3, 0x8C, 0x82, 0x1E, 0xE0,
        0xF5, 0x47, 0x43, 0x11, 0x45, 0xDC, 0xB3, 0x13,
        0x92, 0x86, 0xAB, 0xB1, 0x17, 0x94, 0xA4, 0x3A,
        0x3C, 0x1B, 0x52, 0x29, 0xE4, 0xBC, 0xFE, 0x95,
        0x9C, 0x78, 0xAD, 0xAE, 0xE2, 0xD5, 0xF2, 0x49,
        0x7B, 0x5D, 0x24, 0xBC, 0x21, 0xFA, 0x03, 0xA9,
        0xA5, 0x8C, 0x24, 0x55, 0x37, 0x3E, 0xC8, 0x95,
        0x83, 0xE7, 0xE5, 0x88, 0xD7, 0xFE, 0x67, 0x99,
        0x1E, 0xE9, 0x37, 0x83, 0xED, 0x4A, 0x6F, 0x9E,
        0xEA, 0xE0, 0x4E, 0x64, 0xE2, 0xE1, 0xE0, 0xE6,
        0x99, 0xF6, 0xDC, 0x9C, 0x5D, 0x39, 0xEF, 0x92,
        0x78, 0xC9, 0x85, 0xE7, 0xFD, 0xF2, 0xA7, 0x64,
        0xFF, 0xD1, 0xA0, 0xB9, 0x57, 0x92, 0xAD, 0x68,
        0x1E, 0x93, 0x0D, 0x76, 0xDF, 0x4E, 0xFE, 0x5D,
        0x65, 0xDB, 0xBD, 0x0F, 0x14, 0x38, 0x48, 0x1E,
        0xD8, 0x33, 0xAD, 0x49, 0x46, 0xAD, 0x1C, 0x69,
        0xAD, 0x21, 0xDD, 0x7C, 0x86, 0x18, 0x57, 0x74,
        0x42, 0x6F, 0x3F, 0xCF, 0x53, 0xB5, 0x2A, 0xD4,
        0xB4, 0x0D, 0x22, 0x8C, 0xE1, 0x24, 0x07, 0x2F,
        0x59, 0x2C, 0x7D, 0xAA, 0x05, 0x7F, 0x17, 0xD7,
        0x90, 0xA5, 0xBD, 0x5B, 0x93, 0x83, 0x4D, 0x58,
        0xC0, 0x8C, 0x88, 0xDC, 0x8F, 0x0E, 0xF4, 0x88,
        0x15, 0x64, 0x25, 0xB7, 0x44, 0x65, 0x4E, 0xAC,
        0xA9, 0xD6, 0x48, 0x58, 0xA4, 0xD6, 0xCE, 0xB4,
        0x78, 0x79, 0x51, 0x94, 0xBF, 0xAD, 0xB1, 0x8D,
        0xC0, 0xEA, 0x05, 0x4F, 0x97, 0x71, 0x21, 0x5A,
        0xD3, 0xCB, 0x1F, 0xD0, 0x31, 0xD7, 0xBE, 0x45,
        0x98, 0x62, 0x19, 0x26, 0x47, 0x8D, 0x37, 0x5A,
        0x18, 0x45, 0xAA, 0x91, 0xD7, 0xC7, 0x33, 0xF8,
        0xF0, 0xE1, 0x88, 0xC8, 0x38, 0x96, 0xED, 0xF8,
        0x3B, 0x86, 0x46, 0xC9, 0x9E, 0x29, 0xC0, 0xDA,
        0x22, 0x90, 0xE7, 0x1C, 0x3D, 0x2E, 0x97, 0x07,
        0x20, 0xC9, 0x7B, 0x5B, 0x7F, 0x95, 0x04, 0x86,
        0x03, 0x3C, 0x6A, 0x25, 0x71, 0xDD, 0xF2, 0xBC,
        0xCD, 0xAB, 0xB2, 0xDF, 0xA5, 0xFC, 0xE4, 0xC3,
        0xA1, 0x88, 0x46, 0x06, 0x04, 0x1D, 0x18, 0x1C,
        0x72, 0x87, 0x94, 0xAE, 0x0E, 0x80, 0x6E, 0xCB,
        0x49, 0xAF, 0x16, 0x75, 0x6A, 0x4C, 0xE7, 0x3C,
        0x87, 0xBD, 0x42, 0x34, 0xE6, 0x0F, 0x05, 0x53,
        0x5F, 0xA5, 0x92, 0x9F, 0xD5, 0xA3, 0x44, 0x73,
        0x26, 0x64, 0x01, 0xF6, 0x3B, 0xBD, 0x6B, 0x90,
        0xE0, 0x03, 0x47, 0x2A, 0xC0, 0xCE, 0x88, 0xF1,
        0xB6, 0x66, 0x59, 0x72, 0x79, 0xD0, 0x56, 0xA6,
        0x32, 0xC8, 0xD6, 0xB7, 0x90, 0xFD, 0x41, 0x17,
        0x67, 0x84, 0x8A, 0x69, 0xE3, 0x7A, 0x8A, 0x83,
        0x9B, 0xC7, 0x66, 0xA0, 0x2C, 0xA2, 0xF6, 0x95,
        0xEC, 0x63, 0xF0, 0x56, 0xA4, 0xE2, 0xA1, 0x14,
        0xCA, 0xCF, 0x9F, 0xD9, 0x0D, 0x73, 0x0C, 0x97,
        0x0D, 0xB3, 0x87, 0xF6, 0xDE, 0x73, 0x39, 0x5F,
        0x70, 0x1A, 0x1D, 0x95, 0x3B, 0x2A, 0x89, 0xDD,
        0x7E, 0xDA, 0xD4, 0x39, 0xFC, 0x20, 0x5A, 0x54,
        0xA4, 0x81, 0xE8, 0x89, 0xB0, 0x98, 0xD5, 0x25,
        0x56, 0x70, 0xF0, 0x26, 0xB4, 0xA2, 0xBF, 0x02,
        0xD2, 0xBD, 0xDE, 0x87, 0xC7, 0x66, 0xB2, 0x5F,
        0xC5, 0xE0, 0xFD, 0x45, 0x37, 0x57, 0xE7, 0x56,
        0xD1, 0x8C, 0x8C, 0xD9, 0x12, 0xF9, 0xA7, 0x7F,
        0x8E, 0x6B, 0xF0, 0x20, 0x53, 0x74, 0xB4, 0x62
    };
    static const byte k_512[KYBER_SS_SZ] = {
        0x0B, 0xF3, 0x23, 0x33, 0x8D, 0x6F, 0x0A, 0x21,
        0xD5, 0x51, 0x4B, 0x67, 0x3C, 0xD1, 0x0B, 0x71,
        0x4C, 0xE6, 0xE3, 0x6F, 0x35, 0xBC, 0xD1, 0xBF,
        0x54, 0x41, 0x96, 0x36, 0x8E, 0xE5, 0x1A, 0x13
    };
#endif
#ifndef WOLFSSL_NO_KYBER768
    static const byte ek_768[KYBER768_PUBLIC_KEY_SIZE] = {
        0x89, 0xD2, 0xCB, 0x65, 0xF9, 0x4D, 0xCB, 0xFC,
        0x89, 0x0E, 0xFC, 0x7D, 0x0E, 0x5A, 0x7A, 0x38,
        0x34, 0x4D, 0x16, 0x41, 0xA3, 0xD0, 0xB0, 0x24,
        0xD5, 0x07, 0x97, 0xA5, 0xF2, 0x3C, 0x3A, 0x18,
        0xB3, 0x10, 0x1A, 0x12, 0x69, 0x06, 0x9F, 0x43,
        0xA8, 0x42, 0xBA, 0xCC, 0x09, 0x8A, 0x88, 0x21,
        0x27, 0x1C, 0x67, 0x3D, 0xB1, 0xBE, 0xB3, 0x30,
        0x34, 0xE4, 0xD7, 0x77, 0x4D, 0x16, 0x63, 0x5C,
        0x7C, 0x2C, 0x3C, 0x27, 0x63, 0x45, 0x35, 0x38,
        0xBC, 0x16, 0x32, 0xE1, 0x85, 0x15, 0x91, 0xA5,
        0x16, 0x42, 0x97, 0x4E, 0x59, 0x28, 0xAB, 0xB8,
        0xE5, 0x5F, 0xE5, 0x56, 0x12, 0xF9, 0xB1, 0x41,
        0xAF, 0xF0, 0x15, 0x54, 0x53, 0x94, 0xB2, 0x09,
        0x2E, 0x59, 0x09, 0x70, 0xEC, 0x29, 0xA7, 0xB7,
        0xE7, 0xAA, 0x1F, 0xB4, 0x49, 0x3B, 0xF7, 0xCB,
        0x73, 0x19, 0x06, 0xC2, 0xA5, 0xCB, 0x49, 0xE6,
        0x61, 0x48, 0x59, 0x06, 0x4E, 0x19, 0xB8, 0xFA,
        0x26, 0xAF, 0x51, 0xC4, 0x4B, 0x5E, 0x75, 0x35,
        0xBF, 0xDA, 0xC0, 0x72, 0xB6, 0x46, 0xD3, 0xEA,
        0x49, 0x0D, 0x27, 0x7F, 0x0D, 0x97, 0xCE, 0xD4,
        0x73, 0x95, 0xFE, 0xD9, 0x1E, 0x8F, 0x2B, 0xCE,
        0x0E, 0x3C, 0xA1, 0x22, 0xC2, 0x02, 0x5F, 0x74,
        0x06, 0x7A, 0xB9, 0x28, 0xA8, 0x22, 0xB3, 0x56,
        0x53, 0xA7, 0x4F, 0x06, 0x75, 0x76, 0x29, 0xAF,
        0xB1, 0xA1, 0xCA, 0xF2, 0x37, 0x10, 0x0E, 0xA9,
        0x35, 0xE7, 0x93, 0xC8, 0xF5, 0x8A, 0x71, 0xB3,
        0xD6, 0xAE, 0x2C, 0x86, 0x58, 0xB1, 0x01, 0x50,
        0xD4, 0xA3, 0x8F, 0x57, 0x2A, 0x0D, 0x49, 0xD2,
        0x8A, 0xE8, 0x94, 0x51, 0xD3, 0x38, 0x32, 0x6F,
        0xDB, 0x3B, 0x43, 0x50, 0x03, 0x6C, 0x10, 0x81,
        0x11, 0x77, 0x40, 0xED, 0xB8, 0x6B, 0x12, 0x08,
        0x1C, 0x5C, 0x12, 0x23, 0xDB, 0xB5, 0x66, 0x0D,
        0x5B, 0x3C, 0xB3, 0x78, 0x7D, 0x48, 0x18, 0x49,
        0x30, 0x4C, 0x68, 0xBE, 0x87, 0x54, 0x66, 0xF1,
        0x4E, 0xE5, 0x49, 0x5C, 0x2B, 0xD7, 0x95, 0xAE,
        0x41, 0x2D, 0x09, 0x00, 0x2D, 0x65, 0xB8, 0x71,
        0x9B, 0x90, 0xCB, 0xA3, 0x60, 0x3A, 0xC4, 0x95,
        0x8E, 0xA0, 0x3C, 0xC1, 0x38, 0xC8, 0x6F, 0x78,
        0x51, 0x59, 0x31, 0x25, 0x33, 0x47, 0x01, 0xB6,
        0x77, 0xF8, 0x2F, 0x49, 0x52, 0xA4, 0xC9, 0x3B,
        0x5B, 0x4C, 0x13, 0x4B, 0xB4, 0x2A, 0x85, 0x7F,
        0xD1, 0x5C, 0x65, 0x08, 0x64, 0xA6, 0xAA, 0x94,
        0xEB, 0x69, 0x1C, 0x0B, 0x69, 0x1B, 0xE4, 0x68,
        0x4C, 0x1F, 0x5B, 0x74, 0x90, 0x46, 0x7F, 0xC0,
        0x1B, 0x1D, 0x1F, 0xDA, 0x4D, 0xDA, 0x35, 0xC4,
        0xEC, 0xC2, 0x31, 0xBC, 0x73, 0xA6, 0xFE, 0xF4,
        0x2C, 0x99, 0xD3, 0x4E, 0xB8, 0x2A, 0x4D, 0x01,
        0x49, 0x87, 0xB3, 0xE3, 0x86, 0x91, 0x0C, 0x62,
        0x67, 0x9A, 0x11, 0x8F, 0x3C, 0x5B, 0xD9, 0xF4,
        0x67, 0xE4, 0x16, 0x20, 0x42, 0x42, 0x43, 0x57,
        0xDB, 0x92, 0xEF, 0x48, 0x4A, 0x4A, 0x17, 0x98,
        0xC1, 0x25, 0x7E, 0x87, 0x0A, 0x30, 0xCB, 0x20,
        0xAA, 0xA0, 0x33, 0x5D, 0x83, 0x31, 0x4F, 0xE0,
        0xAA, 0x7E, 0x63, 0xA8, 0x62, 0x64, 0x80, 0x41,
        0xA7, 0x2A, 0x63, 0x21, 0x52, 0x32, 0x20, 0xB1,
        0xAC, 0xE9, 0xBB, 0x70, 0x1B, 0x21, 0xAC, 0x12,
        0x53, 0xCB, 0x81, 0x2C, 0x15, 0x57, 0x5A, 0x90,
        0x85, 0xEA, 0xBE, 0xAD, 0xE7, 0x3A, 0x4A, 0xE7,
        0x6E, 0x6A, 0x7B, 0x15, 0x8A, 0x20, 0x58, 0x6D,
        0x78, 0xA5, 0xAC, 0x62, 0x0A, 0x5C, 0x9A, 0xBC,
        0xC9, 0xC0, 0x43, 0x35, 0x0A, 0x73, 0x65, 0x6B,
        0x0A, 0xBE, 0x82, 0x2D, 0xA5, 0xE0, 0xBA, 0x76,
        0x04, 0x5F, 0xAD, 0x75, 0x40, 0x1D, 0x7A, 0x3B,
        0x70, 0x37, 0x91, 0xB7, 0xE9, 0x92, 0x61, 0x71,
        0x0F, 0x86, 0xB7, 0x24, 0x21, 0xD2, 0x40, 0xA3,
        0x47, 0x63, 0x83, 0x77, 0x20, 0x5A, 0x15, 0x2C,
        0x79, 0x41, 0x30, 0xA4, 0xE0, 0x47, 0x74, 0x2B,
        0x88, 0x83, 0x03, 0xBD, 0xDC, 0x30, 0x91, 0x16,
        0x76, 0x4D, 0xE7, 0x42, 0x4C, 0xEB, 0xEA, 0x6D,
        0xB6, 0x53, 0x48, 0xAC, 0x53, 0x7E, 0x01, 0xA9,
        0xCC, 0x56, 0xEA, 0x66, 0x7D, 0x5A, 0xA8, 0x7A,
        0xC9, 0xAA, 0xA4, 0x31, 0x7D, 0x26, 0x2C, 0x10,
        0x14, 0x30, 0x50, 0xB8, 0xD0, 0x7A, 0x72, 0x8C,
        0xA6, 0x33, 0xC1, 0x3E, 0x46, 0x8A, 0xBC, 0xEA,
        0xD3, 0x72, 0xC7, 0x7B, 0x8E, 0xCF, 0x3B, 0x98,
        0x6B, 0x98, 0xC1, 0xE5, 0x58, 0x60, 0xB2, 0xB4,
        0x21, 0x67, 0x66, 0xAD, 0x87, 0x4C, 0x35, 0xED,
        0x72, 0x05, 0x06, 0x87, 0x39, 0x23, 0x02, 0x20,
        0xB5, 0xA2, 0x31, 0x7D, 0x10, 0x2C, 0x59, 0x83,
        0x56, 0xF1, 0x68, 0xAC, 0xBE, 0x80, 0x60, 0x8D,
        0xE4, 0xC9, 0xA7, 0x10, 0xB8, 0xDD, 0x07, 0x07,
        0x8C, 0xD7, 0xC6, 0x71, 0x05, 0x8A, 0xF1, 0xB0,
        0xB8, 0x30, 0x4A, 0x31, 0x4F, 0x7B, 0x29, 0xBE,
        0x78, 0xA9, 0x33, 0xC7, 0xB9, 0x29, 0x44, 0x24,
        0x95, 0x4A, 0x1B, 0xF8, 0xBC, 0x74, 0x5D, 0xE8,
        0x61, 0x98, 0x65, 0x9E, 0x0E, 0x12, 0x25, 0xA9,
        0x10, 0x72, 0x60, 0x74, 0x96, 0x9C, 0x39, 0xA9,
        0x7C, 0x19, 0x24, 0x06, 0x01, 0xA4, 0x6E, 0x01,
        0x3D, 0xCD, 0xCB, 0x67, 0x7A, 0x8C, 0xBD, 0x2C,
        0x95, 0xA4, 0x06, 0x29, 0xC2, 0x56, 0xF2, 0x4A,
        0x32, 0x89, 0x51, 0xDF, 0x57, 0x50, 0x2A, 0xB3,
        0x07, 0x72, 0xCC, 0x7E, 0x5B, 0x85, 0x00, 0x27,
        0xC8, 0x55, 0x17, 0x81, 0xCE, 0x49, 0x85, 0xBD,
        0xAC, 0xF6, 0xB8, 0x65, 0xC1, 0x04, 0xE8, 0xA4,
        0xBC, 0x65, 0xC4, 0x16, 0x94, 0xD4, 0x56, 0xB7,
        0x16, 0x9E, 0x45, 0xAB, 0x3D, 0x7A, 0xCA, 0xBE,
        0xAF, 0xE2, 0x3A, 0xD6, 0xA7, 0xB9, 0x4D, 0x19,
        0x79, 0xA2, 0xF4, 0xC1, 0xCA, 0xE7, 0xCD, 0x77,
        0xD6, 0x81, 0xD2, 0x90, 0xB5, 0xD8, 0xE4, 0x51,
        0xBF, 0xDC, 0xCC, 0xF5, 0x31, 0x0B, 0x9D, 0x12,
        0xA8, 0x8E, 0xC2, 0x9B, 0x10, 0x25, 0x5D, 0x5E,
        0x17, 0xA1, 0x92, 0x67, 0x0A, 0xA9, 0x73, 0x1C,
        0x5C, 0xA6, 0x7E, 0xC7, 0x84, 0xC5, 0x02, 0x78,
        0x1B, 0xE8, 0x52, 0x7D, 0x6F, 0xC0, 0x03, 0xC6,
        0x70, 0x1B, 0x36, 0x32, 0x28, 0x4B, 0x40, 0x30,
        0x7A, 0x52, 0x7C, 0x76, 0x20, 0x37, 0x7F, 0xEB,
        0x0B, 0x73, 0xF7, 0x22, 0xC9, 0xE3, 0xCD, 0x4D,
        0xEC, 0x64, 0x87, 0x6B, 0x93, 0xAB, 0x5B, 0x7C,
        0xFC, 0x4A, 0x65, 0x7F, 0x85, 0x2B, 0x65, 0x92,
        0x82, 0x86, 0x43, 0x84, 0xF4, 0x42, 0xB2, 0x2E,
        0x8A, 0x21, 0x10, 0x93, 0x87, 0xB8, 0xB4, 0x75,
        0x85, 0xFC, 0x68, 0x0D, 0x0B, 0xA4, 0x5C, 0x7A,
        0x8B, 0x1D, 0x72, 0x74, 0xBD, 0xA5, 0x78, 0x45,
        0xD1, 0x00, 0xD0, 0xF4, 0x2A, 0x3B, 0x74, 0x62,
        0x87, 0x73, 0x35, 0x1F, 0xD7, 0xAC, 0x30, 0x5B,
        0x24, 0x97, 0x63, 0x9B, 0xE9, 0x0B, 0x3F, 0x4F,
        0x71, 0xA6, 0xAA, 0x35, 0x61, 0xEE, 0xCC, 0x6A,
        0x69, 0x1B, 0xB5, 0xCB, 0x39, 0x14, 0xD8, 0x63,
        0x4C, 0xA1, 0xE1, 0xAF, 0x54, 0x3C, 0x04, 0x9A,
        0x8C, 0x6E, 0x86, 0x8C, 0x51, 0xF0, 0x42, 0x3B,
        0xD2, 0xD5, 0xAE, 0x09, 0xB7, 0x9E, 0x57, 0xC2,
        0x7F, 0x3F, 0xE3, 0xAE, 0x2B, 0x26, 0xA4, 0x41,
        0xBA, 0xBF, 0xC6, 0x71, 0x8C, 0xE8, 0xC0, 0x5B,
        0x4F, 0xE7, 0x93, 0xB9, 0x10, 0xB8, 0xFB, 0xCB,
        0xBE, 0x7F, 0x10, 0x13, 0x24, 0x2B, 0x40, 0xE0,
        0x51, 0x4D, 0x0B, 0xDC, 0x5C, 0x88, 0xBA, 0xC5,
        0x94, 0xC7, 0x94, 0xCE, 0x51, 0x22, 0xFB, 0xF3,
        0x48, 0x96, 0x81, 0x91, 0x47, 0xB9, 0x28, 0x38,
        0x15, 0x87, 0x96, 0x3B, 0x0B, 0x90, 0x03, 0x4A,
        0xA0, 0x7A, 0x10, 0xBE, 0x17, 0x6E, 0x01, 0xC8,
        0x0A, 0xD6, 0xA4, 0xB7, 0x1B, 0x10, 0xAF, 0x42,
        0x41, 0x40, 0x0A, 0x2A, 0x4C, 0xBB, 0xC0, 0x59,
        0x61, 0xA1, 0x5E, 0xC1, 0x47, 0x4E, 0xD5, 0x1A,
        0x3C, 0xC6, 0xD3, 0x58, 0x00, 0x67, 0x9A, 0x46,
        0x28, 0x09, 0xCA, 0xA3, 0xAB, 0x4F, 0x70, 0x94,
        0xCD, 0x66, 0x10, 0xB4, 0xA7, 0x00, 0xCB, 0xA9,
        0x39, 0xE7, 0xEA, 0xC9, 0x3E, 0x38, 0xC9, 0x97,
        0x55, 0x90, 0x87, 0x27, 0x61, 0x9E, 0xD7, 0x6A,
        0x34, 0xE5, 0x3C, 0x4F, 0xA2, 0x5B, 0xFC, 0x97,
        0x00, 0x82, 0x06, 0x69, 0x7D, 0xD1, 0x45, 0xE5,
        0xB9, 0x18, 0x8E, 0x5B, 0x01, 0x4E, 0x94, 0x16,
        0x81, 0xE1, 0x5F, 0xE3, 0xE1, 0x32, 0xB8, 0xA3,
        0x90, 0x34, 0x74, 0x14, 0x8B, 0xA2, 0x8B, 0x98,
        0x71, 0x11, 0xC9, 0xBC, 0xB3, 0x98, 0x9B, 0xBB,
        0xC6, 0x71, 0xC5, 0x81, 0xB4, 0x4A, 0x49, 0x28,
        0x45, 0xF2, 0x88, 0xE6, 0x21, 0x96, 0xE4, 0x71,
        0xFE, 0xD3, 0xC3, 0x9C, 0x1B, 0xBD, 0xDB, 0x08,
        0x37, 0xD0, 0xD4, 0x70, 0x6B, 0x09, 0x22, 0xC4
    };
    static const byte seed_768[KYBER_ENC_RAND_SZ] = {
        0x2C, 0xE7, 0x4A, 0xD2, 0x91, 0x13, 0x35, 0x18,
        0xFE, 0x60, 0xC7, 0xDF, 0x5D, 0x25, 0x1B, 0x9D,
        0x82, 0xAD, 0xD4, 0x84, 0x62, 0xFF, 0x50, 0x5C,
        0x6E, 0x54, 0x7E, 0x94, 0x9E, 0x6B, 0x6B, 0xF7
    };
    static const byte c_768[KYBER768_CIPHER_TEXT_SIZE] = {
        0x56, 0xB4, 0x2D, 0x59, 0x3A, 0xAB, 0x8E, 0x87,
        0x73, 0xBD, 0x92, 0xD7, 0x6E, 0xAB, 0xDD, 0xF3,
        0xB1, 0x54, 0x6F, 0x83, 0x26, 0xF5, 0x7A, 0x7B,
        0x77, 0x37, 0x64, 0xB6, 0xC0, 0xDD, 0x30, 0x47,
        0x0F, 0x68, 0xDF, 0xF8, 0x2E, 0x0D, 0xCA, 0x92,
        0x50, 0x92, 0x74, 0xEC, 0xFE, 0x83, 0xA9, 0x54,
        0x73, 0x5F, 0xDE, 0x6E, 0x14, 0x67, 0x6D, 0xAA,
        0xA3, 0x68, 0x0C, 0x30, 0xD5, 0x24, 0xF4, 0xEF,
        0xA7, 0x9E, 0xD6, 0xA1, 0xF9, 0xED, 0x7E, 0x1C,
        0x00, 0x56, 0x0E, 0x86, 0x83, 0x53, 0x8C, 0x31,
        0x05, 0xAB, 0x93, 0x1B, 0xE0, 0xD2, 0xB2, 0x49,
        0xB3, 0x8C, 0xB9, 0xB1, 0x3A, 0xF5, 0xCE, 0xAF,
        0x78, 0x87, 0xA5, 0x9D, 0xBA, 0x16, 0x68, 0x8A,
        0x7F, 0x28, 0xDE, 0x0B, 0x14, 0xD1, 0x9F, 0x39,
        0x1E, 0xB4, 0x18, 0x32, 0xA5, 0x64, 0x79, 0x41,
        0x6C, 0xCF, 0x94, 0xE9, 0x97, 0x39, 0x0E, 0xD7,
        0x87, 0x8E, 0xEA, 0xFF, 0x49, 0x32, 0x8A, 0x70,
        0xE0, 0xAB, 0x5F, 0xCE, 0x6C, 0x63, 0xC0, 0x9B,
        0x35, 0xF4, 0xE4, 0x59, 0x94, 0xDE, 0x61, 0x5B,
        0x88, 0xBB, 0x72, 0x2F, 0x70, 0xE8, 0x7D, 0x2B,
        0xBD, 0x72, 0xAE, 0x71, 0xE1, 0xEE, 0x90, 0x08,
        0xE4, 0x59, 0xD8, 0xE7, 0x43, 0x03, 0x9A, 0x8D,
        0xDE, 0xB8, 0x74, 0xFC, 0xE5, 0x30, 0x1A, 0x2F,
        0x8C, 0x0E, 0xE8, 0xC2, 0xFE, 0xE7, 0xA4, 0xEE,
        0x68, 0xB5, 0xED, 0x6A, 0x6D, 0x9A, 0xB7, 0x4F,
        0x98, 0xBB, 0x3B, 0xA0, 0xFE, 0x89, 0xE8, 0x2B,
        0xD5, 0xA5, 0x25, 0xC5, 0xE8, 0x79, 0x0F, 0x81,
        0x8C, 0xCC, 0x60, 0x58, 0x77, 0xD4, 0x6C, 0x8B,
        0xDB, 0x5C, 0x33, 0x7B, 0x02, 0x5B, 0xB8, 0x40,
        0xFF, 0x47, 0x18, 0x96, 0xE4, 0x3B, 0xFA, 0x99,
        0xD7, 0x3D, 0xBE, 0x31, 0x80, 0x5C, 0x27, 0xA4,
        0x3E, 0x57, 0xF0, 0x61, 0x8B, 0x3A, 0xE5, 0x22,
        0xA4, 0x64, 0x4E, 0x0D, 0x4E, 0x4C, 0x1C, 0x54,
        0x84, 0x89, 0x43, 0x1B, 0xE5, 0x58, 0xF3, 0xBF,
        0xC5, 0x0E, 0x16, 0x61, 0x7E, 0x11, 0x0D, 0xD7,
        0xAF, 0x9A, 0x6F, 0xD8, 0x3E, 0x3F, 0xBB, 0x68,
        0xC3, 0x04, 0xD1, 0x5F, 0x6C, 0xB7, 0x00, 0xD6,
        0x1D, 0x7A, 0xA9, 0x15, 0xA6, 0x75, 0x1E, 0xA3,
        0xBA, 0x80, 0x22, 0x3E, 0x65, 0x41, 0x32, 0xA2,
        0x09, 0x99, 0xA4, 0x3B, 0xF4, 0x08, 0x59, 0x27,
        0x30, 0xB9, 0xA9, 0x49, 0x96, 0x36, 0xC0, 0x9F,
        0xA7, 0x29, 0xF9, 0xCB, 0x1F, 0x9D, 0x34, 0x42,
        0xF4, 0x73, 0x57, 0xA2, 0xB9, 0xCF, 0x15, 0xD3,
        0x10, 0x3B, 0x9B, 0xF3, 0x96, 0xC2, 0x30, 0x88,
        0xF1, 0x18, 0xED, 0xE3, 0x46, 0xB5, 0xC0, 0x38,
        0x91, 0xCF, 0xA5, 0xD5, 0x17, 0xCE, 0xF8, 0x47,
        0x13, 0x22, 0xE7, 0xE3, 0x10, 0x87, 0xC4, 0xB0,
        0x36, 0xAB, 0xAD, 0x78, 0x4B, 0xFF, 0x72, 0xA9,
        0xB1, 0x1F, 0xA1, 0x98, 0xFA, 0xCB, 0xCB, 0x91,
        0xF0, 0x67, 0xFE, 0xAF, 0x76, 0xFC, 0xFE, 0x53,
        0x27, 0xC1, 0x07, 0x0B, 0x3D, 0xA6, 0x98, 0x84,
        0x00, 0x75, 0x67, 0x60, 0xD2, 0xD1, 0xF0, 0x60,
        0x29, 0x8F, 0x16, 0x83, 0xD5, 0x1E, 0x36, 0x16,
        0xE9, 0x8C, 0x51, 0xC9, 0xC0, 0x3A, 0xA4, 0x2F,
        0x2E, 0x63, 0x36, 0x51, 0xA4, 0x7A, 0xD3, 0xCC,
        0x2A, 0xB4, 0xA8, 0x52, 0xAE, 0x0C, 0x4B, 0x04,
        0xB4, 0xE1, 0xC3, 0xDD, 0x94, 0x44, 0x45, 0xA2,
        0xB1, 0x2B, 0x4F, 0x42, 0xA6, 0x43, 0x51, 0x05,
        0xC0, 0x41, 0x22, 0xFC, 0x35, 0x87, 0xAF, 0xE4,
        0x09, 0xA0, 0x0B, 0x30, 0x8D, 0x63, 0xC5, 0xDD,
        0x81, 0x63, 0x65, 0x45, 0x04, 0xEE, 0xDB, 0xB7,
        0xB5, 0x32, 0x95, 0x77, 0xC3, 0x5F, 0xBE, 0xB3,
        0xF4, 0x63, 0x87, 0x2C, 0xAC, 0x28, 0x14, 0x2B,
        0x3C, 0x12, 0xA7, 0x40, 0xEC, 0x6E, 0xA7, 0xCE,
        0x9A, 0xD7, 0x8C, 0x6F, 0xC8, 0xFE, 0x1B, 0x4D,
        0xF5, 0xFC, 0x55, 0xC1, 0x66, 0x7F, 0x31, 0xF2,
        0x31, 0x2D, 0xA0, 0x77, 0x99, 0xDC, 0x87, 0x0A,
        0x47, 0x86, 0x08, 0x54, 0x9F, 0xED, 0xAF, 0xE0,
        0x21, 0xF1, 0xCF, 0x29, 0x84, 0x18, 0x03, 0x64,
        0xE9, 0x0A, 0xD9, 0x8D, 0x84, 0x56, 0x52, 0xAA,
        0x3C, 0xDD, 0x7A, 0x8E, 0xB0, 0x9F, 0x5E, 0x51,
        0x42, 0x3F, 0xAB, 0x42, 0xA7, 0xB7, 0xBB, 0x4D,
        0x51, 0x48, 0x64, 0xBE, 0x8D, 0x71, 0x29, 0x7E,
        0x9C, 0x3B, 0x17, 0xA9, 0x93, 0xF0, 0xAE, 0x62,
        0xE8, 0xEF, 0x52, 0x63, 0x7B, 0xD1, 0xB8, 0x85,
        0xBD, 0x9B, 0x6A, 0xB7, 0x27, 0x85, 0x4D, 0x70,
        0x3D, 0x8D, 0xC4, 0x78, 0xF9, 0x6C, 0xB8, 0x1F,
        0xCE, 0x4C, 0x60, 0x38, 0x3A, 0xC0, 0x1F, 0xCF,
        0x0F, 0x97, 0x1D, 0x4C, 0x8F, 0x35, 0x2B, 0x7A,
        0x82, 0xE2, 0x18, 0x65, 0x2F, 0x2C, 0x10, 0x6C,
        0xA9, 0x2A, 0xE6, 0x86, 0xBA, 0xCF, 0xCE, 0xF5,
        0xD3, 0x27, 0x34, 0x7A, 0x97, 0xA9, 0xB3, 0x75,
        0xD6, 0x73, 0x41, 0x55, 0x2B, 0xC2, 0xC5, 0x38,
        0x77, 0x8E, 0x0F, 0x98, 0x01, 0x82, 0x3C, 0xCD,
        0xFC, 0xD1, 0xEA, 0xAD, 0xED, 0x55, 0xB1, 0x8C,
        0x97, 0x57, 0xE3, 0xF2, 0x12, 0xB2, 0x88, 0x9D,
        0x38, 0x57, 0xDB, 0x51, 0xF9, 0x81, 0xD1, 0x61,
        0x85, 0xFD, 0x0F, 0x90, 0x08, 0x53, 0xA7, 0x50,
        0x05, 0xE3, 0x02, 0x0A, 0x8B, 0x95, 0xB7, 0xD8,
        0xF2, 0xF2, 0x63, 0x1C, 0x70, 0xD7, 0x8A, 0x95,
        0x7C, 0x7A, 0x62, 0xE1, 0xB3, 0x71, 0x90, 0x70,
        0xAC, 0xD1, 0xFD, 0x48, 0x0C, 0x25, 0xB8, 0x38,
        0x47, 0xDA, 0x02, 0x7B, 0x6E, 0xBB, 0xC2, 0xEE,
        0xC2, 0xDF, 0x22, 0xC8, 0x7F, 0x9B, 0x46, 0xD5,
        0xD7, 0xBA, 0xF1, 0x56, 0xB5, 0x3C, 0xEE, 0x92,
        0x95, 0x72, 0xB9, 0x2C, 0x47, 0x84, 0xC4, 0xE8,
        0x29, 0xF3, 0x44, 0x6A, 0x1F, 0xFE, 0x47, 0xF9,
        0x9D, 0xEC, 0xD0, 0x43, 0x60, 0x29, 0xDD, 0xEB,
        0xD3, 0xED, 0x8E, 0x87, 0xE5, 0xE7, 0x3D, 0x12,
        0x3D, 0xBE, 0x8A, 0x4D, 0xDA, 0xCF, 0x2A, 0xBD,
        0xE8, 0x7F, 0x33, 0xAE, 0x2B, 0x62, 0x1C, 0x0E,
        0xC5, 0xD5, 0xCA, 0xD1, 0x25, 0x9D, 0xEE, 0xC2,
        0xAE, 0xFF, 0x60, 0x88, 0xF0, 0x4F, 0x27, 0xA2,
        0x03, 0x38, 0xB5, 0x76, 0x25, 0x43, 0xE5, 0x10,
        0x08, 0x99, 0xA4, 0xCB, 0xFB, 0x7B, 0x3C, 0xA4,
        0x56, 0xB3, 0xA1, 0x9B, 0x83, 0xA4, 0xC4, 0x32,
        0x23, 0x0C, 0x23, 0xE1, 0xC7, 0xF1, 0x07, 0xC4,
        0xCB, 0x11, 0x21, 0x52, 0xF1, 0xC0, 0xF3, 0x0D,
        0xA0, 0xBB, 0x33, 0xF4, 0xF1, 0x1F, 0x47, 0xEE,
        0xA4, 0x38, 0x72, 0xBA, 0xFA, 0x84, 0xAE, 0x22,
        0x25, 0x6D, 0x70, 0x8E, 0x06, 0x04, 0xDA, 0xDE,
        0x4B, 0x2A, 0x4D, 0xDE, 0x8C, 0xCC, 0xF1, 0x19,
        0x30, 0xE1, 0x35, 0x53, 0x93, 0x4A, 0xE3, 0xEC,
        0xE5, 0x2F, 0x3D, 0x7C, 0xCC, 0x00, 0x28, 0x73,
        0x77, 0x87, 0x9F, 0xE6, 0xB8, 0xEC, 0xE7, 0xEF,
        0x79, 0x42, 0x35, 0x07, 0xC9, 0xDA, 0x33, 0x95,
        0x59, 0xC2, 0x0D, 0xE1, 0xC5, 0x19, 0x55, 0x99,
        0x9B, 0xAE, 0x47, 0x40, 0x1D, 0xC3, 0xCD, 0xFA,
        0xA1, 0xB2, 0x56, 0xD0, 0x9C, 0x7D, 0xB9, 0xFC,
        0x86, 0x98, 0xBF, 0xCE, 0xFA, 0x73, 0x02, 0xD5,
        0x6F, 0xBC, 0xDE, 0x1F, 0xBA, 0xAA, 0x1C, 0x65,
        0x34, 0x54, 0xE6, 0xFD, 0x3D, 0x84, 0xE4, 0xF7,
        0x9A, 0x93, 0x1C, 0x68, 0x1C, 0xBB, 0x6C, 0xB4,
        0x62, 0xB1, 0x0D, 0xAE, 0x11, 0x2B, 0xDF, 0xB7,
        0xF6, 0x5C, 0x7F, 0xDF, 0x6E, 0x5F, 0xC5, 0x94,
        0xEC, 0x3A, 0x47, 0x4A, 0x94, 0xBD, 0x97, 0xE6,
        0xEC, 0x81, 0xF7, 0x1C, 0x23, 0x0B, 0xF7, 0x0C,
        0xA0, 0xF1, 0x3C, 0xE3, 0xDF, 0xFB, 0xD9, 0xFF,
        0x98, 0x04, 0xEF, 0xD8, 0xF3, 0x7A, 0x4D, 0x36,
        0x29, 0xB4, 0x3A, 0x8F, 0x55, 0x54, 0x4E, 0xBC,
        0x5A, 0xC0, 0xAB, 0xD9, 0xA3, 0x3D, 0x79, 0x69,
        0x90, 0x68, 0x34, 0x6A, 0x0F, 0x1A, 0x3A, 0x96,
        0xE1, 0x15, 0xA5, 0xD8, 0x0B, 0xE1, 0x65, 0xB5,
        0x62, 0xD0, 0x82, 0x98, 0x4D, 0x5A, 0xAC, 0xC3,
        0xA2, 0x30, 0x19, 0x81, 0xA6, 0x41, 0x8F, 0x8B,
        0xA7, 0xD7, 0xB0, 0xD7, 0xCA, 0x58, 0x75, 0xC6
    };
    static const byte k_768[KYBER_SS_SZ] = {
        0x26, 0x96, 0xD2, 0x8E, 0x9C, 0x61, 0xC2, 0xA0,
        0x1C, 0xE9, 0xB1, 0x60, 0x8D, 0xCB, 0x9D, 0x29,
        0x27, 0x85, 0xA0, 0xCD, 0x58, 0xEF, 0xB7, 0xFE,
        0x13, 0xB1, 0xDE, 0x95, 0xF0, 0xDB, 0x55, 0xB3
    };
#endif
#ifndef WOLFSSL_NO_KYBER1024
    static const byte ek_1024[KYBER1024_PUBLIC_KEY_SIZE] = {
        0x30, 0x7A, 0x4C, 0xEA, 0x41, 0x48, 0x21, 0x9B,
        0x95, 0x8E, 0xA0, 0xB7, 0x88, 0x66, 0x59, 0x23,
        0x5A, 0x4D, 0x19, 0x80, 0xB1, 0x92, 0x61, 0x08,
        0x47, 0xD8, 0x6E, 0xF3, 0x27, 0x39, 0xF9, 0x4C,
        0x3B, 0x44, 0x6C, 0x4D, 0x81, 0xD8, 0x9B, 0x8B,
        0x42, 0x2A, 0x9D, 0x07, 0x9C, 0x88, 0xB1, 0x1A,
        0xCA, 0xF3, 0x21, 0xB0, 0x14, 0x29, 0x4E, 0x18,
        0xB2, 0x96, 0xE5, 0x2F, 0x3F, 0x74, 0x4C, 0xF9,
        0x63, 0x4A, 0x4F, 0xB0, 0x1D, 0xB0, 0xD9, 0x9E,
        0xF2, 0x0A, 0x63, 0x3A, 0x55, 0x2E, 0x76, 0xA0,
        0x58, 0x5C, 0x61, 0x09, 0xF0, 0x18, 0x76, 0x8B,
        0x76, 0x3A, 0xF3, 0x67, 0x8B, 0x47, 0x80, 0x08,
        0x9C, 0x13, 0x42, 0xB9, 0x69, 0x07, 0xA2, 0x9A,
        0x1C, 0x11, 0x52, 0x1C, 0x74, 0x4C, 0x27, 0x97,
        0xD0, 0xBF, 0x2B, 0x9C, 0xCD, 0xCA, 0x61, 0x46,
        0x72, 0xB4, 0x50, 0x76, 0x77, 0x3F, 0x45, 0x8A,
        0x31, 0xEF, 0x86, 0x9B, 0xE1, 0xEB, 0x2E, 0xFE,
        0xB5, 0x0D, 0x0E, 0x37, 0x49, 0x5D, 0xC5, 0xCA,
        0x55, 0xE0, 0x75, 0x28, 0x93, 0x4F, 0x62, 0x93,
        0xC4, 0x16, 0x80, 0x27, 0xD0, 0xE5, 0x3D, 0x07,
        0xFA, 0xCC, 0x66, 0x30, 0xCB, 0x08, 0x19, 0x7E,
        0x53, 0xFB, 0x19, 0x3A, 0x17, 0x11, 0x35, 0xDC,
        0x8A, 0xD9, 0x97, 0x94, 0x02, 0xA7, 0x1B, 0x69,
        0x26, 0xBC, 0xDC, 0xDC, 0x47, 0xB9, 0x34, 0x01,
        0x91, 0x0A, 0x5F, 0xCC, 0x1A, 0x81, 0x3B, 0x68,
        0x2B, 0x09, 0xBA, 0x7A, 0x72, 0xD2, 0x48, 0x6D,
        0x6C, 0x79, 0x95, 0x16, 0x46, 0x5C, 0x14, 0x72,
        0x9B, 0x26, 0x94, 0x9B, 0x0B, 0x7C, 0xBC, 0x7C,
        0x64, 0x0F, 0x26, 0x7F, 0xED, 0x80, 0xB1, 0x62,
        0xC5, 0x1F, 0xD8, 0xE0, 0x92, 0x27, 0xC1, 0x01,
        0xD5, 0x05, 0xA8, 0xFA, 0xE8, 0xA2, 0xD7, 0x05,
        0x4E, 0x28, 0xA7, 0x8B, 0xA8, 0x75, 0x0D, 0xEC,
        0xF9, 0x05, 0x7C, 0x83, 0x97, 0x9F, 0x7A, 0xBB,
        0x08, 0x49, 0x45, 0x64, 0x80, 0x06, 0xC5, 0xB2,
        0x88, 0x04, 0xF3, 0x4E, 0x73, 0xB2, 0x38, 0x11,
        0x1A, 0x65, 0xA1, 0xF5, 0x00, 0xB1, 0xCC, 0x60,
        0x6A, 0x84, 0x8F, 0x28, 0x59, 0x07, 0x0B, 0xEB,
        0xA7, 0x57, 0x31, 0x79, 0xF3, 0x61, 0x49, 0xCF,
        0x58, 0x01, 0xBF, 0x89, 0xA1, 0xC3, 0x8C, 0xC2,
        0x78, 0x41, 0x55, 0x28, 0xD0, 0x3B, 0xDB, 0x94,
        0x3F, 0x96, 0x28, 0x0C, 0x8C, 0xC5, 0x20, 0x42,
        0xD9, 0xB9, 0x1F, 0xAA, 0x9D, 0x6E, 0xA7, 0xBC,
        0xBB, 0x7A, 0xB1, 0x89, 0x7A, 0x32, 0x66, 0x96,
        0x6F, 0x78, 0x39, 0x34, 0x26, 0xC7, 0x6D, 0x8A,
        0x49, 0x57, 0x8B, 0x98, 0xB1, 0x59, 0xEB, 0xB4,
        0x6E, 0xE0, 0xA8, 0x83, 0xA2, 0x70, 0xD8, 0x05,
        0x7C, 0xD0, 0x23, 0x1C, 0x86, 0x90, 0x6A, 0x91,
        0xDB, 0xBA, 0xDE, 0x6B, 0x24, 0x69, 0x58, 0x1E,
        0x2B, 0xCA, 0x2F, 0xEA, 0x83, 0x89, 0xF7, 0xC7,
        0x4B, 0xCD, 0x70, 0x96, 0x1E, 0xA5, 0xB9, 0x34,
        0xFB, 0xCF, 0x9A, 0x65, 0x90, 0xBF, 0x86, 0xB8,
        0xDB, 0x54, 0x88, 0x54, 0xD9, 0xA3, 0xFB, 0x30,
        0x11, 0x04, 0x33, 0xBD, 0x7A, 0x1B, 0x65, 0x9C,
        0xA8, 0x56, 0x80, 0x85, 0x63, 0x92, 0x37, 0xB3,
        0xBD, 0xC3, 0x7B, 0x7F, 0xA7, 0x16, 0xD4, 0x82,
        0xA2, 0x5B, 0x54, 0x10, 0x6B, 0x3A, 0x8F, 0x54,
        0xD3, 0xAA, 0x99, 0xB5, 0x12, 0x3D, 0xA9, 0x60,
        0x66, 0x90, 0x45, 0x92, 0xF3, 0xA5, 0x4E, 0xE2,
        0x3A, 0x79, 0x81, 0xAB, 0x60, 0x8A, 0x2F, 0x44,
        0x13, 0xCC, 0x65, 0x89, 0x46, 0xC6, 0xD7, 0x78,
        0x0E, 0xA7, 0x65, 0x64, 0x4B, 0x3C, 0xC0, 0x6C,
        0x70, 0x03, 0x4A, 0xB4, 0xEB, 0x35, 0x19, 0x12,
        0xE7, 0x71, 0x5B, 0x56, 0x75, 0x5D, 0x09, 0x02,
        0x15, 0x71, 0xBF, 0x34, 0x0A, 0xB9, 0x25, 0x98,
        0xA2, 0x4E, 0x81, 0x18, 0x93, 0x19, 0x5B, 0x96,
        0xA1, 0x62, 0x9F, 0x80, 0x41, 0xF5, 0x86, 0x58,
        0x43, 0x15, 0x61, 0xFC, 0x0A, 0xB1, 0x52, 0x92,
        0xB9, 0x13, 0xEC, 0x47, 0x3F, 0x04, 0x47, 0x9B,
        0xC1, 0x45, 0xCD, 0x4C, 0x56, 0x3A, 0x28, 0x62,
        0x35, 0x64, 0x6C, 0xD3, 0x05, 0xA9, 0xBE, 0x10,
        0x14, 0xE2, 0xC7, 0xB1, 0x30, 0xC3, 0x3E, 0xB7,
        0x7C, 0xC4, 0xA0, 0xD9, 0x78, 0x6B, 0xD6, 0xBC,
        0x2A, 0x95, 0x4B, 0xF3, 0x00, 0x57, 0x78, 0xF8,
        0x91, 0x7C, 0xE1, 0x37, 0x89, 0xBB, 0xB9, 0x62,
        0x80, 0x78, 0x58, 0xB6, 0x77, 0x31, 0x57, 0x2B,
        0x6D, 0x3C, 0x9B, 0x4B, 0x52, 0x06, 0xFA, 0xC9,
        0xA7, 0xC8, 0x96, 0x16, 0x98, 0xD8, 0x83, 0x24,
        0xA9, 0x15, 0x18, 0x68, 0x99, 0xB2, 0x99, 0x23,
        0xF0, 0x84, 0x42, 0xA3, 0xD3, 0x86, 0xBD, 0x41,
        0x6B, 0xCC, 0x9A, 0x10, 0x01, 0x64, 0xC9, 0x30,
        0xEC, 0x35, 0xEA, 0xFB, 0x6A, 0xB3, 0x58, 0x51,
        0xB6, 0xC8, 0xCE, 0x63, 0x77, 0x36, 0x6A, 0x17,
        0x5F, 0x3D, 0x75, 0x29, 0x8C, 0x51, 0x8D, 0x44,
        0x89, 0x89, 0x33, 0xF5, 0x3D, 0xEE, 0x61, 0x71,
        0x45, 0x09, 0x33, 0x79, 0xC4, 0x65, 0x9F, 0x68,
        0x58, 0x3B, 0x2B, 0x28, 0x12, 0x26, 0x66, 0xBE,
        0xC5, 0x78, 0x38, 0x99, 0x1F, 0xF1, 0x6C, 0x36,
        0x8D, 0xD2, 0x2C, 0x36, 0xE7, 0x80, 0xC9, 0x1A,
        0x35, 0x82, 0xE2, 0x5E, 0x19, 0x79, 0x4C, 0x6B,
        0xF2, 0xAB, 0x42, 0x45, 0x8A, 0x8D, 0xD7, 0x70,
        0x5D, 0xE2, 0xC2, 0xAA, 0x20, 0xC0, 0x54, 0xE8,
        0x4B, 0x3E, 0xF3, 0x50, 0x32, 0x79, 0x86, 0x26,
        0xC2, 0x48, 0x26, 0x32, 0x53, 0xA7, 0x1A, 0x11,
        0x94, 0x35, 0x71, 0x34, 0x0A, 0x97, 0x8C, 0xD0,
        0xA6, 0x02, 0xE4, 0x7D, 0xEE, 0x54, 0x0A, 0x88,
        0x14, 0xBA, 0x06, 0xF3, 0x14, 0x14, 0x79, 0x7C,
        0xDF, 0x60, 0x49, 0x58, 0x23, 0x61, 0xBB, 0xAB,
        0xA3, 0x87, 0xA8, 0x3D, 0x89, 0x91, 0x3F, 0xE4,
        0xC0, 0xC1, 0x12, 0xB9, 0x56, 0x21, 0xA4, 0xBD,
        0xA8, 0x12, 0x3A, 0x14, 0xD1, 0xA8, 0x42, 0xFB,
        0x57, 0xB8, 0x3A, 0x4F, 0xBA, 0xF3, 0x3A, 0x8E,
        0x55, 0x22, 0x38, 0xA5, 0x96, 0xAA, 0xE7, 0xA1,
        0x50, 0xD7, 0x5D, 0xA6, 0x48, 0xBC, 0x44, 0x64,
        0x49, 0x77, 0xBA, 0x1F, 0x87, 0xA4, 0xC6, 0x8A,
        0x8C, 0x4B, 0xD2, 0x45, 0xB7, 0xD0, 0x07, 0x21,
        0xF7, 0xD6, 0x4E, 0x82, 0x2B, 0x08, 0x5B, 0x90,
        0x13, 0x12, 0xEC, 0x37, 0xA8, 0x16, 0x98, 0x02,
        0x16, 0x0C, 0xCE, 0x11, 0x60, 0xF0, 0x10, 0xBE,
        0x8C, 0xBC, 0xAC, 0xE8, 0xE7, 0xB0, 0x05, 0xD7,
        0x83, 0x92, 0x34, 0xA7, 0x07, 0x86, 0x83, 0x09,
        0xD0, 0x37, 0x84, 0xB4, 0x27, 0x3B, 0x1C, 0x8A,
        0x16, 0x01, 0x33, 0xED, 0x29, 0x81, 0x84, 0x70,
        0x46, 0x25, 0xF2, 0x9C, 0xFA, 0x08, 0x6D, 0x13,
        0x26, 0x3E, 0xE5, 0x89, 0x91, 0x23, 0xC5, 0x96,
        0xBA, 0x78, 0x8E, 0x5C, 0x54, 0xA8, 0xE9, 0xBA,
        0x82, 0x9B, 0x8A, 0x9D, 0x90, 0x4B, 0xC4, 0xBC,
        0x0B, 0xBE, 0xA7, 0x6B, 0xC5, 0x3F, 0xF8, 0x11,
        0x21, 0x45, 0x98, 0x47, 0x2C, 0x9C, 0x20, 0x2B,
        0x73, 0xEF, 0xF0, 0x35, 0xDC, 0x09, 0x70, 0x3A,
        0xF7, 0xBF, 0x1B, 0xAB, 0xAA, 0xC7, 0x31, 0x93,
        0xCB, 0x46, 0x11, 0x7A, 0x7C, 0x94, 0x92, 0xA4,
        0x3F, 0xC9, 0x57, 0x89, 0xA9, 0x24, 0xC5, 0x91,
        0x27, 0x87, 0xB2, 0xE2, 0x09, 0x0E, 0xBB, 0xCF,
        0xD3, 0x79, 0x62, 0x21, 0xF0, 0x6D, 0xEB, 0xF9,
        0xCF, 0x70, 0xE0, 0x56, 0xB8, 0xB9, 0x16, 0x1D,
        0x63, 0x47, 0xF4, 0x73, 0x35, 0xF3, 0xE1, 0x77,
        0x6D, 0xA4, 0xBB, 0x87, 0xC1, 0x5C, 0xC8, 0x26,
        0x14, 0x6F, 0xF0, 0x24, 0x9A, 0x41, 0x3B, 0x45,
        0xAA, 0x93, 0xA8, 0x05, 0x19, 0x6E, 0xA4, 0x53,
        0x11, 0x4B, 0x52, 0x4E, 0x31, 0x0A, 0xED, 0xAA,
        0x46, 0xE3, 0xB9, 0x96, 0x42, 0x36, 0x87, 0x82,
        0x56, 0x6D, 0x04, 0x9A, 0x72, 0x6D, 0x6C, 0xCA,
        0x91, 0x09, 0x93, 0xAE, 0xD6, 0x21, 0xD0, 0x14,
        0x9E, 0xA5, 0x88, 0xA9, 0xAB, 0xD9, 0x09, 0xDB,
        0xB6, 0x9A, 0xA2, 0x28, 0x29, 0xD9, 0xB8, 0x3A,
        0xDA, 0x22, 0x09, 0xA6, 0xC2, 0x65, 0x9F, 0x21,
        0x69, 0xD6, 0x68, 0xB9, 0x31, 0x48, 0x42, 0xC6,
        0xE2, 0x2A, 0x74, 0x95, 0x8B, 0x4C, 0x25, 0xBB,
        0xDC, 0xD2, 0x93, 0xD9, 0x9C, 0xB6, 0x09, 0xD8,
        0x66, 0x74, 0x9A, 0x48, 0x5D, 0xFB, 0x56, 0x02,
        0x48, 0x83, 0xCF, 0x54, 0x65, 0xDB, 0xA0, 0x36,
        0x32, 0x06, 0x58, 0x7F, 0x45, 0x59, 0x7F, 0x89,
        0x00, 0x2F, 0xB8, 0x60, 0x72, 0x32, 0x13, 0x8E,
        0x03, 0xB2, 0xA8, 0x94, 0x52, 0x5F, 0x26, 0x53,
        0x70, 0x05, 0x4B, 0x48, 0x86, 0x36, 0x14, 0x47,
        0x2B, 0x95, 0xD0, 0xA2, 0x30, 0x34, 0x42, 0xE3,
        0x78, 0xB0, 0xDD, 0x1C, 0x75, 0xAC, 0xBA, 0xB9,
        0x71, 0xA9, 0xA8, 0xD1, 0x28, 0x1C, 0x79, 0x61,
        0x3A, 0xCE, 0xC6, 0x93, 0x3C, 0x37, 0x7B, 0x3C,
        0x57, 0x8C, 0x2A, 0x61, 0xA1, 0xEC, 0x18, 0x1B,
        0x10, 0x12, 0x97, 0xA3, 0x7C, 0xC5, 0x19, 0x7B,
        0x29, 0x42, 0xF6, 0xA0, 0xE4, 0x70, 0x4C, 0x0E,
        0xC6, 0x35, 0x40, 0x48, 0x1B, 0x9F, 0x15, 0x9D,
        0xC2, 0x55, 0xB5, 0x9B, 0xB5, 0x5D, 0xF4, 0x96,
        0xAE, 0x54, 0x21, 0x7B, 0x76, 0x89, 0xBD, 0x51,
        0xDB, 0xA0, 0x38, 0x3A, 0x3D, 0x72, 0xD8, 0x52,
        0xFF, 0xCA, 0x76, 0xDF, 0x05, 0xB6, 0x6E, 0xEC,
        0xCB, 0xD4, 0x7B, 0xC5, 0x30, 0x40, 0x81, 0x76,
        0x28, 0xC7, 0x1E, 0x36, 0x1D, 0x6A, 0xF8, 0x89,
        0x08, 0x49, 0x16, 0xB4, 0x08, 0xA4, 0x66, 0xC9,
        0x6E, 0x70, 0x86, 0xC4, 0xA6, 0x0A, 0x10, 0xFC,
        0xF7, 0x53, 0x7B, 0xB9, 0x4A, 0xFB, 0xCC, 0x7D,
        0x43, 0x75, 0x90, 0x91, 0x9C, 0x28, 0x65, 0x0C,
        0x4F, 0x23, 0x68, 0x25, 0x92, 0x26, 0xA9, 0xBF,
        0xDA, 0x3A, 0x3A, 0x0B, 0xA1, 0xB5, 0x08, 0x7D,
        0x9D, 0x76, 0x44, 0x2F, 0xD7, 0x86, 0xC6, 0xF8,
        0x1C, 0x68, 0xC0, 0x36, 0x0D, 0x71, 0x94, 0xD7,
        0x07, 0x2C, 0x45, 0x33, 0xAE, 0xA8, 0x6C, 0x2D,
        0x1F, 0x8C, 0x0A, 0x27, 0x69, 0x60, 0x66, 0xF6,
        0xCF, 0xD1, 0x10, 0x03, 0xF7, 0x97, 0x27, 0x0B,
        0x32, 0x38, 0x97, 0x13, 0xCF, 0xFA, 0x09, 0x3D,
        0x99, 0x1B, 0x63, 0x84, 0x4C, 0x38, 0x5E, 0x72,
        0x27, 0x7F, 0x16, 0x6F, 0x5A, 0x39, 0x34, 0xD6,
        0xBB, 0x89, 0xA4, 0x78, 0x8D, 0xE2, 0x83, 0x21,
        0xDE, 0xFC, 0x74, 0x57, 0xAB, 0x48, 0x4B, 0xD3,
        0x09, 0x86, 0xDC, 0x1D, 0xAB, 0x30, 0x08, 0xCD,
        0x7B, 0x22, 0xF6, 0x97, 0x02, 0xFA, 0xBB, 0x9A,
        0x10, 0x45, 0x40, 0x7D, 0xA4, 0x79, 0x1C, 0x35,
        0x90, 0xFF, 0x59, 0x9D, 0x81, 0xD6, 0x88, 0xCF,
        0xA7, 0xCC, 0x12, 0xA6, 0x8C, 0x50, 0xF5, 0x1A,
        0x10, 0x09, 0x41, 0x1B, 0x44, 0x85, 0x0F, 0x90,
        0x15, 0xDC, 0x84, 0xA9, 0x3B, 0x17, 0xC7, 0xA2,
        0x07, 0x55, 0x2C, 0x66, 0x1E, 0xA9, 0x83, 0x8E,
        0x31, 0xB9, 0x5E, 0xAD, 0x54, 0x62, 0x48, 0xE5,
        0x6B, 0xE7, 0xA5, 0x13, 0x05, 0x05, 0x26, 0x87,
        0x71, 0x19, 0x98, 0x80, 0xA1, 0x41, 0x77, 0x1A,
        0x9E, 0x47, 0xAC, 0xFE, 0xD5, 0x90, 0xCB, 0x3A,
        0xA7, 0xCB, 0x7C, 0x5F, 0x74, 0x91, 0x1D, 0x89,
        0x12, 0xC2, 0x9D, 0x62, 0x33, 0xF4, 0xD5, 0x3B,
        0xC6, 0x41, 0x39, 0xE2, 0xF5, 0x5B, 0xE7, 0x55,
        0x07, 0xDD, 0x77, 0x86, 0x8E, 0x38, 0x4A, 0xEC,
        0x58, 0x1F, 0x3F, 0x41, 0x1D, 0xB1, 0xA7, 0x42,
        0x97, 0x2D, 0x3E, 0xBF, 0xD3, 0x31, 0x5C, 0x84,
        0xA5, 0xAD, 0x63, 0xA0, 0xE7, 0x5C, 0x8B, 0xCA,
        0x3E, 0x30, 0x41, 0xE0, 0x5D, 0x90, 0x67, 0xAF,
        0xF3, 0xB1, 0x24, 0x4F, 0x76, 0x3E, 0x79, 0x83
    };
    static const byte seed_1024[KYBER_ENC_RAND_SZ] = {
        0x59, 0xC5, 0x15, 0x4C, 0x04, 0xAE, 0x43, 0xAA,
        0xFF, 0x32, 0x70, 0x0F, 0x08, 0x17, 0x00, 0x38,
        0x9D, 0x54, 0xBE, 0xC4, 0xC3, 0x7C, 0x08, 0x8B,
        0x1C, 0x53, 0xF6, 0x62, 0x12, 0xB1, 0x2C, 0x72
    };
    static const byte c_1024[KYBER1024_CIPHER_TEXT_SIZE] = {
        0xE2, 0xD5, 0xFD, 0x4C, 0x13, 0xCE, 0xA0, 0xB5,
        0x2D, 0x87, 0x4F, 0xEA, 0x90, 0x12, 0xF3, 0xA5,
        0x17, 0x43, 0xA1, 0x09, 0x37, 0x10, 0xBB, 0xF2,
        0x39, 0x50, 0xF9, 0x14, 0x7A, 0x47, 0x2E, 0xE5,
        0x53, 0x39, 0x28, 0xA2, 0xF4, 0x6D, 0x59, 0x2F,
        0x35, 0xDA, 0x8B, 0x4F, 0x75, 0x8C, 0x89, 0x3B,
        0x0D, 0x7B, 0x98, 0x94, 0x8B, 0xE4, 0x47, 0xB1,
        0x7C, 0xB2, 0xAE, 0x58, 0xAF, 0x8A, 0x48, 0x9D,
        0xDD, 0x92, 0x32, 0xB9, 0x9B, 0x1C, 0x0D, 0x2D,
        0xE7, 0x7C, 0xAA, 0x47, 0x2B, 0xC3, 0xBB, 0xD4,
        0xA7, 0xC6, 0x0D, 0xBF, 0xDC, 0xA9, 0x2E, 0xBF,
        0x3A, 0x1C, 0xE1, 0xC2, 0x2D, 0xAD, 0x13, 0xE8,
        0x87, 0x00, 0x4E, 0x29, 0x24, 0xFD, 0x22, 0x65,
        0x6F, 0x5E, 0x50, 0x87, 0x91, 0xDE, 0x06, 0xD8,
        0x5E, 0x1A, 0x14, 0x26, 0x80, 0x8E, 0xD9, 0xA8,
        0x9F, 0x6E, 0x2F, 0xD3, 0xC2, 0x45, 0xD4, 0x75,
        0x8B, 0x22, 0xB0, 0x2C, 0xAD, 0xE3, 0x3B, 0x60,
        0xFC, 0x88, 0x9A, 0x33, 0xFC, 0x44, 0x47, 0xED,
        0xEB, 0xBF, 0xD4, 0x53, 0x0D, 0xE8, 0x65, 0x96,
        0xA3, 0x37, 0x89, 0xD5, 0xDB, 0xA6, 0xE6, 0xEC,
        0x9F, 0x89, 0x87, 0x9A, 0xF4, 0xBE, 0x49, 0x09,
        0xA6, 0x90, 0x17, 0xC9, 0xBB, 0x7A, 0x5E, 0x31,
        0x81, 0x5E, 0xA5, 0xF1, 0x32, 0xEE, 0xC4, 0x98,
        0x4F, 0xAA, 0x7C, 0xCF, 0x59, 0x4D, 0xD0, 0x0D,
        0x4D, 0x84, 0x87, 0xE4, 0x56, 0x21, 0xAF, 0x8F,
        0x6E, 0x33, 0x05, 0x51, 0x43, 0x9C, 0x93, 0xEC,
        0x07, 0x8A, 0x7A, 0x3C, 0xC1, 0x59, 0x4A, 0xF9,
        0x1F, 0x84, 0x17, 0x37, 0x5F, 0xD6, 0x08, 0x8C,
        0xEB, 0x5E, 0x85, 0xC6, 0x70, 0x99, 0x09, 0x1B,
        0xAC, 0x11, 0x49, 0x8A, 0x0D, 0x71, 0x14, 0x55,
        0xF5, 0xE0, 0xD9, 0x5C, 0xD7, 0xBB, 0xE5, 0xCD,
        0xD8, 0xFE, 0xCB, 0x31, 0x9E, 0x68, 0x53, 0xC2,
        0x3C, 0x9B, 0xE2, 0xC7, 0x63, 0xDF, 0x57, 0x86,
        0x66, 0xC4, 0x0A, 0x40, 0xA8, 0x74, 0x86, 0xE4,
        0x6B, 0xA8, 0x71, 0x61, 0x46, 0x19, 0x29, 0x04,
        0x51, 0x0A, 0x6D, 0xC5, 0x9D, 0xA8, 0x02, 0x58,
        0x25, 0x28, 0x3D, 0x68, 0x4D, 0xB9, 0x14, 0x10,
        0xB4, 0xF1, 0x2C, 0x6D, 0x8F, 0xBD, 0x0A, 0xDD,
        0x75, 0xD3, 0x09, 0x89, 0x18, 0xCB, 0x04, 0xAC,
        0x7B, 0xC4, 0xDB, 0x0D, 0x6B, 0xCD, 0xF1, 0x19,
        0x4D, 0xD8, 0x62, 0x92, 0xE0, 0x5B, 0x7B, 0x86,
        0x30, 0x62, 0x5B, 0x58, 0x9C, 0xC5, 0x09, 0xD2,
        0x15, 0xBB, 0xD0, 0x6A, 0x2E, 0x7C, 0x66, 0xF4,
        0x24, 0xCD, 0xF8, 0xC4, 0x0A, 0xC6, 0xC1, 0xE5,
        0xAE, 0x6C, 0x96, 0x4B, 0x7D, 0x9E, 0x92, 0xF9,
        0x5F, 0xC5, 0xC8, 0x85, 0x22, 0x81, 0x62, 0x8B,
        0x81, 0xB9, 0xAF, 0xAB, 0xC7, 0xF0, 0x3B, 0xE3,
        0xF6, 0x2E, 0x80, 0x47, 0xBB, 0x88, 0xD0, 0x1C,
        0x68, 0x68, 0x7B, 0x8D, 0xD4, 0xFE, 0x63, 0x82,
        0x00, 0x62, 0xB6, 0x78, 0x8A, 0x53, 0x72, 0x90,
        0x53, 0x82, 0x6E, 0xD3, 0xB7, 0xC7, 0xEF, 0x82,
        0x41, 0xE1, 0x9C, 0x85, 0x11, 0x7B, 0x3C, 0x53,
        0x41, 0x88, 0x1D, 0x4F, 0x29, 0x9E, 0x50, 0x37,
        0x4C, 0x8E, 0xEF, 0xD5, 0x56, 0x0B, 0xD1, 0x83,
        0x19, 0xA7, 0x96, 0x3A, 0x3D, 0x02, 0xF0, 0xFB,
        0xE8, 0x4B, 0xC4, 0x84, 0xB5, 0xA4, 0x01, 0x8B,
        0x97, 0xD2, 0x74, 0x19, 0x1C, 0x95, 0xF7, 0x02,
        0xBA, 0xB9, 0xB0, 0xD1, 0x05, 0xFA, 0xF9, 0xFD,
        0xCF, 0xF9, 0x7E, 0x43, 0x72, 0x36, 0x56, 0x75,
        0x99, 0xFA, 0xF7, 0x3B, 0x07, 0x5D, 0x40, 0x61,
        0x04, 0xD4, 0x03, 0xCD, 0xF8, 0x12, 0x24, 0xDA,
        0x59, 0x0B, 0xEC, 0x28, 0x97, 0xE3, 0x01, 0x09,
        0xE1, 0xF2, 0xE5, 0xAE, 0x46, 0x10, 0xC8, 0x09,
        0xA7, 0x3F, 0x63, 0x8C, 0x84, 0x21, 0x0B, 0x34,
        0x47, 0xA7, 0xC8, 0xB6, 0xDD, 0xDB, 0x5A, 0xE2,
        0x00, 0xBF, 0x20, 0xE2, 0xFE, 0x4D, 0x4B, 0xA6,
        0xC6, 0xB1, 0x27, 0x67, 0xFB, 0x87, 0x60, 0xF6,
        0x6C, 0x51, 0x18, 0xE7, 0xA9, 0x93, 0x5B, 0x41,
        0xC9, 0xA4, 0x71, 0xA1, 0xD3, 0x23, 0x76, 0x88,
        0xC1, 0xE6, 0x18, 0xCC, 0x3B, 0xE9, 0x36, 0xAA,
        0x3F, 0x5E, 0x44, 0xE0, 0x86, 0x82, 0x0B, 0x81,
        0x0E, 0x06, 0x32, 0x11, 0xFC, 0x21, 0xC4, 0x04,
        0x4B, 0x3A, 0xC4, 0xD0, 0x0D, 0xF1, 0xBC, 0xC7,
        0xB2, 0x4D, 0xC0, 0x7B, 0xA4, 0x8B, 0x23, 0xB0,
        0xFC, 0x12, 0xA3, 0xED, 0x3D, 0x0A, 0x5C, 0xF7,
        0x67, 0x14, 0x15, 0xAB, 0x9C, 0xF2, 0x12, 0x86,
        0xFE, 0x63, 0xFB, 0x41, 0x41, 0x85, 0x70, 0x55,
        0x5D, 0x47, 0x39, 0xB8, 0x81, 0x04, 0xA8, 0x59,
        0x3F, 0x29, 0x30, 0x25, 0xA4, 0xE3, 0xEE, 0x7C,
        0x67, 0xE4, 0xB4, 0x8E, 0x40, 0xF6, 0xBA, 0x8C,
        0x09, 0x86, 0x0C, 0x3F, 0xBB, 0xE5, 0x5D, 0x45,
        0xB4, 0x5F, 0xC9, 0xAB, 0x62, 0x9B, 0x17, 0xC2,
        0x76, 0xC9, 0xC9, 0xE2, 0xAF, 0x3A, 0x04, 0x3B,
        0xEA, 0xFC, 0x18, 0xFD, 0x4F, 0x25, 0xEE, 0x7F,
        0x83, 0xBD, 0xDC, 0xD2, 0xD9, 0x39, 0x14, 0xB7,
        0xED, 0x4F, 0x7C, 0x9A, 0xF1, 0x27, 0xF3, 0xF1,
        0x5C, 0x27, 0x7B, 0xE1, 0x65, 0x51, 0xFE, 0xF3,
        0xAE, 0x03, 0xD7, 0xB9, 0x14, 0x3F, 0x0C, 0x9C,
        0x01, 0x9A, 0xB9, 0x7E, 0xEA, 0x07, 0x63, 0x66,
        0x13, 0x1F, 0x51, 0x83, 0x63, 0x71, 0x1B, 0x34,
        0xE9, 0x6D, 0x3F, 0x8A, 0x51, 0x3F, 0x3E, 0x20,
        0xB1, 0xD4, 0x52, 0xC4, 0xB7, 0xAE, 0x3B, 0x97,
        0x5E, 0xA9, 0x4D, 0x88, 0x0D, 0xAC, 0x66, 0x93,
        0x39, 0x97, 0x50, 0xD0, 0x22, 0x20, 0x40, 0x3F,
        0x0D, 0x3E, 0x3F, 0xC1, 0x17, 0x2A, 0x4D, 0xE9,
        0xDC, 0x28, 0x0E, 0xAF, 0x0F, 0xEE, 0x28, 0x83,
        0xA6, 0x66, 0x0B, 0xF5, 0xA3, 0xD2, 0x46, 0xFF,
        0x41, 0xD2, 0x1B, 0x36, 0xEA, 0x52, 0x1C, 0xF7,
        0xAA, 0x68, 0x9F, 0x80, 0x0D, 0x0F, 0x86, 0xF4,
        0xFA, 0x10, 0x57, 0xD8, 0xA1, 0x3F, 0x9D, 0xA8,
        0xFF, 0xFD, 0x0D, 0xC1, 0xFA, 0xD3, 0xC0, 0x4B,
        0xB1, 0xCC, 0xCB, 0x7C, 0x83, 0x4D, 0xB0, 0x51,
        0xA7, 0xAC, 0x2E, 0x4C, 0x60, 0x30, 0x19, 0x96,
        0xC9, 0x30, 0x71, 0xEA, 0x41, 0x6B, 0x42, 0x17,
        0x59, 0x93, 0x56, 0x59, 0xCF, 0x62, 0xCA, 0x5F,
        0x13, 0xAE, 0x07, 0xC3, 0xB1, 0x95, 0xC1, 0x48,
        0x15, 0x9D, 0x8B, 0xEB, 0x03, 0xD4, 0x40, 0xB0,
        0x0F, 0x53, 0x05, 0x76, 0x5F, 0x20, 0xC0, 0xC4,
        0x6E, 0xEE, 0x59, 0xC6, 0xD1, 0x62, 0x06, 0x40,
        0x2D, 0xB1, 0xC7, 0x15, 0xE8, 0x88, 0xBD, 0xE5,
        0x9C, 0x78, 0x1F, 0x35, 0xA7, 0xCC, 0x7C, 0x1C,
        0x5E, 0xCB, 0x21, 0x55, 0xAE, 0x3E, 0x95, 0x9C,
        0x09, 0x64, 0xCC, 0x1E, 0xF8, 0xD7, 0xC6, 0x9D,
        0x14, 0x58, 0xA9, 0xA4, 0x2F, 0x95, 0xF4, 0xC6,
        0xB5, 0xB9, 0x96, 0x34, 0x57, 0x12, 0xAA, 0x29,
        0x0F, 0xBB, 0xF7, 0xDF, 0xD4, 0xA6, 0xE8, 0x64,
        0x63, 0x02, 0x2A, 0x3F, 0x47, 0x25, 0xF6, 0x51,
        0x1B, 0xF7, 0xEA, 0x5E, 0x95, 0xC7, 0x07, 0xCD,
        0x35, 0x73, 0x60, 0x9A, 0xAD, 0xEA, 0xF5, 0x40,
        0x15, 0x2C, 0x49, 0x5F, 0x37, 0xFE, 0x6E, 0xC8,
        0xBB, 0x9F, 0xA2, 0xAA, 0x61, 0xD1, 0x57, 0x35,
        0x93, 0x4F, 0x47, 0x37, 0x92, 0x8F, 0xDE, 0x90,
        0xBA, 0x99, 0x57, 0x22, 0x46, 0x5D, 0x4A, 0x64,
        0x50, 0x5A, 0x52, 0x01, 0xF0, 0x7A, 0xA5, 0x8C,
        0xFD, 0x8A, 0xE2, 0x26, 0xE0, 0x20, 0x70, 0xB2,
        0xDB, 0xF5, 0x12, 0xB9, 0x75, 0x31, 0x9A, 0x7E,
        0x87, 0x53, 0xB4, 0xFD, 0xAE, 0x0E, 0xB4, 0x92,
        0x28, 0x69, 0xCC, 0x8E, 0x25, 0xC4, 0xA5, 0x56,
        0x0C, 0x2A, 0x06, 0x85, 0xDE, 0x3A, 0xC3, 0x92,
        0xA8, 0x92, 0x5B, 0xA8, 0x82, 0x00, 0x48, 0x94,
        0x74, 0x2E, 0x43, 0xCC, 0xFC, 0x27, 0x74, 0x39,
        0xEC, 0x80, 0x50, 0xA9, 0xAE, 0xB4, 0x29, 0x32,
        0xE0, 0x1C, 0x84, 0x0D, 0xFC, 0xED, 0xCC, 0x34,
        0xD3, 0x99, 0x12, 0x89, 0xA6, 0x2C, 0x17, 0xD1,
        0x28, 0x4C, 0x83, 0x95, 0x14, 0xB9, 0x33, 0x51,
        0xDB, 0xB2, 0xDD, 0xA8, 0x1F, 0x92, 0x45, 0x65,
        0xD7, 0x0E, 0x70, 0x79, 0xD5, 0xB8, 0x12, 0x6C,
        0xAA, 0xB7, 0xA4, 0xA1, 0xC7, 0x31, 0x65, 0x5A,
        0x53, 0xBC, 0xC0, 0x9F, 0x5D, 0x63, 0xEC, 0x90,
        0x86, 0xDE, 0xA6, 0x50, 0x05, 0x59, 0x85, 0xED,
        0xFA, 0x82, 0x97, 0xD9, 0xC9, 0x54, 0x10, 0xC5,
        0xD1, 0x89, 0x4D, 0x17, 0xD5, 0x93, 0x05, 0x49,
        0xAD, 0xBC, 0x2B, 0x87, 0x33, 0xC9, 0x9F, 0xE6,
        0x2E, 0x17, 0xC4, 0xDE, 0x34, 0xA5, 0xD8, 0x9B,
        0x12, 0xD1, 0x8E, 0x42, 0xA4, 0x22, 0xD2, 0xCE,
        0x77, 0x9C, 0x2C, 0x28, 0xEB, 0x2D, 0x98, 0x00,
        0x3D, 0x5C, 0xD3, 0x23, 0xFC, 0xBE, 0xCF, 0x02,
        0xB5, 0x06, 0x6E, 0x0E, 0x73, 0x48, 0x10, 0xF0,
        0x9E, 0xD8, 0x90, 0x13, 0xC0, 0x0F, 0x01, 0x1B,
        0xD2, 0x20, 0xF2, 0xE5, 0xD6, 0xA3, 0x62, 0xDF,
        0x90, 0x59, 0x91, 0x98, 0xA0, 0x93, 0xB0, 0x3C,
        0x8D, 0x8E, 0xFB, 0xFE, 0x0B, 0x61, 0x75, 0x92,
        0xFA, 0xF1, 0xE6, 0x42, 0x20, 0xC4, 0x44, 0x0B,
        0x53, 0xFF, 0xB4, 0x71, 0x64, 0xF3, 0x69, 0xC9,
        0x52, 0x90, 0xBA, 0x9F, 0x31, 0x08, 0xD6, 0x86,
        0xC5, 0x7D, 0xB6, 0x45, 0xC5, 0x3C, 0x01, 0x2E,
        0x57, 0xAF, 0x25, 0xBD, 0x66, 0x93, 0xE2, 0xCC,
        0x6B, 0x57, 0x65, 0x1A, 0xF1, 0x59, 0x1F, 0xE5,
        0xD8, 0x91, 0x66, 0x40, 0xEC, 0x01, 0x7C, 0x25,
        0x3D, 0xF0, 0x60, 0x6B, 0xB6, 0xB3, 0x03, 0x5F,
        0xAE, 0x74, 0x8F, 0x3D, 0x40, 0x34, 0x22, 0x3B,
        0x1B, 0x5E, 0xFB, 0xF5, 0x28, 0x3E, 0x77, 0x8C,
        0x10, 0x94, 0x29, 0x1C, 0xF7, 0xB1, 0x9B, 0xE0,
        0xF3, 0x17, 0x35, 0x0E, 0x6F, 0x85, 0x18, 0xFD,
        0xE0, 0xEF, 0xB1, 0x38, 0x1F, 0xB6, 0xE1, 0x6C,
        0x24, 0x1F, 0x7F, 0x17, 0xA5, 0x21, 0x06, 0x93,
        0xA2, 0x74, 0x15, 0x9E, 0x7F, 0xAC, 0x86, 0x8C,
        0xD0, 0xDC, 0x43, 0x59, 0xC3, 0xD9, 0xEE, 0xFE,
        0xA0, 0xD9, 0xE3, 0x1E, 0x43, 0xFA, 0x65, 0x13,
        0x92, 0xC6, 0x5A, 0x54, 0x3A, 0x59, 0xB3, 0xEE,
        0xE3, 0xA6, 0x39, 0xDC, 0x94, 0x17, 0xD0, 0x56,
        0xA5, 0xFF, 0x0F, 0x16, 0x0B, 0xEE, 0xE2, 0xEA,
        0xC2, 0x9A, 0x7D, 0x88, 0xC0, 0x98, 0x2C, 0xF7,
        0x0B, 0x5A, 0x46, 0x37, 0x9F, 0x21, 0xE5, 0x06,
        0xAA, 0xC6, 0x1A, 0x9B, 0xB1, 0xB8, 0xC2, 0xB9,
        0xDA, 0xB0, 0xE4, 0x4A, 0x82, 0x3B, 0x61, 0xD0,
        0xAA, 0x11, 0xD9, 0x4F, 0x76, 0xA4, 0xA8, 0xE2,
        0x1F, 0x9D, 0x42, 0x80, 0x68, 0x32, 0x08, 0xF4,
        0xEA, 0x91, 0x11, 0x16, 0xF6, 0xFD, 0x6A, 0x97,
        0x42, 0x69, 0x34, 0xEC, 0x34, 0x26, 0xB8, 0xC8,
        0xF7, 0x03, 0xDA, 0x85, 0xE9, 0xDC, 0xF9, 0x93,
        0x36, 0x13, 0x60, 0x03, 0x72, 0x8B, 0x8E, 0xCD,
        0xD0, 0x4A, 0x38, 0x9F, 0x6A, 0x81, 0x7A, 0x78,
        0xBF, 0xA6, 0x1B, 0xA4, 0x60, 0x20, 0xBF, 0x3C,
        0x34, 0x82, 0x95, 0x08, 0xF9, 0xD0, 0x6D, 0x15,
        0x53, 0xCD, 0x98, 0x7A, 0xAC, 0x38, 0x0D, 0x86,
        0xF1, 0x68, 0x84, 0x3B, 0xA3, 0x90, 0x4D, 0xE5,
        0xF7, 0x05, 0x8A, 0x41, 0xB4, 0xCD, 0x38, 0x8B,
        0xC9, 0xCE, 0x3A, 0xBA, 0x7E, 0xE7, 0x13, 0x9B,
        0x7F, 0xC9, 0xE5, 0xB8, 0xCF, 0xAA, 0xA3, 0x89,
        0x90, 0xBD, 0x4A, 0x5D, 0xB3, 0x2E, 0x26, 0x13,
        0xE7, 0xEC, 0x4F, 0x5F, 0x8B, 0x12, 0x92, 0xA3,
        0x8C, 0x6F, 0x4F, 0xF5, 0xA4, 0x04, 0x90, 0xD7,
        0x6B, 0x12, 0x66, 0x52, 0xFC, 0xF8, 0x6E, 0x24,
        0x52, 0x35, 0xD6, 0x36, 0xC6, 0x5C, 0xD1, 0x02,
        0xB0, 0x1E, 0x22, 0x78, 0x1A, 0x72, 0x91, 0x8C
    };
    static const byte k_1024[KYBER_SS_SZ] = {
        0x72, 0x64, 0xBD, 0xE5, 0xC6, 0xCE, 0xC1, 0x48,
        0x49, 0x69, 0x3E, 0x2C, 0x3C, 0x86, 0xE4, 0x8F,
        0x80, 0x95, 0x8A, 0x4F, 0x61, 0x86, 0xFC, 0x69,
        0x33, 0x3A, 0x41, 0x48, 0xE6, 0xE4, 0x97, 0xF3
    };
#endif
    static byte ct[KYBER_MAX_CIPHER_TEXT_SIZE];
    static byte ss[KYBER_SS_SZ];

    key = (KyberKey*)XMALLOC(sizeof(KyberKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);
    if (key != NULL) {
        XMEMSET(key, 0, sizeof(KyberKey));
    }

#ifndef WOLFSSL_NO_KYBER512
    ExpectIntEQ(wc_KyberKey_Init(KYBER512, key, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_KyberKey_DecodePublicKey(key, ek_512, sizeof(ek_512)), 0);
    ExpectIntEQ(wc_KyberKey_EncapsulateWithRandom(key, ct, ss, seed_512,
        sizeof(seed_512)), 0);
    ExpectIntEQ(XMEMCMP(ct, c_512, KYBER512_CIPHER_TEXT_SIZE), 0);
    ExpectIntEQ(XMEMCMP(ss, k_512, KYBER_SS_SZ), 0);
    wc_KyberKey_Free(key);
#endif
#ifndef WOLFSSL_NO_KYBER768
    ExpectIntEQ(wc_KyberKey_Init(KYBER768, key, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_KyberKey_DecodePublicKey(key, ek_768, sizeof(ek_768)), 0);
    ExpectIntEQ(wc_KyberKey_EncapsulateWithRandom(key, ct, ss, seed_768,
        sizeof(seed_768)), 0);
    ExpectIntEQ(XMEMCMP(ct, c_768, KYBER768_CIPHER_TEXT_SIZE), 0);
    ExpectIntEQ(XMEMCMP(ss, k_768, KYBER_SS_SZ), 0);
    wc_KyberKey_Free(key);
#endif
#ifndef WOLFSSL_NO_KYBER1024
    ExpectIntEQ(wc_KyberKey_Init(KYBER1024, key, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_KyberKey_DecodePublicKey(key, ek_1024, sizeof(ek_1024)), 0);
    ExpectIntEQ(wc_KyberKey_EncapsulateWithRandom(key, ct, ss, seed_1024,
        sizeof(seed_1024)), 0);
    ExpectIntEQ(XMEMCMP(ct, c_1024, KYBER1024_CIPHER_TEXT_SIZE), 0);
    ExpectIntEQ(XMEMCMP(ss, k_1024, KYBER_SS_SZ), 0);
    wc_KyberKey_Free(key);
#endif

    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_kyber_decapsulate_kats(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_HAVE_KYBER) && defined(WOLFSSL_WC_KYBER) && \
    !defined(WOLFSSL_KYBER_ORIGINAL)
    KyberKey* key;
#ifndef WOLFSSL_NO_KYBER512
    static const byte dk_512[KYBER512_PRIVATE_KEY_SIZE] = {
        0x69, 0xF9, 0xCB, 0xFD, 0x12, 0x37, 0xBA, 0x16,
        0x1C, 0xF6, 0xE6, 0xC1, 0x8F, 0x48, 0x8F, 0xC6,
        0xE3, 0x9A, 0xB4, 0xA5, 0xC9, 0xE6, 0xC2, 0x2E,
        0xA4, 0xE3, 0xAD, 0x8F, 0x26, 0x7A, 0x9C, 0x44,
        0x20, 0x10, 0xD3, 0x2E, 0x61, 0xF8, 0x3E, 0x6B,
        0xFA, 0x5C, 0x58, 0x70, 0x61, 0x45, 0x37, 0x6D,
        0xBB, 0x84, 0x95, 0x28, 0xF6, 0x80, 0x07, 0xC8,
        0x22, 0xB3, 0x3A, 0x95, 0xB8, 0x49, 0x04, 0xDC,
        0xD2, 0x70, 0x8D, 0x03, 0x40, 0xC8, 0xB8, 0x08,
        0xBC, 0xD3, 0xAA, 0xD0, 0xE4, 0x8B, 0x85, 0x84,
        0x95, 0x83, 0xA1, 0xB4, 0xE5, 0x94, 0x5D, 0xD9,
        0x51, 0x4A, 0x7F, 0x64, 0x61, 0xE0, 0x57, 0xB7,
        0xEC, 0xF6, 0x19, 0x57, 0xE9, 0x7C, 0xF6, 0x28,
        0x15, 0xF9, 0xC3, 0x22, 0x94, 0xB3, 0x26, 0xE1,
        0xA1, 0xC4, 0xE3, 0x60, 0xB9, 0x49, 0x8B, 0xA8,
        0x0F, 0x8C, 0xA9, 0x15, 0x32, 0xB1, 0x71, 0xD0,
        0xAE, 0xFC, 0x48, 0x49, 0xFA, 0x53, 0xBC, 0x61,
        0x79, 0x32, 0xE2, 0x08, 0xA6, 0x77, 0xC6, 0x04,
        0x4A, 0x66, 0x00, 0xB8, 0xD8, 0xB8, 0x3F, 0x26,
        0xA7, 0x47, 0xB1, 0x8C, 0xFB, 0x78, 0xBE, 0xAF,
        0xC5, 0x51, 0xAD, 0x52, 0xB7, 0xCA, 0x6C, 0xB8,
        0x8F, 0x3B, 0x5D, 0x9C, 0xE2, 0xAF, 0x6C, 0x67,
        0x95, 0x6C, 0x47, 0x8C, 0xEF, 0x49, 0x1F, 0x59,
        0xE0, 0x19, 0x1B, 0x3B, 0xBE, 0x92, 0x9B, 0x94,
        0xB6, 0x66, 0xC1, 0x76, 0x13, 0x8B, 0x00, 0xF4,
        0x97, 0x24, 0x34, 0x1E, 0xE2, 0xE1, 0x64, 0xB9,
        0x4C, 0x05, 0x3C, 0x18, 0x5A, 0x51, 0xF9, 0x3E,
        0x00, 0xF3, 0x68, 0x61, 0x61, 0x3A, 0x7F, 0xD7,
        0x2F, 0xEB, 0xD2, 0x3A, 0x8B, 0x96, 0xA2, 0x60,
        0x23, 0x42, 0x39, 0xC9, 0x62, 0x8F, 0x99, 0x5D,
        0xC1, 0x38, 0x07, 0xB4, 0x3A, 0x69, 0x46, 0x81,
        0x67, 0xCB, 0x1A, 0x8F, 0x9D, 0xD0, 0x7E, 0xE3,
        0xB3, 0x32, 0x38, 0xF6, 0x30, 0x96, 0xEB, 0xC4,
        0x9D, 0x50, 0x51, 0xC4, 0xB6, 0x59, 0x63, 0xD7,
        0x4A, 0x47, 0x66, 0xC2, 0x26, 0xF0, 0xB9, 0x4F,
        0x18, 0x62, 0xC2, 0x12, 0x4C, 0x8C, 0x74, 0x97,
        0x48, 0xC0, 0xBC, 0x4D, 0xC1, 0x4C, 0xB3, 0x49,
        0x06, 0xB8, 0x1C, 0x55, 0x24, 0xFB, 0x81, 0x00,
        0x79, 0x85, 0x42, 0xDC, 0x6C, 0xC2, 0xAA, 0x0A,
        0x70, 0x85, 0x75, 0xEA, 0xBC, 0xC1, 0x1F, 0x96,
        0xA9, 0xE6, 0x1C, 0x01, 0x7A, 0x96, 0xA7, 0xCE,
        0x93, 0xC4, 0x20, 0x91, 0x73, 0x71, 0x13, 0xAE,
        0x78, 0x3C, 0x0A, 0xE8, 0x75, 0x5E, 0x59, 0x41,
        0x11, 0xED, 0xFA, 0xBF, 0xD8, 0x6C, 0x32, 0x12,
        0xC6, 0x12, 0xA7, 0xB6, 0x2A, 0xFD, 0x3C, 0x7A,
        0x5C, 0x78, 0xB2, 0xF0, 0x73, 0x44, 0xB7, 0x89,
        0xC2, 0xB2, 0xDB, 0xB5, 0xF4, 0x44, 0x8B, 0xE9,
        0x7B, 0xBA, 0x42, 0x33, 0xC0, 0x03, 0x9C, 0x0F,
        0xE8, 0x43, 0x00, 0xF9, 0xB0, 0x3A, 0xC9, 0x94,
        0x97, 0xE6, 0xD4, 0x6B, 0x6E, 0x95, 0x30, 0x8F,
        0xF8, 0x47, 0x90, 0xF6, 0x12, 0xCF, 0x18, 0x6E,
        0xC1, 0x68, 0x11, 0xE8, 0x0C, 0x17, 0x93, 0x16,
        0xA6, 0x3B, 0x25, 0x70, 0x3F, 0x60, 0xB8, 0x42,
        0xB6, 0x19, 0x07, 0xE6, 0x28, 0x94, 0xE7, 0x36,
        0x64, 0x7B, 0x3C, 0x09, 0xDA, 0x6F, 0xEC, 0x59,
        0x32, 0x78, 0x2B, 0x36, 0xE0, 0x63, 0x50, 0x85,
        0xA3, 0x94, 0x9E, 0x69, 0x4D, 0x7E, 0x17, 0xCB,
        0xA3, 0xD9, 0x06, 0x43, 0x30, 0x43, 0x8C, 0x07,
        0x1B, 0x58, 0x36, 0xA7, 0x70, 0xC5, 0x5F, 0x62,
        0x13, 0xCC, 0x14, 0x25, 0x84, 0x5D, 0xE5, 0xA3,
        0x34, 0xD7, 0x5D, 0x3E, 0x50, 0x58, 0xC7, 0x80,
        0x9F, 0xDA, 0x4B, 0xCD, 0x78, 0x19, 0x1D, 0xA9,
        0x79, 0x73, 0x25, 0xE6, 0x23, 0x6C, 0x26, 0x50,
        0xFC, 0x60, 0x4E, 0xE4, 0x3A, 0x83, 0xCE, 0xB3,
        0x49, 0x80, 0x08, 0x44, 0x03, 0xA3, 0x32, 0x59,
        0x85, 0x79, 0x07, 0x79, 0x9A, 0x9D, 0x2A, 0x71,
        0x3A, 0x63, 0x3B, 0x5C, 0x90, 0x47, 0x27, 0xF6,
        0x1E, 0x42, 0x52, 0x09, 0x91, 0xD6, 0x55, 0x70,
        0x5C, 0xB6, 0xBC, 0x1B, 0x74, 0xAF, 0x60, 0x71,
        0x3E, 0xF8, 0x71, 0x2F, 0x14, 0x08, 0x68, 0x69,
        0xBE, 0x8E, 0xB2, 0x97, 0xD2, 0x28, 0xB3, 0x25,
        0xA0, 0x60, 0x9F, 0xD6, 0x15, 0xEA, 0xB7, 0x08,
        0x15, 0x40, 0xA6, 0x1A, 0x82, 0xAB, 0xF4, 0x3B,
        0x7D, 0xF9, 0x8A, 0x59, 0x5B, 0xE1, 0x1F, 0x41,
        0x6B, 0x41, 0xE1, 0xEB, 0x75, 0xBB, 0x57, 0x97,
        0x7C, 0x25, 0xC6, 0x4E, 0x97, 0x43, 0x7D, 0x88,
        0xCA, 0x5F, 0xDA, 0x61, 0x59, 0xD6, 0x68, 0xF6,
        0xBA, 0xB8, 0x15, 0x75, 0x55, 0xB5, 0xD5, 0x4C,
        0x0F, 0x47, 0xCB, 0xCD, 0x16, 0x84, 0x3B, 0x1A,
        0x0A, 0x0F, 0x02, 0x10, 0xEE, 0x31, 0x03, 0x13,
        0x96, 0x7F, 0x3D, 0x51, 0x64, 0x99, 0x01, 0x8F,
        0xDF, 0x31, 0x14, 0x77, 0x24, 0x70, 0xA1, 0x88,
        0x9C, 0xC0, 0x6C, 0xB6, 0xB6, 0x69, 0x0A, 0xC3,
        0x1A, 0xBC, 0xFA, 0xF4, 0xBC, 0x70, 0x76, 0x84,
        0x54, 0x5B, 0x00, 0x0B, 0x58, 0x0C, 0xCB, 0xFC,
        0xBC, 0xE9, 0xFA, 0x70, 0xAA, 0xEA, 0x0B, 0xBD,
        0x91, 0x10, 0x99, 0x2A, 0x7C, 0x6C, 0x06, 0xCB,
        0x36, 0x85, 0x27, 0xFD, 0x22, 0x90, 0x90, 0x75,
        0x7E, 0x6F, 0xE7, 0x57, 0x05, 0xFA, 0x59, 0x2A,
        0x76, 0x08, 0xF0, 0x50, 0xC6, 0xF8, 0x87, 0x03,
        0xCC, 0x28, 0xCB, 0x00, 0x0C, 0x1D, 0x7E, 0x77,
        0xB8, 0x97, 0xB7, 0x2C, 0x62, 0xBC, 0xC7, 0xAE,
        0xA2, 0x1A, 0x57, 0x72, 0x94, 0x83, 0xD2, 0x21,
        0x18, 0x32, 0xBE, 0xD6, 0x12, 0x43, 0x0C, 0x98,
        0x31, 0x03, 0xC6, 0x9E, 0x8C, 0x07, 0x2C, 0x0E,
        0xA7, 0x89, 0x8F, 0x22, 0x83, 0xBE, 0xC4, 0x8C,
        0x5A, 0xC8, 0x19, 0x84, 0xD4, 0xA5, 0xA8, 0x36,
        0x19, 0x73, 0x5A, 0x84, 0x2B, 0xD1, 0x72, 0xC0,
        0xD1, 0xB3, 0x9F, 0x43, 0x58, 0x8A, 0xF1, 0x70,
        0x45, 0x8B, 0xA9, 0xEE, 0x74, 0x92, 0xEA, 0xAA,
        0x94, 0xEA, 0x53, 0xA4, 0xD3, 0x84, 0x98, 0xEC,
        0xBB, 0x98, 0xA5, 0xF4, 0x07, 0xE7, 0xC9, 0x7B,
        0x4E, 0x16, 0x6E, 0x39, 0x71, 0x92, 0xC2, 0x16,
        0x03, 0x30, 0x14, 0xB8, 0x78, 0xE9, 0x38, 0x07,
        0x5C, 0x6C, 0x1F, 0x10, 0xA0, 0x06, 0x5A, 0xBC,
        0x31, 0x63, 0x72, 0x2F, 0x1A, 0x2E, 0xFF, 0xEC,
        0x8D, 0x6E, 0x3A, 0x0C, 0x4F, 0x71, 0x74, 0xFC,
        0x16, 0xB7, 0x9F, 0xB5, 0x18, 0x6A, 0x75, 0x16,
        0x8F, 0x81, 0xA5, 0x6A, 0xA4, 0x8A, 0x20, 0xA0,
        0x4B, 0xDD, 0xF1, 0x82, 0xC6, 0xE1, 0x79, 0xC3,
        0xF6, 0x90, 0x61, 0x55, 0x5E, 0xF7, 0x39, 0x6D,
        0xD0, 0xB7, 0x49, 0x96, 0x01, 0xA6, 0xEB, 0x3A,
        0x96, 0xA9, 0xA2, 0x2D, 0x04, 0xF1, 0x16, 0x8D,
        0xB5, 0x63, 0x55, 0xB0, 0x76, 0x00, 0xA2, 0x03,
        0x70, 0x63, 0x7B, 0x64, 0x59, 0x76, 0xBB, 0xD9,
        0x7B, 0x6D, 0x62, 0x88, 0xA0, 0xD3, 0x03, 0x63,
        0x60, 0x47, 0x2E, 0x3A, 0xC7, 0x1D, 0x56, 0x6D,
        0xB8, 0xFB, 0xB1, 0xB1, 0xD7, 0x6C, 0xB7, 0x55,
        0xCD, 0x0D, 0x68, 0xBD, 0xBF, 0xC0, 0x48, 0xEB,
        0xA2, 0x52, 0x5E, 0xEA, 0x9D, 0xD5, 0xB1, 0x44,
        0xFB, 0x3B, 0x60, 0xFB, 0xC3, 0x42, 0x39, 0x32,
        0x0C, 0xBC, 0x06, 0x9B, 0x35, 0xAB, 0x16, 0xB8,
        0x75, 0x65, 0x36, 0xFB, 0x33, 0xE8, 0xA6, 0xAF,
        0x1D, 0xD4, 0x2C, 0x79, 0xF4, 0x8A, 0xD1, 0x20,
        0xAE, 0x4B, 0x15, 0x9D, 0x3D, 0x8C, 0x31, 0x90,
        0x60, 0xCC, 0xE5, 0x69, 0xC3, 0xF6, 0x03, 0x53,
        0x65, 0x58, 0x5D, 0x34, 0x41, 0x37, 0x95, 0xA6,
        0xA1, 0x8E, 0xC5, 0x13, 0x6A, 0xB1, 0x3C, 0x90,
        0xE3, 0xAF, 0x14, 0xC0, 0xB8, 0xA4, 0x64, 0xC8,
        0x6B, 0x90, 0x73, 0x22, 0x2B, 0x56, 0xB3, 0xF7,
        0x32, 0x8A, 0xEA, 0x79, 0x81, 0x55, 0x32, 0x59,
        0x11, 0x25, 0x0E, 0xF0, 0x16, 0xD7, 0x28, 0x02,
        0xE3, 0x87, 0x8A, 0xA5, 0x05, 0x40, 0xCC, 0x98,
        0x39, 0x56, 0x97, 0x1D, 0x6E, 0xFA, 0x35, 0x2C,
        0x02, 0x55, 0x4D, 0xC7, 0x60, 0xA5, 0xA9, 0x13,
        0x58, 0xEA, 0x56, 0x37, 0x08, 0x84, 0xFD, 0x5B,
        0x3F, 0x85, 0xB7, 0x0E, 0x83, 0xE4, 0x69, 0x7D,
        0xEB, 0x17, 0x05, 0x16, 0x9E, 0x9C, 0x60, 0xA7,
        0x45, 0x28, 0xCF, 0x15, 0x28, 0x1C, 0xB1, 0xB1,
        0xC4, 0x57, 0xD4, 0x67, 0xB5, 0xF9, 0x3A, 0x60,
        0x37, 0x3D, 0x10, 0xE0, 0xCF, 0x6A, 0x83, 0x7A,
        0xA3, 0xC9, 0x59, 0x6A, 0x72, 0xBE, 0xC2, 0x9B,
        0x2D, 0x7E, 0x58, 0x65, 0x3D, 0x53, 0x30, 0x61,
        0xD3, 0x81, 0xD5, 0x17, 0x59, 0x75, 0x22, 0x17,
        0xEB, 0x46, 0xCA, 0xC7, 0x80, 0x7C, 0x4A, 0xD3,
        0x8B, 0x61, 0x16, 0x44, 0xAC, 0xF0, 0xA3, 0xF2,
        0x6B, 0x6B, 0x08, 0x4A, 0xB4, 0x7A, 0x83, 0xBF,
        0x0D, 0x69, 0x6F, 0x8A, 0x47, 0x68, 0xFC, 0x35,
        0xBC, 0xA6, 0xBC, 0x79, 0x03, 0xB2, 0xA2, 0x37,
        0xC2, 0x77, 0x49, 0xF5, 0x51, 0x0C, 0x86, 0x38,
        0x69, 0xE6, 0xAE, 0x56, 0xBB, 0x2A, 0xFE, 0x47,
        0x71, 0xC9, 0x22, 0x18, 0x74, 0xF5, 0x0F, 0x5B,
        0x14, 0xBA, 0xAD, 0x59, 0x93, 0xB4, 0x92, 0x38,
        0xFD, 0x0A, 0x0C, 0x9F, 0x79, 0xB7, 0xB4, 0x58,
        0x4E, 0x41, 0x30, 0x1F, 0x7A, 0x88, 0x5C, 0x9F,
        0x91, 0x81, 0x9B, 0xEA, 0x00, 0xD5, 0x12, 0x58,
        0x17, 0x30, 0x53, 0x9F, 0xB3, 0x7E, 0x59, 0xE8,
        0x6A, 0x6D, 0x19, 0xCA, 0x25, 0xF0, 0xA8, 0x11,
        0xC9, 0xB4, 0x28, 0xBA, 0x86, 0x14, 0xAA, 0x4F,
        0x94, 0x80, 0x7B, 0xC0, 0x31, 0xCB, 0xCC, 0x18,
        0x3F, 0x3B, 0xF0, 0x7F, 0xE2, 0xC1, 0xA6, 0xEB,
        0xA8, 0x0D, 0x5A, 0x70, 0x6E, 0xE0, 0xDA, 0xB2,
        0x7E, 0x23, 0x14, 0x58, 0x02, 0x5D, 0x84, 0xA7,
        0xA9, 0xB0, 0x23, 0x05, 0x01, 0x11, 0x6C, 0x29,
        0x0A, 0x6B, 0xB5, 0x06, 0x26, 0xD9, 0x7B, 0x93,
        0x98, 0x50, 0x94, 0x28, 0x28, 0x39, 0x0B, 0x0A,
        0x20, 0x01, 0xB7, 0x85, 0x3A, 0xD1, 0xAE, 0x9B,
        0x01, 0x1B, 0x2D, 0xB3, 0x6C, 0xAE, 0xEA, 0x73,
        0xA2, 0x32, 0x8E, 0x3C, 0x56, 0x48, 0x5B, 0x49,
        0x1C, 0x29, 0x91, 0x15, 0xA0, 0x17, 0xC9, 0x07,
        0xAB, 0x54, 0x31, 0x72, 0x60, 0xA5, 0x93, 0xA0,
        0xD7, 0xBA, 0x6D, 0x06, 0x61, 0x5D, 0x6E, 0x2C,
        0xA8, 0x4B, 0x86, 0x0E, 0xFF, 0x3C, 0xCB, 0x59,
        0x72, 0x11, 0xBF, 0xE3, 0x6B, 0xDE, 0xF8, 0x06,
        0x9A, 0xFA, 0x36, 0xC5, 0xA7, 0x33, 0x92, 0x72,
        0x26, 0x50, 0xE4, 0x95, 0x7D, 0xCA, 0x59, 0x7A,
        0xCB, 0xA5, 0x60, 0x5B, 0x63, 0xC1, 0x63, 0xCF,
        0xA9, 0x4B, 0x64, 0xDD, 0xD6, 0x23, 0x01, 0xA4,
        0x33, 0x20, 0x83, 0x36, 0x19, 0x72, 0x58, 0x9D,
        0xB0, 0x59, 0x9A, 0x69, 0x4D, 0xD4, 0x54, 0x7A,
        0x5E, 0xE9, 0x19, 0x65, 0x77, 0xC2, 0x2E, 0xD4,
        0x27, 0xAC, 0x89, 0xBB, 0x8B, 0xA3, 0x75, 0x3E,
        0xB7, 0x6C, 0x41, 0xF2, 0xC1, 0x12, 0x9C, 0x8A,
        0x77, 0xD6, 0x80, 0x5F, 0xA7, 0x19, 0xB1, 0xB6,
        0xCA, 0x11, 0xB7, 0x40, 0xA7, 0x8A, 0x3D, 0x41,
        0xB5, 0x33, 0x05, 0x26, 0xAB, 0x87, 0xD5, 0x8D,
        0x59, 0x25, 0x31, 0x5A, 0x14, 0x85, 0xED, 0xC6,
        0x47, 0xC1, 0x60, 0x4E, 0xB3, 0x81, 0x38, 0xDE,
        0x63, 0x7A, 0xD2, 0xC6, 0xCA, 0x5B, 0xE4, 0x4E,
        0x10, 0x08, 0xB2, 0xC0, 0x86, 0x7B, 0x22, 0x9C,
        0xCC, 0x36, 0x61, 0x9E, 0x27, 0x58, 0xC4, 0xC2,
        0x02, 0x9E, 0xAE, 0xB2, 0x6E, 0x7A, 0x80, 0x3F,
        0xCA, 0x30, 0x5A, 0x59, 0xCD, 0x58, 0x5E, 0x11,
        0x7D, 0x69, 0x8E, 0xCE, 0x01, 0x1C, 0xC3, 0xFC,
        0xE5, 0x4D, 0x2E, 0x11, 0x45, 0x45, 0xA2, 0x1A,
        0xC5, 0xBE, 0x67, 0x71, 0xAB, 0x8F, 0x13, 0x12,
        0x2F, 0xAD, 0x29, 0x5E, 0x74, 0x5A, 0x50, 0x3B,
        0x14, 0x2F, 0x91, 0xAE, 0xF7, 0xBD, 0xE9, 0x99,
        0x98, 0x84, 0x5F, 0xDA, 0x04, 0x35, 0x55, 0xC9,
        0xC1, 0xEE, 0x53, 0x5B, 0xE1, 0x25, 0xE5, 0xDC,
        0xE5, 0xD2, 0x66, 0x66, 0x7E, 0x72, 0x3E, 0x67,
        0xB6, 0xBA, 0x89, 0x1C, 0x16, 0xCB, 0xA1, 0x74,
        0x09, 0x8A, 0x3F, 0x35, 0x17, 0x78, 0xB0, 0x88,
        0x8C, 0x95, 0x90, 0xA9, 0x09, 0x0C, 0xD4, 0x04
    };
    static const byte c_512[KYBER512_CIPHER_TEXT_SIZE] = {
        0x16, 0x1C, 0xD2, 0x59, 0xFE, 0xAA, 0x7E, 0xC6,
        0xB2, 0x86, 0x49, 0x8A, 0x9A, 0x6F, 0x69, 0xF8,
        0xB2, 0x62, 0xA2, 0xE2, 0x09, 0x3D, 0x0F, 0xBD,
        0x76, 0xD5, 0xDC, 0x1C, 0x9F, 0xDE, 0x0D, 0xED,
        0xB3, 0x65, 0x81, 0x00, 0x4C, 0xB4, 0x81, 0x12,
        0xF8, 0x52, 0xE7, 0xF8, 0x7F, 0x64, 0x9E, 0x8A,
        0x42, 0xCD, 0x9E, 0x03, 0x49, 0xE7, 0xDA, 0xBD,
        0xF0, 0xA9, 0xAC, 0x1B, 0x52, 0x1C, 0x37, 0xEA,
        0x52, 0x41, 0x37, 0x0A, 0x8A, 0xB2, 0x91, 0x1C,
        0xC7, 0x99, 0x02, 0xC9, 0x5D, 0x28, 0x22, 0x4F,
        0xA8, 0x89, 0x6A, 0xD7, 0x15, 0x20, 0x9E, 0xCD,
        0xD5, 0xD7, 0x84, 0xE9, 0x1D, 0xD9, 0xD0, 0xBE,
        0x91, 0x6B, 0x45, 0x65, 0xF4, 0xD5, 0x66, 0x9A,
        0xEE, 0x0D, 0xEF, 0x93, 0x1E, 0x97, 0x68, 0x29,
        0x4E, 0xEC, 0x52, 0x58, 0xDE, 0x83, 0x91, 0xEC,
        0xE2, 0x71, 0xE7, 0xE4, 0xCF, 0xD9, 0xD2, 0x3A,
        0x79, 0xFA, 0xC3, 0xA8, 0xE0, 0xDB, 0x5D, 0xDD,
        0x6E, 0x01, 0x07, 0x23, 0x56, 0x88, 0xBB, 0xDF,
        0x7B, 0xC5, 0xD5, 0x63, 0x2F, 0x20, 0x6C, 0x63,
        0xA0, 0xC9, 0x56, 0x4F, 0x30, 0x96, 0x5C, 0xA5,
        0x8C, 0x69, 0xFF, 0x92, 0xD2, 0x5A, 0x4F, 0x93,
        0xA0, 0x9E, 0xAB, 0x9B, 0x90, 0x85, 0x94, 0x7E,
        0x07, 0x8A, 0x23, 0xE4, 0xD9, 0xC1, 0x3B, 0x8A,
        0x56, 0xE7, 0x3E, 0x18, 0xDF, 0x42, 0xD6, 0x94,
        0x9F, 0xAF, 0x59, 0x21, 0xF2, 0xE3, 0x73, 0xD4,
        0x50, 0xC8, 0xC0, 0x9D, 0x07, 0xB1, 0x52, 0xA9,
        0x7C, 0x24, 0x54, 0x47, 0x42, 0x94, 0x81, 0xD4,
        0x98, 0xBE, 0xB7, 0x25, 0x6B, 0xC4, 0x7F, 0x68,
        0xF9, 0x92, 0x2B, 0x0B, 0x1C, 0x62, 0xD9, 0xC2,
        0x3F, 0x9F, 0x73, 0x3D, 0xD7, 0x37, 0x92, 0xCF,
        0xC7, 0xB4, 0x3C, 0xBC, 0xEA, 0x27, 0x7D, 0x51,
        0xB2, 0xB8, 0xAD, 0x4A, 0x4F, 0x52, 0x2F, 0x64,
        0x2C, 0xAD, 0x5C, 0x5D, 0xEB, 0x21, 0xF3, 0x62,
        0x7F, 0x8A, 0xF4, 0xD3, 0xE5, 0xBC, 0x9E, 0x91,
        0xD4, 0xCB, 0x2F, 0x12, 0x4B, 0x5B, 0xD7, 0xC2,
        0xF4, 0xA0, 0x50, 0xCA, 0x75, 0x5B, 0xDB, 0x80,
        0x56, 0x60, 0x96, 0x63, 0xFB, 0x95, 0x11, 0xC9,
        0xAD, 0x83, 0xB5, 0x03, 0x90, 0x88, 0xCC, 0x01,
        0xF0, 0xDD, 0x54, 0x35, 0x3B, 0x0D, 0xD7, 0x43,
        0x3F, 0x0C, 0x6C, 0xEE, 0x0D, 0x07, 0x59, 0x59,
        0x81, 0x0D, 0xEC, 0x54, 0x16, 0x52, 0x2B, 0xB1,
        0xF1, 0xF6, 0x55, 0x47, 0xA0, 0xC2, 0xE9, 0xCC,
        0x9B, 0xC1, 0x7F, 0x8D, 0x39, 0xD2, 0x93, 0x09,
        0xEB, 0xE7, 0x9F, 0x21, 0x33, 0x1B, 0x75, 0xE1,
        0x2A, 0xF2, 0xE9, 0x3F, 0x03, 0xF7, 0x4F, 0x7F,
        0x87, 0xD3, 0x60, 0xF1, 0xDA, 0xF8, 0x6C, 0xED,
        0x73, 0x60, 0x92, 0xA2, 0x11, 0xA8, 0x15, 0x88,
        0x59, 0xC4, 0x2E, 0x22, 0x3C, 0xFE, 0x2E, 0x6E,
        0x55, 0x34, 0x37, 0xD8, 0x05, 0x76, 0xCF, 0xD1,
        0x94, 0x4E, 0x97, 0xEE, 0xFF, 0x9B, 0x49, 0xE5,
        0xEC, 0xCF, 0xC6, 0x78, 0xEE, 0x16, 0x52, 0x68,
        0xDF, 0xE3, 0xD3, 0x59, 0x6B, 0x4B, 0x86, 0x20,
        0x4A, 0x81, 0xC6, 0x06, 0x3B, 0x0C, 0xDC, 0xE6,
        0x19, 0xFD, 0xBB, 0x96, 0xDF, 0x7D, 0xE6, 0xE0,
        0xBD, 0x52, 0x70, 0xB4, 0xD5, 0x9C, 0x4D, 0xC5,
        0x08, 0x47, 0x6E, 0x7F, 0x07, 0x08, 0xF9, 0x8C,
        0x7A, 0x4F, 0x66, 0x45, 0xC4, 0x9D, 0x06, 0x10,
        0x0C, 0x76, 0x0C, 0x59, 0x95, 0x28, 0xD1, 0xB8,
        0xBB, 0xFE, 0x62, 0x81, 0x91, 0xCC, 0x08, 0x3C,
        0x8D, 0x22, 0x5A, 0x09, 0x3F, 0x9F, 0x17, 0xE3,
        0x55, 0x74, 0x98, 0x6F, 0x86, 0xBA, 0xA4, 0x68,
        0x98, 0xB5, 0x89, 0xF3, 0xCB, 0x7D, 0xB4, 0x6A,
        0x45, 0xF3, 0xED, 0xD4, 0xFA, 0xC2, 0x08, 0x08,
        0xF4, 0xCD, 0x02, 0x49, 0xDA, 0x69, 0x3F, 0x8F,
        0xAB, 0xFB, 0xD4, 0xE1, 0x0C, 0x02, 0xC6, 0x5B,
        0xA8, 0xC8, 0x61, 0x0F, 0xA8, 0xC6, 0xDF, 0x3D,
        0xBA, 0xEB, 0x67, 0x63, 0xDD, 0x48, 0x2A, 0xF4,
        0x15, 0x58, 0xB1, 0xE1, 0x5C, 0xC9, 0xC7, 0xA7,
        0x2E, 0x07, 0x16, 0x85, 0xAC, 0x19, 0xA0, 0x51,
        0xF1, 0x92, 0x45, 0xB9, 0xF7, 0x7C, 0x30, 0x38,
        0xA5, 0x4E, 0x29, 0x58, 0x62, 0x3E, 0xB8, 0x10,
        0x59, 0x55, 0x60, 0x9E, 0x27, 0xD6, 0x7C, 0xF7,
        0x2E, 0xC5, 0xC4, 0xA8, 0xE9, 0xB9, 0xC2, 0x92,
        0x4A, 0x9E, 0x22, 0x98, 0x50, 0x8B, 0xAB, 0xA1,
        0x3C, 0xF1, 0x11, 0xFD, 0xFB, 0x06, 0x2C, 0x96,
        0x07, 0xAC, 0x1A, 0xAA, 0x6C, 0x63, 0x73, 0x10,
        0xA8, 0x89, 0x4B, 0xF0, 0xB9, 0x6F, 0x0C, 0x19,
        0x13, 0x61, 0x86, 0xB6, 0x18, 0xDF, 0xFB, 0x27,
        0x55, 0x28, 0xBE, 0xD1, 0xCC, 0x27, 0x15, 0xDE,
        0xF4, 0x12, 0xF7, 0x7A, 0x3C, 0xF9, 0x66, 0x45,
        0x73, 0x3B, 0x04, 0x8A, 0x78, 0x47, 0x43, 0x20,
        0xD1, 0xA3, 0x80, 0xF5, 0xEE, 0xDB, 0xDA, 0x21,
        0xFA, 0x01, 0x25, 0xC9, 0x1D, 0x3C, 0x37, 0xC5,
        0x4B, 0xF3, 0x75, 0x2A, 0x1F, 0x84, 0x71, 0xC8,
        0x1F, 0xCA, 0xE2, 0xD3, 0xED, 0xA9, 0x66, 0xE1,
        0x4E, 0x66, 0xF2, 0x23, 0xB0, 0x54, 0xD7, 0x98,
        0x48, 0xFF, 0x94, 0x11, 0xD6, 0x34, 0x02, 0x4A,
        0x09, 0x89, 0x70, 0xAD, 0xE6, 0xA8, 0x8B, 0x5F,
        0x90, 0x69, 0xF7, 0x60, 0x58, 0x4D, 0xC4, 0xCF,
        0xFF, 0xCE, 0xA8, 0xEC, 0xE1, 0x1B, 0xB5, 0x56,
        0x6B, 0xD2, 0x36, 0x0A, 0xB7, 0x07, 0xDF, 0x2D,
        0x21, 0xB6, 0x74, 0x88, 0xD9, 0x31, 0xF0, 0x20,
        0x06, 0x91, 0x76, 0x42, 0x3E, 0x69, 0x44, 0x49,
        0x0C, 0xB3, 0x85, 0xE7, 0x0B, 0x35, 0x8A, 0x25,
        0x34, 0x6B, 0xAF, 0xCD, 0xD0, 0x6D, 0x40, 0x2F,
        0xF2, 0x4D, 0x6C, 0x1E, 0x5F, 0x61, 0xA8, 0x5D
    };
    static const byte kprime_512[KYBER_SS_SZ] = {
        0xDF, 0x46, 0x2A, 0xD6, 0x8F, 0x1E, 0xC8, 0x97,
        0x2E, 0xD9, 0xB0, 0x2D, 0x6D, 0xE0, 0x60, 0x4B,
        0xDE, 0xC7, 0x57, 0x20, 0xE0, 0x50, 0x49, 0x73,
        0x51, 0xE6, 0xEC, 0x93, 0x3E, 0x71, 0xF8, 0x82
    };
#endif
#ifndef WOLFSSL_NO_KYBER768
    static const byte dk_768[KYBER768_PRIVATE_KEY_SIZE] = {
        0x1E, 0x4A, 0xC8, 0x7B, 0x1A, 0x69, 0x2A, 0x52,
        0x9F, 0xDB, 0xBA, 0xB9, 0x33, 0x74, 0xC5, 0x7D,
        0x11, 0x0B, 0x10, 0xF2, 0xB1, 0xDD, 0xEB, 0xAC,
        0x0D, 0x19, 0x6B, 0x7B, 0xA6, 0x31, 0xB8, 0xE9,
        0x29, 0x30, 0x28, 0xA8, 0xF3, 0x79, 0x88, 0x8C,
        0x42, 0x2D, 0xC8, 0xD3, 0x2B, 0xBF, 0x22, 0x60,
        0x10, 0xC2, 0xC1, 0xEC, 0x73, 0x18, 0x90, 0x80,
        0x45, 0x6B, 0x05, 0x64, 0xB2, 0x58, 0xB0, 0xF2,
        0x31, 0x31, 0xBC, 0x79, 0xC8, 0xE8, 0xC1, 0x1C,
        0xEF, 0x39, 0x38, 0xB2, 0x43, 0xC5, 0xCE, 0x9C,
        0x0E, 0xDD, 0x37, 0xC8, 0xF9, 0xD2, 0x98, 0x77,
        0xDB, 0xBB, 0x61, 0x5B, 0x9B, 0x5A, 0xC3, 0xC9,
        0x48, 0x48, 0x7E, 0x46, 0x71, 0x96, 0xA9, 0x14,
        0x3E, 0xFB, 0xC7, 0xCE, 0xDB, 0x64, 0xB4, 0x5D,
        0x4A, 0xCD, 0xA2, 0x66, 0x6C, 0xBC, 0x28, 0x04,
        0xF2, 0xC8, 0x66, 0x2E, 0x12, 0x8F, 0x6A, 0x99,
        0x69, 0xEC, 0x15, 0xBC, 0x0B, 0x93, 0x51, 0xF6,
        0xF9, 0x63, 0x46, 0xAA, 0x7A, 0xBC, 0x74, 0x3A,
        0x14, 0xFA, 0x03, 0x0E, 0x37, 0xA2, 0xE7, 0x59,
        0x7B, 0xDD, 0xFC, 0x5A, 0x22, 0xF9, 0xCE, 0xDA,
        0xF8, 0x61, 0x48, 0x32, 0x52, 0x72, 0x10, 0xB2,
        0x6F, 0x02, 0x4C, 0x7F, 0x6C, 0x0D, 0xCF, 0x55,
        0x1E, 0x97, 0xA4, 0x85, 0x87, 0x64, 0xC3, 0x21,
        0xD1, 0x83, 0x4A, 0xD5, 0x1D, 0x75, 0xBB, 0x24,
        0x6D, 0x27, 0x72, 0x37, 0xB7, 0xBD, 0x41, 0xDC,
        0x43, 0x62, 0xD0, 0x63, 0xF4, 0x29, 0x82, 0x92,
        0x27, 0x2D, 0x01, 0x01, 0x17, 0x80, 0xB7, 0x98,
        0x56, 0xB2, 0x96, 0xC4, 0xE9, 0x46, 0x65, 0x8B,
        0x79, 0x60, 0x31, 0x97, 0xC9, 0xB2, 0xA9, 0x9E,
        0xC6, 0x6A, 0xCB, 0x06, 0xCE, 0x2F, 0x69, 0xB5,
        0xA5, 0xA6, 0x1E, 0x9B, 0xD0, 0x6A, 0xD4, 0x43,
        0xCE, 0xB0, 0xC7, 0x4E, 0xD6, 0x53, 0x45, 0xA9,
        0x03, 0xB6, 0x14, 0xE8, 0x13, 0x68, 0xAA, 0xC2,
        0xB3, 0xD2, 0xA7, 0x9C, 0xA8, 0xCC, 0xAA, 0x1C,
        0x3B, 0x88, 0xFB, 0x82, 0xA3, 0x66, 0x32, 0x86,
        0x0B, 0x3F, 0x79, 0x50, 0x83, 0x3F, 0xD0, 0x21,
        0x2E, 0xC9, 0x6E, 0xDE, 0x4A, 0xB6, 0xF5, 0xA0,
        0xBD, 0xA3, 0xEC, 0x60, 0x60, 0xA6, 0x58, 0xF9,
        0x45, 0x7F, 0x6C, 0xC8, 0x7C, 0x6B, 0x62, 0x0C,
        0x1A, 0x14, 0x51, 0x98, 0x74, 0x86, 0xE4, 0x96,
        0x61, 0x2A, 0x10, 0x1D, 0x0E, 0x9C, 0x20, 0x57,
        0x7C, 0x57, 0x1E, 0xDB, 0x52, 0x82, 0x60, 0x8B,
        0xF4, 0xE1, 0xAC, 0x92, 0x6C, 0x0D, 0xB1, 0xC8,
        0x2A, 0x50, 0x4A, 0x79, 0x9D, 0x89, 0x88, 0x5C,
        0xA6, 0x25, 0x2B, 0xD5, 0xB1, 0xC1, 0x83, 0xAF,
        0x70, 0x13, 0x92, 0xA4, 0x07, 0xC0, 0x5B, 0x84,
        0x8C, 0x2A, 0x30, 0x16, 0xC4, 0x06, 0x13, 0xF0,
        0x2A, 0x44, 0x9B, 0x3C, 0x79, 0x26, 0xDA, 0x06,
        0x7A, 0x53, 0x31, 0x16, 0x50, 0x68, 0x40, 0x09,
        0x75, 0x10, 0x46, 0x0B, 0xBF, 0xD3, 0x60, 0x73,
        0xDC, 0xB0, 0xBF, 0xA0, 0x09, 0xB3, 0x6A, 0x91,
        0x23, 0xEA, 0xA6, 0x8F, 0x83, 0x5F, 0x74, 0xA0,
        0x1B, 0x00, 0xD2, 0x09, 0x78, 0x35, 0x96, 0x4D,
        0xF5, 0x21, 0xCE, 0x92, 0x10, 0x78, 0x9C, 0x30,
        0xB7, 0xF0, 0x6E, 0x58, 0x44, 0xB4, 0x44, 0xC5,
        0x33, 0x22, 0x39, 0x6E, 0x47, 0x99, 0xBA, 0xF6,
        0xA8, 0x8A, 0xF7, 0x31, 0x58, 0x60, 0xD0, 0x19,
        0x2D, 0x48, 0xC2, 0xC0, 0xDA, 0x6B, 0x5B, 0xA6,
        0x43, 0x25, 0x54, 0x3A, 0xCD, 0xF5, 0x90, 0x0E,
        0x8B, 0xC4, 0x77, 0xAB, 0x05, 0x82, 0x00, 0x72,
        0xD4, 0x63, 0xAF, 0xFE, 0xD0, 0x97, 0xE0, 0x62,
        0xBD, 0x78, 0xC9, 0x9D, 0x12, 0xB3, 0x85, 0x13,
        0x1A, 0x24, 0x1B, 0x70, 0x88, 0x65, 0xB4, 0x19,
        0x0A, 0xF6, 0x9E, 0xA0, 0xA6, 0x4D, 0xB7, 0x14,
        0x48, 0xA6, 0x08, 0x29, 0x36, 0x9C, 0x75, 0x55,
        0x19, 0x8E, 0x43, 0x8C, 0x9A, 0xBC, 0x31, 0x0B,
        0xC7, 0x01, 0x01, 0x91, 0x3B, 0xB1, 0x2F, 0xAA,
        0x5B, 0xEE, 0xF9, 0x75, 0x84, 0x16, 0x17, 0xC8,
        0x47, 0xCD, 0x6B, 0x33, 0x6F, 0x87, 0x79, 0x87,
        0x75, 0x38, 0x22, 0x02, 0x0B, 0x92, 0xC4, 0xCC,
        0x97, 0x05, 0x5C, 0x9B, 0x1E, 0x0B, 0x12, 0x8B,
        0xF1, 0x1F, 0x50, 0x50, 0x05, 0xB6, 0xAB, 0x0E,
        0x62, 0x77, 0x95, 0xA2, 0x06, 0x09, 0xEF, 0xA9,
        0x91, 0xE5, 0x98, 0xB8, 0x0F, 0x37, 0xB1, 0xC6,
        0xA1, 0xC3, 0xA1, 0xE9, 0xAE, 0xE7, 0x02, 0x8F,
        0x77, 0x57, 0x0A, 0xB2, 0x13, 0x91, 0x28, 0xA0,
        0x01, 0x08, 0xC5, 0x0E, 0xB3, 0x05, 0xCD, 0xB8,
        0xF9, 0xA6, 0x03, 0xA6, 0xB0, 0x78, 0x41, 0x3F,
        0x6F, 0x9B, 0x14, 0xC6, 0xD8, 0x2B, 0x51, 0x99,
        0xCE, 0x59, 0xD8, 0x87, 0x90, 0x2A, 0x28, 0x1A,
        0x02, 0x7B, 0x71, 0x74, 0x95, 0xFE, 0x12, 0x67,
        0x2A, 0x12, 0x7B, 0xBF, 0x9B, 0x25, 0x6C, 0x43,
        0x72, 0x0D, 0x7C, 0x16, 0x0B, 0x28, 0x1C, 0x12,
        0x75, 0x7D, 0xA1, 0x35, 0xB1, 0x93, 0x33, 0x52,
        0xBE, 0x4A, 0xB6, 0x7E, 0x40, 0x24, 0x8A, 0xFC,
        0x31, 0x8E, 0x23, 0x70, 0xC3, 0xB8, 0x20, 0x8E,
        0x69, 0x5B, 0xDF, 0x33, 0x74, 0x59, 0xB9, 0xAC,
        0xBF, 0xE5, 0xB4, 0x87, 0xF7, 0x6E, 0x9B, 0x4B,
        0x40, 0x01, 0xD6, 0xCF, 0x90, 0xCA, 0x8C, 0x69,
        0x9A, 0x17, 0x4D, 0x42, 0x97, 0x2D, 0xC7, 0x33,
        0xF3, 0x33, 0x89, 0xFD, 0xF5, 0x9A, 0x1D, 0xAB,
        0xA8, 0x1D, 0x83, 0x49, 0x55, 0x02, 0x73, 0x34,
        0x18, 0x5A, 0xD0, 0x2C, 0x76, 0xCF, 0x29, 0x48,
        0x46, 0xCA, 0x92, 0x94, 0xBA, 0x0E, 0xD6, 0x67,
        0x41, 0xDD, 0xEC, 0x79, 0x1C, 0xAB, 0x34, 0x19,
        0x6A, 0xC5, 0x65, 0x7C, 0x5A, 0x78, 0x32, 0x1B,
        0x56, 0xC3, 0x33, 0x06, 0xB5, 0x10, 0x23, 0x97,
        0xA5, 0xC0, 0x9C, 0x35, 0x08, 0xF7, 0x6B, 0x48,
        0x28, 0x24, 0x59, 0xF8, 0x1D, 0x0C, 0x72, 0xA4,
        0x3F, 0x73, 0x7B, 0xC2, 0xF1, 0x2F, 0x45, 0x42,
        0x26, 0x28, 0xB6, 0x7D, 0xB5, 0x1A, 0xC1, 0x42,
        0x42, 0x76, 0xA6, 0xC0, 0x8C, 0x3F, 0x76, 0x15,
        0x66, 0x5B, 0xBB, 0x8E, 0x92, 0x81, 0x48, 0xA2,
        0x70, 0xF9, 0x91, 0xBC, 0xF3, 0x65, 0xA9, 0x0F,
        0x87, 0xC3, 0x06, 0x87, 0xB6, 0x88, 0x09, 0xC9,
        0x1F, 0x23, 0x18, 0x13, 0xB8, 0x66, 0xBE, 0xA8,
        0x2E, 0x30, 0x37, 0x4D, 0x80, 0xAA, 0x0C, 0x02,
        0x97, 0x34, 0x37, 0x49, 0x8A, 0x53, 0xB1, 0x4B,
        0xF6, 0xB6, 0xCA, 0x1E, 0xD7, 0x6A, 0xB8, 0xA2,
        0x0D, 0x54, 0xA0, 0x83, 0xF4, 0xA2, 0x6B, 0x7C,
        0x03, 0x8D, 0x81, 0x96, 0x76, 0x40, 0xC2, 0x0B,
        0xF4, 0x43, 0x1E, 0x71, 0xDA, 0xCC, 0xE8, 0x57,
        0x7B, 0x21, 0x24, 0x0E, 0x49, 0x4C, 0x31, 0xF2,
        0xD8, 0x77, 0xDA, 0xF4, 0x92, 0x4F, 0xD3, 0x9D,
        0x82, 0xD6, 0x16, 0x7F, 0xBC, 0xC1, 0xF9, 0xC5,
        0xA2, 0x59, 0xF8, 0x43, 0xE3, 0x09, 0x87, 0xCC,
        0xC4, 0xBC, 0xE7, 0x49, 0x3A, 0x24, 0x04, 0xB5,
        0xE4, 0x43, 0x87, 0xF7, 0x07, 0x42, 0x57, 0x81,
        0xB7, 0x43, 0xFB, 0x55, 0x56, 0x85, 0x58, 0x4E,
        0x25, 0x57, 0xCC, 0x03, 0x8B, 0x1A, 0x9B, 0x3F,
        0x40, 0x43, 0x12, 0x1F, 0x54, 0x72, 0xEB, 0x2B,
        0x96, 0xE5, 0x94, 0x1F, 0xEC, 0x01, 0x1C, 0xEE,
        0xA5, 0x07, 0x91, 0x63, 0x6C, 0x6A, 0xBC, 0x26,
        0xC1, 0x37, 0x7E, 0xE3, 0xB5, 0x14, 0x6F, 0xC7,
        0xC8, 0x5C, 0xB3, 0x35, 0xB1, 0xE7, 0x95, 0xEE,
        0xC2, 0x03, 0x3E, 0xE4, 0x4B, 0x9A, 0xA9, 0x06,
        0x85, 0x24, 0x5E, 0xF7, 0xB4, 0x43, 0x6C, 0x00,
        0x0E, 0x66, 0xBC, 0x8B, 0xCB, 0xF1, 0xCD, 0xB8,
        0x03, 0xAC, 0x14, 0x21, 0xB1, 0xFD, 0xB2, 0x66,
        0xD5, 0x29, 0x1C, 0x83, 0x10, 0x37, 0x3A, 0x8A,
        0x3C, 0xE9, 0x56, 0x2A, 0xB1, 0x97, 0x95, 0x38,
        0x71, 0xAB, 0x99, 0xF3, 0x82, 0xCC, 0x5A, 0xA9,
        0xC0, 0xF2, 0x73, 0xD1, 0xDC, 0xA5, 0x5D, 0x27,
        0x12, 0x85, 0x38, 0x71, 0xE1, 0xA8, 0x3C, 0xB3,
        0xB8, 0x54, 0x50, 0xF7, 0x6D, 0x3F, 0x3C, 0x42,
        0xBA, 0xB5, 0x50, 0x5F, 0x72, 0x12, 0xFD, 0xB6,
        0xB8, 0xB7, 0xF6, 0x02, 0x99, 0x72, 0xA8, 0xF3,
        0x75, 0x1E, 0x4C, 0x94, 0xC1, 0x10, 0x8B, 0x02,
        0xD6, 0xAC, 0x79, 0xF8, 0xD9, 0x38, 0xF0, 0x5A,
        0x1B, 0x2C, 0x22, 0x9B, 0x14, 0xB4, 0x2B, 0x31,
        0xB0, 0x1A, 0x36, 0x40, 0x17, 0xE5, 0x95, 0x78,
        0xC6, 0xB0, 0x33, 0x83, 0x37, 0x74, 0xCB, 0x9B,
        0x57, 0x0F, 0x90, 0x86, 0xB7, 0x22, 0x90, 0x3B,
        0x37, 0x54, 0x46, 0xB4, 0x95, 0xD8, 0xA2, 0x9B,
        0xF8, 0x07, 0x51, 0x87, 0x7A, 0x80, 0xFB, 0x72,
        0x4A, 0x02, 0x10, 0xC3, 0xE1, 0x69, 0x2F, 0x39,
        0x7C, 0x2F, 0x1D, 0xDC, 0x2E, 0x6B, 0xA1, 0x7A,
        0xF8, 0x1B, 0x92, 0xAC, 0xFA, 0xBE, 0xF5, 0xF7,
        0x57, 0x3C, 0xB4, 0x93, 0xD1, 0x84, 0x02, 0x7B,
        0x71, 0x82, 0x38, 0xC8, 0x9A, 0x35, 0x49, 0xB8,
        0x90, 0x5B, 0x28, 0xA8, 0x33, 0x62, 0x86, 0x7C,
        0x08, 0x2D, 0x30, 0x19, 0xD3, 0xCA, 0x70, 0x70,
        0x07, 0x31, 0xCE, 0xB7, 0x3E, 0x84, 0x72, 0xC1,
        0xA3, 0xA0, 0x93, 0x36, 0x1C, 0x5F, 0xEA, 0x6A,
        0x7D, 0x40, 0x95, 0x5D, 0x07, 0xA4, 0x1B, 0x64,
        0xE5, 0x00, 0x81, 0xA3, 0x61, 0xB6, 0x04, 0xCC,
        0x51, 0x84, 0x47, 0xC8, 0xE2, 0x57, 0x65, 0xAB,
        0x7D, 0x68, 0xB2, 0x43, 0x27, 0x52, 0x07, 0xAF,
        0x8C, 0xA6, 0x56, 0x4A, 0x4C, 0xB1, 0xE9, 0x41,
        0x99, 0xDB, 0xA1, 0x87, 0x8C, 0x59, 0xBE, 0xC8,
        0x09, 0xAB, 0x48, 0xB2, 0xF2, 0x11, 0xBA, 0xDC,
        0x6A, 0x19, 0x98, 0xD9, 0xC7, 0x22, 0x7C, 0x13,
        0x03, 0xF4, 0x69, 0xD4, 0x6A, 0x9C, 0x7E, 0x53,
        0x03, 0xF9, 0x8A, 0xBA, 0x67, 0x56, 0x9A, 0xE8,
        0x22, 0x7C, 0x16, 0xBA, 0x1F, 0xB3, 0x24, 0x44,
        0x66, 0xA2, 0x5E, 0x7F, 0x82, 0x36, 0x71, 0x81,
        0x0C, 0xC2, 0x62, 0x06, 0xFE, 0xB2, 0x9C, 0x7E,
        0x2A, 0x1A, 0x91, 0x95, 0x9E, 0xEB, 0x03, 0xA9,
        0x82, 0x52, 0xA4, 0xF7, 0x41, 0x26, 0x74, 0xEB,
        0x9A, 0x4B, 0x27, 0x7E, 0x1F, 0x25, 0x95, 0xFC,
        0xA6, 0x40, 0x33, 0xB4, 0x1B, 0x40, 0x33, 0x08,
        0x12, 0xE9, 0x73, 0x5B, 0x7C, 0x60, 0x75, 0x01,
        0xCD, 0x81, 0x83, 0xA2, 0x2A, 0xFC, 0x33, 0x92,
        0x55, 0x37, 0x44, 0xF3, 0x3C, 0x4D, 0x20, 0x25,
        0x26, 0x94, 0x5C, 0x6D, 0x78, 0xA6, 0x0E, 0x20,
        0x1A, 0x16, 0x98, 0x7A, 0x6F, 0xA5, 0x9D, 0x94,
        0x46, 0x4B, 0x56, 0x50, 0x65, 0x56, 0x78, 0x48,
        0x24, 0xA0, 0x70, 0x58, 0xF5, 0x73, 0x20, 0xE7,
        0x6C, 0x82, 0x5B, 0x93, 0x47, 0xF2, 0x93, 0x6F,
        0x4A, 0x0E, 0x5C, 0xDA, 0xA1, 0x8C, 0xF8, 0x83,
        0x39, 0x45, 0xAE, 0x31, 0x2A, 0x36, 0xB5, 0xF5,
        0xA3, 0x81, 0x0A, 0xAC, 0x82, 0x38, 0x1F, 0xDA,
        0xE4, 0xCB, 0x9C, 0x68, 0x31, 0xD8, 0xEB, 0x8A,
        0xBA, 0xB8, 0x50, 0x41, 0x64, 0x43, 0xD7, 0x39,
        0x08, 0x6B, 0x1C, 0x32, 0x6F, 0xC2, 0xA3, 0x97,
        0x57, 0x04, 0xE3, 0x96, 0xA5, 0x96, 0x80, 0xC3,
        0xB5, 0xF3, 0x60, 0xF5, 0x48, 0x0D, 0x2B, 0x62,
        0x16, 0x9C, 0xD9, 0x4C, 0xA7, 0x1B, 0x37, 0xBC,
        0x58, 0x78, 0xBA, 0x29, 0x85, 0xE0, 0x68, 0xBA,
        0x05, 0x0B, 0x2C, 0xE5, 0x07, 0x26, 0xD4, 0xB4,
        0x45, 0x1B, 0x77, 0xAA, 0xA8, 0x67, 0x6E, 0xAE,
        0x09, 0x49, 0x82, 0x21, 0x01, 0x92, 0x19, 0x7B,
        0x1E, 0x92, 0xA2, 0x7F, 0x59, 0x86, 0x8B, 0x78,
        0x86, 0x78, 0x87, 0xB9, 0xA7, 0x0C, 0x32, 0xAF,
        0x84, 0x63, 0x0A, 0xA9, 0x08, 0x81, 0x43, 0x79,
        0xE6, 0x51, 0x91, 0x50, 0xBA, 0x16, 0x43, 0x9B,
        0x5E, 0x2B, 0x06, 0x03, 0xD0, 0x6A, 0xA6, 0x67,
        0x45, 0x57, 0xF5, 0xB0, 0x98, 0x3E, 0x5C, 0xB6,
        0xA9, 0x75, 0x96, 0x06, 0x9B, 0x01, 0xBB, 0x31,
        0x28, 0xC4, 0x16, 0x68, 0x06, 0x57, 0x20, 0x4F,
        0xD0, 0x76, 0x40, 0x39, 0x2E, 0x16, 0xB1, 0x9F,
        0x33, 0x7A, 0x99, 0xA3, 0x04, 0x84, 0x4E, 0x1A,
        0xA4, 0x74, 0xE9, 0xC7, 0x99, 0x06, 0x29, 0x71,
        0xF6, 0x72, 0x26, 0x89, 0x60, 0xF5, 0xA8, 0x2F,
        0x95, 0x00, 0x70, 0xBB, 0xE9, 0xC2, 0xA7, 0x19,
        0x50, 0xA3, 0x78, 0x5B, 0xDF, 0x0B, 0x84, 0x40,
        0x25, 0x5E, 0xD6, 0x39, 0x28, 0xD2, 0x57, 0x84,
        0x51, 0x68, 0xB1, 0xEC, 0xCC, 0x41, 0x91, 0x32,
        0x5A, 0xA7, 0x66, 0x45, 0x71, 0x9B, 0x28, 0xEB,
        0xD8, 0x93, 0x02, 0xDC, 0x67, 0x23, 0xC7, 0x86,
        0xDF, 0x52, 0x17, 0xB2, 0x43, 0x09, 0x9C, 0xA7,
        0x82, 0x38, 0xE5, 0x7E, 0x64, 0x69, 0x2F, 0x20,
        0x6B, 0x17, 0x7A, 0xBC, 0x25, 0x96, 0x60, 0x39,
        0x5C, 0xD7, 0x86, 0x0F, 0xB3, 0x5A, 0x16, 0xF6,
        0xB2, 0xFE, 0x65, 0x48, 0xC8, 0x5A, 0xB6, 0x63,
        0x30, 0xC5, 0x17, 0xFA, 0x74, 0xCD, 0xF3, 0xCB,
        0x49, 0xD2, 0x6B, 0x11, 0x81, 0x90, 0x1A, 0xF7,
        0x75, 0xA1, 0xE1, 0x80, 0x81, 0x3B, 0x6A, 0x24,
        0xC4, 0x56, 0x82, 0x9B, 0x5C, 0x38, 0x10, 0x4E,
        0xCE, 0x43, 0xC7, 0x6A, 0x43, 0x7A, 0x6A, 0x33,
        0xB6, 0xFC, 0x6C, 0x5E, 0x65, 0xC8, 0xA8, 0x94,
        0x66, 0xC1, 0x42, 0x54, 0x85, 0xB2, 0x9B, 0x9E,
        0x18, 0x54, 0x36, 0x8A, 0xFC, 0xA3, 0x53, 0xE1,
        0x43, 0xD0, 0xA9, 0x0A, 0x6C, 0x6C, 0x9E, 0x7F,
        0xDB, 0x62, 0xA6, 0x06, 0x85, 0x6B, 0x56, 0x14,
        0xF1, 0x2B, 0x64, 0xB7, 0x96, 0x02, 0x0C, 0x35,
        0x34, 0xC3, 0x60, 0x5C, 0xFD, 0xC7, 0x3B, 0x86,
        0x71, 0x4F, 0x41, 0x18, 0x50, 0x22, 0x8A, 0x28,
        0xB8, 0xF4, 0xB4, 0x9E, 0x66, 0x34, 0x16, 0xC8,
        0x4F, 0x7E, 0x38, 0x1F, 0x6A, 0xF1, 0x07, 0x13,
        0x43, 0xBF, 0x9D, 0x39, 0xB4, 0x54, 0x39, 0x24,
        0x0C, 0xC0, 0x38, 0x97, 0x29, 0x5F, 0xEA, 0x08,
        0x0B, 0x14, 0xBB, 0x2D, 0x81, 0x19, 0xA8, 0x80,
        0xE1, 0x64, 0x49, 0x5C, 0x61, 0xBE, 0xBC, 0x71,
        0x39, 0xC1, 0x18, 0x57, 0xC8, 0x5E, 0x17, 0x50,
        0x33, 0x8D, 0x63, 0x43, 0x91, 0x37, 0x06, 0xA5,
        0x07, 0xC9, 0x56, 0x64, 0x64, 0xCD, 0x28, 0x37,
        0xCF, 0x91, 0x4D, 0x1A, 0x3C, 0x35, 0xE8, 0x9B,
        0x23, 0x5C, 0x6A, 0xB7, 0xED, 0x07, 0x8B, 0xED,
        0x23, 0x47, 0x57, 0xC0, 0x2E, 0xF6, 0x99, 0x3D,
        0x4A, 0x27, 0x3C, 0xB8, 0x15, 0x05, 0x28, 0xDA,
        0x4D, 0x76, 0x70, 0x81, 0x77, 0xE9, 0x42, 0x55,
        0x46, 0xC8, 0x3E, 0x14, 0x70, 0x39, 0x76, 0x66,
        0x03, 0xB3, 0x0D, 0xA6, 0x26, 0x8F, 0x45, 0x98,
        0xA5, 0x31, 0x94, 0x24, 0x0A, 0x28, 0x32, 0xA3,
        0xD6, 0x75, 0x33, 0xB5, 0x05, 0x6F, 0x9A, 0xAA,
        0xC6, 0x1B, 0x4B, 0x17, 0xB9, 0xA2, 0x69, 0x3A,
        0xA0, 0xD5, 0x88, 0x91, 0xE6, 0xCC, 0x56, 0xCD,
        0xD7, 0x72, 0x41, 0x09, 0x00, 0xC4, 0x05, 0xAF,
        0x20, 0xB9, 0x03, 0x79, 0x7C, 0x64, 0x87, 0x69,
        0x15, 0xC3, 0x7B, 0x84, 0x87, 0xA1, 0x44, 0x9C,
        0xE9, 0x24, 0xCD, 0x34, 0x5C, 0x29, 0xA3, 0x6E,
        0x08, 0x23, 0x8F, 0x7A, 0x15, 0x7C, 0xC7, 0xE5,
        0x16, 0xAB, 0x5B, 0xA7, 0x3C, 0x80, 0x63, 0xF7,
        0x26, 0xBB, 0x5A, 0x0A, 0x03, 0x19, 0xE5, 0x71,
        0x27, 0x43, 0x8C, 0x7F, 0xC6, 0x01, 0xC9, 0x9C,
        0xCA, 0xAE, 0x4C, 0x1A, 0x83, 0x72, 0x6F, 0xDC,
        0xB5, 0x04, 0x5E, 0xD1, 0xA8, 0x2A, 0x98, 0x5E,
        0xA9, 0x95, 0x39, 0x6D, 0x77, 0x27, 0x2C, 0x66,
        0xCE, 0x49, 0x32, 0x89, 0xF6, 0x11, 0x09, 0x10,
        0xF3, 0x7C, 0x27, 0x41, 0xCE, 0x47, 0x02, 0x6A,
        0x6F, 0x82, 0x61, 0x99, 0x9C, 0x64, 0x82, 0x57,
        0x2B, 0x16, 0x93, 0x91, 0x2E, 0xF1, 0x2E, 0xEB,
        0xEA, 0x7A, 0xCF, 0x92, 0x34, 0xFB, 0x40, 0x9F,
        0x2A, 0x60, 0x90, 0xE6, 0xB0, 0xBF, 0xD8, 0x95,
        0x46, 0x9D, 0x0B, 0x2A, 0x92, 0x1B, 0xB7, 0x23,
        0xF8, 0x7A, 0x33, 0xEA, 0x54, 0x65, 0xAB, 0x90,
        0xF5, 0x14, 0xB6, 0x76, 0x98, 0xC0, 0x76, 0x8B,
        0x6C, 0xA4, 0x98, 0xB0, 0x22, 0xC5, 0x12, 0xFA,
        0x08, 0x75, 0xF0, 0x54, 0xAA, 0x22, 0x65, 0x86,
        0x7E, 0x31, 0xC0, 0xE5, 0x22, 0x65, 0x1E, 0x02,
        0x4A, 0x07, 0xD6, 0x0D, 0xD9, 0xF6, 0x33, 0x16,
        0x69, 0x21, 0xF4, 0x12, 0x6B, 0xC2, 0xB6, 0xAA,
        0x01, 0xCC, 0x15, 0xA0, 0x9B, 0x85, 0xBF, 0xF8,
        0x21, 0x8C, 0x5A, 0xAE, 0x95, 0xBC, 0x1F, 0xFB,
        0x26, 0xAE, 0x5A, 0x13, 0x76, 0x70, 0xF0, 0x49,
        0x10, 0xCA, 0x9D, 0x72, 0x41, 0xB6, 0x66, 0x0C,
        0x39, 0x4C, 0x54, 0x55, 0x91, 0x77, 0x46, 0xA2,
        0x66, 0x82, 0xFB, 0x71, 0xA4, 0x32, 0xEA, 0x95,
        0x30, 0xE8, 0x39, 0xBD, 0xEB, 0x07, 0x43, 0x30,
        0x04, 0xF4, 0x5A, 0x0D, 0xDA, 0xA0, 0xB2, 0x4E,
        0x3A, 0x56, 0x6A, 0x54, 0x08, 0x15, 0xF2, 0x81,
        0xE3, 0xFC, 0x25, 0x9A, 0xC6, 0xCB, 0xC0, 0xAC,
        0xB8, 0xD6, 0x22, 0x68, 0xB6, 0x03, 0xBC, 0x67,
        0x6A, 0xB4, 0x15, 0xC4, 0x74, 0xBB, 0x94, 0x87,
        0x3E, 0x44, 0x87, 0xAE, 0x31, 0xA4, 0xE3, 0x84,
        0x5C, 0x79, 0x90, 0x15, 0x50, 0x89, 0x0E, 0xE8,
        0x78, 0x4E, 0xEF, 0x90, 0x4F, 0xEE, 0x62, 0xBA,
        0x8C, 0x5F, 0x95, 0x2C, 0x68, 0x41, 0x30, 0x52,
        0xE0, 0xA7, 0xE3, 0x38, 0x8B, 0xB8, 0xFF, 0x0A,
        0xD6, 0x02, 0xAE, 0x3E, 0xA1, 0x4D, 0x9D, 0xF6,
        0xDD, 0x5E, 0x4C, 0xC6, 0xA3, 0x81, 0xA4, 0x1D,
        0xA5, 0xC1, 0x37, 0xEC, 0xC4, 0x9D, 0xF5, 0x87,
        0xE1, 0x78, 0xEA, 0xF4, 0x77, 0x02, 0xEC, 0x62,
        0x37, 0x80, 0x69, 0x1A, 0x32, 0x33, 0xF6, 0x9F,
        0x12, 0xBD, 0x9C, 0x9B, 0x96, 0x37, 0xC5, 0x13,
        0x78, 0xAD, 0x71, 0xA8, 0x31, 0x05, 0x52, 0x77,
        0x25, 0x4C, 0xC6, 0x3C, 0x5A, 0xD4, 0xCB, 0x76,
        0xB4, 0xAB, 0x82, 0xE5, 0xFC, 0xA1, 0x35, 0xE8,
        0xD2, 0x6A, 0x6B, 0x3A, 0x89, 0xFA, 0x5B, 0x6F
    };
    static const byte c_768[KYBER768_CIPHER_TEXT_SIZE] = {
        0xA5, 0xC8, 0x1C, 0x76, 0xC2, 0x43, 0x05, 0xE1,
        0xCE, 0x5D, 0x81, 0x35, 0xD4, 0x15, 0x23, 0x68,
        0x2E, 0x9E, 0xE6, 0xD7, 0xB4, 0x0A, 0xD4, 0x1D,
        0xF1, 0xF3, 0x7C, 0x9B, 0x17, 0xDC, 0xE7, 0x80,
        0x76, 0x01, 0x9A, 0x6B, 0x0B, 0x7C, 0x95, 0xC9,
        0xBE, 0x7A, 0xF2, 0x95, 0x07, 0xB2, 0xD5, 0xA6,
        0x98, 0x7C, 0x8E, 0xE3, 0x25, 0x91, 0x90, 0x85,
        0x52, 0x43, 0xE6, 0xE5, 0x6F, 0x56, 0x20, 0x60,
        0x8C, 0x52, 0xD9, 0x6F, 0xAB, 0x10, 0x3A, 0x87,
        0x00, 0xFB, 0xA1, 0xA8, 0x7D, 0xCA, 0x60, 0x78,
        0x11, 0x8A, 0x08, 0x71, 0x76, 0x2C, 0x95, 0x34,
        0xC0, 0xC0, 0xC3, 0x97, 0x8C, 0x91, 0xC3, 0xA0,
        0x1F, 0x0F, 0x60, 0x8D, 0xCF, 0x75, 0x78, 0x15,
        0x43, 0x8F, 0xE8, 0x95, 0x7C, 0x8A, 0x85, 0x91,
        0x83, 0xB1, 0xB6, 0x72, 0x1A, 0x08, 0x65, 0xBE,
        0xBC, 0x79, 0x9D, 0x4E, 0x5C, 0x0E, 0x7B, 0xD3,
        0xEA, 0xE4, 0x85, 0x8E, 0x6A, 0xB6, 0xA2, 0xE7,
        0x65, 0x8E, 0xD8, 0x0D, 0x4E, 0xD1, 0x58, 0xB0,
        0x36, 0xB9, 0x3F, 0xA0, 0x3A, 0xFA, 0x6A, 0xE3,
        0x13, 0x6C, 0xF3, 0xD6, 0x93, 0xC9, 0x11, 0xBC,
        0xC7, 0x59, 0x05, 0xE5, 0xB0, 0xCB, 0x28, 0x65,
        0xB9, 0xE9, 0x88, 0x45, 0x22, 0xA7, 0x77, 0x77,
        0x61, 0x3E, 0x53, 0x11, 0x1D, 0x5A, 0x1C, 0x7D,
        0x3D, 0xAB, 0x73, 0x4C, 0xEB, 0x03, 0x65, 0x7A,
        0xE0, 0xC8, 0x97, 0x63, 0xE9, 0x94, 0x71, 0x05,
        0x47, 0x76, 0xBA, 0xE7, 0xD5, 0x1B, 0x0E, 0x73,
        0xA5, 0xBB, 0x35, 0xAE, 0xC3, 0x0F, 0xF6, 0xBC,
        0x93, 0x68, 0x49, 0x16, 0xFE, 0xF1, 0x16, 0x25,
        0x86, 0x45, 0x2F, 0x42, 0x66, 0x53, 0xE2, 0xCA,
        0x84, 0x4D, 0x57, 0x44, 0x30, 0x7F, 0xF9, 0xAE,
        0xB2, 0x87, 0xA6, 0x44, 0x77, 0x83, 0xB2, 0x1A,
        0x0E, 0x93, 0x9C, 0x81, 0x42, 0x1D, 0x63, 0x1F,
        0x5D, 0xCB, 0x45, 0x2E, 0x51, 0xED, 0x34, 0xE3,
        0xDA, 0xD1, 0xCF, 0x50, 0x4E, 0x0A, 0x3B, 0x0F,
        0x47, 0x11, 0xA8, 0xDC, 0x64, 0x99, 0xD1, 0x69,
        0x1D, 0x10, 0x95, 0x69, 0x33, 0x6C, 0xE1, 0x55,
        0x8A, 0x4C, 0x0A, 0x46, 0x4E, 0x20, 0x87, 0xEA,
        0x8F, 0x9E, 0x3B, 0x18, 0xF7, 0x47, 0xEF, 0x61,
        0xF4, 0x57, 0x6A, 0xEB, 0x42, 0xB1, 0x7C, 0xAD,
        0xB7, 0xF0, 0xFD, 0x84, 0xDA, 0x8E, 0x3A, 0x6F,
        0x47, 0x1D, 0x95, 0xED, 0xFA, 0x65, 0xBE, 0x9E,
        0x6C, 0x9F, 0x6A, 0xE7, 0x56, 0xA2, 0x2A, 0x4F,
        0x1A, 0x5C, 0x54, 0x3C, 0x26, 0xBA, 0x7B, 0xAD,
        0x88, 0xE1, 0x6D, 0x5F, 0x5B, 0x7E, 0x12, 0xE2,
        0xD4, 0xCA, 0x34, 0xB3, 0xA6, 0x4D, 0x17, 0xF8,
        0x7C, 0xCF, 0xC4, 0xFF, 0x8C, 0x5E, 0x4F, 0x53,
        0x75, 0x2A, 0x07, 0x7C, 0x68, 0x72, 0x1E, 0x8C,
        0xC8, 0x17, 0xF9, 0xFF, 0x24, 0x87, 0x61, 0x70,
        0xFF, 0x2A, 0xF8, 0x9F, 0xA9, 0x58, 0x55, 0xA5,
        0xB1, 0xDE, 0x34, 0x7C, 0x07, 0xFD, 0xDB, 0xCF,
        0xE7, 0x26, 0x4A, 0xA5, 0xED, 0x64, 0x01, 0x49,
        0x15, 0x61, 0xD8, 0x31, 0x53, 0x8F, 0x85, 0x2B,
        0x0E, 0xD7, 0xB9, 0xE8, 0xEB, 0xAF, 0xFC, 0x06,
        0x02, 0x84, 0xF2, 0x2D, 0x2B, 0xAE, 0xE5, 0x6F,
        0xA9, 0xF6, 0xD0, 0x14, 0x32, 0xA1, 0x15, 0xA2,
        0xD6, 0xA6, 0x4C, 0x38, 0xAE, 0x0A, 0x50, 0xBA,
        0x36, 0x2F, 0xB5, 0x7B, 0x53, 0xE3, 0xE8, 0x55,
        0xB8, 0x3C, 0xE8, 0xC4, 0x22, 0x74, 0x04, 0x55,
        0x99, 0xF6, 0x5F, 0xA6, 0xA8, 0x92, 0x1D, 0x85,
        0xF9, 0x4E, 0xD2, 0x30, 0xB5, 0x16, 0x71, 0x2D,
        0xB6, 0xFD, 0x2F, 0xF2, 0x8B, 0x3A, 0x33, 0x71,
        0xD9, 0xBE, 0x05, 0x8A, 0xE7, 0x5C, 0x2F, 0xA5,
        0x91, 0xB7, 0xEC, 0x3C, 0x3D, 0xAA, 0x1F, 0x76,
        0x42, 0xBC, 0x26, 0xC3, 0x24, 0xC0, 0x80, 0x90,
        0x60, 0x7E, 0x66, 0x62, 0x15, 0x4D, 0xB3, 0x7C,
        0xF7, 0x47, 0x96, 0x7A, 0x1F, 0x9F, 0xC2, 0x90,
        0x89, 0xF5, 0x70, 0xEB, 0xE6, 0x0E, 0xEE, 0xF8,
        0x9F, 0xD2, 0x44, 0x81, 0x02, 0x8C, 0x85, 0xAE,
        0xF1, 0xDC, 0x3B, 0x09, 0xF2, 0x2C, 0xD3, 0x69,
        0x1B, 0xBB, 0xB8, 0x21, 0xC7, 0xA8, 0xA0, 0xF3,
        0x5A, 0xD1, 0x2B, 0xE1, 0xDD, 0x19, 0x9B, 0x97,
        0x70, 0x48, 0xF3, 0xD4, 0x8C, 0x16, 0xBB, 0x2C,
        0xA9, 0x4C, 0xEC, 0xB8, 0x92, 0x87, 0x70, 0xD5,
        0xBB, 0x32, 0x9A, 0x03, 0x27, 0xE0, 0xB2, 0x86,
        0xFA, 0xA1, 0xC6, 0x52, 0x81, 0x03, 0x1A, 0x31,
        0xC8, 0x4F, 0x2E, 0xDC, 0x9C, 0x04, 0xD4, 0x75,
        0xED, 0x4E, 0x12, 0x8E, 0x51, 0xEF, 0xA9, 0x7D,
        0x01, 0x48, 0xCB, 0xA6, 0xC9, 0x5F, 0x67, 0x4C,
        0x58, 0x9F, 0x30, 0x1C, 0x26, 0x5B, 0xED, 0x70,
        0x8E, 0x9A, 0xD8, 0xDA, 0x3C, 0x5C, 0xEC, 0xBD,
        0xEE, 0xED, 0x35, 0xEF, 0x1E, 0x25, 0x31, 0x32,
        0xBA, 0x89, 0x92, 0x0D, 0x78, 0x6B, 0x88, 0x23,
        0x0B, 0x01, 0x3B, 0xCF, 0x2D, 0xC9, 0x2D, 0x6B,
        0x15, 0x7A, 0xFA, 0x8D, 0xA8, 0x59, 0x2C, 0xD0,
        0x74, 0x3D, 0x49, 0x82, 0xBE, 0x60, 0xD7, 0xC2,
        0xD5, 0xC4, 0x72, 0xAB, 0x9F, 0xA7, 0xF4, 0xCC,
        0x3D, 0x12, 0xB0, 0xEB, 0xAF, 0x0A, 0xBE, 0x55,
        0x5C, 0x75, 0x80, 0x54, 0x26, 0x84, 0x4D, 0xD9,
        0x42, 0x86, 0x43, 0xF8, 0x44, 0x06, 0xA1, 0xB8,
        0xD6, 0xFA, 0xED, 0xFD, 0x8A, 0xE6, 0xE7, 0x3A,
        0x72, 0x77, 0x2A, 0x21, 0x59, 0xAC, 0xAB, 0xD9,
        0x72, 0xAE, 0xB6, 0xF7, 0xDE, 0x09, 0x1A, 0xC5,
        0xFD, 0xD7, 0xF4, 0x9A, 0x3D, 0xC6, 0x64, 0x1C,
        0xDF, 0x62, 0x44, 0x6B, 0x4B, 0x04, 0xA3, 0x1F,
        0x73, 0xB8, 0x0A, 0x62, 0xF8, 0x0A, 0x40, 0x4A,
        0x8C, 0xB1, 0x8C, 0xE3, 0xE6, 0x54, 0x80, 0xEF,
        0x7B, 0x52, 0xBF, 0x00, 0x91, 0x11, 0x7E, 0x5D,
        0x08, 0xEA, 0xE1, 0xB0, 0xAA, 0xBB, 0x72, 0xE6,
        0xDF, 0xFF, 0xF7, 0x6F, 0x6E, 0x44, 0xBB, 0xD7,
        0xEA, 0x57, 0x0D, 0x66, 0x04, 0xBC, 0x2E, 0x74,
        0x31, 0x8B, 0xAF, 0xA3, 0x15, 0xA3, 0x88, 0x61,
        0xAA, 0x1B, 0x21, 0xAF, 0xB2, 0xA5, 0x3F, 0x26,
        0x14, 0xF1, 0xD6, 0x40, 0x07, 0x59, 0x84, 0xAE,
        0x62, 0xE2, 0xFC, 0xA1, 0xD1, 0xB4, 0xDB, 0x36,
        0x9F, 0x15, 0x70, 0x5C, 0xE7, 0xD4, 0xDF, 0x8A,
        0xE9, 0x82, 0x64, 0x50, 0x10, 0x51, 0xC0, 0xDE,
        0xF2, 0x1D, 0x64, 0x5D, 0x49, 0x62, 0x5A, 0xF0,
        0x2C, 0xA4, 0x28, 0xD9, 0xF0, 0xC2, 0xCD, 0x9F,
        0xBA, 0xEE, 0xAB, 0x97, 0xE8, 0xE9, 0x15, 0x16,
        0x62, 0xB6, 0x99, 0x2B, 0x4C, 0x99, 0xAB, 0x1B,
        0x92, 0x5D, 0x08, 0x92, 0x03, 0x63, 0x37, 0x3F,
        0x76, 0xD3, 0xFD, 0xF0, 0x82, 0x8C, 0xAA, 0x69,
        0xC8, 0xB1, 0xBD, 0xC6, 0xF5, 0x21, 0xDF, 0x64,
        0x1C, 0xF1, 0xC8, 0xA4, 0xE7, 0xEF, 0x0C, 0x23,
        0x28, 0x9A, 0x4E, 0x2C, 0xF1, 0x8A, 0xCE, 0xBB,
        0xE4, 0xC1, 0xE6, 0x83, 0x69, 0xBD, 0x52, 0x35,
        0x12, 0x01, 0x42, 0xEC, 0xDD, 0x1A, 0x73, 0x81,
        0x1E, 0x2E, 0x53, 0x3A, 0x64, 0x7D, 0x7A, 0xEE,
        0x16, 0xDA, 0xA0, 0x3B, 0x68, 0x36, 0x39, 0xDC,
        0xF1, 0xE1, 0xF1, 0xE7, 0x1C, 0xFA, 0xED, 0x48,
        0xF6, 0x9A, 0xEC, 0x3E, 0x83, 0x17, 0x33, 0xDA,
        0x19, 0xCE, 0xBE, 0xC1, 0xDD, 0xBF, 0x71, 0xCB,
        0xAE, 0x08, 0x00, 0xF2, 0xF6, 0xD6, 0x4A, 0x09,
        0x6E, 0xC4, 0x95, 0xD6, 0x2F, 0x43, 0x44, 0xF7,
        0xAA, 0x56, 0x21, 0xB3, 0x22, 0x35, 0x3A, 0x79,
        0x5A, 0xA0, 0x99, 0xEA, 0x3A, 0x07, 0x02, 0x72,
        0xD0, 0x53, 0xD4, 0x65, 0x3A, 0x20, 0xCF, 0x21,
        0x0E, 0xAA, 0xF1, 0x2C, 0xAE, 0x60, 0x23, 0xD8,
        0xE5, 0x11, 0x8D, 0xF0, 0x4B, 0x38, 0x4A, 0x44,
        0xD1, 0xED, 0xB9, 0x1C, 0x44, 0x98, 0x9E, 0xF7,
        0xEE, 0x57, 0xF2, 0xBF, 0x81, 0xA2, 0x4B, 0xDC,
        0x76, 0x80, 0x7D, 0xA9, 0x67, 0xEE, 0x65, 0x25,
        0x41, 0x0C, 0x5C, 0x48, 0x50, 0x67, 0xEF, 0xC3,
        0xD3, 0x9A, 0x9A, 0xD4, 0x2C, 0xC7, 0x53, 0xBA,
        0xA5, 0x9A, 0x1F, 0xD2, 0x8A, 0xF3, 0x5C, 0x00,
        0xD1, 0x8A, 0x40, 0x6A, 0x28, 0xFC, 0x79, 0xBA
    };
    static const byte kprime_768[KYBER_SS_SZ] = {
        0xDC, 0x5B, 0x88, 0x88, 0xBC, 0x1E, 0xBA, 0x5C,
        0x19, 0x69, 0xC2, 0x11, 0x64, 0xEA, 0x43, 0xE2,
        0x2E, 0x7A, 0xC0, 0xCD, 0x01, 0x2A, 0x2F, 0x26,
        0xCB, 0x8C, 0x48, 0x7E, 0x69, 0xEF, 0x7C, 0xE4
    };
#endif
#ifndef WOLFSSL_NO_KYBER1024
    static const byte dk_1024[KYBER1024_PRIVATE_KEY_SIZE] = {
        0x84, 0x45, 0xC3, 0x36, 0xF3, 0x51, 0x8B, 0x29,
        0x81, 0x63, 0xDC, 0xBB, 0x63, 0x57, 0x59, 0x79,
        0x83, 0xCA, 0x2E, 0x87, 0x3D, 0xCB, 0x49, 0x61,
        0x0C, 0xF5, 0x2F, 0x14, 0xDB, 0xCB, 0x94, 0x7C,
        0x1F, 0x3E, 0xE9, 0x26, 0x69, 0x67, 0x27, 0x6B,
        0x0C, 0x57, 0x6C, 0xF7, 0xC3, 0x0E, 0xE6, 0xB9,
        0x3D, 0xEA, 0x51, 0x18, 0x67, 0x6C, 0xBE, 0xE1,
        0xB1, 0xD4, 0x79, 0x42, 0x06, 0xFB, 0x36, 0x9A,
        0xBA, 0x41, 0x16, 0x7B, 0x43, 0x93, 0x85, 0x5C,
        0x84, 0xEB, 0xA8, 0xF3, 0x23, 0x73, 0xC0, 0x5B,
        0xAE, 0x76, 0x31, 0xC8, 0x02, 0x74, 0x4A, 0xAD,
        0xB6, 0xC2, 0xDE, 0x41, 0x25, 0x0C, 0x49, 0x43,
        0x15, 0x23, 0x0B, 0x52, 0x82, 0x6C, 0x34, 0x58,
        0x7C, 0xB2, 0x1B, 0x18, 0x3B, 0x49, 0xB2, 0xA5,
        0xAC, 0x04, 0x92, 0x1A, 0xC6, 0xBF, 0xAC, 0x1B,
        0x24, 0xA4, 0xB3, 0x7A, 0x93, 0xA4, 0xB1, 0x68,
        0xCC, 0xE7, 0x59, 0x1B, 0xE6, 0x11, 0x1F, 0x47,
        0x62, 0x60, 0xF2, 0x76, 0x29, 0x59, 0xF5, 0xC1,
        0x64, 0x01, 0x18, 0xC2, 0x42, 0x37, 0x72, 0xE2,
        0xAD, 0x03, 0xDC, 0x71, 0x68, 0xA3, 0x8C, 0x6D,
        0xD3, 0x9F, 0x5F, 0x72, 0x54, 0x26, 0x42, 0x80,
        0xC8, 0xBC, 0x10, 0xB9, 0x14, 0x16, 0x80, 0x70,
        0x47, 0x2F, 0xA8, 0x80, 0xAC, 0xB8, 0x60, 0x1A,
        0x8A, 0x08, 0x37, 0xF2, 0x5F, 0xE1, 0x94, 0x68,
        0x7C, 0xD6, 0x8B, 0x7D, 0xE2, 0x34, 0x0F, 0x03,
        0x6D, 0xAD, 0x89, 0x1D, 0x38, 0xD1, 0xB0, 0xCE,
        0x9C, 0x26, 0x33, 0x35, 0x5C, 0xF5, 0x7B, 0x50,
        0xB8, 0x96, 0x03, 0x6F, 0xCA, 0x26, 0x0D, 0x26,
        0x69, 0xF8, 0x5B, 0xAC, 0x79, 0x71, 0x4F, 0xDA,
        0xFB, 0x41, 0xEF, 0x80, 0xB8, 0xC3, 0x02, 0x64,
        0xC3, 0x13, 0x86, 0xAE, 0x60, 0xB0, 0x5F, 0xAA,
        0x54, 0x2A, 0x26, 0xB4, 0x1E, 0xB8, 0x5F, 0x67,
        0x06, 0x8F, 0x08, 0x80, 0x34, 0xFF, 0x67, 0xAA,
        0x2E, 0x81, 0x5A, 0xAB, 0x8B, 0xCA, 0x6B, 0xF7,
        0x1F, 0x70, 0xEC, 0xC3, 0xCB, 0xCB, 0xC4, 0x5E,
        0xF7, 0x01, 0xFC, 0xD5, 0x42, 0xBD, 0x21, 0xC7,
        0xB0, 0x95, 0x68, 0xF3, 0x69, 0xC6, 0x69, 0xF3,
        0x96, 0x47, 0x38, 0x44, 0xFB, 0xA1, 0x49, 0x57,
        0xF5, 0x19, 0x74, 0xD8, 0x52, 0xB9, 0x78, 0x01,
        0x46, 0x03, 0xA2, 0x10, 0xC0, 0x19, 0x03, 0x62,
        0x87, 0x00, 0x89, 0x94, 0xF2, 0x12, 0x55, 0xB2,
        0x50, 0x99, 0xAD, 0x82, 0xAA, 0x13, 0x24, 0x38,
        0x96, 0x3B, 0x2C, 0x0A, 0x47, 0xCD, 0xF5, 0xF3,
        0x2B, 0xA4, 0x6B, 0x76, 0xC7, 0xA6, 0x55, 0x9F,
        0x18, 0xBF, 0xD5, 0x55, 0xB7, 0x62, 0xE4, 0x87,
        0xB6, 0xAC, 0x99, 0x2F, 0xE2, 0x0E, 0x28, 0x3C,
        0xA0, 0xB3, 0xF6, 0x16, 0x44, 0x96, 0x95, 0x59,
        0x95, 0xC3, 0xB2, 0x8A, 0x57, 0xBB, 0xC2, 0x98,
        0x26, 0xF0, 0x6F, 0xB3, 0x8B, 0x25, 0x34, 0x70,
        0xAF, 0x63, 0x1B, 0xC4, 0x6C, 0x3A, 0x8F, 0x9C,
        0xE8, 0x24, 0x32, 0x19, 0x85, 0xDD, 0x01, 0xC0,
        0x5F, 0x69, 0xB8, 0x24, 0xF9, 0x16, 0x63, 0x3B,
        0x40, 0x65, 0x4C, 0x75, 0xAA, 0xEB, 0x93, 0x85,
        0x57, 0x6F, 0xFD, 0xE2, 0x99, 0x0A, 0x6B, 0x0A,
        0x3B, 0xE8, 0x29, 0xD6, 0xD8, 0x4E, 0x34, 0xF1,
        0x78, 0x05, 0x89, 0xC7, 0x92, 0x04, 0xC6, 0x3C,
        0x79, 0x8F, 0x55, 0xD2, 0x31, 0x87, 0xE4, 0x61,
        0xD4, 0x8C, 0x21, 0xE5, 0xC0, 0x47, 0xE5, 0x35,
        0xB1, 0x9F, 0x45, 0x8B, 0xBA, 0x13, 0x45, 0xB9,
        0xE4, 0x1E, 0x0C, 0xB4, 0xA9, 0xC2, 0xD8, 0xC4,
        0x0B, 0x49, 0x0A, 0x3B, 0xAB, 0xC5, 0x53, 0xB3,
        0x02, 0x6B, 0x16, 0x72, 0xD2, 0x8C, 0xBC, 0x8B,
        0x49, 0x8A, 0x3A, 0x99, 0x57, 0x9A, 0x83, 0x2F,
        0xEA, 0xE7, 0x46, 0x10, 0xF0, 0xB6, 0x25, 0x0C,
        0xC3, 0x33, 0xE9, 0x49, 0x3E, 0xB1, 0x62, 0x1E,
        0xD3, 0x4A, 0xA4, 0xAB, 0x17, 0x5F, 0x2C, 0xA2,
        0x31, 0x15, 0x25, 0x09, 0xAC, 0xB6, 0xAC, 0x86,
        0xB2, 0x0F, 0x6B, 0x39, 0x10, 0x84, 0x39, 0xE5,
        0xEC, 0x12, 0xD4, 0x65, 0xA0, 0xFE, 0xF3, 0x50,
        0x03, 0xE1, 0x42, 0x77, 0xA2, 0x18, 0x12, 0x14,
        0x6B, 0x25, 0x44, 0x71, 0x6D, 0x6A, 0xB8, 0x2D,
        0x1B, 0x07, 0x26, 0xC2, 0x7A, 0x98, 0xD5, 0x89,
        0xEB, 0xDA, 0xCC, 0x4C, 0x54, 0xBA, 0x77, 0xB2,
        0x49, 0x8F, 0x21, 0x7E, 0x14, 0xE3, 0x4E, 0x66,
        0x02, 0x5A, 0x2A, 0x14, 0x3A, 0x99, 0x25, 0x20,
        0xA6, 0x1C, 0x06, 0x72, 0xCC, 0x9C, 0xCE, 0xD7,
        0xC9, 0x45, 0x0C, 0x68, 0x3E, 0x90, 0xA3, 0xE4,
        0x65, 0x1D, 0xB6, 0x23, 0xA6, 0xDB, 0x39, 0xAC,
        0x26, 0x12, 0x5B, 0x7F, 0xC1, 0x98, 0x6D, 0x7B,
        0x04, 0x93, 0xB8, 0xB7, 0x2D, 0xE7, 0x70, 0x7D,
        0xC2, 0x0B, 0xBD, 0xD4, 0x37, 0x13, 0x15, 0x6A,
        0xF7, 0xD9, 0x43, 0x0E, 0xF4, 0x53, 0x99, 0x66,
        0x3C, 0x22, 0x02, 0x73, 0x91, 0x68, 0x69, 0x2D,
        0xD6, 0x57, 0x54, 0x5B, 0x05, 0x6D, 0x9C, 0x92,
        0x38, 0x5A, 0x7F, 0x41, 0x4B, 0x34, 0xB9, 0x0C,
        0x79, 0x60, 0xD5, 0x7B, 0x35, 0xBA, 0x7D, 0xDE,
        0x7B, 0x81, 0xFC, 0xA0, 0x11, 0x9D, 0x74, 0x1B,
        0x12, 0x78, 0x09, 0x26, 0x01, 0x8F, 0xE4, 0xC8,
        0x03, 0x0B, 0xF0, 0x38, 0xE1, 0x8B, 0x4F, 0xA3,
        0x37, 0x43, 0xD0, 0xD3, 0xC8, 0x46, 0x41, 0x7E,
        0x9D, 0x59, 0x15, 0xC2, 0x46, 0x31, 0x59, 0x38,
        0xB1, 0xE2, 0x33, 0x61, 0x45, 0x01, 0xD0, 0x26,
        0x95, 0x95, 0x51, 0x25, 0x8B, 0x23, 0x32, 0x30,
        0xD4, 0x28, 0xB1, 0x81, 0xB1, 0x32, 0xF1, 0xD0,
        0xB0, 0x26, 0x06, 0x7B, 0xA8, 0x16, 0x99, 0x9B,
        0xC0, 0xCD, 0x6B, 0x54, 0x7E, 0x54, 0x8B, 0x63,
        0xC9, 0xEA, 0xA0, 0x91, 0xBA, 0xC4, 0x93, 0xDC,
        0x59, 0x8D, 0xBC, 0x2B, 0x0E, 0x14, 0x6A, 0x25,
        0x91, 0xC2, 0xA8, 0xC0, 0x09, 0xDD, 0x51, 0x70,
        0xAA, 0xE0, 0x27, 0xC5, 0x41, 0xA1, 0xB5, 0xE6,
        0x6E, 0x45, 0xC6, 0x56, 0x12, 0x98, 0x4C, 0x46,
        0x77, 0x04, 0x93, 0xEC, 0x89, 0x6E, 0xF2, 0x5A,
        0xA9, 0x30, 0x5E, 0x9F, 0x06, 0x69, 0x2C, 0xD0,
        0xB2, 0xF0, 0x69, 0x62, 0xE2, 0x05, 0xBE, 0xBE,
        0x11, 0x3A, 0x34, 0xEB, 0xB1, 0xA4, 0x83, 0x0A,
        0x9B, 0x37, 0x49, 0x64, 0x1B, 0xB9, 0x35, 0x00,
        0x7B, 0x23, 0xB2, 0x4B, 0xFE, 0x57, 0x69, 0x56,
        0x25, 0x4D, 0x7A, 0x35, 0xAA, 0x49, 0x6A, 0xC4,
        0x46, 0xC6, 0x7A, 0x7F, 0xEC, 0x85, 0xA6, 0x00,
        0x57, 0xE8, 0x58, 0x06, 0x17, 0xBC, 0xB3, 0xFA,
        0xD1, 0x5C, 0x76, 0x44, 0x0F, 0xED, 0x54, 0xCC,
        0x78, 0x93, 0x94, 0xFE, 0xA2, 0x44, 0x52, 0xCC,
        0x6B, 0x05, 0x85, 0xB7, 0xEB, 0x0A, 0x88, 0xBB,
        0xA9, 0x50, 0x0D, 0x98, 0x00, 0xE6, 0x24, 0x1A,
        0xFE, 0xB5, 0x23, 0xB5, 0x5A, 0x96, 0xA5, 0x35,
        0x15, 0x1D, 0x10, 0x49, 0x57, 0x32, 0x06, 0xE5,
        0x9C, 0x7F, 0xEB, 0x07, 0x09, 0x66, 0x82, 0x36,
        0x34, 0xF7, 0x7D, 0x5F, 0x12, 0x91, 0x75, 0x5A,
        0x24, 0x31, 0x19, 0x62, 0x1A, 0xF8, 0x08, 0x4A,
        0xB7, 0xAC, 0x1E, 0x22, 0xA0, 0x56, 0x8C, 0x62,
        0x01, 0x41, 0x7C, 0xBE, 0x36, 0x55, 0xD8, 0xA0,
        0x8D, 0xD5, 0xB5, 0x13, 0x88, 0x4C, 0x98, 0xD5,
        0xA4, 0x93, 0xFD, 0x49, 0x38, 0x2E, 0xA4, 0x18,
        0x60, 0xF1, 0x33, 0xCC, 0xD6, 0x01, 0xE8, 0x85,
        0x96, 0x64, 0x26, 0xA2, 0xB1, 0xF2, 0x3D, 0x42,
        0xD8, 0x2E, 0x24, 0x58, 0x2D, 0x99, 0x72, 0x51,
        0x92, 0xC2, 0x17, 0x77, 0x46, 0x7B, 0x14, 0x57,
        0xB1, 0xDD, 0x42, 0x9A, 0x0C, 0x41, 0xA5, 0xC3,
        0xD7, 0x04, 0xCE, 0xA0, 0x62, 0x78, 0xC5, 0x99,
        0x41, 0xB4, 0x38, 0xC6, 0x27, 0x27, 0x09, 0x78,
        0x09, 0xB4, 0x53, 0x0D, 0xBE, 0x83, 0x7E, 0xA3,
        0x96, 0xB6, 0xD3, 0x10, 0x77, 0xFA, 0xD3, 0x73,
        0x30, 0x53, 0x98, 0x9A, 0x84, 0x42, 0xAA, 0xC4,
        0x25, 0x5C, 0xB1, 0x63, 0xB8, 0xCA, 0x2F, 0x27,
        0x50, 0x1E, 0xA9, 0x67, 0x30, 0x56, 0x95, 0xAB,
        0xD6, 0x59, 0xAA, 0x02, 0xC8, 0x3E, 0xE6, 0x0B,
        0xB5, 0x74, 0x20, 0x3E, 0x99, 0x37, 0xAE, 0x1C,
        0x62, 0x1C, 0x8E, 0xCB, 0x5C, 0xC1, 0xD2, 0x1D,
        0x55, 0x69, 0x60, 0xB5, 0xB9, 0x16, 0x1E, 0xA9,
        0x6F, 0xFF, 0xEB, 0xAC, 0x72, 0xE1, 0xB8, 0xA6,
        0x15, 0x4F, 0xC4, 0xD8, 0x8B, 0x56, 0xC0, 0x47,
        0x41, 0xF0, 0x90, 0xCB, 0xB1, 0x56, 0xA7, 0x37,
        0xC9, 0xE6, 0xA2, 0x2B, 0xA8, 0xAC, 0x70, 0x4B,
        0xC3, 0x04, 0xF8, 0xE1, 0x7E, 0x5E, 0xA8, 0x45,
        0xFD, 0xE5, 0x9F, 0xBF, 0x78, 0x8C, 0xCE, 0x0B,
        0x97, 0xC8, 0x76, 0x1F, 0x89, 0xA2, 0x42, 0xF3,
        0x05, 0x25, 0x83, 0xC6, 0x84, 0x4A, 0x63, 0x20,
        0x31, 0xC9, 0x64, 0xA6, 0xC4, 0xA8, 0x5A, 0x12,
        0x8A, 0x28, 0x61, 0x9B, 0xA1, 0xBB, 0x3D, 0x1B,
        0xEA, 0x4B, 0x49, 0x84, 0x1F, 0xC8, 0x47, 0x61,
        0x4A, 0x06, 0x68, 0x41, 0xF5, 0x2E, 0xD0, 0xEB,
        0x8A, 0xE0, 0xB8, 0xB0, 0x96, 0xE9, 0x2B, 0x81,
        0x95, 0x40, 0x58, 0x15, 0xB2, 0x31, 0x26, 0x6F,
        0x36, 0xB1, 0x8C, 0x1A, 0x53, 0x33, 0x3D, 0xAB,
        0x95, 0xD2, 0xA9, 0xA3, 0x74, 0xB5, 0x47, 0x8A,
        0x4A, 0x41, 0xFB, 0x87, 0x59, 0x95, 0x7C, 0x9A,
        0xB2, 0x2C, 0xAE, 0x54, 0x5A, 0xB5, 0x44, 0xBA,
        0x8D, 0xD0, 0x5B, 0x83, 0xF3, 0xA6, 0x13, 0xA2,
        0x43, 0x7A, 0xDB, 0x07, 0x3A, 0x96, 0x35, 0xCB,
        0x4B, 0xBC, 0x96, 0x5F, 0xB4, 0x54, 0xCF, 0x27,
        0xB2, 0x98, 0xA4, 0x0C, 0xD0, 0xDA, 0x3B, 0x8F,
        0x9C, 0xA9, 0x9D, 0x8C, 0xB4, 0x28, 0x6C, 0x5E,
        0xB4, 0x76, 0x41, 0x67, 0x96, 0x07, 0x0B, 0xA5,
        0x35, 0xAA, 0xA5, 0x8C, 0xDB, 0x45, 0x1C, 0xD6,
        0xDB, 0x5C, 0xBB, 0x0C, 0xA2, 0x0F, 0x0C, 0x71,
        0xDE, 0x97, 0xC3, 0x0D, 0xA9, 0x7E, 0xC7, 0x90,
        0x6D, 0x06, 0xB4, 0xB9, 0x39, 0x39, 0x60, 0x28,
        0xC4, 0x6B, 0xA0, 0xE7, 0xA8, 0x65, 0xBC, 0x83,
        0x08, 0xA3, 0x81, 0x0F, 0x12, 0x12, 0x00, 0x63,
        0x39, 0xF7, 0xBC, 0x16, 0x9B, 0x16, 0x66, 0xFD,
        0xF4, 0x75, 0x91, 0x1B, 0xBC, 0x8A, 0xAA, 0xB4,
        0x17, 0x55, 0xC9, 0xA8, 0xAA, 0xBF, 0xA2, 0x3C,
        0x0E, 0x37, 0xF8, 0x4F, 0xE4, 0x69, 0x99, 0xE0,
        0x30, 0x49, 0x4B, 0x92, 0x98, 0xEF, 0x99, 0x34,
        0xE8, 0xA6, 0x49, 0xC0, 0xA5, 0xCC, 0xE2, 0xB2,
        0x2F, 0x31, 0x80, 0x9A, 0xFE, 0xD2, 0x39, 0x55,
        0xD8, 0x78, 0x81, 0xD9, 0x9F, 0xC1, 0xD3, 0x52,
        0x89, 0x6C, 0xAC, 0x90, 0x55, 0xBE, 0xA0, 0xD0,
        0x16, 0xCC, 0xBA, 0x78, 0x05, 0xA3, 0xA5, 0x0E,
        0x22, 0x16, 0x30, 0x37, 0x9B, 0xD0, 0x11, 0x35,
        0x22, 0x1C, 0xAD, 0x5D, 0x95, 0x17, 0xC8, 0xCC,
        0x42, 0x63, 0x7B, 0x9F, 0xC0, 0x71, 0x8E, 0x9A,
        0x9B, 0xB4, 0x94, 0x5C, 0x72, 0xD8, 0xD1, 0x1D,
        0x3D, 0x65, 0x9D, 0x83, 0xA3, 0xC4, 0x19, 0x50,
        0x9A, 0xF5, 0xB4, 0x70, 0xDD, 0x89, 0xB7, 0xF3,
        0xAC, 0xCF, 0x5F, 0x35, 0xCF, 0xC3, 0x22, 0x11,
        0x5F, 0xD6, 0x6A, 0x5C, 0xD2, 0x87, 0x56, 0x51,
        0x32, 0x6F, 0x9B, 0x31, 0x68, 0x91, 0x3B, 0xE5,
        0xB9, 0xC8, 0x7A, 0xE0, 0xB0, 0x25, 0xEC, 0x7A,
        0x2F, 0x4A, 0x07, 0x27, 0x50, 0x94, 0x6A, 0xC6,
        0x11, 0x70, 0xA7, 0x82, 0x6D, 0x97, 0x04, 0xC5,
        0xA2, 0x3A, 0x1C, 0x0A, 0x23, 0x25, 0x14, 0x6C,
        0x3B, 0xC1, 0x85, 0x88, 0x26, 0xC6, 0xB3, 0x92,
        0x79, 0xC2, 0xDA, 0x74, 0x38, 0xA3, 0x70, 0xED,
        0x8A, 0x0A, 0xA5, 0x16, 0x9E, 0x3B, 0xEC, 0x29,
        0xED, 0x88, 0x47, 0x87, 0x32, 0x75, 0x8D, 0x45,
        0x41, 0x43, 0xE2, 0x27, 0xF8, 0x59, 0x58, 0x83,
        0x29, 0x78, 0x42, 0xE6, 0xAF, 0x13, 0x3B, 0x17,
        0xE4, 0x81, 0x1B, 0x0F, 0x57, 0x13, 0xAC, 0x73,
        0xB7, 0xE3, 0x47, 0x42, 0x3E, 0xB9, 0x28, 0x22,
        0xD2, 0x30, 0x6F, 0xA1, 0x45, 0x00, 0xA7, 0x20,
        0x7A, 0x06, 0x72, 0x67, 0x20, 0x46, 0x54, 0x4A,
        0xCC, 0x4E, 0xA9, 0xC1, 0x6E, 0xD7, 0x42, 0x1A,
        0x06, 0x9E, 0x0D, 0x73, 0x7A, 0x98, 0x62, 0x85,
        0x19, 0xC6, 0xA2, 0x9A, 0x42, 0x4A, 0x86, 0x8B,
        0x46, 0xD9, 0xA0, 0xCC, 0x7C, 0x6C, 0x9D, 0xDD,
        0x8B, 0x8B, 0xCB, 0xF4, 0x22, 0xC8, 0xF4, 0x8A,
        0x73, 0x14, 0x3D, 0x5A, 0xBB, 0x66, 0xBC, 0x55,
        0x49, 0x94, 0x18, 0x43, 0x08, 0x02, 0xBA, 0xC5,
        0x44, 0x46, 0x3C, 0xC7, 0x31, 0x9D, 0x17, 0x99,
        0x8F, 0x29, 0x41, 0x13, 0x65, 0x76, 0x6D, 0x04,
        0xC8, 0x47, 0xF3, 0x12, 0x9D, 0x90, 0x77, 0xB7,
        0xD8, 0x33, 0x9B, 0xFB, 0x96, 0xA6, 0x73, 0x9C,
        0x3F, 0x6B, 0x74, 0xA8, 0xF0, 0x5F, 0x91, 0x38,
        0xAB, 0x2F, 0xE3, 0x7A, 0xCB, 0x57, 0x63, 0x4D,
        0x18, 0x20, 0xB5, 0x01, 0x76, 0xF5, 0xA0, 0xB6,
        0xBC, 0x29, 0x40, 0xF1, 0xD5, 0x93, 0x8F, 0x19,
        0x36, 0xB5, 0xF9, 0x58, 0x28, 0xB9, 0x2E, 0xB7,
        0x29, 0x73, 0xC1, 0x59, 0x0A, 0xEB, 0x7A, 0x55,
        0x2C, 0xEC, 0xA1, 0x0B, 0x00, 0xC3, 0x03, 0xB7,
        0xC7, 0x5D, 0x40, 0x20, 0x71, 0xA7, 0x9E, 0x2C,
        0x81, 0x0A, 0xF7, 0xC7, 0x45, 0xE3, 0x33, 0x67,
        0x12, 0x49, 0x2A, 0x42, 0x04, 0x3F, 0x29, 0x03,
        0xA3, 0x7C, 0x64, 0x34, 0xCE, 0xE2, 0x0B, 0x1D,
        0x15, 0x9B, 0x05, 0x76, 0x99, 0xFF, 0x9C, 0x1D,
        0x3B, 0xD6, 0x80, 0x29, 0x83, 0x9A, 0x08, 0xF4,
        0x3E, 0x6C, 0x1C, 0x81, 0x99, 0x13, 0x53, 0x2F,
        0x91, 0x1D, 0xD3, 0x70, 0xC7, 0x02, 0x14, 0x88,
        0xE1, 0x1C, 0xB5, 0x04, 0xCB, 0x9C, 0x70, 0x57,
        0x0F, 0xFF, 0x35, 0xB4, 0xB4, 0x60, 0x11, 0x91,
        0xDC, 0x1A, 0xD9, 0xE6, 0xAD, 0xC5, 0xFA, 0x96,
        0x18, 0x79, 0x8D, 0x7C, 0xC8, 0x60, 0xC8, 0x7A,
        0x93, 0x9E, 0x4C, 0xCF, 0x85, 0x33, 0x63, 0x22,
        0x68, 0xCF, 0x1A, 0x51, 0xAF, 0xF0, 0xCB, 0x81,
        0x1C, 0x55, 0x45, 0xCB, 0x16, 0x56, 0xE6, 0x52,
        0x69, 0x47, 0x74, 0x30, 0x69, 0x9C, 0xCD, 0xEA,
        0x38, 0x00, 0x63, 0x0B, 0x78, 0xCD, 0x58, 0x10,
        0x33, 0x4C, 0xCF, 0x02, 0xE0, 0x13, 0xF3, 0xB8,
        0x02, 0x44, 0xE7, 0x0A, 0xCD, 0xB0, 0x60, 0xBB,
        0xE7, 0xA5, 0x53, 0xB0, 0x63, 0x45, 0x6B, 0x2E,
        0xA8, 0x07, 0x47, 0x34, 0x13, 0x16, 0x5C, 0xE5,
        0x7D, 0xD5, 0x63, 0x47, 0x3C, 0xFB, 0xC9, 0x06,
        0x18, 0xAD, 0xE1, 0xF0, 0xB8, 0x88, 0xAA, 0x48,
        0xE7, 0x22, 0xBB, 0x27, 0x51, 0x85, 0x8F, 0xE1,
        0x96, 0x87, 0x44, 0x2A, 0x48, 0xE7, 0xCA, 0x0D,
        0x2A, 0x29, 0xCD, 0x51, 0xBF, 0xD8, 0xF7, 0x8C,
        0x17, 0xB9, 0x66, 0x0B, 0xFB, 0x54, 0xA4, 0x70,
        0xB2, 0xAE, 0x9A, 0x95, 0x5C, 0x6A, 0xB8, 0xD6,
        0xE5, 0xCC, 0x92, 0xAC, 0x8E, 0xD3, 0xC1, 0x85,
        0xDA, 0xA8, 0xBC, 0x29, 0xF0, 0x57, 0x8E, 0xBB,
        0x81, 0x2B, 0x97, 0xC9, 0xE5, 0xA8, 0x48, 0xA6,
        0x38, 0x4D, 0xE4, 0xE7, 0x5A, 0x31, 0x47, 0x0B,
        0x53, 0x06, 0x6A, 0x8D, 0x02, 0x7B, 0xA4, 0x4B,
        0x21, 0x74, 0x9C, 0x04, 0x92, 0x46, 0x5F, 0x90,
        0x72, 0xB2, 0x83, 0x76, 0xC4, 0xE2, 0x90, 0xB3,
        0x0C, 0x18, 0x63, 0xF9, 0xE5, 0xB7, 0x99, 0x96,
        0x08, 0x34, 0x22, 0xBD, 0x8C, 0x27, 0x2C, 0x10,
        0xEC, 0xC6, 0xEB, 0x9A, 0x0A, 0x82, 0x25, 0xB3,
        0x1A, 0xA0, 0xA6, 0x6E, 0x35, 0xB9, 0xC0, 0xB9,
        0xA7, 0x95, 0x82, 0xBA, 0x20, 0xA3, 0xC0, 0x4C,
        0xD2, 0x99, 0x14, 0xF0, 0x83, 0xA0, 0x15, 0x82,
        0x88, 0xBA, 0x4D, 0x6E, 0xB6, 0x2D, 0x87, 0x26,
        0x4B, 0x91, 0x2B, 0xCA, 0x39, 0x73, 0x2F, 0xBD,
        0xE5, 0x36, 0xA3, 0x77, 0xAD, 0x02, 0xB8, 0xC8,
        0x35, 0xD4, 0xA2, 0xF4, 0xE7, 0xB1, 0xCE, 0x11,
        0x5D, 0x0C, 0x86, 0x0B, 0xEA, 0xA7, 0x95, 0x5A,
        0x49, 0xAD, 0x68, 0x95, 0x86, 0xA8, 0x9A, 0x2B,
        0x9F, 0x9B, 0x10, 0xD1, 0x59, 0x5D, 0x2F, 0xC0,
        0x65, 0xAD, 0x01, 0x8A, 0x7D, 0x56, 0xC6, 0x14,
        0x47, 0x1F, 0x8E, 0x94, 0x6F, 0xE8, 0xAB, 0x49,
        0xE8, 0x22, 0x65, 0x91, 0x11, 0x9F, 0xCA, 0xDB,
        0x4F, 0x9A, 0x86, 0x16, 0x31, 0x37, 0x87, 0x36,
        0xB6, 0x68, 0x8B, 0x78, 0x2D, 0x58, 0xE9, 0x7E,
        0x45, 0x72, 0x75, 0x3A, 0x96, 0x64, 0xB6, 0xB8,
        0x53, 0x68, 0x12, 0xB2, 0x59, 0x11, 0xAA, 0x76,
        0xA2, 0x42, 0x37, 0x54, 0x33, 0x19, 0x27, 0x38,
        0xEE, 0xE7, 0x62, 0xF6, 0xB8, 0x43, 0x15, 0xBB,
        0x34, 0x36, 0x23, 0x1E, 0x0A, 0x9B, 0x27, 0x7E,
        0xD2, 0x8A, 0xE0, 0x05, 0x07, 0x28, 0x34, 0x64,
        0x57, 0xE1, 0x34, 0x05, 0x06, 0x2D, 0xB2, 0x80,
        0x4B, 0x8D, 0xA6, 0x0B, 0xB5, 0xC7, 0x93, 0xD4,
        0xCC, 0x0E, 0x10, 0x1C, 0xBA, 0x2D, 0x91, 0x82,
        0xFD, 0x71, 0x24, 0xFF, 0x52, 0xBF, 0x4C, 0xA2,
        0x82, 0x92, 0xAC, 0x26, 0xD6, 0x78, 0x08, 0x89,
        0x53, 0x97, 0x1D, 0xBA, 0x0B, 0x6F, 0xEC, 0x2C,
        0x96, 0x59, 0x35, 0x32, 0x91, 0xC7, 0x0C, 0x5B,
        0x92, 0x45, 0xA0, 0xCA, 0x25, 0x33, 0x04, 0xAF,
        0xD3, 0xC9, 0x51, 0x02, 0xBE, 0xA6, 0x68, 0x75,
        0xC6, 0x20, 0x16, 0x80, 0xB4, 0xBD, 0xA3, 0x86,
        0x87, 0xB6, 0x48, 0xC2, 0x8E, 0xB3, 0x74, 0x78,
        0xE3, 0xBC, 0x00, 0xCA, 0x8A, 0x3C, 0xC2, 0x72,
        0x04, 0x64, 0x2B, 0x42, 0xB6, 0x8F, 0xCB, 0xE7,
        0xB2, 0x1A, 0x36, 0x6D, 0x06, 0x68, 0xA5, 0x02,
        0x9A, 0x7D, 0xEE, 0xF9, 0x4C, 0xDD, 0x6A, 0x95,
        0xD7, 0xEA, 0x89, 0x31, 0x67, 0x3B, 0xF7, 0x11,
        0x2D, 0x40, 0x42, 0x10, 0x7B, 0x1B, 0x8B, 0x97,
        0x00, 0xC9, 0x74, 0xF9, 0xC4, 0xE8, 0x3A, 0x8F,
        0xAC, 0xD8, 0x9B, 0xFE, 0x0C, 0xA3, 0xCC, 0x4C,
        0x2F, 0xCE, 0x80, 0xA0, 0x3D, 0x35, 0x76, 0xC2,
        0x22, 0xA7, 0x92, 0xB7, 0x2B, 0x1F, 0x07, 0x0A,
        0xB7, 0xF6, 0xB6, 0xF2, 0xB5, 0xCA, 0x2A, 0xF5,
        0x05, 0x4A, 0xFA, 0x70, 0xA8, 0x96, 0x99, 0x01,
        0x59, 0xB4, 0x5D, 0x10, 0x03, 0xE2, 0xA0, 0x56,
        0x48, 0x67, 0x5E, 0x59, 0x60, 0x16, 0xF1, 0xB7,
        0x1D, 0xD0, 0xF7, 0xBD, 0xA7, 0xE2, 0x09, 0x7F,
        0xC7, 0x3B, 0x3A, 0x14, 0x3D, 0x12, 0xC7, 0x26,
        0x02, 0x0A, 0xC3, 0x49, 0x58, 0xAD, 0x70, 0x62,
        0xB9, 0x2B, 0x9A, 0xBF, 0x3C, 0xA6, 0xBE, 0x5A,
        0xE2, 0x9F, 0x57, 0x13, 0x5E, 0x62, 0x5A, 0x36,
        0x79, 0x71, 0x83, 0x7E, 0x63, 0x63, 0xD1, 0x53,
        0x20, 0x94, 0xE0, 0x22, 0xA2, 0x34, 0x67, 0xCF,
        0x93, 0x2E, 0x1F, 0x89, 0xB5, 0xB0, 0x80, 0x3C,
        0x1E, 0xC9, 0x9B, 0x58, 0x5A, 0x78, 0xB5, 0x86,
        0x50, 0x96, 0x74, 0x6F, 0x32, 0x25, 0x82, 0x14,
        0xEC, 0xB3, 0x80, 0x65, 0xC9, 0x7F, 0x45, 0x5E,
        0x15, 0x5A, 0xCC, 0x2D, 0xD0, 0x05, 0xA9, 0xC7,
        0x6B, 0xED, 0x59, 0xCD, 0xA7, 0x38, 0x37, 0xD3,
        0x03, 0x50, 0x4E, 0x6C, 0x97, 0x6A, 0x60, 0x6A,
        0x2B, 0xE7, 0xBB, 0xEC, 0x59, 0x48, 0xB9, 0x1A,
        0x34, 0x9E, 0x89, 0x36, 0x68, 0x8C, 0xC0, 0x27,
        0x97, 0x54, 0xB7, 0x43, 0xAB, 0xC5, 0x86, 0x66,
        0xB1, 0x9B, 0x6C, 0x32, 0x60, 0x05, 0x1F, 0x19,
        0x20, 0x6B, 0xB9, 0x62, 0xBB, 0x66, 0x33, 0xEB,
        0x00, 0x48, 0xE3, 0x2B, 0xAA, 0xCC, 0x5B, 0x02,
        0x0D, 0x02, 0xC8, 0x6C, 0xA9, 0x77, 0x0A, 0xD4,
        0x69, 0xDB, 0x54, 0xA1, 0x06, 0xAC, 0x73, 0xA3,
        0x5B, 0x80, 0x57, 0x42, 0x2B, 0x3D, 0xB2, 0x02,
        0xC5, 0xA5, 0xB4, 0xE3, 0xD5, 0x35, 0xF0, 0xFC,
        0x99, 0x32, 0x6C, 0x4B, 0x8B, 0x7B, 0x16, 0xF1,
        0xCB, 0x5A, 0xF9, 0x68, 0x03, 0xFA, 0x8C, 0x19,
        0x5F, 0xC0, 0xBC, 0xED, 0xDA, 0xAF, 0x01, 0x2A,
        0x51, 0x72, 0x8B, 0x76, 0x48, 0x90, 0x82, 0x37,
        0x3C, 0x91, 0xE9, 0x2C, 0x87, 0xAC, 0xCA, 0x79,
        0x51, 0x60, 0x78, 0x2E, 0x3B, 0x0D, 0xD6, 0x43,
        0x54, 0x4B, 0xB9, 0x6A, 0xBC, 0x27, 0x08, 0xD4,
        0x9B, 0x75, 0x9C, 0xF0, 0x57, 0xAA, 0x22, 0x3B,
        0xAF, 0xD9, 0x6A, 0x33, 0x0B, 0xAF, 0x39, 0x81,
        0x0F, 0xE8, 0x67, 0x1B, 0x43, 0x43, 0xC2, 0x97,
        0xDA, 0x1E, 0x19, 0x69, 0xC9, 0x96, 0x21, 0x6A,
        0xB5, 0x10, 0x6D, 0xA6, 0x68, 0x94, 0x1B, 0x16,
        0x0D, 0x44, 0x77, 0x01, 0x71, 0x36, 0xCB, 0xCA,
        0x5B, 0x5A, 0x8D, 0x44, 0xC4, 0xA8, 0xB1, 0xCF,
        0x3E, 0xF7, 0x97, 0x85, 0xE5, 0xAA, 0x25, 0xC3,
        0xA1, 0xAD, 0x6C, 0x24, 0xFD, 0x14, 0x0F, 0x79,
        0x20, 0x7D, 0xE5, 0xA4, 0x99, 0xF8, 0xA1, 0x53,
        0x4F, 0xFA, 0x80, 0x4A, 0xA7, 0xB3, 0x88, 0x9C,
        0xBE, 0x25, 0xC0, 0x41, 0x47, 0x04, 0xAA, 0x57,
        0x89, 0x7F, 0x17, 0x86, 0x23, 0x64, 0xEC, 0xA5,
        0x62, 0x58, 0x00, 0x72, 0x48, 0x81, 0x39, 0x12,
        0xB8, 0x36, 0x49, 0x7F, 0x03, 0x59, 0xC2, 0xF7,
        0x23, 0x8A, 0x05, 0xD3, 0x05, 0xA0, 0xEA, 0x15,
        0x2E, 0x72, 0xB4, 0x44, 0x17, 0xA8, 0x68, 0x13,
        0x4E, 0x91, 0xB3, 0xCA, 0x79, 0x31, 0x23, 0x2F,
        0xD4, 0xC2, 0x5F, 0x8C, 0x2A, 0x49, 0x2A, 0x33,
        0x9C, 0xDC, 0x0A, 0x13, 0x89, 0x67, 0x21, 0x14,
        0x51, 0xF2, 0x56, 0x26, 0x78, 0xFA, 0x14, 0x08,
        0x0A, 0x34, 0x43, 0x6C, 0x42, 0xB0, 0x78, 0x65,
        0xAC, 0x03, 0x6A, 0x81, 0xE9, 0x7A, 0x77, 0x87,
        0xA9, 0x38, 0x02, 0x5C, 0xAF, 0x81, 0x34, 0x50,
        0x36, 0x8B, 0xED, 0x0C, 0x94, 0xB1, 0x85, 0x76,
        0x04, 0x52, 0x64, 0x05, 0xD2, 0x7A, 0x1C, 0x1A,
        0xBC, 0x81, 0xB5, 0xB6, 0xEC, 0x13, 0xC7, 0x19,
        0x30, 0xA9, 0x7D, 0x92, 0x32, 0xCF, 0x70, 0x21,
        0xEF, 0x87, 0xA4, 0xD1, 0x55, 0x32, 0x8E, 0x62,
        0xB5, 0x83, 0xA8, 0x3B, 0x4A, 0xF2, 0x1F, 0x9F,
        0x57, 0x50, 0xF8, 0x57, 0x51, 0x50, 0x42, 0x4F,
        0x63, 0xB8, 0x99, 0xD7, 0x1C, 0xAD, 0x26, 0x7C,
        0x09, 0xE4, 0x46, 0x71, 0x46, 0xE1, 0x6E, 0x9B,
        0x6C, 0x65, 0x3F, 0x00, 0x8C, 0x31, 0x13, 0x75,
        0xE2, 0xE0, 0x06, 0xD4, 0x07, 0x6A, 0x54, 0x6B,
        0x82, 0xF5, 0x31, 0x42, 0x22, 0xF7, 0xC6, 0x54,
        0x31, 0x7E, 0x79, 0xEC, 0x60, 0x35, 0xB7, 0x3F,
        0xAF, 0x49, 0x17, 0x57, 0xE6, 0x1C, 0x82, 0x83,
        0x26, 0xD5, 0x30, 0x44, 0x54, 0x1C, 0x4D, 0x45,
        0x37, 0xAB, 0xD3, 0xEA, 0x1E, 0x67, 0x99, 0x8C,
        0x33, 0x82, 0x97, 0x4C, 0xA7, 0x8A, 0xE1, 0xB1,
        0x96, 0x0E, 0x4A, 0x92, 0x26, 0xB0, 0x21, 0x9A,
        0xB0, 0x70, 0xF0, 0xD7, 0xAA, 0x66, 0xD7, 0x6F,
        0x93, 0x16, 0xAD, 0xB8, 0x0C, 0x54, 0xD6, 0x49,
        0x97, 0x71, 0xB4, 0x71, 0xE8, 0x16, 0x8D, 0x47,
        0xBC, 0xAA, 0x08, 0x32, 0x4A, 0xB6, 0xBA, 0x92,
        0xC3, 0xA7, 0x02, 0x75, 0xF2, 0x4F, 0xA4, 0xDC,
        0x10, 0xE2, 0x51, 0x63, 0x3F, 0xB9, 0x8D, 0x16,
        0x2B, 0xB5, 0x53, 0x72, 0x02, 0xC6, 0xA5, 0x53,
        0xCE, 0x78, 0x41, 0xC4, 0xD4, 0x0B, 0x87, 0x3B,
        0x85, 0xCA, 0x03, 0xA0, 0xA1, 0xE1, 0xCF, 0xAD,
        0xE6, 0xBA, 0x51, 0x80, 0xAB, 0x13, 0x23, 0xCC,
        0xBA, 0x9A, 0x3E, 0x9C, 0x53, 0xD3, 0x75, 0x75,
        0xAB, 0x1F, 0xD9, 0xE7, 0x31, 0x6C, 0x6F, 0xEE,
        0xCB, 0x0A, 0x14, 0xDF, 0x6F, 0x2D, 0xA5, 0x6C,
        0x2F, 0x56, 0xF5, 0x5A, 0x89, 0x63, 0x5C, 0xFC,
        0xFD, 0xA4, 0x79, 0x27, 0xAF, 0x1F, 0x0A, 0x47,
        0xB2, 0xD4, 0xE4, 0xE6, 0x16, 0x34, 0xB1, 0xB5,
        0x1D, 0x37, 0xA3, 0xA3, 0x07, 0xA9, 0x72, 0x42,
        0x0D, 0xE1, 0xB7, 0xA4, 0x81, 0xB8, 0x3E, 0x58,
        0x3B, 0x6A, 0xF1, 0x6F, 0x63, 0xCB, 0x00, 0xC6
    };
    static const byte c_1024[KYBER1024_CIPHER_TEXT_SIZE] = {
        0x0C, 0x68, 0x1B, 0x4A, 0xA8, 0x1F, 0x26, 0xAD,
        0xFB, 0x64, 0x5E, 0xC2, 0x4B, 0x37, 0x52, 0xF6,
        0xB3, 0x2C, 0x68, 0x64, 0x5A, 0xA5, 0xE7, 0xA9,
        0x99, 0xB6, 0x20, 0x36, 0xA5, 0x3D, 0xC5, 0xCB,
        0x06, 0x0A, 0x47, 0x3C, 0x08, 0xE5, 0xDA, 0x5C,
        0x0F, 0x5A, 0xF0, 0xE5, 0x17, 0x0C, 0x65, 0x97,
        0xE5, 0x0E, 0xC0, 0x80, 0x60, 0xF9, 0x9B, 0x0C,
        0x00, 0xEE, 0x9B, 0xDD, 0xAD, 0x7E, 0x7D, 0x25,
        0xA2, 0x2B, 0x22, 0x6F, 0x90, 0x14, 0x9B, 0x4C,
        0xE8, 0x87, 0xC7, 0x2F, 0xB6, 0x0A, 0xFF, 0x21,
        0x44, 0xEA, 0x2A, 0x72, 0x38, 0x3B, 0x31, 0x18,
        0xF9, 0x22, 0xD0, 0x32, 0xA1, 0x6F, 0x55, 0x42,
        0x89, 0x90, 0x2A, 0x14, 0xCF, 0x77, 0x55, 0x51,
        0x2B, 0xB1, 0x18, 0x6B, 0xAF, 0xAF, 0xFE, 0x79,
        0x4D, 0x2B, 0x6C, 0xDE, 0x90, 0x10, 0x9E, 0x65,
        0x82, 0xD3, 0x9C, 0xE0, 0xC9, 0x61, 0x97, 0x48,
        0x4B, 0x3F, 0xA0, 0x7F, 0xC9, 0x1D, 0x39, 0x4F,
        0xC8, 0xD8, 0x8E, 0x7F, 0xC4, 0xBE, 0x00, 0x2E,
        0x2D, 0xB5, 0x6F, 0x0C, 0x4D, 0x9D, 0x3F, 0xBD,
        0xA2, 0x74, 0x53, 0x6A, 0x0B, 0x86, 0xAB, 0xC6,
        0xE3, 0x9B, 0xDA, 0x52, 0x93, 0x1A, 0xEB, 0xB8,
        0xF1, 0x08, 0x4C, 0x5C, 0x1F, 0x7C, 0xB3, 0x17,
        0x77, 0x88, 0xB7, 0xF3, 0x31, 0xB7, 0x07, 0x43,
        0x61, 0x16, 0x34, 0x91, 0xD4, 0x28, 0xE7, 0x8B,
        0xCB, 0xB5, 0x7B, 0x63, 0x08, 0x41, 0xAA, 0x98,
        0x73, 0x33, 0x37, 0x7C, 0xF0, 0x95, 0x69, 0xCF,
        0xD1, 0x4C, 0xC2, 0xA1, 0x1C, 0x50, 0x1B, 0xDF,
        0x82, 0xC9, 0x3D, 0xE0, 0x5B, 0xEA, 0x20, 0x06,
        0x0D, 0xE8, 0x9C, 0x68, 0x6B, 0x82, 0x45, 0x71,
        0xCE, 0xF9, 0x4A, 0xB3, 0xFD, 0xAF, 0xA8, 0x51,
        0x26, 0x19, 0x81, 0x36, 0x69, 0xD4, 0xF5, 0x36,
        0x37, 0xFE, 0xFA, 0x4D, 0x02, 0x8C, 0xB2, 0x33,
        0xE5, 0x69, 0x30, 0xE2, 0x23, 0x5F, 0x7E, 0x60,
        0x34, 0xCA, 0x94, 0xB1, 0x43, 0xB7, 0x7A, 0xD4,
        0xA6, 0x87, 0x56, 0xE8, 0xA9, 0x18, 0x4D, 0xBA,
        0x61, 0xA8, 0x9F, 0x91, 0xED, 0xFB, 0x51, 0xA3,
        0x92, 0x11, 0x40, 0x24, 0x73, 0xA5, 0xF8, 0x91,
        0x45, 0x73, 0x6B, 0x2B, 0xF8, 0x56, 0x9C, 0x70,
        0x5B, 0x0C, 0xDB, 0x89, 0x80, 0xA4, 0x47, 0xE4,
        0xE1, 0xEA, 0xAD, 0x3E, 0x7E, 0x05, 0x78, 0xF5,
        0xF8, 0x6B, 0x8D, 0x03, 0xC9, 0xDA, 0xFE, 0x87,
        0x5E, 0x33, 0x9B, 0x44, 0x23, 0x84, 0x56, 0x16,
        0x79, 0x9E, 0xDC, 0xE0, 0x5F, 0x31, 0xB9, 0x26,
        0x64, 0xC5, 0xA5, 0x92, 0x53, 0xA6, 0x0E, 0x9D,
        0x89, 0x54, 0x8A, 0x30, 0x0C, 0x1A, 0xDB, 0x6D,
        0x19, 0x0A, 0x77, 0x5C, 0x5E, 0xE6, 0xE8, 0xA8,
        0x9B, 0x6E, 0x77, 0x9B, 0x03, 0x4C, 0x34, 0x00,
        0xA6, 0x25, 0xF4, 0xBB, 0xED, 0xBF, 0x91, 0x9C,
        0x45, 0xB2, 0xBC, 0xD1, 0x4C, 0x66, 0x92, 0x48,
        0xFC, 0x43, 0xC3, 0xEF, 0x47, 0xE1, 0x00, 0x75,
        0x89, 0x42, 0xE7, 0x5E, 0x8E, 0xD6, 0x07, 0x5A,
        0x96, 0xD7, 0x0D, 0x4E, 0xBD, 0x2B, 0x61, 0x35,
        0x82, 0x24, 0xDD, 0xA1, 0xEC, 0x4C, 0x19, 0xC2,
        0xA9, 0x28, 0x98, 0x17, 0x6F, 0xEB, 0x3C, 0x02,
        0xED, 0xCB, 0x99, 0x08, 0xBA, 0xE4, 0x9B, 0xD9,
        0x4A, 0xF0, 0x28, 0xED, 0xF8, 0xCF, 0xC2, 0xE5,
        0xF2, 0xE0, 0xBD, 0x37, 0x50, 0x06, 0x98, 0x6A,
        0xD4, 0x9E, 0x71, 0x75, 0x48, 0xE7, 0x46, 0xFE,
        0xF4, 0x9C, 0x86, 0x8B, 0xCE, 0xA2, 0x79, 0x0A,
        0xA9, 0x7E, 0x04, 0x06, 0x1B, 0x75, 0x60, 0x5C,
        0xB3, 0x9E, 0xFD, 0x46, 0x3D, 0x7B, 0x3D, 0x68,
        0xBA, 0x57, 0x44, 0x34, 0xFF, 0x7B, 0xE8, 0xE2,
        0xB8, 0x4B, 0xFC, 0x47, 0xE6, 0x7E, 0x9C, 0xD1,
        0x5F, 0x3E, 0xD4, 0x50, 0xC6, 0x1A, 0xFB, 0xA7,
        0x9A, 0x20, 0xB0, 0xB6, 0xF2, 0x87, 0x77, 0x7C,
        0x72, 0xF4, 0xAD, 0x24, 0x81, 0x74, 0xF1, 0x95,
        0x94, 0x77, 0xAA, 0x7A, 0x7C, 0x97, 0xF1, 0x22,
        0xC5, 0x04, 0x47, 0xC7, 0x48, 0x4F, 0x38, 0x2B,
        0xC4, 0x7D, 0x81, 0xFC, 0xC9, 0xC7, 0xE8, 0x92,
        0xC8, 0x83, 0x9D, 0x37, 0xB3, 0x53, 0x94, 0xB5,
        0x3E, 0x6B, 0x2B, 0x18, 0x95, 0xAB, 0xB0, 0xDE,
        0x8C, 0x98, 0xF2, 0x63, 0x3D, 0xC4, 0x41, 0x3A,
        0x8D, 0x57, 0x35, 0xDF, 0xC9, 0xA6, 0x40, 0x26,
        0xB6, 0xF3, 0x47, 0x79, 0xD6, 0xAC, 0x8A, 0xD9,
        0x9C, 0xC3, 0x1A, 0xA8, 0x98, 0xC2, 0xE7, 0x05,
        0x7F, 0x3D, 0xB8, 0xA1, 0xA8, 0xA9, 0x85, 0x27,
        0xA7, 0x9E, 0x43, 0x55, 0x2F, 0x28, 0xD1, 0x02,
        0x3E, 0x1F, 0x6A, 0x6B, 0x84, 0x85, 0x5C, 0xF5,
        0xE6, 0xDF, 0x88, 0x9B, 0xA2, 0x69, 0xF0, 0x48,
        0x94, 0x6E, 0x84, 0x02, 0x1C, 0x65, 0xC5, 0xA9,
        0x3B, 0x00, 0x7B, 0x07, 0x74, 0x1C, 0x1E, 0xE1,
        0x76, 0xC7, 0x39, 0x49, 0x11, 0x0F, 0x54, 0x8E,
        0xF4, 0x33, 0x2D, 0xCD, 0xD4, 0x91, 0xD2, 0xCE,
        0xFD, 0x02, 0x48, 0x88, 0x3F, 0x5E, 0x95, 0x25,
        0xBC, 0x91, 0xF3, 0x0A, 0xF1, 0x7C, 0xF5, 0xA9,
        0x8D, 0xD4, 0x4E, 0xF9, 0xA7, 0x1F, 0x99, 0xBB,
        0x73, 0x29, 0x85, 0xBA, 0x10, 0xA7, 0x23, 0xEF,
        0x47, 0x6F, 0xCF, 0x96, 0x6D, 0xA9, 0x45, 0x6B,
        0x24, 0x97, 0x8E, 0x33, 0x05, 0x0D, 0x0E, 0xC9,
        0x0D, 0x3C, 0xE4, 0x63, 0x78, 0x85, 0x1C, 0x9E,
        0xCF, 0xCF, 0xD3, 0x6C, 0x89, 0x5D, 0x44, 0xE9,
        0xE5, 0x06, 0x99, 0x30, 0x82, 0x52, 0x3D, 0x26,
        0x18, 0x57, 0x66, 0xB2, 0x35, 0x68, 0xCB, 0x95,
        0xE6, 0x41, 0x08, 0xF8, 0x9D, 0x10, 0x14, 0x74,
        0x7C, 0x67, 0xB6, 0xF3, 0xC8, 0x76, 0x7B, 0xE5,
        0xFC, 0x34, 0x12, 0x27, 0xDE, 0x94, 0x88, 0x86,
        0x1C, 0x5F, 0xE8, 0x11, 0x40, 0x9F, 0x80, 0x95,
        0x7D, 0x07, 0x52, 0x2A, 0x72, 0xCF, 0x6A, 0xB0,
        0x37, 0x8D, 0x0F, 0x2F, 0x28, 0xAF, 0x54, 0x81,
        0x85, 0xC3, 0x93, 0x67, 0x77, 0x99, 0x44, 0x66,
        0xA0, 0x19, 0xD3, 0x3B, 0x18, 0xA5, 0x4F, 0x38,
        0x0A, 0x33, 0x89, 0x2A, 0xB4, 0xD4, 0xBD, 0x50,
        0x7B, 0x5A, 0x61, 0xD0, 0xD3, 0x58, 0x34, 0x1A,
        0xC9, 0x2F, 0x07, 0xB4, 0x3B, 0x8F, 0x6A, 0xFC,
        0x69, 0x91, 0xBB, 0x6A, 0x1E, 0xAC, 0x23, 0xCA,
        0x6F, 0x73, 0xE9, 0x1F, 0x24, 0x64, 0xBD, 0x11,
        0x90, 0x98, 0xD7, 0xE7, 0x68, 0xE7, 0x7E, 0xCE,
        0x53, 0xFB, 0x89, 0x9B, 0xEB, 0x42, 0x26, 0x5E,
        0xCF, 0x7B, 0x27, 0x1F, 0x66, 0x54, 0x62, 0x82,
        0xD4, 0x72, 0xC3, 0x62, 0x39, 0x00, 0x6B, 0xB0,
        0xAB, 0xAB, 0xCC, 0xA2, 0x45, 0x50, 0xBA, 0xA0,
        0xA6, 0x01, 0x34, 0x8C, 0x81, 0x0F, 0xF5, 0xF9,
        0xEE, 0x50, 0x4B, 0xF7, 0x15, 0x5D, 0xEE, 0x41,
        0x41, 0xA1, 0x16, 0x05, 0xA4, 0xF3, 0x50, 0x9A,
        0xC9, 0xCA, 0xEF, 0x66, 0x24, 0xD2, 0x1D, 0xE3,
        0x32, 0xD5, 0xD5, 0x08, 0x28, 0xB5, 0x2E, 0x92,
        0x88, 0x5D, 0x3B, 0x90, 0x55, 0x3B, 0x14, 0x46,
        0x3A, 0xFB, 0x1E, 0xDC, 0xCD, 0x3B, 0x56, 0x9B,
        0x5A, 0x7F, 0x00, 0xBB, 0x66, 0x76, 0x9D, 0xAD,
        0xAC, 0x23, 0xAD, 0x8B, 0xB5, 0xD7, 0x3A, 0x6F,
        0x39, 0x0E, 0x6F, 0xC2, 0xF6, 0xF8, 0xEE, 0x3C,
        0xF4, 0x00, 0x9A, 0x5C, 0x3E, 0x1E, 0xF6, 0x0E,
        0x8F, 0x04, 0x06, 0x72, 0xD2, 0x62, 0xE6, 0x49,
        0x03, 0x79, 0xBB, 0xC7, 0x04, 0x95, 0xDF, 0xF2,
        0x37, 0xBE, 0xCD, 0x99, 0x52, 0xCD, 0x7E, 0xDE,
        0xB6, 0xD1, 0xDF, 0xC3, 0x60, 0xB3, 0xFC, 0x8B,
        0x0A, 0xF4, 0x80, 0xFF, 0xE0, 0x24, 0xAE, 0xEF,
        0xCD, 0x4E, 0x9C, 0xE9, 0x5D, 0x9B, 0x46, 0x9C,
        0x9A, 0x70, 0xE5, 0x11, 0x0D, 0xA0, 0xBA, 0xC1,
        0x24, 0xFC, 0x37, 0x41, 0xDC, 0xF4, 0x91, 0x16,
        0x26, 0x17, 0x96, 0x50, 0x4D, 0x5F, 0x49, 0x0B,
        0x43, 0x3C, 0x33, 0xC4, 0x0E, 0xDC, 0xE2, 0xB7,
        0x51, 0x51, 0xDA, 0x25, 0x6A, 0x86, 0x8A, 0x5E,
        0x35, 0xF8, 0x62, 0x26, 0xB8, 0x15, 0x1C, 0x91,
        0x93, 0x4C, 0xCC, 0x3D, 0xAC, 0xA3, 0x91, 0xDE,
        0xCC, 0xA7, 0x45, 0x37, 0x56, 0x60, 0xB6, 0xEC,
        0x41, 0xAE, 0x5D, 0x81, 0x08, 0x38, 0xCB, 0xEE,
        0xFF, 0xA1, 0x25, 0x57, 0x88, 0x44, 0x12, 0x35,
        0x7B, 0x10, 0x08, 0x36, 0x3D, 0x32, 0xB2, 0x37,
        0xAA, 0x1D, 0xD8, 0xE2, 0xD9, 0xC6, 0x36, 0x7A,
        0xDA, 0x09, 0xB2, 0xC9, 0x50, 0x60, 0x20, 0x6C,
        0xEC, 0x3E, 0xED, 0x39, 0x1F, 0xDC, 0x5D, 0xBE,
        0xF6, 0xF0, 0x8B, 0xDF, 0x04, 0x08, 0xE5, 0x85,
        0xAE, 0x5E, 0xBC, 0x8E, 0x97, 0x45, 0xD4, 0x4F,
        0xEC, 0xA9, 0x75, 0xAB, 0xBC, 0x14, 0x0B, 0xB3,
        0x7B, 0x8A, 0xDD, 0x16, 0xFC, 0xC2, 0x95, 0x69,
        0x10, 0xDC, 0x72, 0xBB, 0x3F, 0x02, 0xE9, 0xA1,
        0x30, 0xC9, 0xA8, 0x4F, 0x9C, 0xCB, 0x74, 0xD1,
        0x34, 0xCD, 0xF4, 0x0A, 0xFC, 0xBA, 0x20, 0x09,
        0xC8, 0xF0, 0x04, 0x02, 0x39, 0xBC, 0x99, 0x22,
        0x0E, 0xF6, 0x4C, 0x4D, 0xCC, 0xDE, 0x2E, 0x2E,
        0x5C, 0x9B, 0x68, 0x60, 0x2F, 0xBE, 0x8E, 0xF4,
        0xC9, 0x8B, 0x34, 0x68, 0xC7, 0x9D, 0xF4, 0xE0,
        0x78, 0x51, 0x1B, 0xFB, 0x8A, 0xA3, 0xDA, 0x09,
        0x59, 0x7A, 0x02, 0x51, 0x1E, 0x7C, 0x21, 0xA7,
        0xCF, 0x66, 0xA9, 0x38, 0x43, 0xA9, 0x48, 0x68,
        0xF1, 0x9E, 0x85, 0x52, 0x55, 0x2E, 0x3A, 0xCD,
        0xF6, 0xCB, 0x81, 0x06, 0x34, 0xDB, 0x97, 0xCB,
        0xC4, 0xBB, 0x56, 0x97, 0x09, 0xDA, 0xD4, 0x84,
        0x56, 0x45, 0x44, 0x6F, 0xA8, 0xD2, 0x89, 0xFC,
        0x59, 0x30, 0x7B, 0x80, 0x1E, 0x60, 0xCE, 0x2A,
        0x91, 0xE0, 0x6E, 0x9C, 0x22, 0xC1, 0x6E, 0x2E,
        0x59, 0xBD, 0xE3, 0x8A, 0x41, 0x6B, 0xB1, 0xB4,
        0xAC, 0x54, 0x57, 0x43, 0x8F, 0xDC, 0x5D, 0x64,
        0x45, 0x0A, 0x89, 0xEC, 0xB8, 0x32, 0xC1, 0xBB,
        0x27, 0x9D, 0xBF, 0x59, 0x33, 0x46, 0x81, 0x77,
        0x6A, 0xC0, 0x04, 0x09, 0x84, 0x6D, 0x09, 0xD6,
        0xF6, 0x87, 0x77, 0x2E, 0x34, 0x08, 0x50, 0xAB,
        0x86, 0x73, 0x38, 0x42, 0x15, 0xE1, 0x2C, 0x8D,
        0x0F, 0x53, 0x1C, 0x45, 0x1E, 0x58, 0x49, 0x3E,
        0x0E, 0xE4, 0x15, 0xAD, 0x59, 0x4D, 0xF3, 0x8C,
        0x34, 0x40, 0x8C, 0x7E, 0xD9, 0xF0, 0xC3, 0x92,
        0xF1, 0x53, 0x46, 0x04, 0xEA, 0xC3, 0xD9, 0xC1,
        0x54, 0x65, 0xA9, 0xA4, 0x66, 0x32, 0x21, 0x4B,
        0x53, 0x69, 0x90, 0xD7, 0x80, 0x78, 0xE5, 0xBD,
        0x7E, 0xAE, 0x20, 0x13, 0xFF, 0xF8, 0xFD, 0xD8,
        0xB2, 0x75, 0xC8, 0x9D, 0x97, 0xC9, 0x35, 0x3D,
        0xF3, 0xC4, 0x2A, 0x28, 0xE8, 0x14, 0xD8, 0x46,
        0x8E, 0x2B, 0x48, 0xDB, 0x09, 0x76, 0xD8, 0x8F,
        0x5E, 0xEC, 0xEF, 0xEA, 0xFB, 0x8F, 0x7F, 0x4A,
        0xF2, 0x91, 0xA7, 0x28, 0xF6, 0x24, 0x9E, 0xCF,
        0x56, 0x22, 0x33, 0x92, 0x69, 0xAA, 0x94, 0x53,
        0x29, 0xE9, 0x19, 0xF8, 0xB4, 0x41, 0xC8, 0x3D,
        0x55, 0x07, 0xF3, 0x0D, 0xF0, 0xFD, 0x2B, 0x13,
        0xFF, 0x80, 0x6F, 0x52, 0x2D, 0xAA, 0x11, 0xAF,
        0x67, 0x6A, 0x51, 0x3C, 0x14, 0x9C, 0x70, 0xF0,
        0xD6, 0xE9, 0x9A, 0x88, 0x04, 0x50, 0xA5, 0x4E,
        0x04, 0x17, 0xFE, 0x3C, 0x1E, 0x51, 0x3E, 0x9D,
        0x92, 0x0E, 0x30, 0xA8, 0xB4, 0x28, 0x91, 0x26,
        0x7A, 0x2D, 0xC5, 0x0A, 0xD8, 0x1F, 0x98, 0x04,
        0x49, 0x20, 0xC0, 0x99, 0xDF, 0x22, 0xC7, 0x39,
        0x98, 0xA2, 0x5C, 0x58, 0x1A, 0x51, 0x78, 0xC7,
        0x2B, 0x17, 0xAC, 0x87, 0x5B, 0xC6, 0x85, 0x48,
        0xA0, 0xFB, 0x0C, 0xBE, 0xE3, 0x8F, 0x05, 0x01,
        0x7B, 0x12, 0x43, 0x33, 0x43, 0xA6, 0x58, 0xF1,
        0x98, 0x0C, 0x81, 0x24, 0xEA, 0x6D, 0xD8, 0x1F
    };
    static const byte kprime_1024[KYBER_SS_SZ] = {
        0x8F, 0x33, 0x6E, 0x9C, 0x28, 0xDF, 0x34, 0x9E,
        0x03, 0x22, 0x0A, 0xF0, 0x1C, 0x42, 0x83, 0x2F,
        0xEF, 0xAB, 0x1F, 0x2A, 0x74, 0xC1, 0x6F, 0xAF,
        0x6F, 0x64, 0xAD, 0x07, 0x1C, 0x1A, 0x33, 0x94
    };
#endif
    static byte ss[KYBER_SS_SZ];

    key = (KyberKey*)XMALLOC(sizeof(KyberKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);
    if (key != NULL) {
        XMEMSET(key, 0, sizeof(KyberKey));
    }

#ifndef WOLFSSL_NO_KYBER512
    ExpectIntEQ(wc_KyberKey_Init(KYBER512, key, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_KyberKey_DecodePrivateKey(key, dk_512, sizeof(dk_512)), 0);
    ExpectIntEQ(wc_KyberKey_Decapsulate(key, ss, c_512, sizeof(c_512)), 0);
    ExpectIntEQ(XMEMCMP(ss, kprime_512, KYBER_SS_SZ), 0);
    wc_KyberKey_Free(key);
#endif
#ifndef WOLFSSL_NO_KYBER768
    ExpectIntEQ(wc_KyberKey_Init(KYBER768, key, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_KyberKey_DecodePrivateKey(key, dk_768, sizeof(dk_768)), 0);
    ExpectIntEQ(wc_KyberKey_Decapsulate(key, ss, c_768, sizeof(c_768)), 0);
    ExpectIntEQ(XMEMCMP(ss, kprime_768, KYBER_SS_SZ), 0);
    wc_KyberKey_Free(key);
#endif
#ifndef WOLFSSL_NO_KYBER1024
    ExpectIntEQ(wc_KyberKey_Init(KYBER1024, key, NULL, INVALID_DEVID), 0);
    ExpectIntEQ(wc_KyberKey_DecodePrivateKey(key, dk_1024, sizeof(dk_1024)), 0);
    ExpectIntEQ(wc_KyberKey_Decapsulate(key, ss, c_1024, sizeof(c_1024)), 0);
    ExpectIntEQ(XMEMCMP(ss, kprime_1024, KYBER_SS_SZ), 0);
    wc_KyberKey_Free(key);
#endif

    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && !defined(WOLFSSL_NO_ML_DSA_44)
static const byte ml_dsa_44_pub_key[] = {
    0x7c, 0x33, 0x31, 0x41, 0x15, 0xa7, 0x2d, 0x6b,
    0x17, 0x7c, 0x10, 0xab, 0x75, 0xf7, 0x83, 0xb3,
    0x30, 0x75, 0x6f, 0xa9, 0x42, 0xb0, 0x9b, 0x59,
    0x59, 0x99, 0x2b, 0x5d, 0x7d, 0x6e, 0xeb, 0xdd,
    0xd9, 0x99, 0x8f, 0x7b, 0xad, 0xe5, 0x90, 0x0f,
    0xa4, 0x80, 0xd8, 0xa2, 0x0d, 0x95, 0xea, 0x63,
    0x2b, 0xcf, 0xb4, 0x5b, 0x3c, 0xd1, 0x5a, 0xc4,
    0xc4, 0xd1, 0x71, 0x28, 0x4b, 0x0b, 0x28, 0x32,
    0x73, 0xb5, 0x0d, 0xd6, 0x8f, 0x6b, 0x01, 0x26,
    0x04, 0x45, 0xa3, 0x80, 0xc0, 0x21, 0x12, 0xee,
    0x52, 0x0f, 0x35, 0xe4, 0x8e, 0xca, 0xf8, 0x91,
    0xf4, 0x99, 0x51, 0xe2, 0x80, 0x76, 0xa7, 0x2d,
    0x09, 0xf5, 0x04, 0xcc, 0xa6, 0x6b, 0x20, 0xc4,
    0xac, 0xcd, 0x6c, 0x9c, 0x09, 0xe7, 0x51, 0xa2,
    0x29, 0x60, 0xfd, 0xf2, 0xbd, 0x7e, 0x4c, 0x9d,
    0xc0, 0xba, 0x62, 0x2f, 0x53, 0xb2, 0x47, 0x03,
    0xf2, 0x6f, 0x70, 0x51, 0xa8, 0xe1, 0xb7, 0x9f,
    0x37, 0x15, 0xfa, 0xd1, 0x6c, 0x74, 0x1a, 0x2b,
    0x4f, 0x39, 0x4f, 0x43, 0x49, 0x71, 0x6a, 0xf8,
    0x7c, 0x65, 0x1a, 0xdd, 0x1a, 0x25, 0xf8, 0x79,
    0xfa, 0x8c, 0x02, 0xf2, 0xf7, 0xf7, 0x7b, 0x9f,
    0xe4, 0xaf, 0x9e, 0x1a, 0x0b, 0x5b, 0x2e, 0x41,
    0xbb, 0xa9, 0x4f, 0xd0, 0xdb, 0xad, 0xe5, 0x25,
    0xff, 0x36, 0x3b, 0x9a, 0xc3, 0xdf, 0xb6, 0x27,
    0xd3, 0xba, 0xb0, 0xd4, 0xb2, 0x07, 0xc3, 0xd8,
    0xab, 0x10, 0x3d, 0xcd, 0x23, 0x52, 0x46, 0xe6,
    0x96, 0x57, 0x85, 0xc7, 0x60, 0xe2, 0x8c, 0x46,
    0x65, 0x7d, 0x76, 0x1c, 0x45, 0x20, 0x5d, 0x51,
    0xd6, 0x13, 0xde, 0xe5, 0x3d, 0xc2, 0x8c, 0x36,
    0xdb, 0x7f, 0x83, 0x6f, 0x6a, 0xc2, 0xa3, 0xf2,
    0xdc, 0x63, 0x69, 0x7f, 0xbd, 0xd0, 0xc1, 0x90,
    0xfb, 0x62, 0x42, 0xa1, 0xf6, 0xf7, 0xdd, 0xc2,
    0x4a, 0x38, 0x62, 0x9b, 0xef, 0x67, 0xf9, 0x5c,
    0xd8, 0xff, 0xf4, 0xf2, 0x67, 0x90, 0x42, 0x85,
    0xaf, 0xe2, 0x92, 0x6e, 0xc4, 0x9b, 0x63, 0xc3,
    0x91, 0xa5, 0x11, 0x66, 0x13, 0x83, 0xbc, 0xbb,
    0xc7, 0x34, 0x3b, 0x30, 0x40, 0x53, 0x91, 0xdf,
    0x7c, 0x3d, 0x17, 0xdd, 0xa1, 0xa6, 0x80, 0xfd,
    0x26, 0x9d, 0x60, 0x7b, 0xcd, 0xb4, 0x2b, 0xba,
    0x61, 0x0f, 0x43, 0x7c, 0x51, 0x3c, 0xb9, 0xfa,
    0xdb, 0x48, 0x35, 0x9f, 0x0d, 0x0c, 0x04, 0xe8,
    0xf9, 0x6e, 0x07, 0x65, 0x7d, 0x46, 0x1b, 0xd2,
    0x51, 0xdb, 0x55, 0x27, 0xd7, 0x3d, 0x1e, 0x36,
    0x07, 0x59, 0x18, 0xec, 0x04, 0x4b, 0x87, 0xbb,
    0xfb, 0x27, 0xac, 0xeb, 0x8f, 0x43, 0x46, 0xd0,
    0x39, 0x00, 0x90, 0x54, 0x70, 0xb1, 0x71, 0xf2,
    0xe7, 0x3d, 0x02, 0x1a, 0xcf, 0x87, 0x16, 0x67,
    0xa2, 0x3c, 0x31, 0x48, 0xe8, 0xbd, 0x4f, 0xb3,
    0xc2, 0xfd, 0x3d, 0xa1, 0x9c, 0x87, 0x54, 0x60,
    0x30, 0x21, 0x52, 0x57, 0xcd, 0x03, 0x96, 0x9e,
    0xa7, 0x8d, 0xe5, 0x02, 0x04, 0x78, 0x43, 0x72,
    0xda, 0xb2, 0x22, 0xf1, 0xee, 0x8f, 0x27, 0x0b,
    0x8f, 0x7b, 0xf8, 0xbc, 0x16, 0xa1, 0xef, 0x0b,
    0x35, 0xda, 0xfc, 0x29, 0x1b, 0xf8, 0xa1, 0x35,
    0x40, 0xe7, 0xed, 0x4c, 0x02, 0x4a, 0x83, 0xb7,
    0x49, 0x75, 0x34, 0x3f, 0x2b, 0xb3, 0x61, 0xf5,
    0xa3, 0x9b, 0x23, 0xca, 0xfb, 0x58, 0x16, 0x4f,
    0x3c, 0x50, 0xbf, 0x81, 0xab, 0x54, 0x50, 0x1a,
    0x39, 0x57, 0x5f, 0x9a, 0x72, 0x22, 0xba, 0xa4,
    0xf6, 0xbf, 0xac, 0x31, 0x5c, 0xc5, 0x96, 0xd7,
    0xa9, 0xe4, 0x3b, 0x0c, 0xd0, 0x7f, 0x79, 0x68,
    0x4d, 0x41, 0x04, 0x81, 0x73, 0xcf, 0x47, 0x4a,
    0x7b, 0x37, 0xac, 0x8e, 0x47, 0x0d, 0x72, 0x65,
    0x0f, 0x9d, 0x44, 0xd7, 0x08, 0x21, 0x5b, 0x3f,
    0xc8, 0x9d, 0xea, 0xa2, 0x64, 0x7b, 0x0d, 0x98,
    0xc1, 0x61, 0xcd, 0xa4, 0xf7, 0x8c, 0x4a, 0xa3,
    0x3b, 0xdd, 0x92, 0xce, 0x61, 0x97, 0x0e, 0x98,
    0xa4, 0x10, 0xb5, 0x1f, 0xc5, 0xfb, 0xee, 0x49,
    0x36, 0x8f, 0xe3, 0x2d, 0x46, 0x9c, 0xa9, 0xff,
    0xdd, 0x1a, 0x48, 0x1b, 0x5a, 0x99, 0x84, 0x0a,
    0x3d, 0x5c, 0xd7, 0x67, 0x32, 0x88, 0x87, 0x2a,
    0x34, 0x50, 0x04, 0xad, 0xe6, 0xbb, 0x3c, 0xb5,
    0xee, 0x80, 0x99, 0x70, 0xaa, 0x9d, 0x5a, 0x63,
    0xec, 0xd5, 0x9a, 0x6a, 0x3a, 0xe8, 0xaa, 0x3d,
    0x3f, 0xe8, 0x15, 0x2c, 0x16, 0x3e, 0x86, 0x46,
    0x21, 0xf2, 0xd2, 0x6e, 0x74, 0x3d, 0x53, 0x94,
    0x7c, 0x41, 0xec, 0x5b, 0xf5, 0xa4, 0xc8, 0x1f,
    0x75, 0x22, 0x50, 0x58, 0x31, 0xf5, 0x29, 0x9a,
    0xc2, 0x2c, 0x67, 0xd9, 0xf6, 0x2e, 0xa1, 0xa9,
    0x0a, 0x69, 0x90, 0x7a, 0xd8, 0xed, 0x5c, 0x09,
    0x3d, 0x14, 0xa3, 0x2b, 0xc0, 0x47, 0x88, 0xb7,
    0xea, 0x14, 0x8a, 0xec, 0xaf, 0x0c, 0xb7, 0xc6,
    0x7c, 0x32, 0x0f, 0x57, 0xea, 0x9f, 0xd4, 0x99,
    0x8d, 0xab, 0xd6, 0xc9, 0x31, 0x07, 0x81, 0x37,
    0x3d, 0xf5, 0x07, 0xb3, 0x93, 0xb7, 0x04, 0x20,
    0xdf, 0x91, 0xef, 0xfb, 0xa6, 0x7d, 0x4b, 0x5d,
    0xd4, 0x24, 0xd2, 0x0b, 0xc5, 0x34, 0xf6, 0x7a,
    0xf9, 0x4a, 0x48, 0xc7, 0xab, 0xaf, 0xa8, 0xd2,
    0xfc, 0x41, 0xc9, 0x8b, 0xa8, 0xc4, 0x2f, 0x94,
    0x4e, 0xb0, 0xab, 0xd3, 0xd9, 0x09, 0x4b, 0x1f,
    0x35, 0xb7, 0xb4, 0x4c, 0x2d, 0x6b, 0xe6, 0xb4,
    0x2e, 0x8a, 0x09, 0xd3, 0x9d, 0x54, 0x3f, 0x53,
    0xcc, 0x8e, 0x16, 0x18, 0x4e, 0x9a, 0xe8, 0x52,
    0x84, 0x3a, 0x3e, 0xdb, 0xab, 0x65, 0xc4, 0xa1,
    0x3c, 0xd0, 0xf6, 0x57, 0x3c, 0x0e, 0x10, 0xed,
    0xb2, 0xa9, 0x7d, 0x70, 0x3f, 0x18, 0x1a, 0xba,
    0x31, 0x33, 0xcb, 0x2a, 0xfd, 0x13, 0xf5, 0x23,
    0xd7, 0x71, 0xfa, 0xb6, 0xe8, 0xda, 0x63, 0xca,
    0x55, 0x3c, 0x5b, 0x87, 0x27, 0x96, 0x3d, 0xd0,
    0x43, 0x9d, 0x76, 0x9f, 0x28, 0x5a, 0xb6, 0xc8,
    0x81, 0xe4, 0x7c, 0x2a, 0x7a, 0x84, 0x0f, 0x2d,
    0x1b, 0xd0, 0xe4, 0x0e, 0x1b, 0x47, 0x32, 0xc8,
    0x02, 0x2d, 0x39, 0x0e, 0x7d, 0xb1, 0x12, 0x56,
    0x50, 0x00, 0xae, 0xcc, 0x45, 0x0a, 0xd5, 0x30,
    0x16, 0xe7, 0x3a, 0x53, 0x02, 0xbc, 0xd5, 0xef,
    0xca, 0x00, 0xea, 0x5f, 0xbe, 0x15, 0x0d, 0x08,
    0x76, 0xc1, 0x03, 0x93, 0x96, 0x4a, 0x88, 0xda,
    0x9d, 0x0b, 0x51, 0x39, 0x9a, 0xef, 0xd2, 0xde,
    0x8a, 0x2c, 0xe6, 0xf3, 0xa5, 0x70, 0x15, 0x3a,
    0x17, 0x43, 0x31, 0xfc, 0x47, 0x9d, 0xec, 0x3b,
    0x28, 0x6f, 0xdf, 0x45, 0x6f, 0x9e, 0x10, 0xbb,
    0x8e, 0x43, 0xc5, 0x59, 0xe5, 0x61, 0x9b, 0xa7,
    0xa1, 0xb8, 0x7a, 0x1c, 0xd4, 0x25, 0x26, 0xca,
    0xe9, 0x2b, 0x0b, 0x3d, 0x06, 0xeb, 0x44, 0x44,
    0xab, 0x4a, 0x5e, 0x68, 0x5c, 0x93, 0xf1, 0x3f,
    0x39, 0x01, 0xb9, 0xf1, 0x01, 0xb7, 0xb6, 0x14,
    0x44, 0x1d, 0x6d, 0x6b, 0x03, 0x45, 0x0d, 0xf3,
    0xbf, 0x71, 0x4e, 0xf3, 0x84, 0x3d, 0xef, 0xea,
    0x60, 0x2e, 0x2e, 0xf7, 0x33, 0xa6, 0xbe, 0x53,
    0x49, 0x26, 0xed, 0xb4, 0xbf, 0x7f, 0xb0, 0x1d,
    0x39, 0xb2, 0xc2, 0x88, 0xc2, 0xa2, 0xd4, 0x7f,
    0x0e, 0x1c, 0x44, 0xa3, 0x38, 0x76, 0xa7, 0xa6,
    0x19, 0x7e, 0x4c, 0x84, 0x25, 0x01, 0xb2, 0x78,
    0xb4, 0x56, 0xc5, 0xc1, 0x50, 0x3f, 0xf2, 0xb6,
    0x76, 0x09, 0x55, 0x57, 0x1c, 0xd1, 0x55, 0x23,
    0x16, 0x2a, 0x51, 0x16, 0xaa, 0x13, 0x4f, 0x35,
    0x69, 0xaf, 0xea, 0x01, 0x5f, 0x22, 0xc9, 0x2e,
    0xe9, 0x8c, 0x6c, 0xa2, 0x17, 0x92, 0xdc, 0x3d,
    0xd6, 0xf0, 0xfa, 0x5a, 0x53, 0xe0, 0xcd, 0x55,
    0xa2, 0x91, 0x62, 0xba, 0xae, 0x67, 0x40, 0x1c,
    0xda, 0xb4, 0xcc, 0xfc, 0x67, 0x1f, 0x44, 0xa0,
    0x50, 0xa5, 0xde, 0xc5, 0xde, 0x5e, 0xa0, 0x3b,
    0x05, 0x84, 0x1c, 0x2a, 0xc4, 0x96, 0x47, 0xd6,
    0x97, 0x56, 0x40, 0x33, 0x99, 0x7c, 0x8b, 0x56,
    0xb4, 0xfb, 0xf4, 0x23, 0xcb, 0x48, 0x81, 0x6c,
    0xa4, 0x53, 0x41, 0x8c, 0x28, 0x61, 0xd7, 0x8c,
    0xde, 0xde, 0xeb, 0xd4, 0xe7, 0x8a, 0x2a, 0x40,
    0x83, 0x1c, 0xa4, 0x19, 0x0f, 0x6c, 0x73, 0xa5,
    0x0e, 0xb6, 0x5c, 0x14, 0x36, 0xff, 0xc9, 0x99,
    0x56, 0x53, 0x8c, 0x4e, 0x4f, 0x4a, 0x82, 0xc8,
    0x76, 0x83, 0x81, 0xf1, 0x17, 0x82, 0x98, 0x3e,
    0x9c, 0x99, 0x3a, 0x7c, 0x08, 0x77, 0x3e, 0xe2,
    0x10, 0x98, 0xb0, 0xf6, 0x1d, 0xd3, 0x24, 0xe8,
    0x98, 0xcf, 0xd8, 0x9a, 0xb8, 0xd7, 0xbe, 0x56,
    0xa2, 0xb6, 0xf8, 0x2e, 0xfe, 0xeb, 0x96, 0xfa,
    0xd0, 0xba, 0x79, 0x9e, 0xde, 0x72, 0x0d, 0x53,
    0x5f, 0xdd, 0x0d, 0xb2, 0x0a, 0x8f, 0x14, 0x94,
    0x87, 0x25, 0x5e, 0xcd, 0xd4, 0x4b, 0xaa, 0xc9,
    0x7e, 0x41, 0x9f, 0x33, 0x77, 0xbe, 0x6d, 0x57,
    0x68, 0xef, 0xee, 0x1a, 0xc4, 0x5c, 0x7b, 0xca,
    0x7e, 0x33, 0x93, 0x3d, 0x88, 0x91, 0xd1, 0x34,
    0x6a, 0x39, 0x98, 0x92, 0x50, 0x1a, 0x02, 0xcf,
    0x89, 0x34, 0x33, 0x10, 0x65, 0x23, 0x4d, 0xb7,
    0x00, 0xcc, 0xc1, 0x60, 0xdd, 0x7d, 0x8e, 0xd1,
    0x16, 0xa7, 0x71, 0x7b, 0x20, 0xcb, 0xe4, 0xe8,
    0xcc, 0xfc, 0xb8, 0x5f, 0xe4, 0xe2, 0xd6, 0x8c,
    0x43, 0x9c, 0x06, 0xf4, 0x8d, 0xbc, 0x56, 0xd0,
    0x0c, 0xd6, 0x0b, 0x6c, 0x33, 0x0e, 0x08, 0x77,
    0x66, 0x52, 0x1f, 0x48, 0x0c, 0x50, 0x4a, 0xc2,
    0x99, 0x0a, 0x15, 0x86, 0xc3, 0x9b, 0x7a, 0x5f,
    0xfb, 0x58, 0xbd, 0x63, 0x0c, 0xbe, 0x83, 0x40,
    0x8f, 0xba, 0x39, 0xfb, 0x45, 0xb9, 0xf7, 0x96,
    0x62, 0xec, 0x7e, 0x77, 0xa4, 0xfb, 0xe1, 0x86,
    0x5c, 0x0a, 0xae, 0x32, 0xbd, 0x79, 0x76, 0x8b
};
static const byte ml_dsa_44_good_sig[] = {
    0x09, 0xf0, 0xae, 0xbb, 0x25, 0xc7, 0xfc, 0xdd,
    0x93, 0x25, 0x9c, 0x50, 0xd9, 0x2e, 0x72, 0x5d,
    0x53, 0xf5, 0x29, 0xd7, 0x4c, 0xc2, 0xd6, 0x81,
    0x5c, 0xf3, 0x3f, 0x9a, 0x8a, 0xa9, 0x00, 0x21,
    0x6c, 0xc6, 0xb9, 0x72, 0xb7, 0x0e, 0x00, 0x55,
    0x9f, 0xd7, 0xae, 0x92, 0xc3, 0xbc, 0x8f, 0x2d,
    0x4f, 0x54, 0x87, 0x56, 0x52, 0xd3, 0xdd, 0xaf,
    0xe0, 0xff, 0xda, 0x80, 0x1b, 0xf3, 0x56, 0x90,
    0xdd, 0x07, 0x86, 0xad, 0xf7, 0xf3, 0x8e, 0xcf,
    0x3a, 0x57, 0x30, 0x52, 0xaa, 0xd2, 0xb1, 0xf0,
    0x66, 0xea, 0x67, 0xab, 0x94, 0x1d, 0x96, 0x04,
    0xaa, 0xcf, 0x0e, 0xb0, 0xbc, 0x7d, 0x8a, 0x4c,
    0x62, 0x21, 0x82, 0x81, 0x98, 0x63, 0x22, 0x91,
    0xb9, 0xfe, 0x53, 0x63, 0x8d, 0xdf, 0xe6, 0x19,
    0xc1, 0x54, 0x3b, 0xf0, 0xf5, 0xe4, 0xc4, 0x36,
    0x66, 0x2f, 0xcc, 0x4f, 0xed, 0xc6, 0x62, 0x7d,
    0x8b, 0x7b, 0x89, 0xac, 0x23, 0x0b, 0x40, 0x4e,
    0x2d, 0xdc, 0xe5, 0xa2, 0xbc, 0x8b, 0xac, 0xe7,
    0x0b, 0xaa, 0x15, 0xa0, 0x79, 0x4a, 0x97, 0x8a,
    0xc8, 0xb1, 0x31, 0xea, 0x29, 0x99, 0x14, 0x5d,
    0x5b, 0x8c, 0xc2, 0xd0, 0xc2, 0x29, 0xd0, 0x85,
    0xb9, 0x25, 0x16, 0x08, 0xe8, 0x41, 0xa7, 0x77,
    0x1a, 0xbf, 0x5a, 0x48, 0x5a, 0x7f, 0x97, 0x44,
    0x62, 0xb4, 0x68, 0x2e, 0x05, 0x48, 0xde, 0x0f,
    0x69, 0xcc, 0x05, 0x3c, 0xa4, 0x85, 0x20, 0x60,
    0xfd, 0x45, 0x6a, 0x14, 0xb9, 0x76, 0x8d, 0x48,
    0xe7, 0x71, 0xd0, 0xd7, 0xbe, 0xe3, 0x36, 0xd6,
    0x94, 0x5c, 0x22, 0x6e, 0x28, 0xc6, 0x34, 0x93,
    0xf4, 0x6c, 0xf2, 0x62, 0xbf, 0x8f, 0x6d, 0x07,
    0xff, 0x38, 0x92, 0x23, 0x19, 0x55, 0xd0, 0x66,
    0x72, 0x76, 0xc1, 0x43, 0xbc, 0x60, 0x5d, 0xaa,
    0x61, 0x10, 0xdb, 0x0c, 0x49, 0x7b, 0x99, 0xce,
    0x14, 0xe3, 0x0b, 0x80, 0xdc, 0x8a, 0x3d, 0xa5,
    0x3a, 0x0e, 0x29, 0x88, 0x09, 0x1f, 0x9c, 0x03,
    0x32, 0x13, 0xc2, 0xe1, 0x49, 0x26, 0xc7, 0x11,
    0xfa, 0x7f, 0x2d, 0x64, 0xfc, 0xf9, 0xaf, 0xd0,
    0x4d, 0xcf, 0x3a, 0x23, 0x49, 0xde, 0xf2, 0x5d,
    0xad, 0xf3, 0xde, 0xe0, 0x9a, 0xa2, 0x96, 0x0a,
    0x9d, 0x97, 0x39, 0x88, 0x60, 0x75, 0xec, 0x29,
    0x9b, 0x93, 0xfc, 0x80, 0xb3, 0xeb, 0xb0, 0xc6,
    0xa8, 0xea, 0x75, 0x67, 0xed, 0xbd, 0x42, 0x2a,
    0xed, 0x22, 0x27, 0xdb, 0x41, 0x3a, 0x94, 0x86,
    0xd7, 0x4a, 0xf1, 0x8f, 0xa5, 0x47, 0x38, 0xa3,
    0x3c, 0xe7, 0x17, 0x5d, 0xce, 0xdc, 0x32, 0x7c,
    0xe4, 0x05, 0x58, 0x98, 0x67, 0xc8, 0xaf, 0x35,
    0x5d, 0xf9, 0xc0, 0x10, 0x6d, 0x9d, 0xd3, 0x27,
    0x79, 0x3c, 0x1d, 0xdd, 0xfb, 0x53, 0x3c, 0x03,
    0x4c, 0xb3, 0x1b, 0x0b, 0x3a, 0x60, 0x80, 0xcd,
    0x9b, 0x1e, 0x5f, 0x3f, 0x29, 0xfa, 0xb1, 0x09,
    0x9a, 0x88, 0x58, 0x4a, 0xf5, 0xed, 0xe9, 0x7c,
    0x9d, 0x70, 0xbe, 0x57, 0xfb, 0x92, 0x12, 0xc9,
    0x8c, 0x6b, 0x77, 0xe2, 0x44, 0xc6, 0x82, 0x2a,
    0x29, 0xb3, 0x9c, 0xb0, 0x60, 0xda, 0x3d, 0xcd,
    0x4e, 0x49, 0x96, 0x8c, 0xd7, 0x2b, 0x29, 0x28,
    0x7b, 0xec, 0xf1, 0x46, 0x40, 0xf0, 0xe1, 0xd7,
    0x48, 0x9e, 0xdf, 0xfd, 0xa6, 0xd0, 0xaa, 0x35,
    0x94, 0x7a, 0x94, 0x57, 0xf3, 0xd4, 0x15, 0x19,
    0xd3, 0xc5, 0x35, 0x73, 0xc4, 0xf5, 0x86, 0x0d,
    0x2a, 0x5b, 0x67, 0x0d, 0x8d, 0xaa, 0x18, 0x3e,
    0xea, 0x9d, 0x80, 0xe7, 0xf8, 0xbb, 0x23, 0xea,
    0x5d, 0x1c, 0x4d, 0xb2, 0x58, 0x7e, 0xe5, 0xef,
    0x80, 0xc1, 0x63, 0x44, 0xaf, 0x1d, 0xed, 0xf6,
    0x92, 0x05, 0x0c, 0xda, 0xcc, 0x58, 0x39, 0x27,
    0xdd, 0x24, 0xac, 0x63, 0x23, 0x34, 0xaa, 0x2d,
    0xd0, 0x5b, 0xd7, 0x7f, 0x6d, 0xcb, 0x64, 0xed,
    0xb3, 0x9b, 0x05, 0x90, 0x79, 0xc2, 0x25, 0x68,
    0xed, 0xf6, 0xa8, 0x7e, 0x30, 0x4a, 0x46, 0x44,
    0xad, 0xc8, 0x12, 0x8d, 0x04, 0xc3, 0x11, 0x83,
    0x7e, 0x77, 0xef, 0x9c, 0xa2, 0xf9, 0x3b, 0x06,
    0x84, 0x7f, 0x72, 0xd9, 0x2f, 0x22, 0x95, 0xb7,
    0x7b, 0x4e, 0x35, 0x6a, 0xfa, 0x73, 0x7d, 0x88,
    0x5b, 0xac, 0x7b, 0xc5, 0x53, 0xc1, 0xfe, 0x6b,
    0x7c, 0x05, 0xc3, 0xe4, 0xae, 0x48, 0x1a, 0xea,
    0x6e, 0x51, 0x46, 0x1e, 0x82, 0x80, 0xde, 0x31,
    0xe1, 0x41, 0x71, 0x88, 0x41, 0xa7, 0xb2, 0xcd,
    0x3d, 0xf7, 0x5c, 0x4f, 0x4c, 0xfd, 0x3f, 0x6f,
    0x6c, 0x82, 0xc1, 0xba, 0xe0, 0xf0, 0xb4, 0x8c,
    0xd5, 0xb5, 0x32, 0xbf, 0x91, 0x49, 0x7e, 0x39,
    0x5e, 0x0a, 0xdf, 0x4b, 0xd6, 0x07, 0x72, 0xff,
    0x58, 0x65, 0x1b, 0x1f, 0xc6, 0x56, 0xd2, 0x00,
    0xec, 0x60, 0xd1, 0x22, 0xc9, 0x1a, 0xa4, 0xcc,
    0x26, 0xb4, 0xd1, 0x93, 0xbc, 0xfc, 0x52, 0xdf,
    0xa1, 0x23, 0x37, 0x9b, 0xa2, 0xa8, 0x8f, 0xf3,
    0x39, 0x03, 0xa5, 0x4c, 0xf0, 0x68, 0xe5, 0x95,
    0x62, 0xfb, 0xd8, 0x88, 0x39, 0xf6, 0x02, 0x0a,
    0x4e, 0x7c, 0xf0, 0xbf, 0x71, 0x99, 0x0f, 0x19,
    0x61, 0xd9, 0x39, 0xe8, 0x3f, 0x59, 0x22, 0x4a,
    0xaa, 0xdd, 0x03, 0xf8, 0x09, 0xb8, 0xaf, 0xd9,
    0xb9, 0x9c, 0x3f, 0xf1, 0xfe, 0x49, 0xae, 0x99,
    0x2f, 0xa2, 0x22, 0x5a, 0x3c, 0xe9, 0xe9, 0xf7,
    0xba, 0x2d, 0xeb, 0x1f, 0x6c, 0xa7, 0xe1, 0x87,
    0x2f, 0xa5, 0xff, 0xcf, 0x1c, 0x22, 0x8d, 0xf2,
    0x5f, 0x63, 0xf5, 0xbb, 0x36, 0x66, 0xcc, 0x62,
    0x89, 0x8e, 0xf7, 0x78, 0xc5, 0x97, 0x95, 0xde,
    0xec, 0x43, 0x39, 0x6e, 0x0d, 0xe0, 0x8e, 0xbd,
    0x2b, 0x3b, 0xe6, 0xff, 0xf5, 0x8f, 0x90, 0xd2,
    0xd2, 0xce, 0x3b, 0x6f, 0x78, 0xf5, 0xd3, 0x42,
    0xf3, 0x0f, 0x27, 0x4b, 0x2b, 0xe4, 0xd8, 0x0d,
    0x31, 0xfa, 0xba, 0xdc, 0x54, 0x21, 0x9a, 0xbf,
    0x1e, 0x1d, 0x06, 0x8e, 0xd9, 0x58, 0xce, 0x9a,
    0x71, 0x79, 0x4d, 0xcb, 0xfb, 0x99, 0x4b, 0x66,
    0xed, 0xef, 0x75, 0x20, 0x4d, 0x47, 0x9b, 0x40,
    0xd5, 0xcf, 0xd9, 0x00, 0xfe, 0x32, 0x45, 0xae,
    0x4b, 0x7e, 0x8e, 0x7b, 0xf9, 0xd4, 0xd4, 0x2e,
    0x1a, 0x2a, 0xac, 0x73, 0xdb, 0x79, 0xb7, 0x02,
    0x6a, 0x3d, 0xa2, 0xfe, 0x52, 0x27, 0x25, 0x43,
    0xd1, 0xb5, 0x48, 0x0e, 0xef, 0xf1, 0x0f, 0xe7,
    0x27, 0xc2, 0x59, 0x4e, 0x47, 0xe2, 0x12, 0xaa,
    0x1e, 0xae, 0xbc, 0x86, 0x22, 0x70, 0x33, 0xa5,
    0x50, 0x3f, 0xed, 0x3c, 0x98, 0xbb, 0xd5, 0xb3,
    0x3e, 0x43, 0x21, 0x8e, 0x3e, 0x8c, 0xcc, 0x0c,
    0xcf, 0x50, 0xcd, 0xeb, 0x1b, 0x9d, 0x0c, 0xc9,
    0xe3, 0x2f, 0xbb, 0x4b, 0x43, 0xfc, 0x37, 0x27,
    0xcb, 0xc9, 0x5a, 0xe9, 0x45, 0x92, 0x9d, 0xe9,
    0x60, 0x8f, 0x93, 0x1b, 0xd8, 0x6a, 0x68, 0x86,
    0xc2, 0x1d, 0x49, 0x92, 0x11, 0x29, 0x62, 0x14,
    0x15, 0x4c, 0xe9, 0x33, 0xe3, 0x70, 0x2d, 0x6b,
    0x8b, 0xb5, 0x22, 0x44, 0x82, 0xbe, 0x43, 0xe2,
    0x80, 0xfb, 0xb5, 0xfa, 0x6a, 0x30, 0x04, 0x20,
    0xb6, 0x58, 0xe1, 0xf4, 0x8c, 0xe6, 0x4c, 0x7c,
    0x8d, 0x38, 0xf6, 0xdd, 0x59, 0xfc, 0x5a, 0xd7,
    0x9f, 0x34, 0x92, 0xcc, 0xde, 0x65, 0x89, 0xa7,
    0xd9, 0x57, 0xf7, 0xf2, 0x71, 0x39, 0xaf, 0xb6,
    0x88, 0x02, 0x40, 0x24, 0x8b, 0x4f, 0xc5, 0xfc,
    0xdc, 0x5c, 0xc0, 0x1d, 0xa6, 0x68, 0x87, 0xe0,
    0x8f, 0xdc, 0xf0, 0xac, 0xd8, 0x5f, 0x1c, 0xb3,
    0x07, 0xac, 0x58, 0x97, 0x3f, 0x3e, 0x72, 0x19,
    0x18, 0x64, 0x55, 0x73, 0x11, 0x71, 0xd1, 0xa4,
    0xa6, 0x57, 0xb0, 0x27, 0xaf, 0xad, 0x8a, 0xf7,
    0xdf, 0xde, 0x1e, 0xdb, 0x31, 0xc9, 0x32, 0x85,
    0x90, 0x40, 0x3d, 0xfe, 0x64, 0x5d, 0xe3, 0x94,
    0x74, 0x98, 0xa7, 0xed, 0x84, 0x44, 0x13, 0x76,
    0xba, 0xe9, 0x09, 0x9a, 0x17, 0xe0, 0x38, 0x03,
    0x3b, 0x7a, 0xa7, 0x0e, 0x74, 0xbd, 0x93, 0xb1,
    0x85, 0x64, 0xc9, 0xc4, 0x22, 0xb9, 0xdf, 0x80,
    0xac, 0xa1, 0x17, 0xdb, 0x11, 0xdb, 0xfa, 0xeb,
    0x90, 0x3c, 0x28, 0xfb, 0xa2, 0x36, 0x76, 0x61,
    0x20, 0x00, 0x88, 0x15, 0xc0, 0x79, 0x9f, 0x7d,
    0x9f, 0x90, 0xdb, 0x79, 0xbf, 0x1c, 0xdf, 0x86,
    0xc9, 0x60, 0x8c, 0xea, 0xa6, 0x24, 0x81, 0xd6,
    0x6d, 0xd8, 0x8d, 0x17, 0x5f, 0x5c, 0x6d, 0x93,
    0xbc, 0xed, 0xe5, 0x41, 0x05, 0xbe, 0xc6, 0x0f,
    0x66, 0x50, 0xc3, 0xce, 0x7e, 0x6c, 0x80, 0x88,
    0xf5, 0x52, 0x61, 0xaf, 0xdb, 0xc0, 0x80, 0xbe,
    0x78, 0x49, 0x64, 0x39, 0x54, 0x26, 0xeb, 0xab,
    0x07, 0x4d, 0x38, 0x66, 0x06, 0x98, 0x58, 0xaa,
    0x40, 0xc4, 0x89, 0xb2, 0x08, 0x85, 0xf3, 0x14,
    0x58, 0x5d, 0x36, 0xf7, 0xf0, 0x6b, 0x72, 0x79,
    0x6d, 0xbe, 0x5e, 0x24, 0x68, 0xf1, 0x3c, 0xa2,
    0x82, 0x22, 0x6e, 0xc4, 0x46, 0x94, 0x8e, 0x00,
    0xcb, 0xc0, 0x07, 0x69, 0xa5, 0x6d, 0x57, 0x04,
    0x79, 0xeb, 0x06, 0x7a, 0x42, 0x20, 0x6e, 0xdc,
    0xb5, 0xa4, 0xdd, 0x74, 0xb3, 0x92, 0x16, 0x71,
    0x7d, 0x99, 0xfa, 0x26, 0x35, 0x57, 0xe2, 0x83,
    0xc2, 0xb6, 0xfb, 0x0a, 0xae, 0x22, 0xed, 0xe3,
    0x98, 0x65, 0x18, 0x32, 0xf8, 0xe5, 0xed, 0xa9,
    0xf9, 0x7d, 0xb8, 0xea, 0x21, 0x51, 0x6c, 0x70,
    0x4c, 0xfa, 0xec, 0x6d, 0x4c, 0xf4, 0xcb, 0x1c,
    0x43, 0xfb, 0xfc, 0xbb, 0xa9, 0xcb, 0xc5, 0x21,
    0xb3, 0x89, 0xd6, 0x4c, 0xc4, 0x42, 0xd1, 0x55,
    0x3d, 0x43, 0x74, 0xbf, 0xb7, 0x47, 0xb3, 0x5b,
    0x14, 0xc3, 0x8f, 0x42, 0x30, 0x57, 0xb0, 0x22,
    0x56, 0xbe, 0x8d, 0x88, 0x7e, 0x7d, 0x63, 0xc8,
    0xec, 0x01, 0x41, 0xd5, 0x9d, 0xb6, 0x7a, 0x3b,
    0xfe, 0x8b, 0x95, 0x94, 0xdb, 0xca, 0xf1, 0xb4,
    0x56, 0xd7, 0x83, 0xf4, 0x11, 0x05, 0x65, 0xde,
    0x7a, 0xa3, 0x5a, 0x7a, 0x70, 0xe4, 0xd2, 0xad,
    0xc0, 0xff, 0x3f, 0x66, 0x2e, 0x1a, 0x65, 0x38,
    0xda, 0x1f, 0x3f, 0xac, 0x04, 0x2f, 0x0f, 0xde,
    0x7e, 0x55, 0x05, 0x12, 0xe9, 0xe7, 0x69, 0xf9,
    0x34, 0x2c, 0x84, 0x97, 0xa8, 0x86, 0x0c, 0x24,
    0x32, 0x87, 0xfd, 0xbe, 0x67, 0xd1, 0x02, 0x21,
    0x3b, 0x33, 0xfd, 0x11, 0xb1, 0xca, 0x4f, 0xeb,
    0x40, 0x38, 0xf6, 0x19, 0x83, 0x9d, 0x73, 0x44,
    0x37, 0xd6, 0x69, 0x6d, 0x85, 0xda, 0xf7, 0x69,
    0xfb, 0x88, 0x2b, 0xe7, 0xe7, 0x3c, 0x18, 0xa8,
    0x13, 0xb7, 0xee, 0x5c, 0x50, 0x5b, 0xa3, 0x09,
    0x1c, 0xef, 0x8d, 0x37, 0x89, 0x75, 0x0f, 0x8b,
    0xea, 0x17, 0x02, 0x47, 0x21, 0xcb, 0xa8, 0x73,
    0x71, 0x23, 0x4c, 0xf7, 0x50, 0xdd, 0x21, 0xe5,
    0xdb, 0x40, 0x3a, 0x87, 0x40, 0x8d, 0x60, 0x89,
    0x9e, 0x20, 0x00, 0x58, 0xeb, 0xbb, 0x24, 0x9b,
    0x0a, 0x17, 0x8f, 0xf6, 0x56, 0x07, 0x11, 0x5b,
    0xa7, 0xcd, 0x93, 0x0a, 0x31, 0x3d, 0x1f, 0x45,
    0xa0, 0x08, 0x8f, 0x88, 0x34, 0xa5, 0x01, 0x3b,
    0xea, 0x07, 0xa3, 0x7b, 0x66, 0x3e, 0x96, 0xe8,
    0xf7, 0x4d, 0x63, 0x04, 0x55, 0x89, 0xf1, 0x02,
    0x1e, 0x4a, 0x21, 0xb1, 0x2b, 0x8c, 0x7f, 0x2e,
    0x0c, 0x64, 0x26, 0x36, 0xd8, 0x63, 0xab, 0xf5,
    0x22, 0xaf, 0xa9, 0xfa, 0xfa, 0x21, 0x4b, 0x7e,
    0x6f, 0x8c, 0xce, 0x98, 0xf2, 0x85, 0x3f, 0x2c,
    0x07, 0x90, 0xc3, 0x2c, 0x06, 0xc5, 0xde, 0xc8,
    0xc2, 0x7c, 0xd7, 0x9b, 0x64, 0x25, 0x8a, 0x9b,
    0x77, 0x07, 0xc7, 0x4c, 0xd7, 0x67, 0xff, 0xe6,
    0xdb, 0x17, 0xf5, 0xc4, 0x2a, 0x14, 0x44, 0x1a,
    0xff, 0xda, 0xe0, 0xa7, 0x09, 0x1c, 0xe9, 0x03,
    0xde, 0x4a, 0x59, 0xe4, 0xdf, 0xa3, 0x0d, 0x3a,
    0x43, 0xdf, 0x80, 0x82, 0x87, 0xfa, 0x75, 0xf5,
    0xe8, 0xef, 0x6f, 0xd0, 0x89, 0xdd, 0xa1, 0x75,
    0x17, 0x5b, 0x71, 0x47, 0xe8, 0x8d, 0xae, 0xf6,
    0x18, 0x7f, 0xb9, 0x24, 0x68, 0x3f, 0x17, 0x6b,
    0xa8, 0x30, 0x67, 0x7e, 0x02, 0x9b, 0xf6, 0x4d,
    0x03, 0xa8, 0xfb, 0x33, 0x2f, 0xb4, 0x65, 0x72,
    0x2a, 0x30, 0xa6, 0x93, 0x94, 0x7a, 0x41, 0x0f,
    0xd3, 0x67, 0x0b, 0xba, 0xa4, 0x49, 0x7c, 0xcf,
    0x1f, 0x59, 0x1e, 0x2e, 0x45, 0xd4, 0xa8, 0xb1,
    0x98, 0x2b, 0xd7, 0x6f, 0x55, 0xb8, 0xf2, 0x65,
    0x7b, 0x96, 0x18, 0xf7, 0x2e, 0xde, 0x9c, 0x39,
    0x7a, 0x08, 0x2e, 0xe7, 0x3c, 0x9e, 0x4a, 0xfe,
    0xba, 0x49, 0xce, 0xba, 0x65, 0x18, 0xae, 0xae,
    0x9b, 0xd5, 0xf5, 0xeb, 0xd3, 0xdc, 0xd7, 0x2c,
    0x92, 0x3c, 0xe2, 0x93, 0xb9, 0x69, 0xf2, 0x20,
    0xea, 0xbd, 0xa9, 0x01, 0x2b, 0x72, 0x7c, 0x93,
    0x6c, 0x1f, 0x80, 0x3a, 0xd2, 0x2d, 0xf6, 0xc1,
    0x31, 0x63, 0xd2, 0x2f, 0x6c, 0x1a, 0x54, 0x1f,
    0x74, 0xe6, 0xa0, 0xac, 0xb1, 0x04, 0x03, 0xb3,
    0x22, 0x19, 0x48, 0x0a, 0xa7, 0x55, 0x25, 0xc1,
    0x77, 0x28, 0xb9, 0xbe, 0xef, 0xa8, 0xc6, 0x2b,
    0xd5, 0x6c, 0x5d, 0x7b, 0x85, 0xcd, 0x10, 0x2d,
    0x9e, 0xfd, 0xb8, 0xa5, 0x10, 0x65, 0xf7, 0x29,
    0xa7, 0x41, 0x18, 0xc8, 0xc2, 0x23, 0xe5, 0xcb,
    0x96, 0x91, 0x8a, 0x7e, 0x45, 0x30, 0x6b, 0x91,
    0xf1, 0x88, 0xb3, 0x2e, 0x92, 0x96, 0x0a, 0x42,
    0x4a, 0x16, 0x9d, 0x0c, 0xa8, 0xa7, 0xe5, 0x64,
    0x38, 0x8a, 0x53, 0x41, 0x28, 0xbf, 0xd7, 0xa4,
    0x14, 0x05, 0x59, 0x11, 0x2e, 0x0f, 0xc8, 0x5c,
    0x97, 0x8d, 0xd3, 0x92, 0xbf, 0xb9, 0x05, 0xfa,
    0xff, 0x38, 0xbf, 0xd6, 0xc5, 0x22, 0xf8, 0xa4,
    0x75, 0x30, 0x45, 0x93, 0x14, 0xda, 0xc0, 0x7f,
    0xea, 0x24, 0xe0, 0x33, 0x68, 0xf2, 0x6d, 0xe1,
    0xb1, 0x0c, 0x7d, 0x40, 0xaa, 0x16, 0x53, 0xa1,
    0xf6, 0x26, 0xb1, 0x25, 0xe8, 0x83, 0xe9, 0xea,
    0xea, 0xd2, 0x5a, 0x24, 0xda, 0xe2, 0x6e, 0xd1,
    0x2a, 0x87, 0x64, 0x48, 0x13, 0x55, 0xb1, 0x2c,
    0x1a, 0x58, 0x43, 0x5b, 0x63, 0x14, 0x3e, 0x02,
    0xf0, 0xcf, 0x61, 0x7d, 0x83, 0x81, 0xb9, 0x65,
    0x4b, 0x72, 0xee, 0xff, 0xfb, 0x6a, 0xbe, 0x71,
    0x26, 0x56, 0x28, 0x13, 0x9f, 0x31, 0xda, 0x8c,
    0x2f, 0xdb, 0x21, 0xbe, 0x4b, 0x66, 0xbb, 0xad,
    0x7a, 0x13, 0x55, 0x92, 0x7c, 0xb5, 0x6e, 0x5f,
    0x45, 0x1b, 0x64, 0x2d, 0xad, 0x6d, 0x32, 0x07,
    0xe4, 0x91, 0xdc, 0x0c, 0x1b, 0x5f, 0xcd, 0x86,
    0xe2, 0x99, 0x2b, 0xb9, 0x7e, 0x60, 0xbd, 0xad,
    0xa1, 0x5c, 0xab, 0x7f, 0x76, 0xf3, 0x77, 0xba,
    0x73, 0x7f, 0x6a, 0x88, 0x4e, 0xff, 0x40, 0x72,
    0x7a, 0x4d, 0x9b, 0x20, 0x2d, 0xc9, 0x2a, 0x30,
    0x0f, 0x8f, 0x0f, 0xc9, 0x79, 0xc8, 0xc3, 0x8a,
    0x83, 0x52, 0xff, 0x66, 0x7a, 0x42, 0x04, 0x08,
    0x6e, 0x5b, 0x13, 0xda, 0xb9, 0xb6, 0x2d, 0x45,
    0x77, 0x9a, 0xa0, 0x2b, 0xc1, 0x87, 0xc2, 0xa6,
    0x35, 0x7f, 0x39, 0x34, 0x2e, 0x95, 0x1e, 0x8c,
    0xbf, 0x89, 0x6d, 0xcf, 0x82, 0xb8, 0x9f, 0x9b,
    0xd1, 0xbc, 0xa2, 0x55, 0x83, 0xf4, 0xca, 0x21,
    0x11, 0x8f, 0x28, 0xa9, 0x5e, 0x28, 0x23, 0xb4,
    0x43, 0x60, 0xb6, 0x11, 0x1a, 0x6f, 0xb4, 0xd1,
    0x96, 0xc8, 0x79, 0xf2, 0x39, 0x8b, 0x82, 0xae,
    0xe0, 0xc2, 0xe4, 0xf9, 0xfb, 0xf8, 0x85, 0x64,
    0x28, 0xad, 0xb5, 0xfd, 0x37, 0xc5, 0x21, 0x38,
    0x31, 0x94, 0x0d, 0xbe, 0xd8, 0xaf, 0x9b, 0x8a,
    0x7d, 0xfb, 0x56, 0xd8, 0x23, 0xf7, 0x55, 0x55,
    0xe7, 0xd9, 0x63, 0x65, 0xfd, 0x64, 0x2e, 0x8a,
    0x1d, 0x1b, 0xac, 0x4e, 0x2f, 0xef, 0x1b, 0x77,
    0xca, 0x01, 0xd6, 0xfc, 0xb0, 0x11, 0xda, 0x6b,
    0xef, 0x9f, 0x76, 0x81, 0x3e, 0x3f, 0x26, 0x4b,
    0x3b, 0x97, 0xa0, 0x7d, 0xd6, 0xcf, 0x51, 0x0d,
    0x06, 0xf7, 0xf5, 0x88, 0x64, 0x34, 0x7a, 0xe3,
    0xb9, 0x16, 0xc3, 0x06, 0x04, 0xf3, 0xe9, 0x55,
    0xd2, 0xff, 0x49, 0xec, 0x57, 0x84, 0x1f, 0x39,
    0x28, 0x71, 0x57, 0x87, 0x40, 0xf2, 0x7a, 0x30,
    0xa0, 0x88, 0xba, 0x6c, 0xb1, 0x09, 0x30, 0x3a,
    0x11, 0x75, 0xcf, 0xbe, 0x4c, 0xf7, 0xf7, 0xca,
    0x44, 0x52, 0x91, 0xd0, 0x4c, 0x12, 0x3e, 0x3a,
    0x4b, 0x31, 0x20, 0xfe, 0x27, 0xd2, 0x08, 0x5b,
    0x83, 0x7b, 0x82, 0xd3, 0xa3, 0x72, 0xba, 0x2f,
    0x5f, 0xa3, 0x71, 0xcd, 0x8d, 0x3f, 0x94, 0xce,
    0x86, 0xa8, 0x6b, 0x43, 0xb7, 0x06, 0x80, 0x70,
    0x64, 0x06, 0xab, 0x54, 0xce, 0xb5, 0x29, 0xaf,
    0x73, 0xf7, 0x0f, 0x65, 0x70, 0xa7, 0x84, 0x1a,
    0x0b, 0xdb, 0x0c, 0xa9, 0x20, 0xea, 0x06, 0x7a,
    0xba, 0x80, 0xc6, 0xae, 0x3e, 0x0a, 0x7b, 0xd6,
    0x21, 0x99, 0xe0, 0xae, 0x6e, 0x8f, 0x80, 0xa9,
    0x97, 0x27, 0x3d, 0x7e, 0xb2, 0xd8, 0x06, 0x10,
    0x36, 0x07, 0x64, 0x12, 0xd0, 0xc7, 0x91, 0xd2,
    0x81, 0x74, 0x22, 0x8b, 0x8f, 0xe0, 0x48, 0xc4,
    0xe1, 0x9b, 0x05, 0xc8, 0xc5, 0xc3, 0x9a, 0x7b,
    0x9d, 0xee, 0x23, 0xe0, 0x98, 0xc0, 0xd0, 0x05,
    0x21, 0x89, 0x9a, 0xf4, 0x45, 0xd1, 0x1d, 0x80,
    0x79, 0xb7, 0xfe, 0x3c, 0xff, 0x84, 0x86, 0xf0,
    0x2a, 0x69, 0x8b, 0x2d, 0x3b, 0x82, 0xa0, 0xab,
    0xee, 0xe6, 0xf4, 0x64, 0x84, 0x2b, 0x7a, 0x42,
    0x12, 0x8d, 0x10, 0xa6, 0xae, 0x10, 0x6d, 0x03,
    0xb5, 0x72, 0x09, 0xf8, 0x3f, 0xe4, 0x1c, 0x0a,
    0x08, 0x0d, 0x1a, 0x45, 0x5b, 0x70, 0x7b, 0x95,
    0xa1, 0xa7, 0xb4, 0xb6, 0xbf, 0xcc, 0xfc, 0x09,
    0x1a, 0x30, 0x40, 0x44, 0x5e, 0x69, 0x73, 0x7a,
    0x81, 0xa5, 0xb9, 0xd7, 0xdd, 0xe3, 0xee, 0xfb,
    0x16, 0x1a, 0x1d, 0x40, 0x41, 0x4e, 0x8d, 0x90,
    0x92, 0x9d, 0xaf, 0xb0, 0xbb, 0xc2, 0xe0, 0xfc,
    0x06, 0x0b, 0x20, 0x37, 0x47, 0x50, 0x53, 0x65,
    0x87, 0x89, 0x99, 0xa4, 0xb7, 0xdb, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x0f, 0x20, 0x30, 0x3e
};
#endif

static int test_wc_dilithium(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM)
    dilithium_key* key;
    byte level;
#if !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) || \
    !defined(WOLFSSL_DILITHIUM_NO_SIGN)
    WC_RNG rng;
#endif
    byte* privKey = NULL;
#ifndef WOLFSSL_DILITHIUM_NO_SIGN
    word32 privKeyLen = DILITHIUM_MAX_KEY_SIZE;
#endif
    byte* pubKey = NULL;
#ifndef WOLFSSL_DILITHIUM_NO_VERIFY
    word32 pubKeyLen = DILITHIUM_MAX_PUB_KEY_SIZE;
#endif

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);
    privKey = (byte*)XMALLOC(DILITHIUM_MAX_KEY_SIZE, NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(privKey);
    pubKey = (byte*)XMALLOC(DILITHIUM_MAX_PUB_KEY_SIZE, NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(pubKey);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }
#if !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) || \
    !defined(WOLFSSL_DILITHIUM_NO_SIGN)
    XMEMSET(&rng, 0, sizeof(WC_RNG));
#endif

#if !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) || \
    !defined(WOLFSSL_DILITHIUM_NO_SIGN)
    ExpectIntEQ(wc_InitRng(&rng), 0);
#endif

    ExpectIntEQ(wc_dilithium_init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_init_ex(NULL, NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    wc_dilithium_free(NULL);

    ExpectIntEQ(wc_dilithium_init(key), 0);
    wc_dilithium_free(key);
    ExpectIntEQ(wc_dilithium_init_ex(key, NULL, INVALID_DEVID), 0);

#ifndef WOLFSSL_DILITHIUM_NO_VERIFY
    ExpectIntEQ(wc_dilithium_export_public(key, pubKey, &pubKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef WOLFSSL_DILITHIUM_NO_SIGN
    ExpectIntEQ(wc_dilithium_export_private(key, privKey, &privKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

#ifdef WOLFSSL_DILITHIUM_PRIVATE_KEY
    ExpectIntEQ(wc_dilithium_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_priv_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#endif
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_pub_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#if !defined(WOLFSSL_DILITHIUM_NO_SIGN) || !defined(WOLFSSL_DILITHIUM_NO_VERIFY)
    ExpectIntEQ(wc_dilithium_sig_size(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifdef WOLFSSL_DILITHIUM_PRIVATE_KEY
    ExpectIntEQ(wc_dilithium_size(key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_priv_size(key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#endif
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_pub_size(key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#if !defined(WOLFSSL_DILITHIUM_NO_SIGN) || !defined(WOLFSSL_DILITHIUM_NO_VERIFY)
    ExpectIntEQ(wc_dilithium_sig_size(key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    ExpectIntEQ(wc_dilithium_set_level(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_set_level(key, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_set_level(NULL, WC_ML_DSA_44), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_set_level(key, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_set_level(key, 4), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_dilithium_get_level(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_get_level(key, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_get_level(NULL, &level), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_get_level(key, &level), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#ifndef WOLFSSL_NO_ML_DSA_87
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
    ExpectIntEQ(wc_dilithium_get_level(key, &level), 0);
    ExpectIntEQ(level, WC_ML_DSA_87);
#ifdef WOLFSSL_DILITHIUM_PRIVATE_KEY
    ExpectIntEQ(wc_dilithium_size(key), DILITHIUM_LEVEL5_KEY_SIZE);
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_priv_size(key), DILITHIUM_LEVEL5_PRV_KEY_SIZE);
#endif
#endif
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_pub_size(key), DILITHIUM_LEVEL5_PUB_KEY_SIZE);
#endif
#if !defined(WOLFSSL_DILITHIUM_NO_SIGN) || !defined(WOLFSSL_DILITHIUM_NO_VERIFY)
    ExpectIntEQ(wc_dilithium_sig_size(key), DILITHIUM_LEVEL5_SIG_SIZE);
#endif
#else
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), WC_NO_ERR_TRACE(NOT_COMPILED_IN));
#endif
#ifndef WOLFSSL_NO_ML_DSA_65
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
    ExpectIntEQ(wc_dilithium_get_level(key, &level), 0);
    ExpectIntEQ(level, WC_ML_DSA_65);
#ifdef WOLFSSL_DILITHIUM_PRIVATE_KEY
    ExpectIntEQ(wc_dilithium_size(key), DILITHIUM_LEVEL3_KEY_SIZE);
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_priv_size(key), DILITHIUM_LEVEL3_PRV_KEY_SIZE);
#endif
#endif
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_pub_size(key), DILITHIUM_LEVEL3_PUB_KEY_SIZE);
#endif
#if !defined(WOLFSSL_DILITHIUM_NO_SIGN) || !defined(WOLFSSL_DILITHIUM_NO_VERIFY)
    ExpectIntEQ(wc_dilithium_sig_size(key), DILITHIUM_LEVEL3_SIG_SIZE);
#endif
#else
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), WC_NO_ERR_TRACE(NOT_COMPILED_IN));
#endif
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
    ExpectIntEQ(wc_dilithium_get_level(key, &level), 0);
    ExpectIntEQ(level, WC_ML_DSA_44);
#ifdef WOLFSSL_DILITHIUM_PRIVATE_KEY
    ExpectIntEQ(wc_dilithium_size(key), DILITHIUM_LEVEL2_KEY_SIZE);
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_priv_size(key), DILITHIUM_LEVEL2_PRV_KEY_SIZE);
#endif
#endif
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
    ExpectIntEQ(wc_dilithium_pub_size(key), DILITHIUM_LEVEL2_PUB_KEY_SIZE);
#endif
#if !defined(WOLFSSL_DILITHIUM_NO_SIGN) || !defined(WOLFSSL_DILITHIUM_NO_VERIFY)
    ExpectIntEQ(wc_dilithium_sig_size(key), DILITHIUM_LEVEL2_SIG_SIZE);
#endif
#else
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), WC_NO_ERR_TRACE(NOT_COMPILED_IN));
#endif

#ifndef WOLFSSL_DILITHIUM_NO_VERIFY
    ExpectIntEQ(wc_dilithium_export_public(key, pubKey, &pubKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef WOLFSSL_DILITHIUM_NO_SIGN
    ExpectIntEQ(wc_dilithium_export_private(key, privKey, &privKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    wc_dilithium_free(key);
#if !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) || \
    !defined(WOLFSSL_DILITHIUM_NO_SIGN)
    wc_FreeRng(&rng);
#endif
    XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_dilithium_make_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY)
    dilithium_key* key;
    WC_RNG rng;

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_dilithium_init(key), 0);

    ExpectIntEQ(wc_dilithium_make_key(key, &rng), WC_NO_ERR_TRACE(BAD_STATE_E));

#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
#else
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
#endif

    ExpectIntEQ(wc_dilithium_make_key(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_make_key(key, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_make_key(NULL, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_make_key(key, &rng), 0);

    wc_dilithium_free(key);
    wc_FreeRng(&rng);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_dilithium_sign(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    !defined(WOLFSSL_DILITHIUM_NO_SIGN)
    dilithium_key* key;
    dilithium_key* importKey = NULL;
    WC_RNG rng;
    byte* privKey = NULL;
    word32 privKeyLen = DILITHIUM_MAX_KEY_SIZE;
    word32 badKeyLen;
    byte msg[32];
    byte* sig = NULL;
    word32 sigLen = DILITHIUM_MAX_SIG_SIZE;

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);
    importKey = (dilithium_key*)XMALLOC(sizeof(*key), NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(importKey);
    privKey = (byte*)XMALLOC(DILITHIUM_MAX_KEY_SIZE, NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(privKey);
    sig = (byte*)XMALLOC(DILITHIUM_MAX_SIG_SIZE, NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(sig);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }
    if (importKey != NULL) {
        XMEMSET(importKey, 0, sizeof(*importKey));
    }
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(msg, 0x55, sizeof(msg));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_dilithium_init(key), 0);

#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
#else
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
#endif

#ifdef WOLFSSL_DILITHIUM_NO_MAKE_KEY
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_import_private(bench_dilithium_level2_key,
        sizeof_bench_dilithium_level2_key, key), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_import_private(bench_dilithium_level3_key,
        sizeof_bench_dilithium_level3_key, key), 0);
#else
    ExpectIntEQ(wc_dilithium_import_private(bench_dilithium_level5_key,
        sizeof_bench_dilithium_level5_key, key), 0);
#endif
#else
    ExpectIntEQ(wc_dilithium_make_key(key, &rng), 0);
#endif

    ExpectIntEQ(wc_dilithium_sign_msg(NULL, 32, NULL, NULL, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(msg, 32, NULL, NULL, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(NULL, 32, sig, NULL, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(NULL, 32, NULL, &sigLen, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(NULL, 32, NULL, NULL, key, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(NULL, 32, NULL, NULL, NULL, &rng),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(NULL, 32, sig, &sigLen, key, &rng),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(msg, 32, NULL, &sigLen, key, &rng),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(msg, 32, sig, NULL, key, &rng),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(msg, 32, sig, &sigLen, NULL, &rng),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(msg, 32, sig, &sigLen, key, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_sign_msg(msg, 32, sig, &sigLen, key, &rng), 0);

    ExpectIntEQ(wc_dilithium_export_private(NULL, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_private(key, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_private(NULL, privKey, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_private(NULL, NULL, &privKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_private(NULL, privKey, &privKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_private(key, NULL, &privKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_private(key, privKey, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    badKeyLen = 0;
    ExpectIntEQ(wc_dilithium_export_private(key, privKey, &badKeyLen),
        WC_NO_ERR_TRACE(BUFFER_E));
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(badKeyLen, DILITHIUM_LEVEL2_KEY_SIZE);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(badKeyLen, DILITHIUM_LEVEL3_KEY_SIZE);
#else
    ExpectIntEQ(badKeyLen, DILITHIUM_LEVEL5_KEY_SIZE);
#endif
    ExpectIntEQ(wc_dilithium_export_private(key, privKey, &privKeyLen),
        0);
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(privKeyLen, DILITHIUM_LEVEL2_KEY_SIZE);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(privKeyLen, DILITHIUM_LEVEL3_KEY_SIZE);
#else
    ExpectIntEQ(privKeyLen, DILITHIUM_LEVEL5_KEY_SIZE);
#endif

    ExpectIntEQ(wc_dilithium_init(importKey), 0);
    ExpectIntEQ(wc_dilithium_import_private(privKey, privKeyLen, importKey),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(importKey, WC_ML_DSA_44), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_set_level(importKey, WC_ML_DSA_65), 0);
#else
    ExpectIntEQ(wc_dilithium_set_level(importKey, WC_ML_DSA_87), 0);
#endif
    ExpectIntEQ(wc_dilithium_import_private(NULL, 0, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_private(privKey, 0, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_private(NULL, privKeyLen, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_private(NULL, 0, importKey),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_private(NULL, privKeyLen, importKey),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_private(privKey, 0, importKey),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_private(privKey, privKeyLen, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_private(privKey, privKeyLen, importKey),
        0);
    ExpectIntEQ(wc_dilithium_sign_msg(msg, 32, sig, &sigLen, key, &rng), 0);
#ifdef WOLFSSL_DILITHIUM_CHECK_KEY
    ExpectIntEQ(wc_dilithium_check_key(importKey), WC_NO_ERR_TRACE(PUBLIC_KEY_E));
#endif
    wc_dilithium_free(importKey);

    wc_dilithium_free(key);
    wc_FreeRng(&rng);

    XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(importKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_dilithium_verify(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && \
    (!defined(WOLFSSL_NO_ML_DSA_44) || !defined(WOLFSSL_DILITHIUM_NO_SIGN))
    dilithium_key* key;
    dilithium_key* importKey = NULL;
    WC_RNG rng;
    byte* pubKey = NULL;
    word32 pubKeyLen = DILITHIUM_MAX_PUB_KEY_SIZE;
    word32 badKeyLen;
    byte msg[32];
    byte* sig = NULL;
    word32 sigLen = DILITHIUM_MAX_SIG_SIZE;
    int res;
#ifndef WOLFSSL_NO_ML_DSA_44
    byte b;
#endif

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);
    importKey = (dilithium_key*)XMALLOC(sizeof(*key), NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(importKey);
    pubKey = (byte*)XMALLOC(DILITHIUM_MAX_PUB_KEY_SIZE, NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(pubKey);
    sig = (byte*)XMALLOC(DILITHIUM_MAX_SIG_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(sig);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }
    if (importKey != NULL) {
        XMEMSET(importKey, 0, sizeof(*importKey));
    }
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(msg, 0x55, sizeof(msg));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_dilithium_init(key), 0);

#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
#else
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
#endif

#if !defined(WOLFSSL_NO_ML_DSA_44)
    ExpectIntEQ(wc_dilithium_import_public(ml_dsa_44_pub_key,
        (word32)sizeof(ml_dsa_44_pub_key), key), 0);
    if (sig != NULL) {
        XMEMCPY(sig, ml_dsa_44_good_sig, sizeof(ml_dsa_44_good_sig));
    }
    sigLen = (word32)sizeof(ml_dsa_44_good_sig);
#else
#ifdef WOLFSSL_DILITHIUM_NO_MAKE_KEY
#ifndef WOLFSSL_NO_ML_DSA_65
    ExpectIntEQ(wc_dilithium_import_public(bench_dilithium_level3_pub_key,
        sizeof_bench_dilithium_level3_pub_key, key), 0);
#else
    ExpectIntEQ(wc_dilithium_import_public(bench_dilithium_level5_pub_key,
        sizeof_bench_dilithium_level5_pub_key, key), 0);
#endif /* !WOLFSSL_NO_ML_DSA_65 */
#else
    ExpectIntEQ(wc_dilithium_make_key(key, &rng), 0);
#endif /* WOLFSSL_DILITHIUM_NO_MAKE_KEY */

    ExpectIntEQ(wc_dilithium_sign_msg(msg, 32, sig, &sigLen, key, &rng), 0);
#endif /* !WOLFSSL_NO_ML_DSA_44 */

    ExpectIntEQ(wc_dilithium_export_public(NULL, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_public(key, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_public(NULL, pubKey, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_public(NULL, NULL, &pubKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_public(NULL, pubKey, &pubKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_public(key, NULL, &pubKeyLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_public(key, pubKey, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    badKeyLen = 0;
    ExpectIntEQ(wc_dilithium_export_public(key, pubKey, &badKeyLen),
        WC_NO_ERR_TRACE(BUFFER_E));
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(badKeyLen, DILITHIUM_LEVEL2_PUB_KEY_SIZE);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(badKeyLen, DILITHIUM_LEVEL3_PUB_KEY_SIZE);
#else
    ExpectIntEQ(badKeyLen, DILITHIUM_LEVEL5_PUB_KEY_SIZE);
#endif
    ExpectIntEQ(wc_dilithium_export_public(key, pubKey, &pubKeyLen), 0);
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(pubKeyLen, DILITHIUM_LEVEL2_PUB_KEY_SIZE);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(pubKeyLen, DILITHIUM_LEVEL3_PUB_KEY_SIZE);
#else
    ExpectIntEQ(pubKeyLen, DILITHIUM_LEVEL5_PUB_KEY_SIZE);
#endif

    ExpectIntEQ(wc_dilithium_verify_msg(NULL, 0, NULL, 32, NULL, NULL),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_verify_msg(sig, 0, NULL, 32, NULL, NULL),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_verify_msg(NULL, 0, msg, 32, NULL, NULL),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_verify_msg(NULL, 0, NULL, 32, &res, NULL),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_verify_msg(NULL, 0, NULL, 32, NULL, key),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_verify_msg(NULL, sigLen, msg, 32, &res, key),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_verify_msg(sig, 0, msg, 32, &res, key),
       WC_NO_ERR_TRACE(BUFFER_E));
    ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, NULL, 32, &res, key),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, NULL, key),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, &res, NULL),
       WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    res = 0;
    ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, &res, key), 0);
    ExpectIntEQ(res, 1);

    ExpectIntEQ(wc_dilithium_init(importKey), 0);
    ExpectIntEQ(wc_dilithium_import_public(pubKey, pubKeyLen, importKey),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(importKey, WC_ML_DSA_44), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_set_level(importKey, WC_ML_DSA_65), 0);
#else
    ExpectIntEQ(wc_dilithium_set_level(importKey, WC_ML_DSA_87), 0);
#endif
    ExpectIntEQ(wc_dilithium_import_public(NULL, 0, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_public(pubKey, 0, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_public(NULL, pubKeyLen, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_public(NULL, 0, importKey),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_public(NULL, pubKeyLen, importKey),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_public(pubKey, 0, importKey),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_public(pubKey, pubKeyLen, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_public(pubKey, pubKeyLen, importKey), 0);
    res = 0;
    ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, &res, importKey),
        0);
    ExpectIntEQ(res, 1);
#ifdef WOLFSSL_DILITHIUM_CHECK_KEY
    ExpectIntEQ(wc_dilithium_check_key(importKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    wc_dilithium_free(importKey);

#ifndef WOLFSSL_NO_ML_DSA_44
    if (sig != NULL) {
        if (sig[sigLen - 5] == 0) {
            /* Unused hints meant to be 0. */
            sig[sigLen - 5] = 0xff;
            res = 1;
            ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, &res,
                key), WC_NO_ERR_TRACE(SIG_VERIFY_E));
            ExpectIntEQ(res, 0);
            sig[sigLen - 5] = 0x00;
        }

        /* Last count of hints must be less than PARAMS_ML_DSA_44_OMEGA == 80 */
        b = sig[sigLen - 1];
        sig[sigLen - 1] = 0xff;
        res = 1;
        ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, &res, key),
            WC_NO_ERR_TRACE(SIG_VERIFY_E));
        ExpectIntEQ(res, 0);
        sig[sigLen - 1] = b;

        if (sig[sigLen - 4] > 1) {
            /* Index must be less than previous. */
            b = sig[sigLen - 84];
            sig[sigLen - 84] = 0xff;
            res = 1;
            ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, &res,
                key), WC_NO_ERR_TRACE(SIG_VERIFY_E));
            ExpectIntEQ(res, 0);
            sig[sigLen - 84] = b;
        }

        /* Mess up commit hash. */
        sig[0] ^= 0x80;
        res = 1;
        ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, &res, key),
            0);
        ExpectIntEQ(res, 0);
        sig[0] ^= 0x80;

        /* Mess up z. */
        sig[100] ^= 0x80;
        res = 1;
        ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, &res, key),
            0);
        ExpectIntEQ(res, 0);
        sig[100] ^= 0x80;

        /* Set all indeces to 0. */
        XMEMSET(sig + sigLen - 4, 0, 4);
        ExpectIntEQ(wc_dilithium_verify_msg(sig, sigLen, msg, 32, &res, key),
            WC_NO_ERR_TRACE(SIG_VERIFY_E));
        ExpectIntEQ(res, 0);
    }
#endif

    wc_dilithium_free(key);
    wc_FreeRng(&rng);

    XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(importKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_dilithium_sign_vfy(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) && \
    !defined(WOLFSSL_DILITHIUM_NO_SIGN) && !defined(WOLFSSL_DILITHIUM_NO_VERIFY)
    dilithium_key* key;
    WC_RNG rng;
    byte msg[64];
    byte* sig = NULL;
    word32 sigLen;
    byte ctx[10];
    int res;

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);
    sig = (byte*)XMALLOC(DILITHIUM_MAX_SIG_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(sig);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(msg, 0xAA, sizeof(msg));
    XMEMSET(ctx, 0x01, sizeof(ctx));

    ExpectIntEQ(wc_InitRng(&rng), 0);

#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_init(key), 0);
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
    ExpectIntEQ(wc_dilithium_make_key(key, &rng), 0);

    sigLen = DILITHIUM_MAX_SIG_SIZE;
    ExpectIntEQ(wc_dilithium_sign_ctx_msg(ctx, sizeof(ctx), msg, sizeof(msg),
        sig, &sigLen, key, &rng), 0);
    ExpectIntEQ(wc_dilithium_verify_ctx_msg(sig, sigLen, ctx, sizeof(ctx), msg,
        sizeof(msg), &res, key), 0);
    ExpectIntEQ(res, 1);

    sigLen = DILITHIUM_MAX_SIG_SIZE;
    ExpectIntEQ(wc_dilithium_sign_ctx_hash(ctx, sizeof(ctx),
        WC_HASH_TYPE_SHA3_512, msg, sizeof(msg), sig, &sigLen, key, &rng), 0);
    ExpectIntEQ(wc_dilithium_verify_ctx_hash(sig, sigLen, ctx, sizeof(ctx),
        WC_HASH_TYPE_SHA3_512, msg, sizeof(msg), &res, key), 0);
    ExpectIntEQ(res, 1);

    wc_dilithium_free(key);
#endif
#ifndef WOLFSSL_NO_ML_DSA_65
    ExpectIntEQ(wc_dilithium_init(key), 0);
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
    ExpectIntEQ(wc_dilithium_make_key(key, &rng), 0);

    sigLen = DILITHIUM_MAX_SIG_SIZE;
    ExpectIntEQ(wc_dilithium_sign_ctx_msg(ctx, sizeof(ctx), msg, sizeof(msg),
        sig, &sigLen, key, &rng), 0);
    ExpectIntEQ(wc_dilithium_verify_ctx_msg(sig, sigLen, ctx, sizeof(ctx), msg,
        sizeof(msg), &res, key), 0);
    ExpectIntEQ(res, 1);

    sigLen = DILITHIUM_MAX_SIG_SIZE;
    ExpectIntEQ(wc_dilithium_sign_ctx_hash(ctx, sizeof(ctx),
        WC_HASH_TYPE_SHA3_512, msg, sizeof(msg), sig, &sigLen, key, &rng), 0);
    ExpectIntEQ(wc_dilithium_verify_ctx_hash(sig, sigLen, ctx, sizeof(ctx),
        WC_HASH_TYPE_SHA3_512, msg, sizeof(msg), &res, key), 0);
    ExpectIntEQ(res, 1);

    wc_dilithium_free(key);
#endif
#ifndef WOLFSSL_NO_ML_DSA_87
    ExpectIntEQ(wc_dilithium_init(key), 0);
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
    ExpectIntEQ(wc_dilithium_make_key(key, &rng), 0);

    sigLen = DILITHIUM_MAX_SIG_SIZE;
    ExpectIntEQ(wc_dilithium_sign_ctx_msg(ctx, sizeof(ctx), msg, sizeof(msg),
        sig, &sigLen, key, &rng), 0);
    ExpectIntEQ(wc_dilithium_verify_ctx_msg(sig, sigLen, ctx, sizeof(ctx), msg,
        sizeof(msg), &res, key), 0);
    ExpectIntEQ(res, 1);

    sigLen = DILITHIUM_MAX_SIG_SIZE;
    ExpectIntEQ(wc_dilithium_sign_ctx_hash(ctx, sizeof(ctx),
        WC_HASH_TYPE_SHA3_512, msg, sizeof(msg), sig, &sigLen, key, &rng), 0);
    ExpectIntEQ(wc_dilithium_verify_ctx_hash(sig, sigLen, ctx, sizeof(ctx),
        WC_HASH_TYPE_SHA3_512, msg, sizeof(msg), &res, key), 0);
    ExpectIntEQ(res, 1);

    wc_dilithium_free(key);
#endif

    wc_FreeRng(&rng);
    XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);

#endif
    return EXPECT_RESULT();
}

static int test_wc_dilithium_check_key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    defined(WOLFSSL_DILITHIUM_CHECK_KEY) && \
    !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY)
    dilithium_key* checkKey;
    WC_RNG rng;
    byte* privCheckKey = NULL;
    word32 privCheckKeyLen = DILITHIUM_MAX_KEY_SIZE;
    byte* pubCheckKey = NULL;
    word32 pubCheckKeyLen = DILITHIUM_MAX_PUB_KEY_SIZE;

    checkKey = (dilithium_key*)XMALLOC(sizeof(*checkKey), NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(checkKey);
    privCheckKey = (byte*)XMALLOC(DILITHIUM_MAX_KEY_SIZE, NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(privCheckKey);
    pubCheckKey = (byte*)XMALLOC(DILITHIUM_MAX_PUB_KEY_SIZE, NULL,
        DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(pubCheckKey);

    if (checkKey != NULL) {
        XMEMSET(checkKey, 0, sizeof(*checkKey));
    }
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectIntEQ(wc_dilithium_check_key(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_dilithium_init(checkKey), 0);

    ExpectIntEQ(wc_dilithium_export_key(NULL, privCheckKey,
        &privCheckKeyLen, pubCheckKey, &pubCheckKeyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_key(privCheckKey,
        privCheckKeyLen, pubCheckKey, pubCheckKeyLen, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(checkKey, privCheckKey,
        &privCheckKeyLen, pubCheckKey, &pubCheckKeyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_import_key(privCheckKey,
        privCheckKeyLen, pubCheckKey, pubCheckKeyLen, checkKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(checkKey, WC_ML_DSA_44), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_set_level(checkKey, WC_ML_DSA_65), 0);
#else
    ExpectIntEQ(wc_dilithium_set_level(checkKey, WC_ML_DSA_87), 0);
#endif
    ExpectIntEQ(wc_dilithium_make_key(checkKey, &rng), 0);

    ExpectIntEQ(wc_dilithium_export_key(NULL, NULL, NULL, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(checkKey, NULL, NULL, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(NULL, privCheckKey, NULL, NULL, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(NULL, NULL, &privCheckKeyLen, NULL,
        NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(NULL, NULL, NULL, pubCheckKey, NULL),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(NULL, NULL, NULL, NULL,
        &pubCheckKeyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(NULL     , privCheckKey,
        &privCheckKeyLen, pubCheckKey, &pubCheckKeyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(checkKey, NULL        ,
        &privCheckKeyLen, pubCheckKey, &pubCheckKeyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(checkKey, privCheckKey,
        NULL            , pubCheckKey, &pubCheckKeyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(checkKey, privCheckKey,
        &privCheckKeyLen, NULL       , &pubCheckKeyLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(checkKey, privCheckKey,
        &privCheckKeyLen, pubCheckKey, NULL           ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_dilithium_export_key(checkKey, privCheckKey,
        &privCheckKeyLen, pubCheckKey, &pubCheckKeyLen), 0);

    /* Modify hash. */
    if (pubCheckKey != NULL) {
        pubCheckKey[0] ^= 0x80;
        ExpectIntEQ(wc_dilithium_import_key(NULL, 0, NULL, 0, NULL),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_dilithium_import_key(privCheckKey, 0, NULL, 0, NULL),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_dilithium_import_key(NULL, 0, pubCheckKey, 0, NULL),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_dilithium_import_key(NULL, 0, NULL, 0, checkKey),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_dilithium_import_key(NULL        ,
            privCheckKeyLen, pubCheckKey, pubCheckKeyLen, checkKey),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_dilithium_import_key(privCheckKey,
            0              , pubCheckKey, pubCheckKeyLen, checkKey),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_dilithium_import_key(privCheckKey,
            privCheckKeyLen, NULL       , pubCheckKeyLen, checkKey),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_dilithium_import_key(privCheckKey,
            privCheckKeyLen, pubCheckKey, 0             , checkKey),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_dilithium_import_key(privCheckKey,
            privCheckKeyLen, pubCheckKey, pubCheckKeyLen, NULL     ),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_dilithium_import_key(privCheckKey,
            privCheckKeyLen, pubCheckKey, pubCheckKeyLen, checkKey), 0);
        ExpectIntEQ(wc_dilithium_check_key(checkKey), WC_NO_ERR_TRACE(PUBLIC_KEY_E));
        pubCheckKey[0] ^= 0x80;

        /* Modify encoded t1. */
        pubCheckKey[48] ^= 0x80;
        ExpectIntEQ(wc_dilithium_import_key(privCheckKey,
            privCheckKeyLen,pubCheckKey, pubCheckKeyLen, checkKey), 0);
        ExpectIntEQ(wc_dilithium_check_key(checkKey), WC_NO_ERR_TRACE(PUBLIC_KEY_E));
        pubCheckKey[48] ^= 0x80;
    }

    wc_dilithium_free(checkKey);
    wc_FreeRng(&rng);

    XFREE(pubCheckKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(privCheckKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(checkKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    defined(WOLFSSL_DILITHIUM_PUBLIC_KEY)
static const unsigned char ml_dsa_public_der[] = {
#ifndef WOLFSSL_NO_ML_DSA_44
        0x30, 0x82, 0x05, 0x32, 0x30, 0x0d, 0x06, 0x09,
        0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03,
        0x11, 0x03, 0x82, 0x05, 0x21, 0x00,
        0xBC, 0x5F, 0xF8, 0x10, 0xEB, 0x08, 0x90, 0x48,
        0xB8, 0xAB, 0x30, 0x20, 0xA7, 0xBD, 0x3B, 0x16,
        0xC0, 0xE0, 0xCA, 0x3D, 0x6B, 0x97, 0xE4, 0x64,
        0x6C, 0x2C, 0xCA, 0xE0, 0xBB, 0xF1, 0x9E, 0xF7,
        0x23, 0x0A, 0x19, 0xD7, 0x5A, 0xDB, 0xDE, 0xD5,
        0x2D, 0xB8, 0x55, 0xE2, 0x52, 0xA7, 0x19, 0xFC,
        0xBD, 0x14, 0x7B, 0xA6, 0x7B, 0x2F, 0xAD, 0x14,
        0xED, 0x0E, 0x68, 0xFD, 0xFE, 0x8C, 0x65, 0xBA,
        0xDE, 0xAC, 0xB0, 0x91, 0x11, 0x93, 0xAD, 0xFA,
        0x87, 0x94, 0xD7, 0x8F, 0x8E, 0x3D, 0x66, 0x2A,
        0x1C, 0x49, 0xDA, 0x81, 0x9F, 0xD9, 0x59, 0xE7,
        0xF0, 0x78, 0xF2, 0x03, 0xC4, 0x56, 0xF8, 0xB6,
        0xE7, 0xC9, 0x41, 0x58, 0x98, 0xE5, 0x41, 0xC7,
        0x30, 0x32, 0xDB, 0xD6, 0x19, 0xEA, 0xF6, 0x0F,
        0x8D, 0x64, 0xF8, 0x68, 0x3D, 0xA9, 0x9E, 0xCA,
        0x51, 0x22, 0x0B, 0x0A, 0xCA, 0x28, 0x46, 0x40,
        0x99, 0xF5, 0x47, 0xC0, 0x27, 0x77, 0xBD, 0x37,
        0xD8, 0x4A, 0x59, 0xBD, 0x37, 0xED, 0x7A, 0x8A,
        0x92, 0x63, 0x3C, 0x75, 0xD0, 0x7C, 0x79, 0x3F,
        0xE7, 0x25, 0x2B, 0x58, 0x4A, 0xBF, 0x6A, 0x15,
        0xEE, 0x14, 0x50, 0x7E, 0x5E, 0x19, 0x3F, 0x89,
        0x86, 0x4D, 0x09, 0xAC, 0x87, 0x27, 0xA6, 0xD0,
        0x42, 0x1F, 0x0C, 0x19, 0xF0, 0xE2, 0xFB, 0xFC,
        0x21, 0x3D, 0x3F, 0xBD, 0x70, 0xF4, 0xF9, 0x76,
        0x2C, 0xEC, 0xFF, 0x23, 0x1E, 0x9C, 0x8A, 0x76,
        0x28, 0xD3, 0xF8, 0xB0, 0x85, 0x7B, 0x03, 0x2D,
        0x32, 0xDE, 0x62, 0xFF, 0x8E, 0xCB, 0xF4, 0x00,
        0x82, 0x89, 0xBF, 0x34, 0x40, 0x36, 0x65, 0xF8,
        0x1A, 0x08, 0x1A, 0xD5, 0xA8, 0x5A, 0x28, 0x2F,
        0x99, 0xBA, 0xB9, 0xE5, 0x38, 0x5A, 0xFB, 0xCC,
        0xCF, 0x44, 0xB7, 0x4C, 0x01, 0x96, 0xC7, 0x54,
        0x55, 0x27, 0xEC, 0x30, 0x26, 0xDA, 0x12, 0x80,
        0xC4, 0xEB, 0x37, 0xD0, 0x9C, 0xFE, 0x3E, 0xC4,
        0xB4, 0x91, 0x0B, 0x62, 0xEB, 0x98, 0x15, 0xA4,
        0x25, 0xC6, 0x59, 0x0F, 0xC4, 0xAD, 0x3F, 0xBB,
        0x22, 0x57, 0x52, 0xCC, 0x1F, 0xC5, 0x69, 0x3F,
        0x18, 0x7E, 0x7D, 0xEC, 0x4E, 0xEF, 0xBE, 0xB6,
        0xB9, 0x1B, 0xD9, 0x1C, 0x5E, 0x2E, 0xA6, 0xA9,
        0x1D, 0x14, 0xD0, 0x97, 0xBE, 0x20, 0x3F, 0xBA,
        0x0B, 0xF9, 0x37, 0xC9, 0x75, 0x07, 0xDC, 0x00,
        0x7C, 0x4C, 0xAA, 0x9B, 0x07, 0x85, 0x89, 0x29,
        0x66, 0xFF, 0x15, 0x90, 0x09, 0x24, 0xE5, 0x79,
        0xD4, 0xFB, 0xA0, 0x2B, 0xDA, 0x87, 0x55, 0x5F,
        0x07, 0x3D, 0xAE, 0x00, 0x51, 0x3E, 0x70, 0x80,
        0x9A, 0xBB, 0xC7, 0x11, 0xFB, 0xA2, 0xE7, 0x64,
        0x95, 0x77, 0xC4, 0x2A, 0xFD, 0xC2, 0x4B, 0xF7,
        0x41, 0x3E, 0x51, 0x26, 0x8A, 0xD6, 0xDB, 0x61,
        0x13, 0xB7, 0xD9, 0x19, 0x1A, 0xF9, 0xD0, 0x61,
        0xDB, 0xDE, 0xD5, 0xD6, 0x30, 0x87, 0x76, 0x50,
        0xC1, 0x24, 0xF1, 0x1B, 0xC4, 0xBD, 0xC3, 0xFD,
        0xC6, 0xA9, 0x00, 0xF6, 0x31, 0x26, 0xF9, 0x21,
        0xE8, 0x38, 0xAD, 0x0C, 0x22, 0x75, 0xA3, 0x38,
        0x9A, 0x39, 0xBD, 0x99, 0xA1, 0x34, 0x50, 0x45,
        0x50, 0x10, 0x1C, 0xD3, 0xE9, 0x5E, 0x6D, 0x14,
        0x96, 0xBE, 0x7D, 0xE6, 0x62, 0x7D, 0xF4, 0xFD,
        0x6C, 0x28, 0xBB, 0xF4, 0x0B, 0x30, 0xEF, 0xA9,
        0xB5, 0xC3, 0xD5, 0xC8, 0x5A, 0xB1, 0x4A, 0x65,
        0xC0, 0x2D, 0x6D, 0x47, 0x81, 0xFF, 0x13, 0xD3,
        0x28, 0x60, 0x85, 0x54, 0xB6, 0xD1, 0x5E, 0xD9,
        0x12, 0x89, 0xA6, 0xD5, 0x5A, 0xAC, 0x0C, 0x38,
        0xE3, 0x77, 0x06, 0xF7, 0x35, 0x5E, 0x9A, 0x4F,
        0xDA, 0x61, 0x5B, 0x87, 0x59, 0x26, 0xBF, 0xE5,
        0xA5, 0x9D, 0x9E, 0xF2, 0x73, 0xBF, 0x94, 0xA0,
        0x7C, 0xFA, 0x57, 0x31, 0x78, 0xF0, 0xE0, 0x04,
        0xB6, 0xE1, 0xEF, 0x0A, 0x83, 0x49, 0xE9, 0xBC,
        0xC0, 0x19, 0x81, 0xF2, 0x46, 0x0F, 0x0A, 0x27,
        0x43, 0xC2, 0x8D, 0x1E, 0x13, 0x8F, 0xFB, 0x76,
        0x5E, 0x7E, 0x33, 0x97, 0xB7, 0x91, 0x33, 0x35,
        0xD4, 0x02, 0xFE, 0x91, 0x80, 0x6A, 0xA8, 0xFC,
        0x81, 0x92, 0x53, 0xAF, 0x32, 0x69, 0x2F, 0xA6,
        0x51, 0xE8, 0x67, 0xF5, 0x90, 0x7E, 0xF4, 0x6F,
        0x00, 0x62, 0x5A, 0x03, 0x0E, 0xC9, 0x04, 0xED,
        0xAB, 0x21, 0x42, 0x6D, 0x59, 0x11, 0x9D, 0x2C,
        0xAA, 0x43, 0xBD, 0x93, 0x5D, 0xEC, 0x0A, 0x55,
        0x0C, 0x61, 0xEE, 0x4B, 0x27, 0x9C, 0x1C, 0xA3,
        0xA7, 0x9C, 0x79, 0xA6, 0x6E, 0x3F, 0x2D, 0x2F,
        0xAD, 0xB0, 0x0F, 0x59, 0xA3, 0xA4, 0x38, 0xAA,
        0x44, 0x57, 0x01, 0x06, 0x07, 0x30, 0x17, 0xFA,
        0x1C, 0x87, 0x57, 0x50, 0x01, 0x09, 0x72, 0x0D,
        0x12, 0x5B, 0xBA, 0x23, 0x1A, 0x0C, 0x36, 0x35,
        0x0C, 0x78, 0x08, 0x6D, 0xFD, 0xC8, 0xD6, 0x13,
        0xAE, 0xCA, 0x88, 0xC4, 0xCC, 0xAE, 0xB4, 0xA4,
        0x4D, 0x13, 0xAD, 0xB3, 0xC7, 0x17, 0xD6, 0x5C,
        0x82, 0xA3, 0x51, 0xB9, 0xB6, 0xEA, 0xBF, 0x6A,
        0x10, 0xF4, 0xB4, 0xE9, 0x62, 0x3E, 0x3A, 0x95,
        0xB4, 0xD4, 0x0A, 0x12, 0xA8, 0x18, 0xAC, 0x6B,
        0x38, 0x22, 0xDB, 0x82, 0xFB, 0x05, 0xDC, 0x42,
        0x02, 0x64, 0x8B, 0x44, 0x54, 0x68, 0x9A, 0xEB,
        0x69, 0xEA, 0x32, 0x5F, 0x03, 0xE3, 0x5D, 0xEF,
        0xA5, 0x47, 0x08, 0x48, 0x14, 0x20, 0xC6, 0xD6,
        0x97, 0xBB, 0x91, 0x2F, 0xCA, 0x0D, 0x3F, 0x19,
        0x2E, 0xF2, 0x97, 0xDF, 0xE7, 0x7F, 0xF3, 0x6B,
        0x21, 0x03, 0xF1, 0xAD, 0x1A, 0xEE, 0xCE, 0xD1,
        0xC8, 0x14, 0xC2, 0xCD, 0x7E, 0xF1, 0x6B, 0xCE,
        0x47, 0x6A, 0xD0, 0x4F, 0x94, 0x1A, 0xFC, 0x79,
        0xE3, 0x29, 0x54, 0x74, 0xA4, 0x10, 0x62, 0x51,
        0x8C, 0x00, 0x37, 0x86, 0x09, 0x34, 0xF0, 0xE5,
        0xE6, 0x52, 0xF7, 0x27, 0x49, 0xA6, 0x98, 0x63,
        0x2A, 0x09, 0x91, 0xF6, 0x13, 0xF5, 0xCB, 0x96,
        0xCA, 0x11, 0x78, 0xF9, 0x74, 0xF2, 0xC4, 0xAA,
        0x0C, 0xE6, 0x3D, 0xC2, 0x4E, 0x36, 0x4C, 0x92,
        0xA6, 0x43, 0xB9, 0x0A, 0x5F, 0x85, 0xA6, 0x2F,
        0xD4, 0xD8, 0xD2, 0xB1, 0x93, 0xD2, 0x9B, 0x18,
        0xBE, 0xDE, 0x26, 0x53, 0xFC, 0x5D, 0x3F, 0x24,
        0xF5, 0xB2, 0xC0, 0x18, 0xDB, 0xBC, 0xB6, 0xEF,
        0x00, 0xF3, 0x05, 0xBF, 0x93, 0x66, 0x6B, 0xD4,
        0x7F, 0xEA, 0x91, 0x93, 0xBC, 0x23, 0x3D, 0xB3,
        0x91, 0x21, 0x44, 0x2E, 0x93, 0x8D, 0xA5, 0xDD,
        0x07, 0xEE, 0x6E, 0x87, 0x9C, 0x5B, 0x9D, 0xFF,
        0x41, 0xEC, 0xEE, 0x5E, 0x05, 0x89, 0xAE, 0x61,
        0x75, 0xFF, 0x5E, 0xC6, 0xF6, 0xD2, 0x62, 0x9F,
        0x56, 0xB1, 0x8B, 0x4D, 0xE6, 0x6F, 0xCB, 0x13,
        0xDF, 0x04, 0x00, 0xA7, 0x97, 0xC9, 0x22, 0x70,
        0xF6, 0x9B, 0xDE, 0xBD, 0xDC, 0xB8, 0x8C, 0x42,
        0x48, 0x91, 0x9B, 0x56, 0xCD, 0xA7, 0x0B, 0x8A,
        0xC4, 0xF9, 0x42, 0x9C, 0x29, 0x2D, 0xA9, 0x4D,
        0x64, 0x78, 0x28, 0x07, 0x64, 0xFE, 0x23, 0x86,
        0xFC, 0x38, 0xCB, 0x09, 0x31, 0x45, 0x88, 0x39,
        0xEF, 0x4E, 0x7D, 0xE8, 0xF0, 0x68, 0x9D, 0x99,
        0x80, 0x59, 0x88, 0xC7, 0xF9, 0x61, 0x11, 0x85,
        0x2C, 0x89, 0x29, 0xE5, 0xA5, 0x40, 0xD3, 0xB7,
        0x8D, 0x71, 0x2D, 0xEC, 0xC3, 0x96, 0xFE, 0xF3,
        0xEC, 0x34, 0x40, 0x21, 0x84, 0xE4, 0xFD, 0x29,
        0xF3, 0x63, 0xEA, 0x80, 0xF6, 0xFC, 0x50, 0xBA,
        0x9A, 0x11, 0x35, 0x1A, 0xCE, 0xEA, 0x8F, 0xE6,
        0x8D, 0x54, 0x1E, 0x1A, 0xA5, 0x84, 0x8D, 0x9F,
        0x6E, 0x61, 0xDF, 0xB6, 0x2B, 0x2F, 0x23, 0xBC,
        0x50, 0x81, 0xE8, 0x2F, 0x76, 0x22, 0x6E, 0x03,
        0x28, 0x49, 0x82, 0xEC, 0x48, 0x48, 0x12, 0x09,
        0xB1, 0xA7, 0xD4, 0xC8, 0x79, 0x7E, 0x44, 0xBF,
        0xA8, 0x70, 0xB2, 0x20, 0x04, 0xDB, 0x74, 0xBD,
        0x7D, 0x47, 0x8D, 0x5B, 0x36, 0x14, 0xD2, 0xB1,
        0xDA, 0x75, 0x02, 0xB3, 0x98, 0xEB, 0x9D, 0xA8,
        0x0D, 0x06, 0x46, 0x1E, 0x90, 0xE0, 0x30, 0x60,
        0x44, 0x6A, 0xB4, 0xA8, 0x23, 0x84, 0x32, 0xBF,
        0xAF, 0x75, 0x2F, 0x39, 0x17, 0x91, 0x21, 0x4F,
        0x1E, 0x6B, 0x63, 0x59, 0x0D, 0x53, 0x60, 0x60,
        0xD1, 0xC2, 0x45, 0x30, 0x7B, 0xC5, 0xC1, 0xBA,
        0xC4, 0xAA, 0xA0, 0x99, 0xD3, 0x6B, 0xB6, 0xDC,
        0xBC, 0x97, 0x3C, 0xF2, 0xE6, 0x9F, 0x27, 0x34,
        0xD0, 0xF2, 0x9A, 0xEE, 0xC4, 0x56, 0x7B, 0x99,
        0xA1, 0x6B, 0xC1, 0x7C, 0x6C, 0xDD, 0xAC, 0xEF,
        0xE4, 0x99, 0x27, 0xFB, 0x14, 0xE7, 0xD9, 0x8D,
        0xD4, 0x26, 0x35, 0x19, 0x46, 0x9C, 0xCA, 0x3D,
        0xB4, 0x67, 0x9A, 0x68, 0xCE, 0xED, 0xA9, 0x55,
        0x59, 0x22, 0x10, 0xFC, 0x49, 0xAA, 0x5F, 0xBE,
        0x93, 0x4C, 0xC7, 0x3D, 0x84, 0xE4, 0xBA, 0x54,
        0x78, 0x00, 0x2D, 0x68, 0x90, 0x98, 0x90, 0x68,
        0xEF, 0x8F, 0xC9, 0x8C, 0x25, 0x32, 0xB8, 0x3B,
        0xF3, 0xCB, 0x9E, 0xF0, 0x28, 0x93, 0xC2, 0x15,
        0x24, 0x26, 0xB9, 0xD1, 0xA9, 0x47, 0x34, 0xDF,
        0xB4, 0xF9, 0x11, 0x35, 0x14, 0x3C, 0x9E, 0xED,
        0x18, 0xFD, 0x51, 0xAE, 0x87, 0x5D, 0x07, 0xA2,
        0x37, 0x75, 0x60, 0x6A, 0x73, 0x4F, 0xBA, 0x98,
        0xC0, 0x63, 0xB4, 0xA1, 0x62, 0x2E, 0x7F, 0xF2,
        0x1A, 0xA7, 0xE6, 0x52, 0xA3, 0xD6, 0xC1, 0x9F,
        0xE0, 0xDC, 0x67, 0x61, 0xB7, 0xD3, 0x53, 0x02,
        0xBF, 0x21, 0x4D, 0x30, 0x79, 0xF7, 0x60, 0x51,
        0x08, 0x2A, 0x87, 0x59, 0x29, 0x92, 0x0D, 0xC3,
        0xB3, 0xCB, 0x43, 0x21, 0x1A, 0x23, 0xA4, 0x3A,
        0x50, 0x33, 0x2F, 0xAF, 0x1A, 0xC2, 0x19, 0x1E,
        0x71, 0x71, 0x25, 0xF6, 0x3E, 0x25, 0x86, 0xC4,
        0xD8, 0x6D, 0xCA, 0x6B, 0xCD, 0x3D, 0x03, 0x8F,
        0x9D, 0x3A, 0x7B, 0x66, 0xCB, 0xC7, 0xDF, 0x34
#elif !defined(WOLFSSL_NO_ML_DSA_65)
        0x30, 0x82, 0x07, 0xb2, 0x30, 0x0d, 0x06, 0x09,
        0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03,
        0x12, 0x03, 0x82, 0x07, 0xa1, 0x00,
        0xD2, 0xFD, 0x03, 0xF3, 0xA1, 0xB7, 0xF6, 0x35,
        0xAF, 0x9F, 0x34, 0xD5, 0x80, 0xA9, 0x8F, 0x52,
        0x4C, 0x73, 0x5B, 0xD5, 0xBA, 0x23, 0x55, 0xDC,
        0x6E, 0x03, 0x5B, 0xD2, 0x17, 0x65, 0x58, 0x0C,
        0xBB, 0x11, 0x19, 0x23, 0xF1, 0x94, 0xA7, 0xCC,
        0x8A, 0x7B, 0xB2, 0xEB, 0xC5, 0xC0, 0xE7, 0x1A,
        0xA6, 0x37, 0xCC, 0x80, 0x0E, 0x61, 0x03, 0xB8,
        0x50, 0xA5, 0x39, 0xB2, 0xA3, 0x9E, 0x1B, 0x6D,
        0x71, 0x3E, 0x5D, 0xB8, 0x31, 0x4C, 0x9A, 0xE1,
        0xF8, 0xBF, 0x8A, 0x38, 0xF0, 0x6A, 0xFB, 0x9D,
        0x73, 0xB1, 0x61, 0xB0, 0xFF, 0xE3, 0xA4, 0x89,
        0x17, 0x06, 0xAE, 0x26, 0xD5, 0x4F, 0xFB, 0x49,
        0x6D, 0xF8, 0xDC, 0x0F, 0x19, 0x83, 0x50, 0x95,
        0x00, 0xC9, 0xAB, 0xBD, 0x28, 0xE5, 0x9B, 0x3F,
        0xCD, 0xAB, 0xBD, 0xAD, 0xAB, 0xD4, 0x5E, 0xC3,
        0x14, 0x99, 0x37, 0x8B, 0xDE, 0x84, 0x9E, 0x7C,
        0x1F, 0x19, 0xB7, 0x04, 0x4D, 0x67, 0xE0, 0x51,
        0x06, 0xD7, 0x13, 0x6D, 0x95, 0x38, 0x0D, 0x56,
        0x05, 0xD4, 0x46, 0x5D, 0x87, 0x75, 0x57, 0x06,
        0x5D, 0xF0, 0xA7, 0x5D, 0x3C, 0x28, 0x54, 0x2F,
        0x40, 0xFE, 0xED, 0x42, 0xEC, 0x7E, 0x28, 0x06,
        0x37, 0xB0, 0x83, 0xD9, 0x88, 0xBC, 0xA5, 0xF6,
        0x39, 0x4E, 0x02, 0x39, 0x6C, 0x46, 0x76, 0x18,
        0x4F, 0xB6, 0x33, 0x18, 0xDA, 0xFA, 0xF5, 0xBB,
        0xDD, 0xE0, 0x0E, 0x30, 0x8F, 0xE8, 0x40, 0x19,
        0xC2, 0x34, 0x0A, 0x3F, 0x3E, 0x1C, 0x08, 0x65,
        0x62, 0x49, 0x70, 0x71, 0x12, 0x83, 0x35, 0x6A,
        0xE1, 0x4B, 0xD6, 0xB9, 0x4D, 0x1C, 0x9A, 0xE1,
        0x88, 0xDE, 0x1A, 0x8A, 0x2C, 0xA8, 0x24, 0xA8,
        0xEA, 0xE2, 0xFE, 0x6A, 0xFB, 0x38, 0xD8, 0x3A,
        0x2D, 0x99, 0x99, 0x6A, 0xB2, 0x1F, 0xE3, 0xE8,
        0x4C, 0x0B, 0xE6, 0xB6, 0xDA, 0x08, 0x87, 0x9B,
        0x67, 0x73, 0x74, 0xFA, 0x7C, 0x69, 0x1B, 0x13,
        0xD4, 0x0F, 0xA9, 0xD4, 0xCC, 0x26, 0xB2, 0x28,
        0x8D, 0x5A, 0x8C, 0x9A, 0x43, 0x72, 0x43, 0x81,
        0x00, 0x4D, 0x61, 0xB0, 0xD5, 0x7F, 0xF4, 0x00,
        0x31, 0x4C, 0x8E, 0x30, 0xEE, 0x79, 0x6A, 0xF1,
        0x0F, 0x7E, 0xE2, 0x1B, 0xF1, 0x3D, 0x08, 0x18,
        0x04, 0x65, 0xAB, 0xC7, 0x2E, 0xDD, 0xB0, 0x80,
        0xC6, 0xA0, 0x71, 0x84, 0xE3, 0xEE, 0xDC, 0x47,
        0xC1, 0x9A, 0xA7, 0xF0, 0x9D, 0x1F, 0x33, 0x09,
        0xE1, 0x83, 0xA2, 0xBD, 0x9B, 0x05, 0x73, 0xDD,
        0xE4, 0x74, 0xA8, 0x1B, 0xA4, 0xF7, 0x8D, 0x0C,
        0x52, 0x3D, 0x0C, 0x04, 0xF9, 0x00, 0x60, 0xFD,
        0x57, 0x1A, 0x35, 0xC0, 0x37, 0xE0, 0x79, 0xC5,
        0xE2, 0x10, 0xD7, 0x39, 0x0D, 0xF5, 0x68, 0xF2,
        0xE2, 0xF0, 0x3C, 0xE4, 0x44, 0x20, 0xC8, 0x2F,
        0x3F, 0xE6, 0x9E, 0xB9, 0xB4, 0x8E, 0xE9, 0x09,
        0x62, 0xD6, 0xB0, 0xF2, 0x44, 0x40, 0x64, 0x8F,
        0x71, 0xED, 0xB2, 0x41, 0xEE, 0x65, 0x66, 0xFC,
        0x1A, 0x64, 0xCA, 0xBF, 0x66, 0xBE, 0x6F, 0xEC,
        0xBC, 0xB1, 0x38, 0x7C, 0x82, 0xA7, 0xBC, 0x20,
        0x2D, 0x9E, 0x36, 0x79, 0x98, 0xE2, 0xA2, 0x91,
        0xAF, 0x0C, 0xD1, 0x57, 0x06, 0x77, 0xFE, 0x8D,
        0x63, 0xA3, 0x28, 0x5A, 0x2E, 0xA6, 0xEB, 0x29,
        0xAF, 0x9D, 0xC1, 0xAE, 0xC1, 0xC3, 0x6C, 0x47,
        0x06, 0xB1, 0x2B, 0xAA, 0x20, 0x83, 0x96, 0x92,
        0xF2, 0x86, 0xA6, 0xE0, 0x32, 0x14, 0x68, 0xF7,
        0x47, 0x93, 0x45, 0xC4, 0xD5, 0x2F, 0xBD, 0xB2,
        0xF0, 0x67, 0x25, 0xB5, 0x54, 0xB8, 0x9E, 0x24,
        0x92, 0x61, 0x26, 0x81, 0xAC, 0xEB, 0xC6, 0xC7,
        0xBA, 0xDA, 0x92, 0x25, 0x81, 0x8D, 0xBC, 0x35,
        0xD6, 0x4C, 0x22, 0xC4, 0x8B, 0xFF, 0x80, 0xA7,
        0x30, 0xD0, 0x71, 0x6D, 0xFA, 0xC9, 0x9D, 0xFD,
        0x5B, 0x89, 0x92, 0x61, 0x1D, 0x0C, 0x93, 0xEE,
        0x90, 0xBD, 0xB2, 0x60, 0x02, 0x2A, 0xFE, 0x25,
        0xD9, 0x13, 0xE0, 0x6E, 0xFF, 0xB5, 0x9C, 0xB1,
        0xF8, 0xA6, 0x0C, 0xBF, 0xA5, 0xAB, 0x2F, 0x45,
        0x9A, 0x16, 0xF4, 0x67, 0xE9, 0x89, 0x52, 0x5E,
        0x0A, 0x37, 0xEB, 0xE5, 0x6E, 0x83, 0x3F, 0xDE,
        0x55, 0xDB, 0x9D, 0x15, 0x30, 0xAD, 0xCF, 0x45,
        0x84, 0x6D, 0xF2, 0x81, 0xE4, 0x7C, 0xAA, 0x1E,
        0x0A, 0x27, 0xEF, 0xDE, 0x21, 0x07, 0xD3, 0x54,
        0xCE, 0xA0, 0xF6, 0xA4, 0x54, 0x69, 0x2F, 0x04,
        0xCD, 0x83, 0x8E, 0xBD, 0xD4, 0x6E, 0x19, 0x1E,
        0x5D, 0x9C, 0x11, 0x83, 0x9A, 0x2C, 0x3F, 0x48,
        0x8A, 0x4F, 0xC7, 0xCD, 0x26, 0x5A, 0x7B, 0x5D,
        0x32, 0xB0, 0x8C, 0xBD, 0xBF, 0xAB, 0x9D, 0x2C,
        0xCD, 0x76, 0x22, 0x2C, 0x8E, 0xE3, 0x7D, 0xDC,
        0xBD, 0x2A, 0xA0, 0x63, 0xED, 0x86, 0x14, 0x73,
        0xA6, 0x45, 0x4C, 0xAE, 0xA3, 0x77, 0x85, 0x0B,
        0x1A, 0x2B, 0x9D, 0xDB, 0xBC, 0xB3, 0x74, 0xFA,
        0xB5, 0xB1, 0x2F, 0x35, 0x1C, 0x8E, 0x58, 0x88,
        0x87, 0x2E, 0x5C, 0xD1, 0xF6, 0x0A, 0x4F, 0xAE,
        0x1F, 0xF8, 0x37, 0xD1, 0x92, 0xC2, 0x2B, 0xEB,
        0x41, 0xEE, 0x6F, 0xA3, 0x92, 0xFC, 0xDF, 0x45,
        0x50, 0xFF, 0x46, 0xB5, 0xCE, 0x90, 0x6D, 0x01,
        0x7E, 0xF3, 0x07, 0x7D, 0xF1, 0x32, 0x30, 0x0D,
        0x8B, 0xBF, 0xA9, 0xBB, 0x03, 0xC7, 0x5E, 0x79,
        0xE2, 0xF0, 0x4C, 0x28, 0x4A, 0xD0, 0x6A, 0x44,
        0x39, 0x96, 0x49, 0xC3, 0xE2, 0xA2, 0xA8, 0xD1,
        0xEF, 0xE9, 0xB7, 0xA4, 0xE0, 0xC2, 0x71, 0x04,
        0x7A, 0xB7, 0x59, 0x08, 0xBF, 0xF7, 0xDF, 0x9E,
        0x30, 0xEC, 0xA5, 0x47, 0x74, 0x5B, 0xAE, 0x23,
        0xA8, 0x6F, 0xF9, 0xA8, 0xB5, 0x8C, 0x25, 0x38,
        0xB8, 0x8B, 0x86, 0x64, 0x01, 0x07, 0x69, 0x02,
        0xDC, 0x5F, 0x0B, 0xD7, 0x61, 0x68, 0x7B, 0x49,
        0xEA, 0xFE, 0x36, 0xD3, 0x50, 0xCB, 0xED, 0xFD,
        0xD3, 0x6C, 0x12, 0x1C, 0xF2, 0x37, 0x86, 0xBF,
        0xCF, 0x7E, 0x47, 0x07, 0x64, 0x96, 0xEA, 0xB6,
        0xBB, 0xDA, 0x77, 0x40, 0x49, 0xC2, 0xEB, 0xAB,
        0xE2, 0xDE, 0x99, 0xC4, 0xC2, 0x4F, 0x2D, 0xB7,
        0x36, 0x84, 0x01, 0x5B, 0x37, 0x39, 0x77, 0x49,
        0x67, 0x60, 0xCF, 0x9A, 0xC2, 0x3D, 0x8B, 0x62,
        0x31, 0x33, 0xDB, 0x2D, 0xE1, 0x0D, 0x73, 0xFA,
        0x6A, 0xD1, 0xC6, 0xDA, 0xC8, 0x43, 0x4F, 0x28,
        0xC6, 0xE2, 0x51, 0xCE, 0x72, 0x93, 0xCF, 0xF3,
        0xF3, 0xB6, 0x1E, 0xFC, 0xB5, 0xA4, 0x35, 0x12,
        0x36, 0x70, 0xF2, 0x98, 0x46, 0xA1, 0x3D, 0xF3,
        0xEE, 0x71, 0x26, 0x04, 0x46, 0x1F, 0x1B, 0xAB,
        0x8F, 0x4E, 0xBC, 0x83, 0x6D, 0xE0, 0x58, 0x97,
        0x8A, 0xE7, 0x34, 0x39, 0x6A, 0x98, 0x08, 0x1B,
        0x35, 0xCC, 0x98, 0x18, 0x8A, 0x86, 0x94, 0x9C,
        0x99, 0x27, 0x0D, 0x47, 0x09, 0x85, 0x4C, 0x5B,
        0x35, 0xB1, 0x7F, 0x48, 0xA3, 0x73, 0x13, 0x4C,
        0x81, 0x4C, 0xC8, 0xA0, 0xF3, 0xE2, 0xFA, 0x80,
        0x7F, 0x2A, 0x91, 0x85, 0x30, 0x90, 0x78, 0x64,
        0x77, 0x82, 0x82, 0xD7, 0x5E, 0x03, 0xA4, 0x1B,
        0x25, 0x04, 0xEE, 0xD8, 0x16, 0xA4, 0x17, 0xA3,
        0xAC, 0x6B, 0xA1, 0x60, 0x80, 0xC3, 0x9B, 0x73,
        0x10, 0x19, 0x20, 0x02, 0xA7, 0x28, 0xF7, 0xF2,
        0x03, 0x95, 0x00, 0x9A, 0x9E, 0x16, 0x76, 0x7C,
        0xE1, 0x97, 0x1F, 0x5D, 0xE7, 0xD2, 0x29, 0xA5,
        0x06, 0x13, 0x36, 0x9E, 0x43, 0x82, 0x04, 0x5A,
        0x8E, 0x81, 0x90, 0x1F, 0x4D, 0xBA, 0x81, 0x02,
        0xF3, 0xD4, 0x13, 0xFE, 0x35, 0xB3, 0x26, 0xA8,
        0x74, 0xF2, 0x33, 0xB7, 0x19, 0xA7, 0x13, 0x76,
        0x00, 0xD3, 0x5D, 0x33, 0xAE, 0xB6, 0xB7, 0x25,
        0x96, 0x24, 0x08, 0x3A, 0xA9, 0x68, 0x73, 0x0C,
        0x8F, 0x78, 0x29, 0x2A, 0xD2, 0x8F, 0x14, 0xEE,
        0xAB, 0xE6, 0x60, 0x83, 0x59, 0x84, 0xFE, 0x69,
        0xEF, 0x23, 0xDE, 0xC8, 0xC3, 0x27, 0xC0, 0xEB,
        0x0B, 0x88, 0x2D, 0x58, 0x7E, 0x1E, 0xC4, 0x33,
        0xDA, 0x85, 0xC9, 0xFD, 0x1E, 0x0A, 0x34, 0x99,
        0x4D, 0xEA, 0x24, 0x0C, 0x85, 0x44, 0x52, 0xD1,
        0x8C, 0x30, 0xF4, 0x96, 0xE4, 0x9E, 0xC9, 0x04,
        0xB6, 0x02, 0xE0, 0xF5, 0x06, 0x2E, 0xDC, 0xDA,
        0x03, 0x28, 0x0A, 0x53, 0xB4, 0x31, 0x35, 0x74,
        0xCC, 0x2C, 0x0D, 0x54, 0x71, 0xBC, 0x96, 0x13,
        0xBD, 0xFD, 0x66, 0x41, 0xF5, 0xBD, 0x12, 0x7B,
        0xAB, 0x5B, 0x5E, 0xB3, 0xD4, 0x99, 0xA3, 0x31,
        0x14, 0x04, 0x82, 0x20, 0xE8, 0x19, 0xF8, 0xEE,
        0x12, 0xCA, 0x92, 0x2C, 0x8F, 0x17, 0xD9, 0xC9,
        0xF5, 0x1A, 0xD5, 0xBD, 0x68, 0x83, 0xB1, 0x0E,
        0x6A, 0xA2, 0x48, 0x3B, 0xA4, 0x9D, 0xC5, 0x47,
        0xDA, 0x76, 0x86, 0x15, 0x13, 0x44, 0xF4, 0xE9,
        0x09, 0x9B, 0x38, 0xE4, 0x30, 0xB5, 0x22, 0x6B,
        0x05, 0x98, 0x32, 0xCF, 0x03, 0xDB, 0x48, 0xFB,
        0x02, 0xDB, 0xA4, 0xE6, 0x15, 0x93, 0xDC, 0x45,
        0x76, 0x36, 0x04, 0x91, 0x89, 0x0E, 0x53, 0xEC,
        0x0E, 0x6A, 0xC7, 0x3C, 0xF3, 0x2B, 0x25, 0xD8,
        0x23, 0xB3, 0x84, 0x56, 0xE2, 0x86, 0x50, 0x5A,
        0x54, 0x1E, 0x5A, 0xEE, 0xE9, 0x6B, 0x19, 0x14,
        0xF5, 0xF7, 0x66, 0x87, 0xCE, 0x2B, 0x01, 0x60,
        0x22, 0x7A, 0xBE, 0xD7, 0x79, 0x93, 0x59, 0x4B,
        0xCD, 0x83, 0x13, 0x66, 0x20, 0x6D, 0x75, 0x71,
        0x40, 0x82, 0xF1, 0xC4, 0x6F, 0x1F, 0x44, 0x39,
        0xAC, 0x81, 0xA5, 0x7A, 0xF3, 0x1C, 0x81, 0xC5,
        0x55, 0x30, 0x7A, 0x07, 0x0F, 0xFA, 0x94, 0xE0,
        0x47, 0x9B, 0x78, 0x4B, 0xBD, 0x88, 0xA6, 0x0C,
        0xD4, 0xC7, 0xCF, 0xD9, 0x4E, 0x6A, 0xFE, 0x02,
        0xF6, 0xB2, 0x1F, 0x72, 0xAF, 0x0D, 0xCD, 0x66,
        0x09, 0xD4, 0x0C, 0x96, 0x5C, 0x14, 0xE5, 0xF2,
        0x38, 0x91, 0x83, 0xE5, 0x3D, 0xE9, 0x30, 0xF7,
        0xDE, 0x1D, 0x44, 0x21, 0x5C, 0xF4, 0x91, 0x44,
        0x84, 0x4E, 0x8B, 0x87, 0xF7, 0x8A, 0x7F, 0x13,
        0x2A, 0xEF, 0xE2, 0x2B, 0xE8, 0x0B, 0x4E, 0x3A,
        0x05, 0xEE, 0x3A, 0x68, 0xCC, 0xF6, 0x09, 0xEF,
        0x44, 0x04, 0x74, 0x02, 0xE4, 0x49, 0x30, 0x46,
        0xE6, 0xF9, 0xC7, 0x67, 0xFF, 0x8A, 0x75, 0xE2,
        0x8B, 0x3C, 0xE0, 0x77, 0xFD, 0xE7, 0xE7, 0xEE,
        0xD3, 0x13, 0xB5, 0xBF, 0x7E, 0x46, 0x01, 0x27,
        0xCA, 0x81, 0x82, 0xE9, 0xBC, 0x79, 0x4C, 0x0D,
        0xFA, 0x73, 0x0F, 0xB9, 0x20, 0x08, 0x05, 0x75,
        0xA7, 0x51, 0xB5, 0xCA, 0xEC, 0x85, 0xA1, 0x09,
        0xB4, 0x42, 0x2B, 0xA2, 0x66, 0x74, 0x3F, 0x0D,
        0x03, 0x2B, 0xDA, 0x8F, 0x1C, 0xA6, 0x24, 0x8C,
        0xDB, 0x91, 0x75, 0x30, 0xDF, 0x13, 0x02, 0xA5,
        0xF8, 0xC1, 0x8D, 0xC6, 0x42, 0xD5, 0x24, 0x78,
        0xC9, 0x8C, 0x12, 0xA3, 0xF1, 0x6E, 0xF2, 0xB6,
        0x2B, 0x4F, 0x59, 0xEA, 0x1B, 0xB5, 0x8D, 0xE7,
        0xB6, 0x5B, 0x3C, 0x71, 0x53, 0xCE, 0x6D, 0xA5,
        0xE4, 0x95, 0x07, 0x46, 0xF8, 0x0E, 0x08, 0x7A,
        0x0E, 0x35, 0x86, 0xD0, 0x97, 0x79, 0x1B, 0xF3,
        0x6D, 0xEF, 0x86, 0x5D, 0x68, 0x59, 0x1D, 0x39,
        0xD0, 0x90, 0x37, 0x73, 0xEE, 0xA9, 0x62, 0x14,
        0x7F, 0x34, 0x70, 0x41, 0x38, 0xB5, 0x4D, 0xF7,
        0x92, 0x4C, 0xDD, 0x8C, 0x33, 0x3D, 0xB5, 0xE1,
        0xA4, 0x09, 0xCC, 0xB2, 0xB3, 0x4E, 0x2C, 0x3C,
        0x8C, 0x7F, 0xDD, 0x3F, 0xD8, 0xD0, 0x12, 0xCB,
        0xF3, 0x82, 0xAA, 0xA8, 0x5E, 0x83, 0xA1, 0x2F,
        0x23, 0x5A, 0x2D, 0x14, 0x7D, 0x03, 0x5B, 0x7B,
        0x28, 0xB3, 0x4B, 0x6F, 0x57, 0x94, 0x9F, 0x32,
        0x24, 0x82, 0xA7, 0xD4, 0xD3, 0xB1, 0x50, 0x45,
        0xC4, 0x20, 0xD5, 0xAD, 0xDC, 0x7F, 0x0E, 0x69,
        0xB4, 0xDC, 0x1C, 0xBA, 0x58, 0xB0, 0x1D, 0x87,
        0x24, 0x80, 0xB0, 0x6A, 0x26, 0x0D, 0x82, 0x7D,
        0x89, 0x1B, 0x13, 0xC4, 0xC5, 0xCA, 0x50, 0xC7,
        0x48, 0xDE, 0x3C, 0x77, 0x1B, 0xE6, 0x1E, 0x9A,
        0xA1, 0x70, 0x16, 0x5C, 0xB0, 0x1F, 0x4B, 0xF5,
        0xDA, 0x27, 0xA7, 0x79, 0x1D, 0x3A, 0xD3, 0xF6,
        0x26, 0x7B, 0x4C, 0xB4, 0xE6, 0x1B, 0x28, 0xFA,
        0x17, 0x08, 0x41, 0x8D, 0x93, 0x2D, 0xFC, 0x41,
        0x61, 0x88, 0x0C, 0x5D, 0x3B, 0x17, 0xA9, 0x66,
        0x3A, 0x90, 0x61, 0xFA, 0x8F, 0x18, 0x04, 0x31,
        0x58, 0x50, 0xFE, 0x4E, 0x73, 0x06, 0xC8, 0x82,
        0xB3, 0x82, 0x27, 0xE8, 0x67, 0xF8, 0x08, 0x72,
        0xCD, 0xC1, 0x94, 0x4D, 0x47, 0x26, 0x15, 0xEA,
        0x49, 0x00, 0xEF, 0x7D, 0x27, 0x0B, 0x88, 0x1D,
        0x41, 0x30, 0xF5, 0x6C, 0x5C, 0xC9, 0x80, 0xD9,
        0x2A, 0x47, 0xAD, 0xA6, 0x65, 0x7E, 0xB6, 0xF3,
        0x7A, 0x38, 0x5D, 0x2D, 0x8C, 0xC9, 0x93, 0xE1,
        0x44, 0x2E, 0xB0, 0x52, 0x81, 0x85, 0x36, 0x36,
        0x99, 0x1E, 0x34, 0xAA, 0xDC, 0x68, 0x95, 0x4D,
        0x04, 0xE7, 0xAD, 0xEF, 0x76, 0xBF, 0x88, 0x0F,
        0x05, 0x9B, 0x0C, 0xBB, 0x55, 0xD9, 0x15, 0xA4,
        0xB1, 0x23, 0xE2, 0xF1, 0x33, 0x9A, 0x07, 0x3C,
        0xBF, 0xBC, 0x40, 0x9B, 0xEF, 0xF6, 0x40, 0x0A,
        0xE0, 0x96, 0xD5, 0xAE, 0x18, 0xEC, 0x42, 0xCF,
        0xFA, 0xD5, 0xB4, 0x98, 0x0F, 0xA3, 0x5B, 0xF0,
        0x34, 0x13, 0xAD, 0xB5, 0xD7, 0xE6, 0x87, 0x6A,
        0xC3, 0x55, 0xD1, 0xC9, 0xED, 0x70, 0xCA, 0x2B,
        0x97, 0x39, 0x54, 0xD1, 0x2B, 0x3C, 0xDD, 0x76,
        0xAC, 0x68, 0x35, 0xDB, 0x96, 0x00, 0x3E, 0xD8,
        0xC4, 0xE2, 0x88, 0xB7, 0x1F, 0xD7, 0x7D, 0xBA,
        0xA7, 0x63, 0x57, 0x20, 0xE1, 0x2A, 0xE0, 0xA3,
        0x17, 0xDE, 0x80, 0x8C, 0x66, 0x4E, 0x31, 0x7F,
        0x55, 0x27, 0x57, 0x91, 0xF3, 0x24, 0x5C, 0xA4,
        0xFE, 0x5D, 0x4D, 0x41, 0x07, 0x7F, 0xC1, 0x50,
        0xA6, 0xE4, 0x03, 0xD5, 0xA2, 0x08, 0xE4, 0x6E,
        0xAD, 0xBE, 0x8F, 0x2C, 0xFB, 0x8A, 0xF4, 0x72,
        0xF4, 0xA0, 0xCE, 0xAC, 0x01, 0x52, 0x19, 0x47,
        0x8E, 0x6B, 0x86, 0xC9, 0x58, 0xCF, 0x86, 0x52,
        0x5B, 0x74, 0x85, 0xC1, 0x73, 0x4C, 0x7E, 0xF0,
        0x0E, 0x90, 0x68, 0x3F, 0xFF, 0x5D, 0xBD, 0x0A,
        0x7D, 0x41, 0x3A, 0x85, 0x50, 0x21, 0x02, 0x6A,
        0x1B, 0x32, 0x01, 0x3A, 0x46, 0x16, 0xCB, 0xCD,
        0x37, 0x00, 0xAC, 0xBC, 0x70, 0x5B, 0xE3, 0xEF,
        0xBA, 0x62, 0x5C, 0x69, 0xA0, 0x25, 0x26, 0x7B,
        0xCE, 0x9D, 0x13, 0x5E, 0x3F, 0x5B, 0x5C, 0xC8,
        0xC4, 0x39, 0x56, 0x40, 0x7E, 0x84, 0xB6, 0x66,
        0x31, 0x03, 0xE2, 0x9C, 0x24, 0x20, 0x35, 0x55,
        0x1A, 0xE7, 0x97, 0xF5, 0x6C, 0x63, 0x74, 0xBE,
        0x0C, 0x79, 0x8C, 0x0C, 0xF3, 0x98, 0xF1, 0xED
#else
        0x30, 0x82, 0x0a, 0x32, 0x30, 0x0d, 0x06, 0x09,
        0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03,
        0x13, 0x03, 0x82, 0x0a, 0x21, 0x00,
        0x69, 0x24, 0xBB, 0x42, 0x57, 0xA7, 0xB9, 0xAF,
        0xF0, 0x95, 0xC3, 0x0B, 0xB3, 0x5C, 0x6A, 0xE4,
        0x19, 0x82, 0x63, 0x12, 0x0F, 0x80, 0x39, 0xAA,
        0x4E, 0x78, 0xE1, 0x74, 0xA7, 0x86, 0xCE, 0x00,
        0x83, 0x01, 0xE6, 0x66, 0xF5, 0x9D, 0x3E, 0xC5,
        0x04, 0x4D, 0xE4, 0x56, 0x78, 0x8F, 0xDE, 0x19,
        0xEB, 0x39, 0x67, 0x7B, 0x5F, 0x9F, 0xE1, 0x41,
        0x50, 0xDA, 0x46, 0x3A, 0x70, 0x6F, 0x3B, 0xAF,
        0x71, 0x5B, 0x95, 0x33, 0x6B, 0x2D, 0x68, 0x5A,
        0x7C, 0xD7, 0x88, 0x07, 0x13, 0xE4, 0x58, 0x7B,
        0xF7, 0xD8, 0x57, 0xBF, 0x7E, 0x31, 0x56, 0x96,
        0xB8, 0xD0, 0xD9, 0xD4, 0x9E, 0x14, 0x29, 0x18,
        0xBF, 0x09, 0x74, 0xE7, 0xF4, 0x32, 0x37, 0xD4,
        0xBE, 0x3A, 0xD3, 0x94, 0x59, 0x9E, 0x3D, 0x39,
        0xBB, 0x76, 0x49, 0x93, 0x25, 0x53, 0x44, 0x7E,
        0x5D, 0x5A, 0xCC, 0x34, 0x99, 0x93, 0x01, 0x76,
        0xEC, 0xD3, 0xA8, 0x44, 0xA4, 0x25, 0xF5, 0x0D,
        0x05, 0x11, 0xC9, 0x22, 0x6C, 0x4B, 0x9A, 0x24,
        0xF2, 0xA0, 0x11, 0xCD, 0x88, 0xD3, 0x23, 0x08,
        0xE0, 0x31, 0x2A, 0x0C, 0x87, 0xCC, 0x34, 0xA9,
        0x95, 0x82, 0x3C, 0x65, 0xF4, 0xF0, 0xF9, 0x8E,
        0x50, 0xC3, 0x77, 0x88, 0xCE, 0x38, 0xDC, 0x28,
        0xFB, 0x8B, 0x9B, 0xFA, 0xAF, 0xA9, 0x04, 0xB5,
        0x41, 0xEE, 0x71, 0x2F, 0x6A, 0x04, 0x1E, 0x06,
        0x11, 0x37, 0x4F, 0x6B, 0xF1, 0x7E, 0xAC, 0x0B,
        0xD5, 0x6F, 0x3B, 0x6B, 0xF3, 0x36, 0xDA, 0x92,
        0x42, 0x07, 0x0C, 0x24, 0x69, 0xA2, 0x0C, 0x4D,
        0x16, 0x16, 0x14, 0x9A, 0x61, 0x59, 0x25, 0x20,
        0x11, 0xD2, 0x99, 0xF9, 0x3F, 0x98, 0x6D, 0x87,
        0x5D, 0xD3, 0x0B, 0x38, 0xA2, 0x25, 0x49, 0x17,
        0x45, 0x70, 0x13, 0x8C, 0x2B, 0xB3, 0xAA, 0x9C,
        0xBE, 0xA9, 0x19, 0x74, 0xF3, 0xD8, 0x9B, 0xF5,
        0xAE, 0x32, 0xBE, 0x9E, 0x58, 0xB8, 0x54, 0xA2,
        0xF8, 0xE8, 0x6F, 0xF7, 0x67, 0x80, 0xC0, 0x34,
        0x90, 0xF4, 0x67, 0xDB, 0x06, 0x51, 0xC2, 0x0B,
        0x1D, 0xF6, 0x0E, 0xB9, 0x7A, 0x3C, 0x99, 0xD9,
        0xBD, 0x66, 0x4B, 0xE6, 0xA5, 0xE4, 0xC8, 0xA8,
        0xAD, 0x4C, 0xC3, 0x63, 0x90, 0xD7, 0x00, 0x4E,
        0x4B, 0xB4, 0x21, 0xDA, 0xED, 0x65, 0x4C, 0x35,
        0x7D, 0xA4, 0xD6, 0x84, 0x98, 0x93, 0x3E, 0xC7,
        0x17, 0x77, 0xAD, 0x64, 0xC2, 0xAE, 0x01, 0x3C,
        0x73, 0xEB, 0x45, 0x7C, 0x68, 0xEF, 0x9A, 0x74,
        0x5A, 0xDE, 0xEB, 0x4F, 0xDF, 0xC8, 0x79, 0xE7,
        0x74, 0xD0, 0x3F, 0xAF, 0x6B, 0x14, 0xAA, 0xB1,
        0x07, 0x52, 0xE2, 0x4B, 0x52, 0xD0, 0xF2, 0xD9,
        0x4D, 0x54, 0x0A, 0x1E, 0xBE, 0x10, 0xF5, 0x97,
        0xE5, 0x14, 0x44, 0x2D, 0x6C, 0x13, 0xC2, 0xE2,
        0x49, 0x8E, 0x8A, 0xF3, 0x01, 0x7C, 0x52, 0xDB,
        0x23, 0x3A, 0x90, 0x71, 0x7D, 0xF2, 0x5B, 0x4D,
        0x07, 0x2B, 0x7D, 0x88, 0xEE, 0x87, 0x31, 0xD1,
        0x68, 0x24, 0xC9, 0x5D, 0x1F, 0xB9, 0x83, 0xC4,
        0x49, 0xDE, 0xB4, 0x66, 0x27, 0x60, 0x60, 0xFE,
        0xE4, 0xC7, 0xEE, 0x38, 0x14, 0x51, 0xF2, 0x32,
        0xC2, 0x9C, 0x7C, 0x32, 0x20, 0x85, 0x0C, 0x61,
        0xD1, 0xC3, 0xC0, 0x0D, 0xB1, 0xCD, 0x97, 0x26,
        0xA0, 0x2A, 0x56, 0x60, 0x9F, 0x3A, 0x65, 0xD3,
        0xD1, 0x64, 0x60, 0x45, 0x88, 0xCD, 0x9B, 0x43,
        0x14, 0x12, 0xF1, 0xAD, 0xD9, 0x14, 0xC5, 0xC2,
        0xDA, 0xBB, 0xC9, 0x04, 0x67, 0xC0, 0xC4, 0xEA,
        0x5F, 0x76, 0xE2, 0x4A, 0xA6, 0x18, 0x76, 0x5F,
        0x8B, 0x06, 0x36, 0xD7, 0xB0, 0x65, 0xE1, 0xF4,
        0xE6, 0xF6, 0x22, 0xEA, 0xE1, 0x71, 0x52, 0x45,
        0x8C, 0x76, 0x65, 0x86, 0x77, 0x2D, 0x36, 0x3F,
        0xA9, 0x92, 0x14, 0xF4, 0x72, 0xB0, 0xDB, 0x8A,
        0x1E, 0x49, 0xD8, 0x2D, 0x02, 0x78, 0xF2, 0x95,
        0x8B, 0x0A, 0xAA, 0x15, 0x86, 0xDB, 0x13, 0x4B,
        0xDF, 0xD2, 0x43, 0x87, 0x42, 0x49, 0x50, 0x07,
        0xE2, 0xFE, 0x5B, 0x60, 0xE2, 0x46, 0x39, 0x92,
        0x26, 0x94, 0x7A, 0x12, 0xEA, 0x17, 0x63, 0x1C,
        0xAA, 0x53, 0x46, 0x87, 0xCB, 0x75, 0xC0, 0x60,
        0xB4, 0x79, 0x7E, 0xAB, 0x82, 0x77, 0xCC, 0x4F,
        0x8A, 0x7A, 0x20, 0x38, 0x76, 0x06, 0xEF, 0xE2,
        0xDB, 0xD3, 0xE7, 0x36, 0x24, 0x92, 0x77, 0xD9,
        0x0F, 0xCA, 0xB9, 0x92, 0xA8, 0xC9, 0x9E, 0x85,
        0xAB, 0x03, 0xEB, 0x4C, 0xAC, 0x5D, 0x88, 0x55,
        0x39, 0x58, 0x52, 0x8A, 0xF9, 0x29, 0x74, 0x71,
        0x81, 0x35, 0xF1, 0xD0, 0xC7, 0x93, 0xEB, 0x00,
        0x0E, 0xA0, 0xAE, 0xC3, 0xEC, 0x18, 0x58, 0xFD,
        0xD1, 0x86, 0x88, 0xD1, 0xDA, 0x27, 0x27, 0x8D,
        0xEB, 0xF2, 0xCA, 0x81, 0x10, 0xBA, 0x4A, 0x20,
        0x4F, 0x79, 0x30, 0xE1, 0xC8, 0xCE, 0xEC, 0xAF,
        0xB7, 0x3F, 0x75, 0xDD, 0xB3, 0x4C, 0x5C, 0x55,
        0x96, 0x8A, 0x79, 0x33, 0x05, 0x84, 0x26, 0xB5,
        0x5D, 0x03, 0x9F, 0x72, 0x92, 0xAC, 0x43, 0xF6,
        0x45, 0x84, 0xF6, 0xDF, 0x18, 0x7A, 0x1D, 0x6B,
        0x00, 0x3F, 0x51, 0x4C, 0xC1, 0x3B, 0x26, 0xC2,
        0xF3, 0x48, 0x19, 0x5A, 0xA3, 0x21, 0xDE, 0x6A,
        0x27, 0xEC, 0x11, 0x34, 0x8D, 0xE5, 0x0D, 0x82,
        0x5A, 0x29, 0x64, 0xC6, 0x31, 0x99, 0x2E, 0x4B,
        0x0B, 0x42, 0x5B, 0x1B, 0xEB, 0x4F, 0x96, 0x00,
        0xE3, 0xAD, 0xC4, 0x43, 0x1C, 0xF2, 0xE8, 0x8B,
        0x42, 0x23, 0xD2, 0xDB, 0x66, 0x3C, 0x3C, 0xE7,
        0x0E, 0xF8, 0x5D, 0xDD, 0x56, 0xA9, 0xBA, 0xF1,
        0x38, 0xA9, 0xD7, 0xED, 0xD8, 0x94, 0x13, 0x1C,
        0x3A, 0x8F, 0x41, 0xA0, 0x4E, 0xF9, 0xF8, 0x67,
        0x52, 0xB7, 0x21, 0x81, 0xFA, 0xBB, 0x37, 0xC8,
        0x6B, 0x87, 0x7E, 0x61, 0xD6, 0x0E, 0xED, 0x95,
        0xEE, 0xFF, 0xAB, 0xE6, 0x37, 0x6E, 0x14, 0xAC,
        0xA8, 0x17, 0xC5, 0xF4, 0x19, 0x61, 0xAF, 0x8A,
        0x78, 0x49, 0xBA, 0xC0, 0x94, 0x91, 0x7B, 0x2D,
        0x13, 0x22, 0x76, 0xB6, 0xB3, 0x48, 0x6A, 0xFF,
        0x95, 0x0D, 0x23, 0xD4, 0xAA, 0xDC, 0x24, 0xCE,
        0x98, 0xA5, 0x26, 0x9E, 0x1C, 0x69, 0x91, 0x79,
        0x60, 0xA3, 0x1E, 0xE0, 0x9A, 0x52, 0x7C, 0x35,
        0x81, 0x75, 0xCA, 0xA0, 0xCB, 0x1B, 0x01, 0x8E,
        0x95, 0x26, 0xD9, 0x35, 0x34, 0xEA, 0xDB, 0xAC,
        0xB5, 0x2B, 0x27, 0x3D, 0x73, 0x5E, 0x22, 0xDD,
        0x0D, 0x5C, 0x28, 0xFA, 0x3E, 0x47, 0xCF, 0xE9,
        0x0B, 0x52, 0x15, 0xAE, 0x24, 0xF1, 0x46, 0xC3,
        0x46, 0x4B, 0xFE, 0xAF, 0x01, 0xD2, 0x8D, 0xAA,
        0x55, 0x3C, 0x1E, 0x94, 0x42, 0x8A, 0x10, 0x4A,
        0x9D, 0x78, 0xAE, 0xC7, 0x62, 0x59, 0x1E, 0x88,
        0x79, 0xF7, 0x68, 0x51, 0xCF, 0xB4, 0x64, 0x85,
        0x66, 0x72, 0x1B, 0x0C, 0xAC, 0x1F, 0x14, 0xFE,
        0x16, 0x14, 0x9A, 0x9D, 0x82, 0x10, 0xCC, 0x8F,
        0x2F, 0x50, 0xDE, 0xF7, 0xB4, 0x6C, 0x84, 0x3B,
        0xE9, 0x3B, 0xD8, 0xD5, 0x56, 0x02, 0x49, 0x33,
        0x50, 0xAB, 0x56, 0x0E, 0xA5, 0xBA, 0x17, 0x71,
        0x64, 0x23, 0xBE, 0x0E, 0xB8, 0x36, 0x0A, 0xB1,
        0x09, 0xD8, 0xFB, 0x18, 0xBF, 0xEA, 0x04, 0x08,
        0x47, 0xB7, 0x33, 0x51, 0x45, 0xD4, 0xF2, 0x00,
        0xD1, 0x9C, 0xF6, 0xFE, 0x7B, 0xAC, 0x91, 0x7F,
        0x42, 0x6C, 0x9B, 0x3D, 0x39, 0xA9, 0xCA, 0x43,
        0x29, 0x81, 0x8F, 0x24, 0x0E, 0x7D, 0xA3, 0x82,
        0x76, 0x10, 0x72, 0xF4, 0xA6, 0x50, 0x5E, 0xA8,
        0xE7, 0x6C, 0x1E, 0x44, 0x6F, 0xEB, 0x66, 0x25,
        0xE3, 0x8D, 0xDB, 0xCD, 0x3C, 0xDA, 0x81, 0xE8,
        0x3B, 0xF7, 0x68, 0xF3, 0xE0, 0x1D, 0x9D, 0x26,
        0x3B, 0x36, 0x73, 0x03, 0xAE, 0x15, 0x6C, 0x0B,
        0x71, 0x83, 0x36, 0x4A, 0x1E, 0x79, 0x41, 0xA0,
        0x92, 0x98, 0xA3, 0xAD, 0xF7, 0xBD, 0x23, 0x1E,
        0x61, 0x14, 0xB9, 0xDC, 0xE7, 0x95, 0x2B, 0x11,
        0x3F, 0x78, 0x16, 0x31, 0x38, 0xB9, 0x26, 0x6F,
        0x84, 0x3F, 0x1E, 0xD9, 0x7D, 0x9C, 0x2B, 0x16,
        0x3A, 0x6E, 0x8B, 0xD4, 0xC1, 0xAB, 0x4E, 0x17,
        0x93, 0x67, 0xC5, 0xAC, 0x96, 0xCE, 0xCF, 0x50,
        0x50, 0xFE, 0x82, 0x1F, 0xDF, 0xA4, 0x4E, 0x9E,
        0x68, 0x0B, 0x61, 0xC6, 0x01, 0x89, 0x32, 0xDF,
        0x71, 0x78, 0x11, 0x45, 0x9A, 0xF2, 0x54, 0x2E,
        0x2C, 0xDE, 0x77, 0x17, 0x8C, 0x2E, 0x98, 0x80,
        0xF0, 0x11, 0xE4, 0x05, 0xEA, 0xFA, 0x59, 0xC8,
        0xCB, 0xBE, 0xD7, 0x6E, 0x5A, 0x19, 0x41, 0x10,
        0x4B, 0x1B, 0x9D, 0x3A, 0x60, 0x49, 0x1C, 0x95,
        0x47, 0x55, 0xE0, 0x2E, 0x89, 0x41, 0x03, 0xF1,
        0xF4, 0x97, 0x74, 0x75, 0xE9, 0xEA, 0x36, 0x60,
        0x9F, 0xD6, 0x7C, 0x9D, 0xE3, 0x18, 0xED, 0xA2,
        0x37, 0x0D, 0xCC, 0xDB, 0xB9, 0xCE, 0xF7, 0xAE,
        0x63, 0x60, 0x90, 0x5E, 0xC2, 0x20, 0x83, 0x8C,
        0x97, 0x69, 0x82, 0x34, 0x41, 0xCD, 0xD0, 0xDA,
        0x8E, 0xF0, 0xAB, 0xE5, 0xF2, 0xD1, 0xD7, 0x6E,
        0x2F, 0xE0, 0x8F, 0xEF, 0x53, 0xDE, 0x1D, 0x61,
        0x66, 0xAB, 0x1A, 0x92, 0xB1, 0xAC, 0x09, 0x3E,
        0x5A, 0xBF, 0x76, 0x58, 0xC4, 0xB5, 0x72, 0x87,
        0xF2, 0xD1, 0xFD, 0x7B, 0x82, 0xDE, 0xDA, 0xF8,
        0xD5, 0xA4, 0xFB, 0xAC, 0x4B, 0x35, 0xD5, 0x82,
        0x31, 0x69, 0x4E, 0x16, 0x24, 0x97, 0x57, 0x8A,
        0xBD, 0x7A, 0xA7, 0xC8, 0xFE, 0x7B, 0x35, 0x41,
        0xA7, 0xF1, 0x8E, 0x54, 0xE8, 0xB7, 0xF0, 0x87,
        0x64, 0xC5, 0xE6, 0x84, 0x49, 0xDF, 0x65, 0x59,
        0x01, 0x54, 0x98, 0x32, 0xD6, 0x28, 0xFA, 0x63,
        0xD2, 0xB2, 0xC5, 0xA1, 0x50, 0x93, 0x39, 0x94,
        0xA9, 0x86, 0x33, 0x17, 0xAD, 0x40, 0xD7, 0x78,
        0xD9, 0xD2, 0xC0, 0x5C, 0x78, 0x98, 0x85, 0x0B,
        0x90, 0x17, 0x32, 0x23, 0xC7, 0xA0, 0xAF, 0x89,
        0x0F, 0xD7, 0xE6, 0x62, 0x21, 0xB6, 0xF0, 0x63,
        0x18, 0xB2, 0xED, 0x5E, 0x19, 0x9C, 0xB4, 0x24,
        0x88, 0x5A, 0xB8, 0x41, 0xE7, 0xA4, 0x72, 0x6F,
        0xAB, 0xA2, 0xF9, 0xBB, 0x53, 0xBC, 0x32, 0x36,
        0x43, 0x4C, 0x35, 0xFB, 0xBE, 0x4B, 0x1A, 0x0F,
        0x93, 0xF5, 0x0C, 0x37, 0x89, 0x6C, 0x29, 0xF8,
        0xE3, 0x02, 0xAD, 0x31, 0xED, 0x33, 0x31, 0xD6,
        0x20, 0xE3, 0xB6, 0x29, 0x45, 0x51, 0x01, 0xA1,
        0xF1, 0xCC, 0x7B, 0xA5, 0xE4, 0x6E, 0x68, 0xED,
        0x4A, 0x8C, 0xCC, 0x87, 0xB4, 0xDC, 0x75, 0xBC,
        0x01, 0x62, 0xB6, 0x33, 0x0F, 0x83, 0x3F, 0xBA,
        0x25, 0x75, 0xDF, 0xAF, 0x5B, 0x5F, 0x28, 0xBC,
        0x54, 0xFF, 0x2B, 0xA8, 0x1E, 0x7A, 0x47, 0x31,
        0x3C, 0x15, 0x48, 0x2B, 0x60, 0x5E, 0x66, 0xBB,
        0x38, 0xC6, 0x19, 0x8F, 0x13, 0x92, 0x10, 0x40,
        0x80, 0xFB, 0xE7, 0x8B, 0x86, 0xB1, 0xBC, 0x9A,
        0x6F, 0xB8, 0x81, 0xF5, 0xC7, 0x82, 0x01, 0x47,
        0xE6, 0xBA, 0x14, 0xB8, 0x1A, 0xCC, 0xF2, 0x0C,
        0xAE, 0x96, 0x64, 0x10, 0x94, 0xC2, 0x16, 0x90,
        0x2E, 0xA5, 0xC1, 0x25, 0xF6, 0xC9, 0x35, 0xA1,
        0x50, 0xD7, 0xC9, 0xAC, 0xC5, 0xD9, 0xE2, 0xE5,
        0xD9, 0x0E, 0x38, 0xC0, 0x50, 0x3A, 0xA9, 0x42,
        0x60, 0x17, 0xC7, 0x6A, 0xAF, 0xCD, 0x52, 0x61,
        0xB5, 0x06, 0x27, 0x4E, 0xC1, 0x3A, 0x96, 0x79,
        0xFB, 0x09, 0x79, 0x60, 0x27, 0xA4, 0xBB, 0x75,
        0x9D, 0x92, 0x82, 0x79, 0xB9, 0x4D, 0x84, 0x1A,
        0x09, 0x73, 0x93, 0xBF, 0x7E, 0x5B, 0xD6, 0x9A,
        0x49, 0x6C, 0xC3, 0xDE, 0xCD, 0x2B, 0x0F, 0x07,
        0xF8, 0x33, 0x92, 0xAA, 0xDE, 0x33, 0xDC, 0x51,
        0xB2, 0xA8, 0x4F, 0x6A, 0x07, 0x63, 0x5D, 0xC0,
        0xEF, 0x57, 0xA9, 0xAD, 0x59, 0x59, 0xB6, 0xA5,
        0x0B, 0x7B, 0xA5, 0x09, 0xAD, 0x5B, 0x11, 0xFA,
        0xD2, 0x6B, 0x41, 0x9F, 0x9F, 0x1E, 0x3F, 0x9C,
        0x73, 0x29, 0xB5, 0xA9, 0x53, 0xD7, 0xCC, 0x87,
        0xB2, 0xDE, 0x21, 0x06, 0x11, 0xCF, 0x52, 0xA6,
        0x39, 0xEF, 0x2B, 0x39, 0x08, 0x01, 0x2C, 0xB8,
        0x8E, 0x1D, 0x6F, 0x57, 0x62, 0x50, 0x79, 0xCB,
        0x10, 0x3D, 0x6C, 0x98, 0x10, 0x1A, 0x11, 0xBD,
        0x22, 0x33, 0xB6, 0x56, 0x02, 0xCA, 0x30, 0x49,
        0xBD, 0x32, 0x05, 0x20, 0x41, 0x9F, 0x76, 0xB0,
        0x61, 0xE3, 0x59, 0x8D, 0xE3, 0x81, 0x52, 0xC8,
        0x87, 0x67, 0xD1, 0xA2, 0x4F, 0xBD, 0x02, 0xBB,
        0x10, 0xC3, 0x8E, 0xAC, 0xAE, 0x31, 0x7D, 0xE6,
        0xBB, 0x28, 0x7B, 0x4D, 0x2C, 0xAE, 0x5D, 0xA0,
        0x21, 0x49, 0x65, 0xD8, 0x77, 0x37, 0x78, 0x62,
        0x6E, 0x9B, 0x97, 0x28, 0x59, 0xD8, 0x48, 0x2B,
        0x8D, 0x05, 0x47, 0xE4, 0xF5, 0x6D, 0xFF, 0x87,
        0x68, 0x1D, 0x5B, 0xC5, 0x12, 0x0F, 0x61, 0x3F,
        0xBB, 0xD9, 0x1E, 0x1F, 0x14, 0xE6, 0xDE, 0xFE,
        0x67, 0x2E, 0x2A, 0x7E, 0xAB, 0xCB, 0xBB, 0x9B,
        0x11, 0x08, 0x2C, 0x5E, 0x70, 0x0A, 0xA0, 0xB1,
        0xF7, 0xC1, 0x78, 0x5F, 0xCE, 0xD1, 0x9A, 0x93,
        0xAF, 0xE7, 0xC5, 0x9F, 0xA2, 0x51, 0x9B, 0xCD,
        0xEB, 0x49, 0x4C, 0x3D, 0x13, 0xB2, 0x12, 0x5F,
        0x38, 0x53, 0x23, 0xB8, 0x16, 0xC6, 0x8F, 0x8F,
        0x56, 0x28, 0xC7, 0xC2, 0xAB, 0xFD, 0x02, 0x78,
        0xA3, 0x37, 0x07, 0x3D, 0xA7, 0x4D, 0x16, 0x09,
        0x96, 0x98, 0xC4, 0xB1, 0x14, 0xE8, 0xA8, 0xCE,
        0x34, 0x4E, 0x0A, 0x15, 0xD0, 0xFC, 0x7E, 0xD4,
        0x97, 0xB0, 0x01, 0xD5, 0x3D, 0x4C, 0x96, 0xDC,
        0x39, 0x54, 0xD3, 0xB4, 0xB9, 0x56, 0xCB, 0x9D,
        0x2A, 0x27, 0x2C, 0x51, 0xF1, 0x55, 0x9B, 0x22,
        0x90, 0x4B, 0x40, 0xCC, 0x85, 0x31, 0xE4, 0x0C,
        0xC4, 0x12, 0xC6, 0x8C, 0xB6, 0xEE, 0xA4, 0xA4,
        0x09, 0x0B, 0x38, 0xE2, 0x79, 0x73, 0x29, 0x98,
        0x54, 0x67, 0xE8, 0x18, 0xA5, 0x24, 0xD3, 0x22,
        0x8E, 0xAC, 0xAE, 0x78, 0x25, 0xD3, 0xDA, 0xD2,
        0xEA, 0xA4, 0x22, 0xFD, 0xC7, 0x7A, 0xED, 0x71,
        0xA2, 0x05, 0xDA, 0x78, 0x38, 0xD9, 0x45, 0xE7,
        0xFE, 0xC3, 0x7E, 0x4D, 0xCA, 0x67, 0xE5, 0x04,
        0xCE, 0x35, 0xE5, 0xB0, 0x45, 0xF5, 0x6F, 0x1E,
        0x8D, 0x75, 0x29, 0xEB, 0xD6, 0xF1, 0xAF, 0x7B,
        0x6E, 0x93, 0x9E, 0x2B, 0x7A, 0xB4, 0x02, 0x7D,
        0x37, 0xA5, 0x13, 0x5D, 0x17, 0x2D, 0xA1, 0xAF,
        0x9C, 0xA2, 0xF7, 0x28, 0xA6, 0xF3, 0x7D, 0xE6,
        0x0D, 0xD2, 0x3D, 0x97, 0xD1, 0x1E, 0x75, 0xAB,
        0x1F, 0xD5, 0x1F, 0x8E, 0x9A, 0x13, 0x97, 0xE5,
        0x82, 0x21, 0x59, 0xDB, 0x58, 0x38, 0x02, 0xB3,
        0x2E, 0xEB, 0xB4, 0x56, 0x7E, 0xCE, 0x37, 0x46,
        0xD1, 0xAE, 0x33, 0x31, 0x47, 0x85, 0x64, 0x3D,
        0xD2, 0xA0, 0x74, 0x1E, 0x7F, 0x1B, 0xF2, 0xD2,
        0x61, 0xF2, 0x21, 0x24, 0xE8, 0xDD, 0xD0, 0x8C,
        0x64, 0x0A, 0x48, 0xB5, 0x47, 0x17, 0x51, 0x7C,
        0x21, 0xCD, 0x32, 0x53, 0x28, 0xBC, 0x23, 0x9C,
        0xA0, 0x28, 0xB2, 0x63, 0x0D, 0x06, 0x3C, 0x8C,
        0xC2, 0x0B, 0xE9, 0xBD, 0xB4, 0x85, 0x02, 0xDA,
        0xDD, 0xE7, 0x3F, 0xFE, 0xD5, 0x96, 0x38, 0x16,
        0x53, 0x3E, 0x02, 0x0A, 0xED, 0x12, 0x08, 0x53,
        0x62, 0x55, 0xB1, 0xCC, 0xE9, 0x85, 0x43, 0x31,
        0x27, 0xFF, 0x4F, 0x04, 0xD5, 0xB1, 0xE2, 0xF2,
        0x10, 0x87, 0x04, 0xB8, 0xB9, 0x66, 0x58, 0x8C,
        0x01, 0x56, 0xAF, 0xC2, 0xAE, 0x19, 0x29, 0x86,
        0xFB, 0xEC, 0x44, 0x3B, 0xAE, 0xF6, 0xCB, 0x85,
        0xA6, 0xF2, 0x9C, 0x77, 0x92, 0x40, 0x5A, 0x24,
        0x11, 0x47, 0x10, 0xAE, 0x1C, 0x74, 0x64, 0x44,
        0xFD, 0xF5, 0xFB, 0x65, 0x9E, 0x5E, 0x34, 0x68,
        0x26, 0x20, 0x7B, 0x8C, 0x54, 0x46, 0x3A, 0x06,
        0x17, 0xCE, 0x17, 0xFF, 0x33, 0xE4, 0x0F, 0x93,
        0x1F, 0xE5, 0x76, 0x71, 0x5C, 0x93, 0x2E, 0xF2,
        0x9F, 0xD7, 0x6B, 0x04, 0xA6, 0x9B, 0x58, 0xE0,
        0x30, 0x3D, 0x8E, 0xF2, 0x56, 0x78, 0xC8, 0xB7,
        0x0A, 0xF1, 0x2E, 0x90, 0x45, 0x59, 0x1C, 0x04,
        0xE8, 0xB7, 0x71, 0x06, 0x94, 0x04, 0x15, 0x17,
        0x7E, 0x86, 0x85, 0x93, 0xA0, 0x9C, 0x7E, 0x14,
        0x61, 0x9A, 0x4B, 0x33, 0x2F, 0x9A, 0xDC, 0x3A,
        0x65, 0x8B, 0x86, 0x01, 0x7F, 0x32, 0x65, 0x6C,
        0x54, 0x29, 0xC1, 0x15, 0xE1, 0x10, 0x03, 0x7A,
        0x8C, 0xC7, 0xE5, 0x44, 0x67, 0x7D, 0x2D, 0xD2,
        0x39, 0xA5, 0x9D, 0x54, 0xD0, 0xF3, 0xC7, 0x46,
        0x0E, 0xC1, 0x52, 0x08, 0x34, 0x6B, 0xA5, 0x6D,
        0xF5, 0x08, 0x6C, 0x5D, 0xBC, 0xC4, 0x1E, 0x0C,
        0x95, 0xFC, 0xB6, 0x86, 0x1C, 0x2C, 0x0C, 0x32,
        0xAA, 0xF3, 0x45, 0x4E, 0xFE, 0xE2, 0xFF, 0xBA,
        0x21, 0x4B, 0x43, 0x0E, 0xF2, 0x48, 0xA5, 0x9B,
        0x32, 0x44, 0x4D, 0x8D, 0x0D, 0x3D, 0xB8, 0x7C,
        0x9D, 0x4B, 0x15, 0x36, 0xD1, 0x57, 0x72, 0x8E,
        0xE7, 0x58, 0x5E, 0xF5, 0x32, 0x77, 0x6A, 0x00,
        0x3A, 0x02, 0x3C, 0x0A, 0xB0, 0xE9, 0xFF, 0x55,
        0x71, 0x08, 0xC3, 0x90, 0x68, 0x4D, 0x56, 0x5A,
        0x66, 0x50, 0x63, 0x26, 0x6A, 0xE6, 0x67, 0x0E,
        0xD5, 0x3B, 0x0F, 0xAF, 0x8F, 0xF6, 0x78, 0x29,
        0xBB, 0x73, 0x78, 0x25, 0xB1, 0x53, 0xA9, 0x33,
        0x8C, 0xBE, 0x3D, 0xF1, 0xA4, 0x62, 0x84, 0x9B,
        0x93, 0xA8, 0x1F, 0x84, 0xED, 0x07, 0xBE, 0x6D,
        0x62, 0x40, 0x00, 0x32, 0x74, 0x73, 0x7F, 0x61,
        0x8D, 0xCB, 0x26, 0xE4, 0x82, 0x52, 0xCE, 0x42,
        0x04, 0xDD, 0x31, 0x39, 0xFF, 0x68, 0x76, 0xF4,
        0x3B, 0x30, 0x5D, 0x83, 0x56, 0x20, 0xFE, 0xDF,
        0x79, 0xAA, 0x67, 0x43, 0x3D, 0xC2, 0x52, 0x87,
        0x32, 0x0E, 0x99, 0x17, 0x96, 0x7B, 0x70, 0xB2,
        0xD8, 0x66, 0xD1, 0x7B, 0x69, 0x8B, 0xFF, 0xF2,
        0xB3, 0xAB, 0x95, 0x14, 0x94, 0x9E, 0x58, 0xB5,
        0x7C, 0x68, 0xA4, 0x54, 0x12, 0xC1, 0xFC, 0x42,
        0x1C, 0x76, 0x8B, 0xF5, 0xEE, 0x8A, 0x10, 0xC8,
        0xAE, 0xF5, 0x69, 0x26, 0xF5, 0x1E, 0xC6, 0x2C,
        0x11, 0x56, 0x9F, 0x31, 0xAA, 0x51, 0x78, 0x68,
        0xE5, 0xCA, 0xD8, 0x9E, 0x95, 0x80, 0x66, 0xEB,
        0x9E, 0xDD, 0x72, 0x71, 0xB3, 0x1C, 0xB4, 0xB1,
        0xD6, 0xCE, 0x21, 0x12, 0x25, 0xAE, 0xB5, 0xB5,
        0x7F, 0x74, 0x97, 0x19, 0xDA, 0x07, 0xEC, 0xBE,
        0xFE, 0x03, 0x88, 0x1D, 0xDE, 0x3D, 0x81, 0xE4,
        0x13, 0x5F, 0x2D, 0xC8, 0x1A, 0xF7, 0x79, 0x77,
        0x6C, 0x1B, 0x80, 0x57, 0x16, 0x2A, 0x6C, 0x98,
        0x2F, 0xBB, 0x4D, 0xA6, 0xA9, 0xAD, 0x28, 0x4A,
        0xB1, 0x0C, 0x70, 0x02, 0x20, 0x44, 0xF4, 0x6D,
        0x40, 0x0B, 0xF6, 0xAD, 0x71, 0x82, 0xD1, 0x97,
        0x78, 0x99, 0x83, 0xBE, 0x99, 0x22, 0x79, 0x79,
        0xA1, 0x33, 0x4B, 0xA1, 0x49, 0xD8, 0x69, 0xBA,
        0x1C, 0x40, 0x88, 0x12, 0x34, 0x35, 0xBF, 0x97,
        0x85, 0x41, 0x35, 0x6D, 0xAF, 0x17, 0x1F, 0x33,
        0xAD, 0xB1, 0xC9, 0x79, 0x07, 0xA0, 0xFB, 0x58,
        0x45, 0x07, 0x4A, 0x85, 0xD2, 0x6F, 0x54, 0x61,
        0x35, 0xAE, 0xD0, 0xF9, 0x1B, 0xE4, 0x53, 0x9C,
        0x12, 0xBF, 0x94, 0x11, 0xE4, 0xB5, 0x56, 0xF6,
        0x87, 0xD0, 0x69, 0xDB, 0x6B, 0x21, 0xFE, 0x2B,
        0x7F, 0x32, 0x18, 0x87, 0x44, 0x8C, 0xEA, 0x55,
        0xDB, 0x19, 0xFB, 0xB8, 0xB0, 0x48, 0x2A, 0x55,
        0xAE, 0xC1, 0x67, 0x38, 0xD7, 0x4C, 0xD2, 0x65,
        0x09, 0x38, 0x36, 0xBE, 0x99, 0xD4, 0xFB, 0x53,
        0xE9, 0xB0, 0x14, 0xB0, 0x37, 0xCD, 0xBF, 0xE9
#endif
    };
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
static const unsigned char dilithium_public_der[] = {
#ifndef WOLFSSL_NO_ML_DSA_44
    0x30, 0x82, 0x05, 0x34, 0x30, 0x0d, 0x06, 0x0b,
    0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x82, 0x0b,
    0x0c, 0x04, 0x04, 0x03, 0x82, 0x05, 0x21, 0x00,
    0x0a, 0xf7, 0xc8, 0xa4, 0x96, 0x01, 0xa7, 0xb2,
    0x2e, 0x4d, 0xc9, 0xd9, 0x1c, 0xa1, 0x86, 0x09,
    0xce, 0x14, 0x6f, 0xe8, 0x33, 0x3c, 0x7b, 0xdb,
    0x19, 0x9c, 0x56, 0x39, 0x6a, 0x6c, 0x5d, 0x1f,
    0xe4, 0x26, 0xcb, 0x16, 0x91, 0x4d, 0xeb, 0x5a,
    0x36, 0x22, 0xee, 0xda, 0xdf, 0x46, 0x3e, 0xa1,
    0x4f, 0x9a, 0x30, 0xb5, 0x3f, 0x60, 0xf7, 0x75,
    0x47, 0xdc, 0x55, 0xf1, 0xbe, 0xbc, 0x87, 0x6c,
    0x50, 0x7c, 0x21, 0x55, 0x35, 0xad, 0xa7, 0xf9,
    0x1c, 0xf8, 0xa1, 0x92, 0x79, 0x10, 0x52, 0x7a,
    0xc3, 0xba, 0xd3, 0x9d, 0xc6, 0x9b, 0xf4, 0xcb,
    0x1b, 0xa2, 0xde, 0x83, 0x86, 0xa6, 0x35, 0xea,
    0xf2, 0x8c, 0xdc, 0xba, 0x3e, 0xef, 0x9c, 0xf5,
    0x8e, 0xc3, 0xb0, 0xc0, 0x5b, 0xcc, 0x35, 0x6a,
    0x81, 0xe5, 0x17, 0xb3, 0x9a, 0x57, 0xa6, 0x4a,
    0x87, 0xb1, 0xa7, 0xf5, 0xa2, 0x96, 0x40, 0x8b,
    0xc1, 0x62, 0xb2, 0xd9, 0x76, 0xe8, 0x51, 0x33,
    0x44, 0x3d, 0xeb, 0x14, 0x86, 0x88, 0x2c, 0xc1,
    0x47, 0xba, 0x2b, 0x85, 0x3b, 0x72, 0xcb, 0x9f,
    0x40, 0xba, 0x19, 0x58, 0xa4, 0x34, 0x0a, 0xd2,
    0x8c, 0x97, 0xbd, 0x3d, 0x09, 0xb0, 0x4a, 0xeb,
    0xaa, 0xee, 0x58, 0x1e, 0xc1, 0x19, 0x26, 0x70,
    0x15, 0xa5, 0x17, 0x7e, 0xd0, 0xa1, 0x08, 0xf9,
    0x6d, 0xcf, 0x20, 0x62, 0x95, 0x8e, 0x61, 0xf4,
    0x29, 0x96, 0x6f, 0x38, 0x1c, 0x67, 0xd5, 0xa6,
    0x4c, 0xf5, 0x1f, 0xda, 0x12, 0x22, 0x24, 0x6b,
    0x0d, 0xb7, 0x6a, 0xe5, 0xaf, 0x6c, 0x89, 0x52,
    0xc2, 0x85, 0x85, 0x5f, 0x16, 0x33, 0x0c, 0xc6,
    0x7a, 0xe0, 0xa8, 0xed, 0x13, 0x58, 0xf3, 0xa0,
    0x80, 0x42, 0x3c, 0xe3, 0x57, 0xd1, 0xe2, 0x66,
    0xc4, 0xe0, 0x3d, 0x49, 0x32, 0x21, 0xd9, 0xa1,
    0x3c, 0x93, 0x0a, 0xf7, 0x5f, 0x34, 0x65, 0xa4,
    0x30, 0xf9, 0xe7, 0x8a, 0x96, 0x04, 0xdb, 0xc5,
    0x16, 0x15, 0x10, 0x74, 0x4f, 0xc9, 0x6b, 0x4b,
    0x66, 0x29, 0xb0, 0xd1, 0x3b, 0xdd, 0x41, 0x0a,
    0xfe, 0xdf, 0x5f, 0x72, 0x91, 0xbc, 0x99, 0x2f,
    0x8d, 0x72, 0x3a, 0x4a, 0xde, 0x11, 0x3a, 0x20,
    0xb2, 0x56, 0xb5, 0x73, 0x89, 0xb4, 0x63, 0x37,
    0x86, 0xbd, 0x99, 0x8b, 0x03, 0x56, 0x50, 0x21,
    0x11, 0x78, 0x8c, 0xd5, 0xc1, 0x92, 0x33, 0x72,
    0x6e, 0x8d, 0x88, 0x2d, 0x10, 0x8f, 0x31, 0xd3,
    0x23, 0xe5, 0xaa, 0x1f, 0xe1, 0x37, 0xec, 0x34,
    0x42, 0x30, 0x75, 0xff, 0xb2, 0x1a, 0x8e, 0x29,
    0x03, 0x4c, 0xfd, 0xdf, 0x53, 0xf2, 0x0b, 0x2d,
    0xf9, 0x1c, 0x9e, 0xb6, 0x5a, 0x6c, 0x5e, 0x88,
    0x48, 0x29, 0x89, 0x42, 0xfc, 0x97, 0xfb, 0x27,
    0x1c, 0x99, 0x2a, 0xbf, 0x7f, 0x04, 0xb2, 0xcd,
    0xc9, 0x3a, 0x39, 0xfe, 0x4f, 0x47, 0x92, 0x0b,
    0x85, 0xfc, 0x92, 0x57, 0xc5, 0x0b, 0x23, 0x1f,
    0x0b, 0x72, 0xb4, 0xde, 0xfe, 0xbe, 0xb7, 0x39,
    0xb3, 0xd7, 0x48, 0x03, 0xed, 0x76, 0xac, 0x63,
    0xf7, 0x2a, 0x58, 0xef, 0xdb, 0x63, 0x5a, 0x56,
    0x68, 0xcc, 0xb2, 0x8b, 0x22, 0xac, 0xdf, 0xc4,
    0xad, 0x6f, 0xad, 0x24, 0xfd, 0x30, 0xfb, 0xed,
    0x6e, 0xde, 0x65, 0x2b, 0xb4, 0x57, 0x35, 0x49,
    0xc1, 0xc9, 0x82, 0xf4, 0x72, 0x69, 0xef, 0x34,
    0xc0, 0x37, 0x8b, 0x8b, 0xd3, 0xd3, 0x25, 0xcc,
    0xe5, 0xf5, 0xf6, 0x9c, 0xa3, 0xe7, 0x88, 0xd7,
    0x55, 0x73, 0x31, 0x4c, 0xb1, 0x7b, 0x64, 0xb3,
    0x38, 0xde, 0x47, 0x9a, 0xfc, 0xf1, 0xfa, 0xf8,
    0x6e, 0xc5, 0x95, 0xb9, 0xaf, 0x6a, 0x7a, 0x94,
    0x80, 0x0d, 0x29, 0x62, 0x99, 0x0a, 0x34, 0xa2,
    0x8f, 0xa1, 0x5e, 0x98, 0x7c, 0x4e, 0x18, 0xcd,
    0x63, 0x68, 0x0e, 0xfa, 0x6f, 0x49, 0x01, 0x02,
    0xcd, 0xf1, 0xc1, 0x09, 0x57, 0xa3, 0x03, 0xec,
    0x94, 0x36, 0xab, 0xc6, 0x1c, 0xc0, 0x98, 0x22,
    0x15, 0x5b, 0x5b, 0x61, 0x3c, 0xc2, 0x5b, 0x6f,
    0x1c, 0x82, 0x41, 0x39, 0x87, 0xde, 0x92, 0xa9,
    0xe4, 0x12, 0x74, 0x3b, 0x31, 0x36, 0xac, 0x92,
    0xb0, 0x23, 0x26, 0xfa, 0xd8, 0xa3, 0xe8, 0x84,
    0xfc, 0x52, 0xc5, 0x7b, 0xd1, 0x4b, 0xe2, 0x1a,
    0x33, 0xdd, 0x3c, 0xdf, 0x27, 0x50, 0x6f, 0x12,
    0xd3, 0x17, 0x66, 0xd7, 0x54, 0x33, 0x30, 0x2b,
    0xe8, 0xd1, 0x1f, 0x2d, 0xf3, 0x37, 0x81, 0xa0,
    0x3c, 0x21, 0x8c, 0xea, 0x95, 0xa5, 0x5b, 0x3a,
    0x24, 0xed, 0xf7, 0x67, 0x7b, 0x72, 0x3a, 0xda,
    0x31, 0xbd, 0xa7, 0x63, 0xa6, 0x6f, 0xf9, 0xdf,
    0x06, 0x36, 0xb4, 0xe2, 0x35, 0x4b, 0xa5, 0x8e,
    0x29, 0x8e, 0x6c, 0x02, 0xc5, 0x06, 0x9b, 0x98,
    0x6e, 0x5e, 0x00, 0x6a, 0x42, 0x09, 0x4b, 0xc3,
    0x09, 0x37, 0x67, 0x19, 0x58, 0x6d, 0x40, 0x50,
    0xb0, 0x62, 0x5b, 0xd6, 0x63, 0x7f, 0xed, 0xb0,
    0x97, 0x80, 0x9e, 0x91, 0x3f, 0x82, 0xfd, 0x83,
    0x36, 0xce, 0x06, 0xc4, 0xdc, 0xa4, 0x1e, 0x70,
    0xd4, 0x94, 0xfc, 0x6e, 0x46, 0xa3, 0xc8, 0xed,
    0x34, 0x0a, 0xb1, 0x9a, 0x66, 0x5d, 0xc0, 0xce,
    0x73, 0xd3, 0x65, 0xcb, 0xfb, 0x79, 0xdd, 0xf6,
    0x19, 0xf6, 0xd8, 0xa9, 0xe6, 0x34, 0x15, 0x86,
    0x7a, 0x30, 0x79, 0xde, 0x2b, 0x06, 0xa4, 0xc0,
    0xc8, 0xa2, 0xc1, 0x41, 0xb3, 0x4c, 0xf6, 0xdb,
    0x16, 0xcd, 0xd2, 0x8b, 0xf1, 0x18, 0x5a, 0xc8,
    0x3e, 0xd9, 0x54, 0x40, 0xd4, 0xce, 0x88, 0xbb,
    0x66, 0xf1, 0x74, 0x20, 0xa2, 0x3c, 0x31, 0x09,
    0xba, 0xac, 0x61, 0x15, 0x9f, 0x73, 0x5f, 0xa7,
    0xe5, 0x0d, 0xb3, 0xab, 0xa2, 0x72, 0x25, 0xc9,
    0x87, 0x9b, 0x18, 0xdb, 0xff, 0xfb, 0x39, 0x84,
    0x8d, 0xf8, 0x97, 0x47, 0xab, 0xc4, 0xfb, 0xc2,
    0xd8, 0xe8, 0xce, 0x6e, 0x65, 0x76, 0x88, 0x4a,
    0x22, 0x2f, 0xdd, 0x43, 0xa7, 0xc4, 0x8d, 0x32,
    0x12, 0x75, 0x0b, 0x72, 0xd6, 0xb7, 0x43, 0x84,
    0xc8, 0x59, 0xa8, 0xb7, 0x8b, 0x84, 0x33, 0x92,
    0x8f, 0x94, 0xe8, 0xd0, 0xaf, 0x11, 0x35, 0xde,
    0xb7, 0x63, 0xb8, 0x91, 0x4c, 0x96, 0x4e, 0x9c,
    0x62, 0x28, 0xa2, 0xbc, 0x0b, 0x90, 0xae, 0x94,
    0x90, 0xe9, 0x32, 0xeb, 0xe3, 0x77, 0x60, 0x5f,
    0x87, 0x48, 0x4b, 0xb0, 0x78, 0x0e, 0xe2, 0x85,
    0x47, 0x06, 0xa4, 0xc9, 0x26, 0xac, 0x8f, 0xe7,
    0xc2, 0xc7, 0xce, 0xf5, 0xd1, 0x20, 0xa8, 0x56,
    0xe1, 0x4f, 0x50, 0x90, 0xb3, 0xc1, 0x03, 0x57,
    0xd3, 0x62, 0x0e, 0x2a, 0xe8, 0x86, 0xf4, 0x94,
    0x0e, 0xa5, 0x8b, 0x4e, 0x73, 0xa2, 0x76, 0xac,
    0x00, 0x29, 0xe5, 0x80, 0x26, 0x02, 0x13, 0xd1,
    0xb2, 0x68, 0x72, 0x23, 0x38, 0x55, 0xfc, 0x4d,
    0x05, 0x60, 0x49, 0x7b, 0xfb, 0xaa, 0x17, 0x8f,
    0x26, 0x0a, 0x08, 0x33, 0x8d, 0x7f, 0x4e, 0xe5,
    0x6e, 0xf8, 0x84, 0x9b, 0x9f, 0xcb, 0xa2, 0x2b,
    0xfb, 0xaf, 0xad, 0x21, 0xe2, 0x4f, 0x6f, 0x55,
    0xc1, 0x78, 0x46, 0xe3, 0xb5, 0x63, 0x06, 0x9b,
    0x93, 0x7d, 0xac, 0xd4, 0xe0, 0x64, 0x01, 0x8d,
    0xac, 0x30, 0x8b, 0x8b, 0x55, 0xb7, 0x8a, 0x16,
    0x3f, 0xc9, 0x82, 0x7f, 0xb5, 0x3b, 0x0d, 0xc0,
    0x46, 0x89, 0x5c, 0x6c, 0x45, 0x21, 0x78, 0xda,
    0x84, 0x1f, 0xc8, 0xcf, 0xf1, 0x1e, 0x79, 0x71,
    0x3b, 0xc8, 0xe2, 0x8b, 0x41, 0xfe, 0xaf, 0x2f,
    0x3b, 0x23, 0x13, 0xc5, 0x46, 0x87, 0xc6, 0x24,
    0x37, 0x21, 0x68, 0x8a, 0x3e, 0x45, 0x61, 0xf4,
    0xad, 0xf5, 0x1c, 0x23, 0x45, 0xa3, 0x42, 0xf2,
    0xa9, 0xac, 0x94, 0x50, 0xc9, 0x3d, 0x5e, 0x70,
    0x33, 0x2b, 0x78, 0xd1, 0x5c, 0x13, 0x35, 0xe6,
    0x13, 0x80, 0x5e, 0x55, 0xa7, 0xcc, 0x67, 0xb0,
    0x6c, 0xfe, 0xa2, 0x24, 0x02, 0x6d, 0xb3, 0xcb,
    0x9e, 0x94, 0xb3, 0xc6, 0x01, 0xf3, 0x01, 0x3a,
    0xe4, 0xa7, 0xa3, 0xdf, 0x56, 0x4c, 0x30, 0xce,
    0xb1, 0xd5, 0x1b, 0x68, 0x9b, 0x75, 0xae, 0xf4,
    0xb9, 0x2a, 0xe5, 0x8b, 0x7b, 0xe5, 0x99, 0x46,
    0x5f, 0x29, 0xf6, 0x82, 0xd0, 0x42, 0xb1, 0x45,
    0x09, 0x16, 0x5b, 0x32, 0x11, 0xca, 0x48, 0xea,
    0x51, 0x12, 0x0a, 0x9f, 0x6e, 0x3f, 0x74, 0xe6,
    0xe0, 0xfe, 0xf8, 0xa5, 0xc0, 0xfd, 0x15, 0x6e,
    0x2b, 0x4a, 0xd5, 0x76, 0xa8, 0x3d, 0xe3, 0x0d,
    0xfe, 0x44, 0x11, 0x5e, 0x7a, 0xde, 0x12, 0x29,
    0x5a, 0x5a, 0x25, 0xc0, 0x8e, 0x98, 0xd1, 0x11,
    0xc8, 0x00, 0x65, 0xb2, 0xf4, 0xd7, 0x56, 0x32,
    0x46, 0x2b, 0x4f, 0x7e, 0xc3, 0x4e, 0xf1, 0x17,
    0xff, 0x03, 0x32, 0xae, 0xe3, 0xbe, 0x0b, 0xab,
    0xfb, 0x43, 0x0f, 0x6d, 0xa5, 0xc6, 0x44, 0xba,
    0xc9, 0xe3, 0x3d, 0x40, 0xe7, 0x6c, 0xe8, 0x21,
    0xb2, 0x46, 0x7b, 0x3b, 0x3d, 0xde, 0x80, 0xc8,
    0xea, 0xf4, 0x6b, 0xf3, 0x53, 0xca, 0x51, 0x84,
    0xcf, 0xad, 0x7e, 0xce, 0xce, 0xc2, 0x65, 0xfc,
    0x03, 0x8c, 0xcb, 0xfa, 0xcb, 0x37, 0x89, 0x82,
    0x59, 0x5e, 0x36, 0x52, 0xe4, 0xbc, 0x8d, 0x47,
    0x7c, 0xb8, 0x3f, 0x63, 0x59, 0xdc, 0xd3, 0x74,
    0x11, 0x33, 0xb4, 0x69, 0x74, 0x40, 0x0d, 0x42,
    0x63, 0x1d, 0xe6, 0x5c, 0x1b, 0xca, 0x41, 0xff,
    0x23, 0x4e, 0xe8, 0x3d, 0x14, 0xa8, 0x17, 0x18,
    0xd0, 0x78, 0x08, 0x87, 0x7d, 0x5e, 0xdc, 0x3a,
    0x07, 0xba, 0x12, 0x8e, 0x8e, 0x56, 0x0a, 0xcb,
    0x37, 0xf6, 0x54, 0xeb, 0x55, 0x16, 0x8f, 0x06,
    0x15, 0x28, 0x6b, 0xfb, 0xed, 0x38, 0x9e, 0x9b,
    0x98, 0x5b, 0xdc, 0x67, 0x33, 0x0e, 0x02, 0x36,
    0x1b, 0x7a, 0x9a, 0x43, 0xcd, 0xf2, 0x65, 0xef,
    0x37, 0x19, 0x24, 0x6f, 0x4b, 0xb9, 0x4d, 0x3e,
    0x0b, 0x47, 0xd1, 0x67, 0x50, 0x6a, 0x7f, 0x07
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    0x30, 0x82, 0x07, 0xb4, 0x30, 0x0d, 0x06, 0x0b,
    0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x82, 0x0b,
    0x0c, 0x06, 0x05, 0x03, 0x82, 0x07, 0xa1, 0x00,
    0xff, 0x89, 0xee, 0xad, 0x20, 0x8f, 0x61, 0xa4,
    0x07, 0x1c, 0x54, 0x98, 0x8c, 0xf4, 0x2e, 0xd9,
    0xe6, 0x0f, 0xcb, 0x0e, 0xab, 0xa1, 0x37, 0x4d,
    0xc0, 0x48, 0x24, 0x78, 0xd6, 0x2d, 0x9b, 0x6f,
    0x0f, 0x17, 0x08, 0x71, 0xc3, 0xd1, 0xc8, 0x7a,
    0xe7, 0x32, 0xcb, 0xcd, 0xd6, 0xb5, 0x90, 0x08,
    0xe1, 0xda, 0xaa, 0x89, 0x3e, 0x4a, 0x62, 0x98,
    0x3d, 0xc6, 0x71, 0x30, 0xb4, 0x63, 0xa5, 0x3b,
    0xb3, 0x69, 0x75, 0x10, 0xaf, 0x5e, 0x72, 0x78,
    0xa2, 0xef, 0x63, 0x63, 0x21, 0xe7, 0xf4, 0xa7,
    0x9c, 0x50, 0x74, 0x14, 0x3e, 0xdd, 0x73, 0x9e,
    0x97, 0x65, 0xdd, 0xdf, 0x3c, 0x40, 0x4d, 0x03,
    0x49, 0xe4, 0xbf, 0x65, 0xe7, 0x44, 0x8f, 0x59,
    0x00, 0xe2, 0x98, 0xb5, 0x66, 0xa3, 0x3b, 0x11,
    0x9f, 0xc7, 0xc2, 0x16, 0x61, 0xf0, 0x1e, 0x89,
    0xc8, 0x96, 0x8d, 0x18, 0xac, 0x86, 0xa0, 0xe2,
    0xd9, 0x8c, 0xef, 0x53, 0x6d, 0x4e, 0x74, 0xc9,
    0x66, 0x28, 0x16, 0xf3, 0x62, 0xc4, 0x6f, 0x2b,
    0x6e, 0x36, 0x03, 0xad, 0xc5, 0xe4, 0x8f, 0x0b,
    0x90, 0x8c, 0x8f, 0xff, 0x5d, 0xdf, 0x7a, 0xe6,
    0xaf, 0x9a, 0x43, 0xbc, 0xd4, 0x73, 0x22, 0xdc,
    0x5f, 0x08, 0xa1, 0x17, 0x97, 0x89, 0x79, 0xf5,
    0xdc, 0xed, 0x4f, 0x85, 0x8e, 0x0c, 0x23, 0x35,
    0x3c, 0x34, 0x19, 0x65, 0xf5, 0xd6, 0xc9, 0x2d,
    0x7a, 0x2e, 0x67, 0xd5, 0xf1, 0x82, 0x97, 0xaa,
    0x05, 0x26, 0x84, 0x25, 0x47, 0x58, 0x2c, 0xe6,
    0x59, 0xc7, 0x98, 0x7a, 0xdb, 0x40, 0x45, 0x1c,
    0x71, 0x55, 0x2e, 0xea, 0x3f, 0x6e, 0x7c, 0x82,
    0x52, 0x6a, 0x19, 0x3a, 0xd3, 0xa1, 0x3c, 0xce,
    0x00, 0x06, 0xec, 0xed, 0x97, 0xce, 0xd8, 0xdf,
    0xde, 0xa3, 0xed, 0xe7, 0x81, 0x62, 0x02, 0x9c,
    0x1b, 0x51, 0xa1, 0xf4, 0x9d, 0x1b, 0x28, 0x76,
    0x93, 0x96, 0x20, 0x55, 0x60, 0x1f, 0xaf, 0x52,
    0xc3, 0xce, 0xb9, 0x12, 0x66, 0xf5, 0x64, 0x22,
    0x87, 0x86, 0x29, 0x80, 0x8f, 0x18, 0x33, 0xba,
    0x48, 0x71, 0x1d, 0x00, 0xfe, 0xa5, 0xfc, 0xc6,
    0x87, 0xbe, 0x44, 0x3c, 0xc9, 0x49, 0xfb, 0x68,
    0x3c, 0xdf, 0xca, 0xef, 0xa7, 0xdc, 0x67, 0xb8,
    0x28, 0xd6, 0xad, 0x18, 0xaf, 0xad, 0x1f, 0x4c,
    0x85, 0xa3, 0x64, 0xac, 0x3f, 0xa9, 0x39, 0x28,
    0xef, 0x8a, 0x45, 0x7e, 0xb0, 0xf4, 0x89, 0x72,
    0xf7, 0xb1, 0xef, 0x9d, 0x1c, 0x3c, 0x93, 0xcb,
    0xa0, 0xfb, 0x2a, 0x90, 0xe2, 0x1d, 0x49, 0x8e,
    0x36, 0xb8, 0x07, 0xf4, 0xb3, 0x09, 0xf0, 0x6f,
    0x3c, 0xd9, 0x37, 0x19, 0x57, 0xd4, 0x1e, 0x2a,
    0xa2, 0xa7, 0x2e, 0xc1, 0xcd, 0x8d, 0x48, 0x47,
    0xb5, 0x8a, 0x12, 0x93, 0x34, 0xb8, 0xec, 0x32,
    0x07, 0x49, 0xb6, 0x8d, 0x73, 0xd4, 0x2c, 0x6a,
    0xa0, 0x33, 0x29, 0x21, 0x5d, 0x37, 0xa9, 0x39,
    0x40, 0xbe, 0x71, 0x29, 0xbe, 0xd1, 0x4b, 0xbc,
    0x9a, 0x17, 0x93, 0x52, 0xb8, 0x81, 0xee, 0xc5,
    0xff, 0x25, 0x78, 0x2f, 0x52, 0x0a, 0x8f, 0xb2,
    0xef, 0xf3, 0x1d, 0x68, 0x56, 0x31, 0x29, 0x84,
    0x55, 0x47, 0x32, 0x34, 0x0f, 0x60, 0x07, 0xd6,
    0x2b, 0xb9, 0x29, 0xaf, 0x0f, 0xcd, 0x1c, 0xc0,
    0x77, 0x4c, 0xc6, 0x31, 0xdb, 0xf4, 0x17, 0xbe,
    0x3d, 0xf8, 0x8c, 0xf1, 0x02, 0x7c, 0x6b, 0xd4,
    0xaf, 0x03, 0xb2, 0xf4, 0x78, 0x8d, 0xd3, 0x4e,
    0x5c, 0x04, 0xb9, 0x01, 0xe3, 0x73, 0xb4, 0x67,
    0xe9, 0xa8, 0x77, 0x6f, 0x87, 0x2b, 0xe2, 0x00,
    0x98, 0x5f, 0x02, 0x43, 0x85, 0x03, 0x4c, 0x71,
    0xd2, 0xe7, 0x61, 0x03, 0x22, 0x9e, 0xe5, 0xc2,
    0xa7, 0x66, 0x42, 0x7c, 0x9f, 0xf4, 0xb8, 0x6b,
    0x2d, 0xe4, 0xaa, 0x51, 0xda, 0x08, 0x73, 0x75,
    0x26, 0x45, 0xdc, 0xa6, 0x20, 0xd7, 0xcb, 0x00,
    0xfc, 0xe4, 0xdb, 0x28, 0x92, 0xf8, 0xb0, 0xc7,
    0xf0, 0x4b, 0x6d, 0xe8, 0xc1, 0x84, 0x38, 0xed,
    0x1a, 0xd4, 0x66, 0x69, 0xc4, 0x96, 0x40, 0xc4,
    0x7d, 0xfa, 0x58, 0x70, 0x7e, 0x70, 0x40, 0xba,
    0xfc, 0x95, 0xb6, 0x4c, 0x7c, 0x58, 0xbc, 0xb3,
    0x59, 0x08, 0x14, 0x03, 0x35, 0xf3, 0xf1, 0xaa,
    0xd5, 0xa2, 0x57, 0x70, 0xb6, 0x20, 0x75, 0x0a,
    0x58, 0x66, 0x74, 0xf7, 0x1c, 0xfd, 0x99, 0x7c,
    0x20, 0xda, 0xe7, 0x76, 0xcb, 0xf4, 0xa3, 0x9b,
    0xbc, 0x8f, 0x74, 0xef, 0xe2, 0x46, 0x5a, 0x72,
    0x33, 0x06, 0x32, 0x1e, 0xbd, 0x4e, 0x4c, 0xf6,
    0x16, 0x43, 0xa5, 0xa5, 0xa5, 0x6c, 0x76, 0x33,
    0x35, 0x63, 0xdc, 0xe4, 0xec, 0x7f, 0x8a, 0xfa,
    0xc3, 0x53, 0x69, 0x28, 0xf7, 0xd6, 0x97, 0xb9,
    0x3a, 0xf4, 0x15, 0x90, 0x50, 0xd3, 0xdf, 0xf5,
    0xd3, 0xcf, 0x15, 0x76, 0xe3, 0x3d, 0x24, 0x14,
    0xfd, 0xd3, 0x01, 0x25, 0x82, 0xb4, 0xe3, 0xd8,
    0x68, 0x89, 0x86, 0xa8, 0x26, 0x02, 0x5f, 0xc6,
    0xf4, 0x99, 0x3b, 0x97, 0xa8, 0x65, 0xed, 0x18,
    0xbb, 0x3c, 0x43, 0x4a, 0x6e, 0xaa, 0xbc, 0x83,
    0x85, 0x19, 0x9f, 0x9b, 0xb8, 0xa4, 0xa3, 0xb2,
    0xb7, 0x56, 0x07, 0x6c, 0xbf, 0x7d, 0xff, 0x5d,
    0xb5, 0x1e, 0x83, 0xc8, 0x74, 0x70, 0x98, 0x17,
    0x40, 0xe0, 0x2d, 0xad, 0x31, 0x00, 0x8e, 0x42,
    0xd5, 0xb2, 0x25, 0xaa, 0x82, 0xaf, 0x33, 0xd8,
    0x5b, 0xe2, 0x07, 0xed, 0xda, 0x84, 0xe9, 0xa2,
    0xff, 0xbb, 0xa5, 0x47, 0x95, 0x6e, 0xa1, 0x8d,
    0x59, 0x52, 0xeb, 0xf3, 0x3c, 0x18, 0x29, 0x92,
    0x72, 0x27, 0x18, 0xfc, 0x95, 0xb9, 0xde, 0x46,
    0xda, 0xcc, 0x4c, 0x31, 0x1d, 0x78, 0x86, 0xd2,
    0x8c, 0x38, 0x9c, 0x32, 0xab, 0xf7, 0xca, 0x73,
    0x85, 0xa5, 0xf1, 0xe0, 0x25, 0x06, 0xf9, 0x18,
    0x14, 0xab, 0x3b, 0x73, 0x26, 0xee, 0xa0, 0xfd,
    0x15, 0xac, 0xd6, 0x4e, 0x6b, 0xdb, 0x01, 0xa1,
    0xdc, 0xd1, 0x2f, 0xd2, 0xb7, 0x5e, 0x12, 0x4f,
    0x4b, 0x59, 0xd8, 0x03, 0x12, 0x60, 0xc9, 0x81,
    0xb7, 0x06, 0x23, 0x09, 0xc4, 0xd9, 0xa8, 0x93,
    0x6e, 0x96, 0xf4, 0x93, 0x53, 0xf0, 0x3d, 0xde,
    0x10, 0x88, 0xb1, 0xd0, 0xcc, 0xad, 0x2c, 0xbf,
    0x88, 0x98, 0x8f, 0x25, 0x76, 0xd7, 0x65, 0x77,
    0xcc, 0x36, 0x1d, 0x1b, 0x6b, 0x60, 0x58, 0xc4,
    0xfe, 0xe6, 0xca, 0xa8, 0x29, 0x33, 0x69, 0x36,
    0xb8, 0x12, 0x95, 0x38, 0xd9, 0xd4, 0x16, 0xe9,
    0x3e, 0x40, 0x8c, 0xc7, 0xae, 0x04, 0x11, 0xdf,
    0x51, 0xd3, 0xdd, 0xbf, 0xa9, 0x41, 0x43, 0x4c,
    0xff, 0x87, 0x2f, 0xea, 0x0f, 0x13, 0x66, 0x2a,
    0x2b, 0x18, 0xe8, 0xc4, 0xff, 0xa0, 0x1c, 0x78,
    0x79, 0x21, 0xf8, 0xaa, 0x8a, 0xf8, 0x92, 0xdf,
    0x7b, 0x5f, 0x6a, 0x71, 0x60, 0x67, 0x5d, 0x94,
    0xf6, 0xbb, 0x1d, 0x90, 0x7c, 0x51, 0x70, 0x1d,
    0x87, 0xde, 0xf8, 0x91, 0xcb, 0x42, 0x9f, 0xc7,
    0x4b, 0xa0, 0x16, 0xee, 0xb4, 0x73, 0xe8, 0xe0,
    0x0b, 0xa5, 0xd3, 0x26, 0x9e, 0x52, 0xda, 0x4a,
    0x1f, 0xae, 0x76, 0xbf, 0xbb, 0x4d, 0x74, 0x98,
    0xa6, 0xae, 0xc0, 0x60, 0x96, 0xc5, 0xad, 0x9b,
    0x91, 0x31, 0xb9, 0x50, 0x3d, 0x9a, 0x0f, 0xe1,
    0x93, 0xef, 0x08, 0x72, 0xb2, 0x66, 0xe5, 0x5d,
    0xe4, 0x15, 0x53, 0x8e, 0xb0, 0xb3, 0xf8, 0x78,
    0xfc, 0x5d, 0x44, 0xc5, 0xbf, 0xf5, 0x01, 0x54,
    0xc5, 0x45, 0xa9, 0x30, 0xa4, 0xf1, 0x49, 0x79,
    0x4e, 0xab, 0xfc, 0xb2, 0x93, 0xe7, 0x3a, 0xe1,
    0x7f, 0x1f, 0x2f, 0x45, 0x3a, 0x53, 0x2b, 0x68,
    0xb3, 0xa4, 0xac, 0x23, 0x54, 0xb7, 0x5d, 0x25,
    0xa3, 0xe3, 0x90, 0x8a, 0xb0, 0x02, 0xfb, 0x7f,
    0x2d, 0xeb, 0x80, 0xc2, 0x5c, 0x62, 0xe1, 0x36,
    0x5a, 0x82, 0x8f, 0x4e, 0x74, 0xeb, 0x7d, 0x70,
    0xaf, 0x23, 0x92, 0x65, 0x3a, 0x11, 0xc0, 0x29,
    0xdb, 0xf7, 0x9a, 0xdc, 0x81, 0x45, 0x25, 0x0c,
    0x2e, 0x4f, 0x88, 0x41, 0x34, 0x53, 0xc6, 0x08,
    0x21, 0x77, 0xc1, 0xbb, 0x61, 0x48, 0x20, 0x69,
    0x1a, 0xbb, 0x71, 0x1b, 0x56, 0x18, 0x79, 0x75,
    0x16, 0x9a, 0xb3, 0x79, 0x31, 0x11, 0xa2, 0x89,
    0x8d, 0xea, 0x10, 0xb0, 0x04, 0x7f, 0xf8, 0x6e,
    0xdc, 0x08, 0x9b, 0x51, 0xa7, 0x64, 0xbd, 0x8d,
    0xd4, 0xd0, 0x1e, 0x38, 0x50, 0x1a, 0xa8, 0x7e,
    0x20, 0xae, 0xee, 0x8c, 0xa7, 0x72, 0x94, 0xc9,
    0xba, 0xf0, 0x67, 0xbd, 0x25, 0x1a, 0x3a, 0xdf,
    0x75, 0x39, 0xb7, 0xd3, 0x83, 0x3b, 0x89, 0xdf,
    0xb5, 0x2d, 0xd3, 0x12, 0x24, 0x21, 0x7c, 0x9e,
    0x92, 0x1c, 0x19, 0xae, 0x28, 0xcb, 0x2e, 0x2e,
    0x3c, 0xa9, 0x9b, 0xbd, 0xf9, 0x33, 0x30, 0xb2,
    0xbd, 0x8b, 0xbf, 0xc1, 0x8b, 0x32, 0xf1, 0x20,
    0xa1, 0x00, 0xfd, 0x11, 0x7d, 0x9a, 0xa8, 0x14,
    0x2c, 0xce, 0x16, 0x16, 0x4b, 0xdd, 0x56, 0x91,
    0x15, 0x36, 0x83, 0xcb, 0x01, 0x58, 0x35, 0xe1,
    0xdc, 0x22, 0x3d, 0xf8, 0xc2, 0x06, 0x54, 0x68,
    0x77, 0xd1, 0x47, 0x28, 0xdc, 0x09, 0x2a, 0x86,
    0x13, 0x80, 0xa6, 0xe9, 0xd0, 0xb4, 0xa3, 0x41,
    0x47, 0xf4, 0x71, 0x24, 0x10, 0x4c, 0x9f, 0xb7,
    0x57, 0x34, 0x48, 0x1b, 0xb4, 0xed, 0x0e, 0x89,
    0x4c, 0xf1, 0x73, 0x44, 0xff, 0x35, 0xb6, 0xe0,
    0x8f, 0x02, 0xa3, 0xa3, 0x81, 0x55, 0x38, 0xb5,
    0xc1, 0x99, 0xb3, 0x88, 0x84, 0x0d, 0xd9, 0x73,
    0x77, 0x65, 0x0b, 0xd7, 0xf8, 0x03, 0x88, 0xcb,
    0xdf, 0x25, 0xaf, 0xc6, 0xf1, 0xfa, 0x5c, 0x4d,
    0xfa, 0xc3, 0x7b, 0x8f, 0xb8, 0x38, 0x5d, 0x29,
    0xbb, 0x3d, 0x3e, 0x62, 0x1c, 0xdd, 0xe6, 0x97,
    0xe6, 0xe9, 0xbe, 0x6e, 0xd2, 0xb7, 0x7a, 0x9a,
    0x8e, 0xaf, 0xb3, 0xc8, 0x9e, 0x19, 0xee, 0x3d,
    0x5b, 0x1f, 0xec, 0x34, 0x3a, 0x1c, 0x27, 0x90,
    0xbd, 0x1e, 0x49, 0x72, 0x25, 0x2e, 0x38, 0x48,
    0x7d, 0xe1, 0x85, 0x46, 0xa7, 0x1b, 0x4a, 0xd5,
    0x23, 0x75, 0x6d, 0x8b, 0xc3, 0xf1, 0x87, 0xec,
    0x8b, 0x45, 0xf0, 0x9b, 0xb2, 0x14, 0x7a, 0x7c,
    0x8d, 0x78, 0x9c, 0x82, 0x64, 0x14, 0xfe, 0x01,
    0xfa, 0x04, 0x33, 0x96, 0xdd, 0x5f, 0x56, 0xbc,
    0xb2, 0x03, 0xe3, 0x0c, 0xa1, 0x09, 0x66, 0xa0,
    0x5e, 0x44, 0xde, 0x21, 0xae, 0x7d, 0x7a, 0x0e,
    0x81, 0x27, 0xd2, 0xfb, 0x85, 0xed, 0x27, 0x27,
    0xac, 0x11, 0x1c, 0xa1, 0x6d, 0xe9, 0xc1, 0xca,
    0xf6, 0x40, 0x7c, 0x95, 0x01, 0xb7, 0xa8, 0x29,
    0x9a, 0xd2, 0xcc, 0x62, 0x70, 0x1c, 0x7d, 0x0e,
    0xe5, 0x60, 0xcb, 0x79, 0xa3, 0xd7, 0x5d, 0x48,
    0x4b, 0x3c, 0xf8, 0x12, 0xe8, 0x7a, 0x7e, 0x83,
    0xab, 0x24, 0x33, 0x0f, 0x7b, 0x0a, 0x38, 0xae,
    0xb1, 0xfc, 0xc3, 0x50, 0x5c, 0x83, 0x53, 0xfd,
    0x15, 0xd6, 0x49, 0x54, 0xb6, 0x40, 0xe5, 0xe8,
    0x55, 0xba, 0x08, 0x2f, 0x21, 0xd7, 0x0e, 0x71,
    0x8a, 0xb2, 0xe1, 0x6b, 0xc6, 0x7e, 0x0f, 0x1c,
    0x4d, 0x41, 0x9f, 0x38, 0xc2, 0xce, 0x41, 0x41,
    0x48, 0xcd, 0xec, 0x16, 0x1d, 0x23, 0x8e, 0x41,
    0xcd, 0x5e, 0xf9, 0x5f, 0x01, 0x5e, 0x73, 0xa2,
    0xa1, 0xef, 0xe9, 0x57, 0xe0, 0xba, 0xe6, 0xbb,
    0x2b, 0xff, 0x3e, 0xb8, 0xad, 0xd5, 0x12, 0xc1,
    0x54, 0x49, 0xca, 0x93, 0xb0, 0x7d, 0x7b, 0xcf,
    0xf0, 0xc5, 0x94, 0x43, 0x30, 0x94, 0x11, 0x8d,
    0x15, 0x79, 0x2e, 0x57, 0xb8, 0x24, 0xcd, 0x2e,
    0xc2, 0x49, 0x3d, 0x92, 0x44, 0x23, 0x0c, 0x3e,
    0xa0, 0xf9, 0xa5, 0xad, 0x2a, 0x56, 0xec, 0xf4,
    0x6d, 0x0f, 0x5b, 0xb5, 0xd4, 0x2a, 0x3f, 0x2b,
    0x17, 0x9f, 0x5d, 0x33, 0x97, 0x42, 0xd4, 0x1e,
    0x14, 0x49, 0x01, 0xfb, 0xb6, 0x72, 0xbc, 0x14,
    0x5b, 0x79, 0xf4, 0x0a, 0xc5, 0x49, 0xe1, 0x76,
    0x44, 0x78, 0x87, 0xd1, 0x8e, 0x5b, 0xd5, 0x95,
    0xad, 0x19, 0x7c, 0x0d, 0x39, 0x7f, 0x41, 0x2e,
    0xd7, 0x9e, 0xbc, 0xfd, 0x2c, 0xde, 0xfa, 0x01,
    0x7d, 0x2b, 0x04, 0xef, 0x4d, 0xf9, 0xf4, 0x5b,
    0xed, 0x05, 0x9a, 0x50, 0x35, 0xe7, 0xb0, 0xba,
    0x24, 0xea, 0x16, 0x51, 0xe1, 0x6f, 0x32, 0x08,
    0x94, 0xd6, 0x19, 0x9d, 0x0e, 0x4c, 0xc1, 0xbb,
    0x01, 0x87, 0xa5, 0x90, 0x5f, 0x6f, 0xc4, 0xed,
    0xa1, 0x4c, 0x06, 0x4d, 0x2c, 0x47, 0x24, 0xda,
    0xae, 0xd2, 0x41, 0x92, 0x1f, 0x46, 0xce, 0xec,
    0xb1, 0xcc, 0x80, 0x1e, 0xb2, 0xcb, 0x66, 0x48,
    0x22, 0xec, 0x0e, 0x47, 0xfc, 0xad, 0x17, 0xfe,
    0x7b, 0xc5, 0x4d, 0x34, 0x95, 0x40, 0xd0, 0x02,
    0x7e, 0x90, 0xaa, 0x92, 0xaf, 0x48, 0x64, 0xc5,
    0xc1, 0x56, 0xd8, 0x9b, 0x6c, 0x5f, 0x2e, 0xfa,
    0xd7, 0x84, 0xdc, 0x71, 0x65, 0x1b, 0xfb, 0xbc,
    0x21, 0xc7, 0x57, 0xf4, 0x71, 0x2e, 0x6f, 0x34,
    0x85, 0x99, 0xa8, 0x5c, 0x6f, 0x34, 0x22, 0x44,
    0x89, 0x01, 0xf9, 0x48, 0xd2, 0xe2, 0xe4, 0x71,
    0x9d, 0x48, 0x07, 0x97, 0xd4, 0x66, 0xe4, 0x4d,
    0x48, 0xa3, 0x08, 0x7f, 0x6e, 0xaa, 0x7b, 0xe9,
    0x93, 0x81, 0x03, 0x0c, 0xd2, 0x48, 0xcf, 0x3f,
    0x5f, 0xbe, 0x03, 0xfb, 0x0f, 0xad, 0xc3, 0x81,
    0xd9, 0xce, 0x88, 0x0b, 0xfa, 0xed, 0x29, 0x7e,
    0x0b, 0xa1, 0x6f, 0x4c, 0x7d, 0xe4, 0x36, 0xff,
    0xdf, 0x94, 0x1a, 0x24, 0xb3, 0x7b, 0xca, 0x24,
    0x7e, 0x3a, 0x19, 0x53, 0x13, 0x4a, 0x17, 0x58,
    0xe7, 0x16, 0x9b, 0x50, 0xd8, 0xda, 0xcc, 0x6e,
    0x05, 0x25, 0xfe, 0x16, 0xcb, 0x5b, 0xd5, 0x35,
    0x76, 0x40, 0x44, 0x96, 0x23, 0x97, 0xe2, 0x4a,
    0x72, 0x0c, 0x54, 0x43, 0xc0, 0x09, 0x85, 0x8e,
    0x15, 0x85, 0xaf, 0x3c, 0x5e, 0x5f, 0x3c, 0x2d,
    0x21, 0x42, 0x75, 0xb7, 0xe4, 0x50, 0xf9, 0x00,
    0xa3, 0x4f, 0xb1, 0x7c, 0xfe, 0x62, 0xd0, 0xe9,
    0x6d, 0x51, 0xcc, 0x83, 0xc1, 0xdc, 0x37, 0x10,
    0x90, 0x0a, 0x15, 0xd8, 0xd5, 0x02, 0xf7, 0x74,
    0xb8, 0x46, 0x84, 0xc3, 0x61, 0x17, 0x26, 0x0f,
    0xe4, 0xde, 0x1a, 0xcf, 0x42, 0x53, 0x63, 0x2f,
    0x8d, 0xf7, 0x06, 0x07, 0xc3, 0x33, 0x39, 0x59,
    0xe9, 0x17, 0xc8, 0x05, 0xd2, 0xa2, 0xae, 0x53,
    0x2c, 0x7e, 0xd0, 0x9d, 0x5c, 0xb5, 0x42, 0x9f,
    0x84, 0xd7, 0xfe, 0x93, 0x74, 0xfb, 0xbb, 0xd2,
    0x1e, 0x57, 0x4e, 0x7f, 0x79, 0xaf, 0xd2, 0xf9,
    0x5e, 0x41, 0x9e, 0x63, 0x54, 0x61, 0x47, 0x0c,
    0x92, 0x4c, 0xc9, 0xfe, 0x4f, 0xcb, 0xe5, 0x8e,
    0x65, 0xb3, 0x97, 0x1b, 0xd8, 0xd1, 0x62, 0xfd
#else
    0x30, 0x82, 0x0a, 0x34, 0x30, 0x0d, 0x06, 0x0b,
    0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x82, 0x0b,
    0x0c, 0x08, 0x07, 0x03, 0x82, 0x0a, 0x21, 0x00,
    0x7f, 0x5f, 0x63, 0x81, 0x6f, 0x04, 0x4c, 0xec,
    0xa8, 0xaf, 0x7b, 0x99, 0x41, 0xc6, 0xff, 0xdf,
    0x77, 0x66, 0x28, 0xc0, 0xe2, 0x58, 0xea, 0x9c,
    0x60, 0xbb, 0x03, 0x3e, 0xca, 0xa8, 0x38, 0x64,
    0xfb, 0xf7, 0x1b, 0x3f, 0xec, 0xfd, 0x0f, 0xf1,
    0x9c, 0xe4, 0xfd, 0xad, 0x83, 0xf7, 0x03, 0x66,
    0x6e, 0x7f, 0x4d, 0x42, 0xab, 0x6b, 0x73, 0x26,
    0xde, 0x6f, 0x8c, 0xc4, 0xca, 0x21, 0x66, 0x31,
    0x79, 0x57, 0x88, 0xcb, 0x1e, 0xab, 0xda, 0x1d,
    0x56, 0x70, 0xd9, 0x83, 0xa1, 0xb4, 0x83, 0xce,
    0xcc, 0x0f, 0xeb, 0xd6, 0x63, 0xbd, 0xf6, 0x02,
    0x5d, 0x5b, 0x0c, 0x17, 0x3c, 0x3e, 0x15, 0x02,
    0x22, 0xa1, 0x5d, 0xb5, 0xc5, 0x81, 0x28, 0x95,
    0x0b, 0x34, 0x2b, 0x96, 0x0a, 0xae, 0x6a, 0xa8,
    0xb5, 0x1d, 0x56, 0xbb, 0x7d, 0x83, 0x9a, 0x15,
    0xad, 0x63, 0x9e, 0x86, 0x8c, 0x6e, 0x6a, 0xa8,
    0xde, 0x55, 0xd0, 0xce, 0xc0, 0x2e, 0x05, 0xfe,
    0x1f, 0x4d, 0xd7, 0x12, 0xa4, 0x5a, 0xe9, 0x04,
    0x0d, 0x20, 0x84, 0x90, 0xb9, 0xca, 0x64, 0xe4,
    0xad, 0x2e, 0x74, 0x4b, 0x1d, 0x2f, 0xcc, 0xac,
    0xd8, 0x1a, 0x5e, 0xb2, 0x78, 0xbe, 0x61, 0xf7,
    0x36, 0xa3, 0xd1, 0x93, 0x86, 0xb5, 0x15, 0xf1,
    0x74, 0xf8, 0x9f, 0x6d, 0x6a, 0x8f, 0x6d, 0x86,
    0x8b, 0x36, 0x61, 0x10, 0xc9, 0x1a, 0x31, 0x39,
    0x09, 0xe6, 0x15, 0xa0, 0xb1, 0xfa, 0x69, 0xd4,
    0xc2, 0xb2, 0x56, 0x4c, 0x06, 0x33, 0x13, 0xc4,
    0x78, 0x53, 0x16, 0xfc, 0x52, 0x99, 0xe6, 0x27,
    0xc9, 0x3b, 0x24, 0x5c, 0x3e, 0x85, 0x73, 0x76,
    0x61, 0xa3, 0x61, 0xf0, 0x95, 0xd5, 0xb2, 0xf5,
    0x21, 0xe7, 0x09, 0xc3, 0x0c, 0x5c, 0xb0, 0x36,
    0xce, 0x45, 0x68, 0x41, 0x45, 0xcb, 0x1c, 0x36,
    0x2f, 0x3a, 0x00, 0x07, 0x56, 0xbe, 0x61, 0xd2,
    0x77, 0x37, 0x63, 0xa4, 0xdb, 0xfa, 0xa9, 0x6b,
    0x37, 0x90, 0x35, 0xd1, 0x1e, 0x27, 0x5b, 0x3e,
    0xc0, 0x0a, 0x02, 0x64, 0xe4, 0x58, 0x49, 0xab,
    0x2d, 0xc1, 0x38, 0x29, 0x3d, 0x44, 0xf9, 0xac,
    0xb7, 0x65, 0xd1, 0x5f, 0xf8, 0xce, 0x52, 0x76,
    0x22, 0x15, 0x61, 0x02, 0x1f, 0xa7, 0xcd, 0xff,
    0xeb, 0xa6, 0x7f, 0x6b, 0xba, 0x75, 0xe3, 0x09,
    0x01, 0x06, 0x41, 0x20, 0x88, 0x75, 0x64, 0x6b,
    0x97, 0x38, 0x13, 0xab, 0x4c, 0x0a, 0xd4, 0x7e,
    0xd2, 0xfa, 0x78, 0xe8, 0x9f, 0x5d, 0xf9, 0x53,
    0x30, 0x17, 0xf1, 0x10, 0x9e, 0x4a, 0x32, 0x17,
    0x3a, 0x9b, 0xb9, 0x25, 0x8e, 0xeb, 0xd9, 0x41,
    0x01, 0xa2, 0xc6, 0x58, 0x4a, 0x9f, 0xc3, 0x73,
    0xfd, 0xe2, 0xe4, 0x2c, 0x92, 0xb4, 0xa2, 0x3d,
    0x0f, 0x1f, 0x37, 0x64, 0xf1, 0x17, 0x2a, 0x8c,
    0xc6, 0xb5, 0xb0, 0x69, 0x7d, 0xfe, 0x08, 0xe0,
    0x8e, 0xaa, 0xe0, 0x08, 0xd5, 0x28, 0x92, 0x51,
    0x73, 0x8a, 0x2f, 0x7a, 0x4a, 0xbf, 0x52, 0x8d,
    0x3e, 0x9b, 0x36, 0x6a, 0xfb, 0x19, 0xf0, 0xea,
    0xfe, 0x05, 0xbd, 0x2d, 0xa9, 0x58, 0x48, 0x02,
    0xa8, 0x20, 0x9e, 0xdc, 0x04, 0x57, 0xc2, 0x0c,
    0xae, 0xc1, 0x03, 0xe7, 0x17, 0x48, 0x80, 0x00,
    0x8d, 0x1b, 0xd0, 0xc5, 0xdc, 0x2a, 0x02, 0x6e,
    0x8e, 0x54, 0xf3, 0x79, 0x31, 0x02, 0x93, 0xc5,
    0xf2, 0x55, 0xea, 0x61, 0xd0, 0xb2, 0x8e, 0xc9,
    0x74, 0x17, 0x0d, 0x38, 0xf8, 0xab, 0xf4, 0x42,
    0xd4, 0xc2, 0xdc, 0xf7, 0x1b, 0xdb, 0x65, 0x36,
    0x9f, 0x56, 0xe2, 0xeb, 0xf7, 0xe5, 0x2d, 0x45,
    0xae, 0xc0, 0x95, 0xbc, 0xe4, 0x1f, 0x22, 0xdc,
    0x0f, 0x54, 0xed, 0x14, 0xb8, 0xf1, 0x2f, 0x5d,
    0xd1, 0x79, 0xa0, 0x81, 0x17, 0x71, 0xa1, 0xd6,
    0xf0, 0x88, 0x9c, 0x1c, 0xc7, 0x95, 0x07, 0xb0,
    0xea, 0xf7, 0xd3, 0xa2, 0x55, 0xfe, 0x85, 0x65,
    0x42, 0x06, 0xec, 0xd2, 0xbe, 0x03, 0x8f, 0x63,
    0x84, 0x4b, 0xb1, 0x47, 0x48, 0x20, 0x71, 0xd2,
    0xdf, 0xc9, 0x59, 0xb0, 0x24, 0x8a, 0x6e, 0xf9,
    0x4a, 0xa1, 0x7b, 0xed, 0x11, 0xb6, 0xf9, 0x9b,
    0xf7, 0x93, 0x0e, 0xcb, 0x7a, 0x32, 0x22, 0x23,
    0x4e, 0x86, 0xce, 0xad, 0x9d, 0x1b, 0x84, 0x57,
    0xaf, 0xa5, 0x04, 0x03, 0x0a, 0xc9, 0x04, 0x97,
    0xd0, 0xce, 0x8e, 0x2a, 0x9a, 0x00, 0x15, 0xeb,
    0xac, 0x96, 0x57, 0xde, 0xe6, 0xc1, 0x2d, 0xbd,
    0xfc, 0xd6, 0x95, 0x0f, 0x5f, 0x19, 0xac, 0xaf,
    0x6c, 0xd8, 0xa6, 0x1e, 0xd8, 0xdb, 0x14, 0xfd,
    0xba, 0x0f, 0xd0, 0x3f, 0x61, 0xe3, 0x76, 0xfc,
    0x47, 0x61, 0x07, 0x24, 0x49, 0x17, 0xca, 0x24,
    0x31, 0x16, 0x26, 0x4f, 0xdc, 0x2b, 0x39, 0xae,
    0x5f, 0xfa, 0x4f, 0x82, 0xef, 0xe1, 0x41, 0x8c,
    0x3e, 0x8e, 0xa7, 0x6c, 0xf2, 0x51, 0xf7, 0x85,
    0x35, 0x6c, 0xad, 0xea, 0x32, 0x35, 0xf3, 0xc0,
    0x14, 0x17, 0xe2, 0x98, 0x27, 0x36, 0x7e, 0x60,
    0x2f, 0x01, 0x60, 0x3e, 0x18, 0xf4, 0x4e, 0xe0,
    0xf5, 0x14, 0x21, 0x81, 0x05, 0x78, 0x1c, 0x5f,
    0x4e, 0x89, 0xbb, 0x23, 0x60, 0xb1, 0x8f, 0x07,
    0x53, 0x16, 0x6e, 0xfb, 0x86, 0x07, 0x90, 0xff,
    0xa6, 0x27, 0x60, 0xe6, 0x3e, 0x92, 0x2a, 0x3c,
    0xa3, 0x57, 0xec, 0x97, 0x23, 0xaf, 0xd2, 0x44,
    0xac, 0x09, 0x87, 0xb0, 0x54, 0xe9, 0x5b, 0x50,
    0x37, 0xfa, 0x12, 0xa4, 0xcb, 0x6f, 0xed, 0x9f,
    0x29, 0x73, 0xa7, 0x09, 0x29, 0x91, 0x93, 0x5c,
    0x54, 0xf4, 0x44, 0xc2, 0x04, 0x64, 0xfc, 0xd2,
    0xf2, 0x0a, 0x0b, 0x45, 0x1f, 0xc5, 0x18, 0xf0,
    0xff, 0x10, 0x1f, 0x3a, 0x97, 0xf8, 0xb1, 0x83,
    0x0e, 0x08, 0xe2, 0x55, 0x75, 0x6a, 0x45, 0x96,
    0xf8, 0x1b, 0xdc, 0xb6, 0x57, 0x83, 0x8c, 0x28,
    0xc0, 0x4a, 0x57, 0xc6, 0xfb, 0x27, 0x3d, 0xfa,
    0x5a, 0x0d, 0x69, 0x56, 0x23, 0x66, 0x02, 0x78,
    0xca, 0xf1, 0xfa, 0xcb, 0xc1, 0xf6, 0x92, 0x1c,
    0xa0, 0xe3, 0x09, 0x7d, 0x48, 0x5e, 0x86, 0xa0,
    0x82, 0xa8, 0xf1, 0x1e, 0xe1, 0xfe, 0xc6, 0x9d,
    0x4f, 0x2e, 0xf4, 0xfc, 0xc6, 0x48, 0x1d, 0xc1,
    0x2a, 0x6a, 0xb7, 0xea, 0x46, 0x89, 0x04, 0xe9,
    0xbd, 0xf1, 0xed, 0x16, 0x76, 0xd8, 0x4b, 0x42,
    0xd5, 0x43, 0xa4, 0xfb, 0x02, 0x01, 0x54, 0x00,
    0xaf, 0x55, 0x52, 0x27, 0xff, 0x00, 0xe2, 0xbb,
    0x4a, 0xf2, 0x69, 0xb4, 0x4e, 0x6c, 0x6b, 0xa3,
    0x96, 0x4f, 0xf4, 0x65, 0x90, 0x2d, 0xc8, 0x57,
    0x1f, 0xb2, 0xf0, 0x86, 0x7b, 0x93, 0x09, 0x49,
    0x31, 0xc4, 0xf4, 0x8f, 0xc8, 0x2d, 0xac, 0x1d,
    0xfc, 0xba, 0xa4, 0xa5, 0x41, 0x90, 0x76, 0x7d,
    0x9e, 0x47, 0xdc, 0x10, 0xe6, 0x0c, 0xf7, 0x0f,
    0xa4, 0xba, 0x4f, 0xe2, 0x46, 0x38, 0x4c, 0x28,
    0xa0, 0x57, 0xb5, 0x3c, 0xb3, 0x4b, 0x8f, 0x03,
    0x04, 0xff, 0xf6, 0xec, 0x60, 0x90, 0x62, 0xfe,
    0x74, 0x76, 0x48, 0xb3, 0xf4, 0x0a, 0x6a, 0x5a,
    0x5b, 0xad, 0xc8, 0x54, 0x62, 0x11, 0x52, 0xd9,
    0x84, 0x1a, 0x09, 0x4b, 0xca, 0x66, 0xaa, 0x3c,
    0x36, 0x08, 0x9d, 0x58, 0xd0, 0x4a, 0x3a, 0x8b,
    0x24, 0xe0, 0x80, 0x9f, 0xe3, 0x76, 0xb6, 0x07,
    0xb1, 0xbc, 0x00, 0x98, 0xb0, 0xc1, 0xe0, 0xf6,
    0x1f, 0x4d, 0xa8, 0xd1, 0x69, 0x44, 0x9c, 0x33,
    0xb0, 0x0f, 0x9c, 0xc9, 0x0c, 0x8c, 0xbc, 0x03,
    0x58, 0x81, 0x76, 0xab, 0x0d, 0xef, 0x25, 0x5a,
    0xf6, 0xab, 0x3b, 0xf1, 0x1f, 0x97, 0x12, 0x8e,
    0x7f, 0x28, 0x77, 0x26, 0x18, 0xc4, 0xc4, 0xda,
    0x2c, 0x43, 0x57, 0xd2, 0x1f, 0x67, 0x95, 0x40,
    0x2c, 0x94, 0x41, 0x69, 0x22, 0x8a, 0x24, 0xd9,
    0xc7, 0xfc, 0xea, 0x49, 0x83, 0x8f, 0x5d, 0x2e,
    0x9d, 0xac, 0x17, 0xb6, 0xe0, 0xc4, 0xe7, 0xe6,
    0xd5, 0xc2, 0x73, 0xa1, 0x8f, 0x33, 0x14, 0x02,
    0xae, 0x01, 0x9f, 0x6f, 0x40, 0x92, 0x4e, 0x03,
    0xc2, 0xa9, 0xf1, 0x36, 0x78, 0xe4, 0xde, 0x39,
    0x4d, 0x29, 0x2e, 0xc2, 0x00, 0x93, 0x79, 0xe4,
    0xb2, 0x29, 0x4b, 0x81, 0x5c, 0x06, 0x06, 0xbc,
    0xc1, 0x01, 0x1c, 0xa7, 0x08, 0xf7, 0x47, 0x1f,
    0x52, 0x4f, 0xdf, 0x94, 0x1e, 0xe6, 0x89, 0xe6,
    0x26, 0x71, 0x2e, 0xa2, 0xd2, 0xfe, 0x04, 0xf2,
    0x12, 0x4c, 0x06, 0x78, 0x34, 0xc0, 0xb9, 0x76,
    0x62, 0x3b, 0x72, 0x25, 0x8c, 0x0d, 0x73, 0x24,
    0xcf, 0x4b, 0x4c, 0x47, 0x20, 0x9d, 0x04, 0x7f,
    0x86, 0x2c, 0x45, 0xb8, 0xfe, 0xb2, 0xaa, 0x36,
    0xf8, 0xe0, 0x24, 0x25, 0x05, 0x23, 0x12, 0x16,
    0xbf, 0x64, 0x10, 0xdd, 0xe4, 0xc0, 0xb0, 0x85,
    0xa7, 0xd3, 0xd1, 0x18, 0x1b, 0x81, 0x6b, 0x94,
    0xfd, 0x07, 0x43, 0xdd, 0x12, 0x37, 0x78, 0x69,
    0xec, 0x8c, 0xd0, 0x41, 0x2c, 0x42, 0x94, 0x3e,
    0x9f, 0xe3, 0x49, 0xb3, 0xb8, 0x45, 0x0b, 0x1d,
    0xc1, 0x9b, 0x4d, 0x21, 0x85, 0x62, 0xea, 0xd1,
    0xc9, 0x12, 0x30, 0x8c, 0x4b, 0x63, 0xeb, 0x7d,
    0x02, 0x52, 0x15, 0xa1, 0x95, 0x48, 0x9f, 0xc2,
    0xce, 0xf3, 0x4b, 0xff, 0x5a, 0xb6, 0x8f, 0xce,
    0xcd, 0x42, 0x21, 0x40, 0x82, 0xad, 0x08, 0x99,
    0x4d, 0x24, 0x58, 0x25, 0xf3, 0x7e, 0x42, 0x86,
    0x06, 0x33, 0x1f, 0x53, 0xbb, 0x07, 0x33, 0xca,
    0xc0, 0x02, 0x18, 0x30, 0x3c, 0xc5, 0x67, 0x1c,
    0x32, 0x3f, 0x2d, 0x58, 0x4c, 0x24, 0x6e, 0x60,
    0x96, 0x1a, 0xf4, 0xd0, 0x55, 0xb8, 0x84, 0xf0,
    0xb9, 0x83, 0xbf, 0x3d, 0x37, 0xe4, 0xa6, 0x06,
    0x1c, 0xd1, 0xd7, 0x91, 0x24, 0xdc, 0x3f, 0xcc,
    0x71, 0xf3, 0x0c, 0x90, 0x2c, 0x1d, 0x2f, 0x90,
    0xc8, 0x3c, 0x6f, 0x2c, 0x5d, 0xad, 0x8c, 0xdf,
    0xbb, 0x0d, 0x2a, 0x7f, 0x4a, 0x34, 0x5a, 0xd9,
    0x83, 0xfd, 0x61, 0x36, 0xe0, 0x0a, 0xb3, 0xf6,
    0x69, 0xb1, 0xaf, 0x81, 0x22, 0xd6, 0x9e, 0x9a,
    0xf8, 0xa6, 0x24, 0x8e, 0x0c, 0xcb, 0x25, 0xc2,
    0xfc, 0xc5, 0x94, 0xbd, 0x23, 0x9c, 0xa9, 0xbd,
    0x76, 0x28, 0xa4, 0x55, 0x92, 0x7c, 0xe6, 0x76,
    0xf7, 0x30, 0xf8, 0x7d, 0xdc, 0x0a, 0x93, 0x9e,
    0x7c, 0x39, 0x0a, 0x70, 0xa0, 0xb2, 0x77, 0xe0,
    0x7a, 0x89, 0x50, 0xce, 0x75, 0xca, 0x2f, 0xa4,
    0x12, 0x0e, 0xcb, 0x75, 0x1f, 0x0a, 0x83, 0xe8,
    0x14, 0x80, 0xa7, 0xb0, 0xe8, 0x11, 0xca, 0x12,
    0x5e, 0xf7, 0x31, 0x65, 0xbd, 0x20, 0x3d, 0x8c,
    0xa6, 0x89, 0x83, 0x68, 0x66, 0x03, 0x28, 0x49,
    0x17, 0xc4, 0x3f, 0x43, 0x02, 0x9b, 0xf8, 0xed,
    0xae, 0x8e, 0x68, 0xbc, 0x8e, 0x39, 0xe7, 0x15,
    0x32, 0x45, 0x66, 0x2c, 0x1f, 0xce, 0x56, 0xc7,
    0xc0, 0x15, 0x52, 0x19, 0x40, 0xcf, 0x87, 0x20,
    0xcd, 0x3d, 0xec, 0x90, 0x8d, 0x04, 0x01, 0x31,
    0x0b, 0x74, 0x80, 0x6e, 0x61, 0xa7, 0xf3, 0x4c,
    0xb2, 0x16, 0x00, 0xd5, 0xdb, 0xcc, 0xbb, 0x2c,
    0x9f, 0xb6, 0x02, 0x4a, 0xcf, 0x71, 0x06, 0xfd,
    0x60, 0xe0, 0x00, 0xbe, 0x22, 0xba, 0x39, 0x36,
    0xa8, 0x7e, 0xe5, 0xcb, 0xea, 0x87, 0xb1, 0xee,
    0xa2, 0x6c, 0x85, 0x94, 0x18, 0x6c, 0xab, 0x9a,
    0x93, 0xa7, 0xab, 0x4e, 0x3b, 0x85, 0xf3, 0xef,
    0x8f, 0x15, 0x74, 0x21, 0x9f, 0x5d, 0x9c, 0x22,
    0x32, 0x71, 0xb5, 0x4d, 0x7f, 0xaa, 0x85, 0xe0,
    0x05, 0x2a, 0x53, 0xbb, 0x3c, 0xab, 0xc3, 0xd2,
    0x73, 0x6e, 0x97, 0xa3, 0xfd, 0x05, 0x58, 0xaa,
    0x49, 0xc8, 0x69, 0xa9, 0x0b, 0x73, 0xd4, 0xe9,
    0x1d, 0x84, 0x60, 0x34, 0x2a, 0x09, 0xb3, 0x0f,
    0x08, 0x13, 0x67, 0x77, 0xb3, 0x24, 0xdf, 0xad,
    0xbf, 0x51, 0x71, 0x2b, 0xbe, 0x4f, 0x5d, 0xf4,
    0xe7, 0x25, 0x4c, 0x24, 0xa2, 0x4a, 0x22, 0xec,
    0xcc, 0x7c, 0x6c, 0x62, 0xee, 0x47, 0x12, 0x43,
    0x88, 0xe4, 0x71, 0xaa, 0x63, 0xaa, 0x2b, 0xed,
    0x70, 0xbf, 0x26, 0x37, 0xcc, 0xa4, 0xff, 0xe9,
    0xb6, 0x65, 0x31, 0x4d, 0x0d, 0x32, 0xd6, 0x84,
    0xb8, 0xab, 0x98, 0xa7, 0x10, 0x44, 0x77, 0xc7,
    0x2a, 0x60, 0xf0, 0xf5, 0xd5, 0xd4, 0x3a, 0x73,
    0x11, 0xa5, 0x1b, 0x18, 0x3c, 0x13, 0xfb, 0xda,
    0x76, 0x9d, 0xeb, 0x3e, 0xb9, 0x7a, 0xce, 0x02,
    0xa7, 0x5e, 0x25, 0x96, 0xd2, 0xbc, 0x85, 0x1a,
    0xd1, 0xa4, 0xe2, 0x02, 0x15, 0x08, 0x49, 0x16,
    0x7c, 0xaf, 0xc6, 0x38, 0x7b, 0x95, 0xf9, 0x37,
    0xc0, 0x87, 0x73, 0x6f, 0x01, 0xcd, 0x2b, 0xf1,
    0xe7, 0x6e, 0x47, 0x18, 0x30, 0xb8, 0x16, 0x87,
    0x1d, 0x23, 0x62, 0x22, 0x85, 0x92, 0x69, 0x46,
    0x9c, 0x65, 0xd8, 0xf1, 0x27, 0x32, 0xe4, 0x16,
    0x7f, 0x9a, 0xba, 0x46, 0x61, 0x60, 0x34, 0xe5,
    0xc0, 0x14, 0xb5, 0xde, 0x4d, 0xd1, 0x71, 0x39,
    0x26, 0xdc, 0x0c, 0x0a, 0x53, 0x9e, 0x31, 0x10,
    0x45, 0x7a, 0xf9, 0xc8, 0xfa, 0x1d, 0x69, 0x5e,
    0x25, 0xc1, 0xe2, 0x00, 0xbf, 0x94, 0xa3, 0xa2,
    0x97, 0xca, 0xb4, 0x6a, 0x89, 0x68, 0xdd, 0xed,
    0x6b, 0x99, 0x5a, 0x87, 0x9e, 0xe9, 0x68, 0xe4,
    0xf2, 0xc2, 0x7e, 0x37, 0x02, 0xdf, 0x96, 0x1a,
    0x5b, 0xed, 0xa1, 0xe8, 0xdf, 0x3c, 0xf7, 0xd2,
    0x25, 0xac, 0xf7, 0x4a, 0x7f, 0x10, 0x27, 0x2b,
    0x02, 0xc7, 0x95, 0x10, 0x5a, 0xb5, 0xb0, 0xcd,
    0xa9, 0xe1, 0x36, 0xe2, 0x1c, 0x87, 0x99, 0x0e,
    0x0a, 0x44, 0xec, 0x97, 0x75, 0xa7, 0x03, 0x27,
    0x38, 0x3b, 0x16, 0x30, 0x00, 0x98, 0xbe, 0x77,
    0xfe, 0x3a, 0xac, 0x6f, 0x8f, 0x4d, 0xe1, 0xa9,
    0x9c, 0xba, 0x39, 0x52, 0xe8, 0xf7, 0xe4, 0xe6,
    0xf9, 0xe9, 0xb3, 0x57, 0x82, 0xb2, 0x23, 0xd6,
    0xa5, 0x14, 0xc0, 0x78, 0xb4, 0xa0, 0xf9, 0x96,
    0xe4, 0x03, 0xe8, 0x6c, 0x27, 0xd8, 0x37, 0x7c,
    0x8f, 0xf4, 0x80, 0x09, 0x09, 0xc9, 0x32, 0x15,
    0xe0, 0x3f, 0x37, 0xa7, 0x1a, 0x5f, 0x8c, 0xfb,
    0xdd, 0xfe, 0x6b, 0x34, 0x28, 0x53, 0x03, 0x4b,
    0x39, 0x91, 0xf2, 0x48, 0x4c, 0x2a, 0x45, 0xfe,
    0x66, 0xf7, 0x23, 0x74, 0xb8, 0x30, 0x70, 0xb4,
    0x0c, 0x2c, 0x65, 0xb1, 0x4e, 0x32, 0x0f, 0x50,
    0xbb, 0x46, 0x9b, 0x03, 0x34, 0x38, 0xfb, 0xe4,
    0x25, 0x37, 0x8d, 0x0f, 0xa1, 0x41, 0x50, 0x85,
    0x92, 0x07, 0x71, 0xff, 0x3c, 0xe6, 0xd9, 0x1d,
    0x55, 0xb7, 0x10, 0x9c, 0xea, 0x70, 0x5f, 0xa3,
    0xba, 0x84, 0x99, 0x91, 0x30, 0x3d, 0x4c, 0x98,
    0x0b, 0x1f, 0x1f, 0xcc, 0x17, 0x94, 0xdd, 0x78,
    0x7d, 0x50, 0xe5, 0xf5, 0x21, 0x88, 0x5a, 0x52,
    0x76, 0x5a, 0x97, 0xbe, 0xba, 0xa9, 0xfe, 0x82,
    0x8a, 0xb5, 0x46, 0xcf, 0x9c, 0xbe, 0xe8, 0x2f,
    0x01, 0x2f, 0x6a, 0x03, 0x8a, 0xfa, 0x4b, 0x0b,
    0xdc, 0x78, 0x79, 0x9c, 0x49, 0xc4, 0x01, 0x26,
    0x16, 0x58, 0xc6, 0xb8, 0xee, 0x6c, 0xc9, 0xa9,
    0x38, 0x7c, 0xcf, 0xf3, 0xf8, 0xd0, 0x6b, 0x99,
    0x43, 0x13, 0xe0, 0x43, 0x8e, 0xfb, 0xb2, 0xdb,
    0x61, 0x67, 0xf4, 0xfc, 0x01, 0x21, 0xd9, 0xb1,
    0x1e, 0x6c, 0x6f, 0x2a, 0x9a, 0x4b, 0x86, 0x3c,
    0x62, 0x03, 0x53, 0x83, 0x11, 0x18, 0x1a, 0x59,
    0x9e, 0x25, 0xfe, 0xdb, 0x85, 0xd0, 0xee, 0x7c,
    0x97, 0x72, 0xca, 0xf3, 0x0d, 0xd4, 0x19, 0x66,
    0x14, 0xaf, 0x46, 0x68, 0x75, 0xdb, 0x8f, 0x5f,
    0x77, 0x7f, 0xfe, 0xa9, 0xe6, 0xa1, 0x9e, 0x46,
    0x5e, 0x92, 0xda, 0xea, 0xdd, 0x89, 0x01, 0xd9,
    0xab, 0x25, 0x7d, 0xb4, 0x64, 0x50, 0x8f, 0xa3,
    0xbe, 0xe2, 0x03, 0xd5, 0xc6, 0x9c, 0xc2, 0xf8,
    0xac, 0xa4, 0x36, 0xa9, 0x37, 0x10, 0x59, 0x00,
    0x45, 0xbb, 0x55, 0x33, 0xb9, 0x6f, 0xbc, 0xa2,
    0x02, 0x9e, 0xa3, 0x1d, 0xf4, 0x17, 0x78, 0x9b,
    0xbc, 0x42, 0x4e, 0x21, 0xc3, 0xde, 0xb5, 0x70,
    0x4a, 0x23, 0x1e, 0xd4, 0x36, 0x5d, 0x7a, 0x08,
    0x37, 0x55, 0x98, 0x07, 0xa0, 0x16, 0xa3, 0x4e,
    0xa1, 0x2b, 0x96, 0x8b, 0x51, 0x63, 0x48, 0xab,
    0xc9, 0x19, 0x6f, 0x5f, 0x25, 0x9d, 0xe7, 0x25,
    0x63, 0xf0, 0x8e, 0xdb, 0x06, 0x2d, 0x42, 0x31,
    0xfd, 0x14, 0x2b, 0x7a, 0x31, 0x43, 0x04, 0xd5,
    0xe2, 0x89, 0x2e, 0xa8, 0xe4, 0x6e, 0xd5, 0xa5,
    0x21, 0x67, 0x9b, 0x92, 0x61, 0x79, 0xdd, 0xe5,
    0x44, 0x43, 0x45, 0x57, 0x13, 0xec, 0x04, 0xc1,
    0x41, 0xa3, 0x14, 0x70, 0x86, 0xda, 0x76, 0x5d,
    0xe8, 0x61, 0xd2, 0xfb, 0x7b, 0xe4, 0x71, 0x46,
    0xa3, 0x52, 0xbf, 0xf2, 0xa0, 0x3c, 0xc1, 0x90,
    0x0c, 0x2e, 0xeb, 0xb3, 0x38, 0xae, 0x13, 0x27,
    0x84, 0xe9, 0x7a, 0xd6, 0x02, 0x40, 0x84, 0xff,
    0x87, 0x1f, 0x37, 0x44, 0xd8, 0x2e, 0x93, 0xf7,
    0x0a, 0xff, 0x5b, 0x4d, 0x07, 0x82, 0xfd, 0x6e,
    0x44, 0xcc, 0x19, 0xc3, 0x7d, 0x7c, 0x31, 0xf9,
    0x0e, 0xa8, 0x1c, 0x0d, 0xcb, 0x8e, 0xe8, 0x33,
    0xb2, 0xff, 0x9e, 0x1d, 0x99, 0x7c, 0x46, 0x5b,
    0xc7, 0x28, 0xec, 0x01, 0x62, 0x82, 0xfe, 0x2a,
    0x22, 0xa3, 0x86, 0x4e, 0x47, 0xe2, 0x57, 0xf1,
    0xb4, 0x58, 0x94, 0x89, 0xe5, 0xf1, 0xcd, 0x4d,
    0x90, 0xd1, 0xa4, 0x4c, 0x34, 0x5d, 0xde, 0xdc,
    0x39, 0x63, 0x8b, 0x85, 0xfd, 0x02, 0x21, 0xf1,
    0x12, 0xa3, 0x6d, 0x65, 0x0f, 0x8d, 0xe5, 0xcd,
    0x70, 0xd5, 0x1d, 0xf8, 0x65, 0x99, 0xfb, 0xe8,
    0xb5, 0x5a, 0x09, 0x39, 0x9e, 0x09, 0x45, 0x62,
    0x22, 0x1d, 0xa2, 0x46, 0xbf, 0x75, 0x20, 0xd1,
    0xe7, 0xb0, 0x06, 0x68, 0xc3, 0x50, 0x48, 0xfc,
    0xf8, 0x5c, 0x67, 0x69, 0x68, 0x66, 0xb6, 0x81,
    0x95, 0x91, 0x81, 0x3d, 0xf6, 0x34, 0xd9, 0x4b,
    0x06, 0x35, 0x17, 0x59, 0x89, 0x18, 0x74, 0x32,
    0x50, 0xcf, 0x81, 0x16, 0x8e, 0x53, 0x9d, 0x1c,
    0xad, 0x2d, 0x8e, 0x16, 0x41, 0xda, 0xca, 0xab,
    0x78, 0x0d, 0xc9, 0x49, 0x61, 0xaa, 0x18, 0xf4,
    0x56, 0x48, 0x29, 0x8c, 0xe3, 0x9a, 0x7d, 0x58,
    0xf8, 0x99, 0x72, 0xf1, 0x78, 0xa8, 0x5a, 0x97,
    0xe3, 0x2a, 0xc6, 0xa9, 0x59, 0xde, 0xcc, 0x62,
    0xfb, 0xab, 0xc5, 0x9a, 0x0b, 0xc7, 0x16, 0x8f,
    0x18, 0x20, 0x6e, 0x01, 0x7e, 0x04, 0xef, 0x72,
    0x83, 0x61, 0xb8, 0x1a, 0x77, 0x0f, 0xd1, 0xa9,
    0x75, 0xe0, 0x4a, 0x11, 0x69, 0x9d, 0xb6, 0xc9,
    0x2e, 0xd3, 0xbf, 0xe2, 0x5b, 0x24, 0x77, 0x30,
    0x85, 0x91, 0xef, 0xa8, 0x93, 0x4e, 0xad, 0x99,
    0xad, 0xcb, 0x6d, 0x9d, 0x8f, 0xd8, 0x0f, 0xe5,
    0x41, 0xd9, 0x9e, 0x0b, 0xce, 0x33, 0xd9, 0xbb,
    0x87, 0x66, 0x2c, 0xa3, 0x0b, 0x68, 0x1b, 0xb0,
    0x71, 0x30, 0xfa, 0x15, 0x2e, 0xe8, 0xc1, 0x99,
    0x71, 0x01, 0xcc, 0xdb, 0x6f, 0x9f, 0x8a, 0xfd,
    0xb4, 0x0f, 0x35, 0xa1, 0x36, 0xf4, 0x3a, 0xc4,
    0x17, 0x77, 0x43, 0x60, 0x10, 0x18, 0xb4, 0xc2,
    0xe5, 0xc0, 0x64, 0xd8, 0x38, 0x7c, 0x05, 0x9a,
    0xfb, 0x2b, 0xb3, 0x9b, 0x9e, 0x34, 0x6b, 0x4b,
    0xc8, 0x3b, 0x77, 0xe0, 0x6f, 0x08, 0xa1, 0x7b,
    0x66, 0x69, 0x2f, 0xdb, 0x34, 0x9e, 0x98, 0x90,
    0x5b, 0x4d, 0x7b, 0xa2, 0x32, 0x8e, 0x64, 0xe6,
    0x0d, 0x75, 0xc9, 0x96, 0xe3, 0x57, 0xba, 0xad,
    0x3e, 0x3b, 0x23, 0xfb, 0x9e, 0x7f, 0xc0, 0x3c,
    0xd5, 0x41, 0x9c, 0xfb, 0xbc, 0xb3, 0x52, 0x49
#endif
};
#endif
#endif

static int test_wc_dilithium_public_der_decode(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    defined(WOLFSSL_DILITHIUM_PUBLIC_KEY)
    dilithium_key* key;
    word32 idx = 0;

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }

    ExpectIntEQ(wc_dilithium_init(key), 0);
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
#else
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
#endif
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(ml_dsa_public_der, &idx, key,
        (word32)sizeof(ml_dsa_public_der)), 0);
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
    idx = 0;
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44_DRAFT), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65_DRAFT), 0);
#else
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87_DRAFT), 0);
#endif
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(dilithium_public_der, &idx, key,
        (word32)sizeof(dilithium_public_der)), 0);
#endif

    wc_dilithium_free(key);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_dilithium_der(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    !defined(WOLFSSL_DILITHIUM_NO_ASN1) && \
    !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY)
#define DILITHIUM_MAX_DER_SIZE    8192
    dilithium_key* key;
    WC_RNG rng;
    byte* der = NULL;
    int len;
    int pubLen;
    int pubDerLen;
    int privDerLen;
    int keyDerLen;
    word32 idx;

#ifndef WOLFSSL_NO_ML_DSA_44
    pubLen = DILITHIUM_LEVEL2_PUB_KEY_SIZE;
    pubDerLen = DILITHIUM_LEVEL2_PUB_KEY_SIZE + 22;
    privDerLen = DILITHIUM_LEVEL2_KEY_SIZE + 28;
    keyDerLen = DILITHIUM_LEVEL2_PUB_KEY_SIZE + DILITHIUM_LEVEL2_KEY_SIZE + 32;
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    pubLen = DILITHIUM_LEVEL3_PUB_KEY_SIZE;
    pubDerLen = DILITHIUM_LEVEL3_PUB_KEY_SIZE + 22;
    privDerLen = DILITHIUM_LEVEL3_KEY_SIZE + 28;
    keyDerLen = DILITHIUM_LEVEL3_PUB_KEY_SIZE + DILITHIUM_LEVEL3_KEY_SIZE + 32;
#else
    pubLen = DILITHIUM_LEVEL5_PUB_KEY_SIZE;
    pubDerLen = DILITHIUM_LEVEL5_PUB_KEY_SIZE + 22;
    privDerLen = DILITHIUM_LEVEL5_KEY_SIZE + 28;
    keyDerLen = DILITHIUM_LEVEL5_PUB_KEY_SIZE + DILITHIUM_LEVEL5_KEY_SIZE + 32;
#endif

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);
    der = (byte*)XMALLOC(DILITHIUM_MAX_DER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(der);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_dilithium_init(key), 0);

    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key, der, DILITHIUM_MAX_DER_SIZE,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key, der, DILITHIUM_MAX_DER_SIZE,
        1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key, der, DILITHIUM_MAX_DER_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(der, &idx, key, pubDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &idx, key, privDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
#elif !defined(WOLFSSL_NO_ML_DSA_65)
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
#else
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
#endif

    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key, der, DILITHIUM_MAX_DER_SIZE,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key, der, DILITHIUM_MAX_DER_SIZE,
        1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key, der, DILITHIUM_MAX_DER_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_dilithium_make_key(key, &rng), 0);

    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(NULL, NULL, 0                     ,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(NULL, der , 0                     ,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(NULL, NULL, DILITHIUM_MAX_DER_SIZE,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(NULL, der , DILITHIUM_MAX_DER_SIZE,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key , der , 0                     ,
        0), WC_NO_ERR_TRACE(BUFFER_E));
    /* Get length only. */
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key , NULL, 0                     ,
        0), pubLen);
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key , NULL, DILITHIUM_MAX_DER_SIZE,
        0), pubLen);
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key , NULL, 0                     ,
        1), pubDerLen);
    ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key , NULL, DILITHIUM_MAX_DER_SIZE,
        1), pubDerLen);

    ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, NULL,
        0                     ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntGT(wc_Dilithium_PrivateKeyToDer(key , NULL,
        0                     ), 0);
    ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, der ,
        0                     ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, NULL,
        DILITHIUM_MAX_DER_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, der ,
        DILITHIUM_MAX_DER_SIZE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key , der ,
        0                     ), WC_NO_ERR_TRACE(BUFFER_E));
    /* Get length only. */
    ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key , NULL,
        DILITHIUM_MAX_DER_SIZE), privDerLen);

    ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, NULL, 0                     ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntGT(wc_Dilithium_KeyToDer(key , NULL, 0                     ),
        0           );
    ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, der , 0                     ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, NULL, DILITHIUM_MAX_DER_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, der , DILITHIUM_MAX_DER_SIZE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_KeyToDer(key , der , 0                     ),
        WC_NO_ERR_TRACE(BUFFER_E));
    /* Get length only. */
    ExpectIntEQ(wc_Dilithium_KeyToDer(key , NULL, DILITHIUM_MAX_DER_SIZE),
        keyDerLen);

    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(NULL, NULL, NULL, 0        ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(der , NULL, NULL, 0        ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(NULL, &idx, NULL, 0        ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(NULL, NULL, key , 0        ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(NULL, NULL, NULL, pubDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(NULL, &idx, key , pubDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(der , NULL, key , pubDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(der , &idx, NULL, pubDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(der , &idx, key , 0        ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(NULL, NULL, NULL, 0         ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der , NULL, NULL, 0         ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(NULL, &idx, NULL, 0         ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(NULL, NULL, key , 0         ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(NULL, NULL, NULL, privDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(NULL, &idx, key , privDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der , NULL, key , privDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der , &idx, NULL, privDerLen),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der , &idx, key , 0         ),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(len = wc_Dilithium_PublicKeyToDer(key, der,
        DILITHIUM_MAX_DER_SIZE, 0), pubLen);
    ExpectIntEQ(wc_dilithium_import_public(der, len, key), 0);

    ExpectIntEQ(len = wc_Dilithium_PublicKeyToDer(key, der,
        DILITHIUM_MAX_DER_SIZE, 1), pubDerLen);
    idx = 0;
    ExpectIntEQ(wc_Dilithium_PublicKeyDecode(der, &idx, key, len), 0);

    ExpectIntEQ(len = wc_Dilithium_PrivateKeyToDer(key, der,
        DILITHIUM_MAX_DER_SIZE), privDerLen);
    idx = 0;
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &idx, key, len), 0);

    ExpectIntEQ(len = wc_Dilithium_KeyToDer(key, der, DILITHIUM_MAX_DER_SIZE),
        keyDerLen);
    idx = 0;
    ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &idx, key, len), 0);


    wc_dilithium_free(key);
    wc_FreeRng(&rng);

    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_dilithium_make_key_from_seed(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY)
    dilithium_key* key;
#ifndef WOLFSSL_NO_ML_DSA_44
    static const byte seed_44[] = {
        0x93, 0xEF, 0x2E, 0x6E, 0xF1, 0xFB, 0x08, 0x99,
        0x9D, 0x14, 0x2A, 0xBE, 0x02, 0x95, 0x48, 0x23,
        0x70, 0xD3, 0xF4, 0x3B, 0xDB, 0x25, 0x4A, 0x78,
        0xE2, 0xB0, 0xD5, 0x16, 0x8E, 0xCA, 0x06, 0x5F
    };
    static const byte pk_44[] = {
        0xBC, 0x5F, 0xF8, 0x10, 0xEB, 0x08, 0x90, 0x48,
        0xB8, 0xAB, 0x30, 0x20, 0xA7, 0xBD, 0x3B, 0x16,
        0xC0, 0xE0, 0xCA, 0x3D, 0x6B, 0x97, 0xE4, 0x64,
        0x6C, 0x2C, 0xCA, 0xE0, 0xBB, 0xF1, 0x9E, 0xF7,
        0x23, 0x0A, 0x19, 0xD7, 0x5A, 0xDB, 0xDE, 0xD5,
        0x2D, 0xB8, 0x55, 0xE2, 0x52, 0xA7, 0x19, 0xFC,
        0xBD, 0x14, 0x7B, 0xA6, 0x7B, 0x2F, 0xAD, 0x14,
        0xED, 0x0E, 0x68, 0xFD, 0xFE, 0x8C, 0x65, 0xBA,
        0xDE, 0xAC, 0xB0, 0x91, 0x11, 0x93, 0xAD, 0xFA,
        0x87, 0x94, 0xD7, 0x8F, 0x8E, 0x3D, 0x66, 0x2A,
        0x1C, 0x49, 0xDA, 0x81, 0x9F, 0xD9, 0x59, 0xE7,
        0xF0, 0x78, 0xF2, 0x03, 0xC4, 0x56, 0xF8, 0xB6,
        0xE7, 0xC9, 0x41, 0x58, 0x98, 0xE5, 0x41, 0xC7,
        0x30, 0x32, 0xDB, 0xD6, 0x19, 0xEA, 0xF6, 0x0F,
        0x8D, 0x64, 0xF8, 0x68, 0x3D, 0xA9, 0x9E, 0xCA,
        0x51, 0x22, 0x0B, 0x0A, 0xCA, 0x28, 0x46, 0x40,
        0x99, 0xF5, 0x47, 0xC0, 0x27, 0x77, 0xBD, 0x37,
        0xD8, 0x4A, 0x59, 0xBD, 0x37, 0xED, 0x7A, 0x8A,
        0x92, 0x63, 0x3C, 0x75, 0xD0, 0x7C, 0x79, 0x3F,
        0xE7, 0x25, 0x2B, 0x58, 0x4A, 0xBF, 0x6A, 0x15,
        0xEE, 0x14, 0x50, 0x7E, 0x5E, 0x19, 0x3F, 0x89,
        0x86, 0x4D, 0x09, 0xAC, 0x87, 0x27, 0xA6, 0xD0,
        0x42, 0x1F, 0x0C, 0x19, 0xF0, 0xE2, 0xFB, 0xFC,
        0x21, 0x3D, 0x3F, 0xBD, 0x70, 0xF4, 0xF9, 0x76,
        0x2C, 0xEC, 0xFF, 0x23, 0x1E, 0x9C, 0x8A, 0x76,
        0x28, 0xD3, 0xF8, 0xB0, 0x85, 0x7B, 0x03, 0x2D,
        0x32, 0xDE, 0x62, 0xFF, 0x8E, 0xCB, 0xF4, 0x00,
        0x82, 0x89, 0xBF, 0x34, 0x40, 0x36, 0x65, 0xF8,
        0x1A, 0x08, 0x1A, 0xD5, 0xA8, 0x5A, 0x28, 0x2F,
        0x99, 0xBA, 0xB9, 0xE5, 0x38, 0x5A, 0xFB, 0xCC,
        0xCF, 0x44, 0xB7, 0x4C, 0x01, 0x96, 0xC7, 0x54,
        0x55, 0x27, 0xEC, 0x30, 0x26, 0xDA, 0x12, 0x80,
        0xC4, 0xEB, 0x37, 0xD0, 0x9C, 0xFE, 0x3E, 0xC4,
        0xB4, 0x91, 0x0B, 0x62, 0xEB, 0x98, 0x15, 0xA4,
        0x25, 0xC6, 0x59, 0x0F, 0xC4, 0xAD, 0x3F, 0xBB,
        0x22, 0x57, 0x52, 0xCC, 0x1F, 0xC5, 0x69, 0x3F,
        0x18, 0x7E, 0x7D, 0xEC, 0x4E, 0xEF, 0xBE, 0xB6,
        0xB9, 0x1B, 0xD9, 0x1C, 0x5E, 0x2E, 0xA6, 0xA9,
        0x1D, 0x14, 0xD0, 0x97, 0xBE, 0x20, 0x3F, 0xBA,
        0x0B, 0xF9, 0x37, 0xC9, 0x75, 0x07, 0xDC, 0x00,
        0x7C, 0x4C, 0xAA, 0x9B, 0x07, 0x85, 0x89, 0x29,
        0x66, 0xFF, 0x15, 0x90, 0x09, 0x24, 0xE5, 0x79,
        0xD4, 0xFB, 0xA0, 0x2B, 0xDA, 0x87, 0x55, 0x5F,
        0x07, 0x3D, 0xAE, 0x00, 0x51, 0x3E, 0x70, 0x80,
        0x9A, 0xBB, 0xC7, 0x11, 0xFB, 0xA2, 0xE7, 0x64,
        0x95, 0x77, 0xC4, 0x2A, 0xFD, 0xC2, 0x4B, 0xF7,
        0x41, 0x3E, 0x51, 0x26, 0x8A, 0xD6, 0xDB, 0x61,
        0x13, 0xB7, 0xD9, 0x19, 0x1A, 0xF9, 0xD0, 0x61,
        0xDB, 0xDE, 0xD5, 0xD6, 0x30, 0x87, 0x76, 0x50,
        0xC1, 0x24, 0xF1, 0x1B, 0xC4, 0xBD, 0xC3, 0xFD,
        0xC6, 0xA9, 0x00, 0xF6, 0x31, 0x26, 0xF9, 0x21,
        0xE8, 0x38, 0xAD, 0x0C, 0x22, 0x75, 0xA3, 0x38,
        0x9A, 0x39, 0xBD, 0x99, 0xA1, 0x34, 0x50, 0x45,
        0x50, 0x10, 0x1C, 0xD3, 0xE9, 0x5E, 0x6D, 0x14,
        0x96, 0xBE, 0x7D, 0xE6, 0x62, 0x7D, 0xF4, 0xFD,
        0x6C, 0x28, 0xBB, 0xF4, 0x0B, 0x30, 0xEF, 0xA9,
        0xB5, 0xC3, 0xD5, 0xC8, 0x5A, 0xB1, 0x4A, 0x65,
        0xC0, 0x2D, 0x6D, 0x47, 0x81, 0xFF, 0x13, 0xD3,
        0x28, 0x60, 0x85, 0x54, 0xB6, 0xD1, 0x5E, 0xD9,
        0x12, 0x89, 0xA6, 0xD5, 0x5A, 0xAC, 0x0C, 0x38,
        0xE3, 0x77, 0x06, 0xF7, 0x35, 0x5E, 0x9A, 0x4F,
        0xDA, 0x61, 0x5B, 0x87, 0x59, 0x26, 0xBF, 0xE5,
        0xA5, 0x9D, 0x9E, 0xF2, 0x73, 0xBF, 0x94, 0xA0,
        0x7C, 0xFA, 0x57, 0x31, 0x78, 0xF0, 0xE0, 0x04,
        0xB6, 0xE1, 0xEF, 0x0A, 0x83, 0x49, 0xE9, 0xBC,
        0xC0, 0x19, 0x81, 0xF2, 0x46, 0x0F, 0x0A, 0x27,
        0x43, 0xC2, 0x8D, 0x1E, 0x13, 0x8F, 0xFB, 0x76,
        0x5E, 0x7E, 0x33, 0x97, 0xB7, 0x91, 0x33, 0x35,
        0xD4, 0x02, 0xFE, 0x91, 0x80, 0x6A, 0xA8, 0xFC,
        0x81, 0x92, 0x53, 0xAF, 0x32, 0x69, 0x2F, 0xA6,
        0x51, 0xE8, 0x67, 0xF5, 0x90, 0x7E, 0xF4, 0x6F,
        0x00, 0x62, 0x5A, 0x03, 0x0E, 0xC9, 0x04, 0xED,
        0xAB, 0x21, 0x42, 0x6D, 0x59, 0x11, 0x9D, 0x2C,
        0xAA, 0x43, 0xBD, 0x93, 0x5D, 0xEC, 0x0A, 0x55,
        0x0C, 0x61, 0xEE, 0x4B, 0x27, 0x9C, 0x1C, 0xA3,
        0xA7, 0x9C, 0x79, 0xA6, 0x6E, 0x3F, 0x2D, 0x2F,
        0xAD, 0xB0, 0x0F, 0x59, 0xA3, 0xA4, 0x38, 0xAA,
        0x44, 0x57, 0x01, 0x06, 0x07, 0x30, 0x17, 0xFA,
        0x1C, 0x87, 0x57, 0x50, 0x01, 0x09, 0x72, 0x0D,
        0x12, 0x5B, 0xBA, 0x23, 0x1A, 0x0C, 0x36, 0x35,
        0x0C, 0x78, 0x08, 0x6D, 0xFD, 0xC8, 0xD6, 0x13,
        0xAE, 0xCA, 0x88, 0xC4, 0xCC, 0xAE, 0xB4, 0xA4,
        0x4D, 0x13, 0xAD, 0xB3, 0xC7, 0x17, 0xD6, 0x5C,
        0x82, 0xA3, 0x51, 0xB9, 0xB6, 0xEA, 0xBF, 0x6A,
        0x10, 0xF4, 0xB4, 0xE9, 0x62, 0x3E, 0x3A, 0x95,
        0xB4, 0xD4, 0x0A, 0x12, 0xA8, 0x18, 0xAC, 0x6B,
        0x38, 0x22, 0xDB, 0x82, 0xFB, 0x05, 0xDC, 0x42,
        0x02, 0x64, 0x8B, 0x44, 0x54, 0x68, 0x9A, 0xEB,
        0x69, 0xEA, 0x32, 0x5F, 0x03, 0xE3, 0x5D, 0xEF,
        0xA5, 0x47, 0x08, 0x48, 0x14, 0x20, 0xC6, 0xD6,
        0x97, 0xBB, 0x91, 0x2F, 0xCA, 0x0D, 0x3F, 0x19,
        0x2E, 0xF2, 0x97, 0xDF, 0xE7, 0x7F, 0xF3, 0x6B,
        0x21, 0x03, 0xF1, 0xAD, 0x1A, 0xEE, 0xCE, 0xD1,
        0xC8, 0x14, 0xC2, 0xCD, 0x7E, 0xF1, 0x6B, 0xCE,
        0x47, 0x6A, 0xD0, 0x4F, 0x94, 0x1A, 0xFC, 0x79,
        0xE3, 0x29, 0x54, 0x74, 0xA4, 0x10, 0x62, 0x51,
        0x8C, 0x00, 0x37, 0x86, 0x09, 0x34, 0xF0, 0xE5,
        0xE6, 0x52, 0xF7, 0x27, 0x49, 0xA6, 0x98, 0x63,
        0x2A, 0x09, 0x91, 0xF6, 0x13, 0xF5, 0xCB, 0x96,
        0xCA, 0x11, 0x78, 0xF9, 0x74, 0xF2, 0xC4, 0xAA,
        0x0C, 0xE6, 0x3D, 0xC2, 0x4E, 0x36, 0x4C, 0x92,
        0xA6, 0x43, 0xB9, 0x0A, 0x5F, 0x85, 0xA6, 0x2F,
        0xD4, 0xD8, 0xD2, 0xB1, 0x93, 0xD2, 0x9B, 0x18,
        0xBE, 0xDE, 0x26, 0x53, 0xFC, 0x5D, 0x3F, 0x24,
        0xF5, 0xB2, 0xC0, 0x18, 0xDB, 0xBC, 0xB6, 0xEF,
        0x00, 0xF3, 0x05, 0xBF, 0x93, 0x66, 0x6B, 0xD4,
        0x7F, 0xEA, 0x91, 0x93, 0xBC, 0x23, 0x3D, 0xB3,
        0x91, 0x21, 0x44, 0x2E, 0x93, 0x8D, 0xA5, 0xDD,
        0x07, 0xEE, 0x6E, 0x87, 0x9C, 0x5B, 0x9D, 0xFF,
        0x41, 0xEC, 0xEE, 0x5E, 0x05, 0x89, 0xAE, 0x61,
        0x75, 0xFF, 0x5E, 0xC6, 0xF6, 0xD2, 0x62, 0x9F,
        0x56, 0xB1, 0x8B, 0x4D, 0xE6, 0x6F, 0xCB, 0x13,
        0xDF, 0x04, 0x00, 0xA7, 0x97, 0xC9, 0x22, 0x70,
        0xF6, 0x9B, 0xDE, 0xBD, 0xDC, 0xB8, 0x8C, 0x42,
        0x48, 0x91, 0x9B, 0x56, 0xCD, 0xA7, 0x0B, 0x8A,
        0xC4, 0xF9, 0x42, 0x9C, 0x29, 0x2D, 0xA9, 0x4D,
        0x64, 0x78, 0x28, 0x07, 0x64, 0xFE, 0x23, 0x86,
        0xFC, 0x38, 0xCB, 0x09, 0x31, 0x45, 0x88, 0x39,
        0xEF, 0x4E, 0x7D, 0xE8, 0xF0, 0x68, 0x9D, 0x99,
        0x80, 0x59, 0x88, 0xC7, 0xF9, 0x61, 0x11, 0x85,
        0x2C, 0x89, 0x29, 0xE5, 0xA5, 0x40, 0xD3, 0xB7,
        0x8D, 0x71, 0x2D, 0xEC, 0xC3, 0x96, 0xFE, 0xF3,
        0xEC, 0x34, 0x40, 0x21, 0x84, 0xE4, 0xFD, 0x29,
        0xF3, 0x63, 0xEA, 0x80, 0xF6, 0xFC, 0x50, 0xBA,
        0x9A, 0x11, 0x35, 0x1A, 0xCE, 0xEA, 0x8F, 0xE6,
        0x8D, 0x54, 0x1E, 0x1A, 0xA5, 0x84, 0x8D, 0x9F,
        0x6E, 0x61, 0xDF, 0xB6, 0x2B, 0x2F, 0x23, 0xBC,
        0x50, 0x81, 0xE8, 0x2F, 0x76, 0x22, 0x6E, 0x03,
        0x28, 0x49, 0x82, 0xEC, 0x48, 0x48, 0x12, 0x09,
        0xB1, 0xA7, 0xD4, 0xC8, 0x79, 0x7E, 0x44, 0xBF,
        0xA8, 0x70, 0xB2, 0x20, 0x04, 0xDB, 0x74, 0xBD,
        0x7D, 0x47, 0x8D, 0x5B, 0x36, 0x14, 0xD2, 0xB1,
        0xDA, 0x75, 0x02, 0xB3, 0x98, 0xEB, 0x9D, 0xA8,
        0x0D, 0x06, 0x46, 0x1E, 0x90, 0xE0, 0x30, 0x60,
        0x44, 0x6A, 0xB4, 0xA8, 0x23, 0x84, 0x32, 0xBF,
        0xAF, 0x75, 0x2F, 0x39, 0x17, 0x91, 0x21, 0x4F,
        0x1E, 0x6B, 0x63, 0x59, 0x0D, 0x53, 0x60, 0x60,
        0xD1, 0xC2, 0x45, 0x30, 0x7B, 0xC5, 0xC1, 0xBA,
        0xC4, 0xAA, 0xA0, 0x99, 0xD3, 0x6B, 0xB6, 0xDC,
        0xBC, 0x97, 0x3C, 0xF2, 0xE6, 0x9F, 0x27, 0x34,
        0xD0, 0xF2, 0x9A, 0xEE, 0xC4, 0x56, 0x7B, 0x99,
        0xA1, 0x6B, 0xC1, 0x7C, 0x6C, 0xDD, 0xAC, 0xEF,
        0xE4, 0x99, 0x27, 0xFB, 0x14, 0xE7, 0xD9, 0x8D,
        0xD4, 0x26, 0x35, 0x19, 0x46, 0x9C, 0xCA, 0x3D,
        0xB4, 0x67, 0x9A, 0x68, 0xCE, 0xED, 0xA9, 0x55,
        0x59, 0x22, 0x10, 0xFC, 0x49, 0xAA, 0x5F, 0xBE,
        0x93, 0x4C, 0xC7, 0x3D, 0x84, 0xE4, 0xBA, 0x54,
        0x78, 0x00, 0x2D, 0x68, 0x90, 0x98, 0x90, 0x68,
        0xEF, 0x8F, 0xC9, 0x8C, 0x25, 0x32, 0xB8, 0x3B,
        0xF3, 0xCB, 0x9E, 0xF0, 0x28, 0x93, 0xC2, 0x15,
        0x24, 0x26, 0xB9, 0xD1, 0xA9, 0x47, 0x34, 0xDF,
        0xB4, 0xF9, 0x11, 0x35, 0x14, 0x3C, 0x9E, 0xED,
        0x18, 0xFD, 0x51, 0xAE, 0x87, 0x5D, 0x07, 0xA2,
        0x37, 0x75, 0x60, 0x6A, 0x73, 0x4F, 0xBA, 0x98,
        0xC0, 0x63, 0xB4, 0xA1, 0x62, 0x2E, 0x7F, 0xF2,
        0x1A, 0xA7, 0xE6, 0x52, 0xA3, 0xD6, 0xC1, 0x9F,
        0xE0, 0xDC, 0x67, 0x61, 0xB7, 0xD3, 0x53, 0x02,
        0xBF, 0x21, 0x4D, 0x30, 0x79, 0xF7, 0x60, 0x51,
        0x08, 0x2A, 0x87, 0x59, 0x29, 0x92, 0x0D, 0xC3,
        0xB3, 0xCB, 0x43, 0x21, 0x1A, 0x23, 0xA4, 0x3A,
        0x50, 0x33, 0x2F, 0xAF, 0x1A, 0xC2, 0x19, 0x1E,
        0x71, 0x71, 0x25, 0xF6, 0x3E, 0x25, 0x86, 0xC4,
        0xD8, 0x6D, 0xCA, 0x6B, 0xCD, 0x3D, 0x03, 0x8F,
        0x9D, 0x3A, 0x7B, 0x66, 0xCB, 0xC7, 0xDF, 0x34
    };
    static const byte sk_44[] = {
        0xBC, 0x5F, 0xF8, 0x10, 0xEB, 0x08, 0x90, 0x48,
        0xB8, 0xAB, 0x30, 0x20, 0xA7, 0xBD, 0x3B, 0x16,
        0xC0, 0xE0, 0xCA, 0x3D, 0x6B, 0x97, 0xE4, 0x64,
        0x6C, 0x2C, 0xCA, 0xE0, 0xBB, 0xF1, 0x9E, 0xF7,
        0xBA, 0x2B, 0x57, 0xC4, 0x46, 0x55, 0x6E, 0xE2,
        0xB7, 0x2C, 0x78, 0xB9, 0x6B, 0xB7, 0xA8, 0x50,
        0x3D, 0xE4, 0x0A, 0xFB, 0x54, 0x18, 0x4E, 0x3B,
        0x54, 0x63, 0xC2, 0x1A, 0xF7, 0x48, 0x53, 0x23,
        0xDF, 0x98, 0xF0, 0x16, 0x0A, 0xE5, 0xD1, 0x37,
        0x51, 0x27, 0x25, 0xF8, 0x9D, 0x56, 0x3B, 0xC9,
        0xA1, 0x89, 0xD3, 0x1D, 0x20, 0xB3, 0xB3, 0xC8,
        0xFF, 0xAA, 0xF5, 0xE4, 0x86, 0xE7, 0x90, 0x51,
        0xF6, 0xF3, 0x60, 0x5C, 0xCA, 0x25, 0x69, 0xFD,
        0xB4, 0x6B, 0x33, 0x18, 0xD2, 0x38, 0x42, 0xCE,
        0x40, 0xD6, 0x43, 0x86, 0x13, 0xF6, 0x8B, 0x45,
        0x5B, 0x0D, 0x3B, 0xCA, 0x0E, 0x05, 0x0D, 0x4D,
        0x11, 0x99, 0x88, 0xA2, 0xC4, 0x80, 0x1B, 0x90,
        0x84, 0xE0, 0xB0, 0x48, 0xC9, 0x28, 0x09, 0x22,
        0x30, 0x90, 0x24, 0x06, 0x49, 0x98, 0x40, 0x65,
        0x5A, 0x26, 0x8A, 0xDA, 0x32, 0x90, 0xDA, 0x48,
        0x08, 0x22, 0x81, 0x90, 0xC8, 0x14, 0x61, 0xDC,
        0x16, 0x6A, 0x21, 0x47, 0x8E, 0x08, 0xB2, 0x21,
        0xE3, 0x08, 0x68, 0x1A, 0x02, 0x44, 0x14, 0xC6,
        0x65, 0xE1, 0x98, 0x71, 0x90, 0xC6, 0x69, 0x0C,
        0x15, 0x44, 0xC9, 0xA0, 0x11, 0xCC, 0x34, 0x71,
        0x83, 0x40, 0x45, 0x00, 0x12, 0x4D, 0x91, 0x08,
        0x00, 0x83, 0x36, 0x84, 0x12, 0x85, 0x4C, 0xCC,
        0x00, 0x41, 0x09, 0x90, 0x70, 0x18, 0x95, 0x00,
        0xA2, 0xB2, 0x85, 0x94, 0x26, 0x41, 0x0B, 0x00,
        0x41, 0x0A, 0xB9, 0x80, 0xC0, 0xC6, 0x10, 0x0C,
        0x33, 0x29, 0xA3, 0xA6, 0x28, 0x1C, 0x26, 0x10,
        0x1A, 0x37, 0x49, 0x13, 0x35, 0x8A, 0x0B, 0x29,
        0x2E, 0x82, 0xA2, 0x70, 0x8B, 0x38, 0x49, 0x94,
        0x04, 0x80, 0x9B, 0x26, 0x10, 0xA4, 0x80, 0x30,
        0x04, 0x37, 0x0C, 0x48, 0xB2, 0x60, 0x04, 0x17,
        0x2E, 0x19, 0x49, 0x64, 0xC8, 0xC4, 0x64, 0x1A,
        0x96, 0x60, 0x10, 0x83, 0x6D, 0x20, 0x38, 0x22,
        0x49, 0x06, 0x08, 0x1B, 0xB7, 0x20, 0x01, 0x48,
        0x4D, 0xE1, 0x10, 0x49, 0x08, 0x38, 0x44, 0x4C,
        0x16, 0x8E, 0x04, 0xB2, 0x2C, 0x09, 0x91, 0x50,
        0x83, 0x36, 0x06, 0x5C, 0x02, 0x8C, 0x8A, 0x38,
        0x05, 0x1A, 0xB5, 0x81, 0x82, 0xC0, 0x09, 0x51,
        0x12, 0x72, 0x22, 0x10, 0x0D, 0x04, 0x08, 0x2A,
        0xA4, 0x84, 0x10, 0x58, 0x08, 0x52, 0x08, 0x26,
        0x0A, 0x02, 0xB6, 0x2D, 0x8A, 0x12, 0x0E, 0x14,
        0x22, 0x10, 0x48, 0x44, 0x0A, 0x14, 0x23, 0x91,
        0x50, 0x40, 0x90, 0x0A, 0x27, 0x92, 0xA4, 0xB0,
        0x60, 0x08, 0x84, 0x11, 0xC4, 0x40, 0x22, 0x63,
        0x46, 0x2A, 0xDA, 0xA6, 0x90, 0xC1, 0xB2, 0x30,
        0x50, 0x10, 0x00, 0xA0, 0xB4, 0x6C, 0x53, 0xB4,
        0x50, 0x13, 0x05, 0x8D, 0x02, 0x31, 0x0E, 0x08,
        0x20, 0x10, 0x91, 0xC8, 0x4C, 0x22, 0xA7, 0x50,
        0xC2, 0xA6, 0x70, 0x92, 0x46, 0x41, 0x63, 0x16,
        0x8C, 0x84, 0x00, 0x11, 0x0B, 0x81, 0x90, 0x13,
        0x83, 0x71, 0x21, 0x85, 0x30, 0x1B, 0x18, 0x46,
        0xA3, 0x10, 0x84, 0x14, 0x43, 0x40, 0x80, 0x98,
        0x25, 0x0C, 0x27, 0x2C, 0x94, 0x42, 0x41, 0xA2,
        0x88, 0x45, 0x02, 0x13, 0x05, 0x44, 0xB6, 0x44,
        0x52, 0x22, 0x92, 0xD0, 0x80, 0x50, 0x4B, 0xA6,
        0x04, 0x84, 0x36, 0x70, 0x09, 0xB2, 0x4D, 0x19,
        0xA8, 0x84, 0x24, 0x93, 0x49, 0x94, 0xA2, 0x80,
        0x49, 0xB4, 0x48, 0x91, 0x28, 0x64, 0xA1, 0xC8,
        0x65, 0x4B, 0x82, 0x85, 0x93, 0x30, 0x06, 0x63,
        0x12, 0x66, 0x10, 0x37, 0x01, 0x4A, 0x40, 0x80,
        0x18, 0x18, 0x90, 0x44, 0xC4, 0x0D, 0x4B, 0x28,
        0x81, 0xA2, 0x06, 0x40, 0xD4, 0x30, 0x2C, 0x1B,
        0x96, 0x4C, 0xE1, 0xB2, 0x60, 0x44, 0x28, 0x41,
        0xD8, 0x30, 0x65, 0x24, 0x09, 0x04, 0x64, 0x00,
        0x89, 0x63, 0xC2, 0x24, 0xC0, 0x00, 0x49, 0x92,
        0x16, 0x52, 0x23, 0xC1, 0x29, 0x42, 0x26, 0x91,
        0xD0, 0x38, 0x31, 0x83, 0x28, 0x28, 0x4C, 0x28,
        0x61, 0x1A, 0xB2, 0x88, 0x80, 0x26, 0x2D, 0x0C,
        0x19, 0x52, 0x5B, 0x22, 0x60, 0x8A, 0x92, 0x28,
        0xA2, 0x18, 0x90, 0xD9, 0x42, 0x52, 0xCB, 0x40,
        0x8E, 0x9B, 0x16, 0x06, 0x4B, 0xC8, 0x05, 0xE0,
        0x06, 0x6C, 0x49, 0xC2, 0x25, 0xD4, 0x22, 0x69,
        0x14, 0x11, 0x69, 0x1C, 0x34, 0x90, 0x0C, 0x85,
        0x8D, 0x1C, 0x84, 0x49, 0x63, 0x10, 0x85, 0x08,
        0x34, 0x89, 0x58, 0x16, 0x66, 0xA0, 0x38, 0x68,
        0x0B, 0xA2, 0x50, 0xE0, 0x84, 0x61, 0xC1, 0x26,
        0x6E, 0xC9, 0x14, 0x6A, 0xC0, 0xC0, 0x31, 0x84,
        0x18, 0x2E, 0xDC, 0x16, 0x52, 0x14, 0x18, 0x91,
        0x0A, 0x39, 0x2C, 0x83, 0xA6, 0x8D, 0x12, 0x29,
        0x62, 0x92, 0xA6, 0x60, 0x08, 0xA5, 0x10, 0xD9,
        0xC8, 0x4D, 0x24, 0x48, 0x24, 0x83, 0x98, 0x24,
        0x1A, 0x44, 0x42, 0x08, 0x08, 0x48, 0xC8, 0x96,
        0x2D, 0xA1, 0x10, 0x20, 0x60, 0x24, 0x51, 0x9C,
        0x30, 0x11, 0xDB, 0xC8, 0x04, 0x11, 0x22, 0x51,
        0x18, 0x04, 0x68, 0xE2, 0x24, 0x4E, 0x10, 0xC4,
        0x0D, 0x18, 0x37, 0x29, 0x11, 0xB7, 0x84, 0x43,
        0x84, 0x8D, 0x54, 0x40, 0x70, 0x64, 0x80, 0x70,
        0x21, 0xB0, 0x4D, 0x00, 0x26, 0x62, 0x00, 0x45,
        0x25, 0x1B, 0x83, 0x84, 0x84, 0x80, 0x70, 0x19,
        0xB0, 0x04, 0x0A, 0xC9, 0x28, 0xCA, 0x80, 0x05,
        0x1B, 0x21, 0x4E, 0xD4, 0xB0, 0x49, 0x8C, 0x96,
        0x6C, 0xD0, 0x96, 0x25, 0x48, 0x32, 0x72, 0x54,
        0x12, 0x05, 0x09, 0x98, 0x8C, 0x8A, 0x32, 0x6D,
        0xC0, 0x04, 0x31, 0x63, 0xC8, 0x61, 0xC8, 0xC2,
        0x68, 0x9B, 0xB4, 0x8C, 0x5B, 0xC0, 0x2D, 0xC3,
        0xA8, 0x8D, 0x1B, 0x16, 0x6C, 0xD8, 0x96, 0x41,
        0x98, 0x34, 0x02, 0x44, 0x14, 0x2C, 0xD3, 0x86,
        0x44, 0x0A, 0x18, 0x8A, 0x1A, 0x46, 0x92, 0x1A,
        0xB7, 0x08, 0x4C, 0x34, 0x24, 0x21, 0x91, 0x0D,
        0x9A, 0x96, 0x2D, 0xCB, 0x24, 0x22, 0x92, 0x86,
        0x08, 0x98, 0xA0, 0x50, 0xDA, 0x44, 0x6A, 0x19,
        0xB1, 0x05, 0x8B, 0x20, 0x6E, 0x24, 0xC4, 0x81,
        0xC9, 0x98, 0x40, 0x22, 0x19, 0x32, 0x11, 0x05,
        0x69, 0xD3, 0x94, 0x91, 0x08, 0xA7, 0x71, 0xDB,
        0xC0, 0x70, 0x02, 0xB8, 0x28, 0x83, 0xB4, 0x49,
        0xA0, 0x44, 0x8A, 0x0B, 0xB4, 0x10, 0x61, 0x02,
        0x48, 0x1C, 0xA6, 0x11, 0xE3, 0x20, 0x66, 0x40,
        0xB4, 0x70, 0x03, 0xB6, 0x04, 0x60, 0x48, 0x21,
        0x5B, 0x21, 0x83, 0x39, 0x88, 0xDB, 0x67, 0x4A,
        0x61, 0xE7, 0xC2, 0x08, 0xDE, 0xBE, 0x8D, 0xAE,
        0x41, 0x19, 0xAF, 0xB0, 0x26, 0x61, 0xA6, 0x9A,
        0xBC, 0x8B, 0xDD, 0x24, 0x5B, 0x5D, 0x0F, 0xB1,
        0xA2, 0x67, 0x01, 0xC9, 0xB9, 0xC9, 0xA8, 0xF7,
        0xD9, 0xFC, 0xD4, 0xC2, 0x87, 0xFF, 0x3D, 0x60,
        0x8C, 0xF2, 0x58, 0x28, 0x2A, 0x1E, 0xB2, 0x9F,
        0x93, 0x04, 0xE8, 0x9C, 0x14, 0xF3, 0xE1, 0xCE,
        0x56, 0x12, 0x89, 0x1C, 0x60, 0x29, 0x34, 0x52,
        0x60, 0x06, 0xC9, 0x9B, 0x4A, 0xA2, 0x39, 0x9B,
        0xF4, 0x94, 0xBC, 0xF8, 0xDF, 0x61, 0xD6, 0xDF,
        0x4C, 0x69, 0xBC, 0x93, 0xE0, 0x2D, 0x49, 0x95,
        0xE2, 0xF7, 0x6E, 0x9F, 0xDA, 0x4E, 0xF6, 0x7E,
        0xB7, 0x25, 0x6C, 0xA8, 0x9A, 0x3F, 0x38, 0xFE,
        0xB2, 0xE9, 0xDF, 0x6A, 0x01, 0x0D, 0xC1, 0xC1,
        0x50, 0x02, 0xFB, 0xD4, 0x56, 0xFA, 0xE8, 0x84,
        0x82, 0x1A, 0x34, 0x16, 0x6B, 0x06, 0x58, 0xA2,
        0x41, 0x25, 0x95, 0x71, 0x8E, 0x14, 0x9B, 0xBC,
        0x6E, 0x22, 0x0A, 0xEE, 0x26, 0x8D, 0x4D, 0x82,
        0x18, 0xC2, 0x5F, 0x6A, 0x95, 0x7D, 0xE5, 0xB2,
        0x6C, 0xEA, 0x7B, 0x14, 0xCB, 0x32, 0x0D, 0x89,
        0xE1, 0x69, 0x9A, 0xD9, 0xF2, 0xB3, 0x89, 0xC6,
        0x7E, 0xF9, 0x33, 0x86, 0xA2, 0xC6, 0x5F, 0x2C,
        0x32, 0x23, 0x33, 0x67, 0xD7, 0x6A, 0xE4, 0xAB,
        0x2A, 0xBB, 0xD4, 0x22, 0xE9, 0x8E, 0x49, 0x3D,
        0xCC, 0x3C, 0xC5, 0xDA, 0xF6, 0x89, 0xB6, 0x5C,
        0xC4, 0xBC, 0x3F, 0xA5, 0x1C, 0x9C, 0x59, 0xEE,
        0xAF, 0x07, 0x55, 0x17, 0x0C, 0x24, 0x95, 0x80,
        0x4D, 0x02, 0xA6, 0x07, 0xC5, 0xBF, 0x88, 0x7C,
        0xD8, 0x6A, 0x03, 0x89, 0xF2, 0x8F, 0xC9, 0x72,
        0x5E, 0xF4, 0x60, 0x03, 0xF1, 0x3B, 0x01, 0x87,
        0x68, 0x4B, 0xEA, 0xB1, 0xF2, 0x4A, 0x29, 0xF5,
        0x31, 0x96, 0x01, 0xF3, 0x09, 0xC9, 0x1D, 0x2A,
        0x33, 0x3D, 0x1B, 0x88, 0xDF, 0x20, 0x5A, 0x51,
        0x20, 0xC4, 0xCF, 0xDC, 0x22, 0x38, 0x12, 0x4E,
        0x4E, 0x2B, 0x47, 0xD0, 0xB5, 0xE6, 0x6A, 0x65,
        0x4F, 0xE4, 0xCC, 0xCB, 0x07, 0x8F, 0x07, 0xCB,
        0xD4, 0x55, 0xD1, 0x5D, 0x3E, 0xEC, 0x7D, 0xA2,
        0x74, 0xD2, 0x4A, 0x2E, 0x57, 0x18, 0x84, 0xDE,
        0x41, 0xC3, 0xA9, 0xA4, 0xFD, 0xB3, 0xF6, 0x09,
        0x8A, 0x17, 0x2C, 0x30, 0x96, 0x80, 0x39, 0xBD,
        0x0E, 0x4E, 0xB3, 0xE2, 0xFB, 0x6D, 0x6E, 0xEE,
        0xD3, 0x9E, 0x0B, 0x63, 0x62, 0xD5, 0x4E, 0x7B,
        0x88, 0x95, 0x98, 0x69, 0xDD, 0xD5, 0xD8, 0x73,
        0xD9, 0x65, 0x24, 0x01, 0xA2, 0x9F, 0x27, 0xA2,
        0x8E, 0xA6, 0x6D, 0x32, 0xCC, 0xB0, 0xEF, 0x3B,
        0xF4, 0x60, 0x0F, 0x75, 0x57, 0xEE, 0x8D, 0x54,
        0xBF, 0x1D, 0xAD, 0x18, 0xF4, 0x5D, 0xDC, 0xD4,
        0xC9, 0xED, 0x57, 0xB1, 0x3E, 0x44, 0x5B, 0xF1,
        0x22, 0xA4, 0x3F, 0x53, 0x94, 0x03, 0x89, 0xBF,
        0x87, 0x14, 0xFF, 0xAC, 0x72, 0x1E, 0x59, 0x31,
        0x7E, 0x4B, 0x70, 0x50, 0x0A, 0xD0, 0xD1, 0xB9,
        0xA6, 0x27, 0x05, 0x4D, 0x31, 0x93, 0x20, 0x8C,
        0x77, 0x4E, 0x0B, 0x20, 0xED, 0x04, 0x1A, 0x8C,
        0x05, 0x5E, 0x75, 0xEE, 0xCD, 0x37, 0x38, 0xF0,
        0x07, 0x15, 0x8F, 0xAD, 0xDF, 0xCA, 0x5F, 0x43,
        0x56, 0x2D, 0x63, 0x6A, 0x5A, 0xCF, 0x3A, 0x39,
        0x83, 0xD3, 0xCF, 0xEB, 0xCA, 0x10, 0xB8, 0x13,
        0xF9, 0xF6, 0x52, 0x65, 0x19, 0x19, 0x9A, 0x03,
        0x13, 0xCD, 0x1D, 0xE1, 0x3F, 0x06, 0xAD, 0x53,
        0x86, 0xE1, 0xE1, 0x20, 0x79, 0x5F, 0xD2, 0x67,
        0xB7, 0xF4, 0x20, 0x19, 0xD8, 0x4D, 0xF6, 0xCD,
        0x1B, 0xF9, 0x19, 0x30, 0xFC, 0xA7, 0xAF, 0xD5,
        0x2E, 0x80, 0x70, 0x0F, 0x4C, 0xF5, 0xCD, 0xC3,
        0x8A, 0x5F, 0x7A, 0x57, 0x49, 0x79, 0x1C, 0x2F,
        0xDF, 0xFC, 0x4A, 0x10, 0x75, 0x3C, 0x24, 0xDB,
        0x19, 0xE8, 0xEB, 0x65, 0x1C, 0x5B, 0x36, 0x32,
        0x00, 0xF0, 0xB5, 0xD1, 0x69, 0x94, 0x70, 0x26,
        0xE9, 0xF7, 0x4F, 0x01, 0x2D, 0xC7, 0xC5, 0xB3,
        0x39, 0xDD, 0x49, 0xD2, 0x61, 0xCA, 0x1D, 0x37,
        0xF8, 0xF2, 0x83, 0x46, 0xE6, 0x19, 0x78, 0x05,
        0x4F, 0x45, 0xAE, 0xE4, 0x36, 0xDC, 0xCB, 0xE7,
        0xBF, 0xAF, 0xE0, 0x7C, 0xE9, 0xA8, 0xB8, 0x3C,
        0x90, 0xA2, 0x68, 0x6F, 0xA9, 0x54, 0x02, 0x85,
        0x09, 0x25, 0xC8, 0x58, 0x2B, 0xC9, 0xB7, 0x34,
        0xE4, 0xEC, 0xA1, 0xF7, 0xB2, 0x0B, 0x08, 0x6F,
        0x12, 0x9F, 0x27, 0x7A, 0x5C, 0xBD, 0xAA, 0x96,
        0x3C, 0x92, 0x71, 0x7E, 0xF7, 0x0E, 0xC1, 0x9B,
        0xF3, 0xDB, 0xC6, 0xDA, 0x20, 0x3A, 0xD9, 0x0F,
        0x3B, 0x13, 0xBB, 0xC2, 0x2F, 0xBD, 0x98, 0x0B,
        0xB1, 0xB9, 0xD3, 0xA3, 0x44, 0x52, 0xB3, 0x35,
        0x70, 0x21, 0xCE, 0x36, 0x13, 0x58, 0x4E, 0x09,
        0x36, 0xBF, 0x1D, 0x09, 0x42, 0x09, 0x37, 0x81,
        0x5E, 0x11, 0xCC, 0x5D, 0x5D, 0xDB, 0x4B, 0xF1,
        0xD8, 0x30, 0xC4, 0xF8, 0x3F, 0x30, 0xE5, 0x15,
        0x92, 0x1C, 0x78, 0x4D, 0x87, 0xBB, 0x20, 0xC0,
        0x9E, 0x3C, 0x64, 0xBD, 0xCE, 0x9A, 0xB1, 0xC6,
        0x9F, 0xD3, 0x07, 0xEF, 0xE3, 0x59, 0xC7, 0xF9,
        0x38, 0x56, 0x6C, 0x9F, 0x25, 0x17, 0xB0, 0x63,
        0x38, 0x51, 0x67, 0xE2, 0x47, 0xF3, 0x10, 0x81,
        0x11, 0x9B, 0xAC, 0x6B, 0x55, 0xA0, 0xBD, 0xD7,
        0x14, 0x25, 0x51, 0x0F, 0xFA, 0x2A, 0xBD, 0xFA,
        0x88, 0x83, 0x76, 0xA3, 0x7F, 0x20, 0xC2, 0x48,
        0x01, 0x52, 0xBB, 0x36, 0x16, 0x34, 0x52, 0x00,
        0x07, 0xC5, 0xB3, 0x4B, 0xF2, 0x28, 0x17, 0xCB,
        0x2E, 0x67, 0xAC, 0x1A, 0x82, 0x67, 0x0B, 0x71,
        0xF1, 0x96, 0xC8, 0x9F, 0x23, 0xBA, 0x31, 0x4B,
        0x16, 0xA9, 0x48, 0x49, 0x93, 0x04, 0xEF, 0x5C,
        0x03, 0xDC, 0xF5, 0x8E, 0x52, 0xBE, 0x31, 0x48,
        0x63, 0xE7, 0x23, 0xC5, 0x6D, 0x3A, 0xEB, 0x34,
        0x0B, 0xFF, 0x18, 0xAB, 0xFA, 0x20, 0xDC, 0x03,
        0x44, 0x20, 0x30, 0x23, 0x05, 0x33, 0xD9, 0x12,
        0x9B, 0x83, 0xED, 0x22, 0xC3, 0x51, 0xF2, 0x32,
        0x81, 0x72, 0xE3, 0x63, 0x44, 0x74, 0x44, 0xAE,
        0x5C, 0x69, 0x02, 0xB7, 0x92, 0x79, 0x9F, 0x54,
        0x44, 0x50, 0x78, 0x71, 0x19, 0x61, 0x2E, 0x9B,
        0xB4, 0x13, 0x0A, 0x33, 0xA2, 0xA5, 0x96, 0x2A,
        0xC0, 0x9D, 0x57, 0x7D, 0x6D, 0xDC, 0x88, 0x1F,
        0xE6, 0x61, 0x61, 0x26, 0xD8, 0xA0, 0xA7, 0xDF,
        0x2B, 0x22, 0x53, 0xBC, 0x8E, 0xC4, 0xE3, 0x53,
        0x86, 0xEA, 0x55, 0x11, 0xF0, 0xF1, 0x58, 0x87,
        0x14, 0x5B, 0x6C, 0x23, 0xAB, 0x3D, 0x40, 0x33,
        0x39, 0xE4, 0x04, 0x07, 0x3E, 0xD9, 0xC6, 0xA8,
        0x96, 0xA2, 0xF9, 0xEC, 0x70, 0xC4, 0x4B, 0xD2,
        0xAE, 0xC1, 0x0F, 0xC4, 0x36, 0x0E, 0x87, 0x63,
        0x6B, 0xE1, 0x55, 0xB6, 0xA6, 0x7B, 0x7E, 0xDF,
        0x38, 0xCF, 0x73, 0x00, 0x48, 0x13, 0xC9, 0xE7,
        0xD2, 0xC6, 0x54, 0xC2, 0x53, 0x0A, 0x71, 0xE5,
        0xF8, 0xC1, 0x09, 0x42, 0xFB, 0x6D, 0x88, 0x41,
        0x53, 0x5A, 0xB1, 0xDA, 0x43, 0xE8, 0xCB, 0x0B,
        0xB8, 0x9E, 0x78, 0xEC, 0x91, 0xF8, 0xDE, 0x15,
        0x31, 0xA0, 0x36, 0x65, 0xCC, 0xD5, 0xA7, 0x5B,
        0xDA, 0x0E, 0xD0, 0xE5, 0x98, 0x64, 0xEE, 0xEF,
        0x51, 0xA8, 0x3F, 0xA5, 0x53, 0xAF, 0x66, 0x2A,
        0xEE, 0x00, 0xD1, 0xF8, 0x36, 0x7B, 0x4D, 0x5D,
        0xDD, 0xC3, 0x45, 0x54, 0x4C, 0x6B, 0xD5, 0x14,
        0xF8, 0x88, 0xE6, 0x03, 0x3C, 0x25, 0x5D, 0xB6,
        0x50, 0xDA, 0x73, 0x4A, 0xD3, 0x3A, 0x3C, 0xF8,
        0x4B, 0xD3, 0xF0, 0x6F, 0xA1, 0xA7, 0xCA, 0x02,
        0xE4, 0xB8, 0xE9, 0x93, 0xAE, 0x7A, 0xE6, 0x34,
        0x20, 0xA4, 0x6B, 0xA8, 0xA3, 0x81, 0x3D, 0x1E,
        0x9D, 0x29, 0x66, 0xBB, 0x85, 0x60, 0xD7, 0x1C,
        0x62, 0xA0, 0x44, 0xEA, 0x94, 0x17, 0x9F, 0x4E,
        0xB1, 0xB6, 0xED, 0x60, 0x71, 0x9D, 0x51, 0xE0,
        0xEE, 0xF6, 0xCD, 0x07, 0x91, 0x52, 0xF6, 0xBE,
        0x48, 0x8E, 0xC9, 0x19, 0x11, 0xC6, 0xD3, 0xF1,
        0xD1, 0x17, 0x3C, 0x54, 0x1F, 0x9D, 0x25, 0xBF,
        0x34, 0x2F, 0xCA, 0xA3, 0xFF, 0x46, 0xC1, 0x8F,
        0x2A, 0x04, 0x41, 0xD8, 0x3B, 0xDE, 0x35, 0x46,
        0xA9, 0x82, 0x6C, 0x34, 0x96, 0xE0, 0x6F, 0x2F,
        0x2B, 0x0E, 0xEB, 0x9D, 0x5B, 0xE8, 0x73, 0x9F,
        0x83, 0xA4, 0x2D, 0x3B, 0x30, 0x0E, 0x70, 0xEE,
        0x84, 0xDF, 0xFF, 0xB2, 0x07, 0x64, 0xA0, 0x60,
        0x21, 0x2F, 0x05, 0x8C, 0x8A, 0x5F, 0xFA, 0x9A,
        0x34, 0xE9, 0x28, 0xD6, 0xA7, 0xE0, 0x77, 0x08,
        0xFE, 0x53, 0x93, 0xE3, 0x01, 0x7C, 0xE4, 0x70,
        0xEB, 0x96, 0x58, 0xA7, 0x4E, 0x49, 0x51, 0xE6,
        0xFA, 0x48, 0x54, 0xC9, 0xE9, 0xC2, 0x89, 0x88,
        0x81, 0x2E, 0x44, 0x18, 0xA2, 0xE8, 0x32, 0x58,
        0x0B, 0x4A, 0x27, 0x03, 0x72, 0xBC, 0x69, 0x67,
        0x68, 0x89, 0xD0, 0xCC, 0x43, 0x24, 0x0E, 0xDA,
        0xBC, 0x1D, 0x31, 0x14, 0xD8, 0xF3, 0x5A, 0xB2,
        0xE9, 0xEA, 0x95, 0x30, 0x82, 0xE9, 0x53, 0x62,
        0x79, 0xAC, 0xB3, 0xBE, 0x16, 0xD3, 0xA2, 0x05,
        0xF4, 0x6C, 0xB6, 0x7B, 0x22, 0x14, 0x96, 0x93,
        0x5A, 0xC0, 0x42, 0x92, 0xBB, 0xFB, 0x9A, 0x61,
        0xC0, 0xA0, 0x3E, 0xF4, 0xC9, 0xB6, 0x82, 0x04,
        0x95, 0xF3, 0xD8, 0x0E, 0x4A, 0x6F, 0xB7, 0xE1,
        0xC6, 0x99, 0x03, 0xFA, 0x22, 0x6E, 0x02, 0x3E,
        0x95, 0xBA, 0x41, 0x6D, 0xF2, 0xE5, 0xE4, 0x54,
        0x1E, 0x15, 0xDC, 0xC0, 0x00, 0xB5, 0xE6, 0x5C,
        0x97, 0x20, 0xDA, 0xF6, 0x96, 0x01, 0x2F, 0xA2,
        0xA6, 0xCF, 0x75, 0x8E, 0xD6, 0xD2, 0x25, 0xA3,
        0xE4, 0xFE, 0xE4, 0x5A, 0xC5, 0xFB, 0x48, 0x70,
        0x7F, 0xAE, 0x13, 0x3D, 0x59, 0x2C, 0xFD, 0x2E,
        0x8C, 0x43, 0xC2, 0x12, 0x6F, 0x65, 0x2B, 0xEE,
        0x9B, 0xAB, 0x43, 0xA1, 0xA1, 0x0B, 0xE2, 0x41,
        0x1A, 0x67, 0x94, 0xB2, 0x6C, 0xB5, 0x5C, 0xC2,
        0x17, 0xEB, 0x7B, 0x0B, 0x14, 0x6D, 0x23, 0xF7,
        0x92, 0x2D, 0x32, 0x22, 0xAE, 0x5E, 0xE8, 0xC6,
        0xD3, 0x8E, 0x83, 0x99, 0xBA, 0x51, 0xC6, 0x81,
        0xB8, 0x38, 0x16, 0xFC, 0xF7, 0x44, 0x38, 0x82,
        0x59, 0x20, 0xF9, 0xCE, 0x8A, 0x20, 0x2A, 0x8F,
        0x6D, 0x94, 0x2D, 0xA8, 0x62, 0x38, 0xFB, 0x4C,
        0x9F, 0x21, 0x98, 0xEA, 0x8D, 0xFF, 0x81, 0xC1,
        0x72, 0x86, 0xE0, 0x18, 0xDF, 0x4B, 0x7F, 0xE3,
        0x88, 0x4D, 0x17, 0x59, 0xE4, 0xC5, 0x9B, 0xB5,
        0x26, 0x17, 0xAE, 0xD4, 0xE7, 0x8E, 0x4E, 0x7C,
        0x4E, 0x9A, 0x36, 0xE4, 0xE9, 0x96, 0xD3, 0x23,
        0x91, 0xA3, 0x4A, 0x0D, 0xAA, 0xAB, 0x6B, 0x54,
        0x08, 0x15, 0xA3, 0x4D, 0x20, 0x40, 0x7A, 0xEF,
        0x81, 0x94, 0x9B, 0xE6, 0x7B, 0x90, 0x69, 0x50,
        0xD8, 0x9B, 0xE9, 0xF0, 0x85, 0xE9, 0x9E, 0xB5,
        0x87, 0x26, 0x95, 0x17, 0x3B, 0x3E, 0xFA, 0xCA,
        0xE9, 0x45, 0x5D, 0x2B, 0x2C, 0xD4, 0xF7, 0x10,
        0xB8, 0x72, 0xCF, 0x66, 0x2B, 0x73, 0x62, 0x16,
        0xB1, 0xBB, 0xFB, 0x1F, 0x5F, 0x3D, 0x48, 0x6C,
        0x7B, 0x4B, 0x87, 0x56, 0x12, 0x33, 0x3F, 0x8E,
        0x4B, 0xA9, 0x33, 0xDC, 0x79, 0xF0, 0xED, 0xFD,
        0x7B, 0xAA, 0xDE, 0x2C, 0x16, 0xF2, 0x14, 0x6A,
        0x49, 0x6F, 0x79, 0xC4, 0x2A, 0x4D, 0x6B, 0x52,
        0x39, 0xA3, 0x0D, 0xD3, 0xC4, 0x8B, 0xEB, 0x09,
        0x2C, 0xA0, 0x75, 0x00, 0x10, 0xF6, 0x9E, 0xD4,
        0xB9, 0x23, 0x20, 0x14, 0x7D, 0xBB, 0xE2, 0x08,
        0xF6, 0xE8, 0xEB, 0x1C, 0xF2, 0x47, 0xD2, 0x1A,
        0x3A, 0x3B, 0x01, 0xDF, 0x58, 0xC0, 0xAA, 0x62,
        0x94, 0x4D, 0xA0, 0xEF, 0x04, 0x50, 0xE8, 0xCE,
        0x48, 0xAA, 0x13, 0x7E, 0x7E, 0x15, 0x16, 0xC1,
        0xD5, 0xC8, 0x6E, 0xEA, 0x17, 0xFD, 0xFA, 0xC1,
        0x69, 0x07, 0x46, 0xE7, 0x26, 0x70, 0x45, 0xA3,
        0xE9, 0x05, 0x96, 0xBD, 0xB7, 0x5D, 0x50, 0xB6,
        0xDD, 0x5C, 0x34, 0xE5, 0xC8, 0xD8, 0x9D, 0xC6,
        0xF2, 0xF1, 0xD2, 0x44, 0x40, 0xE5, 0x7B, 0x47,
        0x59, 0xB8, 0x62, 0x5F, 0x72, 0xBC, 0x4A, 0x7B,
        0x10, 0xD5, 0x19, 0xD3, 0x31, 0xF9, 0xC4, 0x00,
        0xAA, 0xE1, 0xE5, 0x0D, 0x48, 0x0C, 0xAA, 0xE5,
        0xA1, 0xC0, 0xFA, 0x99, 0xD7, 0x79, 0x24, 0xCF,
        0x8D, 0xFE, 0x56, 0xCD, 0x70, 0x92, 0xE7, 0xB9
    };
#endif /* !WOLFSSL_NO_ML_DSA_44 */
#ifndef WOLFSSL_NO_ML_DSA_65
    static const byte seed_65[] = {
        0x70, 0xCE, 0xFB, 0x9A, 0xED, 0x5B, 0x68, 0xE0,
        0x18, 0xB0, 0x79, 0xDA, 0x82, 0x84, 0xB9, 0xD5,
        0xCA, 0xD5, 0x49, 0x9E, 0xD9, 0xC2, 0x65, 0xFF,
        0x73, 0x58, 0x80, 0x05, 0xD8, 0x5C, 0x22, 0x5C
    };
    static const byte pk_65[] = {
        0xD2, 0xFD, 0x03, 0xF3, 0xA1, 0xB7, 0xF6, 0x35,
        0xAF, 0x9F, 0x34, 0xD5, 0x80, 0xA9, 0x8F, 0x52,
        0x4C, 0x73, 0x5B, 0xD5, 0xBA, 0x23, 0x55, 0xDC,
        0x6E, 0x03, 0x5B, 0xD2, 0x17, 0x65, 0x58, 0x0C,
        0xBB, 0x11, 0x19, 0x23, 0xF1, 0x94, 0xA7, 0xCC,
        0x8A, 0x7B, 0xB2, 0xEB, 0xC5, 0xC0, 0xE7, 0x1A,
        0xA6, 0x37, 0xCC, 0x80, 0x0E, 0x61, 0x03, 0xB8,
        0x50, 0xA5, 0x39, 0xB2, 0xA3, 0x9E, 0x1B, 0x6D,
        0x71, 0x3E, 0x5D, 0xB8, 0x31, 0x4C, 0x9A, 0xE1,
        0xF8, 0xBF, 0x8A, 0x38, 0xF0, 0x6A, 0xFB, 0x9D,
        0x73, 0xB1, 0x61, 0xB0, 0xFF, 0xE3, 0xA4, 0x89,
        0x17, 0x06, 0xAE, 0x26, 0xD5, 0x4F, 0xFB, 0x49,
        0x6D, 0xF8, 0xDC, 0x0F, 0x19, 0x83, 0x50, 0x95,
        0x00, 0xC9, 0xAB, 0xBD, 0x28, 0xE5, 0x9B, 0x3F,
        0xCD, 0xAB, 0xBD, 0xAD, 0xAB, 0xD4, 0x5E, 0xC3,
        0x14, 0x99, 0x37, 0x8B, 0xDE, 0x84, 0x9E, 0x7C,
        0x1F, 0x19, 0xB7, 0x04, 0x4D, 0x67, 0xE0, 0x51,
        0x06, 0xD7, 0x13, 0x6D, 0x95, 0x38, 0x0D, 0x56,
        0x05, 0xD4, 0x46, 0x5D, 0x87, 0x75, 0x57, 0x06,
        0x5D, 0xF0, 0xA7, 0x5D, 0x3C, 0x28, 0x54, 0x2F,
        0x40, 0xFE, 0xED, 0x42, 0xEC, 0x7E, 0x28, 0x06,
        0x37, 0xB0, 0x83, 0xD9, 0x88, 0xBC, 0xA5, 0xF6,
        0x39, 0x4E, 0x02, 0x39, 0x6C, 0x46, 0x76, 0x18,
        0x4F, 0xB6, 0x33, 0x18, 0xDA, 0xFA, 0xF5, 0xBB,
        0xDD, 0xE0, 0x0E, 0x30, 0x8F, 0xE8, 0x40, 0x19,
        0xC2, 0x34, 0x0A, 0x3F, 0x3E, 0x1C, 0x08, 0x65,
        0x62, 0x49, 0x70, 0x71, 0x12, 0x83, 0x35, 0x6A,
        0xE1, 0x4B, 0xD6, 0xB9, 0x4D, 0x1C, 0x9A, 0xE1,
        0x88, 0xDE, 0x1A, 0x8A, 0x2C, 0xA8, 0x24, 0xA8,
        0xEA, 0xE2, 0xFE, 0x6A, 0xFB, 0x38, 0xD8, 0x3A,
        0x2D, 0x99, 0x99, 0x6A, 0xB2, 0x1F, 0xE3, 0xE8,
        0x4C, 0x0B, 0xE6, 0xB6, 0xDA, 0x08, 0x87, 0x9B,
        0x67, 0x73, 0x74, 0xFA, 0x7C, 0x69, 0x1B, 0x13,
        0xD4, 0x0F, 0xA9, 0xD4, 0xCC, 0x26, 0xB2, 0x28,
        0x8D, 0x5A, 0x8C, 0x9A, 0x43, 0x72, 0x43, 0x81,
        0x00, 0x4D, 0x61, 0xB0, 0xD5, 0x7F, 0xF4, 0x00,
        0x31, 0x4C, 0x8E, 0x30, 0xEE, 0x79, 0x6A, 0xF1,
        0x0F, 0x7E, 0xE2, 0x1B, 0xF1, 0x3D, 0x08, 0x18,
        0x04, 0x65, 0xAB, 0xC7, 0x2E, 0xDD, 0xB0, 0x80,
        0xC6, 0xA0, 0x71, 0x84, 0xE3, 0xEE, 0xDC, 0x47,
        0xC1, 0x9A, 0xA7, 0xF0, 0x9D, 0x1F, 0x33, 0x09,
        0xE1, 0x83, 0xA2, 0xBD, 0x9B, 0x05, 0x73, 0xDD,
        0xE4, 0x74, 0xA8, 0x1B, 0xA4, 0xF7, 0x8D, 0x0C,
        0x52, 0x3D, 0x0C, 0x04, 0xF9, 0x00, 0x60, 0xFD,
        0x57, 0x1A, 0x35, 0xC0, 0x37, 0xE0, 0x79, 0xC5,
        0xE2, 0x10, 0xD7, 0x39, 0x0D, 0xF5, 0x68, 0xF2,
        0xE2, 0xF0, 0x3C, 0xE4, 0x44, 0x20, 0xC8, 0x2F,
        0x3F, 0xE6, 0x9E, 0xB9, 0xB4, 0x8E, 0xE9, 0x09,
        0x62, 0xD6, 0xB0, 0xF2, 0x44, 0x40, 0x64, 0x8F,
        0x71, 0xED, 0xB2, 0x41, 0xEE, 0x65, 0x66, 0xFC,
        0x1A, 0x64, 0xCA, 0xBF, 0x66, 0xBE, 0x6F, 0xEC,
        0xBC, 0xB1, 0x38, 0x7C, 0x82, 0xA7, 0xBC, 0x20,
        0x2D, 0x9E, 0x36, 0x79, 0x98, 0xE2, 0xA2, 0x91,
        0xAF, 0x0C, 0xD1, 0x57, 0x06, 0x77, 0xFE, 0x8D,
        0x63, 0xA3, 0x28, 0x5A, 0x2E, 0xA6, 0xEB, 0x29,
        0xAF, 0x9D, 0xC1, 0xAE, 0xC1, 0xC3, 0x6C, 0x47,
        0x06, 0xB1, 0x2B, 0xAA, 0x20, 0x83, 0x96, 0x92,
        0xF2, 0x86, 0xA6, 0xE0, 0x32, 0x14, 0x68, 0xF7,
        0x47, 0x93, 0x45, 0xC4, 0xD5, 0x2F, 0xBD, 0xB2,
        0xF0, 0x67, 0x25, 0xB5, 0x54, 0xB8, 0x9E, 0x24,
        0x92, 0x61, 0x26, 0x81, 0xAC, 0xEB, 0xC6, 0xC7,
        0xBA, 0xDA, 0x92, 0x25, 0x81, 0x8D, 0xBC, 0x35,
        0xD6, 0x4C, 0x22, 0xC4, 0x8B, 0xFF, 0x80, 0xA7,
        0x30, 0xD0, 0x71, 0x6D, 0xFA, 0xC9, 0x9D, 0xFD,
        0x5B, 0x89, 0x92, 0x61, 0x1D, 0x0C, 0x93, 0xEE,
        0x90, 0xBD, 0xB2, 0x60, 0x02, 0x2A, 0xFE, 0x25,
        0xD9, 0x13, 0xE0, 0x6E, 0xFF, 0xB5, 0x9C, 0xB1,
        0xF8, 0xA6, 0x0C, 0xBF, 0xA5, 0xAB, 0x2F, 0x45,
        0x9A, 0x16, 0xF4, 0x67, 0xE9, 0x89, 0x52, 0x5E,
        0x0A, 0x37, 0xEB, 0xE5, 0x6E, 0x83, 0x3F, 0xDE,
        0x55, 0xDB, 0x9D, 0x15, 0x30, 0xAD, 0xCF, 0x45,
        0x84, 0x6D, 0xF2, 0x81, 0xE4, 0x7C, 0xAA, 0x1E,
        0x0A, 0x27, 0xEF, 0xDE, 0x21, 0x07, 0xD3, 0x54,
        0xCE, 0xA0, 0xF6, 0xA4, 0x54, 0x69, 0x2F, 0x04,
        0xCD, 0x83, 0x8E, 0xBD, 0xD4, 0x6E, 0x19, 0x1E,
        0x5D, 0x9C, 0x11, 0x83, 0x9A, 0x2C, 0x3F, 0x48,
        0x8A, 0x4F, 0xC7, 0xCD, 0x26, 0x5A, 0x7B, 0x5D,
        0x32, 0xB0, 0x8C, 0xBD, 0xBF, 0xAB, 0x9D, 0x2C,
        0xCD, 0x76, 0x22, 0x2C, 0x8E, 0xE3, 0x7D, 0xDC,
        0xBD, 0x2A, 0xA0, 0x63, 0xED, 0x86, 0x14, 0x73,
        0xA6, 0x45, 0x4C, 0xAE, 0xA3, 0x77, 0x85, 0x0B,
        0x1A, 0x2B, 0x9D, 0xDB, 0xBC, 0xB3, 0x74, 0xFA,
        0xB5, 0xB1, 0x2F, 0x35, 0x1C, 0x8E, 0x58, 0x88,
        0x87, 0x2E, 0x5C, 0xD1, 0xF6, 0x0A, 0x4F, 0xAE,
        0x1F, 0xF8, 0x37, 0xD1, 0x92, 0xC2, 0x2B, 0xEB,
        0x41, 0xEE, 0x6F, 0xA3, 0x92, 0xFC, 0xDF, 0x45,
        0x50, 0xFF, 0x46, 0xB5, 0xCE, 0x90, 0x6D, 0x01,
        0x7E, 0xF3, 0x07, 0x7D, 0xF1, 0x32, 0x30, 0x0D,
        0x8B, 0xBF, 0xA9, 0xBB, 0x03, 0xC7, 0x5E, 0x79,
        0xE2, 0xF0, 0x4C, 0x28, 0x4A, 0xD0, 0x6A, 0x44,
        0x39, 0x96, 0x49, 0xC3, 0xE2, 0xA2, 0xA8, 0xD1,
        0xEF, 0xE9, 0xB7, 0xA4, 0xE0, 0xC2, 0x71, 0x04,
        0x7A, 0xB7, 0x59, 0x08, 0xBF, 0xF7, 0xDF, 0x9E,
        0x30, 0xEC, 0xA5, 0x47, 0x74, 0x5B, 0xAE, 0x23,
        0xA8, 0x6F, 0xF9, 0xA8, 0xB5, 0x8C, 0x25, 0x38,
        0xB8, 0x8B, 0x86, 0x64, 0x01, 0x07, 0x69, 0x02,
        0xDC, 0x5F, 0x0B, 0xD7, 0x61, 0x68, 0x7B, 0x49,
        0xEA, 0xFE, 0x36, 0xD3, 0x50, 0xCB, 0xED, 0xFD,
        0xD3, 0x6C, 0x12, 0x1C, 0xF2, 0x37, 0x86, 0xBF,
        0xCF, 0x7E, 0x47, 0x07, 0x64, 0x96, 0xEA, 0xB6,
        0xBB, 0xDA, 0x77, 0x40, 0x49, 0xC2, 0xEB, 0xAB,
        0xE2, 0xDE, 0x99, 0xC4, 0xC2, 0x4F, 0x2D, 0xB7,
        0x36, 0x84, 0x01, 0x5B, 0x37, 0x39, 0x77, 0x49,
        0x67, 0x60, 0xCF, 0x9A, 0xC2, 0x3D, 0x8B, 0x62,
        0x31, 0x33, 0xDB, 0x2D, 0xE1, 0x0D, 0x73, 0xFA,
        0x6A, 0xD1, 0xC6, 0xDA, 0xC8, 0x43, 0x4F, 0x28,
        0xC6, 0xE2, 0x51, 0xCE, 0x72, 0x93, 0xCF, 0xF3,
        0xF3, 0xB6, 0x1E, 0xFC, 0xB5, 0xA4, 0x35, 0x12,
        0x36, 0x70, 0xF2, 0x98, 0x46, 0xA1, 0x3D, 0xF3,
        0xEE, 0x71, 0x26, 0x04, 0x46, 0x1F, 0x1B, 0xAB,
        0x8F, 0x4E, 0xBC, 0x83, 0x6D, 0xE0, 0x58, 0x97,
        0x8A, 0xE7, 0x34, 0x39, 0x6A, 0x98, 0x08, 0x1B,
        0x35, 0xCC, 0x98, 0x18, 0x8A, 0x86, 0x94, 0x9C,
        0x99, 0x27, 0x0D, 0x47, 0x09, 0x85, 0x4C, 0x5B,
        0x35, 0xB1, 0x7F, 0x48, 0xA3, 0x73, 0x13, 0x4C,
        0x81, 0x4C, 0xC8, 0xA0, 0xF3, 0xE2, 0xFA, 0x80,
        0x7F, 0x2A, 0x91, 0x85, 0x30, 0x90, 0x78, 0x64,
        0x77, 0x82, 0x82, 0xD7, 0x5E, 0x03, 0xA4, 0x1B,
        0x25, 0x04, 0xEE, 0xD8, 0x16, 0xA4, 0x17, 0xA3,
        0xAC, 0x6B, 0xA1, 0x60, 0x80, 0xC3, 0x9B, 0x73,
        0x10, 0x19, 0x20, 0x02, 0xA7, 0x28, 0xF7, 0xF2,
        0x03, 0x95, 0x00, 0x9A, 0x9E, 0x16, 0x76, 0x7C,
        0xE1, 0x97, 0x1F, 0x5D, 0xE7, 0xD2, 0x29, 0xA5,
        0x06, 0x13, 0x36, 0x9E, 0x43, 0x82, 0x04, 0x5A,
        0x8E, 0x81, 0x90, 0x1F, 0x4D, 0xBA, 0x81, 0x02,
        0xF3, 0xD4, 0x13, 0xFE, 0x35, 0xB3, 0x26, 0xA8,
        0x74, 0xF2, 0x33, 0xB7, 0x19, 0xA7, 0x13, 0x76,
        0x00, 0xD3, 0x5D, 0x33, 0xAE, 0xB6, 0xB7, 0x25,
        0x96, 0x24, 0x08, 0x3A, 0xA9, 0x68, 0x73, 0x0C,
        0x8F, 0x78, 0x29, 0x2A, 0xD2, 0x8F, 0x14, 0xEE,
        0xAB, 0xE6, 0x60, 0x83, 0x59, 0x84, 0xFE, 0x69,
        0xEF, 0x23, 0xDE, 0xC8, 0xC3, 0x27, 0xC0, 0xEB,
        0x0B, 0x88, 0x2D, 0x58, 0x7E, 0x1E, 0xC4, 0x33,
        0xDA, 0x85, 0xC9, 0xFD, 0x1E, 0x0A, 0x34, 0x99,
        0x4D, 0xEA, 0x24, 0x0C, 0x85, 0x44, 0x52, 0xD1,
        0x8C, 0x30, 0xF4, 0x96, 0xE4, 0x9E, 0xC9, 0x04,
        0xB6, 0x02, 0xE0, 0xF5, 0x06, 0x2E, 0xDC, 0xDA,
        0x03, 0x28, 0x0A, 0x53, 0xB4, 0x31, 0x35, 0x74,
        0xCC, 0x2C, 0x0D, 0x54, 0x71, 0xBC, 0x96, 0x13,
        0xBD, 0xFD, 0x66, 0x41, 0xF5, 0xBD, 0x12, 0x7B,
        0xAB, 0x5B, 0x5E, 0xB3, 0xD4, 0x99, 0xA3, 0x31,
        0x14, 0x04, 0x82, 0x20, 0xE8, 0x19, 0xF8, 0xEE,
        0x12, 0xCA, 0x92, 0x2C, 0x8F, 0x17, 0xD9, 0xC9,
        0xF5, 0x1A, 0xD5, 0xBD, 0x68, 0x83, 0xB1, 0x0E,
        0x6A, 0xA2, 0x48, 0x3B, 0xA4, 0x9D, 0xC5, 0x47,
        0xDA, 0x76, 0x86, 0x15, 0x13, 0x44, 0xF4, 0xE9,
        0x09, 0x9B, 0x38, 0xE4, 0x30, 0xB5, 0x22, 0x6B,
        0x05, 0x98, 0x32, 0xCF, 0x03, 0xDB, 0x48, 0xFB,
        0x02, 0xDB, 0xA4, 0xE6, 0x15, 0x93, 0xDC, 0x45,
        0x76, 0x36, 0x04, 0x91, 0x89, 0x0E, 0x53, 0xEC,
        0x0E, 0x6A, 0xC7, 0x3C, 0xF3, 0x2B, 0x25, 0xD8,
        0x23, 0xB3, 0x84, 0x56, 0xE2, 0x86, 0x50, 0x5A,
        0x54, 0x1E, 0x5A, 0xEE, 0xE9, 0x6B, 0x19, 0x14,
        0xF5, 0xF7, 0x66, 0x87, 0xCE, 0x2B, 0x01, 0x60,
        0x22, 0x7A, 0xBE, 0xD7, 0x79, 0x93, 0x59, 0x4B,
        0xCD, 0x83, 0x13, 0x66, 0x20, 0x6D, 0x75, 0x71,
        0x40, 0x82, 0xF1, 0xC4, 0x6F, 0x1F, 0x44, 0x39,
        0xAC, 0x81, 0xA5, 0x7A, 0xF3, 0x1C, 0x81, 0xC5,
        0x55, 0x30, 0x7A, 0x07, 0x0F, 0xFA, 0x94, 0xE0,
        0x47, 0x9B, 0x78, 0x4B, 0xBD, 0x88, 0xA6, 0x0C,
        0xD4, 0xC7, 0xCF, 0xD9, 0x4E, 0x6A, 0xFE, 0x02,
        0xF6, 0xB2, 0x1F, 0x72, 0xAF, 0x0D, 0xCD, 0x66,
        0x09, 0xD4, 0x0C, 0x96, 0x5C, 0x14, 0xE5, 0xF2,
        0x38, 0x91, 0x83, 0xE5, 0x3D, 0xE9, 0x30, 0xF7,
        0xDE, 0x1D, 0x44, 0x21, 0x5C, 0xF4, 0x91, 0x44,
        0x84, 0x4E, 0x8B, 0x87, 0xF7, 0x8A, 0x7F, 0x13,
        0x2A, 0xEF, 0xE2, 0x2B, 0xE8, 0x0B, 0x4E, 0x3A,
        0x05, 0xEE, 0x3A, 0x68, 0xCC, 0xF6, 0x09, 0xEF,
        0x44, 0x04, 0x74, 0x02, 0xE4, 0x49, 0x30, 0x46,
        0xE6, 0xF9, 0xC7, 0x67, 0xFF, 0x8A, 0x75, 0xE2,
        0x8B, 0x3C, 0xE0, 0x77, 0xFD, 0xE7, 0xE7, 0xEE,
        0xD3, 0x13, 0xB5, 0xBF, 0x7E, 0x46, 0x01, 0x27,
        0xCA, 0x81, 0x82, 0xE9, 0xBC, 0x79, 0x4C, 0x0D,
        0xFA, 0x73, 0x0F, 0xB9, 0x20, 0x08, 0x05, 0x75,
        0xA7, 0x51, 0xB5, 0xCA, 0xEC, 0x85, 0xA1, 0x09,
        0xB4, 0x42, 0x2B, 0xA2, 0x66, 0x74, 0x3F, 0x0D,
        0x03, 0x2B, 0xDA, 0x8F, 0x1C, 0xA6, 0x24, 0x8C,
        0xDB, 0x91, 0x75, 0x30, 0xDF, 0x13, 0x02, 0xA5,
        0xF8, 0xC1, 0x8D, 0xC6, 0x42, 0xD5, 0x24, 0x78,
        0xC9, 0x8C, 0x12, 0xA3, 0xF1, 0x6E, 0xF2, 0xB6,
        0x2B, 0x4F, 0x59, 0xEA, 0x1B, 0xB5, 0x8D, 0xE7,
        0xB6, 0x5B, 0x3C, 0x71, 0x53, 0xCE, 0x6D, 0xA5,
        0xE4, 0x95, 0x07, 0x46, 0xF8, 0x0E, 0x08, 0x7A,
        0x0E, 0x35, 0x86, 0xD0, 0x97, 0x79, 0x1B, 0xF3,
        0x6D, 0xEF, 0x86, 0x5D, 0x68, 0x59, 0x1D, 0x39,
        0xD0, 0x90, 0x37, 0x73, 0xEE, 0xA9, 0x62, 0x14,
        0x7F, 0x34, 0x70, 0x41, 0x38, 0xB5, 0x4D, 0xF7,
        0x92, 0x4C, 0xDD, 0x8C, 0x33, 0x3D, 0xB5, 0xE1,
        0xA4, 0x09, 0xCC, 0xB2, 0xB3, 0x4E, 0x2C, 0x3C,
        0x8C, 0x7F, 0xDD, 0x3F, 0xD8, 0xD0, 0x12, 0xCB,
        0xF3, 0x82, 0xAA, 0xA8, 0x5E, 0x83, 0xA1, 0x2F,
        0x23, 0x5A, 0x2D, 0x14, 0x7D, 0x03, 0x5B, 0x7B,
        0x28, 0xB3, 0x4B, 0x6F, 0x57, 0x94, 0x9F, 0x32,
        0x24, 0x82, 0xA7, 0xD4, 0xD3, 0xB1, 0x50, 0x45,
        0xC4, 0x20, 0xD5, 0xAD, 0xDC, 0x7F, 0x0E, 0x69,
        0xB4, 0xDC, 0x1C, 0xBA, 0x58, 0xB0, 0x1D, 0x87,
        0x24, 0x80, 0xB0, 0x6A, 0x26, 0x0D, 0x82, 0x7D,
        0x89, 0x1B, 0x13, 0xC4, 0xC5, 0xCA, 0x50, 0xC7,
        0x48, 0xDE, 0x3C, 0x77, 0x1B, 0xE6, 0x1E, 0x9A,
        0xA1, 0x70, 0x16, 0x5C, 0xB0, 0x1F, 0x4B, 0xF5,
        0xDA, 0x27, 0xA7, 0x79, 0x1D, 0x3A, 0xD3, 0xF6,
        0x26, 0x7B, 0x4C, 0xB4, 0xE6, 0x1B, 0x28, 0xFA,
        0x17, 0x08, 0x41, 0x8D, 0x93, 0x2D, 0xFC, 0x41,
        0x61, 0x88, 0x0C, 0x5D, 0x3B, 0x17, 0xA9, 0x66,
        0x3A, 0x90, 0x61, 0xFA, 0x8F, 0x18, 0x04, 0x31,
        0x58, 0x50, 0xFE, 0x4E, 0x73, 0x06, 0xC8, 0x82,
        0xB3, 0x82, 0x27, 0xE8, 0x67, 0xF8, 0x08, 0x72,
        0xCD, 0xC1, 0x94, 0x4D, 0x47, 0x26, 0x15, 0xEA,
        0x49, 0x00, 0xEF, 0x7D, 0x27, 0x0B, 0x88, 0x1D,
        0x41, 0x30, 0xF5, 0x6C, 0x5C, 0xC9, 0x80, 0xD9,
        0x2A, 0x47, 0xAD, 0xA6, 0x65, 0x7E, 0xB6, 0xF3,
        0x7A, 0x38, 0x5D, 0x2D, 0x8C, 0xC9, 0x93, 0xE1,
        0x44, 0x2E, 0xB0, 0x52, 0x81, 0x85, 0x36, 0x36,
        0x99, 0x1E, 0x34, 0xAA, 0xDC, 0x68, 0x95, 0x4D,
        0x04, 0xE7, 0xAD, 0xEF, 0x76, 0xBF, 0x88, 0x0F,
        0x05, 0x9B, 0x0C, 0xBB, 0x55, 0xD9, 0x15, 0xA4,
        0xB1, 0x23, 0xE2, 0xF1, 0x33, 0x9A, 0x07, 0x3C,
        0xBF, 0xBC, 0x40, 0x9B, 0xEF, 0xF6, 0x40, 0x0A,
        0xE0, 0x96, 0xD5, 0xAE, 0x18, 0xEC, 0x42, 0xCF,
        0xFA, 0xD5, 0xB4, 0x98, 0x0F, 0xA3, 0x5B, 0xF0,
        0x34, 0x13, 0xAD, 0xB5, 0xD7, 0xE6, 0x87, 0x6A,
        0xC3, 0x55, 0xD1, 0xC9, 0xED, 0x70, 0xCA, 0x2B,
        0x97, 0x39, 0x54, 0xD1, 0x2B, 0x3C, 0xDD, 0x76,
        0xAC, 0x68, 0x35, 0xDB, 0x96, 0x00, 0x3E, 0xD8,
        0xC4, 0xE2, 0x88, 0xB7, 0x1F, 0xD7, 0x7D, 0xBA,
        0xA7, 0x63, 0x57, 0x20, 0xE1, 0x2A, 0xE0, 0xA3,
        0x17, 0xDE, 0x80, 0x8C, 0x66, 0x4E, 0x31, 0x7F,
        0x55, 0x27, 0x57, 0x91, 0xF3, 0x24, 0x5C, 0xA4,
        0xFE, 0x5D, 0x4D, 0x41, 0x07, 0x7F, 0xC1, 0x50,
        0xA6, 0xE4, 0x03, 0xD5, 0xA2, 0x08, 0xE4, 0x6E,
        0xAD, 0xBE, 0x8F, 0x2C, 0xFB, 0x8A, 0xF4, 0x72,
        0xF4, 0xA0, 0xCE, 0xAC, 0x01, 0x52, 0x19, 0x47,
        0x8E, 0x6B, 0x86, 0xC9, 0x58, 0xCF, 0x86, 0x52,
        0x5B, 0x74, 0x85, 0xC1, 0x73, 0x4C, 0x7E, 0xF0,
        0x0E, 0x90, 0x68, 0x3F, 0xFF, 0x5D, 0xBD, 0x0A,
        0x7D, 0x41, 0x3A, 0x85, 0x50, 0x21, 0x02, 0x6A,
        0x1B, 0x32, 0x01, 0x3A, 0x46, 0x16, 0xCB, 0xCD,
        0x37, 0x00, 0xAC, 0xBC, 0x70, 0x5B, 0xE3, 0xEF,
        0xBA, 0x62, 0x5C, 0x69, 0xA0, 0x25, 0x26, 0x7B,
        0xCE, 0x9D, 0x13, 0x5E, 0x3F, 0x5B, 0x5C, 0xC8,
        0xC4, 0x39, 0x56, 0x40, 0x7E, 0x84, 0xB6, 0x66,
        0x31, 0x03, 0xE2, 0x9C, 0x24, 0x20, 0x35, 0x55,
        0x1A, 0xE7, 0x97, 0xF5, 0x6C, 0x63, 0x74, 0xBE,
        0x0C, 0x79, 0x8C, 0x0C, 0xF3, 0x98, 0xF1, 0xED
    };
    static const byte sk_65[] = {
        0xD2, 0xFD, 0x03, 0xF3, 0xA1, 0xB7, 0xF6, 0x35,
        0xAF, 0x9F, 0x34, 0xD5, 0x80, 0xA9, 0x8F, 0x52,
        0x4C, 0x73, 0x5B, 0xD5, 0xBA, 0x23, 0x55, 0xDC,
        0x6E, 0x03, 0x5B, 0xD2, 0x17, 0x65, 0x58, 0x0C,
        0xE3, 0x8D, 0x1C, 0x14, 0xF6, 0x46, 0x7C, 0x35,
        0xA9, 0xF3, 0x80, 0xD2, 0x7D, 0xE6, 0x1F, 0x7C,
        0x75, 0x03, 0x15, 0x69, 0xEA, 0x2E, 0xC8, 0x26,
        0x0E, 0xEE, 0x91, 0x05, 0x26, 0x1B, 0x7F, 0xE1,
        0x60, 0xC9, 0x13, 0x44, 0xB0, 0xC6, 0x76, 0x4C,
        0x20, 0x4E, 0x5B, 0x8D, 0x42, 0x46, 0x50, 0xBE,
        0xC0, 0x6B, 0x9E, 0x2E, 0x62, 0x5A, 0xF0, 0x7E,
        0x23, 0xF4, 0x95, 0x0C, 0xA2, 0x4F, 0xB4, 0xD6,
        0xEC, 0x2C, 0x8B, 0x3A, 0x71, 0x7C, 0x93, 0x11,
        0xEB, 0x87, 0x27, 0x9F, 0xE2, 0x5E, 0x31, 0x1F,
        0x48, 0xB8, 0x25, 0x65, 0x01, 0xF6, 0x46, 0x34,
        0x12, 0xB5, 0x0D, 0xBC, 0x89, 0xA8, 0x69, 0xBA,
        0x22, 0x41, 0x11, 0x26, 0x48, 0x40, 0x07, 0x38,
        0x73, 0x02, 0x12, 0x44, 0x25, 0x44, 0x57, 0x54,
        0x83, 0x72, 0x50, 0x33, 0x35, 0x62, 0x58, 0x42,
        0x32, 0x01, 0x62, 0x11, 0x83, 0x61, 0x02, 0x45,
        0x66, 0x56, 0x48, 0x35, 0x61, 0x20, 0x84, 0x52,
        0x60, 0x68, 0x50, 0x45, 0x65, 0x55, 0x12, 0x72,
        0x47, 0x47, 0x21, 0x21, 0x25, 0x40, 0x22, 0x21,
        0x42, 0x81, 0x17, 0x65, 0x03, 0x06, 0x42, 0x61,
        0x52, 0x13, 0x43, 0x25, 0x24, 0x33, 0x82, 0x12,
        0x11, 0x35, 0x62, 0x33, 0x32, 0x07, 0x47, 0x86,
        0x22, 0x31, 0x50, 0x83, 0x70, 0x84, 0x26, 0x43,
        0x45, 0x64, 0x51, 0x48, 0x31, 0x14, 0x86, 0x24,
        0x66, 0x86, 0x74, 0x33, 0x71, 0x36, 0x67, 0x26,
        0x01, 0x47, 0x07, 0x72, 0x11, 0x61, 0x58, 0x85,
        0x58, 0x38, 0x71, 0x83, 0x80, 0x67, 0x01, 0x65,
        0x78, 0x70, 0x64, 0x77, 0x85, 0x60, 0x02, 0x88,
        0x53, 0x48, 0x46, 0x62, 0x25, 0x83, 0x54, 0x88,
        0x04, 0x74, 0x40, 0x12, 0x57, 0x43, 0x71, 0x07,
        0x75, 0x44, 0x38, 0x71, 0x21, 0x14, 0x22, 0x08,
        0x88, 0x72, 0x23, 0x58, 0x87, 0x46, 0x14, 0x85,
        0x53, 0x71, 0x67, 0x73, 0x82, 0x28, 0x22, 0x74,
        0x14, 0x03, 0x57, 0x73, 0x28, 0x71, 0x83, 0x80,
        0x78, 0x14, 0x34, 0x87, 0x52, 0x07, 0x64, 0x74,
        0x01, 0x60, 0x75, 0x61, 0x06, 0x08, 0x61, 0x32,
        0x21, 0x46, 0x15, 0x65, 0x42, 0x67, 0x08, 0x20,
        0x84, 0x10, 0x73, 0x13, 0x03, 0x61, 0x02, 0x86,
        0x50, 0x45, 0x26, 0x12, 0x16, 0x68, 0x33, 0x55,
        0x25, 0x84, 0x73, 0x53, 0x54, 0x52, 0x65, 0x17,
        0x10, 0x60, 0x00, 0x38, 0x57, 0x77, 0x81, 0x24,
        0x26, 0x80, 0x41, 0x46, 0x43, 0x26, 0x67, 0x41,
        0x06, 0x03, 0x55, 0x41, 0x28, 0x33, 0x37, 0x25,
        0x23, 0x06, 0x77, 0x82, 0x15, 0x16, 0x31, 0x73,
        0x00, 0x08, 0x75, 0x26, 0x58, 0x46, 0x34, 0x63,
        0x88, 0x08, 0x84, 0x64, 0x51, 0x11, 0x24, 0x05,
        0x32, 0x10, 0x11, 0x18, 0x18, 0x64, 0x78, 0x22,
        0x41, 0x00, 0x38, 0x55, 0x75, 0x42, 0x10, 0x46,
        0x83, 0x43, 0x73, 0x38, 0x80, 0x07, 0x83, 0x43,
        0x78, 0x74, 0x13, 0x57, 0x62, 0x32, 0x68, 0x80,
        0x65, 0x86, 0x48, 0x53, 0x48, 0x35, 0x51, 0x58,
        0x50, 0x74, 0x46, 0x05, 0x88, 0x70, 0x07, 0x72,
        0x01, 0x31, 0x00, 0x87, 0x54, 0x88, 0x14, 0x20,
        0x84, 0x16, 0x61, 0x15, 0x60, 0x56, 0x85, 0x11,
        0x58, 0x08, 0x05, 0x88, 0x63, 0x01, 0x82, 0x86,
        0x13, 0x14, 0x17, 0x22, 0x01, 0x68, 0x17, 0x17,
        0x86, 0x58, 0x53, 0x10, 0x62, 0x28, 0x52, 0x82,
        0x26, 0x15, 0x04, 0x31, 0x42, 0x88, 0x54, 0x31,
        0x78, 0x05, 0x80, 0x11, 0x50, 0x45, 0x68, 0x82,
        0x33, 0x66, 0x36, 0x36, 0x40, 0x65, 0x15, 0x24,
        0x47, 0x67, 0x06, 0x45, 0x36, 0x42, 0x26, 0x86,
        0x75, 0x06, 0x35, 0x41, 0x33, 0x47, 0x85, 0x12,
        0x17, 0x80, 0x83, 0x87, 0x65, 0x51, 0x42, 0x31,
        0x38, 0x87, 0x56, 0x62, 0x05, 0x17, 0x40, 0x85,
        0x28, 0x14, 0x17, 0x21, 0x38, 0x12, 0x60, 0x81,
        0x24, 0x41, 0x45, 0x75, 0x01, 0x82, 0x87, 0x10,
        0x10, 0x02, 0x13, 0x25, 0x57, 0x04, 0x21, 0x72,
        0x42, 0x78, 0x61, 0x11, 0x70, 0x05, 0x30, 0x47,
        0x72, 0x13, 0x20, 0x30, 0x21, 0x67, 0x44, 0x31,
        0x57, 0x71, 0x45, 0x57, 0x10, 0x54, 0x16, 0x65,
        0x74, 0x15, 0x24, 0x02, 0x43, 0x71, 0x51, 0x20,
        0x55, 0x11, 0x67, 0x83, 0x67, 0x82, 0x52, 0x53,
        0x35, 0x66, 0x42, 0x46, 0x13, 0x70, 0x22, 0x32,
        0x74, 0x00, 0x07, 0x06, 0x81, 0x87, 0x17, 0x57,
        0x80, 0x28, 0x68, 0x01, 0x72, 0x10, 0x04, 0x27,
        0x55, 0x22, 0x86, 0x42, 0x53, 0x15, 0x81, 0x76,
        0x30, 0x86, 0x40, 0x83, 0x11, 0x43, 0x30, 0x53,
        0x82, 0x73, 0x53, 0x03, 0x72, 0x35, 0x68, 0x70,
        0x45, 0x41, 0x15, 0x73, 0x14, 0x12, 0x31, 0x64,
        0x32, 0x66, 0x63, 0x56, 0x21, 0x51, 0x50, 0x82,
        0x10, 0x30, 0x23, 0x38, 0x17, 0x21, 0x27, 0x10,
        0x23, 0x14, 0x22, 0x75, 0x77, 0x28, 0x37, 0x71,
        0x62, 0x75, 0x06, 0x88, 0x72, 0x14, 0x18, 0x73,
        0x13, 0x03, 0x01, 0x50, 0x71, 0x58, 0x62, 0x86,
        0x62, 0x88, 0x86, 0x86, 0x03, 0x27, 0x01, 0x46,
        0x17, 0x22, 0x71, 0x38, 0x53, 0x81, 0x70, 0x33,
        0x88, 0x68, 0x13, 0x78, 0x81, 0x04, 0x86, 0x57,
        0x30, 0x16, 0x52, 0x31, 0x40, 0x83, 0x07, 0x56,
        0x82, 0x10, 0x32, 0x31, 0x28, 0x50, 0x06, 0x50,
        0x81, 0x63, 0x06, 0x75, 0x76, 0x65, 0x11, 0x60,
        0x14, 0x17, 0x12, 0x12, 0x55, 0x56, 0x48, 0x11,
        0x41, 0x13, 0x28, 0x82, 0x62, 0x07, 0x47, 0x64,
        0x24, 0x48, 0x23, 0x24, 0x77, 0x53, 0x26, 0x08,
        0x17, 0x58, 0x11, 0x56, 0x37, 0x48, 0x35, 0x51,
        0x47, 0x86, 0x85, 0x66, 0x66, 0x81, 0x73, 0x20,
        0x21, 0x36, 0x75, 0x22, 0x74, 0x66, 0x83, 0x44,
        0x57, 0x00, 0x66, 0x64, 0x77, 0x20, 0x47, 0x22,
        0x28, 0x56, 0x87, 0x12, 0x47, 0x02, 0x48, 0x07,
        0x02, 0x54, 0x23, 0x01, 0x25, 0x71, 0x37, 0x36,
        0x75, 0x36, 0x00, 0x52, 0x68, 0x15, 0x33, 0x35,
        0x82, 0x06, 0x13, 0x73, 0x24, 0x08, 0x71, 0x76,
        0x15, 0x22, 0x42, 0x60, 0x18, 0x53, 0x43, 0x11,
        0x64, 0x57, 0x76, 0x17, 0x61, 0x56, 0x68, 0x76,
        0x60, 0x65, 0x54, 0x78, 0x10, 0x33, 0x63, 0x14,
        0x21, 0x83, 0x21, 0x60, 0x15, 0x55, 0x80, 0x42,
        0x38, 0x42, 0x03, 0x13, 0x12, 0x34, 0x36, 0x25,
        0x27, 0x30, 0x82, 0x81, 0x25, 0x47, 0x51, 0x35,
        0x44, 0x12, 0x67, 0x35, 0x00, 0x10, 0x01, 0x83,
        0x85, 0x74, 0x42, 0x40, 0x13, 0x03, 0x61, 0x27,
        0x81, 0x26, 0x26, 0x81, 0x18, 0x87, 0x43, 0x51,
        0x20, 0x62, 0x71, 0x27, 0x51, 0x56, 0x10, 0x22,
        0x22, 0x81, 0x11, 0x81, 0x41, 0x66, 0x66, 0x38,
        0x20, 0x86, 0x75, 0x56, 0x12, 0x40, 0x06, 0x54,
        0x61, 0x12, 0x74, 0x40, 0x34, 0x58, 0x58, 0x78,
        0x10, 0x07, 0x85, 0x25, 0x72, 0x88, 0x57, 0x22,
        0x22, 0x25, 0x50, 0x84, 0x00, 0x41, 0x26, 0x08,
        0x36, 0x46, 0x28, 0x78, 0x46, 0x78, 0x05, 0x02,
        0x28, 0x20, 0x77, 0x13, 0x60, 0x75, 0x14, 0x43,
        0x68, 0x78, 0x64, 0x31, 0x38, 0x77, 0x73, 0x73,
        0x55, 0x41, 0x27, 0x00, 0x54, 0x07, 0x08, 0x28,
        0x68, 0x80, 0x04, 0x53, 0x83, 0x43, 0x22, 0x81,
        0x00, 0x64, 0x35, 0x48, 0x67, 0x66, 0x50, 0x17,
        0x75, 0x76, 0x12, 0x75, 0x43, 0x81, 0x62, 0x40,
        0x33, 0x43, 0x45, 0x38, 0x87, 0x21, 0x66, 0x14,
        0x70, 0x48, 0x41, 0x43, 0x14, 0x66, 0x58, 0x78,
        0x45, 0x82, 0x02, 0x25, 0x45, 0x73, 0x15, 0x21,
        0x32, 0x03, 0x02, 0x48, 0x80, 0x80, 0x13, 0x71,
        0x25, 0x54, 0x32, 0x72, 0x05, 0x68, 0x65, 0x24,
        0x68, 0x04, 0x06, 0x16, 0x83, 0x50, 0x54, 0x53,
        0x37, 0x37, 0x27, 0x22, 0x20, 0x68, 0x08, 0x25,
        0x50, 0x84, 0x72, 0x86, 0x74, 0x22, 0x36, 0x16,
        0x80, 0x07, 0x55, 0x18, 0x12, 0x17, 0x84, 0x44,
        0x81, 0x15, 0x64, 0x50, 0x71, 0x10, 0x58, 0x15,
        0x51, 0x10, 0x10, 0x47, 0x16, 0x21, 0x07, 0x58,
        0x61, 0x18, 0x78, 0x00, 0x52, 0x72, 0x64, 0x52,
        0x17, 0x43, 0x23, 0x40, 0x76, 0x48, 0x67, 0x30,
        0x77, 0x63, 0x64, 0x87, 0x51, 0x31, 0x63, 0x84,
        0x68, 0x74, 0x53, 0x63, 0x84, 0x23, 0x54, 0x66,
        0x10, 0x48, 0x36, 0x33, 0x85, 0x21, 0x48, 0x42,
        0x03, 0x82, 0x51, 0x10, 0x33, 0x57, 0x46, 0x80,
        0x16, 0x43, 0x34, 0x02, 0x07, 0x03, 0x53, 0x22,
        0x12, 0x75, 0x73, 0x34, 0x65, 0x83, 0x33, 0x87,
        0x43, 0x85, 0x17, 0x50, 0x36, 0x60, 0x88, 0x02,
        0x58, 0x75, 0x80, 0x88, 0x31, 0x63, 0x60, 0x18,
        0x21, 0x32, 0x26, 0x15, 0x68, 0x74, 0x11, 0x10,
        0x33, 0x14, 0x13, 0x05, 0x34, 0x16, 0x72, 0x65,
        0x35, 0x50, 0x13, 0x34, 0x80, 0x87, 0x10, 0x26,
        0x48, 0x68, 0x84, 0x52, 0x71, 0x44, 0x23, 0x58,
        0x80, 0x35, 0x57, 0x70, 0x54, 0x84, 0x28, 0x70,
        0x55, 0x88, 0x86, 0x83, 0x86, 0x25, 0x21, 0x82,
        0x72, 0x61, 0x17, 0x78, 0x85, 0x17, 0x67, 0x73,
        0x00, 0x57, 0x71, 0x11, 0x78, 0x51, 0x10, 0x65,
        0x63, 0x57, 0x02, 0x87, 0x40, 0x13, 0x40, 0x01,
        0x26, 0x53, 0x45, 0x12, 0x05, 0x46, 0x75, 0x18,
        0x80, 0x70, 0x33, 0x35, 0x66, 0x22, 0x62, 0x00,
        0x70, 0x23, 0x26, 0x87, 0x72, 0x63, 0x11, 0x13,
        0x33, 0x33, 0x81, 0x41, 0x70, 0x62, 0x28, 0x61,
        0x51, 0x47, 0x31, 0x30, 0x25, 0x46, 0x51, 0x17,
        0x61, 0x58, 0x07, 0x41, 0x61, 0x37, 0x37, 0x06,
        0x14, 0x00, 0x54, 0x88, 0x77, 0x75, 0x67, 0x77,
        0x66, 0x53, 0x16, 0x72, 0x66, 0x66, 0x88, 0x76,
        0x43, 0x58, 0x31, 0x04, 0x87, 0x57, 0x06, 0x76,
        0x47, 0x00, 0x43, 0x63, 0x58, 0x60, 0x52, 0x03,
        0x44, 0x27, 0x36, 0x48, 0x61, 0x23, 0x72, 0x16,
        0x10, 0x62, 0x42, 0x08, 0x60, 0x83, 0x23, 0x54,
        0x03, 0x55, 0x55, 0x73, 0x00, 0x61, 0x03, 0x65,
        0x34, 0x27, 0x14, 0x15, 0x86, 0x62, 0x55, 0x80,
        0x16, 0x53, 0x10, 0x18, 0x26, 0x11, 0x35, 0x46,
        0x82, 0x46, 0x13, 0x25, 0x83, 0x47, 0x70, 0x50,
        0x06, 0x01, 0x56, 0x02, 0x11, 0x68, 0x54, 0x53,
        0x03, 0x68, 0x73, 0x36, 0x41, 0x88, 0x86, 0x33,
        0x42, 0x52, 0x01, 0x58, 0x33, 0x42, 0x32, 0x88,
        0x56, 0x81, 0x77, 0x55, 0x51, 0x48, 0x48, 0x12,
        0x01, 0x58, 0x13, 0x85, 0x04, 0x14, 0x71, 0x83,
        0x57, 0x07, 0x54, 0x55, 0x54, 0x55, 0x28, 0x27,
        0x31, 0x36, 0x02, 0x12, 0x32, 0x68, 0x32, 0x13,
        0x82, 0x58, 0x70, 0x28, 0x58, 0x53, 0x44, 0x86,
        0x72, 0x73, 0x42, 0x84, 0x18, 0x22, 0x08, 0x83,
        0x61, 0x02, 0x14, 0x16, 0x17, 0x12, 0x41, 0x57,
        0x48, 0x85, 0x25, 0x10, 0x26, 0x07, 0x36, 0x76,
        0x12, 0x66, 0x17, 0x21, 0x32, 0x36, 0x03, 0x25,
        0x41, 0x10, 0x11, 0x22, 0x66, 0x60, 0x16, 0x16,
        0x32, 0x64, 0x26, 0x05, 0x18, 0x63, 0x51, 0x58,
        0x51, 0x31, 0x42, 0x53, 0x84, 0x56, 0x66, 0x27,
        0x83, 0x33, 0x54, 0x50, 0x76, 0x46, 0x50, 0x80,
        0x25, 0x43, 0x41, 0x57, 0x35, 0x78, 0x25, 0x43,
        0x02, 0x82, 0x38, 0x47, 0x45, 0x70, 0x15, 0x67,
        0x51, 0x77, 0x47, 0x80, 0x31, 0x52, 0x75, 0x00,
        0x00, 0x94, 0x7B, 0xCA, 0x93, 0xC2, 0x7D, 0x58,
        0x4E, 0x2C, 0x66, 0xEA, 0xC9, 0xC7, 0x64, 0x0C,
        0x1C, 0xA2, 0x17, 0xEE, 0xF6, 0x6D, 0xAB, 0xBC,
        0xB2, 0x60, 0xB4, 0xC3, 0x43, 0x00, 0xFA, 0x05,
        0x13, 0x57, 0x82, 0x0F, 0x57, 0x39, 0x25, 0x44,
        0x98, 0x2F, 0xD1, 0x10, 0x57, 0xDE, 0x23, 0x3E,
        0x6D, 0x2D, 0xD8, 0x49, 0x72, 0xA7, 0xE4, 0x7D,
        0x4D, 0xBA, 0x99, 0xBC, 0x30, 0xCF, 0x8F, 0x2A,
        0xD5, 0xA2, 0xC0, 0x24, 0x31, 0x95, 0xED, 0x27,
        0x30, 0xFF, 0xA9, 0x2D, 0x22, 0x7D, 0x15, 0x30,
        0x95, 0x97, 0x2D, 0x4B, 0x34, 0x47, 0xFF, 0xAC,
        0x45, 0xA2, 0x3E, 0xB4, 0x1C, 0xBC, 0x87, 0xCD,
        0xD1, 0x25, 0x0A, 0x8A, 0x47, 0x8B, 0x0F, 0x7A,
        0x1D, 0x5B, 0x39, 0xAA, 0x22, 0x06, 0xE4, 0x86,
        0x45, 0x58, 0x4F, 0xE7, 0xBF, 0x7A, 0x13, 0x16,
        0x8F, 0x48, 0x27, 0x65, 0xE5, 0x7B, 0xB9, 0x24,
        0xAC, 0x6D, 0x9A, 0x11, 0x36, 0x9F, 0x4A, 0x6A,
        0xFF, 0xCD, 0x16, 0x9B, 0x7D, 0x75, 0x12, 0x9B,
        0x35, 0xD5, 0x13, 0x4A, 0x31, 0x76, 0x1B, 0xB8,
        0x35, 0x5A, 0xEE, 0xED, 0x27, 0xE2, 0x01, 0xA0,
        0x63, 0x13, 0x01, 0x3E, 0x30, 0x7A, 0x01, 0xA7,
        0x3A, 0xEA, 0x79, 0x55, 0xC0, 0x57, 0x8C, 0x8C,
        0x5E, 0x5A, 0x1A, 0x2D, 0x2F, 0xA4, 0x59, 0x3F,
        0xAC, 0xD9, 0x04, 0xC6, 0x20, 0x40, 0xBD, 0xB9,
        0xF3, 0x29, 0x93, 0x35, 0x36, 0xBF, 0x8D, 0x81,
        0xC4, 0x25, 0x6B, 0xAA, 0xE8, 0x72, 0x3F, 0xD4,
        0xDC, 0x66, 0xBB, 0x5E, 0x7F, 0x9C, 0xA4, 0x90,
        0x31, 0xA1, 0x93, 0xEC, 0xEC, 0xBB, 0x5D, 0xC3,
        0x90, 0xEC, 0x6D, 0x55, 0x13, 0xC7, 0x9A, 0x05,
        0x2B, 0x3F, 0xD4, 0x36, 0x12, 0xFB, 0x73, 0x75,
        0x31, 0x5D, 0x80, 0x91, 0xF7, 0x9B, 0xAB, 0x13,
        0x18, 0xF1, 0x78, 0x54, 0x56, 0x1B, 0xC9, 0x3A,
        0xE0, 0xE5, 0xCD, 0x6D, 0x13, 0x1E, 0x56, 0x2C,
        0x81, 0x14, 0x81, 0x0C, 0x93, 0x9A, 0xE5, 0x63,
        0xAA, 0x10, 0xB4, 0x7C, 0xE4, 0x48, 0x43, 0x17,
        0xF3, 0x4A, 0xBD, 0x02, 0xD0, 0xCC, 0xAD, 0x58,
        0xDD, 0x29, 0xBC, 0xF6, 0x57, 0xBB, 0xD9, 0x25,
        0x4B, 0x01, 0xCA, 0x97, 0x26, 0x09, 0x19, 0x38,
        0xED, 0x32, 0x05, 0x4B, 0x37, 0xDD, 0x61, 0x72,
        0x40, 0xF4, 0x43, 0x4C, 0x1A, 0x4A, 0x87, 0x11,
        0xAA, 0x3A, 0x39, 0x9A, 0x8A, 0x53, 0x88, 0x33,
        0x0B, 0x70, 0x59, 0xEC, 0xCB, 0xB6, 0xB1, 0xB9,
        0xCF, 0x71, 0x87, 0xAD, 0xF1, 0x0B, 0x0C, 0x91,
        0x71, 0xD3, 0xC0, 0xF6, 0xE2, 0xD4, 0x60, 0xA4,
        0x19, 0x24, 0x76, 0x72, 0xE3, 0xB9, 0xFE, 0xA2,
        0xC9, 0x59, 0x10, 0xBF, 0x2F, 0xB6, 0xA5, 0xD6,
        0x1F, 0x25, 0x74, 0x53, 0xB0, 0x7A, 0xFB, 0x64,
        0xB0, 0xBA, 0x27, 0x58, 0xBC, 0xD7, 0x35, 0x75,
        0x1F, 0x2D, 0x53, 0x51, 0x5E, 0x23, 0x6F, 0xE8,
        0xA5, 0xB4, 0x39, 0x3B, 0x80, 0xBF, 0x06, 0xDF,
        0x97, 0xBD, 0xC6, 0x38, 0x00, 0x87, 0xE6, 0xAA,
        0x8D, 0xDE, 0x6E, 0x09, 0x81, 0x11, 0xA7, 0x34,
        0x3F, 0xCD, 0xD1, 0xE9, 0x03, 0x70, 0x8E, 0x63,
        0x7E, 0xBF, 0x28, 0x32, 0x3C, 0xDA, 0x6B, 0x94,
        0x05, 0x81, 0x0E, 0xDC, 0xFB, 0x36, 0x91, 0x14,
        0x9E, 0xCF, 0x22, 0x4C, 0x50, 0xF8, 0xDF, 0x92,
        0xA9, 0x4A, 0xA4, 0x77, 0x0A, 0x0E, 0x91, 0x46,
        0x61, 0x94, 0xBB, 0x0E, 0x27, 0xBF, 0x1C, 0xAB,
        0xF1, 0x6A, 0xDF, 0xD3, 0x51, 0x22, 0x00, 0x33,
        0xF7, 0x6F, 0x59, 0x25, 0x55, 0x7B, 0xCF, 0x96,
        0x34, 0xE9, 0x46, 0x13, 0x59, 0x62, 0x1D, 0x80,
        0xB4, 0xBB, 0xAD, 0x7E, 0x2A, 0x6E, 0x43, 0x2D,
        0xC4, 0x3B, 0x12, 0x6C, 0xA4, 0x2A, 0xB8, 0x8A,
        0xA8, 0x8F, 0x0A, 0x84, 0xAF, 0x58, 0x02, 0x9C,
        0x99, 0xA0, 0x24, 0x8F, 0x0C, 0x45, 0x40, 0x71,
        0xF3, 0x5B, 0x83, 0x1F, 0xED, 0x12, 0x54, 0xD6,
        0xF4, 0xE2, 0x72, 0x04, 0x85, 0x78, 0x62, 0x15,
        0xF7, 0xC7, 0xF0, 0xC4, 0xED, 0x15, 0xFA, 0x85,
        0x3C, 0xD3, 0xAA, 0x07, 0x25, 0x9B, 0x39, 0x24,
        0x0A, 0x82, 0x13, 0x5C, 0x29, 0x23, 0xA7, 0x2B,
        0x87, 0x6F, 0xAB, 0xB3, 0xF0, 0xF2, 0xC0, 0x96,
        0x13, 0xDE, 0x39, 0xD4, 0x59, 0xA0, 0x7C, 0x14,
        0xE7, 0xBA, 0x43, 0x7D, 0x80, 0x41, 0x49, 0x1F,
        0xCE, 0xC1, 0x43, 0x34, 0x04, 0xBA, 0xD1, 0xDA,
        0x9E, 0xE9, 0x47, 0x1E, 0x17, 0xCB, 0x69, 0x1B,
        0x2A, 0x35, 0x37, 0x10, 0xC9, 0xFF, 0xA4, 0xE5,
        0x17, 0x81, 0x12, 0x02, 0x77, 0x64, 0xEB, 0x7D,
        0xE8, 0x09, 0xC3, 0xE1, 0xF1, 0xFA, 0x41, 0x78,
        0xA5, 0xD4, 0xDC, 0x9E, 0xE2, 0x78, 0x57, 0xEF,
        0xF2, 0x6B, 0x91, 0x71, 0x1F, 0xC1, 0x44, 0xD5,
        0xA7, 0x75, 0xB8, 0xB5, 0x0D, 0x5D, 0xB9, 0x39,
        0xBA, 0x32, 0x07, 0x68, 0x0C, 0x24, 0x2F, 0xC8,
        0x21, 0x94, 0x7F, 0x93, 0x4C, 0x8D, 0xAE, 0xE2,
        0x03, 0x56, 0x3D, 0x28, 0x60, 0x6B, 0xE6, 0x24,
        0xA3, 0x29, 0x01, 0x93, 0x2D, 0xAE, 0x85, 0x71,
        0x2A, 0xF6, 0xC8, 0x01, 0x60, 0x26, 0x92, 0x7E,
        0x9B, 0x81, 0x29, 0x57, 0x4B, 0xE3, 0xCB, 0x1E,
        0x95, 0x33, 0x2B, 0x05, 0x27, 0x07, 0xAC, 0x8A,
        0xA8, 0xF4, 0x35, 0xE8, 0x8B, 0x7E, 0x56, 0x8D,
        0x49, 0x87, 0xC6, 0xAC, 0x0E, 0x90, 0x2B, 0x06,
        0x09, 0xA0, 0x2D, 0x91, 0xB3, 0xF5, 0xFD, 0x3F,
        0xD9, 0x01, 0xDD, 0xD0, 0xDB, 0x98, 0x73, 0xBD,
        0x7C, 0x71, 0xED, 0x92, 0x1D, 0x45, 0x77, 0xA7,
        0x8C, 0x4F, 0xCC, 0x9B, 0xF0, 0x75, 0x20, 0x3D,
        0x38, 0xF5, 0xE7, 0x6E, 0x74, 0xF2, 0x77, 0x48,
        0x4E, 0x05, 0x7B, 0x61, 0x89, 0x00, 0x41, 0x31,
        0xB0, 0xC9, 0xB1, 0xA1, 0x55, 0x29, 0x4D, 0x1C,
        0xD3, 0xD5, 0x20, 0x8E, 0x26, 0x69, 0x01, 0xD7,
        0xD3, 0x14, 0xFA, 0xCC, 0xE7, 0xE2, 0xAA, 0x58,
        0x45, 0x83, 0xA1, 0x1E, 0x4D, 0x7C, 0x21, 0xB9,
        0x4A, 0x32, 0xE5, 0x08, 0xED, 0xDB, 0xBD, 0x7A,
        0x65, 0xAA, 0x86, 0xB4, 0xFD, 0xFA, 0x6B, 0xC2,
        0x85, 0xD4, 0xCF, 0xF5, 0x39, 0x26, 0xC7, 0x17,
        0x3F, 0xBE, 0x1F, 0x89, 0xCC, 0x30, 0x32, 0x34,
        0xB8, 0x78, 0xC6, 0xB8, 0x10, 0x1F, 0x58, 0xAC,
        0x8D, 0x3E, 0x5E, 0x1B, 0xF5, 0xAB, 0x6B, 0x26,
        0x29, 0x7C, 0xC9, 0x7B, 0x95, 0x95, 0x4A, 0xAB,
        0xDB, 0x25, 0xBE, 0x00, 0x8A, 0x3F, 0x47, 0xE5,
        0x64, 0x87, 0xB0, 0x0D, 0x3D, 0xED, 0xA8, 0x90,
        0xD9, 0x2C, 0x83, 0x95, 0x7F, 0xEA, 0xC6, 0xB8,
        0x29, 0x1A, 0xF6, 0x59, 0x59, 0xE1, 0xD1, 0xFC,
        0xA3, 0xBD, 0x19, 0x6E, 0x9F, 0xC9, 0xE6, 0x7E,
        0x06, 0x07, 0x09, 0x48, 0x22, 0xE5, 0xB4, 0x19,
        0x1D, 0xB9, 0x68, 0x24, 0xB9, 0xF0, 0x3F, 0x2E,
        0xF5, 0x7F, 0x52, 0x38, 0xBA, 0x7E, 0x1E, 0x84,
        0xED, 0x55, 0xB7, 0xDF, 0xF3, 0xD6, 0xC2, 0xC1,
        0x27, 0x36, 0x92, 0xA9, 0xA1, 0x92, 0x72, 0x16,
        0x61, 0x30, 0xDB, 0x89, 0xFC, 0x67, 0xDC, 0x94,
        0xDB, 0x61, 0x4E, 0x3E, 0x82, 0xBA, 0x3A, 0x35,
        0x12, 0xB0, 0x12, 0xD5, 0x1F, 0xB4, 0x86, 0xB5,
        0xA3, 0x15, 0x0B, 0x78, 0xE7, 0x24, 0xE2, 0xA1,
        0x2D, 0xE0, 0x7D, 0x86, 0x71, 0xFB, 0xA2, 0xDA,
        0x7F, 0xD5, 0xD1, 0x47, 0x20, 0x8F, 0xC3, 0xAF,
        0x65, 0x3E, 0x65, 0x20, 0xFC, 0x40, 0x87, 0x1A,
        0xF2, 0x17, 0x7E, 0x65, 0xCB, 0xD0, 0xEA, 0xF3,
        0x04, 0x21, 0x7B, 0x36, 0x7A, 0x66, 0x5F, 0x22,
        0x4C, 0xAE, 0xDF, 0xE9, 0x30, 0x06, 0xAC, 0x1E,
        0x14, 0xBC, 0xD6, 0x7A, 0x88, 0xD1, 0x71, 0xF3,
        0xD8, 0xF3, 0xE3, 0x58, 0xA7, 0x19, 0x26, 0xBA,
        0x3E, 0x5C, 0x23, 0x9A, 0x53, 0x12, 0x63, 0xEC,
        0x94, 0x37, 0xBF, 0x2A, 0x03, 0x3B, 0x8B, 0x55,
        0xB2, 0xC0, 0xCB, 0x6E, 0x7E, 0x97, 0x31, 0x6E,
        0x22, 0xDF, 0x77, 0xCA, 0xD9, 0x10, 0xD2, 0x0E,
        0xEC, 0xE1, 0xC5, 0x09, 0x10, 0xA5, 0xCC, 0x32,
        0xAD, 0xAB, 0x09, 0x37, 0x75, 0x50, 0xF9, 0x2D,
        0x5B, 0xB1, 0xF4, 0xC0, 0x7F, 0x4A, 0x28, 0x22,
        0x33, 0x8E, 0x2C, 0xFF, 0x53, 0x48, 0xDF, 0x77,
        0xCF, 0x8E, 0xF8, 0xE6, 0x65, 0x7D, 0xED, 0x1E,
        0x0C, 0xE0, 0x58, 0xE3, 0xCC, 0xFB, 0xF3, 0x9B,
        0x3F, 0x16, 0x6E, 0x30, 0x3D, 0x33, 0xC3, 0x55,
        0x6C, 0x9A, 0xC8, 0xEC, 0xB3, 0xDF, 0x7C, 0x74,
        0xAB, 0x36, 0xD0, 0xF2, 0x79, 0x44, 0x41, 0xBA,
        0x98, 0x08, 0x82, 0x7B, 0x57, 0x8F, 0xB5, 0xC2,
        0x9E, 0x49, 0x4E, 0x21, 0x53, 0x9A, 0xD3, 0xAB,
        0x2B, 0x41, 0xBF, 0x16, 0x1D, 0x7F, 0x69, 0x58,
        0x9D, 0x45, 0x24, 0xC5, 0x4C, 0x89, 0xB4, 0x86,
        0xF7, 0x5D, 0x25, 0x2F, 0x54, 0x1C, 0xC6, 0x3B,
        0x9E, 0x70, 0x6D, 0x64, 0xA1, 0x28, 0x9A, 0x23,
        0x06, 0xC5, 0x95, 0x36, 0x3C, 0xB6, 0xFB, 0xEF,
        0x0A, 0x1B, 0x5B, 0x17, 0xAB, 0x5B, 0x17, 0x94,
        0xBF, 0x27, 0x03, 0x6F, 0x64, 0xEA, 0xF0, 0xBD,
        0x43, 0x0D, 0xD5, 0x8D, 0x80, 0x01, 0x0C, 0xCD,
        0xAD, 0xA4, 0xA5, 0xA3, 0xA1, 0xE4, 0x1A, 0x6F,
        0xBF, 0x12, 0x9D, 0x73, 0x77, 0x9A, 0x37, 0xAE,
        0x5C, 0x8D, 0x68, 0x41, 0xA9, 0x99, 0x3C, 0x51,
        0xE3, 0x64, 0xE0, 0x4F, 0xAC, 0x8E, 0x25, 0xA4,
        0xE6, 0x87, 0x2F, 0x6C, 0x86, 0x0F, 0xA2, 0x65,
        0xC1, 0xC4, 0x42, 0x6A, 0xD9, 0xC2, 0x1D, 0x26,
        0xDA, 0x8C, 0x27, 0x85, 0x46, 0xAD, 0xCD, 0x83,
        0x1F, 0x2B, 0x8B, 0x26, 0xD4, 0xE1, 0xF6, 0x70,
        0x62, 0x3D, 0x95, 0xC8, 0x36, 0x2D, 0xA6, 0x62,
        0xD1, 0xFF, 0x0A, 0xB6, 0x87, 0x50, 0x3F, 0x32,
        0x8D, 0xE0, 0x95, 0x81, 0x0E, 0xDE, 0x12, 0xB4,
        0x9E, 0xAD, 0x15, 0x33, 0x51, 0x95, 0x58, 0xC1,
        0xE9, 0x40, 0xB4, 0x6E, 0x4E, 0xDB, 0x02, 0x7B,
        0xE9, 0xDA, 0x20, 0x39, 0xB2, 0x5D, 0xCF, 0x73,
        0x57, 0xE1, 0x9E, 0x54, 0x16, 0xAE, 0x26, 0x8C,
        0x14, 0xFB, 0x3A, 0x8B, 0xAB, 0xCB, 0x3D, 0x23,
        0xF7, 0x0C, 0xC9, 0xD5, 0x96, 0x81, 0xC5, 0xD8,
        0x33, 0xAC, 0x22, 0xE6, 0x53, 0xD8, 0x6E, 0x22,
        0xCE, 0x82, 0x25, 0x40, 0x75, 0x5D, 0x8D, 0x24,
        0x3C, 0x15, 0x21, 0x3D, 0x07, 0x6C, 0x6B, 0x26,
        0x43, 0x6D, 0xDC, 0x07, 0xC7, 0xE0, 0x01, 0x34,
        0x7B, 0x0C, 0xB8, 0x78, 0x3D, 0xFE, 0xFE, 0xDF,
        0x27, 0x5F, 0xEC, 0x47, 0x92, 0x68, 0x67, 0x34,
        0x00, 0x7F, 0x0F, 0xF8, 0x54, 0x08, 0x11, 0xC2,
        0xAF, 0xE6, 0xCA, 0x15, 0x14, 0x20, 0x53, 0x2F,
        0xA5, 0x52, 0x6A, 0x10, 0x74, 0xC3, 0xD7, 0x89,
        0xF2, 0x93, 0x2D, 0xE4, 0x2E, 0x3A, 0xCF, 0xBF,
        0x94, 0x76, 0x0F, 0x42, 0x6D, 0x96, 0xCF, 0x03,
        0x3F, 0xA4, 0x9E, 0x2F, 0x45, 0x8F, 0x9A, 0x9C,
        0x2E, 0x71, 0xDA, 0xCF, 0xE0, 0x09, 0xDD, 0x9C,
        0x3F, 0x3C, 0x8A, 0xB3, 0x28, 0x2D, 0x6F, 0x38,
        0x3B, 0x98, 0x1C, 0x82, 0xD6, 0x36, 0x4F, 0x0E,
        0x4B, 0xDB, 0x2A, 0xF6, 0xA9, 0x5B, 0xA6, 0x1F,
        0x47, 0x41, 0x50, 0xCA, 0xD7, 0x23, 0x3F, 0x89,
        0x03, 0xDF, 0x97, 0x2D, 0xBB, 0x03, 0x28, 0xC0,
        0xCB, 0x9D, 0x0C, 0xCB, 0xEF, 0x88, 0x3D, 0x2E,
        0x6A, 0xDD, 0x18, 0x0E, 0xCA, 0x1B, 0x66, 0x2F,
        0xC1, 0xD2, 0xDB, 0xBD, 0xDB, 0x36, 0x34, 0x21,
        0x9E, 0x1E, 0xFF, 0x38, 0xB1, 0xE5, 0x28, 0x75,
        0x35, 0x6C, 0x03, 0xEA, 0xDE, 0x94, 0x20, 0x55,
        0xF4, 0x83, 0x50, 0x4B, 0xBB, 0xCB, 0x43, 0x02,
        0xA4, 0x17, 0xCF, 0x6D, 0x32, 0x8E, 0xD7, 0x93,
        0xB1, 0xA3, 0xC0, 0x96, 0x9B, 0x7B, 0x34, 0x18,
        0xF5, 0x0A, 0xB3, 0x9F, 0x83, 0xC5, 0x66, 0x6C,
        0x90, 0xE3, 0x83, 0x56, 0xF7, 0xF9, 0xD4, 0x94,
        0xA6, 0xDC, 0xB6, 0x3D, 0x67, 0xC3, 0x4E, 0x3D,
        0x14, 0xA4, 0xE1, 0x55, 0x96, 0x49, 0x79, 0x26,
        0xC8, 0x56, 0x8D, 0x8E, 0xC3, 0xDB, 0xD9, 0xC2,
        0xE8, 0x2C, 0x38, 0x5B, 0xCF, 0xB8, 0xD9, 0x67,
        0x48, 0x63, 0xBD, 0x4F, 0xBF, 0x17, 0x57, 0xDB,
        0x44, 0x7B, 0xF8, 0x04, 0xAE, 0x95, 0x01, 0x47,
        0xC9, 0x1F, 0xBF, 0x9A, 0xA1, 0x78, 0x91, 0x04,
        0x4C, 0xCA, 0xA7, 0x3B, 0x45, 0x52, 0x85, 0x97,
        0x46, 0x2C, 0xED, 0x75, 0x1D, 0x01, 0x5E, 0xBB,
        0xA9, 0xE2, 0xB7, 0xCD, 0xCB, 0xE6, 0xDC, 0x05,
        0xAA, 0x9E, 0xAE, 0x0C, 0x86, 0x84, 0x8A, 0x34,
        0x75, 0xBB, 0x1C, 0x57, 0x44, 0xF5, 0x90, 0x3E,
        0xE4, 0xA8, 0x42, 0xA4, 0x69, 0xCC, 0x18, 0x12,
        0x71, 0xF2, 0x45, 0xAD, 0x70, 0xD0, 0x2A, 0x48,
        0x37, 0x86, 0x3B, 0x29, 0x6B, 0x4A, 0xDB, 0x4E,
        0x8D, 0x03, 0xD8, 0x2B, 0x64, 0xAA, 0x11, 0xDD,
        0x31, 0xCD, 0xF2, 0x1E, 0xDF, 0x1D, 0xFE, 0x32,
        0x76, 0xC4, 0xDB, 0xC8, 0x77, 0xE3, 0x5B, 0x15,
        0xFB, 0x28, 0x35, 0xEC, 0x3A, 0x1C, 0x45, 0x31,
        0x68, 0xA3, 0x8C, 0xA8, 0xE5, 0x63, 0xCF, 0x3E,
        0x9A, 0x00, 0x73, 0x6C, 0xD5, 0xCF, 0xBD, 0x28,
        0x41, 0xD1, 0x0F, 0x94, 0xAD, 0x55, 0x79, 0x9C,
        0x29, 0x27, 0xE5, 0x46, 0x1B, 0x28, 0xBA, 0xC5,
        0x17, 0x4D, 0x0C, 0xE3, 0xF8, 0xF7, 0xCD, 0x76,
        0x09, 0xFB, 0xC8, 0xDA, 0x0C, 0x38, 0xCC, 0x21,
        0x69, 0x5C, 0xED, 0xAD, 0x12, 0xF8, 0xD2, 0xE6,
        0x49, 0x51, 0xA8, 0x99, 0x6E, 0x51, 0x0D, 0x6D,
        0x52, 0x79, 0x7C, 0x5B, 0xA0, 0xEB, 0x4A, 0xFA,
        0x6B, 0xF2, 0xCC, 0x43, 0xDA, 0x09, 0xDE, 0x31,
        0x79, 0xE8, 0x99, 0xBD, 0x71, 0x88, 0xB3, 0x2A,
        0x98, 0xA4, 0x99, 0xD3, 0x72, 0xF3, 0x70, 0x7C,
        0xED, 0x47, 0x9B, 0x09, 0x81, 0xCB, 0x50, 0xC0,
        0xC0, 0x53, 0x9C, 0xF7, 0xE3, 0x10, 0x0B, 0x72,
        0x0E, 0x46, 0x66, 0x52, 0xA4, 0xF4, 0x99, 0xC2,
        0xBA, 0x3A, 0x17, 0xF5, 0x23, 0x22, 0x68, 0x73,
        0x0B, 0x96, 0x2B, 0xC5, 0x72, 0xC0, 0xDE, 0x96,
        0xE8, 0xC9, 0xE2, 0x8F, 0x7E, 0x35, 0x32, 0xC2,
        0x22, 0x41, 0x96, 0xAA, 0x9E, 0x27, 0x68, 0x8D,
        0xD0, 0x50, 0xD7, 0xCB, 0x78, 0x54, 0xFB, 0x3C,
        0x35, 0xF9, 0xC6, 0x2E, 0xFB, 0x10, 0xDA, 0x84,
        0x83, 0x3F, 0x29, 0xBB, 0x1B, 0xE5, 0xEF, 0x3B,
        0x53, 0x36, 0x38, 0xEE, 0xF7, 0x43, 0xD8, 0x11,
        0x9D, 0xDC, 0x29, 0x0B, 0xDF, 0x08, 0xB6, 0xF0,
        0xF9, 0xE4, 0xE1, 0xE1, 0x34, 0x46, 0xC5, 0x3E,
        0xD6, 0x98, 0x05, 0xDA, 0x26, 0x90, 0x8A, 0x15,
        0xDF, 0x1C, 0x48, 0xE0, 0x09, 0xEC, 0x12, 0x53,
        0xBD, 0x5A, 0x58, 0x98, 0xEB, 0xB5, 0x12, 0x1C,
        0xC2, 0x49, 0x04, 0xC8, 0xB1, 0x0E, 0x24, 0xE6,
        0x80, 0xE5, 0x65, 0x98, 0x50, 0x76, 0xFD, 0xA1,
        0x1D, 0x13, 0xFF, 0xDF, 0xA4, 0xDB, 0x28, 0xAC,
        0x9F, 0x0A, 0xEA, 0x2F, 0x81, 0xFD, 0x7E, 0xD4,
        0xDC, 0xA8, 0xD3, 0xB2, 0xE3, 0x84, 0x8B, 0x4D,
        0x60, 0x46, 0xF6, 0xE0, 0xDE, 0x3A, 0x4F, 0x68,
        0x3F, 0x25, 0xE0, 0x60, 0x5E, 0x84, 0xB3, 0x6F,
        0x48, 0x3C, 0x40, 0x4E, 0xF8, 0x99, 0xCB, 0x3F,
        0xCC, 0xBE, 0x8C, 0xB2, 0xA6, 0xF0, 0xA7, 0xE1,
        0x0B, 0x19, 0x48, 0xCD, 0x4F, 0x93, 0xF1, 0x81,
        0x55, 0x5F, 0x66, 0x1D, 0x31, 0xD4, 0x26, 0x80,
        0x8B, 0xBF, 0x9F, 0x66, 0xFD, 0x60, 0xD6, 0x49,
        0x26, 0x9C, 0xA3, 0xFE, 0x99, 0x1B, 0x22, 0x42,
        0x8C, 0x37, 0xAD, 0x2A, 0x08, 0x68, 0x0F, 0x74,
        0x7C, 0xC0, 0x36, 0x0C, 0xCD, 0x37, 0x3D, 0xC6,
        0xA9, 0xF4, 0x3A, 0x66, 0x47, 0x0E, 0x01, 0x4E,
        0x72, 0xB3, 0xD8, 0xC3, 0x8E, 0x02, 0x04, 0x42,
        0xD8, 0xAA, 0xB9, 0x74, 0xE6, 0x04, 0x93, 0x74,
        0x14, 0x5B, 0x04, 0xCB, 0x7F, 0x30, 0x44, 0xAA,
        0xC1, 0xEF, 0xDA, 0xB2, 0xA1, 0x8B, 0xB4, 0x64,
        0xD4, 0xF2, 0xF2, 0xD8, 0x14, 0x39, 0x74, 0xC9,
        0x5E, 0xEE, 0x85, 0x6D, 0x59, 0xEC, 0x00, 0x28,
        0x8E, 0xD4, 0x3F, 0xF5, 0xCC, 0x88, 0x03, 0x00,
        0x6C, 0x99, 0x55, 0x14, 0xA2, 0xCC, 0x9C, 0xA6,
        0x22, 0xB6, 0x1B, 0xCD, 0x75, 0xEC, 0x51, 0xC2,
        0x02, 0xA9, 0x17, 0x10, 0x5B, 0x4A, 0x4B, 0xED,
        0x1B, 0x80, 0x14, 0x68, 0x31, 0xDC, 0xED, 0x07,
        0xEF, 0xD2, 0xED, 0x25, 0x73, 0x9F, 0x54, 0x09,
        0x69, 0x11, 0xB1, 0x50, 0xD3, 0x07, 0x7C, 0xCD,
        0x73, 0x1A, 0x03, 0x61, 0x68, 0x27, 0x25, 0xD5,
        0x38, 0x03, 0xF8, 0xFC, 0xEA, 0xA8, 0x39, 0x19,
        0x29, 0x1E, 0xDB, 0x44, 0x93, 0xEC, 0x84, 0xCC,
        0xE1, 0xD0, 0xF8, 0x2A, 0x67, 0x92, 0x36, 0xEA,
        0xD1, 0x00, 0x2A, 0xE8, 0x01, 0x8C, 0xAC, 0x9F,
        0xDB, 0xD2, 0x46, 0xFF, 0x09, 0x3D, 0x80, 0x3C,
        0x0D, 0xE3, 0x32, 0x6A, 0x57, 0x90, 0x7B, 0x0D,
        0xD6, 0xB0, 0x1D, 0x08, 0x14, 0x58, 0xC7, 0x57,
        0x28, 0xC6, 0x00, 0x82, 0x99, 0x28, 0x89, 0x0A,
        0x56, 0xAA, 0xAF, 0xEF, 0xCF, 0x74, 0x23, 0xB7,
        0x0A, 0x6D, 0x86, 0xB4, 0x15, 0xB8, 0x35, 0x8D,
        0xD0, 0x44, 0xAB, 0xEE, 0x00, 0xB9, 0xC9, 0x79,
        0x5F, 0xC8, 0xF6, 0x1A, 0x64, 0x68, 0x6D, 0xF5,
        0xF8, 0x76, 0xA8, 0xF3, 0x30, 0x61, 0x59, 0x9A,
        0xE8, 0x30, 0xF7, 0xEB, 0x4C, 0x4B, 0xFF, 0x87,
        0x5F, 0x4A, 0x93, 0x6C, 0x40, 0x3C, 0x5D, 0x16,
        0x0D, 0xE5, 0xD3, 0x3C, 0xAE, 0xE4, 0x0F, 0xB7,
        0x18, 0xDD, 0xA4, 0x47, 0x8A, 0xC6, 0xF5, 0x1C,
        0x59, 0xC2, 0x15, 0x52, 0x54, 0xBD, 0x77, 0x67,
        0x11, 0x18, 0x41, 0x1E, 0x26, 0x09, 0xD0, 0x00,
        0x30, 0x6F, 0xC9, 0x50, 0x70, 0x04, 0xA3, 0x1E,
        0x89, 0x57, 0xEA, 0x40, 0xC2, 0x56, 0x4B, 0x83,
        0xC3, 0xAB, 0xB7, 0x1A, 0x87, 0xC1, 0x1B, 0xD1,
        0x8D, 0x78, 0x91, 0xC4, 0x49, 0xDB, 0xBE, 0x79,
        0xB4, 0xA4, 0xFB, 0x04, 0x83, 0x07, 0xCE, 0x0E,
        0x81, 0x2B, 0x2C, 0x68, 0xEC, 0xAB, 0x77, 0xFD,
        0x11, 0x11, 0x52, 0x6A, 0xB0, 0x81, 0x73, 0x06,
        0xCE, 0xBC, 0xB0, 0x49, 0x7C, 0x55, 0x24, 0x31,
        0xCE, 0x15, 0xE4, 0xAB, 0x52, 0x28, 0x3F, 0x67,
        0x94, 0x80, 0xD6, 0x9D, 0xDD, 0xE1, 0xF2, 0x57,
        0x9C, 0xFD, 0xBE, 0x0B, 0xCA, 0x95, 0xFC, 0x5B,
        0x2D, 0xB0, 0xC5, 0xCC, 0x76, 0xA3, 0x19, 0x50,
        0xF5, 0x11, 0x6A, 0xAE, 0x5F, 0x02, 0xD4, 0x67,
        0x10, 0xE4, 0x25, 0x7A, 0x75, 0xFD, 0xED, 0xF2,
        0xF4, 0x7C, 0xE3, 0x7C, 0x20, 0x3E, 0x7F, 0x24,
        0xD3, 0xC9, 0x17, 0x97, 0x13, 0xC5, 0xD8, 0x07,
        0xC2, 0x96, 0x14, 0x9A, 0x75, 0xCC, 0xB4, 0x44,
        0xF0, 0xC6, 0xF6, 0xAB, 0xDD, 0x2D, 0xBB, 0x29,
        0x85, 0xFE, 0x26, 0x74, 0x82, 0x85, 0x8A, 0x1E
    };
#endif /* WOLFSSL_NO_ML_DSA_65 */
#ifndef WOLFSSL_NO_ML_DSA_87
    static const byte seed_87[] = {
        0x38, 0x35, 0x9F, 0xBC, 0xD7, 0x95, 0x82, 0xCF,
        0xFE, 0x60, 0x9E, 0x13, 0x7E, 0xE2, 0xEF, 0xE8,
        0xA8, 0xDB, 0xCB, 0xAD, 0x18, 0xBA, 0x92, 0xBB,
        0x43, 0x3A, 0xB4, 0xF0, 0x9B, 0x49, 0x29, 0x9D
    };
    static const byte pk_87[] = {
        0x69, 0x24, 0xBB, 0x42, 0x57, 0xA7, 0xB9, 0xAF,
        0xF0, 0x95, 0xC3, 0x0B, 0xB3, 0x5C, 0x6A, 0xE4,
        0x19, 0x82, 0x63, 0x12, 0x0F, 0x80, 0x39, 0xAA,
        0x4E, 0x78, 0xE1, 0x74, 0xA7, 0x86, 0xCE, 0x00,
        0x83, 0x01, 0xE6, 0x66, 0xF5, 0x9D, 0x3E, 0xC5,
        0x04, 0x4D, 0xE4, 0x56, 0x78, 0x8F, 0xDE, 0x19,
        0xEB, 0x39, 0x67, 0x7B, 0x5F, 0x9F, 0xE1, 0x41,
        0x50, 0xDA, 0x46, 0x3A, 0x70, 0x6F, 0x3B, 0xAF,
        0x71, 0x5B, 0x95, 0x33, 0x6B, 0x2D, 0x68, 0x5A,
        0x7C, 0xD7, 0x88, 0x07, 0x13, 0xE4, 0x58, 0x7B,
        0xF7, 0xD8, 0x57, 0xBF, 0x7E, 0x31, 0x56, 0x96,
        0xB8, 0xD0, 0xD9, 0xD4, 0x9E, 0x14, 0x29, 0x18,
        0xBF, 0x09, 0x74, 0xE7, 0xF4, 0x32, 0x37, 0xD4,
        0xBE, 0x3A, 0xD3, 0x94, 0x59, 0x9E, 0x3D, 0x39,
        0xBB, 0x76, 0x49, 0x93, 0x25, 0x53, 0x44, 0x7E,
        0x5D, 0x5A, 0xCC, 0x34, 0x99, 0x93, 0x01, 0x76,
        0xEC, 0xD3, 0xA8, 0x44, 0xA4, 0x25, 0xF5, 0x0D,
        0x05, 0x11, 0xC9, 0x22, 0x6C, 0x4B, 0x9A, 0x24,
        0xF2, 0xA0, 0x11, 0xCD, 0x88, 0xD3, 0x23, 0x08,
        0xE0, 0x31, 0x2A, 0x0C, 0x87, 0xCC, 0x34, 0xA9,
        0x95, 0x82, 0x3C, 0x65, 0xF4, 0xF0, 0xF9, 0x8E,
        0x50, 0xC3, 0x77, 0x88, 0xCE, 0x38, 0xDC, 0x28,
        0xFB, 0x8B, 0x9B, 0xFA, 0xAF, 0xA9, 0x04, 0xB5,
        0x41, 0xEE, 0x71, 0x2F, 0x6A, 0x04, 0x1E, 0x06,
        0x11, 0x37, 0x4F, 0x6B, 0xF1, 0x7E, 0xAC, 0x0B,
        0xD5, 0x6F, 0x3B, 0x6B, 0xF3, 0x36, 0xDA, 0x92,
        0x42, 0x07, 0x0C, 0x24, 0x69, 0xA2, 0x0C, 0x4D,
        0x16, 0x16, 0x14, 0x9A, 0x61, 0x59, 0x25, 0x20,
        0x11, 0xD2, 0x99, 0xF9, 0x3F, 0x98, 0x6D, 0x87,
        0x5D, 0xD3, 0x0B, 0x38, 0xA2, 0x25, 0x49, 0x17,
        0x45, 0x70, 0x13, 0x8C, 0x2B, 0xB3, 0xAA, 0x9C,
        0xBE, 0xA9, 0x19, 0x74, 0xF3, 0xD8, 0x9B, 0xF5,
        0xAE, 0x32, 0xBE, 0x9E, 0x58, 0xB8, 0x54, 0xA2,
        0xF8, 0xE8, 0x6F, 0xF7, 0x67, 0x80, 0xC0, 0x34,
        0x90, 0xF4, 0x67, 0xDB, 0x06, 0x51, 0xC2, 0x0B,
        0x1D, 0xF6, 0x0E, 0xB9, 0x7A, 0x3C, 0x99, 0xD9,
        0xBD, 0x66, 0x4B, 0xE6, 0xA5, 0xE4, 0xC8, 0xA8,
        0xAD, 0x4C, 0xC3, 0x63, 0x90, 0xD7, 0x00, 0x4E,
        0x4B, 0xB4, 0x21, 0xDA, 0xED, 0x65, 0x4C, 0x35,
        0x7D, 0xA4, 0xD6, 0x84, 0x98, 0x93, 0x3E, 0xC7,
        0x17, 0x77, 0xAD, 0x64, 0xC2, 0xAE, 0x01, 0x3C,
        0x73, 0xEB, 0x45, 0x7C, 0x68, 0xEF, 0x9A, 0x74,
        0x5A, 0xDE, 0xEB, 0x4F, 0xDF, 0xC8, 0x79, 0xE7,
        0x74, 0xD0, 0x3F, 0xAF, 0x6B, 0x14, 0xAA, 0xB1,
        0x07, 0x52, 0xE2, 0x4B, 0x52, 0xD0, 0xF2, 0xD9,
        0x4D, 0x54, 0x0A, 0x1E, 0xBE, 0x10, 0xF5, 0x97,
        0xE5, 0x14, 0x44, 0x2D, 0x6C, 0x13, 0xC2, 0xE2,
        0x49, 0x8E, 0x8A, 0xF3, 0x01, 0x7C, 0x52, 0xDB,
        0x23, 0x3A, 0x90, 0x71, 0x7D, 0xF2, 0x5B, 0x4D,
        0x07, 0x2B, 0x7D, 0x88, 0xEE, 0x87, 0x31, 0xD1,
        0x68, 0x24, 0xC9, 0x5D, 0x1F, 0xB9, 0x83, 0xC4,
        0x49, 0xDE, 0xB4, 0x66, 0x27, 0x60, 0x60, 0xFE,
        0xE4, 0xC7, 0xEE, 0x38, 0x14, 0x51, 0xF2, 0x32,
        0xC2, 0x9C, 0x7C, 0x32, 0x20, 0x85, 0x0C, 0x61,
        0xD1, 0xC3, 0xC0, 0x0D, 0xB1, 0xCD, 0x97, 0x26,
        0xA0, 0x2A, 0x56, 0x60, 0x9F, 0x3A, 0x65, 0xD3,
        0xD1, 0x64, 0x60, 0x45, 0x88, 0xCD, 0x9B, 0x43,
        0x14, 0x12, 0xF1, 0xAD, 0xD9, 0x14, 0xC5, 0xC2,
        0xDA, 0xBB, 0xC9, 0x04, 0x67, 0xC0, 0xC4, 0xEA,
        0x5F, 0x76, 0xE2, 0x4A, 0xA6, 0x18, 0x76, 0x5F,
        0x8B, 0x06, 0x36, 0xD7, 0xB0, 0x65, 0xE1, 0xF4,
        0xE6, 0xF6, 0x22, 0xEA, 0xE1, 0x71, 0x52, 0x45,
        0x8C, 0x76, 0x65, 0x86, 0x77, 0x2D, 0x36, 0x3F,
        0xA9, 0x92, 0x14, 0xF4, 0x72, 0xB0, 0xDB, 0x8A,
        0x1E, 0x49, 0xD8, 0x2D, 0x02, 0x78, 0xF2, 0x95,
        0x8B, 0x0A, 0xAA, 0x15, 0x86, 0xDB, 0x13, 0x4B,
        0xDF, 0xD2, 0x43, 0x87, 0x42, 0x49, 0x50, 0x07,
        0xE2, 0xFE, 0x5B, 0x60, 0xE2, 0x46, 0x39, 0x92,
        0x26, 0x94, 0x7A, 0x12, 0xEA, 0x17, 0x63, 0x1C,
        0xAA, 0x53, 0x46, 0x87, 0xCB, 0x75, 0xC0, 0x60,
        0xB4, 0x79, 0x7E, 0xAB, 0x82, 0x77, 0xCC, 0x4F,
        0x8A, 0x7A, 0x20, 0x38, 0x76, 0x06, 0xEF, 0xE2,
        0xDB, 0xD3, 0xE7, 0x36, 0x24, 0x92, 0x77, 0xD9,
        0x0F, 0xCA, 0xB9, 0x92, 0xA8, 0xC9, 0x9E, 0x85,
        0xAB, 0x03, 0xEB, 0x4C, 0xAC, 0x5D, 0x88, 0x55,
        0x39, 0x58, 0x52, 0x8A, 0xF9, 0x29, 0x74, 0x71,
        0x81, 0x35, 0xF1, 0xD0, 0xC7, 0x93, 0xEB, 0x00,
        0x0E, 0xA0, 0xAE, 0xC3, 0xEC, 0x18, 0x58, 0xFD,
        0xD1, 0x86, 0x88, 0xD1, 0xDA, 0x27, 0x27, 0x8D,
        0xEB, 0xF2, 0xCA, 0x81, 0x10, 0xBA, 0x4A, 0x20,
        0x4F, 0x79, 0x30, 0xE1, 0xC8, 0xCE, 0xEC, 0xAF,
        0xB7, 0x3F, 0x75, 0xDD, 0xB3, 0x4C, 0x5C, 0x55,
        0x96, 0x8A, 0x79, 0x33, 0x05, 0x84, 0x26, 0xB5,
        0x5D, 0x03, 0x9F, 0x72, 0x92, 0xAC, 0x43, 0xF6,
        0x45, 0x84, 0xF6, 0xDF, 0x18, 0x7A, 0x1D, 0x6B,
        0x00, 0x3F, 0x51, 0x4C, 0xC1, 0x3B, 0x26, 0xC2,
        0xF3, 0x48, 0x19, 0x5A, 0xA3, 0x21, 0xDE, 0x6A,
        0x27, 0xEC, 0x11, 0x34, 0x8D, 0xE5, 0x0D, 0x82,
        0x5A, 0x29, 0x64, 0xC6, 0x31, 0x99, 0x2E, 0x4B,
        0x0B, 0x42, 0x5B, 0x1B, 0xEB, 0x4F, 0x96, 0x00,
        0xE3, 0xAD, 0xC4, 0x43, 0x1C, 0xF2, 0xE8, 0x8B,
        0x42, 0x23, 0xD2, 0xDB, 0x66, 0x3C, 0x3C, 0xE7,
        0x0E, 0xF8, 0x5D, 0xDD, 0x56, 0xA9, 0xBA, 0xF1,
        0x38, 0xA9, 0xD7, 0xED, 0xD8, 0x94, 0x13, 0x1C,
        0x3A, 0x8F, 0x41, 0xA0, 0x4E, 0xF9, 0xF8, 0x67,
        0x52, 0xB7, 0x21, 0x81, 0xFA, 0xBB, 0x37, 0xC8,
        0x6B, 0x87, 0x7E, 0x61, 0xD6, 0x0E, 0xED, 0x95,
        0xEE, 0xFF, 0xAB, 0xE6, 0x37, 0x6E, 0x14, 0xAC,
        0xA8, 0x17, 0xC5, 0xF4, 0x19, 0x61, 0xAF, 0x8A,
        0x78, 0x49, 0xBA, 0xC0, 0x94, 0x91, 0x7B, 0x2D,
        0x13, 0x22, 0x76, 0xB6, 0xB3, 0x48, 0x6A, 0xFF,
        0x95, 0x0D, 0x23, 0xD4, 0xAA, 0xDC, 0x24, 0xCE,
        0x98, 0xA5, 0x26, 0x9E, 0x1C, 0x69, 0x91, 0x79,
        0x60, 0xA3, 0x1E, 0xE0, 0x9A, 0x52, 0x7C, 0x35,
        0x81, 0x75, 0xCA, 0xA0, 0xCB, 0x1B, 0x01, 0x8E,
        0x95, 0x26, 0xD9, 0x35, 0x34, 0xEA, 0xDB, 0xAC,
        0xB5, 0x2B, 0x27, 0x3D, 0x73, 0x5E, 0x22, 0xDD,
        0x0D, 0x5C, 0x28, 0xFA, 0x3E, 0x47, 0xCF, 0xE9,
        0x0B, 0x52, 0x15, 0xAE, 0x24, 0xF1, 0x46, 0xC3,
        0x46, 0x4B, 0xFE, 0xAF, 0x01, 0xD2, 0x8D, 0xAA,
        0x55, 0x3C, 0x1E, 0x94, 0x42, 0x8A, 0x10, 0x4A,
        0x9D, 0x78, 0xAE, 0xC7, 0x62, 0x59, 0x1E, 0x88,
        0x79, 0xF7, 0x68, 0x51, 0xCF, 0xB4, 0x64, 0x85,
        0x66, 0x72, 0x1B, 0x0C, 0xAC, 0x1F, 0x14, 0xFE,
        0x16, 0x14, 0x9A, 0x9D, 0x82, 0x10, 0xCC, 0x8F,
        0x2F, 0x50, 0xDE, 0xF7, 0xB4, 0x6C, 0x84, 0x3B,
        0xE9, 0x3B, 0xD8, 0xD5, 0x56, 0x02, 0x49, 0x33,
        0x50, 0xAB, 0x56, 0x0E, 0xA5, 0xBA, 0x17, 0x71,
        0x64, 0x23, 0xBE, 0x0E, 0xB8, 0x36, 0x0A, 0xB1,
        0x09, 0xD8, 0xFB, 0x18, 0xBF, 0xEA, 0x04, 0x08,
        0x47, 0xB7, 0x33, 0x51, 0x45, 0xD4, 0xF2, 0x00,
        0xD1, 0x9C, 0xF6, 0xFE, 0x7B, 0xAC, 0x91, 0x7F,
        0x42, 0x6C, 0x9B, 0x3D, 0x39, 0xA9, 0xCA, 0x43,
        0x29, 0x81, 0x8F, 0x24, 0x0E, 0x7D, 0xA3, 0x82,
        0x76, 0x10, 0x72, 0xF4, 0xA6, 0x50, 0x5E, 0xA8,
        0xE7, 0x6C, 0x1E, 0x44, 0x6F, 0xEB, 0x66, 0x25,
        0xE3, 0x8D, 0xDB, 0xCD, 0x3C, 0xDA, 0x81, 0xE8,
        0x3B, 0xF7, 0x68, 0xF3, 0xE0, 0x1D, 0x9D, 0x26,
        0x3B, 0x36, 0x73, 0x03, 0xAE, 0x15, 0x6C, 0x0B,
        0x71, 0x83, 0x36, 0x4A, 0x1E, 0x79, 0x41, 0xA0,
        0x92, 0x98, 0xA3, 0xAD, 0xF7, 0xBD, 0x23, 0x1E,
        0x61, 0x14, 0xB9, 0xDC, 0xE7, 0x95, 0x2B, 0x11,
        0x3F, 0x78, 0x16, 0x31, 0x38, 0xB9, 0x26, 0x6F,
        0x84, 0x3F, 0x1E, 0xD9, 0x7D, 0x9C, 0x2B, 0x16,
        0x3A, 0x6E, 0x8B, 0xD4, 0xC1, 0xAB, 0x4E, 0x17,
        0x93, 0x67, 0xC5, 0xAC, 0x96, 0xCE, 0xCF, 0x50,
        0x50, 0xFE, 0x82, 0x1F, 0xDF, 0xA4, 0x4E, 0x9E,
        0x68, 0x0B, 0x61, 0xC6, 0x01, 0x89, 0x32, 0xDF,
        0x71, 0x78, 0x11, 0x45, 0x9A, 0xF2, 0x54, 0x2E,
        0x2C, 0xDE, 0x77, 0x17, 0x8C, 0x2E, 0x98, 0x80,
        0xF0, 0x11, 0xE4, 0x05, 0xEA, 0xFA, 0x59, 0xC8,
        0xCB, 0xBE, 0xD7, 0x6E, 0x5A, 0x19, 0x41, 0x10,
        0x4B, 0x1B, 0x9D, 0x3A, 0x60, 0x49, 0x1C, 0x95,
        0x47, 0x55, 0xE0, 0x2E, 0x89, 0x41, 0x03, 0xF1,
        0xF4, 0x97, 0x74, 0x75, 0xE9, 0xEA, 0x36, 0x60,
        0x9F, 0xD6, 0x7C, 0x9D, 0xE3, 0x18, 0xED, 0xA2,
        0x37, 0x0D, 0xCC, 0xDB, 0xB9, 0xCE, 0xF7, 0xAE,
        0x63, 0x60, 0x90, 0x5E, 0xC2, 0x20, 0x83, 0x8C,
        0x97, 0x69, 0x82, 0x34, 0x41, 0xCD, 0xD0, 0xDA,
        0x8E, 0xF0, 0xAB, 0xE5, 0xF2, 0xD1, 0xD7, 0x6E,
        0x2F, 0xE0, 0x8F, 0xEF, 0x53, 0xDE, 0x1D, 0x61,
        0x66, 0xAB, 0x1A, 0x92, 0xB1, 0xAC, 0x09, 0x3E,
        0x5A, 0xBF, 0x76, 0x58, 0xC4, 0xB5, 0x72, 0x87,
        0xF2, 0xD1, 0xFD, 0x7B, 0x82, 0xDE, 0xDA, 0xF8,
        0xD5, 0xA4, 0xFB, 0xAC, 0x4B, 0x35, 0xD5, 0x82,
        0x31, 0x69, 0x4E, 0x16, 0x24, 0x97, 0x57, 0x8A,
        0xBD, 0x7A, 0xA7, 0xC8, 0xFE, 0x7B, 0x35, 0x41,
        0xA7, 0xF1, 0x8E, 0x54, 0xE8, 0xB7, 0xF0, 0x87,
        0x64, 0xC5, 0xE6, 0x84, 0x49, 0xDF, 0x65, 0x59,
        0x01, 0x54, 0x98, 0x32, 0xD6, 0x28, 0xFA, 0x63,
        0xD2, 0xB2, 0xC5, 0xA1, 0x50, 0x93, 0x39, 0x94,
        0xA9, 0x86, 0x33, 0x17, 0xAD, 0x40, 0xD7, 0x78,
        0xD9, 0xD2, 0xC0, 0x5C, 0x78, 0x98, 0x85, 0x0B,
        0x90, 0x17, 0x32, 0x23, 0xC7, 0xA0, 0xAF, 0x89,
        0x0F, 0xD7, 0xE6, 0x62, 0x21, 0xB6, 0xF0, 0x63,
        0x18, 0xB2, 0xED, 0x5E, 0x19, 0x9C, 0xB4, 0x24,
        0x88, 0x5A, 0xB8, 0x41, 0xE7, 0xA4, 0x72, 0x6F,
        0xAB, 0xA2, 0xF9, 0xBB, 0x53, 0xBC, 0x32, 0x36,
        0x43, 0x4C, 0x35, 0xFB, 0xBE, 0x4B, 0x1A, 0x0F,
        0x93, 0xF5, 0x0C, 0x37, 0x89, 0x6C, 0x29, 0xF8,
        0xE3, 0x02, 0xAD, 0x31, 0xED, 0x33, 0x31, 0xD6,
        0x20, 0xE3, 0xB6, 0x29, 0x45, 0x51, 0x01, 0xA1,
        0xF1, 0xCC, 0x7B, 0xA5, 0xE4, 0x6E, 0x68, 0xED,
        0x4A, 0x8C, 0xCC, 0x87, 0xB4, 0xDC, 0x75, 0xBC,
        0x01, 0x62, 0xB6, 0x33, 0x0F, 0x83, 0x3F, 0xBA,
        0x25, 0x75, 0xDF, 0xAF, 0x5B, 0x5F, 0x28, 0xBC,
        0x54, 0xFF, 0x2B, 0xA8, 0x1E, 0x7A, 0x47, 0x31,
        0x3C, 0x15, 0x48, 0x2B, 0x60, 0x5E, 0x66, 0xBB,
        0x38, 0xC6, 0x19, 0x8F, 0x13, 0x92, 0x10, 0x40,
        0x80, 0xFB, 0xE7, 0x8B, 0x86, 0xB1, 0xBC, 0x9A,
        0x6F, 0xB8, 0x81, 0xF5, 0xC7, 0x82, 0x01, 0x47,
        0xE6, 0xBA, 0x14, 0xB8, 0x1A, 0xCC, 0xF2, 0x0C,
        0xAE, 0x96, 0x64, 0x10, 0x94, 0xC2, 0x16, 0x90,
        0x2E, 0xA5, 0xC1, 0x25, 0xF6, 0xC9, 0x35, 0xA1,
        0x50, 0xD7, 0xC9, 0xAC, 0xC5, 0xD9, 0xE2, 0xE5,
        0xD9, 0x0E, 0x38, 0xC0, 0x50, 0x3A, 0xA9, 0x42,
        0x60, 0x17, 0xC7, 0x6A, 0xAF, 0xCD, 0x52, 0x61,
        0xB5, 0x06, 0x27, 0x4E, 0xC1, 0x3A, 0x96, 0x79,
        0xFB, 0x09, 0x79, 0x60, 0x27, 0xA4, 0xBB, 0x75,
        0x9D, 0x92, 0x82, 0x79, 0xB9, 0x4D, 0x84, 0x1A,
        0x09, 0x73, 0x93, 0xBF, 0x7E, 0x5B, 0xD6, 0x9A,
        0x49, 0x6C, 0xC3, 0xDE, 0xCD, 0x2B, 0x0F, 0x07,
        0xF8, 0x33, 0x92, 0xAA, 0xDE, 0x33, 0xDC, 0x51,
        0xB2, 0xA8, 0x4F, 0x6A, 0x07, 0x63, 0x5D, 0xC0,
        0xEF, 0x57, 0xA9, 0xAD, 0x59, 0x59, 0xB6, 0xA5,
        0x0B, 0x7B, 0xA5, 0x09, 0xAD, 0x5B, 0x11, 0xFA,
        0xD2, 0x6B, 0x41, 0x9F, 0x9F, 0x1E, 0x3F, 0x9C,
        0x73, 0x29, 0xB5, 0xA9, 0x53, 0xD7, 0xCC, 0x87,
        0xB2, 0xDE, 0x21, 0x06, 0x11, 0xCF, 0x52, 0xA6,
        0x39, 0xEF, 0x2B, 0x39, 0x08, 0x01, 0x2C, 0xB8,
        0x8E, 0x1D, 0x6F, 0x57, 0x62, 0x50, 0x79, 0xCB,
        0x10, 0x3D, 0x6C, 0x98, 0x10, 0x1A, 0x11, 0xBD,
        0x22, 0x33, 0xB6, 0x56, 0x02, 0xCA, 0x30, 0x49,
        0xBD, 0x32, 0x05, 0x20, 0x41, 0x9F, 0x76, 0xB0,
        0x61, 0xE3, 0x59, 0x8D, 0xE3, 0x81, 0x52, 0xC8,
        0x87, 0x67, 0xD1, 0xA2, 0x4F, 0xBD, 0x02, 0xBB,
        0x10, 0xC3, 0x8E, 0xAC, 0xAE, 0x31, 0x7D, 0xE6,
        0xBB, 0x28, 0x7B, 0x4D, 0x2C, 0xAE, 0x5D, 0xA0,
        0x21, 0x49, 0x65, 0xD8, 0x77, 0x37, 0x78, 0x62,
        0x6E, 0x9B, 0x97, 0x28, 0x59, 0xD8, 0x48, 0x2B,
        0x8D, 0x05, 0x47, 0xE4, 0xF5, 0x6D, 0xFF, 0x87,
        0x68, 0x1D, 0x5B, 0xC5, 0x12, 0x0F, 0x61, 0x3F,
        0xBB, 0xD9, 0x1E, 0x1F, 0x14, 0xE6, 0xDE, 0xFE,
        0x67, 0x2E, 0x2A, 0x7E, 0xAB, 0xCB, 0xBB, 0x9B,
        0x11, 0x08, 0x2C, 0x5E, 0x70, 0x0A, 0xA0, 0xB1,
        0xF7, 0xC1, 0x78, 0x5F, 0xCE, 0xD1, 0x9A, 0x93,
        0xAF, 0xE7, 0xC5, 0x9F, 0xA2, 0x51, 0x9B, 0xCD,
        0xEB, 0x49, 0x4C, 0x3D, 0x13, 0xB2, 0x12, 0x5F,
        0x38, 0x53, 0x23, 0xB8, 0x16, 0xC6, 0x8F, 0x8F,
        0x56, 0x28, 0xC7, 0xC2, 0xAB, 0xFD, 0x02, 0x78,
        0xA3, 0x37, 0x07, 0x3D, 0xA7, 0x4D, 0x16, 0x09,
        0x96, 0x98, 0xC4, 0xB1, 0x14, 0xE8, 0xA8, 0xCE,
        0x34, 0x4E, 0x0A, 0x15, 0xD0, 0xFC, 0x7E, 0xD4,
        0x97, 0xB0, 0x01, 0xD5, 0x3D, 0x4C, 0x96, 0xDC,
        0x39, 0x54, 0xD3, 0xB4, 0xB9, 0x56, 0xCB, 0x9D,
        0x2A, 0x27, 0x2C, 0x51, 0xF1, 0x55, 0x9B, 0x22,
        0x90, 0x4B, 0x40, 0xCC, 0x85, 0x31, 0xE4, 0x0C,
        0xC4, 0x12, 0xC6, 0x8C, 0xB6, 0xEE, 0xA4, 0xA4,
        0x09, 0x0B, 0x38, 0xE2, 0x79, 0x73, 0x29, 0x98,
        0x54, 0x67, 0xE8, 0x18, 0xA5, 0x24, 0xD3, 0x22,
        0x8E, 0xAC, 0xAE, 0x78, 0x25, 0xD3, 0xDA, 0xD2,
        0xEA, 0xA4, 0x22, 0xFD, 0xC7, 0x7A, 0xED, 0x71,
        0xA2, 0x05, 0xDA, 0x78, 0x38, 0xD9, 0x45, 0xE7,
        0xFE, 0xC3, 0x7E, 0x4D, 0xCA, 0x67, 0xE5, 0x04,
        0xCE, 0x35, 0xE5, 0xB0, 0x45, 0xF5, 0x6F, 0x1E,
        0x8D, 0x75, 0x29, 0xEB, 0xD6, 0xF1, 0xAF, 0x7B,
        0x6E, 0x93, 0x9E, 0x2B, 0x7A, 0xB4, 0x02, 0x7D,
        0x37, 0xA5, 0x13, 0x5D, 0x17, 0x2D, 0xA1, 0xAF,
        0x9C, 0xA2, 0xF7, 0x28, 0xA6, 0xF3, 0x7D, 0xE6,
        0x0D, 0xD2, 0x3D, 0x97, 0xD1, 0x1E, 0x75, 0xAB,
        0x1F, 0xD5, 0x1F, 0x8E, 0x9A, 0x13, 0x97, 0xE5,
        0x82, 0x21, 0x59, 0xDB, 0x58, 0x38, 0x02, 0xB3,
        0x2E, 0xEB, 0xB4, 0x56, 0x7E, 0xCE, 0x37, 0x46,
        0xD1, 0xAE, 0x33, 0x31, 0x47, 0x85, 0x64, 0x3D,
        0xD2, 0xA0, 0x74, 0x1E, 0x7F, 0x1B, 0xF2, 0xD2,
        0x61, 0xF2, 0x21, 0x24, 0xE8, 0xDD, 0xD0, 0x8C,
        0x64, 0x0A, 0x48, 0xB5, 0x47, 0x17, 0x51, 0x7C,
        0x21, 0xCD, 0x32, 0x53, 0x28, 0xBC, 0x23, 0x9C,
        0xA0, 0x28, 0xB2, 0x63, 0x0D, 0x06, 0x3C, 0x8C,
        0xC2, 0x0B, 0xE9, 0xBD, 0xB4, 0x85, 0x02, 0xDA,
        0xDD, 0xE7, 0x3F, 0xFE, 0xD5, 0x96, 0x38, 0x16,
        0x53, 0x3E, 0x02, 0x0A, 0xED, 0x12, 0x08, 0x53,
        0x62, 0x55, 0xB1, 0xCC, 0xE9, 0x85, 0x43, 0x31,
        0x27, 0xFF, 0x4F, 0x04, 0xD5, 0xB1, 0xE2, 0xF2,
        0x10, 0x87, 0x04, 0xB8, 0xB9, 0x66, 0x58, 0x8C,
        0x01, 0x56, 0xAF, 0xC2, 0xAE, 0x19, 0x29, 0x86,
        0xFB, 0xEC, 0x44, 0x3B, 0xAE, 0xF6, 0xCB, 0x85,
        0xA6, 0xF2, 0x9C, 0x77, 0x92, 0x40, 0x5A, 0x24,
        0x11, 0x47, 0x10, 0xAE, 0x1C, 0x74, 0x64, 0x44,
        0xFD, 0xF5, 0xFB, 0x65, 0x9E, 0x5E, 0x34, 0x68,
        0x26, 0x20, 0x7B, 0x8C, 0x54, 0x46, 0x3A, 0x06,
        0x17, 0xCE, 0x17, 0xFF, 0x33, 0xE4, 0x0F, 0x93,
        0x1F, 0xE5, 0x76, 0x71, 0x5C, 0x93, 0x2E, 0xF2,
        0x9F, 0xD7, 0x6B, 0x04, 0xA6, 0x9B, 0x58, 0xE0,
        0x30, 0x3D, 0x8E, 0xF2, 0x56, 0x78, 0xC8, 0xB7,
        0x0A, 0xF1, 0x2E, 0x90, 0x45, 0x59, 0x1C, 0x04,
        0xE8, 0xB7, 0x71, 0x06, 0x94, 0x04, 0x15, 0x17,
        0x7E, 0x86, 0x85, 0x93, 0xA0, 0x9C, 0x7E, 0x14,
        0x61, 0x9A, 0x4B, 0x33, 0x2F, 0x9A, 0xDC, 0x3A,
        0x65, 0x8B, 0x86, 0x01, 0x7F, 0x32, 0x65, 0x6C,
        0x54, 0x29, 0xC1, 0x15, 0xE1, 0x10, 0x03, 0x7A,
        0x8C, 0xC7, 0xE5, 0x44, 0x67, 0x7D, 0x2D, 0xD2,
        0x39, 0xA5, 0x9D, 0x54, 0xD0, 0xF3, 0xC7, 0x46,
        0x0E, 0xC1, 0x52, 0x08, 0x34, 0x6B, 0xA5, 0x6D,
        0xF5, 0x08, 0x6C, 0x5D, 0xBC, 0xC4, 0x1E, 0x0C,
        0x95, 0xFC, 0xB6, 0x86, 0x1C, 0x2C, 0x0C, 0x32,
        0xAA, 0xF3, 0x45, 0x4E, 0xFE, 0xE2, 0xFF, 0xBA,
        0x21, 0x4B, 0x43, 0x0E, 0xF2, 0x48, 0xA5, 0x9B,
        0x32, 0x44, 0x4D, 0x8D, 0x0D, 0x3D, 0xB8, 0x7C,
        0x9D, 0x4B, 0x15, 0x36, 0xD1, 0x57, 0x72, 0x8E,
        0xE7, 0x58, 0x5E, 0xF5, 0x32, 0x77, 0x6A, 0x00,
        0x3A, 0x02, 0x3C, 0x0A, 0xB0, 0xE9, 0xFF, 0x55,
        0x71, 0x08, 0xC3, 0x90, 0x68, 0x4D, 0x56, 0x5A,
        0x66, 0x50, 0x63, 0x26, 0x6A, 0xE6, 0x67, 0x0E,
        0xD5, 0x3B, 0x0F, 0xAF, 0x8F, 0xF6, 0x78, 0x29,
        0xBB, 0x73, 0x78, 0x25, 0xB1, 0x53, 0xA9, 0x33,
        0x8C, 0xBE, 0x3D, 0xF1, 0xA4, 0x62, 0x84, 0x9B,
        0x93, 0xA8, 0x1F, 0x84, 0xED, 0x07, 0xBE, 0x6D,
        0x62, 0x40, 0x00, 0x32, 0x74, 0x73, 0x7F, 0x61,
        0x8D, 0xCB, 0x26, 0xE4, 0x82, 0x52, 0xCE, 0x42,
        0x04, 0xDD, 0x31, 0x39, 0xFF, 0x68, 0x76, 0xF4,
        0x3B, 0x30, 0x5D, 0x83, 0x56, 0x20, 0xFE, 0xDF,
        0x79, 0xAA, 0x67, 0x43, 0x3D, 0xC2, 0x52, 0x87,
        0x32, 0x0E, 0x99, 0x17, 0x96, 0x7B, 0x70, 0xB2,
        0xD8, 0x66, 0xD1, 0x7B, 0x69, 0x8B, 0xFF, 0xF2,
        0xB3, 0xAB, 0x95, 0x14, 0x94, 0x9E, 0x58, 0xB5,
        0x7C, 0x68, 0xA4, 0x54, 0x12, 0xC1, 0xFC, 0x42,
        0x1C, 0x76, 0x8B, 0xF5, 0xEE, 0x8A, 0x10, 0xC8,
        0xAE, 0xF5, 0x69, 0x26, 0xF5, 0x1E, 0xC6, 0x2C,
        0x11, 0x56, 0x9F, 0x31, 0xAA, 0x51, 0x78, 0x68,
        0xE5, 0xCA, 0xD8, 0x9E, 0x95, 0x80, 0x66, 0xEB,
        0x9E, 0xDD, 0x72, 0x71, 0xB3, 0x1C, 0xB4, 0xB1,
        0xD6, 0xCE, 0x21, 0x12, 0x25, 0xAE, 0xB5, 0xB5,
        0x7F, 0x74, 0x97, 0x19, 0xDA, 0x07, 0xEC, 0xBE,
        0xFE, 0x03, 0x88, 0x1D, 0xDE, 0x3D, 0x81, 0xE4,
        0x13, 0x5F, 0x2D, 0xC8, 0x1A, 0xF7, 0x79, 0x77,
        0x6C, 0x1B, 0x80, 0x57, 0x16, 0x2A, 0x6C, 0x98,
        0x2F, 0xBB, 0x4D, 0xA6, 0xA9, 0xAD, 0x28, 0x4A,
        0xB1, 0x0C, 0x70, 0x02, 0x20, 0x44, 0xF4, 0x6D,
        0x40, 0x0B, 0xF6, 0xAD, 0x71, 0x82, 0xD1, 0x97,
        0x78, 0x99, 0x83, 0xBE, 0x99, 0x22, 0x79, 0x79,
        0xA1, 0x33, 0x4B, 0xA1, 0x49, 0xD8, 0x69, 0xBA,
        0x1C, 0x40, 0x88, 0x12, 0x34, 0x35, 0xBF, 0x97,
        0x85, 0x41, 0x35, 0x6D, 0xAF, 0x17, 0x1F, 0x33,
        0xAD, 0xB1, 0xC9, 0x79, 0x07, 0xA0, 0xFB, 0x58,
        0x45, 0x07, 0x4A, 0x85, 0xD2, 0x6F, 0x54, 0x61,
        0x35, 0xAE, 0xD0, 0xF9, 0x1B, 0xE4, 0x53, 0x9C,
        0x12, 0xBF, 0x94, 0x11, 0xE4, 0xB5, 0x56, 0xF6,
        0x87, 0xD0, 0x69, 0xDB, 0x6B, 0x21, 0xFE, 0x2B,
        0x7F, 0x32, 0x18, 0x87, 0x44, 0x8C, 0xEA, 0x55,
        0xDB, 0x19, 0xFB, 0xB8, 0xB0, 0x48, 0x2A, 0x55,
        0xAE, 0xC1, 0x67, 0x38, 0xD7, 0x4C, 0xD2, 0x65,
        0x09, 0x38, 0x36, 0xBE, 0x99, 0xD4, 0xFB, 0x53,
        0xE9, 0xB0, 0x14, 0xB0, 0x37, 0xCD, 0xBF, 0xE9
    };
    static const byte sk_87[] = {
        0x69, 0x24, 0xBB, 0x42, 0x57, 0xA7, 0xB9, 0xAF,
        0xF0, 0x95, 0xC3, 0x0B, 0xB3, 0x5C, 0x6A, 0xE4,
        0x19, 0x82, 0x63, 0x12, 0x0F, 0x80, 0x39, 0xAA,
        0x4E, 0x78, 0xE1, 0x74, 0xA7, 0x86, 0xCE, 0x00,
        0x3B, 0x9A, 0xC2, 0xC1, 0x42, 0x2A, 0x1A, 0xE8,
        0x02, 0xDD, 0xD7, 0x46, 0x4D, 0x3F, 0x32, 0x72,
        0x9A, 0x3C, 0x7D, 0xE8, 0x94, 0xD5, 0x06, 0xAC,
        0xAD, 0x25, 0xCE, 0xB3, 0x72, 0xEA, 0x31, 0x49,
        0xC9, 0x87, 0x80, 0xDC, 0xD1, 0x31, 0x4B, 0xAA,
        0x29, 0xB9, 0xB8, 0x07, 0x75, 0x4C, 0x47, 0xDE,
        0x5D, 0xCA, 0x95, 0x40, 0x64, 0xF2, 0x85, 0x28,
        0xB8, 0x15, 0xFE, 0x27, 0xB7, 0x9A, 0xC5, 0x06,
        0xB3, 0xAD, 0x76, 0x29, 0xD2, 0xC9, 0x71, 0xAB,
        0x8F, 0x28, 0x2E, 0x0C, 0x6E, 0x7E, 0x55, 0x48,
        0xEE, 0x0E, 0x11, 0x32, 0x42, 0xB7, 0xA0, 0xE0,
        0x64, 0xA6, 0xDB, 0xCE, 0x30, 0xC5, 0x61, 0x9B,
        0x19, 0x80, 0x08, 0x89, 0xA0, 0x44, 0x04, 0xB5,
        0x00, 0x13, 0xC0, 0x88, 0xC1, 0x30, 0x29, 0x62,
        0x12, 0x4C, 0xD3, 0xB4, 0x91, 0x0A, 0x35, 0x2C,
        0x43, 0x12, 0x31, 0x19, 0x99, 0x65, 0x22, 0x18,
        0x52, 0x02, 0xC3, 0x85, 0x23, 0x44, 0x0D, 0x90,
        0x24, 0x4A, 0x1A, 0x30, 0x22, 0x44, 0x28, 0x61,
        0x81, 0x06, 0x29, 0x18, 0x97, 0x68, 0x0A, 0x20,
        0x09, 0x08, 0x32, 0x6A, 0x44, 0xA4, 0x4C, 0x44,
        0x90, 0x21, 0x8A, 0x16, 0x68, 0x9A, 0xA8, 0x51,
        0x1A, 0xA5, 0x2C, 0x62, 0x46, 0x8D, 0x04, 0xC3,
        0x40, 0xD3, 0x86, 0x28, 0x60, 0xA4, 0x60, 0x13,
        0x18, 0x70, 0x84, 0x94, 0x8C, 0x63, 0xC0, 0x44,
        0x04, 0xA9, 0x28, 0x20, 0x08, 0x20, 0x43, 0x16,
        0x2A, 0x23, 0x29, 0x2D, 0x1A, 0xB1, 0x29, 0x48,
        0xB6, 0x09, 0x21, 0x88, 0x31, 0x00, 0xC5, 0x30,
        0x00, 0xC4, 0x8C, 0xD9, 0x82, 0x68, 0xE1, 0x30,
        0x4C, 0x63, 0x32, 0x45, 0x0C, 0x32, 0x86, 0x18,
        0x08, 0x31, 0x91, 0x98, 0x0D, 0x10, 0xB8, 0x70,
        0x9B, 0x30, 0x22, 0x64, 0x04, 0x08, 0x93, 0xA4,
        0x8C, 0x21, 0xC9, 0x70, 0x0C, 0x35, 0x71, 0x5B,
        0x00, 0x0D, 0x14, 0x31, 0x22, 0xCC, 0x98, 0x10,
        0x21, 0x04, 0x80, 0x9B, 0x28, 0x64, 0x1C, 0x30,
        0x80, 0x21, 0x30, 0x71, 0x18, 0x33, 0x50, 0x24,
        0x25, 0x44, 0x08, 0x17, 0x8C, 0xC0, 0x08, 0x48,
        0x84, 0x44, 0x90, 0x48, 0x98, 0x30, 0xCA, 0x44,
        0x00, 0x09, 0x19, 0x51, 0x19, 0x23, 0x0C, 0x52,
        0x20, 0x0E, 0x49, 0x06, 0x32, 0x1C, 0x15, 0x4E,
        0x19, 0x48, 0x85, 0x13, 0x25, 0x49, 0xA3, 0x00,
        0x04, 0x08, 0x15, 0x6D, 0x20, 0x41, 0x0C, 0xDA,
        0x42, 0x52, 0xC1, 0x34, 0x8C, 0x00, 0x31, 0x69,
        0x43, 0x82, 0x24, 0x64, 0x94, 0x6D, 0x1C, 0x81,
        0x11, 0x01, 0x96, 0x21, 0x4B, 0x02, 0x00, 0xCA,
        0x28, 0x84, 0xCC, 0x46, 0x64, 0x51, 0x18, 0x6A,
        0x18, 0x10, 0x00, 0xA4, 0x98, 0x21, 0x60, 0xB0,
        0x68, 0x03, 0x94, 0x6C, 0x94, 0x48, 0x51, 0x80,
        0x40, 0x46, 0x92, 0x22, 0x2C, 0x23, 0x44, 0x69,
        0x98, 0x26, 0x4D, 0x1C, 0x01, 0x08, 0x52, 0x02,
        0x20, 0x8A, 0xA6, 0x08, 0x0A, 0x31, 0x61, 0x93,
        0x40, 0x0E, 0x9C, 0xC8, 0x11, 0x81, 0x32, 0x2E,
        0x21, 0x15, 0x84, 0x84, 0xC2, 0x41, 0x00, 0x22,
        0x72, 0x54, 0x22, 0x62, 0x58, 0x06, 0x92, 0x48,
        0x48, 0x44, 0x11, 0x27, 0x04, 0x04, 0xC0, 0x11,
        0x92, 0x82, 0x45, 0xA1, 0xC6, 0x8C, 0xE3, 0x32,
        0x66, 0xC1, 0x38, 0x72, 0x5A, 0x86, 0x01, 0x0C,
        0xC9, 0x90, 0x84, 0x34, 0x08, 0x58, 0xA8, 0x60,
        0x80, 0xC0, 0x70, 0xD0, 0x26, 0x62, 0x9B, 0x30,
        0x2A, 0x04, 0x29, 0x69, 0x04, 0x10, 0x8D, 0x0B,
        0xB9, 0x04, 0x50, 0x46, 0x28, 0x50, 0x48, 0x24,
        0xD0, 0x48, 0x05, 0xA2, 0x48, 0x02, 0xC3, 0x20,
        0x8C, 0xA0, 0x14, 0x00, 0x41, 0x38, 0x21, 0x4B,
        0x24, 0x01, 0x04, 0xB5, 0x49, 0x42, 0x00, 0x00,
        0x0C, 0x24, 0x28, 0x12, 0x40, 0x84, 0xA2, 0x20,
        0x44, 0x9B, 0x06, 0x90, 0x63, 0xC0, 0x88, 0x8C,
        0x14, 0x21, 0x49, 0x12, 0x10, 0x54, 0x16, 0x24,
        0x20, 0x87, 0x44, 0x50, 0x10, 0x85, 0x0C, 0xB5,
        0x64, 0xDB, 0x24, 0x41, 0xD0, 0x42, 0x29, 0x9A,
        0x16, 0x8A, 0x21, 0xB4, 0x4C, 0x13, 0xB7, 0x70,
        0x10, 0xC0, 0x85, 0x19, 0x02, 0x69, 0xCC, 0x40,
        0x61, 0x1C, 0x48, 0x46, 0x98, 0x06, 0x25, 0x60,
        0x14, 0x46, 0xE4, 0x22, 0x62, 0x24, 0x27, 0x22,
        0x62, 0x24, 0x29, 0x44, 0xC6, 0x2D, 0x08, 0x31,
        0x84, 0x20, 0x32, 0x21, 0x04, 0xB4, 0x61, 0x0A,
        0x38, 0x12, 0xD9, 0x28, 0x44, 0xA4, 0x08, 0x20,
        0xCC, 0xA8, 0x29, 0x0B, 0x21, 0x31, 0x0A, 0x34,
        0x29, 0x03, 0x21, 0x40, 0xC1, 0xA2, 0x6C, 0x8A,
        0x16, 0x12, 0x52, 0xA6, 0x64, 0xA3, 0xB2, 0x51,
        0x04, 0x29, 0x51, 0xC4, 0x04, 0x91, 0x63, 0xB0,
        0x2D, 0x14, 0x44, 0x30, 0x8C, 0x40, 0x66, 0x0C,
        0x40, 0x0C, 0x01, 0xA5, 0x2C, 0x09, 0x94, 0x2D,
        0x62, 0xC6, 0x11, 0x03, 0x98, 0x50, 0x19, 0x10,
        0x4D, 0x19, 0xA8, 0x28, 0xD3, 0x86, 0x40, 0xC0,
        0x30, 0x65, 0x54, 0xA6, 0x71, 0xE0, 0xB4, 0x85,
        0x9B, 0x86, 0x10, 0x04, 0x36, 0x69, 0xD0, 0x46,
        0x29, 0x18, 0xA3, 0x71, 0x40, 0x22, 0x49, 0x00,
        0x43, 0x85, 0xCB, 0x40, 0x28, 0x89, 0x36, 0x66,
        0x41, 0x22, 0x69, 0xA4, 0x28, 0x51, 0xD9, 0x80,
        0x29, 0x14, 0x07, 0x21, 0xDA, 0x80, 0x91, 0x1B,
        0x26, 0x50, 0x5B, 0xA0, 0x60, 0x99, 0x42, 0x71,
        0x50, 0x88, 0x49, 0x10, 0x23, 0x09, 0x5A, 0x90,
        0x21, 0x22, 0x27, 0x8E, 0x43, 0xB2, 0x70, 0x0C,
        0xC9, 0x4C, 0xA4, 0x02, 0x70, 0x92, 0x40, 0x10,
        0x0A, 0x39, 0x70, 0x02, 0x36, 0x0E, 0x11, 0x30,
        0x41, 0xD8, 0x40, 0x2D, 0x1B, 0x24, 0x6D, 0xC3,
        0x92, 0x61, 0x4C, 0x86, 0x8D, 0x21, 0xB8, 0x00,
        0xD3, 0x24, 0x22, 0x12, 0xC8, 0x21, 0x12, 0x99,
        0x85, 0x09, 0x16, 0x0C, 0x5A, 0xA2, 0x24, 0x09,
        0x34, 0x42, 0x10, 0xA2, 0x24, 0x03, 0x42, 0x8C,
        0xC0, 0xB2, 0x8D, 0x12, 0xB6, 0x69, 0x63, 0x34,
        0x0D, 0xCC, 0xB0, 0x65, 0xA1, 0x12, 0x11, 0x4A,
        0x38, 0x69, 0xCC, 0x14, 0x81, 0x58, 0x44, 0x09,
        0x54, 0xA6, 0x80, 0x0C, 0xA8, 0x05, 0xC4, 0x38,
        0x8A, 0x84, 0x06, 0x01, 0x9B, 0x32, 0x2D, 0x83,
        0x12, 0x90, 0x09, 0x02, 0x60, 0xA1, 0x28, 0x88,
        0x58, 0x10, 0x41, 0x24, 0x40, 0x02, 0x19, 0x34,
        0x48, 0x18, 0xA0, 0x4D, 0x00, 0x10, 0x62, 0x13,
        0x22, 0x50, 0xE3, 0x38, 0x21, 0x9A, 0x96, 0x21,
        0x53, 0x08, 0x80, 0x51, 0x26, 0x01, 0x99, 0xC4,
        0x28, 0x1B, 0xB9, 0x71, 0x04, 0x97, 0x84, 0x04,
        0x05, 0x2C, 0xA0, 0xC2, 0x10, 0xD3, 0x42, 0x81,
        0x81, 0x42, 0x4D, 0x61, 0x84, 0x6C, 0x5A, 0x30,
        0x49, 0x1B, 0xC2, 0x24, 0xC0, 0x20, 0x28, 0xCA,
        0x92, 0x2D, 0x4A, 0x90, 0x10, 0x04, 0x27, 0x86,
        0x4C, 0x96, 0x21, 0x09, 0x19, 0x45, 0x14, 0x82,
        0x2C, 0x11, 0xA6, 0x91, 0x13, 0xB8, 0x04, 0x03,
        0x18, 0x70, 0x01, 0xA2, 0x51, 0x52, 0x14, 0x49,
        0x5A, 0x02, 0x30, 0xCB, 0x30, 0x2C, 0x94, 0x10,
        0x2C, 0x00, 0x49, 0x86, 0x09, 0xA0, 0x25, 0xC2,
        0x12, 0x4C, 0x1B, 0x02, 0x69, 0x40, 0xA4, 0x44,
        0x41, 0x16, 0x62, 0x02, 0x25, 0x28, 0xDC, 0xA2,
        0x2D, 0x00, 0x16, 0x42, 0x58, 0x30, 0x66, 0x5B,
        0x86, 0x24, 0xD4, 0x24, 0x48, 0xDB, 0x26, 0x0C,
        0x4C, 0x08, 0x85, 0x01, 0x90, 0x49, 0x21, 0x24,
        0x41, 0x54, 0x06, 0x84, 0x02, 0x43, 0x4A, 0x24,
        0x42, 0x05, 0x40, 0x14, 0x48, 0xCA, 0x44, 0x84,
        0xC0, 0x42, 0x0C, 0x98, 0x26, 0x04, 0x9C, 0xA2,
        0x05, 0xD1, 0xC2, 0x51, 0x13, 0x01, 0x86, 0x1C,
        0xA1, 0x50, 0xD9, 0x02, 0x50, 0x0C, 0x39, 0x86,
        0x8C, 0x00, 0x31, 0x22, 0x05, 0x48, 0xD3, 0x10,
        0x81, 0x12, 0x48, 0x05, 0xD1, 0x08, 0x69, 0x62,
        0x38, 0x2C, 0x0A, 0x23, 0x70, 0x9B, 0x44, 0x72,
        0xE3, 0x48, 0x6E, 0x22, 0x96, 0x70, 0x14, 0x33,
        0x6C, 0xD8, 0x90, 0x29, 0x03, 0x00, 0x49, 0x63,
        0x20, 0x8A, 0x03, 0x91, 0x25, 0x08, 0x89, 0x21,
        0xC0, 0x82, 0x0C, 0x99, 0x40, 0x32, 0xC2, 0x34,
        0x4E, 0x4B, 0x98, 0x69, 0x09, 0x80, 0x44, 0xE4,
        0x04, 0x69, 0x94, 0x20, 0x09, 0x99, 0x24, 0x6D,
        0x09, 0xA9, 0x60, 0x01, 0x29, 0x2D, 0xC8, 0x42,
        0x28, 0x8A, 0x34, 0x02, 0xE4, 0x08, 0x70, 0x0C,
        0x23, 0x6E, 0x0A, 0x05, 0x49, 0x64, 0x44, 0x2A,
        0x82, 0xC8, 0x00, 0x02, 0x48, 0x31, 0xCB, 0x90,
        0x50, 0x1C, 0x05, 0x68, 0x12, 0x12, 0x2C, 0xD0,
        0x80, 0x0C, 0x59, 0x48, 0x61, 0xCB, 0xA6, 0x09,
        0x9C, 0xC0, 0x81, 0x42, 0xB8, 0x00, 0x24, 0x41,
        0x8A, 0x94, 0x20, 0x40, 0x42, 0x14, 0x4D, 0x19,
        0x46, 0x62, 0x18, 0x05, 0x09, 0x24, 0x33, 0x6A,
        0xD4, 0x00, 0x61, 0x12, 0x48, 0x32, 0x8A, 0x04,
        0x72, 0x93, 0xB4, 0x69, 0x62, 0xC2, 0x71, 0x41,
        0xA6, 0x89, 0x44, 0x96, 0x31, 0x62, 0x30, 0x46,
        0x83, 0x42, 0x6C, 0x00, 0x19, 0x22, 0x09, 0x46,
        0x4D, 0x8B, 0x06, 0x49, 0xE1, 0xB0, 0x70, 0x42,
        0x44, 0x31, 0xC1, 0x80, 0x65, 0x9C, 0x00, 0x24,
        0x11, 0xA8, 0x31, 0x13, 0x21, 0x2C, 0x4B, 0x46,
        0x28, 0x1B, 0x18, 0x0D, 0x88, 0x42, 0x70, 0xD1,
        0xB0, 0x0D, 0x90, 0xC8, 0x45, 0xDA, 0xC2, 0x48,
        0x59, 0x14, 0x26, 0x22, 0x44, 0x00, 0xC2, 0x94,
        0x41, 0x50, 0xC8, 0x04, 0x18, 0x00, 0x00, 0xCB,
        0xA6, 0x24, 0x19, 0x02, 0x10, 0x10, 0x89, 0x0C,
        0x18, 0x22, 0x21, 0x62, 0xA8, 0x81, 0xC8, 0x92,
        0x48, 0xD3, 0x94, 0x20, 0x82, 0x06, 0x72, 0x09,
        0xA8, 0x90, 0x0C, 0x49, 0x8A, 0x41, 0x86, 0x28,
        0x19, 0xC5, 0x80, 0x9A, 0x18, 0x4D, 0x14, 0x10,
        0x2E, 0x22, 0x12, 0x52, 0x00, 0x08, 0x12, 0x0C,
        0x33, 0x45, 0x63, 0xC6, 0x30, 0x10, 0x93, 0x4C,
        0x60, 0xC6, 0x31, 0xDC, 0x40, 0x0E, 0x98, 0x82,
        0x50, 0x60, 0x02, 0x2A, 0xD2, 0x22, 0x40, 0xE4,
        0x06, 0x2D, 0xDB, 0x32, 0x0E, 0xCA, 0x32, 0x4E,
        0xD4, 0x18, 0x24, 0x08, 0xC3, 0x28, 0x4A, 0xC2,
        0x68, 0xE2, 0x80, 0x40, 0xA1, 0xC8, 0x64, 0x51,
        0xC2, 0x65, 0xCB, 0x16, 0x60, 0x23, 0x09, 0x4C,
        0x82, 0x04, 0x68, 0xD9, 0x22, 0x2E, 0x1C, 0x49,
        0x92, 0x42, 0x24, 0x21, 0x00, 0x37, 0x0E, 0xC8,
        0x12, 0x72, 0x64, 0x08, 0x25, 0x0A, 0x20, 0x2A,
        0x58, 0x24, 0x04, 0x59, 0x16, 0x4C, 0x08, 0x17,
        0x30, 0x00, 0x46, 0x05, 0x12, 0x90, 0x40, 0x03,
        0x07, 0x21, 0x52, 0xC0, 0x64, 0x1C, 0x83, 0x6D,
        0x9C, 0x32, 0x2E, 0x11, 0x15, 0x8A, 0x10, 0x35,
        0x88, 0x5A, 0xA0, 0x8D, 0xD9, 0x80, 0x48, 0x03,
        0xB6, 0x4C, 0x01, 0x10, 0x65, 0x10, 0x86, 0x40,
        0x11, 0x01, 0x42, 0x0A, 0xC1, 0x64, 0xDB, 0x22,
        0x4D, 0x64, 0xB2, 0x51, 0x02, 0x36, 0x0D, 0x93,
        0x46, 0x31, 0x14, 0xB6, 0x68, 0x63, 0x84, 0x29,
        0xC8, 0x10, 0x24, 0x94, 0x30, 0x08, 0x19, 0x37,
        0x02, 0x14, 0x82, 0x45, 0x88, 0x28, 0x40, 0x54,
        0xA8, 0x29, 0x90, 0x14, 0x12, 0x61, 0x36, 0x12,
        0x0B, 0x09, 0x8C, 0xA4, 0x98, 0x28, 0xC2, 0x92,
        0x45, 0x4C, 0x00, 0x60, 0x63, 0xC4, 0x81, 0xC0,
        0x36, 0x25, 0xCA, 0x88, 0x2D, 0x24, 0x40, 0x30,
        0xD3, 0xA8, 0x2D, 0xC9, 0xC8, 0x25, 0xD2, 0x84,
        0x48, 0x00, 0x32, 0x92, 0x50, 0xA2, 0x71, 0xD3,
        0x44, 0x0D, 0x22, 0x34, 0x60, 0x12, 0x13, 0x12,
        0x86, 0x8C, 0x5F, 0x86, 0x20, 0x79, 0x4A, 0x05,
        0x0E, 0x20, 0xD0, 0xE1, 0x01, 0x17, 0x86, 0x24,
        0x0E, 0xA6, 0x64, 0xF2, 0xF6, 0x9B, 0xB1, 0xB7,
        0xE3, 0x0E, 0xC6, 0x6B, 0x1A, 0x4A, 0x0B, 0xE5,
        0x9B, 0x79, 0xF2, 0x19, 0x8A, 0xD9, 0x80, 0x44,
        0x83, 0xE4, 0x75, 0xE5, 0x3B, 0x3C, 0x49, 0xCB,
        0x0C, 0xE5, 0xEF, 0x92, 0x91, 0x2A, 0xF4, 0x40,
        0xF2, 0x3B, 0x99, 0x58, 0x13, 0xD1, 0x1B, 0x59,
        0xF7, 0x98, 0xE9, 0x3C, 0x9D, 0x13, 0x53, 0x98,
        0x17, 0xC7, 0xAC, 0x68, 0xCA, 0xD1, 0xAA, 0x1A,
        0xC2, 0x76, 0x56, 0xBD, 0x0C, 0x47, 0x97, 0xE9,
        0xC8, 0xEC, 0x17, 0x78, 0x4C, 0x1A, 0x32, 0x7A,
        0x9D, 0xFE, 0xAF, 0x4D, 0x61, 0x91, 0xEE, 0xCD,
        0xAF, 0xE0, 0x49, 0xB7, 0x33, 0xFE, 0x39, 0xD5,
        0xEB, 0x40, 0x00, 0x93, 0x6F, 0xEE, 0xFC, 0xF8,
        0x29, 0x28, 0xE9, 0xF9, 0x4C, 0xFD, 0x5C, 0xF4,
        0xC1, 0xE3, 0xDE, 0xB1, 0x43, 0x3A, 0x47, 0xF6,
        0xD3, 0x28, 0xB5, 0xE8, 0x3D, 0xD1, 0x56, 0xD0,
        0x18, 0x2D, 0xC6, 0x92, 0x34, 0x75, 0x91, 0xAA,
        0x6F, 0x73, 0x2C, 0xFB, 0xE9, 0x82, 0x93, 0x5F,
        0xD1, 0x84, 0x6C, 0xAC, 0xF4, 0xCB, 0x85, 0x15,
        0xC5, 0x5A, 0xB8, 0x5E, 0xE5, 0xAD, 0x44, 0xCB,
        0x09, 0xD3, 0x26, 0x9E, 0x2E, 0x6D, 0x11, 0x78,
        0x09, 0x61, 0xFD, 0x13, 0x1D, 0x5E, 0x6F, 0xBF,
        0x89, 0x84, 0x9F, 0x47, 0xF2, 0xB7, 0x1D, 0x82,
        0x83, 0xFF, 0x25, 0x38, 0x5E, 0x52, 0xB0, 0x7D,
        0xBB, 0x26, 0x6C, 0x67, 0x4C, 0xEE, 0x3D, 0x0B,
        0x5D, 0xF5, 0xA5, 0x6D, 0x8B, 0xDC, 0xDC, 0xFA,
        0xAE, 0xE6, 0xA2, 0x48, 0xE7, 0x1D, 0xB1, 0x34,
        0x5A, 0xFC, 0x59, 0x7C, 0xA8, 0x30, 0xA1, 0xA3,
        0x5B, 0x43, 0x96, 0xEF, 0x4C, 0x1A, 0xDF, 0x9E,
        0xD0, 0x1B, 0xCE, 0x9B, 0x6E, 0xB6, 0x37, 0xFA,
        0x24, 0xAA, 0x16, 0x0B, 0x90, 0x76, 0xBA, 0xE3,
        0x05, 0x59, 0xF8, 0xB2, 0x9D, 0xED, 0xB3, 0xD2,
        0x5B, 0x79, 0x06, 0x4A, 0xB0, 0xCF, 0x8B, 0x8D,
        0x70, 0xAD, 0xDD, 0xEB, 0x8B, 0x17, 0x42, 0x48,
        0xD5, 0xAE, 0xA4, 0xD1, 0x8D, 0xE4, 0x3B, 0x89,
        0x38, 0xCD, 0xD2, 0xAC, 0xBA, 0x54, 0x77, 0xBD,
        0x4A, 0xAC, 0xC3, 0xCE, 0x59, 0x5E, 0x5D, 0x26,
        0x9F, 0xE6, 0x75, 0x21, 0x0D, 0x23, 0x15, 0x2B,
        0x04, 0x71, 0x0F, 0x36, 0x84, 0x28, 0x79, 0x4A,
        0x75, 0xF4, 0x9B, 0x68, 0x3E, 0xD2, 0x0D, 0xD6,
        0x47, 0x51, 0x57, 0x77, 0x95, 0x5A, 0x8C, 0xB3,
        0x8A, 0x36, 0xAF, 0xCD, 0x2C, 0xE0, 0xAC, 0xEC,
        0x4F, 0x0D, 0xFE, 0x80, 0x77, 0x02, 0xD1, 0xEB,
        0x3B, 0xDE, 0x72, 0xE9, 0xE0, 0x85, 0xAA, 0x4E,
        0x09, 0xEB, 0x1B, 0x09, 0x47, 0x41, 0x38, 0x52,
        0xEC, 0x3C, 0x0A, 0xC5, 0x2F, 0x06, 0xCB, 0x95,
        0x9C, 0x85, 0x39, 0x4E, 0xB3, 0x74, 0x81, 0x19,
        0xED, 0xBE, 0x6C, 0x80, 0xD2, 0xD8, 0xF7, 0x92,
        0xCE, 0x0D, 0x91, 0x5E, 0x4F, 0x4B, 0x15, 0x1E,
        0xFB, 0x13, 0x5E, 0x7F, 0x4D, 0xC9, 0x7D, 0x85,
        0x81, 0x41, 0xC5, 0x7F, 0x70, 0x41, 0x7B, 0x43,
        0xA6, 0xA1, 0x26, 0x95, 0x69, 0x78, 0xD7, 0x8E,
        0xFB, 0x9F, 0x03, 0x72, 0x43, 0xB4, 0xCB, 0x41,
        0xDF, 0x96, 0x8B, 0x7E, 0xE5, 0xB5, 0x20, 0x87,
        0xF0, 0x5A, 0xA9, 0xFE, 0x48, 0x7B, 0xD1, 0x6C,
        0x03, 0x47, 0xCF, 0x13, 0x35, 0x76, 0x0B, 0xD2,
        0x39, 0x8A, 0xD5, 0x4D, 0xDA, 0x00, 0xA5, 0xAA,
        0xC4, 0x46, 0xD8, 0x0B, 0x1C, 0x79, 0x98, 0xC6,
        0x02, 0x19, 0x2A, 0xDA, 0xFC, 0xB8, 0x09, 0xD1,
        0x4E, 0xE3, 0x28, 0x64, 0x1B, 0xA3, 0xAA, 0x00,
        0xF8, 0xD2, 0x9C, 0x3A, 0x84, 0x8A, 0xCB, 0xDC,
        0x19, 0x46, 0xBC, 0x0D, 0x35, 0xE0, 0xBE, 0x0F,
        0x8F, 0x7E, 0x3D, 0xA3, 0xF6, 0x8D, 0x9F, 0xA9,
        0x76, 0x8F, 0x5C, 0xF2, 0x75, 0x53, 0x4A, 0x0E,
        0xCA, 0x9E, 0x60, 0xFC, 0xEA, 0x38, 0xF1, 0xE0,
        0x42, 0xC3, 0x16, 0x14, 0x3A, 0x76, 0x7B, 0x33,
        0xAC, 0xCA, 0xD8, 0xC8, 0xD6, 0x6C, 0x70, 0xC7,
        0x5F, 0xD1, 0xF0, 0xB2, 0x58, 0x6B, 0x65, 0x3A,
        0xD4, 0xAF, 0x54, 0xE5, 0x6E, 0xF0, 0x69, 0x33,
        0xEA, 0xD3, 0x1D, 0xE3, 0x65, 0xD1, 0x10, 0xB9,
        0xC4, 0xA2, 0xA9, 0x8B, 0xCB, 0xA1, 0x65, 0xCA,
        0xFE, 0x38, 0x6F, 0x88, 0x7C, 0x72, 0x15, 0x6E,
        0xB1, 0x4F, 0xF0, 0xDA, 0xD6, 0x65, 0x61, 0x6C,
        0xE3, 0xCE, 0x65, 0xC1, 0x90, 0x4F, 0x2C, 0x17,
        0x47, 0xB2, 0xEC, 0x2B, 0x5C, 0x9D, 0x67, 0x76,
        0xBC, 0xD7, 0x9E, 0x5A, 0xC6, 0x4B, 0x79, 0x33,
        0xBD, 0xDE, 0xDE, 0xDD, 0xBB, 0xC7, 0x25, 0xBF,
        0xDB, 0xCC, 0xDE, 0x2F, 0xB3, 0x75, 0xAE, 0x2B,
        0xE3, 0x53, 0x7B, 0xDF, 0x89, 0xBF, 0x4C, 0x25,
        0xF8, 0x3A, 0x49, 0xD6, 0xA6, 0xA8, 0xD0, 0x76,
        0x1C, 0xF3, 0x9D, 0x62, 0x0C, 0x53, 0xED, 0x83,
        0x7D, 0x19, 0x82, 0x55, 0xCF, 0x5B, 0x91, 0x0A,
        0x6D, 0xB5, 0x78, 0x77, 0xDF, 0x92, 0xD8, 0xBB,
        0x6E, 0x9C, 0x52, 0x6B, 0x8C, 0x4E, 0xC9, 0x31,
        0x00, 0xDE, 0xE0, 0x50, 0x0A, 0x21, 0x0C, 0x98,
        0x45, 0x83, 0xE1, 0x53, 0x81, 0x60, 0xED, 0xAC,
        0x2C, 0x6F, 0x86, 0x6E, 0x7F, 0x5D, 0x99, 0xD7,
        0xB1, 0xB8, 0x15, 0x82, 0xF5, 0xD0, 0xEB, 0xBF,
        0x27, 0x86, 0xE3, 0xF5, 0x56, 0x01, 0x3B, 0xA9,
        0xB6, 0xF6, 0x56, 0xEB, 0x79, 0x88, 0x38, 0xEA,
        0x05, 0x79, 0x20, 0x1A, 0x95, 0xD5, 0x6B, 0xBC,
        0x3B, 0xCD, 0xB9, 0x51, 0x1A, 0xFB, 0xD4, 0xD8,
        0x12, 0x88, 0x89, 0x6F, 0x87, 0x10, 0x8C, 0x07,
        0x7F, 0x1A, 0x81, 0xA3, 0xBD, 0x29, 0x7B, 0xB1,
        0x24, 0xA8, 0x00, 0x86, 0x89, 0x02, 0x42, 0x99,
        0x5E, 0x03, 0xCF, 0x42, 0xA0, 0xC2, 0x1E, 0x27,
        0x2A, 0x9A, 0xFA, 0x1D, 0xC1, 0x03, 0x46, 0x3D,
        0x2A, 0xB4, 0x94, 0xF7, 0xD0, 0x17, 0x68, 0x6D,
        0x31, 0x89, 0x4D, 0xD2, 0xF6, 0xEB, 0xB0, 0xC3,
        0xCB, 0x62, 0x23, 0xEC, 0x79, 0xC6, 0x5D, 0x45,
        0xC1, 0xB0, 0xD4, 0xEF, 0x19, 0x61, 0xF1, 0x6D,
        0x65, 0x3F, 0xCF, 0x25, 0x97, 0x7B, 0x65, 0x1E,
        0xC5, 0x1A, 0x13, 0xAE, 0x8D, 0x4A, 0x34, 0x72,
        0xEE, 0x71, 0x96, 0x9A, 0x7A, 0x93, 0x6F, 0x5D,
        0xBB, 0xB9, 0x39, 0x6A, 0x46, 0xD9, 0x76, 0x42,
        0x35, 0x8C, 0xAF, 0x48, 0x94, 0xC9, 0xA6, 0xDF,
        0x84, 0xA5, 0x9C, 0x59, 0x62, 0xA6, 0x99, 0x0A,
        0x76, 0xF0, 0x61, 0x48, 0x90, 0x16, 0x9F, 0x00,
        0x18, 0x70, 0xD4, 0x9C, 0xF2, 0xE7, 0x50, 0x08,
        0xCC, 0x4A, 0x5D, 0x85, 0xE7, 0x2D, 0xE2, 0xD6,
        0xCF, 0x3F, 0xA7, 0x18, 0x52, 0x25, 0x35, 0x22,
        0xFE, 0x8B, 0x0E, 0x42, 0x3C, 0xB4, 0x17, 0xA3,
        0x8E, 0xB7, 0x8C, 0x87, 0x63, 0xC3, 0x72, 0x0C,
        0x04, 0xE6, 0x7F, 0xF8, 0x89, 0x79, 0xEB, 0xA0,
        0x9E, 0x34, 0x53, 0x8B, 0xB5, 0x23, 0xB9, 0x9B,
        0x8E, 0x34, 0x16, 0x74, 0x12, 0xF7, 0x7A, 0xEA,
        0x89, 0x4D, 0x83, 0xAC, 0xF9, 0x46, 0xFC, 0x05,
        0x4D, 0x0A, 0xF4, 0x72, 0x95, 0xE5, 0x1E, 0xD8,
        0x3F, 0x74, 0x86, 0x94, 0x0A, 0x4D, 0x41, 0xC0,
        0x4A, 0xD7, 0xEB, 0xEE, 0x61, 0x0B, 0xF1, 0xD0,
        0x3F, 0xA5, 0x40, 0x71, 0xD5, 0x1A, 0x15, 0x09,
        0xE4, 0xF4, 0x91, 0x63, 0xA2, 0x50, 0x81, 0xBE,
        0x87, 0x90, 0xD0, 0x87, 0xF5, 0xF4, 0xF0, 0x5C,
        0x88, 0x55, 0x0F, 0xCA, 0x9B, 0xF9, 0x9C, 0x9B,
        0xE5, 0x95, 0x3D, 0x51, 0xDD, 0x08, 0x45, 0xC9,
        0x3E, 0x41, 0xEE, 0xEF, 0x62, 0xE0, 0x79, 0x4B,
        0x29, 0x27, 0xC4, 0xF5, 0xED, 0x9B, 0xD3, 0xE3,
        0x4E, 0xA9, 0x20, 0x0A, 0x79, 0xDD, 0xEB, 0x4B,
        0x2D, 0x8F, 0x30, 0x5F, 0xE0, 0x5F, 0x82, 0x7C,
        0x7E, 0x2E, 0xD1, 0x86, 0x34, 0x1C, 0xB5, 0xD1,
        0x15, 0x2F, 0xC8, 0x01, 0x04, 0xE0, 0xE1, 0x36,
        0x83, 0xD9, 0x41, 0x29, 0x4C, 0x77, 0x84, 0x17,
        0x16, 0x4B, 0x68, 0x4A, 0x97, 0x6E, 0x56, 0xE7,
        0x8D, 0xA4, 0xD1, 0x7C, 0x3C, 0x73, 0x22, 0x93,
        0x14, 0x87, 0x0B, 0x85, 0xC4, 0x55, 0xC2, 0x3B,
        0x83, 0x0B, 0x9A, 0x28, 0xA3, 0xD8, 0xC0, 0xB5,
        0x66, 0x42, 0x6D, 0xC1, 0x69, 0xF3, 0x26, 0xAB,
        0xCE, 0x2E, 0xFF, 0xF3, 0x9E, 0x9B, 0x19, 0x9A,
        0xE5, 0xC1, 0x29, 0x2B, 0x6F, 0x2E, 0xF3, 0x7A,
        0xF1, 0xDE, 0xA9, 0x27, 0x2C, 0x8D, 0x54, 0x23,
        0xDF, 0x8A, 0x56, 0x32, 0xF9, 0x91, 0xE1, 0x4D,
        0xCA, 0x25, 0x14, 0x78, 0x8B, 0x62, 0xBE, 0x16,
        0x48, 0x28, 0xE9, 0xAC, 0xB8, 0x93, 0xDD, 0xA6,
        0x02, 0xA5, 0xE2, 0xFB, 0x9E, 0xFC, 0xBE, 0xFD,
        0x95, 0xAB, 0xFB, 0x82, 0xD2, 0xB0, 0x2D, 0x49,
        0xCC, 0x53, 0x08, 0x4A, 0x49, 0xAB, 0x1B, 0xEC,
        0x23, 0xE5, 0xB4, 0xC8, 0xE7, 0x14, 0xCB, 0x03,
        0x40, 0x5F, 0x1B, 0xCF, 0x7E, 0x11, 0xBB, 0x59,
        0x72, 0x9D, 0xDC, 0x0B, 0x7B, 0xEF, 0xB2, 0x91,
        0x27, 0x6D, 0xCE, 0xDA, 0xCA, 0xAD, 0x39, 0xA2,
        0xF0, 0x1C, 0x7D, 0xC9, 0x8B, 0x9E, 0x06, 0x5E,
        0xAF, 0xED, 0x1C, 0xC8, 0xCE, 0x3E, 0x84, 0x80,
        0x80, 0xA2, 0xFC, 0x5B, 0x98, 0xC9, 0xF6, 0xBF,
        0x50, 0x40, 0x27, 0x33, 0x42, 0xF0, 0x31, 0x2F,
        0x8B, 0x98, 0x44, 0x59, 0x4A, 0x50, 0x3D, 0xD3,
        0xE6, 0xAF, 0x1C, 0x9E, 0x35, 0xC1, 0x03, 0x2A,
        0x4A, 0x8A, 0x5E, 0x7B, 0xF3, 0x3A, 0x82, 0xF3,
        0x5E, 0x16, 0xED, 0xF8, 0xC6, 0x0C, 0x90, 0x02,
        0x1D, 0x8C, 0x0B, 0xA4, 0xC3, 0x86, 0x24, 0x5D,
        0xFE, 0xF0, 0x94, 0x48, 0x43, 0x1D, 0x8C, 0x00,
        0xD1, 0xE2, 0x6E, 0xE4, 0xD8, 0xC7, 0x7D, 0xAA,
        0x1A, 0x70, 0x5E, 0xD4, 0x79, 0x2A, 0xCB, 0x4E,
        0xA2, 0x7C, 0x15, 0x66, 0xFB, 0x56, 0x68, 0x3C,
        0x43, 0xBF, 0x67, 0x84, 0x2E, 0x67, 0x53, 0x4C,
        0xB3, 0xF9, 0x67, 0x7C, 0x8A, 0xB9, 0xD0, 0xEE,
        0xE7, 0x82, 0x7C, 0xDE, 0xFC, 0x22, 0x3A, 0xC9,
        0x48, 0xB8, 0x80, 0xB5, 0xF1, 0xCE, 0x95, 0x37,
        0x27, 0x29, 0x32, 0x00, 0x2C, 0x1A, 0x4D, 0xD2,
        0x18, 0xF5, 0x27, 0x16, 0x6E, 0xBF, 0xB2, 0xB2,
        0xFA, 0x2B, 0xF3, 0x72, 0x46, 0xEC, 0xDF, 0xDF,
        0xA7, 0x2B, 0x6D, 0xA1, 0x1C, 0x30, 0xD1, 0xC7,
        0xD2, 0x48, 0xAD, 0x64, 0x81, 0x8F, 0x69, 0x1D,
        0x59, 0xB7, 0x55, 0xDA, 0xF7, 0x1B, 0xED, 0x9A,
        0xB5, 0xFB, 0x52, 0xE0, 0x36, 0x22, 0xA9, 0x00,
        0xD6, 0x6B, 0x4C, 0x63, 0x84, 0x16, 0x9B, 0xDF,
        0x9E, 0xB6, 0x1C, 0x02, 0xDF, 0x45, 0xFB, 0x76,
        0xB1, 0xA2, 0x6F, 0x34, 0xE9, 0x38, 0xB1, 0x90,
        0x86, 0x17, 0x45, 0xC0, 0x21, 0xFA, 0x87, 0x62,
        0x00, 0xC7, 0xFC, 0x8E, 0x22, 0x2D, 0xDB, 0xFA,
        0xD8, 0xBE, 0x78, 0x1B, 0x18, 0x54, 0x24, 0xAA,
        0xAF, 0xC6, 0x58, 0x62, 0xDB, 0x13, 0x2B, 0xEC,
        0x6D, 0x18, 0x83, 0x7A, 0x1F, 0x58, 0xA8, 0x76,
        0xC9, 0x9E, 0x63, 0xF5, 0x14, 0x20, 0xB8, 0x3F,
        0x45, 0x96, 0x75, 0x61, 0x2F, 0x7A, 0xCF, 0x80,
        0xB4, 0xEB, 0x1D, 0xD0, 0x72, 0x1C, 0xAA, 0x1B,
        0x49, 0x70, 0xDA, 0x60, 0x86, 0x79, 0xC6, 0x38,
        0x3E, 0x81, 0x7F, 0xE1, 0x6B, 0x66, 0xB1, 0x91,
        0x81, 0xED, 0xFC, 0x39, 0x27, 0x0C, 0x7E, 0x91,
        0x7B, 0x1F, 0x10, 0xEB, 0x7A, 0x01, 0x19, 0x97,
        0xE9, 0x67, 0x85, 0x3B, 0x78, 0xE0, 0x0C, 0xFD,
        0x58, 0xD2, 0x24, 0xD9, 0x33, 0xCC, 0x5A, 0x99,
        0x55, 0x32, 0xDC, 0xD4, 0xE5, 0x32, 0xE4, 0x03,
        0x05, 0x15, 0xF4, 0xA0, 0x5B, 0x33, 0x1D, 0x57,
        0x5D, 0xDA, 0xC2, 0x9B, 0xAB, 0x06, 0x9F, 0x09,
        0xAF, 0x0D, 0x17, 0x33, 0x73, 0xDB, 0x1E, 0xC2,
        0xB6, 0x36, 0x6B, 0xB3, 0x71, 0x00, 0x8A, 0x23,
        0x86, 0xFD, 0x88, 0xBE, 0x77, 0xF5, 0xED, 0x5E,
        0x19, 0x8C, 0xBE, 0x88, 0xDF, 0x24, 0xBC, 0x6E,
        0x39, 0x3F, 0xEB, 0xC1, 0x0C, 0x47, 0x0A, 0x72,
        0xD4, 0x7C, 0x0F, 0x83, 0x46, 0x53, 0xC9, 0xAE,
        0x80, 0x0E, 0x89, 0x3C, 0x6B, 0xA6, 0x8E, 0xA2,
        0x8A, 0x83, 0x8F, 0xCB, 0xB6, 0x9C, 0x3E, 0x96,
        0x4A, 0x5F, 0xAF, 0xC2, 0x06, 0x7D, 0xD4, 0x06,
        0xB2, 0x57, 0xC9, 0x8D, 0xD3, 0x97, 0x9E, 0xC7,
        0xC7, 0xEC, 0xBE, 0x96, 0xA3, 0x3D, 0x85, 0x51,
        0x5D, 0xA2, 0xCB, 0x6A, 0xA5, 0xE1, 0xFF, 0xF2,
        0x04, 0xAF, 0x62, 0xDD, 0x41, 0x19, 0xA0, 0xE4,
        0x8C, 0x04, 0xA3, 0xF2, 0xB3, 0x86, 0x60, 0xF5,
        0x29, 0x64, 0xD8, 0xD4, 0xAE, 0xE1, 0x46, 0xA9,
        0xC5, 0x3C, 0x31, 0x90, 0x6D, 0xAD, 0x0F, 0xD9,
        0x0B, 0x5D, 0x83, 0xB3, 0xE3, 0x1B, 0x69, 0x0A,
        0x4C, 0x49, 0x35, 0x24, 0x99, 0x81, 0xBE, 0x1F,
        0x1A, 0x85, 0xEC, 0x6E, 0x0F, 0xEE, 0x4C, 0x88,
        0xF2, 0xD8, 0x9E, 0x29, 0x69, 0xAB, 0x8C, 0xBB,
        0xEB, 0x50, 0x19, 0x16, 0x55, 0x8D, 0x29, 0xEA,
        0x7C, 0x3E, 0xCF, 0x1C, 0x9E, 0xF1, 0xA0, 0x43,
        0x50, 0x63, 0x3B, 0x4C, 0xDA, 0x73, 0x7D, 0xFB,
        0x15, 0x1C, 0xB5, 0xE7, 0x36, 0x11, 0x73, 0xF3,
        0xAE, 0xDD, 0xDF, 0x52, 0x7D, 0x73, 0xF2, 0xF9,
        0xD5, 0xB6, 0x21, 0x3A, 0xA6, 0x8F, 0x88, 0x3E,
        0x9A, 0x26, 0x33, 0x78, 0x5E, 0xC6, 0xBE, 0x64,
        0x2A, 0x9F, 0xD0, 0xF2, 0x1A, 0x42, 0xF6, 0xB9,
        0xDA, 0xAB, 0xDC, 0xD1, 0xE6, 0xAD, 0xBE, 0xF6,
        0x48, 0x41, 0xB5, 0x96, 0x86, 0xEA, 0xE3, 0xEC,
        0x88, 0xEE, 0xF0, 0xA9, 0xCB, 0xC1, 0x2B, 0xC0,
        0x12, 0x62, 0x2D, 0xF2, 0xDD, 0x93, 0xA8, 0x62,
        0x29, 0x04, 0x4A, 0xF2, 0xF2, 0x60, 0xD2, 0x18,
        0x3F, 0x51, 0xE8, 0x33, 0xEE, 0x92, 0xD9, 0x8F,
        0x02, 0x51, 0xE3, 0xF8, 0x5F, 0xAB, 0x74, 0xCE,
        0x36, 0x7B, 0x8B, 0x7A, 0xA6, 0x3D, 0x3C, 0xF8,
        0xC8, 0xBF, 0x4D, 0x78, 0x35, 0x8B, 0xAE, 0x0A,
        0x02, 0x41, 0xE2, 0x10, 0xAC, 0x69, 0x35, 0x30,
        0x87, 0xCC, 0x73, 0x31, 0x35, 0x7E, 0xB4, 0x45,
        0x0F, 0x95, 0x09, 0xCF, 0xE5, 0x95, 0xF5, 0x40,
        0x32, 0xEE, 0x05, 0x77, 0x54, 0xA8, 0xED, 0xD7,
        0x46, 0xCB, 0x92, 0x82, 0xE7, 0x68, 0xDC, 0x6B,
        0x83, 0x0C, 0x5B, 0x4A, 0x21, 0x93, 0x43, 0xAD,
        0x12, 0x4E, 0xDB, 0x3B, 0xBC, 0x42, 0x50, 0x55,
        0x66, 0xA7, 0x03, 0x8C, 0x95, 0x9B, 0xC3, 0x55,
        0x85, 0xB6, 0x05, 0x5F, 0x19, 0x68, 0xDA, 0x24,
        0x3F, 0x77, 0x8F, 0x4E, 0x46, 0xDB, 0x46, 0x2A,
        0xBE, 0xB9, 0x3B, 0x81, 0x24, 0x3C, 0x31, 0xEB,
        0x59, 0x62, 0x2E, 0xDF, 0x81, 0xF0, 0x6C, 0xCC,
        0x61, 0xD2, 0xA6, 0xEA, 0x73, 0xE1, 0x09, 0xC3,
        0x87, 0x91, 0x5F, 0x27, 0x7B, 0xCF, 0x1F, 0xC1,
        0x11, 0x05, 0xBB, 0xA7, 0x02, 0x93, 0xC0, 0xFA,
        0xB5, 0xC0, 0x65, 0xF2, 0x3B, 0xAA, 0x19, 0x29,
        0x0A, 0x30, 0x2F, 0x08, 0x09, 0x11, 0x07, 0xA4,
        0xB1, 0xD5, 0x68, 0x85, 0x26, 0x22, 0x09, 0x83,
        0x83, 0x42, 0x77, 0x60, 0xEF, 0x8F, 0x29, 0x28,
        0x62, 0x5B, 0xDD, 0xA5, 0xF5, 0x14, 0xC5, 0xAD,
        0xE9, 0x59, 0x89, 0x1E, 0xF2, 0x95, 0x9F, 0x24,
        0x8A, 0x35, 0x32, 0xBF, 0x9D, 0x30, 0xE7, 0x14,
        0x05, 0x9E, 0xBD, 0xEC, 0x95, 0x87, 0x08, 0xF8,
        0xA8, 0x3C, 0x26, 0x8B, 0xEF, 0x26, 0x82, 0xD6,
        0x03, 0xCA, 0x88, 0x63, 0x47, 0xE1, 0x98, 0xFD,
        0x68, 0x23, 0x39, 0x99, 0xC7, 0x7D, 0x30, 0xD7,
        0x45, 0x5D, 0xE6, 0xBC, 0xFD, 0x01, 0x44, 0x27,
        0x70, 0x62, 0xB3, 0x04, 0xBE, 0xF0, 0xE3, 0x4C,
        0x5A, 0x9D, 0x8D, 0x78, 0x0D, 0x29, 0xEC, 0x23,
        0x21, 0xE0, 0x73, 0x40, 0x77, 0x1C, 0x46, 0x36,
        0x04, 0x83, 0xAD, 0xCA, 0xF1, 0x2D, 0x5B, 0x79,
        0xFD, 0xBF, 0xE2, 0x85, 0x6A, 0xCE, 0x88, 0x59,
        0xF6, 0xB1, 0x24, 0x14, 0xB3, 0xF7, 0xE8, 0xBB,
        0x58, 0x13, 0x49, 0x89, 0x60, 0xF3, 0x4F, 0xDC,
        0x64, 0xFC, 0x84, 0x85, 0x79, 0xCA, 0xF9, 0xDC,
        0xCF, 0x19, 0xB4, 0xFB, 0x82, 0x5E, 0xD5, 0x71,
        0x6D, 0xCC, 0xCD, 0x68, 0x72, 0xCB, 0xDE, 0x38,
        0x31, 0xD6, 0x73, 0x84, 0x94, 0x2C, 0xD8, 0xA9,
        0xEC, 0x4B, 0xBF, 0xEF, 0x57, 0x06, 0xB8, 0xF9,
        0xF0, 0x5F, 0xE1, 0xE8, 0xFE, 0x69, 0xD3, 0xEA,
        0x6A, 0x86, 0x21, 0xC2, 0x21, 0x44, 0x17, 0x7B,
        0x1C, 0x12, 0x59, 0xE1, 0xA7, 0x9D, 0xFD, 0xF8,
        0x97, 0x28, 0x88, 0x7B, 0xEF, 0x1A, 0x70, 0x48,
        0x25, 0x56, 0x83, 0x1B, 0x67, 0x24, 0x40, 0xE1,
        0x3F, 0xE3, 0xE3, 0xFC, 0x82, 0x04, 0xA0, 0x2E,
        0xA1, 0xEF, 0xF1, 0x9D, 0x95, 0x25, 0x38, 0x87,
        0x28, 0x5B, 0xFB, 0xEA, 0x16, 0xA0, 0xF2, 0x19,
        0xEF, 0xBC, 0xEC, 0x30, 0xA8, 0xAE, 0x86, 0x58,
        0x9A, 0x57, 0x03, 0x10, 0x3A, 0x8A, 0x39, 0x3F,
        0xA6, 0xF6, 0xB6, 0x57, 0x70, 0x4A, 0xC6, 0x77,
        0xC1, 0x4C, 0xD1, 0x0D, 0x3D, 0x62, 0xD1, 0x3F,
        0xBD, 0x37, 0x8C, 0x2D, 0xDA, 0x32, 0x5B, 0x61,
        0xB8, 0x59, 0x52, 0xD5, 0x12, 0x93, 0x87, 0x1E,
        0x1F, 0xCD, 0xC9, 0x48, 0xC7, 0x7B, 0xEA, 0xE9,
        0xA6, 0xF0, 0xE8, 0x7C, 0xE1, 0xA8, 0x05, 0x1C,
        0x8F, 0x80, 0x87, 0x68, 0x5C, 0x12, 0x62, 0x4B,
        0xDF, 0x58, 0x38, 0x0E, 0xD6, 0x6F, 0x55, 0xB4,
        0x3D, 0xDD, 0x6D, 0x36, 0x21, 0x73, 0xA5, 0xBD,
        0x38, 0x98, 0x59, 0xC1, 0x7D, 0x95, 0xEC, 0xE3,
        0xAB, 0x73, 0x26, 0x39, 0xFF, 0xE4, 0x51, 0xCD,
        0x10, 0x3E, 0xE4, 0x85, 0x4D, 0xB2, 0xF3, 0x96,
        0x14, 0xF6, 0x58, 0xBA, 0xA3, 0x84, 0xBC, 0x99,
        0x48, 0xD0, 0x71, 0x4E, 0xB4, 0x8A, 0x88, 0x71,
        0x43, 0xE7, 0xA1, 0xFA, 0x4B, 0x69, 0x0C, 0x22,
        0xB4, 0x92, 0xA7, 0x0C, 0x61, 0x2B, 0x59, 0xFF,
        0xD2, 0xD6, 0xB3, 0xB5, 0xE9, 0x9C, 0x20, 0x03,
        0xE2, 0xC3, 0x59, 0xB1, 0xE6, 0x2D, 0xCB, 0x62,
        0x0C, 0x7A, 0x24, 0x6A, 0x7B, 0x9B, 0x32, 0x46,
        0x13, 0x15, 0x56, 0xF2, 0xF3, 0xD5, 0x13, 0xA2,
        0x3C, 0x6A, 0x9F, 0xD2, 0x28, 0x0E, 0xD6, 0x86,
        0xD7, 0x67, 0xCC, 0xD0, 0x17, 0x54, 0xEB, 0x4C,
        0x99, 0x69, 0x2F, 0x2B, 0x38, 0x0C, 0x36, 0x08,
        0x13, 0x44, 0xC1, 0xD3, 0x5E, 0xE1, 0x94, 0x97,
        0x36, 0xB6, 0x97, 0x6F, 0x48, 0x52, 0xCF, 0xBE,
        0x64, 0xFA, 0xBC, 0xF1, 0x1B, 0x9A, 0xFB, 0x82,
        0x85, 0x76, 0xB4, 0xF9, 0x78, 0x7A, 0xA7, 0xD0,
        0x3E, 0x84, 0x59, 0x8A, 0x71, 0x43, 0xEF, 0x73,
        0x11, 0xFA, 0xF2, 0x97, 0x0E, 0x23, 0xED, 0x4C,
        0x17, 0x3F, 0x98, 0x5D, 0x64, 0x50, 0x16, 0x5A,
        0xE3, 0xE2, 0x41, 0xA1, 0x82, 0x34, 0xE7, 0x4F,
        0xF3, 0xDD, 0xB9, 0x21, 0xA5, 0x30, 0x0B, 0x1C,
        0x4F, 0xB6, 0xE4, 0x32, 0xE6, 0x98, 0xF5, 0x3F,
        0x66, 0xE3, 0x8C, 0x07, 0xBC, 0xD6, 0xE7, 0x76,
        0x05, 0xDF, 0x46, 0x24, 0xD5, 0x79, 0x07, 0x62,
        0x92, 0xDE, 0x1C, 0xE6, 0xFC, 0x6F, 0x00, 0x81,
        0xA3, 0x8B, 0xD9, 0x2D, 0x39, 0xB2, 0x4B, 0x73,
        0xBA, 0xC1, 0xC5, 0x2B, 0xD6, 0x8E, 0x91, 0x81,
        0xD3, 0xDC, 0xD0, 0xAC, 0x75, 0x34, 0xDB, 0x48,
        0x90, 0x1E, 0x59, 0x84, 0xF9, 0x90, 0x25, 0x57,
        0xBF, 0xA2, 0x31, 0xB2, 0xEA, 0x28, 0xC3, 0x18,
        0x32, 0x62, 0xA1, 0xB2, 0x22, 0x1F, 0x74, 0x26,
        0xEA, 0x88, 0xA5, 0x81, 0x60, 0x93, 0xA5, 0xCA,
        0xE2, 0xCD, 0x5D, 0x59, 0xA9, 0x39, 0x0F, 0xC9,
        0x3A, 0x29, 0x56, 0x94, 0x4B, 0x06, 0x4C, 0xF0,
        0x13, 0xBC, 0xDB, 0x67, 0xFB, 0x42, 0x3D, 0x13,
        0x28, 0xD2, 0xC6, 0xD7, 0xBA, 0x32, 0x90, 0x13,
        0xFA, 0x2D, 0x30, 0xEF, 0xD6, 0x9F, 0xDC, 0xA1,
        0xA9, 0x5E, 0xA6, 0xD0, 0x6C, 0x73, 0x63, 0x53,
        0x4B, 0x2F, 0x3F, 0x7D, 0xAA, 0xFA, 0x29, 0x6E,
        0xAA, 0x09, 0xB3, 0x66, 0x8E, 0x9C, 0xF8, 0x2D,
        0x9B, 0xA9, 0x59, 0xB3, 0x2F, 0x3C, 0xAD, 0x3C,
        0x10, 0xC6, 0xEA, 0x48, 0x61, 0x15, 0x54, 0x53,
        0x9C, 0x37, 0xDF, 0x6B, 0xCA, 0x33, 0x85, 0xEA,
        0xD3, 0xFC, 0xFF, 0x96, 0xD3, 0x72, 0xB4, 0x23,
        0x93, 0xB7, 0x3C, 0x8D, 0xAA, 0xAA, 0x31, 0x50,
        0x6E, 0xE0, 0x52, 0x7B, 0x7F, 0xB3, 0xE5, 0x93,
        0xDC, 0xCC, 0xA5, 0x7C, 0x8F, 0xBB, 0xD4, 0xA3,
        0xC7, 0xF8, 0xA5, 0x38, 0x99, 0x86, 0x91, 0x32,
        0xFB, 0xC3, 0xE4, 0x05, 0x06, 0x07, 0xBB, 0xFE,
        0x29, 0xC6, 0x75, 0xE3, 0x94, 0x5E, 0x74, 0xA3,
        0x1C, 0xD5, 0x31, 0xBA, 0x7A, 0xEB, 0x2E, 0x2F,
        0x0C, 0xD9, 0x90, 0xB8, 0xF9, 0x83, 0xA9, 0x0D,
        0xFE, 0xA0, 0x56, 0x8F, 0x06, 0x77, 0xEA, 0x95,
        0x63, 0xF7, 0xC4, 0x79, 0xDE, 0x96, 0x89, 0x40,
        0xCF, 0x24, 0x29, 0x92, 0x69, 0x28, 0x65, 0xCF,
        0xDA, 0x89, 0xFA, 0x07, 0x8B, 0xBE, 0xF4, 0x9C,
        0xE4, 0x57, 0x5B, 0xDF, 0xB3, 0x80, 0x36, 0x60,
        0x11, 0xC8, 0x43, 0x5F, 0x12, 0xB4, 0x2D, 0x9A,
        0xB9, 0x9A, 0xB6, 0xA3, 0x19, 0x12, 0xC4, 0x35,
        0x41, 0x49, 0xD7, 0x23, 0x10, 0x1D, 0x13, 0x65,
        0xA6, 0x5E, 0x7C, 0xC6, 0x8D, 0x82, 0xE3, 0x05,
        0x17, 0x77, 0x39, 0x02, 0xFB, 0x38, 0xDD, 0xA2,
        0xB3, 0x24, 0xE7, 0x20, 0x8E, 0x98, 0x7E, 0xD2,
        0x87, 0xD0, 0x92, 0xE7, 0x66, 0x2A, 0x43, 0x02,
        0x41, 0xBF, 0xCA, 0x55, 0x2D, 0x31, 0x41, 0x27,
        0xE3, 0x8C, 0x85, 0x97, 0xA8, 0x95, 0x19, 0xD4,
        0xF1, 0xE6, 0x2A, 0x79, 0x46, 0x5A, 0xD5, 0xF4,
        0xEA, 0xA3, 0xFA, 0x77, 0xCD, 0x98, 0x32, 0x6D,
        0x2F, 0x92, 0xCE, 0x98, 0x52, 0x05, 0x5C, 0xEC,
        0xCF, 0x62, 0xD6, 0x3C, 0xB9, 0xD7, 0xF1, 0x98,
        0xAE, 0x08, 0x5E, 0x4D, 0x45, 0xC8, 0xE4, 0x8F,
        0xCF, 0xFE, 0x59, 0x3A, 0xD6, 0x52, 0xD9, 0x15,
        0x41, 0x67, 0xBF, 0x3E, 0x61, 0x95, 0x81, 0x0A,
        0x44, 0x5A, 0xE1, 0x58, 0xF1, 0xF9, 0xA6, 0x79,
        0x33, 0x63, 0xAF, 0xC1, 0xF2, 0x2C, 0xA8, 0x82,
        0xFE, 0xED, 0x3A, 0x5F, 0x57, 0x27, 0xCA, 0x76,
        0x47, 0x7C, 0x5F, 0x23, 0xF0, 0xFC, 0x87, 0x00,
        0xCD, 0xC6, 0xA5, 0xBC, 0xB2, 0xB2, 0x0B, 0x4F,
        0x92, 0x66, 0x35, 0x1D, 0x30, 0x4A, 0x96, 0xA8,
        0x2B, 0xF5, 0xF3, 0x14, 0xAF, 0x68, 0x5C, 0x1C,
        0x70, 0x7C, 0x92, 0xE3, 0xE8, 0x47, 0xB7, 0x04,
        0x7D, 0x68, 0x9C, 0x70, 0xB2, 0x5E, 0x55, 0x01,
        0xCA, 0xEC, 0x99, 0x19, 0x62, 0x6F, 0x4A, 0x0F,
        0xC8, 0x15, 0x86, 0xAF, 0x1E, 0xC8, 0x88, 0x89,
        0xB4, 0x23, 0x38, 0x7D, 0x5D, 0x95, 0x48, 0x26,
        0x18, 0xA6, 0x50, 0xE8, 0x0B, 0x53, 0xB0, 0x7C,
        0xAC, 0xE3, 0x22, 0x89, 0x40, 0x60, 0x2E, 0x3D,
        0xB4, 0x74, 0x66, 0xCE, 0x9B, 0xCC, 0xB6, 0xE4,
        0xD8, 0xAA, 0x61, 0xC8, 0x91, 0x25, 0x83, 0xE8,
        0x10, 0xB3, 0xB2, 0xE7, 0xE9, 0xCB, 0x48, 0xBD,
        0x40, 0x3E, 0xCF, 0x08, 0xD2, 0x8C, 0x70, 0xAE,
        0x0B, 0x62, 0x08, 0x59, 0xC1, 0xF0, 0x9B, 0x61,
        0x13, 0x14, 0x04, 0xC3, 0xD5, 0xBF, 0xFC, 0xD8,
        0x60, 0xE0, 0xF4, 0x2A, 0xB2, 0x99, 0x00, 0x62,
        0x30, 0xB2, 0x87, 0x6D, 0x77, 0xDD, 0xA9, 0x1C,
        0x8C, 0x62, 0xBD, 0x93, 0xA8, 0x44, 0xE4, 0xB3,
        0x44, 0xE3, 0x25, 0x5E, 0xEA, 0x53, 0x1C, 0x6C,
        0x45, 0x8D, 0x04, 0xAB, 0xDB, 0x0F, 0xAE, 0xF2,
        0xD1, 0xC0, 0xB4, 0xC5, 0x5F, 0x57, 0x0A, 0x5A,
        0x51, 0x02, 0x3F, 0x4D, 0x4E, 0xFF, 0xF5, 0x9F,
        0x9A, 0xBE, 0x17, 0x92, 0x2F, 0xE7, 0x32, 0xCA,
        0x71, 0xBC, 0xD4, 0x34, 0xAD, 0x77, 0x10, 0xB8,
        0x4C, 0xD4, 0xAC, 0x9F, 0x25, 0x07, 0xA0, 0x68,
        0x26, 0x56, 0x2A, 0xD7, 0xF6, 0x47, 0x82, 0x6F,
        0x9D, 0xBB, 0xE4, 0xED, 0xD2, 0x3F, 0x12, 0x43,
        0x69, 0xDB, 0x85, 0x26, 0xFC, 0x2B, 0x4D, 0x52,
        0xF0, 0x74, 0x14, 0x15, 0xF9, 0x72, 0xBE, 0xF6,
        0xA9, 0x35, 0xBD, 0x81, 0x2A, 0x56, 0xC8, 0x22,
        0x1B, 0x7D, 0xEF, 0x0F, 0x51, 0x06, 0xBC, 0x01,
        0xE9, 0x13, 0xE3, 0xD4, 0x3D, 0xB8, 0x6C, 0x2B,
        0xB4, 0xC7, 0xE0, 0x76, 0x26, 0x63, 0xC6, 0xDE,
        0x78, 0x87, 0x21, 0xC2, 0xAA, 0x07, 0xF8, 0x95,
        0x48, 0x87, 0xE2, 0x14, 0x2F, 0x2E, 0x91, 0x4A,
        0x09, 0x9E, 0xFC, 0x0A, 0xEE, 0x13, 0x39, 0x21,
        0x0D, 0x3E, 0x53, 0xDA, 0x3E, 0xCF, 0x88, 0x62,
        0x4B, 0x11, 0x19, 0xBE, 0x34, 0x01, 0x0B, 0x88,
        0x6C, 0x80, 0xF5, 0x1D, 0x18, 0x50, 0x83, 0x8F,
        0x21, 0x50, 0xE7, 0x2B, 0x04, 0x2A, 0xF3, 0x28,
        0x99, 0xC0, 0xD3, 0xD7, 0xB0, 0x2A, 0x57, 0xF8,
        0xCF, 0x26, 0x3A, 0x36, 0x95, 0x62, 0xE4, 0xE9,
        0x45, 0xA3, 0x12, 0x82, 0xA5, 0x02, 0xA9, 0x5E,
        0xE9, 0xBB, 0x03, 0x16, 0xC6, 0x86, 0x10, 0x06,
        0xDA, 0xC1, 0x7F, 0x93, 0x6F, 0x54, 0xC4, 0xC7
    };
#endif /* WOLFSSL_NO_ML_DSA_87 */
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
#ifndef WOLFSSL_NO_ML_DSA_44
    static const byte seed_44_draft[] = {
        0xBA, 0xC0, 0x59, 0x52, 0x75, 0x5B, 0x26, 0x47,
        0x01, 0xCA, 0x7D, 0x80, 0x6D, 0xFA, 0x08, 0x35,
        0x10, 0x28, 0xF6, 0x7B, 0x0E, 0x83, 0xC4, 0x24,
        0x01, 0x6F, 0x66, 0xCC, 0x83, 0x87, 0xD4, 0x69
    };
    static const byte pk_44_draft[] = {
        0x86, 0xF0, 0x0C, 0x20, 0xE0, 0xDA, 0xEE, 0x5E,
        0x1E, 0xDE, 0x71, 0x39, 0x49, 0x0C, 0xC8, 0xCF,
        0xEF, 0xC9, 0xAB, 0x62, 0x3B, 0x8D, 0xEF, 0x0B,
        0xD8, 0x03, 0x12, 0x5B, 0x4A, 0xB2, 0x83, 0x61,
        0xED, 0x7E, 0xA9, 0xED, 0x2D, 0xED, 0x5A, 0x71,
        0xDD, 0xAE, 0x4A, 0x06, 0xE0, 0x2A, 0x5A, 0xAF,
        0x99, 0x69, 0x89, 0xC6, 0xAF, 0xE3, 0x2A, 0xFE,
        0x3D, 0x6E, 0x0A, 0x46, 0x71, 0x48, 0xD7, 0x17,
        0x99, 0x20, 0x01, 0x78, 0xD5, 0x8B, 0x40, 0xCB,
        0x81, 0xA0, 0x33, 0x38, 0xAE, 0x2B, 0x83, 0x4A,
        0xFD, 0x5F, 0xE0, 0xB7, 0xEE, 0xA0, 0xC4, 0x3D,
        0xB6, 0xA4, 0xD5, 0x59, 0x4B, 0xDD, 0x87, 0x1A,
        0xFC, 0x03, 0x30, 0xA0, 0xB3, 0xAD, 0x75, 0x3C,
        0xD4, 0x47, 0x72, 0x59, 0xCE, 0xB7, 0x80, 0xFD,
        0x34, 0x35, 0x5E, 0x96, 0xC8, 0x42, 0xD9, 0xDD,
        0x6C, 0xF1, 0xAB, 0xEF, 0x48, 0xD1, 0xA8, 0x02,
        0x02, 0x0F, 0x5B, 0x71, 0x4D, 0x36, 0x1E, 0x0D,
        0xC2, 0x09, 0x46, 0x7B, 0xF9, 0xEA, 0x24, 0x8F,
        0x7C, 0xCF, 0xB8, 0x9C, 0xF7, 0x49, 0x15, 0x8E,
        0x16, 0x49, 0x7E, 0xC5, 0x54, 0xF5, 0x03, 0x1D,
        0x16, 0x12, 0x02, 0x72, 0x1B, 0x38, 0x2D, 0x58,
        0x53, 0x15, 0x5E, 0xB6, 0x72, 0xCC, 0xA1, 0x09,
        0xB0, 0x2F, 0x10, 0xFA, 0x21, 0x45, 0x46, 0x37,
        0xD4, 0xFA, 0x7F, 0xFB, 0xB0, 0xD9, 0x20, 0xE2,
        0xCB, 0x56, 0xB3, 0x1E, 0xDF, 0x82, 0x67, 0x25,
        0x09, 0xD1, 0x8F, 0xFF, 0xE0, 0x43, 0xBD, 0x37,
        0x2B, 0x73, 0x0E, 0x13, 0x08, 0xC9, 0x49, 0x88,
        0x69, 0x69, 0xD9, 0x8C, 0x86, 0xE4, 0x7E, 0x63,
        0x35, 0xC5, 0xE1, 0xD0, 0x14, 0x9A, 0x89, 0x27,
        0x28, 0x17, 0xB0, 0x5B, 0x7A, 0x8F, 0xDD, 0x72,
        0x8B, 0x0A, 0x0D, 0x49, 0x58, 0x59, 0x2F, 0x0D,
        0x8F, 0x3D, 0x16, 0xCE, 0x7B, 0x11, 0xC7, 0x06,
        0x5D, 0xD5, 0x6D, 0x7B, 0x96, 0xED, 0x1E, 0x1A,
        0xF4, 0x10, 0x85, 0xDA, 0xDE, 0x84, 0x2F, 0x2B,
        0xBA, 0xFB, 0xA2, 0x5F, 0x33, 0x7D, 0x7C, 0x18,
        0x6B, 0xDF, 0x43, 0x3C, 0xE9, 0xEB, 0xB4, 0xC5,
        0x8E, 0x52, 0xF5, 0x7E, 0x4C, 0x3E, 0x6A, 0x33,
        0x41, 0x4C, 0x14, 0x05, 0x8E, 0x2C, 0x19, 0x0E,
        0x86, 0x91, 0x66, 0xDE, 0xF6, 0x4B, 0x35, 0xC2,
        0xDF, 0x3D, 0x4C, 0x7B, 0xC5, 0x58, 0x5E, 0x86,
        0x89, 0x6A, 0xFC, 0x86, 0x48, 0x75, 0xD1, 0x18,
        0xD1, 0xCB, 0x41, 0xC0, 0xF6, 0xD8, 0x87, 0x79,
        0xD9, 0xA2, 0x56, 0x2E, 0x83, 0x26, 0x11, 0xC1,
        0x4B, 0x53, 0x37, 0x85, 0x62, 0xFF, 0x6A, 0x67,
        0xFD, 0x18, 0x79, 0xD7, 0x55, 0x9B, 0xF7, 0x64,
        0xA9, 0x21, 0xB6, 0x1B, 0xF6, 0x11, 0x85, 0xF8,
        0xC0, 0x68, 0xDE, 0x61, 0x0C, 0x61, 0x7E, 0x8E,
        0xED, 0x9E, 0x58, 0x84, 0x16, 0x1A, 0x28, 0xC5,
        0x41, 0x63, 0xB3, 0xF0, 0x82, 0xAA, 0xE8, 0x36,
        0x81, 0x5C, 0xD3, 0xB7, 0xFB, 0x92, 0xF4, 0x7A,
        0x1E, 0x85, 0xA2, 0xB7, 0x21, 0xD5, 0xFA, 0xC8,
        0xE8, 0x02, 0x43, 0x5B, 0x56, 0x42, 0x03, 0x17,
        0x67, 0xEE, 0x3E, 0x31, 0x23, 0x63, 0xC7, 0x33,
        0x95, 0xDE, 0x07, 0xF6, 0x11, 0x3A, 0x2C, 0x3F,
        0x7B, 0xBB, 0x2D, 0x5C, 0x23, 0xF9, 0x2F, 0x9C,
        0x51, 0x19, 0x9F, 0x35, 0xC3, 0x18, 0x9F, 0x83,
        0x6E, 0xA8, 0x03, 0xF1, 0x79, 0x1F, 0xB0, 0xC8,
        0x2F, 0xF4, 0x2E, 0x9A, 0x26, 0xF3, 0x44, 0x02,
        0x8F, 0x45, 0x8B, 0xB0, 0x25, 0x1D, 0xF2, 0xD4,
        0x55, 0xB7, 0x65, 0xEF, 0xDB, 0x3D, 0x8E, 0x92,
        0xC8, 0xA0, 0x63, 0x4C, 0x38, 0xA3, 0x54, 0xD3,
        0xC2, 0x5A, 0x2A, 0x6A, 0x15, 0x27, 0x2A, 0xE2,
        0xFC, 0x25, 0xB6, 0xC8, 0x68, 0xEB, 0xED, 0x2D,
        0x23, 0xE8, 0x6D, 0x5C, 0xDD, 0x3F, 0x18, 0xB4,
        0x6E, 0x79, 0x36, 0xC9, 0x1C, 0xB4, 0x92, 0x41,
        0xAD, 0x35, 0xD4, 0x15, 0xE4, 0x64, 0x1C, 0x51,
        0xCB, 0x0C, 0x41, 0xB7, 0xFD, 0xC1, 0x09, 0x3E,
        0xD2, 0x4D, 0x38, 0x88, 0x77, 0x1C, 0x71, 0x91,
        0x74, 0xD3, 0x28, 0xE0, 0xCE, 0x9A, 0x11, 0x8D,
        0xBF, 0x4D, 0x8D, 0xF0, 0x44, 0xF6, 0x79, 0xFC,
        0x4C, 0xAD, 0x17, 0x88, 0xC0, 0x8C, 0x0B, 0x7A,
        0x90, 0x01, 0x53, 0x6C, 0x6B, 0x44, 0xF6, 0xE5,
        0x2E, 0xEC, 0x44, 0x4F, 0xB8, 0x9B, 0x10, 0xBE,
        0xCF, 0x55, 0x55, 0x29, 0x83, 0xB8, 0xD0, 0x25,
        0x5B, 0xCE, 0x8F, 0xA5, 0xB7, 0x6C, 0xA7, 0x47,
        0x65, 0xA9, 0xE9, 0x9B, 0xA5, 0xBC, 0x28, 0x1D,
        0x9F, 0x1F, 0x5E, 0x97, 0x42, 0x10, 0x84, 0x92,
        0xFB, 0x38, 0x0B, 0x2E, 0xAC, 0x79, 0x0A, 0x7D,
        0x00, 0x2C, 0x35, 0xD0, 0x54, 0x0D, 0x28, 0xE7,
        0xAB, 0x06, 0x02, 0xDA, 0x89, 0xA3, 0x06, 0x8E,
        0x13, 0x9A, 0xA7, 0xCA, 0x48, 0x09, 0xB0, 0x48,
        0x37, 0x08, 0xA7, 0x7D, 0xDA, 0xEB, 0x58, 0x64,
        0x39, 0xB3, 0xF3, 0xB2, 0x4C, 0x00, 0x4B, 0xCB,
        0x94, 0x36, 0xD4, 0x7C, 0x73, 0x45, 0xC8, 0x93,
        0xE5, 0x2A, 0x11, 0xF0, 0xEF, 0x0C, 0xED, 0x5F,
        0x8B, 0x0C, 0x86, 0xAD, 0x3A, 0x01, 0x07, 0x1A,
        0xC0, 0x34, 0xE8, 0x74, 0x21, 0x27, 0x73, 0x56,
        0x93, 0x76, 0x5D, 0x80, 0x59, 0xB4, 0xA4, 0xDC,
        0x80, 0xE7, 0xCE, 0x70, 0x0E, 0x0F, 0xEC, 0x56,
        0x42, 0x6E, 0x9C, 0x76, 0x3D, 0xF6, 0xB4, 0x41,
        0xE2, 0x3E, 0xAC, 0x25, 0xE7, 0x86, 0xA7, 0xA7,
        0x0A, 0x0D, 0x5D, 0x04, 0x1F, 0x45, 0xD4, 0x5B,
        0x42, 0x38, 0x4C, 0x60, 0xE7, 0xB7, 0x0D, 0xC7,
        0x28, 0x4F, 0xA5, 0x4E, 0x0C, 0x1B, 0xC4, 0xDA,
        0x50, 0x1A, 0xA0, 0x93, 0xAE, 0x10, 0x9A, 0x1A,
        0xC8, 0xC6, 0x56, 0xFC, 0x0A, 0xEA, 0x89, 0x3A,
        0x28, 0x21, 0xE9, 0x52, 0x9D, 0xEB, 0x07, 0x68,
        0xC1, 0x57, 0x32, 0x25, 0x1F, 0x93, 0x5D, 0x35,
        0xB2, 0x4B, 0x58, 0x30, 0xAF, 0x51, 0xC6, 0x7D,
        0x47, 0xD1, 0xA2, 0xAD, 0xDE, 0x75, 0x48, 0x84,
        0x74, 0x19, 0x74, 0x18, 0xA0, 0x2C, 0xD8, 0xB2,
        0xFE, 0x44, 0x78, 0x95, 0x6A, 0xBF, 0x56, 0x4D,
        0x20, 0x79, 0xE7, 0xE2, 0xE3, 0x56, 0x69, 0xB3,
        0xFA, 0xE1, 0xEB, 0xE6, 0x11, 0xAC, 0x18, 0xB3,
        0x98, 0xC1, 0x04, 0x20, 0x96, 0x4B, 0xAD, 0xDE,
        0x5B, 0x18, 0xEB, 0x7B, 0xBC, 0x15, 0x11, 0x57,
        0x29, 0x10, 0xE5, 0x80, 0x78, 0x4A, 0xF0, 0x87,
        0xF6, 0xD1, 0x3C, 0x23, 0xC5, 0xF4, 0x2D, 0xD7,
        0xAB, 0xA4, 0xD7, 0xB8, 0x45, 0x8E, 0x04, 0x1B,
        0x78, 0x59, 0x9F, 0x81, 0xE6, 0x04, 0xDF, 0x70,
        0x2B, 0x14, 0x74, 0x16, 0x49, 0xDA, 0xF0, 0xE1,
        0xC8, 0x29, 0xCC, 0x87, 0x8C, 0x2F, 0xFB, 0x18,
        0x3B, 0x47, 0xFC, 0x79, 0x04, 0x84, 0xCB, 0x0A,
        0xD2, 0x64, 0xBF, 0x86, 0xEA, 0x01, 0xAC, 0xE0,
        0xBD, 0xEC, 0x3B, 0xE1, 0xA7, 0x6C, 0xDE, 0x1D,
        0x58, 0x76, 0xCC, 0x53, 0x9E, 0xF6, 0xC6, 0xD4,
        0x2C, 0x87, 0x92, 0xA2, 0x89, 0x27, 0x31, 0x33,
        0x01, 0xA5, 0xA2, 0xE8, 0x8F, 0x13, 0x19, 0x0F,
        0xFD, 0x73, 0xB9, 0x91, 0xBD, 0xB8, 0x80, 0x9A,
        0xA3, 0xB1, 0x21, 0x6C, 0x91, 0x13, 0x8A, 0xAE,
        0xC7, 0xCB, 0x67, 0x14, 0xD1, 0xC0, 0x28, 0x89,
        0x04, 0x8C, 0x9F, 0xDE, 0xA0, 0x9A, 0x99, 0xA8,
        0x61, 0xE6, 0x8F, 0x8E, 0x39, 0xEF, 0x6B, 0x5E,
        0x84, 0x5F, 0x5D, 0x24, 0x37, 0x73, 0x9D, 0x75,
        0xC4, 0xEF, 0xE2, 0xA1, 0xF2, 0xBC, 0x0D, 0xE1,
        0x0D, 0xEC, 0xFA, 0xEE, 0xC1, 0x63, 0xC8, 0x2E,
        0x7D, 0x85, 0x65, 0xC3, 0xF2, 0x0D, 0x8B, 0x73,
        0xF9, 0x3B, 0x0B, 0x3D, 0x49, 0x8B, 0xFB, 0x16,
        0x5B, 0x75, 0x48, 0x9B, 0x56, 0x0A, 0x83, 0x4C,
        0x0D, 0x13, 0xB2, 0xB4, 0x25, 0xC7, 0x2C, 0xCB,
        0xA7, 0x9E, 0xCA, 0x41, 0x44, 0x14, 0x9A, 0x03,
        0xD3, 0x01, 0x8C, 0xB0, 0xD5, 0xA9, 0x36, 0xA4,
        0x16, 0x21, 0x49, 0x0A, 0x99, 0xA1, 0x89, 0xA5,
        0x91, 0x10, 0xA2, 0x1B, 0x3F, 0x98, 0x1E, 0x1C,
        0x43, 0xAA, 0x9C, 0x16, 0x5A, 0xF0, 0x18, 0x64,
        0x0F, 0x6A, 0xE3, 0x97, 0x83, 0x31, 0x4E, 0x84,
        0xC9, 0xEA, 0xD8, 0x9F, 0xEA, 0x9E, 0xD6, 0xF2,
        0x0E, 0x15, 0xA5, 0x48, 0x15, 0x8B, 0x10, 0x1D,
        0x77, 0x78, 0x1B, 0x54, 0x03, 0xC1, 0x2C, 0xB1,
        0xC8, 0x22, 0x11, 0x9D, 0xB8, 0x82, 0x94, 0x26,
        0xA0, 0xED, 0x6C, 0xAD, 0xA8, 0x03, 0xC2, 0xED,
        0x02, 0x74, 0x3E, 0x54, 0xBD, 0x77, 0xA6, 0x0B,
        0x37, 0xFE, 0x04, 0xCD, 0x25, 0x10, 0x2D, 0x52,
        0xC2, 0xD4, 0x5B, 0x9B, 0xAE, 0xFE, 0x35, 0x73,
        0x16, 0x61, 0x84, 0x25, 0x1D, 0xBE, 0x95, 0x34,
        0xA4, 0xF6, 0xB9, 0xA4, 0xF9, 0xAA, 0x5D, 0x1E,
        0x49, 0xBB, 0x19, 0xD9, 0x64, 0xD7, 0x48, 0x1A,
        0x0A, 0x93, 0xC3, 0x69, 0x13, 0x12, 0x68, 0xBB,
        0x97, 0x97, 0xBD, 0x99, 0x69, 0xCE, 0xE6, 0xF5,
        0x84, 0x7B, 0xCC, 0xE4, 0x7D, 0xD3, 0xCD, 0x8A,
        0x7A, 0x4B, 0x98, 0xF4, 0x09, 0x9D, 0xEA, 0x5D,
        0x4E, 0x1F, 0xE1, 0x1E, 0x6C, 0x48, 0xD3, 0x5E,
        0x67, 0xD9, 0xFF, 0x64, 0x4D, 0xA7, 0x64, 0x7A,
        0x01, 0xB2, 0xE9, 0x63, 0x14, 0x10, 0xB7, 0x08,
        0x0C, 0xF9, 0x4D, 0x66, 0x48, 0x46, 0xE3, 0xC2,
        0x48, 0x6B, 0x47, 0xCE, 0x00, 0x98, 0x92, 0x83,
        0xF7, 0xE0, 0x1F, 0x96, 0xFA, 0x53, 0xD5, 0x49,
        0x1C, 0xC7, 0x89, 0xB4, 0xA5, 0x4B, 0x63, 0xBF,
        0xD2, 0x00, 0x79, 0xDD, 0xC1, 0x60, 0xAA, 0xF2,
        0x0F, 0x47, 0xB9, 0x4F, 0x8A, 0x66, 0x05, 0x3D,
        0x96, 0x36, 0x64, 0x48, 0x5F, 0x7E, 0x56, 0x2B,
        0xB3, 0x47, 0xE2, 0x76, 0x64, 0x21, 0x65, 0x34,
        0xFC, 0xDD, 0x2D, 0x4C, 0xE2, 0x99, 0x33, 0x04,
        0xE4, 0x26, 0x15, 0x37, 0x6C, 0x32, 0xB9, 0x17
    };
    static const byte sk_44_draft[] = {
        0x86, 0xF0, 0x0C, 0x20, 0xE0, 0xDA, 0xEE, 0x5E,
        0x1E, 0xDE, 0x71, 0x39, 0x49, 0x0C, 0xC8, 0xCF,
        0xEF, 0xC9, 0xAB, 0x62, 0x3B, 0x8D, 0xEF, 0x0B,
        0xD8, 0x03, 0x12, 0x5B, 0x4A, 0xB2, 0x83, 0x61,
        0x73, 0x61, 0x49, 0x01, 0x0F, 0x94, 0x08, 0x30,
        0x26, 0x02, 0x12, 0x63, 0x64, 0x15, 0x7A, 0x4D,
        0xBA, 0xF5, 0x25, 0xA7, 0xAA, 0x0B, 0x7C, 0x3D,
        0xCE, 0x05, 0x91, 0x95, 0xEF, 0x17, 0x2F, 0xE2,
        0x5A, 0x03, 0x5E, 0x2E, 0x4D, 0xFA, 0xE7, 0x5F,
        0xCD, 0x61, 0x34, 0xFB, 0x3D, 0x3C, 0x5C, 0x60,
        0x1A, 0x6F, 0x09, 0xB5, 0x9D, 0xDD, 0x90, 0x53,
        0xF6, 0x89, 0x50, 0xC2, 0xE1, 0xED, 0x0A, 0x61,
        0x8F, 0xFA, 0xDC, 0x2D, 0xB2, 0x8B, 0xA1, 0x56,
        0xAC, 0x5E, 0x0E, 0xF1, 0x3B, 0x1E, 0x22, 0x9F,
        0xAA, 0x05, 0x96, 0xA3, 0x5E, 0x44, 0x86, 0xA8,
        0xBA, 0x15, 0xD1, 0x11, 0x7D, 0xAA, 0xD0, 0xAA,
        0x01, 0x27, 0x25, 0x04, 0x82, 0x89, 0xA4, 0x22,
        0x2E, 0xDB, 0x80, 0x45, 0xD2, 0x30, 0x45, 0x59,
        0x16, 0x64, 0xE2, 0x08, 0x86, 0x50, 0x00, 0x8E,
        0xCA, 0x08, 0x51, 0x5A, 0x06, 0x01, 0x54, 0x82,
        0x20, 0xC4, 0x92, 0x30, 0x02, 0x21, 0x4E, 0x0A,
        0x93, 0x89, 0x84, 0xB8, 0x70, 0x24, 0x40, 0x51,
        0x24, 0xB3, 0x44, 0xDB, 0x08, 0x40, 0x1B, 0x37,
        0x44, 0x21, 0x22, 0x8E, 0x8C, 0x16, 0x42, 0x10,
        0x22, 0x0E, 0xA1, 0xB2, 0x8D, 0x18, 0x49, 0x30,
        0xC1, 0x32, 0x69, 0x21, 0x03, 0x8E, 0x49, 0x44,
        0x08, 0xD3, 0x16, 0x89, 0x10, 0xA4, 0x25, 0x5C,
        0x22, 0x8A, 0xC0, 0xC8, 0x08, 0xC1, 0x04, 0x6A,
        0xD2, 0xA0, 0x50, 0x8A, 0x02, 0x52, 0x92, 0x16,
        0x44, 0x54, 0x30, 0x4A, 0x92, 0x32, 0x0C, 0x4C,
        0x44, 0x2D, 0x04, 0x15, 0x2A, 0x99, 0x24, 0x42,
        0x52, 0xA8, 0x30, 0x53, 0x24, 0x85, 0x9A, 0xB8,
        0x01, 0xE2, 0x08, 0x09, 0x23, 0x28, 0x08, 0xC4,
        0x98, 0x85, 0x0B, 0xB9, 0x40, 0x60, 0x26, 0x28,
        0x0A, 0x45, 0x12, 0x0C, 0x43, 0x84, 0x82, 0x16,
        0x89, 0xC4, 0x48, 0x28, 0x58, 0x18, 0x2A, 0x20,
        0x07, 0x02, 0xD3, 0x82, 0x45, 0x50, 0xB0, 0x50,
        0x64, 0x36, 0x91, 0x52, 0x02, 0x45, 0x5A, 0x42,
        0x26, 0x01, 0x28, 0x71, 0xD4, 0x86, 0x10, 0x19,
        0xC4, 0x68, 0xC4, 0x30, 0x66, 0xE0, 0x02, 0x49,
        0x18, 0x34, 0x05, 0x04, 0x02, 0x04, 0x90, 0x94,
        0x4C, 0x01, 0xA7, 0x80, 0x12, 0x97, 0x08, 0x19,
        0xC5, 0x41, 0x24, 0xC1, 0x61, 0x08, 0xB0, 0x0C,
        0x21, 0xC1, 0x49, 0x9B, 0x42, 0x51, 0x62, 0x18,
        0x22, 0x54, 0x06, 0x06, 0x93, 0x26, 0x70, 0x49,
        0x86, 0x91, 0x00, 0x28, 0x6C, 0x02, 0xC9, 0x60,
        0x13, 0xC3, 0x09, 0xCB, 0x14, 0x66, 0x09, 0x17,
        0x25, 0x1C, 0x16, 0x89, 0x01, 0xB6, 0x01, 0x60,
        0x86, 0x71, 0x58, 0x96, 0x04, 0x82, 0x38, 0x61,
        0x43, 0x40, 0x72, 0xCC, 0x46, 0x71, 0x81, 0x20,
        0x2C, 0x18, 0x20, 0x6E, 0x03, 0x91, 0x11, 0x9A,
        0x08, 0x89, 0x43, 0x06, 0x48, 0x64, 0x02, 0x6C,
        0x21, 0x33, 0x8D, 0x48, 0x16, 0x66, 0x9B, 0xA4,
        0x2D, 0x01, 0x10, 0x66, 0xDC, 0xB0, 0x25, 0x40,
        0xA0, 0x24, 0xA2, 0xB4, 0x44, 0xC8, 0x26, 0x61,
        0x0A, 0x10, 0x4E, 0xD0, 0x04, 0x11, 0x4A, 0x82,
        0x51, 0x03, 0x04, 0x6C, 0x18, 0x88, 0x6C, 0xE0,
        0x98, 0x41, 0x11, 0x29, 0x06, 0x62, 0x12, 0x8E,
        0xDA, 0x42, 0x91, 0x09, 0x48, 0x60, 0xD1, 0xB4,
        0x80, 0x10, 0x30, 0x30, 0x80, 0x38, 0x82, 0xD0,
        0x84, 0x0D, 0x08, 0x14, 0x92, 0x24, 0x41, 0x40,
        0x0C, 0x10, 0x89, 0xCC, 0x38, 0x8A, 0x13, 0xB6,
        0x89, 0x1A, 0xA7, 0x24, 0x5C, 0x10, 0x12, 0x1B,
        0x21, 0x50, 0x91, 0xB4, 0x29, 0x99, 0xB6, 0x51,
        0x04, 0xB1, 0x91, 0x59, 0xA6, 0x05, 0x19, 0x08,
        0x4A, 0x4A, 0x84, 0x6C, 0x1C, 0x49, 0x02, 0x44,
        0x20, 0x85, 0x14, 0xB1, 0x89, 0x09, 0x44, 0x2C,
        0x10, 0x02, 0x22, 0xE1, 0xB4, 0x25, 0x01, 0x21,
        0x71, 0x53, 0xC2, 0x85, 0x82, 0x88, 0x28, 0xC0,
        0x02, 0x52, 0x19, 0xC5, 0x51, 0x19, 0xA5, 0x09,
        0xC0, 0x82, 0x91, 0x21, 0x47, 0x0D, 0x1C, 0x30,
        0x69, 0xDC, 0xB8, 0x6C, 0x04, 0x41, 0x6A, 0x91,
        0x16, 0x40, 0xA0, 0xC8, 0x24, 0x1A, 0x10, 0x01,
        0x04, 0x39, 0x25, 0x80, 0x16, 0x02, 0x63, 0x36,
        0x71, 0x90, 0xB0, 0x8D, 0x44, 0x16, 0x8E, 0xDA,
        0x16, 0x2E, 0xCB, 0x44, 0x20, 0x54, 0x38, 0x06,
        0x54, 0xC4, 0x01, 0x51, 0x40, 0x86, 0x52, 0x44,
        0x0E, 0x82, 0x02, 0x32, 0x21, 0x38, 0x89, 0x19,
        0x04, 0x40, 0xD8, 0x12, 0x68, 0x21, 0x98, 0x11,
        0x03, 0x33, 0x8A, 0x18, 0x00, 0x45, 0xCB, 0x22,
        0x32, 0xC3, 0x04, 0x46, 0x09, 0x18, 0x51, 0x22,
        0x44, 0x89, 0x13, 0x16, 0x6E, 0xDA, 0x46, 0x45,
        0x09, 0x19, 0x41, 0x81, 0x10, 0x01, 0xDC, 0x18,
        0x8E, 0xC8, 0x44, 0x4C, 0x00, 0x17, 0x82, 0x9C,
        0xA6, 0x4D, 0xC8, 0x08, 0x10, 0x24, 0x42, 0x6D,
        0x91, 0x38, 0x89, 0x8C, 0x40, 0x6E, 0x00, 0x35,
        0x11, 0xD3, 0x24, 0x09, 0x1A, 0x01, 0x65, 0x88,
        0x48, 0x45, 0x09, 0x01, 0x71, 0x43, 0xB8, 0x80,
        0x11, 0x82, 0x2C, 0x84, 0xB8, 0x49, 0x58, 0x14,
        0x28, 0x92, 0x20, 0x32, 0x09, 0x12, 0x05, 0x20,
        0x81, 0x2D, 0x5B, 0x86, 0x11, 0x04, 0x90, 0x45,
        0x49, 0x80, 0x40, 0xD1, 0xC8, 0x24, 0x98, 0xC2,
        0x2C, 0x99, 0xA2, 0x30, 0x04, 0x98, 0x8C, 0x53,
        0x24, 0x02, 0x8A, 0x04, 0x01, 0x4C, 0x28, 0x71,
        0xC3, 0x86, 0x6C, 0x24, 0x49, 0x81, 0x04, 0x02,
        0x28, 0x62, 0x44, 0x32, 0x61, 0x20, 0x28, 0x01,
        0x04, 0x11, 0x0C, 0x09, 0x08, 0x90, 0x98, 0x84,
        0x63, 0xB2, 0x45, 0x63, 0x38, 0x2E, 0x04, 0xA4,
        0x0C, 0x18, 0x05, 0x4E, 0xCC, 0x86, 0x90, 0x43,
        0x40, 0x91, 0x54, 0x02, 0x21, 0x43, 0x28, 0x42,
        0x23, 0x94, 0x29, 0xC8, 0xA6, 0x91, 0x02, 0x09,
        0x80, 0xE3, 0x82, 0x00, 0xC1, 0x34, 0x08, 0xD1,
        0x34, 0x84, 0x12, 0x45, 0x8C, 0x02, 0xC6, 0x81,
        0x41, 0xC6, 0x6C, 0x1B, 0x12, 0x24, 0x04, 0x08,
        0x0D, 0x02, 0x00, 0x0C, 0x9C, 0xA2, 0x05, 0x49,
        0x34, 0x65, 0x00, 0x06, 0x89, 0x88, 0x34, 0x00,
        0xD8, 0x82, 0x29, 0x92, 0x12, 0x91, 0xE3, 0x36,
        0x86, 0xD1, 0x80, 0x71, 0x98, 0xB0, 0x50, 0x48,
        0xC6, 0x11, 0x14, 0x80, 0x0D, 0xA0, 0x12, 0x4D,
        0x9B, 0xB2, 0x40, 0x21, 0x41, 0x50, 0x4B, 0x36,
        0x05, 0x52, 0x10, 0x26, 0x19, 0xB2, 0x60, 0x92,
        0xA2, 0x24, 0xCB, 0x08, 0x00, 0x14, 0x22, 0x49,
        0x5A, 0xD0, 0x55, 0xBD, 0x2B, 0x45, 0xE4, 0x31,
        0x41, 0xA8, 0xC3, 0xA3, 0xAD, 0xBD, 0xB6, 0x37,
        0x92, 0x06, 0x95, 0x6B, 0x3D, 0xD8, 0xE5, 0x33,
        0x71, 0xB6, 0x62, 0xB7, 0x67, 0x6C, 0x77, 0x84,
        0x63, 0x2F, 0x41, 0x1D, 0xBA, 0x51, 0x27, 0xE1,
        0x24, 0x5D, 0xC2, 0x38, 0x71, 0x65, 0x9E, 0x8E,
        0xE4, 0xEB, 0xBB, 0x1D, 0x89, 0xEB, 0x18, 0xCA,
        0x0C, 0xA6, 0x86, 0xA3, 0x4D, 0x7C, 0x7A, 0x02,
        0xAC, 0xDD, 0x34, 0xCE, 0x05, 0x3B, 0x1B, 0x49,
        0xF4, 0x6D, 0x12, 0x33, 0xBC, 0x52, 0x70, 0x59,
        0xDF, 0xBC, 0x5D, 0x49, 0x42, 0x6A, 0xED, 0xC7,
        0xF1, 0x8C, 0xF5, 0x6D, 0x1F, 0xBC, 0xE4, 0xBD,
        0x45, 0x5D, 0x59, 0xF8, 0xCE, 0x9A, 0x39, 0xB5,
        0x96, 0x32, 0xFD, 0x93, 0x65, 0x8E, 0x92, 0xF1,
        0x8F, 0xB0, 0x99, 0xF3, 0x80, 0x0F, 0x66, 0x14,
        0xFE, 0xEB, 0x23, 0x17, 0x2D, 0x4C, 0x8F, 0x41,
        0x9A, 0x9B, 0xD1, 0x5B, 0x5B, 0xC0, 0x3D, 0xA6,
        0x0E, 0xF3, 0xE0, 0xA1, 0x04, 0xDC, 0x24, 0x18,
        0x9D, 0x90, 0xC6, 0x89, 0x5A, 0x7F, 0x10, 0x1E,
        0x4B, 0x21, 0xEC, 0x91, 0xD8, 0x5D, 0x65, 0xDB,
        0xCF, 0x90, 0x62, 0x85, 0xE9, 0x58, 0xA3, 0x47,
        0x92, 0x1C, 0xD0, 0x0C, 0xA3, 0xF3, 0x3E, 0x36,
        0xDB, 0x24, 0xA6, 0x98, 0xAB, 0xA7, 0x89, 0x2B,
        0x71, 0x6C, 0x4D, 0x00, 0xB0, 0xD5, 0xA0, 0xCA,
        0x1A, 0x76, 0x8E, 0x80, 0xB7, 0xAE, 0x83, 0x89,
        0x50, 0xF8, 0xA7, 0x52, 0x8B, 0x94, 0xD2, 0x2B,
        0x9F, 0x49, 0x92, 0x3D, 0x54, 0x0D, 0xB8, 0xD1,
        0x19, 0x49, 0xAC, 0x91, 0xAF, 0xDB, 0xE9, 0x24,
        0x4D, 0xD8, 0xE1, 0xD5, 0x16, 0x0E, 0xB1, 0x39,
        0x40, 0x7D, 0x5F, 0xF5, 0x92, 0xB4, 0xAF, 0xC3,
        0x76, 0x2B, 0xDB, 0x7D, 0x52, 0x97, 0x62, 0x9F,
        0xCF, 0x32, 0x19, 0x5F, 0xE6, 0x32, 0xFB, 0x8E,
        0x39, 0x24, 0xB4, 0xEB, 0xE9, 0x17, 0x9E, 0x47,
        0x69, 0x4D, 0x92, 0x82, 0x96, 0x88, 0x38, 0x11,
        0xCE, 0xD6, 0xBF, 0x18, 0xE3, 0x51, 0x40, 0x81,
        0x11, 0xA0, 0x74, 0xDA, 0x0D, 0x5E, 0xEC, 0xD8,
        0x5D, 0x33, 0x22, 0x1E, 0xB9, 0x5D, 0xBF, 0x79,
        0xB0, 0xA1, 0xEF, 0xD1, 0x2D, 0xA0, 0x5F, 0xA1,
        0xC7, 0x6E, 0xD5, 0x08, 0xB8, 0xD0, 0xC1, 0x95,
        0x51, 0x9B, 0x07, 0xC3, 0x4A, 0x0A, 0xB5, 0xA1,
        0x28, 0xFE, 0x95, 0x95, 0x0A, 0xCF, 0x83, 0xA8,
        0xEB, 0x8F, 0xFB, 0x18, 0xD5, 0xBD, 0x69, 0x50,
        0xF1, 0xDF, 0x06, 0xFA, 0x9A, 0x65, 0x47, 0xBB,
        0x56, 0xE9, 0xCB, 0x8F, 0x69, 0x5F, 0xE0, 0xAD,
        0x19, 0x3A, 0x70, 0xE5, 0x66, 0x42, 0xD7, 0x1C,
        0x0C, 0xB4, 0x03, 0x89, 0x7D, 0x47, 0x4D, 0x29,
        0x67, 0x8C, 0x41, 0x73, 0xAB, 0x7D, 0xFD, 0x69,
        0x15, 0xAD, 0xE3, 0xB7, 0xF8, 0x98, 0x3B, 0xCA,
        0x8F, 0x27, 0x37, 0x7B, 0x72, 0x2C, 0x5F, 0x23,
        0x73, 0x15, 0xE2, 0xB6, 0xBD, 0xDE, 0x84, 0xF8,
        0x7E, 0x22, 0xB9, 0xFD, 0xD3, 0x4D, 0x62, 0x80,
        0xBA, 0xC5, 0x57, 0x29, 0x30, 0x1B, 0x06, 0x4D,
        0x20, 0xB1, 0x53, 0x86, 0xCB, 0x6A, 0x4A, 0xE3,
        0xC1, 0xA9, 0x88, 0xCF, 0xEB, 0x15, 0x2F, 0xA8,
        0xA8, 0x6F, 0xFC, 0x2A, 0xA8, 0x0E, 0xD9, 0xFA,
        0xEA, 0xD7, 0x3B, 0xCE, 0xF8, 0x5B, 0xD8, 0x92,
        0x22, 0x6A, 0x1A, 0x8E, 0x5E, 0x91, 0x37, 0x2C,
        0x21, 0x05, 0xC4, 0xAC, 0xF7, 0x62, 0x83, 0xBA,
        0x55, 0xD5, 0x2C, 0xCE, 0xA1, 0x19, 0x93, 0x0E,
        0xDE, 0xB6, 0xB8, 0x78, 0x0F, 0xBF, 0x4C, 0xA4,
        0x66, 0xAD, 0x97, 0x2F, 0xEE, 0x34, 0xE9, 0xA2,
        0xB6, 0x1D, 0x3C, 0x60, 0xFB, 0xB8, 0x7F, 0xF8,
        0xFD, 0x34, 0x8C, 0xC5, 0xC7, 0x38, 0x72, 0x74,
        0x19, 0xA9, 0xCF, 0x54, 0x49, 0x5B, 0xBA, 0x70,
        0x12, 0xC1, 0x61, 0xDC, 0x32, 0x61, 0x49, 0x66,
        0xF3, 0x57, 0xAA, 0x0F, 0xE6, 0x44, 0x9E, 0x8A,
        0x19, 0x9C, 0x6B, 0x63, 0x2C, 0x14, 0x1E, 0xDD,
        0x00, 0x27, 0xE3, 0x95, 0xE3, 0xE7, 0xD9, 0xFF,
        0x30, 0x2D, 0x14, 0x19, 0x4F, 0x49, 0x20, 0x0B,
        0x58, 0x2A, 0x23, 0x1C, 0xE2, 0xAD, 0x6B, 0x9C,
        0x7B, 0xB6, 0x20, 0x63, 0x08, 0x24, 0x55, 0x04,
        0x58, 0x1F, 0x0E, 0xBE, 0x2A, 0x6F, 0x79, 0x90,
        0x9E, 0x15, 0x8F, 0x4B, 0xDB, 0xE2, 0xBE, 0xBC,
        0x28, 0xB1, 0xC8, 0xFE, 0x00, 0x6D, 0x71, 0xCC,
        0x91, 0x6A, 0xCC, 0xF8, 0x12, 0x8B, 0xEC, 0xF3,
        0x46, 0x53, 0xB1, 0x7F, 0xB3, 0x79, 0xF0, 0xC7,
        0xD7, 0xA5, 0xCF, 0x2C, 0xC3, 0x09, 0x66, 0x82,
        0x53, 0x43, 0xFD, 0xAC, 0xDE, 0xD5, 0x85, 0xB3,
        0x79, 0x74, 0x55, 0xE8, 0xF6, 0xE5, 0xFB, 0xF0,
        0x63, 0x0C, 0x36, 0x63, 0x65, 0x10, 0x43, 0xC9,
        0x60, 0x99, 0xD6, 0x0C, 0xB9, 0x66, 0x1C, 0xA9,
        0x97, 0x4D, 0xDB, 0xA8, 0x13, 0x9E, 0xAE, 0xCA,
        0x7A, 0x5F, 0xE3, 0x24, 0xA0, 0xEE, 0x8A, 0x9D,
        0x7F, 0x03, 0x53, 0x21, 0x6B, 0xAF, 0x3D, 0xF9,
        0x38, 0xF3, 0x7A, 0x1D, 0xDA, 0xE2, 0xEF, 0xBA,
        0x86, 0x21, 0x85, 0x1F, 0x36, 0x08, 0x0B, 0xDA,
        0x37, 0x5A, 0x0A, 0xD7, 0x55, 0x41, 0xD5, 0x84,
        0x1B, 0x36, 0xA2, 0x50, 0x65, 0xD7, 0xF3, 0xA3,
        0xEB, 0xE1, 0xDE, 0x0F, 0x85, 0xAA, 0xF6, 0x2F,
        0xAB, 0xBB, 0xC8, 0xF1, 0x2A, 0xD1, 0x0A, 0x9B,
        0xE4, 0x7B, 0xBC, 0x4D, 0x42, 0xD8, 0xA3, 0x4C,
        0x07, 0x6A, 0x60, 0x3E, 0xE2, 0xDA, 0xE7, 0x00,
        0xDF, 0x27, 0x94, 0xEF, 0x90, 0x99, 0x88, 0x2C,
        0xCF, 0xAA, 0xE1, 0x71, 0x2D, 0xFD, 0x00, 0x9C,
        0x55, 0xBF, 0xC4, 0x7A, 0x55, 0xE9, 0xE0, 0xB4,
        0x7F, 0x3D, 0xE9, 0xB0, 0x01, 0xA7, 0x27, 0x23,
        0x27, 0x58, 0x31, 0x0E, 0x8E, 0x80, 0xD8, 0xEB,
        0x64, 0xA0, 0xC3, 0xC9, 0xEA, 0x69, 0x9C, 0x74,
        0x5E, 0xAF, 0xD5, 0xEF, 0x5C, 0x4E, 0x40, 0x71,
        0xD6, 0x57, 0x77, 0xE2, 0xAF, 0x0E, 0x1D, 0xB8,
        0x5A, 0x91, 0x20, 0x4C, 0x33, 0x4D, 0xD8, 0x4F,
        0x98, 0xE0, 0x86, 0x1D, 0x02, 0xA0, 0xDA, 0x06,
        0x17, 0xC4, 0x5D, 0x2E, 0x49, 0x31, 0xE6, 0xE4,
        0xDC, 0x18, 0x23, 0x26, 0xF3, 0x61, 0xF5, 0x8D,
        0x26, 0x2C, 0x18, 0x4C, 0xDF, 0x71, 0x90, 0x24,
        0x96, 0xD3, 0xD4, 0x1A, 0x6F, 0x08, 0xAB, 0x29,
        0x7D, 0xFF, 0x4E, 0x27, 0x6D, 0x39, 0x83, 0x17,
        0x90, 0xA4, 0x07, 0x8A, 0xDE, 0x79, 0x53, 0xF6,
        0x99, 0x2E, 0xA6, 0x39, 0x47, 0xC3, 0xBE, 0x12,
        0xC7, 0xA5, 0x7E, 0xA2, 0x19, 0x57, 0x04, 0x45,
        0xBE, 0x44, 0x62, 0x92, 0xCA, 0x56, 0xE1, 0xF0,
        0x45, 0x3B, 0xA4, 0xF8, 0xF5, 0xCD, 0xC7, 0xD2,
        0xB2, 0x46, 0x57, 0x51, 0x0B, 0x06, 0xDA, 0x54,
        0x03, 0x9E, 0x52, 0xA2, 0x78, 0x69, 0x25, 0x2E,
        0x75, 0x83, 0x25, 0x3F, 0xA3, 0x62, 0x27, 0xB9,
        0xA6, 0x59, 0x7A, 0xB1, 0xB6, 0xE9, 0xC1, 0xDD,
        0x2F, 0x22, 0x2D, 0x3B, 0xA3, 0x22, 0xD6, 0x11,
        0x7B, 0x08, 0x27, 0x92, 0x83, 0x7A, 0x5D, 0x0D,
        0x6B, 0x9D, 0x5B, 0xEB, 0xE9, 0xC0, 0x88, 0xDE,
        0x44, 0x55, 0xBA, 0x69, 0xC1, 0x7A, 0x4D, 0xE6,
        0x35, 0x67, 0x6F, 0x99, 0x9B, 0x07, 0xD8, 0x04,
        0xAA, 0xEA, 0x7D, 0xFF, 0x8E, 0xB8, 0xAA, 0x4C,
        0x79, 0xE2, 0x88, 0xA8, 0x1D, 0xE8, 0xA6, 0x77,
        0xCA, 0x06, 0xC0, 0xDF, 0x0E, 0x2B, 0xCB, 0xFF,
        0x9F, 0x64, 0x67, 0x11, 0xF1, 0xB9, 0x38, 0x83,
        0x19, 0x05, 0x30, 0x9B, 0x01, 0x11, 0x55, 0x03,
        0xAD, 0x44, 0x7D, 0x3C, 0x07, 0xEF, 0x88, 0x19,
        0x92, 0xC0, 0xFE, 0xE1, 0xAB, 0xDB, 0x24, 0x18,
        0x17, 0xD0, 0x03, 0x5C, 0x91, 0xD4, 0xA6, 0x2A,
        0xF1, 0xE9, 0x72, 0x62, 0x58, 0x22, 0x7D, 0x55,
        0x15, 0xE2, 0xA1, 0x70, 0x14, 0x5E, 0x34, 0xB9,
        0x5A, 0xB7, 0x5D, 0x3F, 0xB8, 0xB5, 0x45, 0x44,
        0xD2, 0x50, 0xD1, 0xC6, 0x7E, 0xE7, 0x3D, 0xF4,
        0xD3, 0xEC, 0xFB, 0x97, 0x32, 0x11, 0x72, 0x51,
        0xB7, 0x4A, 0xC8, 0x38, 0x96, 0xFC, 0x6F, 0x69,
        0xC2, 0xD5, 0xD3, 0x28, 0xE9, 0x63, 0x14, 0x14,
        0xFE, 0xB1, 0xA4, 0x02, 0x80, 0x65, 0x73, 0xD3,
        0x57, 0x07, 0x95, 0x21, 0x40, 0x00, 0x77, 0xA7,
        0x6D, 0x44, 0x2B, 0x0D, 0x77, 0x07, 0x92, 0x64,
        0xD4, 0x3A, 0xE2, 0x7F, 0xF2, 0x1C, 0x14, 0x08,
        0x60, 0x74, 0x8F, 0xFC, 0x0B, 0xE8, 0xEC, 0xA9,
        0xB7, 0x97, 0xA7, 0x85, 0x8A, 0xEF, 0xD7, 0x7E,
        0xD5, 0x15, 0xF7, 0x45, 0x8D, 0x9C, 0xBF, 0x23,
        0xEB, 0x8C, 0x4D, 0xD2, 0x28, 0x7E, 0x0A, 0x61,
        0x2E, 0xBA, 0xBE, 0x89, 0x1D, 0x64, 0x45, 0x22,
        0x70, 0x9D, 0x48, 0xEB, 0x2F, 0x96, 0xF1, 0xA7,
        0xDE, 0xD3, 0x28, 0x4C, 0xC9, 0xFB, 0xF2, 0x9C,
        0x5B, 0xFC, 0xBE, 0xBE, 0xF4, 0x38, 0xC9, 0x43,
        0xC3, 0x66, 0x53, 0xA9, 0x06, 0xE5, 0x71, 0x16,
        0xA4, 0xBB, 0x3B, 0x50, 0x53, 0xCF, 0xF4, 0x1F,
        0xD6, 0x00, 0x07, 0x46, 0xFB, 0x97, 0x0B, 0xF9,
        0x3D, 0xF4, 0xC6, 0x60, 0xD0, 0x37, 0x70, 0xC0,
        0x2D, 0xD1, 0x9F, 0xA5, 0x78, 0xF3, 0x1F, 0x03,
        0x81, 0xB1, 0x93, 0xBA, 0xE5, 0x82, 0xE6, 0xD1,
        0x66, 0x93, 0x83, 0x5B, 0xB9, 0xAD, 0xD9, 0x01,
        0xA5, 0xB6, 0x5C, 0x69, 0x82, 0xD7, 0x2F, 0x35,
        0x35, 0x98, 0xEE, 0xE9, 0xA0, 0x74, 0xC1, 0x91,
        0x44, 0x0A, 0x04, 0xCD, 0x97, 0xBE, 0x6B, 0x60,
        0x90, 0x9A, 0x48, 0x7B, 0x83, 0xA2, 0x28, 0x97,
        0xB5, 0xBA, 0xB1, 0x4D, 0x35, 0x8B, 0x34, 0x0A,
        0xA1, 0xCB, 0xA5, 0xC2, 0xA4, 0x6A, 0x36, 0xB3,
        0x12, 0x46, 0x59, 0xDB, 0x63, 0xE5, 0xF9, 0xF1,
        0x7F, 0xAD, 0x42, 0xF4, 0x24, 0xF0, 0x02, 0x3D,
        0x1E, 0x6C, 0xD5, 0xB3, 0x06, 0x8F, 0x1F, 0x59,
        0x79, 0xCC, 0xF9, 0x5B, 0x4F, 0x8B, 0xD6, 0x03,
        0xC7, 0x53, 0xE6, 0xCE, 0xBB, 0xD8, 0x52, 0x89,
        0x70, 0x5D, 0x98, 0x86, 0xA5, 0x9E, 0x44, 0xA9,
        0xC8, 0x17, 0xA2, 0x6F, 0x43, 0x2D, 0x8D, 0xA7,
        0xDE, 0x3E, 0xFA, 0xE7, 0x98, 0x7B, 0xB5, 0xBE,
        0x7B, 0x10, 0xB8, 0xB8, 0xA5, 0x3D, 0x3E, 0xCD,
        0x94, 0x19, 0x5E, 0x06, 0x51, 0xB8, 0x58, 0x1E,
        0x0E, 0xCF, 0xFE, 0xE5, 0xED, 0x84, 0xB5, 0xF5,
        0x0F, 0x34, 0x32, 0xAC, 0x0A, 0x7F, 0x03, 0xF0,
        0xF8, 0xFC, 0x69, 0xA0, 0x26, 0x0D, 0x2E, 0xFA,
        0x62, 0x49, 0x5C, 0xC4, 0xE5, 0xF6, 0x8B, 0xC5,
        0x26, 0x21, 0x23, 0x3B, 0xBD, 0x9A, 0x23, 0x95,
        0x69, 0xA7, 0x48, 0x94, 0x30, 0x1E, 0xC3, 0x82,
        0xB6, 0x75, 0x30, 0xA6, 0xF3, 0x1E, 0xBB, 0xBC,
        0xF7, 0x21, 0x27, 0x12, 0x2C, 0x51, 0x50, 0x55,
        0x87, 0x0D, 0xF1, 0xCC, 0x6C, 0xFF, 0xEA, 0x7E,
        0x2C, 0xDA, 0x8B, 0x9B, 0x20, 0xF4, 0x75, 0xFB,
        0xC2, 0x3F, 0xBE, 0x09, 0xA6, 0xC9, 0x26, 0xE7,
        0xB5, 0xC7, 0xE6, 0xB9, 0x35, 0x8C, 0xAF, 0xFA,
        0xC0, 0x8D, 0x43, 0x33, 0x25, 0xBA, 0xAA, 0xDC,
        0xCF, 0xBC, 0xE4, 0xC4, 0xC6, 0x26, 0x4A, 0x0D,
        0x9D, 0xCC, 0x2A, 0xE0, 0x5B, 0x1E, 0xC9, 0x78,
        0xF8, 0xA2, 0xB5, 0x46, 0xE5, 0x49, 0xB8, 0x4C,
        0xC2, 0x22, 0x40, 0xCE, 0x97, 0x9A, 0x95, 0x40,
        0xF7, 0xD6, 0x52, 0x54, 0x3B, 0xBB, 0x42, 0xC5,
        0x6F, 0x00, 0x7F, 0x83, 0xDD, 0x88, 0x71, 0xF7,
        0xD4, 0x1B, 0x3D, 0x81, 0xC4, 0xB1, 0x49, 0x9B,
        0xF3, 0x68, 0x15, 0xC5, 0x15, 0x97, 0x0F, 0xC5,
        0x43, 0xDD, 0x07, 0xBE, 0x98, 0x43, 0x2C, 0xB3,
        0xEF, 0x08, 0xCA, 0xDC, 0x9C, 0x27, 0x58, 0xFE,
        0x49, 0xE9, 0x77, 0xD9, 0x1C, 0x62, 0xA4, 0xA2,
        0xF9, 0x78, 0xCC, 0xB3, 0x21, 0x06, 0x10, 0xDE,
        0x5A, 0x52, 0xA3, 0x67, 0xBD, 0x5E, 0xBC, 0x9B,
        0x4E, 0x40, 0x87, 0x93, 0xCF, 0x0E, 0x27, 0x0E,
        0xE3, 0x11, 0x4B, 0xB3, 0xE0, 0xCE, 0x24, 0xB6,
        0x0A, 0x53, 0x03, 0xF8, 0x01, 0x6A, 0x7E, 0xFE,
        0xC8, 0x66, 0x9F, 0x29, 0xF3, 0x45, 0x94, 0xD6,
        0x0E, 0x30, 0xB5, 0x61, 0xA9, 0xEC, 0x8F, 0x71,
        0xF7, 0x36, 0xD6, 0x43, 0x4B, 0x0C, 0xCD, 0x45,
        0xBB, 0xA4, 0xBD, 0xE9, 0xA9, 0xC3, 0xC1, 0x95,
        0x1E, 0xF9, 0x42, 0x07, 0x18, 0xEA, 0xF5, 0x0B,
        0x27, 0xB6, 0xDE, 0xEF, 0x67, 0x33, 0x83, 0x0D,
        0xD9, 0x5E, 0x3A, 0x93, 0xD2, 0xD0, 0xDB, 0xB9,
        0x98, 0xF0, 0x25, 0x21, 0xF3, 0xDF, 0x0B, 0x1E
    };
#endif /* !WOLFSSL_NO_ML_DSA_44 */
#ifndef WOLFSSL_NO_ML_DSA_65
    static const byte seed_65_draft[] = {
        0x41, 0xAF, 0x98, 0x7B, 0x02, 0x6E, 0x47, 0x5F,
        0x37, 0x91, 0x7F, 0x2A, 0x6A, 0x9A, 0x87, 0xE7,
        0x51, 0xAD, 0xF9, 0x5B, 0x92, 0x7F, 0x2D, 0xCE,
        0xF0, 0xD4, 0xF3, 0xDA, 0x8F, 0x8C, 0x86, 0x6B
    };
    static const byte pk_65_draft[] = {
        0xDC, 0x38, 0xE5, 0x5F, 0xDF, 0x2E, 0x9D, 0xD4,
        0x34, 0x5C, 0xAE, 0x1A, 0x7D, 0xF4, 0x2E, 0x2E,
        0xBC, 0x58, 0x57, 0x80, 0x55, 0x02, 0xE4, 0x3F,
        0xA5, 0x19, 0x41, 0xE4, 0x44, 0x58, 0x66, 0x41,
        0x39, 0x5D, 0xF9, 0x20, 0x6C, 0x36, 0x0D, 0x4F,
        0x83, 0x43, 0xBE, 0x86, 0xEF, 0x6C, 0x43, 0xD0,
        0x3E, 0xD0, 0x63, 0x0A, 0x5B, 0x92, 0x8D, 0x31,
        0x19, 0x1D, 0xA9, 0x51, 0x61, 0x48, 0xE6, 0x26,
        0x50, 0x07, 0x54, 0x9B, 0xB0, 0xB7, 0x62, 0x54,
        0xDB, 0x80, 0x4E, 0x48, 0x7F, 0x48, 0xC5, 0x11,
        0x91, 0xFC, 0xA9, 0x26, 0x25, 0x08, 0xA5, 0x99,
        0xA0, 0x3C, 0xB9, 0x0C, 0xCF, 0x6C, 0xCD, 0x83,
        0x9A, 0x38, 0x6D, 0x22, 0xDE, 0x0A, 0xC3, 0x8F,
        0xF7, 0xD0, 0x57, 0x40, 0x53, 0xE9, 0xE9, 0x4E,
        0x73, 0xFA, 0x58, 0x40, 0x9F, 0x6D, 0x8A, 0xD3,
        0x6F, 0x86, 0x84, 0x4D, 0x18, 0xD7, 0x4C, 0x76,
        0x39, 0x57, 0x9E, 0xC0, 0xC7, 0xE4, 0xEE, 0x54,
        0xF4, 0xAD, 0x10, 0xC5, 0x69, 0x59, 0xE0, 0xBC,
        0x9B, 0xF4, 0x20, 0x8F, 0xBA, 0x0A, 0x94, 0x10,
        0x55, 0x07, 0x7E, 0xD1, 0xF9, 0x20, 0xCC, 0x2F,
        0xA9, 0xAE, 0x9D, 0xF5, 0xE4, 0x29, 0x40, 0x7E,
        0x44, 0xA4, 0xDF, 0xB2, 0xE9, 0x25, 0xE0, 0xBA,
        0x8D, 0x6C, 0x33, 0x88, 0x9C, 0xEE, 0x27, 0xDB,
        0xC7, 0x0A, 0x6E, 0x5A, 0x08, 0x92, 0x9B, 0x53,
        0xF8, 0xFD, 0xF9, 0x5B, 0xEB, 0x03, 0x8E, 0x45,
        0xCB, 0x91, 0x19, 0x4E, 0x6B, 0x1E, 0xA0, 0xA4,
        0xF0, 0x43, 0xC9, 0x8F, 0xDF, 0x93, 0x5E, 0x86,
        0xB0, 0x09, 0xD3, 0x47, 0x38, 0x7C, 0x8E, 0x78,
        0x85, 0x71, 0x3D, 0x07, 0x2E, 0x2E, 0x12, 0x6F,
        0x06, 0x97, 0x0E, 0x54, 0xAD, 0x71, 0x09, 0xEF,
        0xA5, 0x55, 0x0A, 0x39, 0x86, 0xE6, 0x17, 0x17,
        0x70, 0x9A, 0xA7, 0xA7, 0x1B, 0xCE, 0x78, 0x06,
        0x2C, 0x61, 0x1A, 0xB9, 0x48, 0x22, 0x41, 0x45,
        0x15, 0xEB, 0x10, 0x3C, 0x6E, 0x24, 0x37, 0xA4,
        0xB5, 0xE8, 0x82, 0x4D, 0x6D, 0xCC, 0x44, 0xC6,
        0xB0, 0x5D, 0xBE, 0x46, 0xDA, 0x5F, 0x00, 0x36,
        0x5B, 0xBD, 0x87, 0x65, 0x3A, 0x96, 0x21, 0x58,
        0x45, 0x65, 0xDB, 0xD8, 0x77, 0x76, 0x7B, 0x25,
        0xC3, 0x78, 0x6E, 0xD9, 0x14, 0xA7, 0x19, 0x69,
        0x4F, 0xBB, 0x1B, 0xDB, 0x37, 0xCE, 0xAF, 0x8C,
        0x88, 0x2E, 0x9E, 0x30, 0xF6, 0xAE, 0x43, 0xCC,
        0x59, 0x0F, 0x67, 0x8A, 0xCB, 0x4F, 0x08, 0x20,
        0x6D, 0x99, 0xD7, 0xA9, 0xDE, 0xE5, 0xE5, 0xB3,
        0xFF, 0xAA, 0x45, 0x3C, 0xF1, 0xE3, 0x02, 0x7D,
        0x2F, 0xEE, 0x69, 0x04, 0x81, 0x73, 0x01, 0x37,
        0x51, 0x68, 0xC8, 0x0B, 0x51, 0xFD, 0x05, 0xB4,
        0x05, 0xBB, 0xA1, 0xDB, 0x1D, 0xF6, 0x5F, 0x70,
        0xD3, 0x0A, 0x37, 0x4B, 0x9C, 0xC4, 0x45, 0x30,
        0x11, 0x36, 0xE2, 0x48, 0x9F, 0xC4, 0x2E, 0x4E,
        0x0C, 0x0C, 0xA1, 0x04, 0x41, 0x75, 0x95, 0xAA,
        0xED, 0xAC, 0xD4, 0xB2, 0xE7, 0x85, 0x7E, 0xE1,
        0xA6, 0xFE, 0x2A, 0x09, 0x19, 0x09, 0x3D, 0x7C,
        0x20, 0x1E, 0x98, 0x3D, 0x6E, 0x02, 0xC1, 0xCA,
        0xBB, 0x24, 0x82, 0x9F, 0x45, 0x1D, 0x26, 0x99,
        0xAE, 0x02, 0x82, 0xF9, 0x86, 0x3B, 0x67, 0x8C,
        0xBD, 0xFE, 0xF1, 0xD0, 0xB6, 0xB8, 0xAB, 0x00,
        0x0F, 0xEC, 0x30, 0xDC, 0x27, 0x58, 0xE2, 0x29,
        0x18, 0x05, 0x5A, 0x66, 0xA5, 0x88, 0x39, 0x8E,
        0x49, 0x5B, 0xB9, 0x52, 0x43, 0x84, 0xDC, 0xA9,
        0x50, 0x2B, 0x83, 0x3C, 0x84, 0x81, 0x37, 0x52,
        0x30, 0x79, 0xBD, 0x04, 0xB8, 0xDD, 0x47, 0xC1,
        0x02, 0x2E, 0xEC, 0x24, 0xD0, 0x56, 0x23, 0xE1,
        0x92, 0xD0, 0x65, 0x7F, 0xC7, 0xC2, 0xF7, 0x60,
        0x73, 0xB8, 0xAF, 0x0A, 0xF4, 0xEF, 0xFC, 0x1B,
        0xC2, 0xB9, 0x76, 0x87, 0x8A, 0xA6, 0xC2, 0x3F,
        0xD3, 0x9F, 0x1F, 0x2D, 0x94, 0xBC, 0x89, 0x4E,
        0x31, 0x8D, 0x28, 0xD0, 0x90, 0xB5, 0x5B, 0x60,
        0x30, 0xC6, 0x0B, 0x37, 0x63, 0x5D, 0xDC, 0xC6,
        0xE0, 0x1A, 0xBA, 0x6B, 0x23, 0xCD, 0x2E, 0x09,
        0x2D, 0x6A, 0x7E, 0x0C, 0xD9, 0x4F, 0xB1, 0xE2,
        0x89, 0x67, 0xE7, 0xB1, 0x54, 0x08, 0xB2, 0xFA,
        0x83, 0x43, 0x7C, 0x77, 0x06, 0xED, 0xE2, 0x29,
        0x53, 0xB7, 0x09, 0xC4, 0x1B, 0x81, 0x55, 0x12,
        0x41, 0x8E, 0x8B, 0x03, 0x36, 0xEE, 0x45, 0x70,
        0x57, 0xA8, 0x73, 0xEF, 0x70, 0x7B, 0x1F, 0x63,
        0xB0, 0xE8, 0x00, 0xBD, 0x1E, 0xE6, 0xA9, 0x93,
        0x9D, 0x03, 0x19, 0x22, 0xDF, 0xE1, 0x01, 0xF2,
        0xA9, 0x6B, 0x90, 0x5C, 0xD2, 0xC1, 0xAC, 0x9F,
        0xB2, 0x21, 0x1C, 0x2D, 0xC6, 0x80, 0x9A, 0xB5,
        0x1E, 0x46, 0x95, 0x6C, 0xCE, 0x47, 0x3E, 0x67,
        0xCD, 0xD6, 0xC9, 0xB9, 0x81, 0x74, 0x7F, 0x17,
        0xA3, 0xF7, 0x48, 0x99, 0xF3, 0x36, 0x84, 0xF3,
        0x16, 0x41, 0x55, 0x5F, 0xA7, 0xBF, 0x4B, 0x69,
        0x8D, 0xA3, 0x3D, 0x1E, 0xEA, 0xF5, 0x1E, 0xC6,
        0xB8, 0x1C, 0xD6, 0x89, 0x45, 0x68, 0xFA, 0xE7,
        0xCA, 0x86, 0xE4, 0xB1, 0xC9, 0x9C, 0xB2, 0xAB,
        0x89, 0x03, 0xE7, 0x19, 0x7B, 0xA9, 0xF2, 0x6B,
        0x4A, 0x43, 0x1D, 0x90, 0xAF, 0xA4, 0xE3, 0xBC,
        0xEF, 0xD4, 0x37, 0xC5, 0x55, 0x5C, 0x9E, 0x14,
        0xC6, 0x18, 0xDD, 0x45, 0x3F, 0x80, 0x49, 0x1C,
        0x93, 0xFF, 0xBD, 0xDD, 0x75, 0x54, 0x0B, 0xD1,
        0xA9, 0xF6, 0xBC, 0x89, 0x98, 0x7D, 0x6F, 0x03,
        0x7B, 0x06, 0xD5, 0x40, 0x7D, 0x85, 0x48, 0x2E,
        0x11, 0x3E, 0xF0, 0x47, 0x77, 0xD0, 0xBA, 0x03,
        0x33, 0x58, 0xC4, 0x8F, 0x76, 0xF8, 0x72, 0x47,
        0x04, 0x21, 0x5E, 0x85, 0x5A, 0x0F, 0x35, 0x77,
        0xFB, 0x96, 0x29, 0x81, 0x2D, 0x55, 0x6E, 0x53,
        0xC6, 0x13, 0x1E, 0xFA, 0x4D, 0xCE, 0xA9, 0x36,
        0x1D, 0x8F, 0xAB, 0xAC, 0x13, 0x19, 0x94, 0xFC,
        0x4B, 0xCD, 0x36, 0x4C, 0x6E, 0x21, 0xAE, 0xF1,
        0x13, 0xA4, 0xF7, 0x64, 0x8E, 0xE1, 0xAF, 0x50,
        0x6A, 0x63, 0x0E, 0xCA, 0x2F, 0xE9, 0x0C, 0x8A,
        0xE7, 0xF2, 0xE3, 0x68, 0x03, 0xE0, 0x40, 0x1C,
        0x64, 0xAB, 0xC3, 0xEC, 0xC0, 0x92, 0xE9, 0x57,
        0x3E, 0x66, 0x72, 0x36, 0x39, 0x22, 0x4E, 0xCD,
        0x13, 0x08, 0xBA, 0xF8, 0x2B, 0xA1, 0xF2, 0x69,
        0x44, 0x7E, 0x90, 0x5C, 0xC8, 0xEC, 0xB6, 0xBE,
        0x8C, 0x30, 0xE0, 0x69, 0xB7, 0x97, 0xA1, 0x1C,
        0x18, 0xE5, 0x54, 0x62, 0xC3, 0x29, 0x99, 0x21,
        0x16, 0xD9, 0x78, 0x1C, 0x4C, 0x9C, 0x88, 0x4C,
        0xA5, 0xE1, 0x11, 0x66, 0x5B, 0x6E, 0x71, 0xE7,
        0xE2, 0xE7, 0xE4, 0x02, 0xDD, 0x1A, 0x8D, 0x0C,
        0xF5, 0x32, 0xFD, 0x41, 0x28, 0x35, 0x75, 0xD0,
        0x0C, 0x5F, 0x06, 0x6A, 0x5A, 0x61, 0x49, 0x59,
        0xC1, 0x0C, 0xD4, 0x9E, 0xD6, 0x29, 0xE2, 0x37,
        0xDF, 0x2B, 0x3D, 0xE8, 0x98, 0xB9, 0xDF, 0x8E,
        0xA0, 0xC4, 0xE2, 0xFC, 0x45, 0x70, 0xE8, 0x1B,
        0xF4, 0xFA, 0xC5, 0xE6, 0xA7, 0xCF, 0x4F, 0xA2,
        0xDA, 0x3D, 0x90, 0x49, 0x24, 0x8F, 0x61, 0x54,
        0xD5, 0x50, 0x8E, 0xE8, 0x0C, 0x14, 0xAD, 0x6F,
        0x65, 0x88, 0x3A, 0xF6, 0x92, 0xDB, 0x35, 0x5D,
        0xFF, 0x21, 0x20, 0xAC, 0x01, 0x16, 0x0B, 0xEC,
        0x84, 0x15, 0x3B, 0xA9, 0x93, 0x92, 0x75, 0xB3,
        0x73, 0xF1, 0x23, 0x69, 0x94, 0x10, 0xF5, 0xFE,
        0x20, 0xA8, 0xAF, 0x05, 0x87, 0x49, 0x4E, 0x9C,
        0xEB, 0x21, 0x0A, 0xCF, 0x0B, 0xA1, 0x65, 0x38,
        0xA6, 0x18, 0x4D, 0xF7, 0xD8, 0xC1, 0x2C, 0x14,
        0x4C, 0xD9, 0x40, 0xC2, 0xF7, 0xBF, 0xE3, 0x07,
        0x79, 0x55, 0xAE, 0xB9, 0xB6, 0x50, 0x06, 0x92,
        0x94, 0x8C, 0x6A, 0x0E, 0x22, 0x14, 0xE2, 0xCC,
        0x65, 0xBA, 0x0C, 0x4D, 0xB6, 0x5C, 0x4A, 0xE9,
        0x0A, 0x08, 0x0C, 0xF9, 0x26, 0xA2, 0x51, 0x85,
        0x36, 0xE2, 0xC1, 0xF1, 0x0A, 0x66, 0x51, 0x66,
        0x7A, 0x98, 0x9B, 0x2C, 0x30, 0x1A, 0x0D, 0x49,
        0x3C, 0x1E, 0xEC, 0x63, 0x53, 0x5E, 0xD9, 0xDD,
        0x84, 0x69, 0xCD, 0x7E, 0x79, 0x58, 0x3D, 0x6E,
        0xD9, 0x98, 0x58, 0xD8, 0x0A, 0x48, 0xB5, 0x13,
        0x3F, 0x72, 0x4C, 0x11, 0x90, 0x15, 0x12, 0x74,
        0xFF, 0x5C, 0x0D, 0xC6, 0x20, 0x8C, 0xC1, 0x99,
        0xCA, 0x8E, 0xFC, 0xA2, 0xE8, 0xB8, 0xEE, 0xAA,
        0x27, 0xC2, 0x97, 0x8D, 0xFA, 0xBE, 0xE0, 0x43,
        0x99, 0xB6, 0x90, 0x60, 0x00, 0x7C, 0x33, 0xD4,
        0x87, 0x71, 0x7B, 0x56, 0x6C, 0xAA, 0xE0, 0xAC,
        0x9D, 0x7E, 0x7E, 0xA3, 0xCF, 0xBB, 0xB3, 0xA0,
        0x5F, 0xD4, 0xC4, 0x3A, 0xA7, 0xB9, 0x0C, 0xCE,
        0xF3, 0x05, 0x09, 0x91, 0xA7, 0xE9, 0x11, 0x55,
        0x32, 0x45, 0xA6, 0x08, 0x0E, 0x10, 0x37, 0x91,
        0xF3, 0xBF, 0xED, 0x64, 0x26, 0xEB, 0x39, 0xC2,
        0x57, 0xAE, 0x64, 0x79, 0x33, 0x7C, 0x51, 0xB2,
        0xC8, 0x85, 0xE0, 0xF9, 0x6D, 0x10, 0x52, 0x9F,
        0x72, 0xF4, 0xD1, 0x5B, 0x54, 0x5B, 0x93, 0x28,
        0x36, 0xA8, 0xCD, 0xB3, 0x30, 0x5B, 0x7A, 0xB0,
        0xB6, 0xF0, 0xD8, 0xA0, 0xBA, 0x24, 0x59, 0x5F,
        0x43, 0x02, 0x01, 0x57, 0x91, 0x7B, 0x94, 0x07,
        0x63, 0x23, 0x12, 0x94, 0xFB, 0x9F, 0xF2, 0xC1,
        0xD6, 0x80, 0x8F, 0x4E, 0xA7, 0x9E, 0x11, 0xD8,
        0xB3, 0x08, 0xB6, 0x3B, 0x3B, 0xF2, 0xEE, 0x14,
        0xA5, 0xDB, 0xB0, 0xBB, 0x17, 0xA5, 0x96, 0x3C,
        0x2F, 0xB9, 0xE7, 0x4A, 0xD7, 0x52, 0x34, 0x98,
        0xCB, 0x0C, 0xEB, 0x42, 0x5B, 0x2D, 0x2D, 0x2B,
        0x0D, 0x94, 0x66, 0xD3, 0xAD, 0x08, 0x0A, 0x28,
        0xF6, 0x0E, 0xDA, 0xD4, 0x54, 0xFD, 0xC6, 0x48,
        0x08, 0xA1, 0x8D, 0xB0, 0x30, 0xFD, 0x18, 0xB1,
        0x50, 0xB1, 0xFD, 0xE0, 0x6E, 0x33, 0x25, 0x0D,
        0x90, 0xB1, 0xC1, 0xE7, 0x88, 0x74, 0x87, 0x05,
        0xE7, 0xBE, 0xBD, 0xAA, 0x8C, 0x6D, 0xC2, 0x3D,
        0x6F, 0x95, 0x84, 0xFA, 0x03, 0x74, 0x85, 0xE1,
        0xED, 0xE5, 0xF4, 0xE8, 0x26, 0x4A, 0x0B, 0x20,
        0x87, 0xB6, 0xE1, 0x10, 0x75, 0x6D, 0x9F, 0x95,
        0x39, 0x4C, 0x0F, 0x50, 0x1B, 0xA8, 0x69, 0x82,
        0xBB, 0xE2, 0xD6, 0x11, 0xD7, 0xBE, 0xFB, 0x4F,
        0x60, 0xD3, 0x16, 0xC6, 0x04, 0x3A, 0x5A, 0xF5,
        0x78, 0x9B, 0x0B, 0x21, 0xA1, 0x00, 0x96, 0xCD,
        0x63, 0x78, 0x1D, 0x2D, 0x4F, 0x6E, 0x50, 0xEE,
        0x62, 0x2D, 0x88, 0x62, 0x01, 0xF6, 0xB4, 0x17,
        0x4F, 0x8C, 0xAD, 0xCB, 0x4B, 0xF9, 0xF6, 0x9D,
        0xC7, 0xD8, 0xCC, 0xBF, 0x96, 0x1B, 0x1B, 0x79,
        0xF3, 0x25, 0x85, 0x23, 0x10, 0x63, 0x30, 0x8D,
        0xA8, 0x3A, 0x4B, 0x92, 0x1B, 0x88, 0x53, 0x24,
        0x2D, 0x29, 0xA5, 0x2E, 0x7A, 0xD5, 0x58, 0xEB,
        0x1B, 0x1C, 0xE6, 0xB8, 0x94, 0x0C, 0x58, 0x96,
        0x5B, 0xA0, 0x2C, 0xBF, 0xE2, 0x99, 0xA0, 0x1F,
        0x0C, 0xCC, 0xBD, 0x83, 0x72, 0x56, 0xBB, 0x13,
        0x61, 0x5A, 0xC2, 0x04, 0x27, 0x29, 0x1F, 0xD4,
        0xE4, 0x3D, 0x8A, 0x87, 0xE3, 0x81, 0x91, 0x07,
        0xD3, 0x9B, 0xBC, 0xA9, 0xB3, 0xBA, 0xF5, 0x8B,
        0x6A, 0xAD, 0xDE, 0xB0, 0x54, 0x3E, 0xFE, 0xCC,
        0xD3, 0xCB, 0x2C, 0x69, 0xF0, 0x58, 0xD7, 0xEF,
        0xA9, 0xC0, 0x15, 0x9B, 0x5A, 0xDF, 0x71, 0x25,
        0x38, 0x44, 0xEC, 0xA9, 0x18, 0x47, 0x41, 0xCE,
        0x3D, 0x53, 0x10, 0x12, 0xC3, 0x1B, 0x59, 0x9A,
        0x93, 0xA1, 0xEA, 0xBE, 0x3E, 0xBA, 0x74, 0xF6,
        0x2D, 0x40, 0x9D, 0xCB, 0x9E, 0xA1, 0xA5, 0x85,
        0xFF, 0xDC, 0xC5, 0x60, 0x6F, 0x61, 0xE8, 0x17,
        0x6C, 0x36, 0x9F, 0x7A, 0x48, 0x47, 0xDD, 0xF1,
        0xF4, 0x43, 0x21, 0xCB, 0xB3, 0x55, 0x86, 0xD0,
        0xE9, 0x46, 0x7D, 0xB5, 0x3D, 0x90, 0x34, 0x1E,
        0xBB, 0x40, 0xD3, 0x2A, 0xEB, 0xE6, 0x4C, 0x46,
        0x42, 0xA2, 0x8A, 0xBF, 0x90, 0xE7, 0x4B, 0x6D,
        0x5C, 0x94, 0x97, 0xD2, 0xF0, 0x97, 0x74, 0x4C,
        0x76, 0x03, 0xAC, 0x3D, 0xDE, 0x15, 0x96, 0x0C,
        0xEF, 0x18, 0x9D, 0xBD, 0x1A, 0x20, 0x35, 0x7E,
        0x2A, 0x70, 0x9D, 0xEA, 0x2E, 0x11, 0xDF, 0xF3,
        0x2F, 0xFE, 0x23, 0xA9, 0xB6, 0xCF, 0xB7, 0xB9,
        0x3F, 0x4F, 0x30, 0x6B, 0x3B, 0x0D, 0x3B, 0xED,
        0xCD, 0x77, 0xD4, 0xBF, 0xEE, 0xDD, 0xB6, 0x56,
        0x24, 0xD4, 0x29, 0x83, 0xDE, 0xDB, 0xC1, 0xFB,
        0x6A, 0xCE, 0x7F, 0x47, 0xD2, 0xC5, 0xF1, 0x78,
        0x5C, 0x2C, 0x5A, 0x28, 0x3E, 0x05, 0x50, 0x2E,
        0xD9, 0xAE, 0x9B, 0x95, 0x64, 0xC7, 0xD2, 0x7B,
        0xCB, 0xC5, 0x91, 0x80, 0xEB, 0x79, 0xC7, 0xCC,
        0xA8, 0x06, 0xC8, 0xF9, 0xDF, 0x2A, 0x49, 0x4A,
        0xF8, 0xFE, 0xBA, 0xA5, 0x85, 0x67, 0x1B, 0xDA,
        0x51, 0x3B, 0xC2, 0x04, 0xA6, 0xA3, 0xFF, 0x99,
        0x21, 0xE8, 0x17, 0x91, 0x33, 0x9B, 0x83, 0x75,
        0x20, 0x5E, 0x95, 0xBE, 0x49, 0xDF, 0x53, 0xFC,
        0x05, 0xA2, 0x3C, 0xAA, 0x5A, 0x22, 0x15, 0xA5,
        0x56, 0xE0, 0x51, 0x30, 0x4E, 0x32, 0x14, 0xF2,
        0x9F, 0x03, 0x51, 0x8E, 0xDD, 0x8B, 0x39, 0x19,
        0x1E, 0x39, 0xC5, 0xA7, 0x1C, 0xC6, 0xA4, 0xE1,
        0x77, 0xCA, 0x8C, 0x9D, 0x27, 0xBC, 0xCC, 0x16,
        0xD6, 0xFC, 0x59, 0x10, 0x23, 0xFF, 0x64, 0x90,
        0x9C, 0x23, 0x5A, 0xFF, 0x7E, 0x27, 0x1B, 0xC7,
        0x7F, 0x21, 0x3B, 0x41, 0xDB, 0xBC, 0x96, 0x60,
        0x0B, 0x35, 0xA1, 0xF3, 0xF8, 0x51, 0x0A, 0x65,
        0xCF, 0xDF, 0x7A, 0xB8, 0x04, 0x56, 0x49, 0xD7,
        0xD3, 0xC5, 0x0B, 0x4A, 0x1F, 0x60, 0xE1, 0x86,
        0x36, 0x53, 0x8E, 0x6C, 0x3E, 0xAF, 0x5B, 0xC1,
        0xCA, 0xCB, 0x22, 0x1A, 0x07, 0xDA, 0x54, 0xEC,
        0xAA, 0x06, 0x72, 0x17, 0xCF, 0x80, 0xC4, 0x89,
        0x56, 0x24, 0x1B, 0xD4, 0xFF, 0x50, 0x6B, 0x51,
        0x55, 0x4D, 0x6E, 0x79, 0x7E, 0xEC, 0x61, 0xC6,
        0xE4, 0x21, 0xC8, 0x0E, 0x10, 0x3F, 0x8C, 0x85,
        0x3A, 0x27, 0xEA, 0x91, 0x07, 0xCB, 0x37, 0x18,
        0x14, 0xB5, 0x63, 0x6E, 0x00, 0xBC, 0x0F, 0x36,
        0xF9, 0x54, 0x75, 0xE7, 0x0B, 0xDC, 0xE7, 0xA0,
        0x59, 0xF0, 0x64, 0xFB, 0x73, 0x07, 0x0E, 0xFE,
        0x57, 0x7F, 0x0D, 0x12, 0xBC, 0xB0, 0xBF, 0xA2,
        0x3A, 0x18, 0x08, 0x7E, 0xD5, 0x6C, 0xF0, 0x6F,
        0xF8, 0x98, 0xFB, 0xA5, 0x10, 0x7B, 0x10, 0x5F,
        0x6B, 0xC8, 0x6D, 0xDE, 0x2F, 0x1F, 0xE0, 0xC8,
        0x19, 0xEE, 0xC2, 0x03, 0x39, 0x49, 0x70, 0x3E,
        0x36, 0xE3, 0x3C, 0x70, 0xE3, 0xEA, 0xAC, 0x34,
        0x32, 0xB7, 0x0D, 0xBA, 0x7C, 0xAB, 0xE6, 0x18
    };
    static const byte sk_65_draft[] = {
        0xDC, 0x38, 0xE5, 0x5F, 0xDF, 0x2E, 0x9D, 0xD4,
        0x34, 0x5C, 0xAE, 0x1A, 0x7D, 0xF4, 0x2E, 0x2E,
        0xBC, 0x58, 0x57, 0x80, 0x55, 0x02, 0xE4, 0x3F,
        0xA5, 0x19, 0x41, 0xE4, 0x44, 0x58, 0x66, 0x41,
        0x52, 0x8D, 0xA0, 0xC7, 0xD2, 0x80, 0xDD, 0x49,
        0x0D, 0x5E, 0xB7, 0x65, 0xDB, 0x32, 0x33, 0x15,
        0x0F, 0x9E, 0xC8, 0xEB, 0xC9, 0x6E, 0xE8, 0xE8,
        0x5C, 0xBD, 0x18, 0x4F, 0xDC, 0xF8, 0xA8, 0xD9,
        0xC5, 0x33, 0x84, 0x79, 0x5A, 0x5E, 0xB7, 0x3C,
        0x6D, 0x82, 0xCA, 0xB9, 0xBA, 0x94, 0xB6, 0x46,
        0xAE, 0x3A, 0xD9, 0x19, 0x6C, 0xB4, 0xDA, 0xE2,
        0xF1, 0x4B, 0xB6, 0x43, 0xF0, 0x24, 0x08, 0xE5,
        0xF7, 0x9A, 0x41, 0xF1, 0x15, 0x9C, 0xA8, 0x08,
        0x79, 0x9F, 0xB8, 0x26, 0xD4, 0x08, 0x32, 0x47,
        0xC8, 0xF0, 0xD5, 0x31, 0xA1, 0xC1, 0x19, 0x04,
        0x02, 0x06, 0x2B, 0x4D, 0x46, 0xAE, 0x43, 0x6A,
        0x25, 0x82, 0x75, 0x41, 0x70, 0x36, 0x42, 0x48,
        0x78, 0x06, 0x36, 0x50, 0x23, 0x84, 0x68, 0x10,
        0x87, 0x08, 0x62, 0x00, 0x08, 0x34, 0x20, 0x73,
        0x32, 0x13, 0x36, 0x61, 0x87, 0x61, 0x43, 0x50,
        0x30, 0x02, 0x26, 0x07, 0x65, 0x45, 0x32, 0x00,
        0x25, 0x75, 0x01, 0x04, 0x88, 0x81, 0x58, 0x64,
        0x52, 0x40, 0x84, 0x22, 0x88, 0x42, 0x82, 0x56,
        0x47, 0x50, 0x05, 0x21, 0x88, 0x25, 0x32, 0x25,
        0x12, 0x85, 0x14, 0x52, 0x87, 0x77, 0x67, 0x18,
        0x46, 0x54, 0x63, 0x07, 0x88, 0x67, 0x37, 0x26,
        0x72, 0x62, 0x41, 0x02, 0x00, 0x01, 0x17, 0x84,
        0x33, 0x64, 0x32, 0x57, 0x06, 0x20, 0x05, 0x44,
        0x88, 0x57, 0x33, 0x45, 0x70, 0x55, 0x14, 0x43,
        0x12, 0x54, 0x04, 0x38, 0x37, 0x08, 0x42, 0x57,
        0x36, 0x05, 0x30, 0x03, 0x86, 0x53, 0x02, 0x53,
        0x75, 0x22, 0x62, 0x13, 0x38, 0x82, 0x48, 0x30,
        0x83, 0x83, 0x64, 0x83, 0x13, 0x74, 0x57, 0x32,
        0x46, 0x70, 0x06, 0x05, 0x82, 0x52, 0x73, 0x55,
        0x25, 0x77, 0x21, 0x78, 0x57, 0x83, 0x66, 0x20,
        0x38, 0x53, 0x21, 0x41, 0x77, 0x56, 0x77, 0x46,
        0x34, 0x42, 0x58, 0x31, 0x08, 0x06, 0x03, 0x62,
        0x20, 0x35, 0x11, 0x42, 0x35, 0x38, 0x63, 0x86,
        0x64, 0x13, 0x13, 0x75, 0x40, 0x01, 0x53, 0x74,
        0x41, 0x31, 0x56, 0x64, 0x38, 0x17, 0x14, 0x16,
        0x62, 0x33, 0x22, 0x12, 0x64, 0x40, 0x67, 0x11,
        0x62, 0x42, 0x25, 0x60, 0x38, 0x05, 0x83, 0x13,
        0x51, 0x00, 0x28, 0x36, 0x62, 0x56, 0x41, 0x43,
        0x58, 0x37, 0x51, 0x22, 0x70, 0x25, 0x82, 0x82,
        0x35, 0x24, 0x06, 0x83, 0x48, 0x58, 0x81, 0x78,
        0x07, 0x86, 0x23, 0x15, 0x75, 0x32, 0x46, 0x75,
        0x35, 0x40, 0x08, 0x43, 0x10, 0x66, 0x74, 0x05,
        0x13, 0x72, 0x74, 0x08, 0x83, 0x41, 0x81, 0x08,
        0x75, 0x87, 0x83, 0x28, 0x56, 0x66, 0x20, 0x01,
        0x18, 0x83, 0x57, 0x22, 0x14, 0x64, 0x18, 0x05,
        0x27, 0x75, 0x22, 0x84, 0x12, 0x38, 0x87, 0x52,
        0x32, 0x25, 0x28, 0x08, 0x14, 0x41, 0x81, 0x14,
        0x03, 0x24, 0x54, 0x23, 0x04, 0x81, 0x40, 0x36,
        0x38, 0x38, 0x64, 0x42, 0x46, 0x36, 0x68, 0x11,
        0x55, 0x00, 0x11, 0x25, 0x76, 0x16, 0x43, 0x07,
        0x23, 0x03, 0x34, 0x10, 0x46, 0x41, 0x14, 0x02,
        0x26, 0x10, 0x74, 0x38, 0x38, 0x72, 0x07, 0x87,
        0x54, 0x11, 0x12, 0x83, 0x75, 0x05, 0x82, 0x17,
        0x45, 0x20, 0x38, 0x41, 0x37, 0x20, 0x00, 0x08,
        0x32, 0x18, 0x16, 0x25, 0x58, 0x85, 0x16, 0x88,
        0x71, 0x82, 0x45, 0x60, 0x33, 0x11, 0x13, 0x42,
        0x43, 0x37, 0x68, 0x11, 0x16, 0x54, 0x04, 0x08,
        0x52, 0x78, 0x13, 0x56, 0x83, 0x52, 0x15, 0x24,
        0x03, 0x61, 0x78, 0x44, 0x13, 0x70, 0x67, 0x36,
        0x74, 0x86, 0x52, 0x50, 0x15, 0x41, 0x88, 0x74,
        0x53, 0x00, 0x05, 0x18, 0x65, 0x62, 0x14, 0x84,
        0x12, 0x32, 0x01, 0x88, 0x40, 0x42, 0x34, 0x05,
        0x32, 0x80, 0x72, 0x55, 0x20, 0x68, 0x16, 0x43,
        0x14, 0x15, 0x15, 0x38, 0x43, 0x85, 0x27, 0x60,
        0x70, 0x18, 0x27, 0x35, 0x53, 0x01, 0x28, 0x73,
        0x27, 0x84, 0x10, 0x53, 0x67, 0x10, 0x45, 0x40,
        0x81, 0x52, 0x86, 0x06, 0x11, 0x18, 0x04, 0x31,
        0x57, 0x25, 0x22, 0x44, 0x47, 0x81, 0x45, 0x44,
        0x55, 0x04, 0x72, 0x57, 0x06, 0x46, 0x76, 0x23,
        0x38, 0x85, 0x65, 0x30, 0x08, 0x48, 0x20, 0x13,
        0x22, 0x77, 0x44, 0x60, 0x43, 0x14, 0x15, 0x27,
        0x86, 0x22, 0x37, 0x37, 0x27, 0x04, 0x27, 0x50,
        0x74, 0x31, 0x10, 0x82, 0x00, 0x75, 0x80, 0x44,
        0x38, 0x10, 0x58, 0x40, 0x86, 0x60, 0x63, 0x13,
        0x65, 0x18, 0x33, 0x70, 0x57, 0x68, 0x05, 0x10,
        0x81, 0x03, 0x42, 0x05, 0x25, 0x65, 0x33, 0x57,
        0x38, 0x05, 0x65, 0x34, 0x46, 0x53, 0x68, 0x11,
        0x75, 0x10, 0x04, 0x54, 0x18, 0x47, 0x52, 0x24,
        0x63, 0x23, 0x74, 0x45, 0x11, 0x34, 0x68, 0x32,
        0x35, 0x38, 0x52, 0x85, 0x28, 0x08, 0x71, 0x78,
        0x37, 0x38, 0x27, 0x10, 0x80, 0x54, 0x26, 0x33,
        0x31, 0x82, 0x44, 0x88, 0x33, 0x24, 0x62, 0x86,
        0x32, 0x82, 0x73, 0x31, 0x28, 0x14, 0x73, 0x87,
        0x06, 0x35, 0x80, 0x36, 0x67, 0x02, 0x33, 0x75,
        0x27, 0x36, 0x38, 0x16, 0x35, 0x70, 0x52, 0x16,
        0x87, 0x58, 0x85, 0x17, 0x22, 0x13, 0x54, 0x85,
        0x07, 0x53, 0x31, 0x26, 0x78, 0x01, 0x85, 0x18,
        0x08, 0x68, 0x38, 0x52, 0x11, 0x73, 0x32, 0x25,
        0x58, 0x82, 0x70, 0x70, 0x36, 0x30, 0x50, 0x38,
        0x65, 0x12, 0x78, 0x31, 0x77, 0x72, 0x18, 0x41,
        0x05, 0x42, 0x32, 0x26, 0x26, 0x50, 0x52, 0x86,
        0x15, 0x76, 0x28, 0x66, 0x88, 0x03, 0x78, 0x28,
        0x70, 0x33, 0x36, 0x27, 0x16, 0x61, 0x43, 0x56,
        0x62, 0x81, 0x85, 0x75, 0x47, 0x60, 0x63, 0x38,
        0x66, 0x81, 0x51, 0x78, 0x03, 0x42, 0x60, 0x38,
        0x01, 0x24, 0x73, 0x63, 0x81, 0x12, 0x01, 0x27,
        0x63, 0x13, 0x11, 0x78, 0x36, 0x37, 0x15, 0x03,
        0x84, 0x58, 0x17, 0x25, 0x67, 0x87, 0x57, 0x83,
        0x71, 0x85, 0x37, 0x53, 0x86, 0x22, 0x33, 0x28,
        0x77, 0x30, 0x18, 0x15, 0x01, 0x37, 0x85, 0x40,
        0x15, 0x38, 0x51, 0x33, 0x17, 0x42, 0x64, 0x04,
        0x56, 0x27, 0x50, 0x45, 0x11, 0x27, 0x20, 0x17,
        0x76, 0x55, 0x33, 0x37, 0x58, 0x88, 0x88, 0x45,
        0x16, 0x55, 0x08, 0x53, 0x52, 0x48, 0x72, 0x85,
        0x30, 0x15, 0x23, 0x44, 0x22, 0x02, 0x43, 0x45,
        0x41, 0x10, 0x00, 0x52, 0x32, 0x73, 0x05, 0x75,
        0x72, 0x16, 0x08, 0x11, 0x51, 0x36, 0x20, 0x04,
        0x76, 0x48, 0x78, 0x56, 0x60, 0x88, 0x07, 0x47,
        0x70, 0x20, 0x46, 0x40, 0x43, 0x26, 0x04, 0x37,
        0x17, 0x51, 0x58, 0x46, 0x72, 0x44, 0x50, 0x23,
        0x67, 0x63, 0x60, 0x84, 0x30, 0x51, 0x52, 0x53,
        0x21, 0x74, 0x85, 0x45, 0x74, 0x43, 0x11, 0x72,
        0x52, 0x65, 0x76, 0x08, 0x78, 0x63, 0x14, 0x27,
        0x41, 0x34, 0x67, 0x07, 0x45, 0x15, 0x10, 0x83,
        0x24, 0x02, 0x80, 0x53, 0x07, 0x21, 0x58, 0x10,
        0x34, 0x20, 0x54, 0x12, 0x58, 0x44, 0x25, 0x53,
        0x33, 0x46, 0x02, 0x38, 0x60, 0x17, 0x70, 0x64,
        0x18, 0x52, 0x62, 0x26, 0x65, 0x61, 0x42, 0x31,
        0x22, 0x57, 0x34, 0x57, 0x02, 0x34, 0x62, 0x76,
        0x74, 0x38, 0x73, 0x21, 0x68, 0x71, 0x07, 0x21,
        0x61, 0x05, 0x20, 0x20, 0x86, 0x83, 0x30, 0x25,
        0x50, 0x50, 0x83, 0x30, 0x31, 0x56, 0x30, 0x31,
        0x76, 0x04, 0x54, 0x80, 0x75, 0x18, 0x82, 0x23,
        0x61, 0x87, 0x58, 0x25, 0x13, 0x63, 0x21, 0x51,
        0x48, 0x02, 0x67, 0x37, 0x12, 0x88, 0x70, 0x60,
        0x07, 0x36, 0x18, 0x15, 0x87, 0x74, 0x55, 0x60,
        0x00, 0x54, 0x37, 0x11, 0x01, 0x37, 0x14, 0x17,
        0x11, 0x72, 0x14, 0x55, 0x31, 0x75, 0x77, 0x48,
        0x10, 0x23, 0x83, 0x20, 0x00, 0x04, 0x32, 0x64,
        0x66, 0x61, 0x71, 0x31, 0x03, 0x15, 0x44, 0x32,
        0x57, 0x25, 0x64, 0x31, 0x28, 0x15, 0x33, 0x67,
        0x86, 0x87, 0x37, 0x03, 0x12, 0x78, 0x86, 0x13,
        0x47, 0x80, 0x61, 0x42, 0x50, 0x40, 0x23, 0x37,
        0x01, 0x01, 0x66, 0x24, 0x06, 0x57, 0x82, 0x02,
        0x22, 0x42, 0x41, 0x02, 0x26, 0x06, 0x41, 0x35,
        0x64, 0x16, 0x44, 0x42, 0x38, 0x30, 0x86, 0x88,
        0x47, 0x71, 0x62, 0x33, 0x24, 0x02, 0x12, 0x37,
        0x42, 0x33, 0x20, 0x81, 0x80, 0x53, 0x07, 0x65,
        0x71, 0x27, 0x13, 0x53, 0x15, 0x43, 0x76, 0x38,
        0x71, 0x30, 0x07, 0x87, 0x25, 0x63, 0x03, 0x33,
        0x70, 0x56, 0x18, 0x13, 0x83, 0x51, 0x44, 0x40,
        0x04, 0x80, 0x62, 0x24, 0x20, 0x64, 0x54, 0x40,
        0x20, 0x73, 0x61, 0x45, 0x01, 0x24, 0x47, 0x78,
        0x23, 0x34, 0x56, 0x10, 0x25, 0x32, 0x02, 0x70,
        0x08, 0x02, 0x23, 0x24, 0x80, 0x43, 0x04, 0x02,
        0x81, 0x11, 0x23, 0x82, 0x03, 0x61, 0x30, 0x33,
        0x15, 0x36, 0x25, 0x32, 0x14, 0x73, 0x22, 0x46,
        0x81, 0x25, 0x16, 0x13, 0x52, 0x58, 0x71, 0x61,
        0x67, 0x08, 0x38, 0x76, 0x71, 0x15, 0x88, 0x47,
        0x31, 0x25, 0x27, 0x18, 0x31, 0x50, 0x40, 0x71,
        0x06, 0x87, 0x37, 0x30, 0x85, 0x64, 0x62, 0x78,
        0x32, 0x74, 0x18, 0x83, 0x67, 0x40, 0x37, 0x44,
        0x56, 0x02, 0x72, 0x61, 0x27, 0x28, 0x38, 0x38,
        0x67, 0x17, 0x58, 0x04, 0x61, 0x28, 0x67, 0x37,
        0x46, 0x50, 0x38, 0x15, 0x45, 0x12, 0x71, 0x44,
        0x22, 0x02, 0x34, 0x83, 0x40, 0x70, 0x55, 0x75,
        0x54, 0x26, 0x88, 0x07, 0x25, 0x58, 0x73, 0x60,
        0x58, 0x61, 0x45, 0x63, 0x35, 0x05, 0x48, 0x63,
        0x48, 0x57, 0x03, 0x31, 0x28, 0x14, 0x05, 0x01,
        0x57, 0x34, 0x64, 0x50, 0x23, 0x86, 0x75, 0x85,
        0x18, 0x75, 0x56, 0x88, 0x08, 0x26, 0x01, 0x34,
        0x01, 0x57, 0x05, 0x28, 0x35, 0x48, 0x17, 0x57,
        0x71, 0x81, 0x41, 0x33, 0x77, 0x86, 0x07, 0x77,
        0x02, 0x25, 0x71, 0x74, 0x37, 0x31, 0x20, 0x14,
        0x32, 0x54, 0x20, 0x35, 0x54, 0x76, 0x83, 0x15,
        0x80, 0x73, 0x27, 0x23, 0x00, 0x58, 0x22, 0x84,
        0x64, 0x56, 0x14, 0x84, 0x38, 0x34, 0x16, 0x21,
        0x77, 0x07, 0x34, 0x81, 0x66, 0x87, 0x40, 0x11,
        0x62, 0x46, 0x45, 0x01, 0x20, 0x53, 0x21, 0x73,
        0x07, 0x76, 0x44, 0x15, 0x61, 0x50, 0x83, 0x48,
        0x58, 0x58, 0x45, 0x33, 0x25, 0x36, 0x07, 0x42,
        0x70, 0x24, 0x07, 0x41, 0x08, 0x35, 0x00, 0x78,
        0x41, 0x47, 0x02, 0x56, 0x07, 0x14, 0x68, 0x33,
        0x55, 0x77, 0x32, 0x40, 0x55, 0x24, 0x50, 0x26,
        0x47, 0x12, 0x65, 0x58, 0x43, 0x05, 0x52, 0x55,
        0x75, 0x50, 0x18, 0x46, 0x65, 0x48, 0x03, 0x32,
        0x85, 0x31, 0x16, 0x52, 0x71, 0x57, 0x87, 0x46,
        0x76, 0x14, 0x42, 0x81, 0x28, 0x74, 0x60, 0x34,
        0x35, 0x55, 0x52, 0x16, 0x58, 0x48, 0x61, 0x75,
        0x80, 0x88, 0x15, 0x32, 0x72, 0x26, 0x31, 0x03,
        0x05, 0x03, 0x16, 0x04, 0x07, 0x37, 0x37, 0x73,
        0x43, 0x81, 0x57, 0x31, 0x88, 0x04, 0x72, 0x76,
        0x01, 0x61, 0x81, 0x17, 0x37, 0x65, 0x44, 0x38,
        0x61, 0x23, 0x16, 0x26, 0x52, 0x45, 0x00, 0x73,
        0x83, 0x63, 0x64, 0x62, 0x26, 0x74, 0x60, 0x11,
        0x81, 0x08, 0x06, 0x30, 0x36, 0x05, 0x10, 0x48,
        0x47, 0x35, 0x10, 0x85, 0x30, 0x86, 0x71, 0x38,
        0x16, 0x37, 0x6F, 0x3B, 0x1C, 0x18, 0xB1, 0xE3,
        0xE8, 0xEE, 0x83, 0x3E, 0x8D, 0x38, 0x43, 0x9E,
        0x78, 0x1C, 0xA3, 0xB8, 0x94, 0x06, 0x54, 0xEF,
        0x44, 0x6C, 0x9A, 0xAC, 0xC3, 0xF1, 0xD3, 0x0E,
        0xE0, 0x10, 0x5B, 0x8F, 0x63, 0xEB, 0x89, 0x74,
        0x6E, 0xF4, 0xBE, 0xB5, 0x4C, 0xFC, 0xE8, 0x81,
        0x2C, 0xF9, 0x47, 0xCF, 0x54, 0x54, 0xFB, 0x1C,
        0xA5, 0x5F, 0x25, 0xA0, 0xFE, 0x57, 0xF5, 0xFC,
        0xFD, 0x73, 0xB0, 0xDA, 0x04, 0xB0, 0xBF, 0x28,
        0x92, 0x92, 0xAF, 0x39, 0x74, 0x72, 0x56, 0x69,
        0xC3, 0x00, 0x03, 0xE0, 0x50, 0x9F, 0xED, 0xC8,
        0x0F, 0x6C, 0x89, 0x4B, 0xB0, 0x47, 0xC2, 0xE2,
        0xAF, 0x48, 0x5C, 0xAD, 0x68, 0xC2, 0x1D, 0x80,
        0xEF, 0x33, 0xB0, 0xC4, 0xFD, 0xA6, 0x7B, 0x85,
        0x31, 0xA1, 0x58, 0x87, 0x67, 0x54, 0x71, 0x3F,
        0xF8, 0xA8, 0xA6, 0x8D, 0x9A, 0xBD, 0xC4, 0x81,
        0x6B, 0x24, 0xB4, 0xA3, 0x6A, 0x8A, 0x2B, 0xB1,
        0xFD, 0x1C, 0x2C, 0x25, 0xC3, 0x72, 0xC4, 0xB7,
        0x75, 0xF8, 0xCC, 0x17, 0x39, 0xCF, 0x2C, 0xE9,
        0xA4, 0x54, 0x58, 0xE4, 0x1A, 0xAE, 0xC6, 0x4A,
        0xEE, 0xDE, 0x75, 0x7C, 0xE7, 0x38, 0xBC, 0xDF,
        0x4D, 0xA0, 0xEE, 0x2B, 0xDD, 0x5F, 0x80, 0x5C,
        0xCF, 0xF7, 0x2A, 0x5F, 0x73, 0x8B, 0xAC, 0x12,
        0x34, 0x2E, 0xE3, 0xF1, 0x4C, 0xB7, 0x22, 0x68,
        0xC2, 0xD6, 0x36, 0x7D, 0xF1, 0x7F, 0x20, 0x46,
        0xA2, 0x4B, 0x47, 0x4B, 0x32, 0x58, 0xF7, 0xB0,
        0x88, 0x54, 0x6C, 0x99, 0x3B, 0x0D, 0xA1, 0xE2,
        0x92, 0x92, 0xEB, 0x72, 0x1E, 0xE7, 0xE5, 0xA1,
        0xF8, 0x6E, 0x14, 0xA5, 0x39, 0xB0, 0x63, 0x6F,
        0x78, 0x82, 0xA1, 0x9C, 0x8D, 0x79, 0x02, 0x85,
        0xA6, 0xDF, 0x7D, 0xEE, 0xCE, 0x17, 0x4D, 0x63,
        0xCF, 0xF3, 0xB2, 0xFF, 0x85, 0x68, 0x81, 0xCB,
        0x38, 0x6B, 0x1B, 0x38, 0xA2, 0xE0, 0xF2, 0x4C,
        0x31, 0xE0, 0x91, 0x93, 0xDD, 0xF3, 0x71, 0x47,
        0xF2, 0x69, 0xD9, 0x4C, 0xDE, 0xF9, 0x90, 0x61,
        0x34, 0x62, 0x07, 0x71, 0x79, 0xD0, 0xDD, 0x09,
        0x32, 0x64, 0x39, 0x49, 0x93, 0x1A, 0x02, 0xBA,
        0xFA, 0x80, 0x17, 0x6E, 0xDF, 0x97, 0xB6, 0xA2,
        0x31, 0x34, 0x71, 0xF0, 0xB1, 0x9B, 0x3B, 0x59,
        0xF4, 0x3B, 0xD2, 0x2A, 0x05, 0x49, 0x3E, 0xFB,
        0x0C, 0xF8, 0xB5, 0xD7, 0xB6, 0x25, 0x2B, 0x09,
        0x8B, 0x4B, 0xFA, 0x39, 0x5B, 0xF9, 0xA2, 0x09,
        0xE9, 0xBB, 0x46, 0x01, 0x30, 0x00, 0x90, 0x32,
        0x58, 0xA6, 0x9B, 0x67, 0xF5, 0x94, 0x11, 0xC8,
        0x35, 0x95, 0xFA, 0x6E, 0x67, 0x42, 0x8D, 0x96,
        0x6D, 0x20, 0xFC, 0xD3, 0x09, 0x61, 0x11, 0x86,
        0x77, 0xC0, 0x86, 0xA3, 0x54, 0xAE, 0x6D, 0x41,
        0xEE, 0x17, 0xDC, 0xA1, 0xB0, 0xB7, 0x50, 0x43,
        0xD6, 0xCE, 0x23, 0xBD, 0xB0, 0x1E, 0x02, 0xE5,
        0x9E, 0xCF, 0xC6, 0x2E, 0x8C, 0x39, 0x71, 0xB1,
        0x45, 0x02, 0x75, 0xBA, 0x7F, 0x60, 0xB0, 0x8B,
        0x1C, 0x33, 0xBA, 0x0C, 0xFF, 0x54, 0x63, 0xE3,
        0x47, 0x5B, 0x07, 0x77, 0x77, 0xC5, 0x72, 0x24,
        0x60, 0xFA, 0xDB, 0x0B, 0xF6, 0x41, 0x82, 0x69,
        0x3C, 0x68, 0x37, 0xF5, 0xFD, 0x45, 0x4A, 0x66,
        0x6C, 0xD7, 0x01, 0x10, 0x78, 0x4A, 0xED, 0x09,
        0xAE, 0x49, 0x0A, 0x60, 0xC7, 0x78, 0x56, 0x51,
        0x15, 0xE3, 0x4A, 0xB5, 0xAE, 0xAD, 0x09, 0xD1,
        0x71, 0xA8, 0xCA, 0x3C, 0x8A, 0xE6, 0xCA, 0x39,
        0x43, 0x60, 0x56, 0x83, 0x3C, 0x58, 0x04, 0xD4,
        0xB4, 0x62, 0xDD, 0x53, 0x05, 0xC8, 0x51, 0xAF,
        0x59, 0xF6, 0x4F, 0x04, 0xC3, 0x1E, 0x69, 0xFF,
        0x82, 0xBF, 0xD7, 0x89, 0xD2, 0x30, 0x9F, 0xF2,
        0xE6, 0x38, 0x05, 0x9C, 0xD5, 0x08, 0xB8, 0x25,
        0xF3, 0x3B, 0x99, 0x85, 0x4E, 0x40, 0xF8, 0x40,
        0xF2, 0x4B, 0x5C, 0x3A, 0xA8, 0x64, 0x41, 0x92,
        0xEA, 0xCA, 0x9A, 0x7B, 0xCF, 0xBA, 0x1F, 0xDE,
        0xE0, 0x9D, 0xCA, 0xAD, 0xB4, 0x0C, 0x90, 0xFF,
        0xE1, 0x6C, 0xEC, 0xDD, 0x32, 0x38, 0x2A, 0xF7,
        0x19, 0x20, 0x39, 0xCB, 0x29, 0x67, 0x2F, 0x70,
        0x71, 0x12, 0x10, 0xB6, 0xB8, 0x3E, 0x8D, 0xFD,
        0xB5, 0xFB, 0xBD, 0xBF, 0xA8, 0xCA, 0x19, 0xC4,
        0xC6, 0xAC, 0x37, 0x31, 0xFC, 0x33, 0xC2, 0x7F,
        0xA2, 0xA2, 0x6D, 0xEB, 0x15, 0x2E, 0xA1, 0x90,
        0xF8, 0x29, 0xC6, 0x34, 0xD1, 0x39, 0x30, 0x24,
        0x1C, 0xB9, 0x26, 0xAC, 0xDD, 0xE5, 0x24, 0x9C,
        0xDD, 0x35, 0x60, 0x7E, 0x38, 0x0C, 0xC1, 0x2A,
        0x7D, 0x1E, 0xA9, 0xBA, 0xA5, 0x58, 0x4C, 0xDD,
        0x26, 0x86, 0x09, 0xDC, 0xC3, 0xB0, 0x1F, 0xCD,
        0xC9, 0xAD, 0xCB, 0x4A, 0x7E, 0x51, 0x67, 0xE5,
        0xED, 0x5A, 0xD2, 0x21, 0xDB, 0x2E, 0xAB, 0xD9,
        0x0A, 0xEC, 0xAE, 0x71, 0xFA, 0x23, 0x7A, 0xEF,
        0x98, 0xDF, 0x53, 0x89, 0x93, 0xE8, 0x71, 0xD7,
        0x35, 0xDA, 0x6B, 0x88, 0x31, 0xAF, 0x67, 0xF2,
        0x97, 0x29, 0x1C, 0x39, 0x67, 0xEB, 0xAF, 0x60,
        0xD9, 0x53, 0xC4, 0x0F, 0x7A, 0x46, 0x4E, 0xF3,
        0x2F, 0x8E, 0xAE, 0xFA, 0x64, 0x2E, 0x37, 0xDE,
        0xA9, 0x74, 0x73, 0x5D, 0xDD, 0xBB, 0x83, 0x54,
        0x27, 0xB9, 0x7A, 0x63, 0x2B, 0x19, 0x8B, 0x26,
        0x22, 0x28, 0x84, 0xA0, 0x58, 0x00, 0x2D, 0x55,
        0xEA, 0x2A, 0x80, 0x0D, 0x6C, 0x97, 0x0E, 0x8B,
        0xF7, 0x67, 0xB2, 0x8B, 0x2D, 0xDE, 0x8F, 0x58,
        0xFE, 0x97, 0x81, 0xE7, 0xE2, 0x58, 0x8D, 0x7E,
        0x1B, 0xAB, 0xE5, 0x15, 0x9D, 0x54, 0xF4, 0x00,
        0x34, 0x1D, 0x12, 0x1B, 0x03, 0x23, 0x2B, 0x06,
        0x2E, 0x8C, 0xD0, 0x0A, 0xDC, 0x19, 0xA1, 0x69,
        0x1D, 0x72, 0x91, 0xB4, 0xED, 0x0E, 0x81, 0xF7,
        0x05, 0x99, 0x84, 0xFC, 0x74, 0x0F, 0x7D, 0xF8,
        0x9B, 0x3E, 0x7F, 0x63, 0x7C, 0x73, 0xEB, 0xF5,
        0x36, 0xB3, 0x24, 0x22, 0xAA, 0x33, 0x0C, 0x30,
        0x42, 0xC3, 0xE2, 0x04, 0x6B, 0x3F, 0x2A, 0x0D,
        0xAB, 0xE8, 0x5A, 0x9A, 0x09, 0xD7, 0xB6, 0xAA,
        0x9C, 0x3E, 0xD0, 0x9E, 0xB5, 0x9B, 0x52, 0x7B,
        0xAF, 0x2D, 0x6B, 0xE0, 0x40, 0x12, 0x34, 0xBE,
        0x49, 0xAB, 0xD2, 0xC8, 0xB5, 0x89, 0x1B, 0x79,
        0xEC, 0xAE, 0x88, 0x89, 0x3C, 0x05, 0xC7, 0x75,
        0xC5, 0x84, 0xF7, 0x10, 0x49, 0x48, 0x92, 0x69,
        0x9E, 0xD5, 0x56, 0xB2, 0x1E, 0x81, 0x18, 0x78,
        0xCB, 0x93, 0x5D, 0x70, 0x3A, 0xB2, 0x67, 0xD1,
        0xCC, 0x8F, 0x83, 0x03, 0xB9, 0x64, 0x46, 0x22,
        0x78, 0x0D, 0x55, 0x67, 0x22, 0x58, 0x0E, 0x22,
        0x6B, 0xBA, 0x01, 0xD4, 0x77, 0x05, 0xA7, 0xAC,
        0xB7, 0xE5, 0xFC, 0xE6, 0x11, 0xCC, 0x92, 0x5A,
        0x8C, 0xC0, 0x08, 0x24, 0xAF, 0xCC, 0x4D, 0xBD,
        0x79, 0xD3, 0x5C, 0x52, 0x2C, 0xFF, 0x1A, 0x48,
        0xBB, 0x91, 0x59, 0x6A, 0x80, 0x32, 0x8C, 0x75,
        0x7C, 0xD2, 0xC1, 0x94, 0x94, 0xA8, 0x55, 0x4B,
        0xF2, 0x96, 0xF7, 0x86, 0xF7, 0x53, 0x4F, 0x54,
        0x74, 0x05, 0x5C, 0xEF, 0x02, 0xA0, 0x8A, 0xD1,
        0x88, 0x72, 0xEB, 0x1B, 0x82, 0xF9, 0xFB, 0xDA,
        0xBC, 0xB9, 0x90, 0x98, 0xF2, 0x4B, 0x9A, 0xA6,
        0x89, 0xD5, 0xB3, 0xD8, 0x7B, 0x94, 0xE3, 0x1F,
        0x17, 0x4F, 0xEB, 0x24, 0x06, 0x2B, 0xAB, 0x5F,
        0x27, 0x9B, 0xCD, 0xCE, 0x50, 0x06, 0x40, 0xDD,
        0x7A, 0x8C, 0x67, 0xF0, 0x8E, 0x07, 0xB4, 0x1C,
        0x3C, 0x13, 0xB2, 0x07, 0x6A, 0x38, 0x59, 0x94,
        0x2C, 0xB1, 0x72, 0xA8, 0x77, 0x5B, 0x15, 0x8F,
        0x88, 0xC4, 0x5C, 0xDC, 0x92, 0xCA, 0xC0, 0xED,
        0x02, 0xFF, 0x1D, 0x57, 0x25, 0xBE, 0x67, 0x3E,
        0x4C, 0xE8, 0x95, 0x2A, 0x80, 0xB2, 0x5D, 0xBC,
        0xFA, 0x17, 0xA9, 0x35, 0x0A, 0x6B, 0x07, 0xC8,
        0x8F, 0x88, 0x8D, 0xBC, 0x97, 0x84, 0xE2, 0x07,
        0x57, 0x92, 0x99, 0x4B, 0xE8, 0xDD, 0xD7, 0xA4,
        0x58, 0xCB, 0x61, 0xCE, 0x16, 0xFC, 0x22, 0xCD,
        0x4B, 0x1A, 0x08, 0xC9, 0xAD, 0x3D, 0xB1, 0xF2,
        0xA9, 0x1B, 0x8E, 0xD0, 0xC7, 0xBC, 0xCE, 0xF9,
        0x0A, 0x7A, 0x4D, 0xBE, 0x82, 0x0A, 0xBD, 0x6C,
        0x42, 0x99, 0xBF, 0x86, 0x65, 0x53, 0xAA, 0x04,
        0x79, 0xD6, 0x6D, 0x7E, 0x0F, 0x40, 0xFA, 0xEE,
        0xCE, 0x38, 0x3B, 0x1C, 0x2F, 0xA4, 0x45, 0xA3,
        0x78, 0x2B, 0xA0, 0x29, 0xC5, 0xAA, 0xA9, 0x09,
        0x29, 0x51, 0xDC, 0x5B, 0xB5, 0x95, 0xE4, 0xCE,
        0xC8, 0x50, 0x71, 0x2D, 0xE9, 0x32, 0x12, 0xA0,
        0x7C, 0x88, 0x6B, 0xED, 0xE4, 0x38, 0xB7, 0x92,
        0xCA, 0xE4, 0xDC, 0xD4, 0x05, 0x3B, 0x2B, 0x84,
        0x95, 0x07, 0xFF, 0xF4, 0x79, 0xFF, 0x1E, 0x73,
        0x1B, 0x8E, 0xDF, 0xA3, 0x15, 0xBD, 0x56, 0xAC,
        0xDA, 0xAD, 0x73, 0x95, 0xC2, 0xD3, 0x72, 0xA8,
        0xF0, 0x8E, 0x6C, 0xE3, 0x7D, 0xBE, 0x4C, 0x87,
        0xFC, 0x0F, 0xA6, 0x3B, 0xED, 0xA4, 0x0F, 0x4F,
        0xF1, 0x5D, 0xF2, 0x56, 0x54, 0xD1, 0xCE, 0x6C,
        0xCA, 0x1C, 0xCB, 0xC2, 0x45, 0x7F, 0x90, 0x61,
        0x0E, 0x3D, 0xCE, 0xBB, 0x5E, 0x41, 0x38, 0x2B,
        0xD4, 0x41, 0x7C, 0x67, 0x7C, 0x71, 0x95, 0x34,
        0xD7, 0xED, 0x4D, 0xAC, 0x6E, 0xF1, 0x46, 0xEA,
        0x7D, 0xA4, 0x4C, 0x69, 0x0B, 0x9C, 0x2F, 0xAA,
        0xF1, 0x17, 0x90, 0x1B, 0xF4, 0x4C, 0x03, 0xBE,
        0x9D, 0x56, 0xCE, 0x0C, 0xCF, 0xE0, 0x87, 0x44,
        0xBE, 0x2C, 0x52, 0xD3, 0xBC, 0xAE, 0x02, 0x30,
        0xC7, 0x26, 0x06, 0x88, 0xA6, 0xAA, 0x9D, 0x50,
        0xF1, 0x94, 0x58, 0xC7, 0x60, 0xF3, 0xA0, 0x6F,
        0x53, 0x66, 0x53, 0xCD, 0x1D, 0xBE, 0xD1, 0xF2,
        0x39, 0xBA, 0x1F, 0xE8, 0x40, 0x84, 0xCD, 0x1C,
        0x8F, 0x3D, 0xB7, 0xD1, 0x51, 0x00, 0xDE, 0xB8,
        0x11, 0xD9, 0x66, 0xAD, 0xD5, 0xE9, 0x33, 0x09,
        0xE1, 0xA8, 0x00, 0x58, 0x65, 0xF1, 0xC1, 0x67,
        0xB4, 0x3A, 0xA7, 0x98, 0x90, 0x6A, 0xDB, 0x91,
        0xDB, 0x4A, 0x16, 0x35, 0xDC, 0x3D, 0x69, 0xEB,
        0x7B, 0xDE, 0xCC, 0x91, 0x1B, 0x8D, 0xE6, 0x46,
        0x61, 0x8E, 0x3F, 0x4C, 0x88, 0x81, 0x85, 0x4A,
        0x73, 0x08, 0x56, 0x52, 0xAE, 0xE6, 0x4A, 0x60,
        0x4A, 0x2E, 0x0C, 0x9A, 0x93, 0x76, 0x35, 0xC9,
        0x36, 0x28, 0x0C, 0x72, 0x19, 0xAD, 0x33, 0xCF,
        0x2B, 0xFB, 0xCE, 0x1A, 0x7D, 0xAC, 0xAA, 0x75,
        0x15, 0x76, 0x81, 0x52, 0x55, 0xCC, 0xB9, 0x39,
        0x07, 0xA3, 0x39, 0x12, 0x8D, 0x6F, 0x53, 0xAF,
        0xC7, 0x14, 0x7F, 0xC7, 0x96, 0x5A, 0x49, 0x3C,
        0x5C, 0xB0, 0x26, 0x47, 0xF4, 0x9D, 0xCA, 0x23,
        0xA6, 0x7D, 0xA6, 0x61, 0xC4, 0xA3, 0x26, 0x40,
        0x0F, 0xA7, 0x27, 0x09, 0xBC, 0x39, 0xFD, 0xA7,
        0x75, 0x38, 0x74, 0xD0, 0x9D, 0x29, 0x15, 0x97,
        0xDE, 0x25, 0x60, 0x4D, 0x19, 0x36, 0x04, 0xFB,
        0xA5, 0x2C, 0xB0, 0xC8, 0xB5, 0xFE, 0xE5, 0x94,
        0x7C, 0xE2, 0x1F, 0x84, 0xBB, 0xFB, 0x78, 0x9E,
        0xA5, 0x7C, 0x5D, 0x4A, 0xB2, 0x48, 0x6F, 0x6E,
        0x67, 0x95, 0x16, 0x5F, 0x01, 0x2A, 0xF8, 0x70,
        0x95, 0xCB, 0x06, 0x93, 0x26, 0x6E, 0x7A, 0x75,
        0xB5, 0xE5, 0x4E, 0x27, 0x1D, 0x8B, 0x30, 0xA6,
        0x67, 0x67, 0xD6, 0xE2, 0xD6, 0xD1, 0x99, 0xA4,
        0x55, 0x73, 0x19, 0x32, 0xF6, 0x0B, 0x6B, 0x4A,
        0xEE, 0x23, 0x33, 0x38, 0x30, 0x68, 0x6F, 0x8E,
        0x60, 0xA9, 0x60, 0x97, 0x3E, 0xEA, 0x5D, 0xE1,
        0x40, 0x6F, 0x0C, 0x76, 0x84, 0xCF, 0xAF, 0x86,
        0x8D, 0x36, 0xE5, 0x7D, 0xAE, 0x9A, 0x13, 0x70,
        0x22, 0x2A, 0x31, 0xFE, 0xC2, 0xFB, 0xE1, 0x58,
        0xA5, 0x4E, 0xEF, 0x10, 0x5B, 0x5E, 0xD4, 0x39,
        0xFC, 0xF9, 0x15, 0x64, 0x78, 0x43, 0x7D, 0x03,
        0x9F, 0x5B, 0xCB, 0x86, 0xD2, 0xEF, 0x28, 0xBD,
        0x14, 0xCB, 0x8A, 0x04, 0x1D, 0x59, 0x23, 0x53,
        0x4D, 0x13, 0xF9, 0x93, 0xFE, 0x19, 0x9C, 0xC3,
        0x3F, 0xD9, 0xC1, 0x12, 0x94, 0x84, 0x13, 0x95,
        0x8F, 0xD9, 0x10, 0xAB, 0x37, 0x69, 0x08, 0x04,
        0x4A, 0x97, 0x82, 0x28, 0x75, 0xBB, 0xC9, 0xF4,
        0x3F, 0x19, 0x6B, 0x00, 0x4C, 0x56, 0x16, 0x1F,
        0x50, 0x82, 0xD1, 0x45, 0xFF, 0x0C, 0x37, 0x28,
        0x04, 0xBB, 0x6C, 0x00, 0x97, 0x3A, 0x79, 0x2D,
        0x9A, 0xB9, 0xA5, 0x16, 0x52, 0x02, 0xA3, 0x86,
        0x81, 0xAA, 0x3A, 0x31, 0xE5, 0xB5, 0x44, 0x2D,
        0x34, 0xE2, 0x7A, 0xD8, 0xFE, 0xA1, 0x36, 0xC0,
        0x36, 0x65, 0x73, 0x12, 0x9F, 0x61, 0x3F, 0x59,
        0xC9, 0x68, 0xB6, 0x34, 0x41, 0x40, 0x25, 0xD6,
        0xE7, 0xAD, 0x25, 0x7D, 0xCB, 0xF1, 0x2A, 0xD8,
        0x53, 0x48, 0x9D, 0xBF, 0xB5, 0xD5, 0x61, 0x18,
        0x0E, 0x2A, 0x21, 0x3E, 0x61, 0x18, 0x07, 0x8E,
        0x6F, 0x9A, 0x96, 0xA8, 0x61, 0xFE, 0x8D, 0x66,
        0x1A, 0x21, 0x99, 0xD9, 0x60, 0x8B, 0xAC, 0x85,
        0x84, 0x3D, 0x41, 0xF9, 0x93, 0x35, 0x24, 0x32,
        0xFF, 0xC0, 0x8A, 0xFA, 0xBC, 0xA7, 0x85, 0x57,
        0x3C, 0x16, 0x83, 0xAE, 0x90, 0xDE, 0x40, 0x12,
        0xE4, 0x2B, 0xA2, 0x47, 0xA4, 0x92, 0x73, 0x54,
        0x6C, 0xA5, 0xB7, 0xEE, 0x62, 0xEA, 0x62, 0x37,
        0xD9, 0xD7, 0x73, 0x58, 0x43, 0xDB, 0x20, 0x60,
        0x8C, 0x4F, 0x87, 0x58, 0xB2, 0x2B, 0xC3, 0x40,
        0xB0, 0xC1, 0xB6, 0xB6, 0xA9, 0xCD, 0xCC, 0x05,
        0x4F, 0x38, 0x5F, 0x08, 0xB3, 0x3B, 0x08, 0x4D,
        0x78, 0x6B, 0x0D, 0x40, 0x46, 0xB9, 0x20, 0xDE,
        0x29, 0x6F, 0x23, 0x96, 0xDA, 0x02, 0xF5, 0x1C,
        0x1A, 0x1A, 0x36, 0xA3, 0x3A, 0xFA, 0x1D, 0x80,
        0x36, 0x3C, 0xF6, 0xB4, 0xDC, 0x2C, 0x88, 0x54,
        0xF7, 0x86, 0xC6, 0xF2, 0x15, 0xF8, 0x85, 0x33,
        0xFB, 0x21, 0x20, 0x59, 0xCE, 0x60, 0x4B, 0xE8,
        0xF1, 0xB7, 0x54, 0x17, 0x1E, 0x83, 0xCD, 0x82,
        0x39, 0x40, 0x14, 0x31, 0xEC, 0x89, 0xC8, 0xE2,
        0x6A, 0xAE, 0x3F, 0x49, 0x5B, 0x38, 0xE7, 0xCD,
        0xE2, 0xF6, 0xEF, 0x90, 0x51, 0x10, 0x83, 0x79,
        0x27, 0x80, 0x2F, 0x45, 0x78, 0x67, 0xAF, 0xF4,
        0x65, 0x95, 0x2D, 0xFE, 0x00, 0xF3, 0x2A, 0x60,
        0x00, 0xF7, 0x26, 0xFA, 0x3C, 0xAD, 0xA9, 0xAF,
        0xCA, 0xF6, 0x69, 0x48, 0x03, 0xBE, 0x18, 0x73,
        0x54, 0x06, 0x06, 0x3E, 0x4E, 0xAD, 0xFC, 0x8B,
        0xC3, 0x43, 0x24, 0x5D, 0xE9, 0xDE, 0x78, 0xDC,
        0xD0, 0xA7, 0x04, 0x77, 0xF0, 0x0D, 0xA3, 0x37,
        0x8C, 0x5F, 0x8B, 0xDF, 0xBE, 0x90, 0x1F, 0xA6,
        0xB3, 0x17, 0x9D, 0x68, 0x36, 0x45, 0x11, 0x60,
        0xFF, 0xF9, 0xBA, 0xDA, 0x80, 0xAA, 0x37, 0x57,
        0xDD, 0x34, 0x30, 0x42, 0x7A, 0x9C, 0x86, 0xB4,
        0x91, 0x30, 0xB8, 0xC0, 0xC4, 0x29, 0x15, 0x31,
        0xF3, 0x9A, 0xB0, 0xCD, 0xAC, 0x8C, 0x7C, 0x8C,
        0x4A, 0xDC, 0x76, 0xB6, 0x31, 0x30, 0xDE, 0x2D,
        0x81, 0x04, 0xC7, 0x48, 0x73, 0x69, 0x02, 0x40,
        0x30, 0x19, 0x66, 0x94, 0x21, 0x65, 0x13, 0x18,
        0xC2, 0x09, 0x14, 0x5F, 0xC4, 0x2F, 0xC4, 0xD6,
        0xA6, 0x05, 0x37, 0xAF, 0x72, 0x0C, 0x47, 0x02,
        0x29, 0x95, 0x08, 0x9D, 0xC9, 0x07, 0x31, 0x38,
        0xA9, 0xB5, 0xDA, 0x21, 0x76, 0x1D, 0x84, 0xD0,
        0x15, 0xAF, 0x2A, 0xA3, 0x69, 0x0A, 0xE9, 0x4F,
        0x75, 0x8A, 0x50, 0xA5, 0x11, 0xD4, 0x5F, 0xAF,
        0x70, 0x43, 0xCB, 0xD7, 0x03, 0x9E, 0xB0, 0xBD,
        0x19, 0x47, 0x94, 0x58, 0x22, 0x86, 0xC6, 0xE3,
        0x62, 0xD8, 0x63, 0x05, 0xD9, 0xE2, 0xE5, 0x4A,
        0x04, 0x54, 0x5A, 0x55, 0x25, 0xAD, 0x15, 0x5C,
        0x4B, 0x71, 0x25, 0xE1, 0x50, 0xE3, 0x62, 0x1B,
        0xD2, 0x43, 0x28, 0xD2, 0x84, 0xE4, 0xE2, 0x05,
        0xE3, 0x01, 0x4C, 0x8F, 0x38, 0x17, 0x49, 0xFD,
        0x3B, 0x52, 0x1A, 0x55, 0xB3, 0x1D, 0x69, 0x83,
        0xAB, 0x9E, 0xC4, 0x73, 0xEE, 0x64, 0x7A, 0x73,
        0x19, 0xEF, 0xCD, 0x7D, 0xB7, 0xF4, 0x2E, 0xCB,
        0x55, 0x2A, 0x8A, 0xCC, 0x8F, 0xF8, 0x4E, 0xFB,
        0xD2, 0x63, 0x8F, 0xF1, 0x10, 0x89, 0x02, 0x93,
        0x3E, 0xAC, 0xA4, 0xB4, 0x89, 0xC7, 0xF7, 0x8B,
        0x3E, 0xE1, 0xE8, 0x93, 0xB9, 0x8E, 0x36, 0x25,
        0xC1, 0xC0, 0xD9, 0x44, 0x81, 0xC0, 0x99, 0x3C,
        0x2B, 0x89, 0xF7, 0xDF, 0xDB, 0xD8, 0xCC, 0x84,
        0xE6, 0xFF, 0xFE, 0xAC, 0x21, 0x16, 0xF1, 0xE2,
        0xEF, 0x0A, 0x32, 0xA7, 0xDE, 0x87, 0x51, 0xEC,
        0xB1, 0x0C, 0x0B, 0xC7, 0x07, 0xD9, 0x9A, 0xF8,
        0xE8, 0xB0, 0xFE, 0xA5, 0x67, 0xAF, 0x53, 0x9F,
        0xEF, 0x23, 0xEF, 0x7D, 0xFF, 0xA8, 0x8E, 0xDE,
        0x97, 0x93, 0x32, 0xA6, 0x7C, 0xCF, 0x49, 0xBC,
        0x36, 0x0D, 0x88, 0x90, 0x89, 0x39, 0x76, 0xA8,
        0x82, 0x19, 0x02, 0xB6, 0x02, 0x82, 0xFE, 0xED,
        0x9C, 0x28, 0x8D, 0xB0, 0x1E, 0x2B, 0x2A, 0xCF,
        0xF3, 0x94, 0xFF, 0x66, 0x33, 0x93, 0x31, 0xD6,
        0xFC, 0xAF, 0xE7, 0xC5, 0x98, 0x01, 0x46, 0xCD,
        0xCB, 0xC4, 0x41, 0x13, 0x6D, 0x42, 0xF5, 0x13,
        0xDF, 0xF9, 0x97, 0x65, 0xD4, 0x7B, 0x6E, 0x10,
        0x79, 0x5D, 0x5A, 0x82, 0xA2, 0x49, 0x53, 0xA7,
        0x6D, 0x9C, 0xDD, 0x0A, 0x80, 0x98, 0x58, 0x07,
        0x30, 0xBF, 0x0B, 0x30, 0xAC, 0x24, 0x9E, 0xA0,
        0xE8, 0xE4, 0x7A, 0x0D, 0xD0, 0x50, 0x82, 0xAE,
        0xBB, 0xEC, 0x15, 0x30, 0x2A, 0xF2, 0xA7, 0xA6,
        0x6A, 0xC8, 0xAE, 0x1E, 0x14, 0x80, 0x7C, 0x18,
        0xE7, 0x2B, 0x88, 0x65, 0xB7, 0x93, 0x12, 0xB3,
        0xC1, 0x2A, 0x20, 0xAD, 0x3B, 0x2E, 0x84, 0xC4,
        0x0D, 0xA7, 0x62, 0x5C, 0x79, 0x52, 0x5D, 0x59,
        0xA4, 0x69, 0x5C, 0x26, 0xFD, 0x4F, 0x80, 0xCC,
        0xFE, 0x8E, 0x70, 0x72, 0xB1, 0x41, 0xE1, 0x75,
        0x53, 0x51, 0xCF, 0x4C, 0x0B, 0x57, 0xF2, 0xB8,
        0x59, 0x76, 0xE6, 0xEF, 0x6D, 0x74, 0xA6, 0x73,
        0x69, 0x7F, 0x7C, 0xB2, 0x35, 0xFE, 0x8A, 0x02,
        0x2F, 0xBE, 0x7C, 0x4D, 0x02, 0xBE, 0x8F, 0xFB,
        0x7A, 0x58, 0x45, 0xEC, 0xBA, 0x1B, 0xC6, 0xB9,
        0x8D, 0xF5, 0xB0, 0x82, 0xD1, 0xB4, 0x97, 0x86,
        0x9B, 0x33, 0x54, 0x49, 0x5B, 0x88, 0xD9, 0xB5,
        0xD0, 0x93, 0x8A, 0x00, 0x5D, 0x0F, 0x37, 0x88,
        0x57, 0xE3, 0xFA, 0x7E, 0x7B, 0xFA, 0x43, 0x74,
        0x8D, 0x64, 0x07, 0xD7, 0x07, 0x85, 0x4D, 0x49,
        0xBC, 0x83, 0xF5, 0xD4, 0x95, 0x3E, 0x3E, 0x09,
        0x65, 0xF3, 0xFC, 0x88, 0xA7, 0xF0, 0x46, 0x61,
        0x44, 0x7D, 0x76, 0xED, 0xC9, 0x8D, 0x0F, 0x8D,
        0xDA, 0x0D, 0x01, 0xC8, 0xB1, 0xA8, 0x9B, 0x4A,
        0xF0, 0xA3, 0x88, 0x54, 0xC1, 0xD6, 0x52, 0x97
    };
#endif /* WOLFSSL_NO_ML_DSA_65 */
#ifndef WOLFSSL_NO_ML_DSA_87
    static const byte seed_87_draft[] = {
        0x22, 0x5F, 0x77, 0x07, 0x5E, 0x66, 0xCE, 0x1C,
        0x99, 0xBA, 0x95, 0xB4, 0xFC, 0xDF, 0x25, 0x8B,
        0xBB, 0x6F, 0xA5, 0xFE, 0x9C, 0x34, 0x9F, 0x0F,
        0xDE, 0x3F, 0x71, 0xD5, 0x33, 0x9F, 0x6F, 0xD8
    };
    static const byte pk_87_draft[] = {
        0x8C, 0x52, 0x4B, 0xD9, 0xAC, 0x48, 0x5C, 0xC6,
        0x9A, 0xA0, 0x75, 0x64, 0xE1, 0x4F, 0x0F, 0x60,
        0x13, 0x0E, 0xDE, 0x34, 0x08, 0xA5, 0xD4, 0x81,
        0xFD, 0x76, 0xC2, 0x51, 0x74, 0x75, 0xA8, 0xFB,
        0x24, 0xBF, 0x9E, 0x97, 0x9C, 0xD2, 0x3E, 0xDA,
        0x8A, 0x1B, 0xB6, 0x76, 0xDA, 0x7D, 0x7F, 0x44,
        0xAD, 0x6B, 0xB9, 0xB0, 0x70, 0xD3, 0xD6, 0x44,
        0x7F, 0xBE, 0x6C, 0x0C, 0x71, 0x37, 0xC6, 0xFB,
        0x7B, 0x39, 0x83, 0x63, 0x9C, 0x41, 0x5C, 0xF2,
        0xC9, 0x15, 0xFF, 0xD4, 0x18, 0xEA, 0xA1, 0x4D,
        0xA9, 0xD1, 0xAD, 0x3C, 0x09, 0x8E, 0xA9, 0x05,
        0x34, 0x6C, 0xAA, 0x75, 0x78, 0xF8, 0x6B, 0x6E,
        0x52, 0xE6, 0x57, 0x55, 0x16, 0xF4, 0x92, 0x3E,
        0x74, 0x3F, 0x96, 0xA3, 0x2A, 0xD0, 0x0E, 0xEE,
        0xA1, 0xCE, 0x8A, 0x33, 0xF4, 0x87, 0xB9, 0xF3,
        0x22, 0x5D, 0x2D, 0x84, 0xCD, 0x27, 0x57, 0xCC,
        0xCF, 0xE6, 0xA3, 0x66, 0x24, 0x53, 0x0E, 0x52,
        0x8A, 0x2F, 0x64, 0xFC, 0xE7, 0x04, 0xE7, 0xA7,
        0x6C, 0x2E, 0x6A, 0xDC, 0x00, 0xEF, 0x9B, 0xEC,
        0x91, 0x07, 0xB9, 0x69, 0x8F, 0x11, 0x59, 0xFC,
        0x52, 0xEF, 0x4C, 0x36, 0x5A, 0xFD, 0xB1, 0x50,
        0xED, 0xC3, 0x43, 0x5E, 0x03, 0xBB, 0x70, 0x26,
        0x00, 0x6E, 0x5A, 0x55, 0x13, 0x51, 0xA4, 0xB1,
        0x5F, 0xB8, 0x9F, 0xD2, 0xE9, 0x98, 0x38, 0xE8,
        0xCF, 0x41, 0x73, 0xFD, 0x0D, 0xF1, 0xF6, 0x80,
        0x89, 0xE1, 0x51, 0x8D, 0xD4, 0xB5, 0x79, 0x27,
        0x76, 0xBD, 0xD9, 0x2F, 0xC7, 0xC7, 0x9B, 0xC7,
        0x99, 0x7F, 0x78, 0x84, 0xD2, 0xB8, 0x80, 0xC5,
        0xD2, 0xB7, 0xEE, 0xC8, 0x0A, 0xFE, 0x35, 0x59,
        0x84, 0x5D, 0x39, 0x08, 0x39, 0xBE, 0x5E, 0xBF,
        0x95, 0x93, 0xA7, 0x3E, 0xD0, 0x1E, 0xF6, 0x7D,
        0x50, 0x3F, 0xFB, 0x74, 0x47, 0x04, 0xA2, 0xDC,
        0x49, 0x48, 0x76, 0x2B, 0xC8, 0x43, 0x45, 0x75,
        0x72, 0x84, 0x4D, 0x15, 0x74, 0xE3, 0xEB, 0x37,
        0x83, 0x0A, 0x3B, 0x7C, 0xD4, 0x02, 0xC7, 0x6E,
        0xD5, 0xB4, 0xFC, 0x15, 0xF0, 0x5E, 0x76, 0x03,
        0x4C, 0xBB, 0x6A, 0x29, 0xDE, 0xBC, 0x7E, 0x2B,
        0x34, 0xB2, 0x14, 0x2A, 0x57, 0xCF, 0x1B, 0x39,
        0x73, 0xE5, 0x8B, 0xFF, 0x47, 0x50, 0x42, 0xDC,
        0x22, 0x6C, 0x7E, 0x13, 0x71, 0xF3, 0x37, 0x51,
        0x40, 0xF2, 0x90, 0x57, 0xAC, 0xB4, 0x64, 0x7C,
        0x5F, 0x92, 0x6D, 0x3F, 0xDC, 0xCC, 0xC8, 0xD2,
        0xE1, 0x6B, 0x81, 0xA9, 0xED, 0xCD, 0x0C, 0x8B,
        0x5B, 0x2E, 0x11, 0x89, 0x87, 0x42, 0x4B, 0xEC,
        0xAD, 0x40, 0xA5, 0xE5, 0xB4, 0x6D, 0x1C, 0xB4,
        0x01, 0x0A, 0x8E, 0x9F, 0x6F, 0x25, 0x92, 0x5D,
        0xFE, 0x6B, 0x6F, 0x24, 0x64, 0x5F, 0x9C, 0x88,
        0x86, 0x96, 0xE8, 0x79, 0x64, 0x5B, 0x6A, 0x3A,
        0x76, 0x21, 0x90, 0xCC, 0xB7, 0xD6, 0x26, 0x9D,
        0x35, 0x54, 0x79, 0xDF, 0x71, 0x90, 0x55, 0x2A,
        0x38, 0x52, 0xD1, 0xE9, 0x56, 0x73, 0xE7, 0x19,
        0x44, 0x6A, 0xD3, 0x10, 0x24, 0xB9, 0x4B, 0xF8,
        0xBB, 0xC9, 0x7B, 0x04, 0x66, 0x39, 0xCE, 0x12,
        0x3F, 0xDE, 0xC3, 0x75, 0xAF, 0x9F, 0x8D, 0x4C,
        0xF7, 0x16, 0x9B, 0xEB, 0x5F, 0xE5, 0x1B, 0xBF,
        0x82, 0x2C, 0x53, 0xBA, 0x2D, 0x98, 0xA4, 0xA0,
        0x14, 0xA2, 0xDE, 0x69, 0x7F, 0x03, 0x3C, 0x9E,
        0x4A, 0x57, 0xC6, 0xED, 0xF6, 0x10, 0x6A, 0x76,
        0x2A, 0x81, 0x92, 0x9F, 0x3E, 0xF0, 0xFD, 0xE9,
        0xB7, 0xB3, 0x8A, 0xF6, 0x1A, 0x19, 0x9A, 0x16,
        0x0F, 0x09, 0x45, 0xBD, 0xBB, 0x96, 0x7C, 0x72,
        0x40, 0xFE, 0x94, 0xBD, 0xE1, 0x60, 0x50, 0x53,
        0x13, 0xC9, 0x2B, 0xFA, 0x52, 0x40, 0xA2, 0xA7,
        0xF0, 0x8C, 0x85, 0x78, 0xDB, 0xD6, 0x7F, 0x21,
        0x39, 0xB5, 0x06, 0x72, 0xEE, 0x99, 0xA1, 0xBD,
        0x78, 0x1F, 0xA4, 0xE9, 0x54, 0xF4, 0xFA, 0xDF,
        0xA7, 0x9E, 0xDD, 0x8E, 0xB1, 0xCF, 0xA8, 0x48,
        0x84, 0x5D, 0x70, 0xCB, 0x2D, 0xA9, 0x66, 0x09,
        0x0B, 0x75, 0x75, 0xA2, 0x32, 0xFE, 0xDF, 0x96,
        0x33, 0x84, 0xA7, 0x84, 0x48, 0x1A, 0xFA, 0x82,
        0x79, 0x0A, 0x87, 0xE1, 0x1F, 0x11, 0x74, 0xD4,
        0x3C, 0xC0, 0x8D, 0x4F, 0xD2, 0x5D, 0xBB, 0x40,
        0x10, 0xB2, 0x6F, 0x23, 0xD2, 0xD6, 0xF4, 0xA5,
        0x87, 0xEF, 0x7D, 0xE8, 0xC6, 0xF7, 0xC6, 0x0F,
        0xF9, 0x6F, 0xF8, 0x4C, 0x39, 0xE4, 0x82, 0x1E,
        0x1E, 0x6A, 0x80, 0x2F, 0xEC, 0x22, 0xD6, 0xA0,
        0xAA, 0xB6, 0x2C, 0xCB, 0x16, 0x43, 0x68, 0xC2,
        0x27, 0xF6, 0xA2, 0x31, 0x62, 0x66, 0xEC, 0x2F,
        0xFF, 0x8D, 0xB4, 0x19, 0x51, 0x19, 0xA0, 0x8C,
        0x67, 0xE2, 0x04, 0x04, 0xB9, 0x1F, 0x08, 0x70,
        0x9E, 0xAA, 0xC2, 0xDE, 0xCB, 0x96, 0x19, 0x8F,
        0x02, 0x74, 0x10, 0xCC, 0x1B, 0x82, 0x5D, 0x9C,
        0x07, 0x00, 0xE5, 0xD7, 0x04, 0x51, 0xBA, 0x7F,
        0x67, 0xF9, 0x64, 0x0C, 0xA3, 0x6B, 0xF3, 0x12,
        0x21, 0x80, 0x68, 0xD6, 0xA2, 0xCA, 0xFF, 0x59,
        0x33, 0x43, 0x7D, 0x67, 0xBF, 0xD4, 0x88, 0x4A,
        0x6E, 0x92, 0xBA, 0x41, 0xE1, 0x28, 0xDA, 0xEB,
        0xE1, 0xEA, 0x25, 0x60, 0xE1, 0x2F, 0xED, 0x2C,
        0xD4, 0x4B, 0xC9, 0x4E, 0x9E, 0x9D, 0xFA, 0xBB,
        0xF9, 0x61, 0x41, 0x4C, 0x24, 0x24, 0xFC, 0x9B,
        0x62, 0xFE, 0x73, 0x74, 0xF6, 0xB8, 0x9B, 0xA9,
        0x02, 0x96, 0xF4, 0x90, 0x18, 0xA7, 0xF5, 0x49,
        0xC1, 0xA3, 0x94, 0xB8, 0xED, 0xBD, 0x0B, 0xF3,
        0xDB, 0xF3, 0xBC, 0x10, 0x6A, 0x6B, 0x3F, 0x79,
        0x07, 0xF2, 0x11, 0x09, 0xD5, 0x42, 0x8F, 0xA9,
        0x09, 0x94, 0xBE, 0xF2, 0x0D, 0x3A, 0x91, 0x33,
        0x01, 0x31, 0x34, 0xBF, 0x0A, 0xCA, 0xF1, 0x3E,
        0x66, 0x18, 0xA6, 0x69, 0xEC, 0xEA, 0xC5, 0xE9,
        0x8B, 0x80, 0xFE, 0x4D, 0x93, 0x7B, 0xD4, 0xE5,
        0x74, 0x90, 0xFA, 0xFD, 0xCE, 0x45, 0xE8, 0xD7,
        0xD8, 0x8F, 0x08, 0x8B, 0x3A, 0xA8, 0x01, 0xA2,
        0xB4, 0xE5, 0xF2, 0x29, 0x41, 0x02, 0xBD, 0xCB,
        0xF9, 0x4A, 0x62, 0x54, 0x99, 0x94, 0x61, 0xB7,
        0x8F, 0xA5, 0x8A, 0x7F, 0xDC, 0xAD, 0xD2, 0xF2,
        0x28, 0x1E, 0xF3, 0x18, 0xAE, 0x21, 0x81, 0xF7,
        0xE9, 0xE5, 0xBF, 0x2B, 0xC2, 0x98, 0x24, 0xB1,
        0x45, 0x56, 0x57, 0x31, 0xA1, 0x48, 0xAB, 0x39,
        0xC2, 0x04, 0x29, 0x1B, 0x5B, 0xD3, 0x23, 0x35,
        0xCC, 0x5A, 0x58, 0x10, 0x11, 0x5B, 0xD5, 0x88,
        0xC2, 0x60, 0x37, 0x3D, 0x1C, 0x1C, 0x7B, 0x09,
        0x95, 0xB5, 0x05, 0x12, 0xD8, 0x52, 0x8D, 0xF5,
        0xBD, 0x4A, 0xA5, 0x45, 0x6F, 0x3D, 0x55, 0x9D,
        0x90, 0xAD, 0xD7, 0xA9, 0xD0, 0x25, 0x0B, 0xD7,
        0x55, 0x11, 0x5C, 0x60, 0xBF, 0xBD, 0xFB, 0x9D,
        0x2A, 0xCE, 0x4F, 0xE6, 0xB8, 0x36, 0x3A, 0x4D,
        0xE7, 0xB6, 0xFF, 0x6B, 0xD8, 0xBA, 0xD4, 0xEE,
        0x95, 0x9A, 0x0A, 0x47, 0xD4, 0x76, 0xE0, 0xF7,
        0xAC, 0x02, 0xB6, 0xA8, 0x10, 0x1E, 0xA5, 0x98,
        0xC0, 0xF4, 0x68, 0x5E, 0x55, 0xC1, 0x67, 0xCD,
        0x16, 0x31, 0xBD, 0xA2, 0x86, 0xF3, 0xF8, 0xC0,
        0xED, 0x4A, 0xFF, 0xE8, 0xF5, 0x2C, 0xFA, 0xD2,
        0x06, 0x78, 0x6D, 0x34, 0xBE, 0xF9, 0x15, 0x84,
        0x6D, 0xE5, 0x5F, 0xA4, 0xAC, 0x84, 0x3B, 0x3A,
        0xA6, 0x2D, 0xC2, 0x01, 0xE0, 0x63, 0x92, 0xC7,
        0x77, 0xB5, 0x4E, 0x2C, 0x40, 0x90, 0x48, 0xAF,
        0x8B, 0xE9, 0x6C, 0x1E, 0xEE, 0x16, 0x8F, 0x4E,
        0x4F, 0xFF, 0x35, 0x15, 0xE5, 0x51, 0xF4, 0xB2,
        0x23, 0x1C, 0x6A, 0xCE, 0x05, 0xDC, 0xDC, 0xAD,
        0x7F, 0x9D, 0xDA, 0xB3, 0x0C, 0xAD, 0x9C, 0x62,
        0x68, 0xD6, 0x84, 0x00, 0x76, 0xFF, 0xD3, 0x01,
        0x18, 0xB0, 0xC4, 0xE5, 0xE5, 0x0D, 0x87, 0x8E,
        0xAF, 0x77, 0xEE, 0xCB, 0x56, 0x88, 0x7F, 0xED,
        0xC5, 0x7C, 0x54, 0xD6, 0x28, 0x46, 0xE0, 0x8C,
        0xE6, 0x87, 0xF2, 0x4D, 0x0D, 0x2F, 0x12, 0x62,
        0x06, 0xDF, 0xB2, 0x4E, 0x03, 0x04, 0x78, 0x0B,
        0x03, 0x4C, 0xCE, 0x86, 0xD1, 0xCD, 0x53, 0x00,
        0xED, 0xC6, 0xF8, 0x9A, 0xCB, 0x59, 0x14, 0xA6,
        0x0C, 0x87, 0x35, 0x92, 0x66, 0x0D, 0x02, 0xA9,
        0xEF, 0x0D, 0x7D, 0xC6, 0x45, 0xF3, 0x11, 0xEF,
        0x1F, 0x55, 0x72, 0x1F, 0x1B, 0x45, 0xD2, 0xE4,
        0x8F, 0x3F, 0x9F, 0xEB, 0x27, 0x02, 0xD8, 0x2C,
        0xEF, 0xAD, 0x7E, 0x7E, 0x10, 0xDD, 0x91, 0x5E,
        0x39, 0x06, 0x7C, 0x39, 0xEA, 0x61, 0xB9, 0xCC,
        0xF1, 0x45, 0x56, 0x81, 0x53, 0x55, 0x42, 0xD4,
        0x37, 0x0F, 0x53, 0xF0, 0x7F, 0xA0, 0xC6, 0x50,
        0x9B, 0x1D, 0xC6, 0x7E, 0x9F, 0x1D, 0x89, 0x3B,
        0xEB, 0x85, 0x59, 0x6D, 0x9C, 0x12, 0xEE, 0xAC,
        0xFC, 0xAE, 0xC0, 0xAE, 0x5F, 0xD4, 0x9C, 0x62,
        0xE7, 0x09, 0x8C, 0xFA, 0x80, 0x1A, 0x19, 0x09,
        0x0F, 0x8D, 0x68, 0x9E, 0x45, 0x33, 0xE2, 0x58,
        0x7B, 0xEF, 0xC7, 0x6A, 0xDC, 0x38, 0x33, 0x3E,
        0x5C, 0x53, 0xB5, 0x99, 0xDB, 0x04, 0xA7, 0xEA,
        0xFB, 0x07, 0x9B, 0x25, 0x47, 0xED, 0xAC, 0x5A,
        0xAA, 0x1E, 0xE5, 0x23, 0xDE, 0x64, 0xE5, 0x87,
        0x46, 0x8C, 0x41, 0x52, 0xC9, 0x4F, 0x90, 0x48,
        0x1C, 0xAA, 0xA6, 0xB0, 0x3A, 0x1E, 0xC9, 0x08,
        0xF7, 0x82, 0x71, 0x13, 0x76, 0x6B, 0x9E, 0x52,
        0x22, 0x32, 0xE0, 0xC6, 0xF7, 0xD7, 0x4C, 0xBD,
        0xC3, 0x1C, 0x18, 0xAF, 0xA0, 0x12, 0xD3, 0x22,
        0x6A, 0xFC, 0x71, 0x8A, 0x64, 0x24, 0xAC, 0x19,
        0x4E, 0x85, 0x3C, 0x51, 0xE6, 0xA3, 0xAD, 0xA9,
        0x59, 0x94, 0xD2, 0x7F, 0xC4, 0x9D, 0x93, 0x5B,
        0x51, 0xD7, 0xF3, 0x03, 0xE7, 0x7D, 0x5B, 0x13,
        0x0E, 0xCD, 0x7D, 0x0F, 0x77, 0x3E, 0x84, 0xD7,
        0x4E, 0x69, 0x57, 0x1B, 0x73, 0x99, 0xC9, 0x4D,
        0xC0, 0x19, 0x6B, 0x9D, 0x5F, 0xBA, 0x69, 0xEE,
        0x11, 0xBD, 0x7C, 0x45, 0xD9, 0xA9, 0x65, 0x88,
        0xA7, 0x0E, 0x16, 0xBF, 0xB3, 0x82, 0x5E, 0x5E,
        0x56, 0x13, 0x02, 0x7D, 0xB1, 0xDC, 0xF5, 0x4A,
        0x82, 0x73, 0x72, 0x35, 0x9B, 0x91, 0xAC, 0x04,
        0x69, 0xE9, 0xEA, 0x19, 0xC9, 0xD8, 0x59, 0xEB,
        0x8F, 0x22, 0x5F, 0x43, 0x11, 0x0C, 0xCF, 0xB4,
        0x16, 0x6C, 0x7D, 0x60, 0xCE, 0x14, 0x24, 0xAD,
        0xD7, 0x07, 0xC2, 0x4E, 0x98, 0xA0, 0xDE, 0x9E,
        0xE6, 0x31, 0xED, 0xF8, 0x5B, 0x9C, 0xAF, 0xF7,
        0x57, 0x59, 0x10, 0xA9, 0x92, 0xDC, 0x4F, 0x0C,
        0x2B, 0x88, 0x75, 0x19, 0x1D, 0xB3, 0xBF, 0x70,
        0x23, 0x17, 0xD5, 0x1A, 0x50, 0x30, 0x18, 0x14,
        0x1A, 0x14, 0xE6, 0x1D, 0x4F, 0x8A, 0x96, 0x3E,
        0xD8, 0x6E, 0xD9, 0xBF, 0x94, 0x4E, 0xDE, 0xB8,
        0xFF, 0xE1, 0x6F, 0xFD, 0x31, 0xE8, 0xFE, 0x43,
        0xC2, 0x40, 0x82, 0x45, 0x50, 0xFE, 0x1B, 0xBC,
        0x77, 0x4B, 0xB4, 0x30, 0xA7, 0xD4, 0x46, 0x32,
        0x6A, 0xF7, 0xC5, 0x92, 0xDA, 0x70, 0xB1, 0xB7,
        0xA1, 0x5A, 0x5D, 0x17, 0x3B, 0xDB, 0x2F, 0x28,
        0x8A, 0x6E, 0xEC, 0xDA, 0xC4, 0xF7, 0x2E, 0xCB,
        0xEB, 0x96, 0x60, 0x92, 0x1B, 0xDD, 0xD6, 0x13,
        0x7C, 0x85, 0x9F, 0x8A, 0x9A, 0xE9, 0x5F, 0xC4,
        0x24, 0xFD, 0x33, 0xDF, 0xB3, 0x98, 0x66, 0xF7,
        0xA1, 0x5A, 0xDC, 0x01, 0xC9, 0xFA, 0x37, 0xF1,
        0x7B, 0xD0, 0xF6, 0x66, 0x8A, 0x26, 0x7C, 0xC2,
        0x1B, 0xFF, 0x62, 0xBC, 0xFD, 0xCD, 0x47, 0xDA,
        0xEE, 0x75, 0xF2, 0xAC, 0x60, 0x69, 0x87, 0x26,
        0xCC, 0x92, 0x10, 0x1C, 0x92, 0xC1, 0x43, 0x09,
        0xE9, 0xCE, 0x7D, 0x05, 0x5C, 0x64, 0x55, 0xCB,
        0xBB, 0x7A, 0xAE, 0x05, 0xDB, 0x38, 0xD3, 0xD5,
        0xBB, 0xD9, 0x9F, 0xCB, 0xCF, 0xB7, 0x9C, 0xEF,
        0x7E, 0x7B, 0x2A, 0x6F, 0x84, 0x4E, 0x6A, 0x7F,
        0xD3, 0x5F, 0xF3, 0xB3, 0xC1, 0xF0, 0x02, 0x9C,
        0xA2, 0x4C, 0x86, 0x0E, 0x6B, 0xE2, 0x2B, 0x1D,
        0x1D, 0xB4, 0x55, 0x7F, 0x85, 0x54, 0x2D, 0x85,
        0x64, 0x89, 0x92, 0x19, 0x65, 0x44, 0xD7, 0x95,
        0x48, 0x2C, 0x46, 0x8D, 0x0E, 0xBA, 0xFB, 0x13,
        0x63, 0x52, 0x2E, 0x22, 0x19, 0x3F, 0x7F, 0xFB,
        0x54, 0x4D, 0x73, 0xA1, 0x3C, 0x22, 0xD6, 0x5D,
        0x2B, 0x4A, 0xBD, 0xD7, 0xBB, 0x72, 0x55, 0x80,
        0xD4, 0x57, 0x4E, 0xDC, 0xF2, 0x8B, 0xB3, 0x09,
        0x6A, 0xF9, 0x1A, 0xD3, 0x41, 0x0E, 0x72, 0x95,
        0x49, 0xE7, 0xD1, 0xDC, 0x05, 0x22, 0xC3, 0x3E,
        0x26, 0x95, 0x00, 0x01, 0x8C, 0xE1, 0x54, 0x47,
        0x84, 0x10, 0xA7, 0x67, 0x45, 0xBB, 0xB9, 0x7B,
        0x0B, 0xB4, 0x74, 0x82, 0xED, 0x6C, 0x26, 0x6E,
        0xF2, 0x56, 0xCA, 0x1A, 0xD1, 0x10, 0x68, 0x40,
        0x28, 0x23, 0xD5, 0x98, 0xB3, 0x6B, 0x75, 0x16,
        0x13, 0x87, 0xE1, 0xF2, 0x3F, 0xAB, 0xC0, 0x2A,
        0xF0, 0x16, 0x59, 0x85, 0x1A, 0x5B, 0x41, 0xB7,
        0x52, 0xB1, 0x79, 0x46, 0x20, 0xDF, 0x59, 0xFB,
        0x33, 0xB3, 0x05, 0xF1, 0x12, 0x8B, 0xDB, 0x7C,
        0x51, 0x90, 0xC9, 0x8A, 0xC9, 0x48, 0x10, 0x54,
        0xF4, 0x0F, 0x88, 0x1D, 0xDB, 0x40, 0x1B, 0x3A,
        0xD7, 0x62, 0xD1, 0x75, 0x73, 0xD6, 0xCA, 0x23,
        0x26, 0xB2, 0xBF, 0x4C, 0xCA, 0x22, 0xDD, 0xF6,
        0xAF, 0x22, 0xB8, 0x4F, 0xC2, 0xC3, 0xB3, 0xD3,
        0xED, 0xFA, 0xBA, 0x2E, 0x38, 0x28, 0x6A, 0xAE,
        0x60, 0xE9, 0x2D, 0x11, 0x33, 0xED, 0x7E, 0xE9,
        0x29, 0x8E, 0x01, 0xB0, 0x0F, 0x13, 0x83, 0x44,
        0x17, 0xFA, 0xB6, 0x54, 0x7C, 0xAC, 0x1F, 0xED,
        0xC9, 0x22, 0xF2, 0x4F, 0x69, 0x24, 0x04, 0xFE,
        0xC2, 0x6A, 0xEB, 0xB0, 0xE4, 0xF5, 0x03, 0xCB,
        0xB3, 0x99, 0x50, 0x66, 0x1F, 0x6B, 0xF3, 0xFE,
        0xB7, 0xBF, 0x8D, 0xBA, 0x59, 0x75, 0x75, 0x51,
        0xB0, 0xA5, 0xB9, 0x66, 0xC8, 0xDD, 0x35, 0xAE,
        0x20, 0x66, 0x21, 0x9B, 0x04, 0x3F, 0xC6, 0x90,
        0x6F, 0x2B, 0x5C, 0x78, 0x49, 0x3C, 0x40, 0xE6,
        0xF9, 0x6B, 0x1A, 0xEF, 0xCE, 0x5A, 0xC1, 0x68,
        0xD3, 0x34, 0x05, 0xD0, 0x21, 0x6C, 0xF8, 0xA8,
        0x55, 0xE4, 0x6E, 0x80, 0x9B, 0xAD, 0xA5, 0xC3,
        0x55, 0x0B, 0x28, 0xBB, 0x54, 0x02, 0xD4, 0xF6,
        0x82, 0x73, 0xAB, 0x56, 0x0B, 0xB1, 0x5F, 0x94,
        0xC3, 0xDA, 0x24, 0x1E, 0x7F, 0x62, 0x6B, 0x98,
        0x6B, 0x2A, 0xF3, 0x92, 0x37, 0x3A, 0xB9, 0xE6,
        0x27, 0xC4, 0xBB, 0xAB, 0xE4, 0x9A, 0x60, 0xD2,
        0xAE, 0xCE, 0xFD, 0x44, 0xEB, 0x1C, 0xCF, 0x74,
        0x54, 0xFC, 0xEC, 0x4F, 0xC2, 0xBA, 0xF4, 0x3B,
        0xAC, 0x03, 0xC7, 0x2E, 0xE6, 0x62, 0x44, 0x61,
        0x42, 0xC8, 0xAE, 0xF1, 0xB2, 0xA9, 0xAC, 0xE0,
        0xCE, 0x23, 0xAF, 0xCC, 0x86, 0x61, 0xFE, 0xC5,
        0xCB, 0xAC, 0x4A, 0x1B, 0x5C, 0xC7, 0x2B, 0xFF,
        0x8A, 0x20, 0x62, 0x0E, 0xB9, 0x1D, 0xDD, 0x93,
        0x19, 0x29, 0xE4, 0xD9, 0x13, 0x1D, 0x28, 0x32,
        0x03, 0x5A, 0xA6, 0x8E, 0x20, 0xC7, 0xD6, 0xC6,
        0x4D, 0x19, 0x17, 0xCC, 0x65, 0xB8, 0x84, 0x0C,
        0x38, 0xB4, 0xA9, 0x45, 0x2B, 0x91, 0x61, 0x79,
        0x87, 0x08, 0xA6, 0xBD, 0x28, 0x9A, 0x58, 0x48,
        0xD5, 0x58, 0xC6, 0xCE, 0xC2, 0xC5, 0x72, 0x16,
        0xD9, 0xF4, 0xED, 0x66, 0xAC, 0xFA, 0x93, 0xE8,
        0x26, 0x10, 0x3B, 0x3D, 0x8F, 0xEA, 0x51, 0xCC,
        0x82, 0xC0, 0xDB, 0xDF, 0xA7, 0x13, 0xFB, 0x1B,
        0x77, 0x7E, 0x6F, 0x9E, 0x3C, 0xC5, 0x86, 0x35,
        0x92, 0x5B, 0x6F, 0x76, 0xA1, 0x71, 0x0D, 0x8C,
        0xDC, 0x95, 0x9F, 0xAC, 0x2C, 0x8E, 0x21, 0x01,
        0x37, 0x06, 0x28, 0x64, 0x4C, 0x23, 0xE2, 0x75,
        0x0B, 0xA7, 0xA4, 0xF5, 0x90, 0x87, 0xD2, 0x43,
        0x71, 0x59, 0x7C, 0x8C, 0xCA, 0x77, 0x3B, 0xC5,
        0x36, 0x46, 0xF7, 0x2F, 0xD3, 0x47, 0x18, 0xD7,
        0xC9, 0x4E, 0x56, 0x2D, 0x49, 0x82, 0xAC, 0x7D,
        0xD7, 0x3D, 0xF1, 0xDD, 0x73, 0x8B, 0xE4, 0xA1,
        0x10, 0x85, 0xB6, 0x94, 0xBE, 0x6A, 0x5E, 0xEE,
        0xBD, 0x60, 0xEB, 0x95, 0x76, 0xA8, 0x52, 0xE1,
        0x47, 0x57, 0xA1, 0x9C, 0xEC, 0x44, 0xE5, 0x6F,
        0x68, 0x34, 0x7E, 0x19, 0xBE, 0xCE, 0x56, 0xC9,
        0xBE, 0xCE, 0xFC, 0xB8, 0x32, 0x6D, 0xCB, 0x84,
        0x59, 0xBF, 0x4D, 0xF6, 0xE1, 0x53, 0x41, 0x61,
        0x5C, 0xFB, 0xD2, 0x48, 0xA6, 0x7F, 0x05, 0xB2,
        0xFC, 0xE8, 0xB2, 0x8A, 0x55, 0x7D, 0x19, 0xC0,
        0x69, 0x3B, 0x91, 0x5D, 0x71, 0xE7, 0xBB, 0x72,
        0x7D, 0xB9, 0x64, 0x6E, 0x8B, 0x5B, 0x70, 0x51,
        0xB5, 0x69, 0x8C, 0xC0, 0xFC, 0x95, 0xB2, 0x43,
        0x08, 0xF8, 0x70, 0xE4, 0x6F, 0x87, 0xA7, 0xDF,
        0x23, 0x84, 0xEE, 0xCF, 0x73, 0x38, 0xDE, 0x99,
        0x4C, 0xF8, 0xF1, 0x2D, 0xA2, 0x68, 0x99, 0xE3,
        0x9B, 0xB8, 0xF6, 0xC1, 0x5C, 0x83, 0x07, 0xE9,
        0xB9, 0xE2, 0x51, 0x62, 0xC8, 0x53, 0xF1, 0xC2,
        0xF7, 0x57, 0x8A, 0xA0, 0x42, 0x3C, 0x18, 0x36,
        0xF3, 0x99, 0xFD, 0x34, 0xB2, 0xF0, 0x1D, 0xBA,
        0x43, 0xEA, 0x72, 0x1C, 0x0B, 0x37, 0x47, 0xBC,
        0xAF, 0xDA, 0x22, 0x1F, 0x1C, 0x08, 0x16, 0x13,
        0xBD, 0xAA, 0x07, 0xFD, 0x7E, 0xCA, 0x70, 0x57,
        0x74, 0xDF, 0x68, 0x6B, 0x9F, 0x2D, 0x56, 0xBD,
        0x21, 0x89, 0xFA, 0x09, 0x04, 0xCA, 0x09, 0xBD,
        0x4F, 0xE6, 0x15, 0xF5, 0x89, 0xAB, 0xAC, 0xB2,
        0xC9, 0xBF, 0xC8, 0xBB, 0x87, 0x83, 0xB4, 0xD3,
        0xDC, 0xB1, 0x25, 0x9B, 0xAE, 0xC5, 0x75, 0x0C,
        0x9E, 0x6A, 0x83, 0x41, 0x85, 0x9D, 0x4B, 0xBF,
        0x62, 0x0C, 0x7D, 0x77, 0xC9, 0x89, 0xA6, 0xE1,
        0x28, 0xBD, 0x13, 0x5D, 0x41, 0x26, 0x80, 0x75,
        0x23, 0x57, 0xE7, 0x4F, 0x4D, 0x02, 0x8E, 0x0F,
        0x43, 0x67, 0xF6, 0xA6, 0xE6, 0xB6, 0x84, 0x8D,
        0xF5, 0x7B, 0x6A, 0x95, 0x73, 0x27, 0x86, 0x02,
        0x72, 0xCB, 0xDF, 0x77, 0x1C, 0x6C, 0x5E, 0xD3,
        0xF0, 0x1C, 0x82, 0x7A, 0x0D, 0xBB, 0x70, 0xA3,
        0x98, 0x8B, 0x7B, 0x4A, 0xFE, 0x2D, 0xB1, 0x5C,
        0x61, 0x89, 0x34, 0x4C, 0x81, 0x4B, 0x52, 0x17,
        0x03, 0x81, 0x54, 0x4F, 0x9E, 0x9E, 0x07, 0x16,
        0xF3, 0xD9, 0x18, 0x01, 0x11, 0xFD, 0x67, 0x18,
        0xA2, 0x64, 0x35, 0x42, 0x81, 0x80, 0x4A, 0xBA,
        0xCB, 0xD5, 0xF5, 0x4A, 0x10, 0x7F, 0xE2, 0xCF,
        0xA5, 0x1E, 0xCB, 0x0C, 0xAB, 0x3E, 0x03, 0x98,
        0x73, 0x89, 0xA4, 0x10, 0x75, 0xD5, 0xAC, 0x3D,
        0xCF, 0x56, 0x75, 0xD8, 0x86, 0xC2, 0x21, 0x42,
        0x99, 0x8D, 0x1B, 0x49, 0x09, 0xFE, 0x86, 0x41,
        0xC9, 0xDC, 0x87, 0x8D, 0x5A, 0xF0, 0xF5, 0xBE,
        0xF5, 0x49, 0x64, 0x5A, 0x7A, 0xC3, 0x5D, 0xE4,
        0xD6, 0xB7, 0x30, 0x92, 0x2A, 0x15, 0x86, 0x02,
        0xBE, 0xBA, 0x6E, 0xF6, 0x3D, 0x2D, 0x70, 0x89,
        0xFB, 0xB5, 0x1E, 0xBA, 0xDA, 0x20, 0x12, 0x49,
        0x22, 0xA0, 0xD8, 0x33, 0x9E, 0x4C, 0xC0, 0x27,
        0x0F, 0x9C, 0x1F, 0xD2, 0xA9, 0xF4, 0xD2, 0xA9,
        0x6D, 0xC5, 0x32, 0x16, 0x35, 0x9F, 0x19, 0x88,
        0xC1, 0xAA, 0xA4, 0x66, 0x33, 0xE6, 0x2C, 0x6A,
        0x6E, 0xA2, 0x1B, 0x33, 0xCB, 0xC3, 0x7E, 0xC5,
        0x31, 0x4D, 0x5C, 0x17, 0x4C, 0x33, 0x7F, 0x09,
        0x01, 0x33, 0x82, 0x84, 0x37, 0x03, 0xEB, 0x0E,
        0xB1, 0x5F, 0x1B, 0x60, 0x8A, 0x2C, 0x9F, 0x39
    };
    static const byte sk_87_draft[] = {
        0x8C, 0x52, 0x4B, 0xD9, 0xAC, 0x48, 0x5C, 0xC6,
        0x9A, 0xA0, 0x75, 0x64, 0xE1, 0x4F, 0x0F, 0x60,
        0x13, 0x0E, 0xDE, 0x34, 0x08, 0xA5, 0xD4, 0x81,
        0xFD, 0x76, 0xC2, 0x51, 0x74, 0x75, 0xA8, 0xFB,
        0x9A, 0xFE, 0xF5, 0x92, 0x58, 0xBB, 0x3C, 0xEB,
        0x4C, 0x5E, 0x83, 0xF9, 0xFF, 0xBC, 0x3B, 0x49,
        0xAE, 0xE1, 0xFC, 0x4B, 0x94, 0x4B, 0x8C, 0x75,
        0xD4, 0x67, 0x75, 0x66, 0x7D, 0x6B, 0xA4, 0xF2,
        0xDA, 0xC2, 0xB7, 0xC4, 0xD8, 0x50, 0x25, 0xCB,
        0x5A, 0xDB, 0xA4, 0xAD, 0xBB, 0x44, 0x20, 0x24,
        0x90, 0xEA, 0xA5, 0x2C, 0xAE, 0x80, 0x22, 0xC9,
        0x59, 0x02, 0xB7, 0x10, 0xB0, 0x5E, 0x1E, 0x5F,
        0x52, 0x7D, 0x88, 0xDA, 0xE2, 0x04, 0xBF, 0x45,
        0xA7, 0xA8, 0x49, 0x97, 0x7D, 0xAD, 0x7C, 0x7C,
        0x9E, 0x9C, 0x4A, 0xCC, 0x36, 0x33, 0x0F, 0x30,
        0xFA, 0xDE, 0x52, 0xE9, 0xAE, 0x23, 0x29, 0x13,
        0x10, 0x17, 0x8A, 0xD0, 0x08, 0x8E, 0xE1, 0x10,
        0x30, 0xD0, 0x84, 0x65, 0x92, 0x12, 0x2A, 0x81,
        0x26, 0x2E, 0x11, 0x14, 0x30, 0x61, 0x38, 0x61,
        0x64, 0x42, 0x05, 0x08, 0x91, 0x90, 0x4C, 0x06,
        0x82, 0xCC, 0x90, 0x45, 0x10, 0x39, 0x90, 0x22,
        0x40, 0x2A, 0x9B, 0x16, 0x26, 0x9A, 0xA8, 0x50,
        0x91, 0x12, 0x70, 0x91, 0x20, 0x4D, 0xC0, 0x34,
        0x90, 0x18, 0x28, 0x31, 0x10, 0x02, 0x11, 0x22,
        0xB3, 0x6C, 0x8B, 0xB8, 0x2C, 0x22, 0xB0, 0x69,
        0x53, 0x36, 0x31, 0x61, 0x42, 0x6C, 0xD9, 0x06,
        0x6A, 0xD9, 0x04, 0x45, 0xDB, 0x18, 0x05, 0x12,
        0x37, 0x4A, 0xD4, 0x06, 0x64, 0xD3, 0xA2, 0x85,
        0xA0, 0x38, 0x8A, 0x14, 0xA5, 0x85, 0x50, 0x20,
        0x85, 0xE4, 0xA8, 0x24, 0xC3, 0xC6, 0x31, 0xC9,
        0x34, 0x4E, 0xD2, 0x14, 0x68, 0x82, 0x90, 0x85,
        0xC4, 0x02, 0x61, 0x24, 0x38, 0x05, 0x01, 0xA3,
        0x50, 0x48, 0x08, 0x62, 0x20, 0xB0, 0x25, 0x5B,
        0xA6, 0x4D, 0x98, 0x92, 0x11, 0xC2, 0x06, 0x00,
        0xD1, 0xB0, 0x4D, 0x21, 0xA4, 0x8C, 0x01, 0x16,
        0x72, 0x11, 0xA6, 0x20, 0xD0, 0x16, 0x45, 0x10,
        0x31, 0x8E, 0xCB, 0xC2, 0x69, 0x02, 0x08, 0x91,
        0xD4, 0x30, 0x89, 0x03, 0x41, 0x05, 0x93, 0x16,
        0x8E, 0x5A, 0x18, 0x04, 0x41, 0x10, 0x6D, 0x18,
        0x42, 0x70, 0x53, 0x16, 0x31, 0x52, 0x30, 0x8E,
        0x0C, 0x49, 0x66, 0x0C, 0x90, 0x0C, 0xA4, 0x08,
        0x2E, 0x41, 0x92, 0x05, 0x24, 0x07, 0x30, 0x12,
        0x46, 0x72, 0x13, 0x99, 0x20, 0xE0, 0xA2, 0x4C,
        0x1B, 0x14, 0x52, 0x5A, 0x90, 0x05, 0x08, 0x82,
        0x31, 0x53, 0xC2, 0x90, 0xCC, 0x42, 0x68, 0x18,
        0xB0, 0x2C, 0x00, 0x80, 0x65, 0x58, 0x12, 0x84,
        0x19, 0x90, 0x08, 0x44, 0x26, 0x4A, 0x10, 0xA9,
        0x0C, 0x12, 0x25, 0x0C, 0x9C, 0x10, 0x25, 0x0C,
        0x28, 0x25, 0xD8, 0x46, 0x84, 0x1A, 0x22, 0x71,
        0x5B, 0x28, 0x6E, 0x98, 0x02, 0x51, 0x61, 0xB4,
        0x51, 0x01, 0xA1, 0x21, 0x24, 0x39, 0x12, 0xC8,
        0x08, 0x85, 0xD1, 0x34, 0x64, 0xA4, 0xA8, 0x04,
        0xA2, 0xC0, 0x09, 0x44, 0x48, 0x48, 0x03, 0x37,
        0x00, 0x20, 0x05, 0x4D, 0x20, 0xA4, 0x05, 0x11,
        0x18, 0x82, 0x42, 0x94, 0x4D, 0x24, 0x16, 0x01,
        0x02, 0x93, 0x4C, 0x00, 0x16, 0x06, 0xC1, 0xC0,
        0x0C, 0x8B, 0xC0, 0x41, 0x41, 0x06, 0x42, 0xA3,
        0xC6, 0x64, 0x1A, 0x85, 0x91, 0x41, 0x06, 0x49,
        0x04, 0xA7, 0x44, 0x82, 0x22, 0x6A, 0x50, 0x08,
        0x0E, 0x14, 0x18, 0x20, 0x4B, 0x88, 0x91, 0x01,
        0xA0, 0x49, 0x1A, 0x85, 0x4D, 0x94, 0x18, 0x10,
        0x0A, 0x05, 0x44, 0x94, 0x38, 0x05, 0x93, 0x40,
        0x68, 0x23, 0x07, 0x85, 0xE2, 0x12, 0x22, 0x9B,
        0xB8, 0x08, 0xD2, 0x10, 0x2A, 0x08, 0xA8, 0x10,
        0x92, 0x40, 0x2D, 0xD8, 0x44, 0x4C, 0xCC, 0x94,
        0x05, 0x24, 0x43, 0x4C, 0xD3, 0xC2, 0x48, 0x10,
        0x21, 0x2D, 0xC9, 0xB6, 0x08, 0xC9, 0x06, 0x4D,
        0xE1, 0x90, 0x20, 0x14, 0x24, 0x70, 0x5C, 0x84,
        0x28, 0xC0, 0xC2, 0x81, 0x22, 0x13, 0x50, 0x44,
        0x84, 0x91, 0xCA, 0xA2, 0x48, 0x12, 0x91, 0x05,
        0x5B, 0x92, 0x8D, 0x92, 0x92, 0x24, 0x82, 0x42,
        0x48, 0x03, 0x37, 0x46, 0xD8, 0x44, 0x86, 0x44,
        0x20, 0x89, 0xE4, 0xC2, 0x84, 0xC2, 0x04, 0x65,
        0x49, 0xA8, 0x4D, 0xA4, 0x38, 0x28, 0xDB, 0xA4,
        0x64, 0x24, 0x00, 0x51, 0xC8, 0x12, 0x6D, 0x19,
        0x82, 0x24, 0xCB, 0x00, 0x44, 0x4B, 0x20, 0x20,
        0x9B, 0x82, 0x4C, 0x5C, 0xA8, 0x08, 0xD2, 0xB6,
        0x8C, 0x08, 0x35, 0x20, 0xC0, 0x92, 0x45, 0xE3,
        0xB4, 0x2C, 0x50, 0x32, 0x0E, 0xD1, 0x82, 0x11,
        0x4A, 0x96, 0x08, 0x1C, 0x86, 0x29, 0x02, 0x19,
        0x71, 0x12, 0x03, 0x6E, 0x94, 0x08, 0x50, 0x12,
        0x27, 0x20, 0x0B, 0x10, 0x12, 0xA1, 0x18, 0x06,
        0x5A, 0x36, 0x4C, 0x93, 0xB4, 0x68, 0x21, 0xA7,
        0x28, 0x09, 0x34, 0x91, 0x18, 0x93, 0x49, 0x4A,
        0x32, 0x60, 0x00, 0x29, 0x2D, 0x94, 0x48, 0x44,
        0x09, 0x94, 0x2C, 0x21, 0x07, 0x6C, 0x41, 0x38,
        0x60, 0x8C, 0x10, 0x46, 0x11, 0x19, 0x65, 0x01,
        0x46, 0x60, 0x1A, 0x29, 0x42, 0x23, 0x30, 0x29,
        0x40, 0x96, 0x85, 0x81, 0xC6, 0x6C, 0x09, 0xA2,
        0x31, 0x23, 0xC9, 0x84, 0x18, 0x27, 0x61, 0x02,
        0xA6, 0x05, 0x1B, 0x11, 0x32, 0xD1, 0x80, 0x24,
        0x59, 0x22, 0x52, 0x21, 0x34, 0x64, 0x0A, 0x21,
        0x52, 0x10, 0xC2, 0x80, 0x5C, 0x98, 0x0D, 0x81,
        0xA0, 0x84, 0x14, 0x97, 0x04, 0xCC, 0xC2, 0x04,
        0x1A, 0x81, 0x45, 0x23, 0x44, 0x6C, 0x13, 0xC0,
        0x44, 0x59, 0xC2, 0x68, 0x64, 0x08, 0x52, 0x51,
        0x30, 0x71, 0x12, 0x49, 0x70, 0x12, 0x94, 0x84,
        0x80, 0x12, 0x12, 0x1B, 0x00, 0x50, 0x84, 0x10,
        0x45, 0x4A, 0x30, 0x10, 0x22, 0x95, 0x49, 0xC9,
        0x82, 0x24, 0x03, 0x35, 0x21, 0x18, 0x16, 0x72,
        0x09, 0x89, 0x65, 0x88, 0xB2, 0x89, 0x41, 0xB4,
        0x90, 0x92, 0x38, 0x8C, 0x08, 0x23, 0x26, 0x0B,
        0x80, 0x61, 0x84, 0x28, 0x6A, 0x4C, 0x98, 0x44,
        0x10, 0xB9, 0x30, 0x93, 0x02, 0x49, 0x22, 0x13,
        0x80, 0x1C, 0xC3, 0x48, 0x50, 0xA8, 0x20, 0x1C,
        0x05, 0x00, 0x5B, 0x02, 0x41, 0xD2, 0x84, 0x61,
        0x4B, 0x40, 0x46, 0x20, 0x21, 0x44, 0xD9, 0xC4,
        0x21, 0xD3, 0xA4, 0x4D, 0xC0, 0xC0, 0x09, 0x5B,
        0x28, 0x91, 0x18, 0x15, 0x41, 0x18, 0xC5, 0x4C,
        0x14, 0xB7, 0x61, 0xDB, 0x34, 0x25, 0x02, 0x06,
        0x41, 0x14, 0xA9, 0x65, 0x0B, 0x10, 0x04, 0x23,
        0xC7, 0x49, 0x13, 0x47, 0x0A, 0xD0, 0x30, 0x80,
        0x99, 0x32, 0x68, 0x50, 0x18, 0x06, 0xA2, 0x28,
        0x65, 0x13, 0x35, 0x82, 0xD3, 0x06, 0x81, 0x22,
        0x49, 0x4D, 0x48, 0x44, 0x30, 0xCA, 0x96, 0x2C,
        0x12, 0xC8, 0x08, 0xA1, 0x24, 0x2C, 0x52, 0xA8,
        0x28, 0x23, 0x14, 0x0A, 0xD4, 0x20, 0x4D, 0x18,
        0x12, 0x72, 0xD4, 0x80, 0x44, 0xDC, 0x26, 0x2C,
        0x88, 0x10, 0x0A, 0x04, 0x14, 0x51, 0xC1, 0x96,
        0x00, 0xA3, 0x40, 0x30, 0x99, 0x48, 0x92, 0x9B,
        0x08, 0x86, 0x81, 0x04, 0x20, 0x4C, 0xB2, 0x29,
        0x18, 0x31, 0x08, 0x09, 0x23, 0x8C, 0x4C, 0x02,
        0x6A, 0xCA, 0x00, 0x62, 0x09, 0x22, 0x2D, 0x21,
        0x00, 0x02, 0x0A, 0x39, 0x41, 0x04, 0xA3, 0x50,
        0x90, 0x80, 0x2D, 0x59, 0xB4, 0x71, 0x13, 0x16,
        0x31, 0x11, 0x90, 0x4C, 0xC3, 0x14, 0x20, 0x60,
        0xB2, 0x30, 0x0A, 0xB6, 0x24, 0x21, 0xA9, 0x10,
        0x89, 0x80, 0x88, 0x44, 0x06, 0x8A, 0x91, 0x22,
        0x8E, 0xD9, 0x36, 0x86, 0x10, 0x46, 0x0A, 0xE1,
        0x16, 0x85, 0x42, 0x40, 0x6C, 0x09, 0x49, 0x11,
        0xE0, 0x88, 0x68, 0x12, 0x08, 0x68, 0x5C, 0x26,
        0x24, 0x04, 0xA8, 0x70, 0xC8, 0x08, 0x05, 0x13,
        0x87, 0x41, 0x23, 0x29, 0x72, 0xC9, 0xB8, 0x88,
        0x1B, 0x22, 0x66, 0x11, 0xA5, 0x2D, 0x11, 0x29,
        0x12, 0x50, 0x12, 0x70, 0x03, 0x09, 0x6A, 0x4B,
        0x88, 0x4C, 0xD2, 0xC8, 0x31, 0x40, 0x26, 0x40,
        0x4C, 0x04, 0x50, 0x58, 0x16, 0x71, 0x90, 0xC2,
        0x00, 0x0A, 0x30, 0x8A, 0xDC, 0x24, 0x85, 0x19,
        0xB0, 0x65, 0x1A, 0xA3, 0x64, 0x13, 0xA3, 0x45,
        0xC8, 0x48, 0x91, 0x91, 0x12, 0x20, 0xDC, 0x42,
        0x40, 0x24, 0xC0, 0x4D, 0xA3, 0x98, 0x10, 0x40,
        0x26, 0x25, 0xDC, 0xB4, 0x68, 0x4B, 0xC2, 0x45,
        0x13, 0x06, 0x91, 0xC8, 0x92, 0x24, 0x82, 0xA8,
        0x20, 0x4C, 0x30, 0x48, 0x52, 0x06, 0x01, 0x0B,
        0x24, 0x51, 0x41, 0x36, 0x40, 0x93, 0xC4, 0x70,
        0x44, 0x40, 0x2C, 0x24, 0x28, 0x22, 0x81, 0xA4,
        0x4C, 0x43, 0x84, 0x60, 0x20, 0x23, 0x90, 0x01,
        0x94, 0x6C, 0xDB, 0x28, 0x21, 0x93, 0x30, 0x80,
        0x93, 0xC0, 0x25, 0xC8, 0xA6, 0x50, 0xCA, 0x24,
        0x26, 0xD1, 0x40, 0x31, 0x04, 0xC4, 0x8D, 0xE2,
        0xC0, 0x04, 0x08, 0x33, 0x8C, 0x18, 0x87, 0x91,
        0xC8, 0xC8, 0x71, 0x40, 0x46, 0x06, 0x00, 0x44,
        0x20, 0x22, 0x49, 0x70, 0x11, 0x45, 0x90, 0x02,
        0xC3, 0x61, 0x60, 0xB4, 0x25, 0x80, 0x16, 0x21,
        0x11, 0x09, 0x04, 0x88, 0x04, 0x05, 0xCC, 0x36,
        0x20, 0x01, 0xB1, 0x2C, 0x64, 0xB6, 0x50, 0x54,
        0x32, 0x42, 0x0B, 0x08, 0x8D, 0x12, 0x39, 0x0D,
        0x10, 0x29, 0x52, 0x88, 0xB0, 0x04, 0x11, 0x38,
        0x44, 0xD2, 0xA6, 0x71, 0x0B, 0x45, 0x48, 0x9C,
        0x34, 0x72, 0xA0, 0x28, 0x49, 0x82, 0x16, 0x86,
        0x12, 0x18, 0x61, 0x04, 0x41, 0x0D, 0x8A, 0xA6,
        0x41, 0x80, 0xA8, 0x61, 0xDA, 0x30, 0x65, 0x82,
        0x84, 0x30, 0x08, 0xA3, 0x29, 0x04, 0x33, 0x8E,
        0x02, 0x24, 0x0D, 0x9C, 0x44, 0x10, 0xC9, 0x02,
        0x81, 0x53, 0x06, 0x66, 0x8B, 0x06, 0x90, 0x03,
        0x87, 0x69, 0x21, 0xC9, 0x69, 0x83, 0x46, 0x4E,
        0x14, 0x24, 0x89, 0x8C, 0xA0, 0x6C, 0x99, 0xA2,
        0x2C, 0x11, 0x37, 0x66, 0x0C, 0xA6, 0x4D, 0xD3,
        0xC8, 0x70, 0x03, 0x02, 0x61, 0xC3, 0xB6, 0x65,
        0x23, 0xC1, 0x6C, 0x10, 0x34, 0x8D, 0x1A, 0xC1,
        0x31, 0x43, 0x40, 0x44, 0xD4, 0x08, 0x02, 0x0A,
        0x36, 0x20, 0xE3, 0x26, 0x42, 0x0A, 0x48, 0x26,
        0x1A, 0x13, 0x44, 0x0C, 0x18, 0x61, 0x91, 0x96,
        0x84, 0x02, 0x17, 0x46, 0x9C, 0x20, 0x40, 0x41,
        0xC6, 0x2D, 0x1B, 0x16, 0x0C, 0x98, 0xB2, 0x90,
        0x1A, 0x20, 0x84, 0xE2, 0x34, 0x2D, 0xCB, 0x14,
        0x44, 0x93, 0xC6, 0x8D, 0x58, 0xB2, 0x69, 0x22,
        0xB2, 0x88, 0xC0, 0xB8, 0x2D, 0xA2, 0xC2, 0x31,
        0x20, 0xA3, 0x24, 0x11, 0x46, 0x48, 0x4A, 0xA6,
        0x50, 0x24, 0x09, 0x21, 0x1A, 0x01, 0x0D, 0x20,
        0x36, 0x01, 0xC4, 0x34, 0x70, 0xDA, 0x16, 0x68,
        0x84, 0x22, 0x4C, 0x11, 0x14, 0x09, 0x13, 0xC4,
        0x68, 0x11, 0x41, 0x2D, 0x1C, 0x10, 0x31, 0xDC,
        0xB2, 0x64, 0x42, 0x36, 0x08, 0x5C, 0x10, 0x88,
        0x04, 0x91, 0x25, 0xE1, 0xA0, 0x20, 0x14, 0x18,
        0x12, 0x14, 0x94, 0x91, 0x4C, 0xC2, 0x24, 0xD4,
        0x06, 0x71, 0x21, 0x02, 0x8D, 0xD4, 0x88, 0x30,
        0xC9, 0x36, 0x0E, 0xE4, 0x82, 0x81, 0xC0, 0x04,
        0x6D, 0x24, 0x23, 0x09, 0x21, 0x45, 0x45, 0x20,
        0x06, 0x65, 0xC2, 0x30, 0x2A, 0x18, 0x30, 0x8E,
        0x24, 0x83, 0x89, 0x93, 0x32, 0x66, 0xC1, 0x48,
        0x45, 0x62, 0x48, 0x0A, 0x52, 0xB8, 0x80, 0x11,
        0x86, 0x21, 0x04, 0x34, 0x11, 0x24, 0xB5, 0x6C,
        0x50, 0x36, 0x0A, 0x19, 0xA7, 0x8C, 0x14, 0x90,
        0x0D, 0x1A, 0xA5, 0x68, 0x0B, 0xB1, 0x11, 0x50,
        0x40, 0x08, 0x48, 0xB6, 0x31, 0x14, 0x28, 0x8D,
        0xE3, 0x47, 0xB4, 0xA1, 0x44, 0x94, 0xCC, 0x9F,
        0x0B, 0x94, 0x9F, 0x25, 0x49, 0xD9, 0xB3, 0x8F,
        0x71, 0xF4, 0x17, 0xA4, 0xA6, 0xAC, 0x24, 0x58,
        0x14, 0x25, 0x03, 0xC8, 0x63, 0x3E, 0x10, 0xA8,
        0xD4, 0x10, 0xD7, 0x90, 0x4A, 0x28, 0x37, 0x90,
        0x70, 0x27, 0xE3, 0x56, 0x5F, 0x04, 0x67, 0x76,
        0xC3, 0x67, 0x3F, 0xF5, 0xA5, 0x11, 0xA2, 0x2C,
        0x11, 0x01, 0x5D, 0x63, 0x71, 0x1A, 0xE6, 0x70,
        0x86, 0x46, 0xAB, 0xCE, 0x03, 0xB6, 0x82, 0xAF,
        0x51, 0xBA, 0x81, 0x94, 0x9C, 0x82, 0x36, 0xA9,
        0x49, 0xA5, 0xA3, 0x11, 0x08, 0x8C, 0x4B, 0x13,
        0x41, 0xF0, 0x08, 0xFD, 0xB2, 0x99, 0xED, 0xA8,
        0x07, 0x61, 0x3C, 0x2E, 0xBC, 0x49, 0x7B, 0x1C,
        0xBC, 0x87, 0xBC, 0xAE, 0x5F, 0x5E, 0x8F, 0x5D,
        0xE7, 0xB9, 0x0C, 0x70, 0x36, 0x25, 0x61, 0xFD,
        0x95, 0x9F, 0xAE, 0x0F, 0x8D, 0xF3, 0xA2, 0x45,
        0x24, 0xA7, 0xDE, 0x60, 0xD1, 0x4E, 0x6D, 0xAC,
        0xC7, 0x6A, 0x32, 0x42, 0xC0, 0x73, 0xEB, 0x78,
        0x50, 0xF4, 0x49, 0x52, 0x5E, 0x6F, 0x81, 0x42,
        0x54, 0xF8, 0x82, 0x05, 0xC9, 0x64, 0x74, 0x6A,
        0x60, 0x5E, 0x36, 0x59, 0x40, 0x50, 0xA3, 0xFE,
        0xDA, 0xE2, 0x6D, 0x8D, 0x6E, 0xE4, 0x5A, 0x27,
        0x73, 0x89, 0xDB, 0x0C, 0x5B, 0x14, 0xD9, 0xED,
        0xB2, 0xC7, 0x1D, 0x71, 0x93, 0x91, 0x0A, 0x72,
        0x32, 0xBE, 0xA3, 0xD8, 0x95, 0x8C, 0x94, 0x7E,
        0x63, 0xEB, 0xCE, 0x8B, 0xFC, 0xB0, 0x3F, 0x77,
        0x5C, 0x43, 0x48, 0x18, 0x83, 0xFE, 0xC8, 0xDA,
        0x89, 0xF2, 0x3B, 0x54, 0x82, 0x44, 0xC6, 0x9C,
        0xCC, 0x77, 0x0A, 0xC1, 0x6F, 0xB9, 0x98, 0x10,
        0xD5, 0xF2, 0x60, 0xFF, 0x38, 0xD2, 0x0D, 0xD6,
        0x8C, 0x38, 0x54, 0x5B, 0xD8, 0x38, 0x84, 0x50,
        0x36, 0xF4, 0x02, 0xC1, 0x06, 0x0F, 0x15, 0x1B,
        0xC8, 0x90, 0x9B, 0x6E, 0x36, 0xC8, 0x3F, 0xE9,
        0x8B, 0x62, 0x15, 0x6F, 0xF0, 0xC2, 0x86, 0x7F,
        0xD1, 0xB5, 0x97, 0x53, 0xAE, 0x41, 0xAE, 0x21,
        0x84, 0xAC, 0x57, 0xA5, 0x1F, 0xA7, 0xC7, 0x24,
        0xDF, 0xDE, 0x2F, 0x3C, 0xCD, 0xA2, 0x7E, 0x1D,
        0x97, 0xE1, 0x96, 0xC5, 0xB4, 0x7D, 0xF9, 0x5F,
        0x7E, 0xEF, 0x09, 0xC4, 0xF3, 0x57, 0xF0, 0x51,
        0x73, 0xAB, 0x0E, 0x6A, 0xCA, 0x64, 0xE4, 0x99,
        0x0F, 0xD2, 0x20, 0xAC, 0x72, 0xF1, 0xA8, 0x23,
        0x8F, 0x94, 0x63, 0xDC, 0xB3, 0xBB, 0x62, 0x2C,
        0xEA, 0xA6, 0x27, 0x5A, 0x93, 0xC6, 0xCD, 0xCE,
        0x1E, 0x09, 0xAF, 0x89, 0xEC, 0x22, 0xE4, 0x30,
        0x2D, 0xB9, 0xCD, 0x08, 0x2E, 0x12, 0x76, 0x79,
        0x99, 0xBC, 0xA0, 0x34, 0x0B, 0xDA, 0x89, 0x08,
        0x14, 0x60, 0x7B, 0x98, 0xE6, 0xAF, 0xD2, 0xE1,
        0x87, 0xC8, 0xDA, 0x50, 0xF7, 0x10, 0x2C, 0x72,
        0x74, 0x50, 0xD0, 0x3C, 0x98, 0x06, 0xFE, 0xEB,
        0xC6, 0xC5, 0x69, 0x31, 0x06, 0xE2, 0x2E, 0x7E,
        0x7D, 0x3D, 0x2B, 0x1F, 0x48, 0x43, 0xC5, 0x95,
        0xDA, 0x84, 0x08, 0x1E, 0x2B, 0x50, 0x6D, 0x91,
        0xA6, 0x2B, 0xCD, 0x08, 0x43, 0x7B, 0xA2, 0xD8,
        0x60, 0x6E, 0xF7, 0x80, 0x08, 0xC3, 0x3F, 0x35,
        0xF3, 0x70, 0xA5, 0xC7, 0x56, 0xFC, 0xBD, 0x34,
        0x46, 0x7B, 0xBF, 0x63, 0x19, 0xAC, 0xB6, 0xC3,
        0x1B, 0x81, 0x84, 0x9F, 0xBB, 0x54, 0x05, 0x99,
        0xAE, 0x43, 0xE2, 0xA5, 0x20, 0xFD, 0x5C, 0xC7,
        0x25, 0x47, 0xB1, 0xFD, 0x80, 0xB5, 0x78, 0xC2,
        0x00, 0x98, 0x02, 0xB9, 0x61, 0x2A, 0xBA, 0x39,
        0xC7, 0x20, 0xB8, 0x7D, 0x7A, 0x03, 0x68, 0xE5,
        0x37, 0x71, 0x1F, 0x72, 0xAA, 0x41, 0x61, 0xB4,
        0xC0, 0xC2, 0xD3, 0x7A, 0xCD, 0xD2, 0xED, 0xC2,
        0xC5, 0x99, 0x8C, 0x62, 0xA3, 0x7D, 0xC8, 0x9C,
        0xD2, 0x50, 0x02, 0x0D, 0xCB, 0x68, 0x15, 0xB0,
        0xD6, 0x19, 0x03, 0xC8, 0x01, 0x12, 0x72, 0xA1,
        0x3A, 0xC2, 0xA6, 0x63, 0x51, 0x26, 0x03, 0x5D,
        0x3F, 0x1D, 0x3B, 0x0E, 0x30, 0x6B, 0xB7, 0xEC,
        0xB6, 0x8E, 0x2D, 0x76, 0xC8, 0xD7, 0xAE, 0x59,
        0x81, 0xFC, 0x5F, 0x57, 0x5E, 0xAD, 0xA0, 0x20,
        0xC8, 0xB4, 0x91, 0x2D, 0xEC, 0x03, 0xC4, 0xC6,
        0x55, 0x05, 0x87, 0xA4, 0xA2, 0x21, 0x09, 0x25,
        0x97, 0x21, 0xA4, 0x46, 0x45, 0x46, 0x40, 0x3B,
        0xDC, 0x6F, 0xCD, 0xFB, 0xFB, 0xD9, 0xF4, 0x2C,
        0xEC, 0xF1, 0xC4, 0x73, 0x41, 0x30, 0x60, 0x63,
        0x9A, 0xF2, 0xA5, 0x26, 0x78, 0x9A, 0x5E, 0x70,
        0x98, 0xDE, 0x35, 0x10, 0xA0, 0x5D, 0x45, 0xD5,
        0x95, 0xF7, 0x11, 0xBC, 0x99, 0xD3, 0x00, 0x67,
        0x9A, 0x30, 0x85, 0x36, 0x50, 0xDB, 0x18, 0xEA,
        0x6D, 0xB2, 0xF3, 0x14, 0xDA, 0x23, 0xE2, 0x8A,
        0x44, 0x21, 0x25, 0xD4, 0xA3, 0x28, 0x43, 0xA0,
        0xC6, 0x5C, 0x99, 0xB0, 0x72, 0x6B, 0xC2, 0x1A,
        0x30, 0xBE, 0x6B, 0x7B, 0xE0, 0x31, 0x54, 0x8C,
        0x29, 0xE5, 0xC6, 0x69, 0x53, 0xDE, 0x05, 0x1E,
        0x43, 0xCC, 0x7E, 0x9A, 0x82, 0x4A, 0xC4, 0x0A,
        0x50, 0x65, 0xDC, 0xD8, 0xF9, 0x01, 0x32, 0x65,
        0x1E, 0xF9, 0xA4, 0xCC, 0x07, 0xB9, 0x55, 0x97,
        0x45, 0xA9, 0x61, 0xF8, 0xBE, 0x99, 0x00, 0x12,
        0xD8, 0x17, 0x62, 0xFB, 0x89, 0xE7, 0x05, 0x5E,
        0x1B, 0xCD, 0x2B, 0x09, 0x6C, 0x5A, 0x5C, 0xA3,
        0x66, 0x4D, 0x02, 0x78, 0x0C, 0xC3, 0x63, 0x30,
        0xD0, 0xFA, 0x7B, 0x11, 0x00, 0x40, 0xDD, 0xF0,
        0x8C, 0x7C, 0xBA, 0x4C, 0x63, 0x78, 0xDA, 0xBB,
        0xDF, 0xF9, 0xC9, 0xA4, 0x40, 0x25, 0x86, 0xD1,
        0xBA, 0x22, 0xD7, 0x69, 0x98, 0x4E, 0x9D, 0x15,
        0x21, 0xA8, 0x56, 0xC0, 0xFF, 0x52, 0xE4, 0xB4,
        0x0F, 0xB2, 0x53, 0xE7, 0xA1, 0x34, 0x18, 0xEA,
        0x5B, 0x25, 0x42, 0x13, 0xE3, 0x13, 0xE7, 0xDF,
        0x54, 0x2B, 0x8D, 0x70, 0x51, 0xC7, 0x60, 0xB1,
        0x1E, 0x4D, 0x3A, 0x46, 0x04, 0xA1, 0x11, 0x43,
        0xAD, 0x24, 0x29, 0x90, 0xC9, 0x04, 0x15, 0xC5,
        0x07, 0xE5, 0x46, 0xB8, 0x50, 0x16, 0x6B, 0x66,
        0xFE, 0x1C, 0x8B, 0xFC, 0x20, 0x9C, 0xC4, 0x88,
        0x10, 0x36, 0x5E, 0x56, 0xE8, 0x45, 0x75, 0x89,
        0xFB, 0xD6, 0xD0, 0x8D, 0x9D, 0x53, 0xAE, 0x89,
        0x19, 0x54, 0xCF, 0xE1, 0xFF, 0x12, 0x13, 0xF2,
        0xC7, 0xBE, 0x4C, 0x1E, 0xB0, 0x70, 0x6E, 0xDC,
        0x0A, 0x64, 0x3B, 0x60, 0x3A, 0xEA, 0x0D, 0x41,
        0xDD, 0x8E, 0x09, 0xB9, 0x96, 0x8F, 0x6A, 0x49,
        0x50, 0xEF, 0xDF, 0xD7, 0x73, 0x8D, 0x16, 0x32,
        0xA8, 0x5C, 0x0A, 0x90, 0x18, 0xA1, 0xEB, 0x19,
        0xCC, 0x50, 0xD5, 0x59, 0xD7, 0x35, 0x3F, 0xBA,
        0x38, 0x1B, 0x5F, 0x71, 0x56, 0x70, 0xB3, 0x20,
        0x4D, 0x9E, 0x16, 0xA8, 0xF7, 0x35, 0x19, 0xD2,
        0x09, 0x0A, 0x22, 0x28, 0x81, 0x61, 0x26, 0x5B,
        0x9C, 0xEC, 0x9D, 0x4A, 0x61, 0xCF, 0x0D, 0x3C,
        0x88, 0xEA, 0x0B, 0x7A, 0xA7, 0xC6, 0xAE, 0x31,
        0xBE, 0xC2, 0xBA, 0x48, 0xBB, 0x9D, 0x06, 0xE1,
        0x32, 0x6D, 0x80, 0xCE, 0x27, 0x5C, 0x6F, 0x13,
        0x79, 0x35, 0x9F, 0x9C, 0x11, 0xEA, 0xDB, 0xF5,
        0x49, 0x15, 0xB6, 0x51, 0x86, 0xFC, 0x62, 0x34,
        0x3D, 0x58, 0x6B, 0x0E, 0xF8, 0x3B, 0xBB, 0x42,
        0xF6, 0x2D, 0x5C, 0xE2, 0xF3, 0xAA, 0x9F, 0x03,
        0x43, 0xE9, 0x9E, 0x90, 0xB9, 0xFF, 0x55, 0x93,
        0x60, 0xF8, 0x10, 0x2F, 0xFC, 0xBD, 0x40, 0x23,
        0xB8, 0x4F, 0x4C, 0x7A, 0x74, 0x9F, 0xDC, 0x55,
        0xDF, 0x5E, 0xCD, 0x23, 0xEB, 0xAC, 0x47, 0x4E,
        0x0D, 0x0F, 0xBE, 0xDE, 0x02, 0x64, 0x61, 0x7E,
        0x73, 0x78, 0x8E, 0x25, 0xE9, 0x7D, 0x66, 0xE5,
        0x82, 0xBF, 0x98, 0x5B, 0x36, 0xCE, 0x17, 0x72,
        0x56, 0x9C, 0xDA, 0x63, 0x77, 0x55, 0x8B, 0xA9,
        0x75, 0xF5, 0x28, 0xC3, 0x78, 0x6D, 0x8F, 0xC2,
        0x75, 0x5F, 0x28, 0x9E, 0x3F, 0xFB, 0xF1, 0xFD,
        0xB7, 0xDE, 0x05, 0x3C, 0xD3, 0xE8, 0xD7, 0x7A,
        0x7D, 0xC9, 0xF7, 0x9D, 0x58, 0xB4, 0xA6, 0x21,
        0x25, 0xFC, 0x52, 0x84, 0x21, 0xF6, 0x0B, 0x6D,
        0xA6, 0x62, 0x51, 0x97, 0xCD, 0xA9, 0xA1, 0x0C,
        0x88, 0x21, 0x67, 0xA5, 0xFB, 0x8C, 0x8A, 0x50,
        0xC5, 0x21, 0x91, 0x3A, 0xAB, 0x95, 0x96, 0xF3,
        0x30, 0x6D, 0x08, 0x42, 0x07, 0x4B, 0x78, 0x1F,
        0xC1, 0xD3, 0x41, 0x15, 0x68, 0xED, 0x93, 0x09,
        0xC7, 0x8B, 0xF9, 0x77, 0x25, 0xD3, 0xCE, 0x2B,
        0xA2, 0x0D, 0xB4, 0xC6, 0x84, 0x7F, 0x8E, 0xE5,
        0x24, 0x46, 0x59, 0x8D, 0x6F, 0x0F, 0x0C, 0xA8,
        0xFC, 0x04, 0x9B, 0x4D, 0x2B, 0xA7, 0x70, 0x1F,
        0x46, 0x7E, 0x76, 0x03, 0xC6, 0x7E, 0xA5, 0x3D,
        0x79, 0xE2, 0xF1, 0xAC, 0xBC, 0xDD, 0xF6, 0x91,
        0x69, 0x4C, 0x44, 0x1F, 0xC3, 0xBF, 0x9F, 0xFC,
        0x4E, 0xB0, 0x79, 0x30, 0x68, 0x89, 0xAC, 0xF2,
        0xD7, 0xC6, 0xE1, 0x6C, 0x37, 0xFB, 0xB3, 0x38,
        0x44, 0x2C, 0x97, 0xAB, 0xDA, 0x2C, 0x88, 0xC7,
        0xF2, 0x80, 0x08, 0x00, 0x4E, 0x44, 0xED, 0xBE,
        0xA4, 0x28, 0x3D, 0xC1, 0xCF, 0x9E, 0x83, 0xE7,
        0x2E, 0x7F, 0xF5, 0x08, 0x47, 0x26, 0xE0, 0xBD,
        0x1A, 0x17, 0xDB, 0x2F, 0xED, 0x19, 0x2E, 0x65,
        0x1B, 0x62, 0x5F, 0x08, 0x82, 0x10, 0x61, 0xCB,
        0xAA, 0xA7, 0xF8, 0x59, 0x4B, 0x46, 0xCB, 0xA2,
        0xCB, 0x41, 0x34, 0x30, 0x51, 0x58, 0x2A, 0xEE,
        0xE1, 0x5E, 0xAC, 0xCA, 0xBF, 0x37, 0x45, 0x98,
        0xBD, 0x93, 0x1B, 0x5A, 0x5E, 0x92, 0x14, 0x05,
        0x75, 0x2D, 0xFB, 0x8F, 0xBD, 0x24, 0x9B, 0x81,
        0xCD, 0xDD, 0xF5, 0xBE, 0x05, 0x0D, 0xBD, 0x4B,
        0x2B, 0x8C, 0x0A, 0xF0, 0x3A, 0x85, 0xD6, 0x74,
        0x65, 0x7F, 0x98, 0xF8, 0x57, 0xA2, 0x36, 0xA2,
        0xFE, 0xE4, 0xB4, 0xA4, 0x0D, 0xEA, 0x9A, 0xBE,
        0x41, 0x79, 0x68, 0x63, 0x70, 0x3F, 0x3E, 0x38,
        0x60, 0xC3, 0x40, 0x81, 0x72, 0xDD, 0x25, 0x34,
        0xB4, 0xFE, 0xAC, 0x41, 0x6E, 0x4A, 0xE7, 0xBF,
        0xE3, 0x87, 0xFA, 0x20, 0x8B, 0xBD, 0x68, 0x9E,
        0x06, 0xA9, 0x15, 0x23, 0x07, 0x04, 0x4B, 0xFA,
        0x45, 0x45, 0xB7, 0x75, 0xD3, 0x3E, 0x16, 0x70,
        0xF6, 0x26, 0xF2, 0x3A, 0x9D, 0xFB, 0xEA, 0xEB,
        0x47, 0xCE, 0x99, 0x6B, 0x0E, 0xB2, 0xE8, 0x2B,
        0x18, 0x15, 0x14, 0x2E, 0xF2, 0x14, 0x0D, 0x44,
        0x47, 0x1E, 0x63, 0x84, 0x5B, 0x3F, 0xA8, 0xEF,
        0x5F, 0xEB, 0xA0, 0x41, 0x77, 0xC1, 0xF4, 0x4F,
        0x8E, 0x2E, 0x29, 0xCD, 0xDB, 0xF2, 0x75, 0x24,
        0x24, 0x46, 0x73, 0xC3, 0x46, 0xB5, 0xCA, 0x13,
        0x35, 0x12, 0x0A, 0x8D, 0x88, 0x89, 0x17, 0x99,
        0x13, 0xCA, 0x66, 0x07, 0x67, 0x6B, 0x7B, 0x3B,
        0x20, 0xD3, 0x5F, 0x78, 0x1C, 0xC0, 0x99, 0x59,
        0x0A, 0xBA, 0x8F, 0xA0, 0xDB, 0xDF, 0xCC, 0x03,
        0xC4, 0xA6, 0xC7, 0x08, 0xB9, 0xFD, 0x95, 0xC2,
        0x45, 0xF9, 0xF3, 0x11, 0x62, 0xF7, 0x14, 0xB9,
        0xEB, 0x09, 0xB3, 0x7C, 0xF8, 0xF6, 0x67, 0xCC,
        0x03, 0xB3, 0x06, 0x6F, 0x60, 0xAC, 0x72, 0xF2,
        0xD3, 0x71, 0x6C, 0x4D, 0xAD, 0x3A, 0x99, 0x75,
        0x5C, 0x52, 0x2D, 0x87, 0x69, 0x3E, 0xD6, 0x7E,
        0x12, 0x96, 0xD3, 0x88, 0x8D, 0x11, 0x85, 0xAA,
        0x0A, 0xA5, 0x32, 0x90, 0x51, 0xC5, 0x65, 0x64,
        0xE0, 0xA9, 0x73, 0xA4, 0xF3, 0x8A, 0x32, 0x83,
        0xE5, 0x08, 0x09, 0x39, 0x6A, 0x90, 0x2C, 0xC3,
        0xFC, 0x92, 0x29, 0x7A, 0x45, 0xBE, 0x02, 0x79,
        0x15, 0x1B, 0xBB, 0x60, 0xBB, 0xD9, 0x42, 0xF1,
        0xE5, 0x14, 0xB4, 0xA5, 0xFF, 0x12, 0x42, 0x30,
        0xB0, 0xCB, 0xD0, 0x1D, 0xB4, 0x62, 0x49, 0xC5,
        0xB7, 0xDA, 0x37, 0x47, 0x2C, 0x8B, 0x16, 0xCA,
        0xD2, 0x2C, 0xA1, 0x24, 0xE6, 0x57, 0xFA, 0xEB,
        0x2C, 0x62, 0x2E, 0x12, 0x74, 0x37, 0x2B, 0x3F,
        0x56, 0x23, 0x9C, 0xED, 0x90, 0xDE, 0x0D, 0x6E,
        0x9E, 0x11, 0x78, 0xA4, 0x9C, 0xB3, 0xA1, 0x37,
        0xF7, 0x4B, 0x09, 0x61, 0xD8, 0x33, 0x1D, 0x80,
        0x68, 0x5C, 0xDD, 0xBD, 0x3E, 0xAE, 0x9D, 0xB8,
        0xBA, 0x42, 0x41, 0xDC, 0xC9, 0x93, 0xF1, 0x92,
        0x2F, 0x7A, 0xF9, 0xFE, 0x67, 0x13, 0x87, 0xBD,
        0x7D, 0x04, 0x17, 0x91, 0xB6, 0x03, 0x5E, 0xA0,
        0x5B, 0x23, 0xEA, 0x0C, 0xFA, 0x45, 0xCB, 0x1A,
        0xC5, 0x7F, 0x63, 0xD6, 0x3D, 0x3C, 0x66, 0x4A,
        0x83, 0x4E, 0x4E, 0x90, 0xA6, 0x63, 0xB0, 0x8A,
        0xD7, 0x0D, 0xB4, 0xB7, 0xA9, 0x0F, 0xC6, 0xC7,
        0x3B, 0xAD, 0x07, 0xA6, 0x94, 0x47, 0xDB, 0x63,
        0x26, 0x00, 0x18, 0x5E, 0x27, 0xB5, 0xE2, 0xE3,
        0xED, 0x8D, 0x97, 0x95, 0x38, 0x20, 0x24, 0x9F,
        0x40, 0x84, 0x44, 0x7E, 0x8C, 0x05, 0xAB, 0xB1,
        0x89, 0x26, 0x7D, 0x46, 0x2C, 0x9F, 0xE5, 0xC1,
        0x27, 0xCE, 0x1D, 0x5A, 0x9F, 0xF1, 0xF8, 0x57,
        0x8F, 0xCF, 0xB7, 0x4E, 0x07, 0xF3, 0xBA, 0x56,
        0xCF, 0xE9, 0x87, 0x21, 0x61, 0xD6, 0x97, 0x7B,
        0x26, 0x97, 0x07, 0xB4, 0x87, 0xFE, 0x25, 0x9C,
        0xA9, 0x8E, 0x06, 0x90, 0x17, 0x2C, 0x98, 0x26,
        0x23, 0xEE, 0xBB, 0x91, 0x8A, 0x15, 0x38, 0xA1,
        0x38, 0xCB, 0x8B, 0xA0, 0xF3, 0x4A, 0xF2, 0x12,
        0xA7, 0xB7, 0x05, 0xB6, 0x09, 0xD0, 0xEC, 0xDD,
        0x21, 0xB6, 0xFA, 0x29, 0x95, 0xB4, 0x08, 0xD5,
        0x95, 0xB7, 0xB8, 0x2E, 0x23, 0xAA, 0x89, 0x81,
        0xE2, 0xD0, 0xFD, 0x9C, 0x8D, 0xF0, 0xCA, 0x61,
        0xE3, 0x1E, 0x73, 0x9E, 0xD1, 0x72, 0x5C, 0x63,
        0xB8, 0x74, 0x0E, 0x2C, 0x27, 0x3A, 0x71, 0xF9,
        0xFE, 0x66, 0x33, 0xE9, 0x41, 0x27, 0x61, 0xA3,
        0xFA, 0xD8, 0x66, 0x2A, 0x52, 0x6D, 0xAB, 0xBF,
        0x32, 0xC2, 0x8E, 0x8F, 0xB0, 0x60, 0x52, 0xE1,
        0x96, 0xC8, 0x1E, 0x9A, 0x3E, 0x07, 0xFA, 0x34,
        0xFA, 0x9C, 0x4C, 0x0D, 0x29, 0x0F, 0x68, 0xA6,
        0x59, 0x28, 0x22, 0xB1, 0x99, 0x56, 0x2C, 0x01,
        0x04, 0x2F, 0x34, 0x65, 0xFD, 0xD4, 0xD0, 0xD5,
        0x17, 0x7C, 0x14, 0x92, 0x73, 0x6C, 0x31, 0xCE,
        0xD4, 0xB3, 0x59, 0x83, 0x6B, 0x34, 0x7C, 0x76,
        0x8C, 0xED, 0xD5, 0xE2, 0x4F, 0x39, 0x44, 0xBF,
        0x90, 0x53, 0x9A, 0xC7, 0xD4, 0x6A, 0x86, 0xA3,
        0xE2, 0x15, 0x59, 0xD0, 0x0F, 0x32, 0x92, 0xC2,
        0x9B, 0x9E, 0xE3, 0xF6, 0x94, 0x96, 0xFD, 0x0B,
        0xB6, 0x06, 0x8F, 0x0D, 0x1F, 0x38, 0xFC, 0x6F,
        0xA2, 0x78, 0xAC, 0xC5, 0xB5, 0x6A, 0x6B, 0xEC,
        0x78, 0x8A, 0x6F, 0xD8, 0x21, 0xB7, 0xCF, 0x66,
        0x73, 0x03, 0xCA, 0x2E, 0x3C, 0x7F, 0x2F, 0x29,
        0x41, 0xC9, 0x88, 0xFD, 0x0E, 0xA0, 0x43, 0xD6,
        0x9E, 0xB1, 0xE7, 0x13, 0x9C, 0xF0, 0x9C, 0xCF,
        0x33, 0x22, 0x57, 0xEF, 0xE5, 0xCE, 0xD9, 0xAC,
        0x7D, 0x34, 0x75, 0xBD, 0xAE, 0x84, 0xEE, 0xE8,
        0x5D, 0x8C, 0x55, 0x86, 0xBA, 0x19, 0xE5, 0x9D,
        0x35, 0x6D, 0xD8, 0x70, 0xC5, 0xE0, 0xEA, 0x77,
        0x3A, 0xE5, 0xB5, 0x2C, 0xD2, 0x28, 0xB5, 0xE8,
        0xAF, 0xB1, 0xD2, 0xC4, 0xE5, 0x59, 0x06, 0xB8,
        0x2E, 0xA6, 0x8F, 0xC4, 0x9B, 0x30, 0xF9, 0x37,
        0xDB, 0x29, 0xA1, 0x44, 0x0B, 0xB7, 0xB5, 0xB4,
        0x12, 0xD3, 0x4E, 0xB3, 0xB7, 0xD8, 0x2F, 0x19,
        0xDE, 0x3B, 0xC3, 0x53, 0xCE, 0x1C, 0x34, 0x4C,
        0xA4, 0x6A, 0xE2, 0xD0, 0x04, 0xDF, 0x3C, 0x53,
        0x8B, 0x06, 0x8F, 0x36, 0xE5, 0x77, 0xB2, 0x7A,
        0x1A, 0xC0, 0x0C, 0xBD, 0xA3, 0xA0, 0xEE, 0xB6,
        0x40, 0xAD, 0x5C, 0x04, 0xAE, 0xCF, 0x64, 0x2B,
        0x8A, 0x18, 0x58, 0x86, 0xDE, 0xC9, 0x3D, 0x7D,
        0x15, 0xBC, 0xEE, 0x4C, 0x22, 0xF4, 0x98, 0xD9,
        0x37, 0xEE, 0xE2, 0x40, 0x43, 0xFF, 0xB2, 0x6F,
        0x05, 0xC0, 0x0E, 0x30, 0xDE, 0xD8, 0x0C, 0x0B,
        0xAD, 0xED, 0xCC, 0xBC, 0x29, 0x95, 0x07, 0x40,
        0x10, 0x99, 0xA0, 0xD1, 0x08, 0xF7, 0xD5, 0xF1,
        0xAD, 0xC9, 0xDD, 0xC8, 0x6A, 0x1E, 0x9E, 0x06,
        0xDF, 0x12, 0xFF, 0x66, 0x33, 0x5E, 0x21, 0x47,
        0xC3, 0xDE, 0x36, 0x98, 0x5B, 0xBF, 0x42, 0x9E,
        0x30, 0xA0, 0x81, 0x5C, 0x28, 0x34, 0x1B, 0x3A,
        0x32, 0xBC, 0xDE, 0x52, 0x53, 0x25, 0x1E, 0xF6,
        0xE2, 0x99, 0x12, 0x92, 0x07, 0x1D, 0xEB, 0x08,
        0x36, 0xA7, 0xD5, 0x18, 0x1F, 0xDB, 0x44, 0xA7,
        0xE1, 0x13, 0x06, 0xB0, 0xDF, 0x63, 0x82, 0x68,
        0xEF, 0xF5, 0x2B, 0x04, 0x0B, 0x93, 0xE8, 0xB0,
        0x92, 0x7B, 0xDE, 0x1F, 0xC9, 0x39, 0x8F, 0x42,
        0x9D, 0x06, 0x22, 0x13, 0xC9, 0x97, 0x2F, 0x43,
        0x8A, 0xBA, 0xAF, 0xF9, 0x71, 0xE3, 0x55, 0x5D,
        0x06, 0x77, 0x38, 0x39, 0xA3, 0xED, 0x41, 0x63,
        0xFE, 0x2A, 0xB3, 0x23, 0x43, 0x0C, 0xF3, 0x17,
        0x3B, 0x69, 0xED, 0x32, 0x0A, 0x54, 0xF3, 0x8D,
        0x76, 0xC6, 0x09, 0xDD, 0x88, 0x5B, 0x23, 0x57,
        0x72, 0xC4, 0x87, 0xB8, 0x9D, 0xF7, 0xCA, 0xFB,
        0x7C, 0x61, 0x67, 0x5C, 0x65, 0xF8, 0xD6, 0xD7,
        0x1E, 0x95, 0xB9, 0x73, 0x4D, 0x2E, 0x1F, 0x43,
        0x3E, 0x2B, 0x58, 0x92, 0x15, 0x2E, 0xAA, 0x51,
        0xF0, 0xD4, 0xF2, 0xA6, 0xCD, 0x12, 0x21, 0xD6,
        0xCA, 0x46, 0x2A, 0xFF, 0xCB, 0x1B, 0x6B, 0xB4,
        0x09, 0x17, 0x3B, 0xA2, 0x94, 0xDF, 0x1D, 0x68,
        0x8B, 0x75, 0xEA, 0x11, 0xD6, 0x99, 0x04, 0xD1,
        0x00, 0xDB, 0x61, 0xBC, 0xF2, 0x3B, 0x88, 0x4B,
        0x33, 0xDF, 0x0F, 0xD4, 0xFB, 0x14, 0x0C, 0x6A,
        0x53, 0x61, 0x1F, 0xBD, 0x28, 0xB2, 0x11, 0x19,
        0x38, 0x71, 0x17, 0x76, 0x4D, 0xEE, 0x01, 0xC4,
        0x77, 0x53, 0x2A, 0xAF, 0xD3, 0x78, 0xFF, 0x45,
        0x7F, 0x97, 0x9D, 0x26, 0x92, 0x0E, 0xD9, 0x4E,
        0x34, 0x1D, 0xE8, 0xDD, 0xBF, 0x5F, 0x87, 0xE6,
        0x35, 0x9A, 0x39, 0x71, 0x59, 0x20, 0x01, 0xFB,
        0x53, 0x2C, 0x61, 0x38, 0x0C, 0x8C, 0x02, 0xD3,
        0xA0, 0x53, 0x95, 0x02, 0xED, 0x5C, 0xFE, 0x9B,
        0xD3, 0x6A, 0xF3, 0x3F, 0x92, 0x6F, 0x33, 0x37,
        0x19, 0x97, 0x81, 0x3A, 0x50, 0xE1, 0xD9, 0x27,
        0x7E, 0x64, 0xF8, 0x01, 0x52, 0x26, 0x51, 0xD1,
        0x06, 0xAF, 0x20, 0xA0, 0x28, 0x0F, 0x3F, 0xCB,
        0x21, 0xB7, 0x55, 0x1A, 0x76, 0xB8, 0x9B, 0x4D,
        0xED, 0x2A, 0x05, 0x0E, 0x6E, 0xAF, 0xCC, 0xA1,
        0x08, 0x9C, 0xBE, 0x3F, 0x98, 0xE6, 0xB4, 0xB9,
        0x83, 0xC9, 0x08, 0x41, 0x96, 0xDD, 0xD9, 0x0D,
        0x52, 0x66, 0x94, 0xA4, 0xEA, 0xFC, 0xE5, 0x48,
        0x04, 0x73, 0x64, 0x79, 0x68, 0xC9, 0x4A, 0x81,
        0xA8, 0x07, 0xF8, 0xD9, 0x4E, 0x07, 0x1E, 0xC1,
        0x8F, 0x62, 0xAB, 0xA6, 0xD7, 0x68, 0xFC, 0x57,
        0x5E, 0x75, 0x1B, 0xBF, 0x3D, 0xA6, 0x91, 0xC5,
        0x08, 0x14, 0x5E, 0xF2, 0x4C, 0x22, 0x8B, 0x4E,
        0x29, 0x2D, 0xC0, 0x46, 0x3A, 0x9C, 0x9D, 0x86,
        0xCF, 0x51, 0x85, 0x9D, 0x93, 0x23, 0xA1, 0xA1,
        0xF3, 0x76, 0xB1, 0x56, 0xB0, 0xF4, 0x1F, 0x39,
        0xDA, 0xDB, 0x13, 0x70, 0x29, 0x89, 0x95, 0xD2,
        0xC5, 0xF3, 0x76, 0xFE, 0xEE, 0x99, 0xCF, 0xA0,
        0x84, 0xEC, 0x70, 0xF0, 0xD3, 0xFA, 0x42, 0xDB,
        0xFD, 0x99, 0x65, 0x2F, 0x84, 0x11, 0x99, 0xCD,
        0x38, 0xB3, 0x1B, 0xAB, 0x8C, 0x2D, 0x33, 0x04,
        0xCA, 0xE1, 0xB3, 0x05, 0x9A, 0x20, 0x80, 0xDB,
        0xED, 0x59, 0x42, 0x30, 0x48, 0x37, 0xB3, 0x85,
        0x5C, 0xEE, 0x54, 0x06, 0x92, 0x97, 0x4E, 0xFC,
        0xFA, 0xF7, 0x25, 0xE0, 0x4E, 0x57, 0xC4, 0x72,
        0x38, 0x59, 0xCA, 0x3C, 0x4A, 0x3F, 0x09, 0xD6,
        0x09, 0x15, 0x83, 0xEF, 0x24, 0x21, 0xDD, 0xFD,
        0x66, 0x9E, 0xBF, 0xEE, 0xCC, 0xBF, 0x86, 0x20,
        0x29, 0x40, 0x5E, 0x42, 0xD2, 0xC0, 0x24, 0x2D,
        0x76, 0xE6, 0x64, 0xF9, 0x5D, 0xC2, 0x85, 0xB6,
        0x09, 0x41, 0x04, 0x62, 0x17, 0xDC, 0xF8, 0xFA,
        0x2A, 0x4C, 0xD1, 0x82, 0x31, 0x57, 0xB7, 0x2B,
        0x49, 0xE8, 0x40, 0x13, 0x2A, 0xA1, 0x86, 0xD2,
        0x9A, 0xB8, 0xA9, 0xBE, 0x39, 0xBE, 0xE9, 0xA5,
        0x35, 0x12, 0x08, 0xF1, 0xA9, 0x9E, 0x57, 0x46,
        0x3A, 0x55, 0x16, 0xA7, 0x41, 0xD9, 0x25, 0xB8,
        0x2F, 0xAF, 0xA8, 0x81, 0x5F, 0x5F, 0x46, 0xA4,
        0x3B, 0xB3, 0xE9, 0x1B, 0x74, 0xEF, 0x5D, 0x57,
        0x48, 0x4A, 0x72, 0x08, 0xDA, 0xFE, 0x1D, 0x55,
        0x6B, 0xAB, 0x8B, 0x13, 0x18, 0xBF, 0xDD, 0xF4,
        0x4E, 0x01, 0x5F, 0x4B, 0xF6, 0x80, 0xD4, 0x16,
        0x4B, 0x2F, 0x03, 0x4B, 0xF8, 0x93, 0x20, 0x21,
        0x55, 0x52, 0x49, 0x4A, 0x6C, 0x1F, 0x7D, 0xAD,
        0x04, 0xEF, 0xB3, 0x74, 0xEE, 0xC5, 0xB6, 0xBC,
        0x33, 0x7A, 0xCF, 0x64, 0xB9, 0xF9, 0x41, 0x70,
        0xAF, 0xE9, 0xC7, 0xD6, 0x25, 0x18, 0x17, 0xAB,
        0xBA, 0xC9, 0x05, 0xEF, 0x40, 0x89, 0xD5, 0x69,
        0x76, 0xAA, 0xA0, 0x3E, 0x4D, 0x1C, 0xE7, 0x9D,
        0x9E, 0x74, 0xF4, 0xF2, 0x7B, 0x40, 0xF6, 0x57,
        0x78, 0x66, 0xFC, 0xDA, 0xE3, 0x6B, 0xD2, 0x6E,
        0xC7, 0x9D, 0x65, 0x84, 0xAF, 0x7A, 0x1F, 0xE4,
        0x34, 0xD4, 0x1A, 0x17, 0xA2, 0x72, 0xB0, 0xEE,
        0x5A, 0x0C, 0xF4, 0x02, 0xAC, 0x1D, 0x6F, 0x4A,
        0xD0, 0xB2, 0x02, 0x3A, 0x7D, 0x2C, 0xF1, 0x43,
        0x0E, 0x1E, 0x96, 0xEB, 0x42, 0xF8, 0x3A, 0xF5,
        0x0B, 0x5D, 0xA9, 0x23, 0x02, 0x28, 0xE5, 0x26,
        0x5E, 0x69, 0x38, 0x2F, 0x85, 0x34, 0x32, 0x5E,
        0x5E, 0x29, 0x33, 0x94, 0x05, 0xBD, 0x58, 0xF8,
        0xE8, 0x9C, 0xBF, 0xB1, 0x5A, 0x05, 0xC6, 0x23,
        0x9B, 0xBB, 0x57, 0x69, 0x8C, 0xE6, 0x41, 0x97,
        0x48, 0x01, 0x95, 0xAF, 0xE9, 0x62, 0x8C, 0x6F,
        0x09, 0x43, 0xF3, 0x64, 0x50, 0x90, 0x2F, 0x14,
        0xF7, 0x30, 0x07, 0xE0, 0x4B, 0xA8, 0x39, 0xAC,
        0x21, 0xC4, 0x07, 0x45, 0x5F, 0xD9, 0x87, 0xB1,
        0x57, 0x47, 0x07, 0x66, 0xFF, 0xC7, 0xAB, 0xEE,
        0x1F, 0x55, 0x71, 0x50, 0x63, 0xCF, 0x58, 0x3B,
        0xC8, 0x1B, 0xEA, 0xA5, 0xE2, 0xF1, 0x57, 0xB3,
        0x77, 0x65, 0xA9, 0xBD, 0x23, 0xC8, 0x30, 0x86,
        0xC3, 0x5F, 0xBF, 0x16, 0x3F, 0x42, 0x28, 0x0A,
        0xC6, 0x5A, 0x57, 0x15, 0x2F, 0xA1, 0x96, 0xA9,
        0x25, 0xC5, 0x8E, 0x32, 0x11, 0x62, 0xB3, 0x54,
        0x18, 0x00, 0xA4, 0xA6, 0xD4, 0x0F, 0x68, 0x27,
        0x8F, 0x21, 0x78, 0x02, 0x37, 0x98, 0xBD, 0xCE,
        0x3F, 0xBC, 0xF2, 0x9C, 0x66, 0x8E, 0x79, 0xA1,
        0x54, 0x12, 0x55, 0x2E, 0xC0, 0x59, 0xC7, 0x18,
        0x18, 0x22, 0x4D, 0x27, 0x8B, 0x8D, 0xF3, 0x08,
        0x99, 0xE6, 0x35, 0x14, 0xB1, 0xE3, 0xB8, 0x7A,
        0x40, 0x7B, 0x68, 0x7B, 0xFF, 0xDC, 0x54, 0x41,
        0x06, 0xCA, 0x91, 0xFE, 0xDB, 0x2B, 0xDA, 0x9E,
        0xC5, 0x20, 0xD8, 0xBF, 0x42, 0xBC, 0xE6, 0x39,
        0xC4, 0x26, 0x9E, 0xF3, 0x82, 0xD9, 0xF1, 0xA0,
        0x04, 0xAF, 0xFB, 0x77, 0x13, 0x36, 0xAF, 0xD7,
        0x91, 0x9B, 0x3A, 0x57, 0x98, 0xFE, 0xAD, 0xCD,
        0x46, 0xF8, 0xF8, 0xF1, 0x87, 0x53, 0xBD, 0x57,
        0x3F, 0x99, 0xBC, 0xA6, 0xBD, 0x9B, 0x6E, 0xF4,
        0x17, 0x7A, 0x78, 0x30, 0x70, 0xA3, 0x43, 0xFF,
        0x92, 0xCD, 0x99, 0x73, 0xAE, 0x65, 0x6A, 0x10,
        0xFF, 0x70, 0x47, 0x0F, 0x16, 0x4C, 0x4A, 0x90,
        0xF4, 0x52, 0x05, 0x79, 0x33, 0x63, 0xDE, 0x14,
        0x65, 0xAF, 0x8A, 0x5E, 0x67, 0x20, 0x03, 0x9F,
        0xE6, 0x70, 0x13, 0x6B, 0xE0, 0xF3, 0x6A, 0x4C,
        0x6B, 0x5B, 0xCB, 0xE1, 0x7C, 0x5D, 0x7D, 0xE3,
        0x23, 0xFD, 0xB8, 0x6A, 0xDA, 0x56, 0x1E, 0xA8,
        0x36, 0xC4, 0x29, 0x2D, 0x70, 0x41, 0x03, 0x18,
        0x31, 0x40, 0x79, 0x2E, 0xC8, 0x22, 0x98, 0x5E,
        0x11, 0xED, 0xA6, 0xDD, 0xB9, 0xAF, 0x8C, 0x27,
        0x5C, 0x1B, 0x2E, 0xEA, 0xB8, 0xC6, 0x2F, 0xA0,
        0x40, 0xB2, 0x64, 0x61, 0xFC, 0x0A, 0x3A, 0x10,
        0x88, 0xC2, 0x58, 0xEC, 0xA5, 0x8D, 0x14, 0xE9,
        0x9D, 0x21, 0xAF, 0x64, 0xD6, 0xC2, 0x5D, 0xAA,
        0x0B, 0x8A, 0x57, 0x0F, 0x84, 0x3E, 0x60, 0x8D,
        0xED, 0x05, 0x1D, 0x98, 0xED, 0xAE, 0x11, 0xD9,
        0x27, 0x03, 0x55, 0xED, 0xF5, 0x34, 0x92, 0x52,
        0xF2, 0x6F, 0x30, 0x3E, 0x69, 0xA5, 0x54, 0xA7,
        0x2E, 0x1B, 0x85, 0xAB, 0xA2, 0x3B, 0xEC, 0xC8,
        0x9D, 0xA9, 0xA3, 0xE4, 0xEF, 0x58, 0xB5, 0x33,
        0x88, 0x55, 0x16, 0x5E, 0x7D, 0x7E, 0x69, 0xFC,
        0xCA, 0xBD, 0x9C, 0x65, 0xFA, 0x0B, 0xBD, 0x7B,
        0x16, 0xC4, 0xE2, 0x9C, 0xB4, 0xF1, 0x6A, 0x25,
        0x70, 0x30, 0x32, 0xED, 0xEA, 0xD3, 0x1D, 0xDB,
        0x6F, 0x29, 0x2E, 0x42, 0x14, 0xBE, 0x03, 0x29,
        0x0A, 0x8A, 0x98, 0x9A, 0xD7, 0xB7, 0x0C, 0xF8,
        0xB9, 0xCF, 0x37, 0xC6, 0xAC, 0xAC, 0x6D, 0xCC,
        0x03, 0x23, 0x9F, 0x66, 0x85, 0x4B, 0x70, 0x45
    };
#endif /* WOLFSSL_NO_ML_DSA_87 */
#endif

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }

    ExpectIntEQ(wc_dilithium_init_ex(key, NULL, INVALID_DEVID), 0);
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
    ExpectIntEQ(wc_dilithium_make_key_from_seed(key, seed_44), 0);
    ExpectIntEQ(XMEMCMP(key->p, pk_44, sizeof(pk_44)), 0);
    ExpectIntEQ(XMEMCMP(key->k, sk_44, sizeof(sk_44)), 0);
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44_DRAFT), 0);
    ExpectIntEQ(wc_dilithium_make_key_from_seed(key, seed_44_draft), 0);
    ExpectIntEQ(XMEMCMP(key->p, pk_44_draft, sizeof(pk_44_draft)), 0);
    ExpectIntEQ(XMEMCMP(key->k, sk_44_draft, sizeof(sk_44_draft)), 0);
#endif
#endif
#ifndef WOLFSSL_NO_ML_DSA_65
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
    ExpectIntEQ(wc_dilithium_make_key_from_seed(key, seed_65), 0);
    ExpectIntEQ(XMEMCMP(key->p, pk_65, sizeof(pk_65)), 0);
    ExpectIntEQ(XMEMCMP(key->k, sk_65, sizeof(sk_65)), 0);
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65_DRAFT), 0);
    ExpectIntEQ(wc_dilithium_make_key_from_seed(key, seed_65_draft), 0);
    ExpectIntEQ(XMEMCMP(key->p, pk_65_draft, sizeof(pk_65_draft)), 0);
    ExpectIntEQ(XMEMCMP(key->k, sk_65_draft, sizeof(sk_65_draft)), 0);
#endif
#endif
#ifndef WOLFSSL_NO_ML_DSA_87
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
    ExpectIntEQ(wc_dilithium_make_key_from_seed(key, seed_87), 0);
    ExpectIntEQ(XMEMCMP(key->p, pk_87, sizeof(pk_87)), 0);
    ExpectIntEQ(XMEMCMP(key->k, sk_87, sizeof(sk_87)), 0);
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87_DRAFT), 0);
    ExpectIntEQ(wc_dilithium_make_key_from_seed(key, seed_87_draft), 0);
    ExpectIntEQ(XMEMCMP(key->p, pk_87_draft, sizeof(pk_87_draft)), 0);
    ExpectIntEQ(XMEMCMP(key->k, sk_87_draft, sizeof(sk_87_draft)), 0);
#endif
#endif

    wc_dilithium_free(key);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_dilithium_sig_kats(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    !defined(WOLFSSL_DILITHIUM_NO_SIGN)
    dilithium_key* key;
#ifndef WOLFSSL_NO_ML_DSA_44
    static const byte sk_44[] = {
        0x5D, 0xFB, 0x07, 0xA2, 0x04, 0x4B, 0x93, 0x16,
        0x75, 0xC7, 0x89, 0x43, 0xEA, 0xC3, 0xC4, 0xC5,
        0x7B, 0x07, 0x77, 0x8A, 0xD9, 0xAF, 0x2E, 0x87,
        0xC4, 0x70, 0xB9, 0xCC, 0x2C, 0x8D, 0xA1, 0xE3,
        0x75, 0xBC, 0xB3, 0xBC, 0xD1, 0x9E, 0x7B, 0xB9,
        0x83, 0xC9, 0x63, 0x66, 0xCC, 0xEA, 0x14, 0x1E,
        0xAE, 0x22, 0x07, 0x75, 0x52, 0x24, 0xC8, 0xC6,
        0xC6, 0x1F, 0x90, 0x89, 0x89, 0xCF, 0xF2, 0xF6,
        0x27, 0x98, 0xA6, 0x86, 0x45, 0x77, 0x95, 0x15,
        0xD4, 0x74, 0xDD, 0xA6, 0x1F, 0x33, 0x41, 0x42,
        0x4E, 0xDA, 0x24, 0x79, 0x60, 0x27, 0x34, 0x4E,
        0x36, 0x94, 0x14, 0x74, 0x81, 0x9A, 0x58, 0x44,
        0x2B, 0x74, 0xBF, 0x50, 0x60, 0xB8, 0x40, 0x94,
        0x4A, 0xEF, 0xDE, 0xA7, 0xA4, 0xCF, 0xFC, 0xB3,
        0x9D, 0xE2, 0x07, 0xFD, 0x9E, 0x6A, 0xC6, 0x2E,
        0x6D, 0x0D, 0xB2, 0xB4, 0x51, 0x2E, 0x20, 0x26,
        0x00, 0xB5, 0x30, 0x01, 0xA9, 0x2D, 0xE2, 0x42,
        0x02, 0x42, 0x12, 0x71, 0x24, 0xB7, 0x28, 0x94,
        0x30, 0x86, 0xDA, 0x22, 0x30, 0x00, 0x87, 0x65,
        0xCC, 0x22, 0x91, 0x1B, 0x05, 0x82, 0x03, 0x46,
        0x8A, 0xA0, 0x32, 0x26, 0x40, 0xB4, 0x84, 0xC3,
        0x14, 0x2D, 0x88, 0x14, 0x8C, 0x94, 0x92, 0x49,
        0x23, 0x15, 0x0E, 0xCA, 0x88, 0x09, 0x18, 0x94,
        0x68, 0x82, 0x38, 0x00, 0x21, 0x41, 0x28, 0x8C,
        0xB8, 0x80, 0x02, 0x09, 0x49, 0x5A, 0xB4, 0x11,
        0x9B, 0x28, 0x05, 0xE4, 0x42, 0x30, 0xCA, 0x24,
        0x80, 0xA4, 0x06, 0x2A, 0xD3, 0x92, 0x05, 0x1C,
        0x03, 0x6A, 0x22, 0x36, 0x4A, 0x92, 0x44, 0x52,
        0xE2, 0x48, 0x28, 0x19, 0x83, 0x68, 0x88, 0xC6,
        0x31, 0x41, 0x90, 0x50, 0x00, 0x43, 0x8E, 0x23,
        0x87, 0x60, 0x19, 0x43, 0x81, 0x50, 0x32, 0x69,
        0x81, 0xC0, 0x51, 0x12, 0x06, 0x08, 0x02, 0x08,
        0x82, 0xC4, 0xA6, 0x81, 0x03, 0xA5, 0x90, 0x8C,
        0xB6, 0x00, 0x90, 0x14, 0x66, 0x01, 0xB1, 0x08,
        0x12, 0x25, 0x48, 0x1A, 0x88, 0x11, 0x43, 0x38,
        0x60, 0x23, 0x26, 0x2E, 0x14, 0x45, 0x0D, 0x9C,
        0x92, 0x8C, 0xA2, 0x46, 0x12, 0x94, 0xA6, 0x05,
        0x88, 0xB0, 0x11, 0x0A, 0xB0, 0x28, 0xA4, 0x42,
        0x09, 0x9C, 0x82, 0x80, 0x1A, 0x80, 0x61, 0x59,
        0xB0, 0x8D, 0x40, 0xA6, 0x6D, 0x12, 0xC9, 0x0C,
        0xD9, 0x18, 0x68, 0xA3, 0x84, 0x2C, 0x02, 0xB6,
        0x25, 0x01, 0x40, 0x2C, 0xD8, 0x20, 0x4D, 0x1B,
        0x35, 0x30, 0x11, 0x10, 0x49, 0x63, 0x44, 0x31,
        0x8A, 0xB2, 0x70, 0x4B, 0x24, 0x28, 0xA0, 0x46,
        0x08, 0xC9, 0x06, 0x81, 0x08, 0xC5, 0x04, 0x4A,
        0xB2, 0x30, 0x08, 0x15, 0x04, 0x24, 0xA2, 0x65,
        0x9B, 0x88, 0x41, 0x19, 0x36, 0x2E, 0xE2, 0xB8,
        0x29, 0xD9, 0x12, 0x64, 0x41, 0xA6, 0x30, 0x22,
        0xB7, 0x8C, 0x93, 0x38, 0x69, 0x93, 0x30, 0x0A,
        0xC8, 0xB6, 0x85, 0x23, 0xB1, 0x8D, 0x01, 0x38,
        0x0A, 0x59, 0xA0, 0x09, 0x64, 0x12, 0x6E, 0x88,
        0x08, 0x22, 0xDB, 0x00, 0x08, 0x0C, 0x08, 0x12,
        0x99, 0x42, 0x44, 0x1B, 0x00, 0x68, 0x08, 0x13,
        0x26, 0x53, 0xA2, 0x40, 0x5A, 0x34, 0x25, 0x98,
        0x90, 0x8C, 0x00, 0x34, 0x2D, 0x93, 0x94, 0x48,
        0xC8, 0x22, 0x4C, 0xE2, 0x44, 0x29, 0xE2, 0x00,
        0x28, 0x14, 0x22, 0x40, 0x48, 0x28, 0x24, 0x22,
        0x49, 0x06, 0xCA, 0xC8, 0x0C, 0x4C, 0x12, 0x80,
        0x1B, 0xA5, 0x41, 0x11, 0x06, 0x48, 0x1B, 0x27,
        0x72, 0x20, 0x07, 0x31, 0x24, 0x10, 0x8E, 0x9C,
        0x94, 0x91, 0x1B, 0x37, 0x82, 0x51, 0x28, 0x2E,
        0x11, 0x06, 0x42, 0x01, 0x34, 0x6E, 0x8C, 0x22,
        0x25, 0x24, 0x34, 0x6A, 0x19, 0x47, 0x21, 0x23,
        0xB6, 0x09, 0x51, 0xB2, 0x31, 0x18, 0x34, 0x45,
        0x8C, 0xB8, 0x20, 0x1C, 0x19, 0x0A, 0x19, 0xB7,
        0x6D, 0x18, 0x97, 0x48, 0x09, 0x82, 0x04, 0x9C,
        0x12, 0x8A, 0x41, 0x08, 0x46, 0x24, 0x13, 0x31,
        0xD0, 0x42, 0x46, 0xC3, 0x16, 0x80, 0x51, 0x10,
        0x2E, 0x51, 0x48, 0x04, 0x5C, 0xC2, 0x64, 0x1A,
        0x10, 0x8E, 0xD9, 0x86, 0x64, 0x90, 0x24, 0x68,
        0x93, 0xB4, 0x45, 0x94, 0x30, 0x4A, 0xE3, 0x12,
        0x0C, 0x54, 0x04, 0x90, 0x03, 0x31, 0x40, 0x62,
        0x92, 0x4D, 0x5C, 0xC8, 0x10, 0x8A, 0xB8, 0x61,
        0x5C, 0x04, 0x6A, 0xC8, 0xB0, 0x85, 0x93, 0x00,
        0x05, 0xC3, 0x06, 0x69, 0x1B, 0x34, 0x8E, 0x03,
        0x84, 0x0C, 0x50, 0x00, 0x2C, 0x8C, 0x96, 0x90,
        0x08, 0x32, 0x68, 0x0B, 0x90, 0x8C, 0x02, 0x86,
        0x2D, 0x18, 0x38, 0x09, 0x1C, 0xB2, 0x21, 0x1B,
        0x48, 0x04, 0x5C, 0x10, 0x86, 0xD8, 0x34, 0x51,
        0x43, 0x84, 0x88, 0x43, 0xB2, 0x65, 0x12, 0xB6,
        0x8D, 0x03, 0x01, 0x45, 0x19, 0xB8, 0x8D, 0x92,
        0x26, 0x4E, 0x12, 0x12, 0x88, 0x52, 0xB2, 0x64,
        0x21, 0x09, 0x26, 0x49, 0x38, 0x05, 0x24, 0x11,
        0x0A, 0x22, 0x38, 0x32, 0x23, 0x31, 0x20, 0x4A,
        0x24, 0x42, 0xC4, 0xA2, 0x44, 0x20, 0x10, 0x0D,
        0xA1, 0xA8, 0x51, 0x23, 0x86, 0x84, 0x81, 0x38,
        0x8E, 0x02, 0x00, 0x4A, 0x1C, 0xB7, 0x24, 0x4C,
        0x06, 0x0A, 0x1C, 0x26, 0x4E, 0xCC, 0x22, 0x48,
        0x4C, 0x92, 0x2D, 0xC0, 0x20, 0x2D, 0xA1, 0x16,
        0x89, 0xC3, 0x44, 0x82, 0x19, 0xA7, 0x6D, 0xC4,
        0x90, 0x10, 0x01, 0x82, 0x89, 0xD8, 0x44, 0x22,
        0xD9, 0x98, 0x20, 0xC0, 0x88, 0x45, 0x88, 0x22,
        0x0C, 0x90, 0x36, 0x90, 0x90, 0xA4, 0x05, 0xD3,
        0x82, 0x21, 0xD0, 0xA6, 0x28, 0x00, 0x33, 0x25,
        0xA2, 0xC2, 0x6C, 0xD8, 0x10, 0x71, 0xD1, 0x96,
        0x50, 0xC3, 0x34, 0x08, 0x8B, 0x94, 0x2D, 0x61,
        0x88, 0x04, 0x1B, 0xC8, 0x2D, 0xE2, 0x30, 0x64,
        0x20, 0x28, 0x24, 0x1A, 0x34, 0x50, 0x10, 0x25,
        0x6A, 0x64, 0x36, 0x81, 0x09, 0xC1, 0x45, 0xE3,
        0x30, 0x80, 0xC3, 0xA6, 0x8C, 0xE0, 0xB6, 0x10,
        0xC3, 0x34, 0x8D, 0xD1, 0x06, 0x11, 0x88, 0x20,
        0x0A, 0x0A, 0xC8, 0x21, 0x20, 0x81, 0x30, 0x9C,
        0x14, 0x61, 0x9B, 0xC2, 0x50, 0x22, 0x15, 0x8D,
        0x80, 0xA0, 0x41, 0x89, 0x24, 0x41, 0x20, 0x93,
        0x40, 0x01, 0xA6, 0x09, 0x08, 0x25, 0x2E, 0xC1,
        0xC6, 0x85, 0x00, 0x17, 0x62, 0x41, 0x30, 0x32,
        0xDC, 0x06, 0x6D, 0x48, 0x88, 0x08, 0x84, 0xC8,
        0x30, 0x5B, 0x96, 0x8D, 0x42, 0xB4, 0x4C, 0xD0,
        0x34, 0x88, 0xD0, 0x04, 0x02, 0x18, 0x15, 0x52,
        0x52, 0x26, 0x30, 0x8C, 0x46, 0x28, 0x20, 0x94,
        0x4C, 0x21, 0x18, 0x00, 0xD0, 0xB2, 0x48, 0x1B,
        0x17, 0x0A, 0x09, 0x30, 0x4C, 0x44, 0xC2, 0x04,
        0x47, 0x5E, 0xF2, 0x33, 0x31, 0xFF, 0x66, 0x73,
        0xE2, 0x6E, 0x6A, 0x32, 0xF2, 0x94, 0xBE, 0xFB,
        0xD5, 0x96, 0x4F, 0xED, 0x98, 0x7A, 0x42, 0xA2,
        0x35, 0xFC, 0x5B, 0x16, 0x08, 0x61, 0x45, 0xC0,
        0xB8, 0xA8, 0x23, 0xFB, 0xC1, 0x4F, 0x1C, 0x8C,
        0xD0, 0x3F, 0xD6, 0xEE, 0xC4, 0x95, 0x28, 0x3E,
        0x03, 0x5C, 0x0D, 0xCA, 0xE5, 0x2E, 0x68, 0xF3,
        0x29, 0xDE, 0x7A, 0xDF, 0xD6, 0x4F, 0xEE, 0x0B,
        0x11, 0x6D, 0x4A, 0x14, 0xE1, 0x53, 0x94, 0xB3,
        0x1D, 0xF8, 0x8B, 0xCA, 0x10, 0xD1, 0xC9, 0x06,
        0xAA, 0x82, 0x28, 0x7C, 0x11, 0x74, 0x99, 0xE9,
        0xD8, 0xC7, 0x7D, 0x17, 0xA9, 0x5C, 0xCC, 0x14,
        0xAF, 0xF9, 0xC2, 0x05, 0xD2, 0x64, 0x80, 0xA5,
        0x70, 0xB5, 0x77, 0x0B, 0x04, 0x81, 0x99, 0xCF,
        0x3F, 0x0E, 0x1B, 0x91, 0xAB, 0x39, 0x4B, 0x1F,
        0x65, 0xD4, 0x7F, 0x92, 0x98, 0xD0, 0x96, 0xCA,
        0x25, 0xC0, 0x99, 0xBC, 0x67, 0xF4, 0x33, 0x42,
        0x63, 0xE3, 0x6B, 0xD9, 0xE6, 0x6B, 0x99, 0x8A,
        0x07, 0xDC, 0x1E, 0x18, 0x1E, 0x05, 0x38, 0x6E,
        0x96, 0x8F, 0x1C, 0xB0, 0xAB, 0x1E, 0x9A, 0x67,
        0xD5, 0xD3, 0x30, 0x11, 0x20, 0x37, 0x82, 0x24,
        0x88, 0x1F, 0x65, 0x17, 0x59, 0xEC, 0x7D, 0xBF,
        0x45, 0x78, 0x1E, 0xF8, 0xA8, 0x4D, 0xAD, 0xAF,
        0xE6, 0x13, 0xD6, 0x01, 0x69, 0x66, 0xBD, 0x88,
        0x44, 0xB6, 0xA6, 0x17, 0xAC, 0xA1, 0xEE, 0xF6,
        0x73, 0xB7, 0x74, 0xCC, 0x80, 0x7B, 0x36, 0xDD,
        0x02, 0xDD, 0x45, 0x21, 0x66, 0x86, 0x03, 0x7F,
        0x9A, 0xC0, 0xB1, 0x2F, 0x57, 0x26, 0xF2, 0x51,
        0xC5, 0x72, 0x43, 0xE2, 0xC1, 0x88, 0xF5, 0xEC,
        0xC0, 0x97, 0xE0, 0xB9, 0x89, 0xB5, 0x8A, 0x5D,
        0x80, 0x4A, 0xBF, 0xD7, 0x20, 0x25, 0x55, 0x77,
        0x66, 0x8E, 0xE3, 0x04, 0xD0, 0x1C, 0x50, 0xFE,
        0x8B, 0x6D, 0x90, 0x68, 0x53, 0xCF, 0x7A, 0x49,
        0x4F, 0xB4, 0x79, 0x91, 0xF1, 0x81, 0xB7, 0x42,
        0x0E, 0x74, 0x19, 0x9C, 0x82, 0xE7, 0x1A, 0x82,
        0x4B, 0xF8, 0xC6, 0x13, 0x1D, 0xF4, 0xD1, 0x85,
        0x6F, 0x11, 0xE7, 0x04, 0x07, 0x70, 0x72, 0x4D,
        0xE7, 0x2C, 0x81, 0x5A, 0xC0, 0x44, 0x3F, 0x2E,
        0x77, 0xEC, 0x22, 0xA1, 0x28, 0xDB, 0x18, 0xE1,
        0x18, 0x3E, 0xE7, 0x96, 0x82, 0xC4, 0x30, 0x24,
        0xC9, 0x07, 0x46, 0x6C, 0x35, 0x4B, 0x1C, 0x7B,
        0x0E, 0x0E, 0xF0, 0x9F, 0x16, 0x48, 0x7B, 0xD8,
        0xA9, 0x9C, 0x3A, 0x0A, 0x9E, 0xDB, 0xF0, 0x0F,
        0x15, 0xA5, 0xEB, 0x1C, 0x50, 0xD4, 0x27, 0x36,
        0xDB, 0x07, 0x63, 0xBD, 0x56, 0xBD, 0xFA, 0x81,
        0x09, 0x9A, 0xDE, 0xCE, 0xE8, 0x4A, 0xEA, 0x06,
        0x9C, 0x06, 0x5B, 0x67, 0x03, 0x14, 0xB9, 0xE4,
        0x8C, 0x66, 0x75, 0xA3, 0xCC, 0x69, 0x39, 0x57,
        0xDA, 0x1D, 0x21, 0xBA, 0xCE, 0xD8, 0x70, 0x02,
        0xFF, 0xF5, 0x6F, 0x25, 0x3A, 0x3D, 0xFC, 0x79,
        0xA3, 0xF0, 0x3A, 0x3F, 0x2B, 0x10, 0x51, 0x9A,
        0xCB, 0xC9, 0x1A, 0xF5, 0xF1, 0x98, 0x5B, 0x5C,
        0x87, 0x96, 0x4E, 0xC8, 0x00, 0x8A, 0x3A, 0x6E,
        0x85, 0x02, 0xA5, 0xF1, 0x69, 0x32, 0x6E, 0xC1,
        0x95, 0x68, 0xCF, 0xA8, 0xE8, 0x85, 0x55, 0x4D,
        0x6A, 0x68, 0x1F, 0x00, 0xDD, 0x26, 0xB3, 0x24,
        0xF4, 0x9D, 0xD2, 0x4D, 0x81, 0x06, 0xDA, 0xE6,
        0x4D, 0x11, 0x73, 0xDF, 0xFE, 0x4F, 0xA6, 0x22,
        0x5E, 0x6C, 0x6D, 0x5E, 0xE3, 0x59, 0xCF, 0xF4,
        0x35, 0xA0, 0x80, 0x86, 0x89, 0x49, 0xB2, 0xED,
        0x0C, 0xC7, 0x3B, 0x42, 0x06, 0x68, 0x8D, 0x90,
        0x04, 0x1A, 0xBD, 0x51, 0xF6, 0xB9, 0x29, 0x2E,
        0xB6, 0xF0, 0x79, 0x40, 0x1E, 0x6E, 0x59, 0x94,
        0xFB, 0xF5, 0x6B, 0x72, 0x82, 0x4C, 0xB6, 0xC7,
        0x2B, 0x12, 0x71, 0x77, 0xDD, 0x89, 0xCC, 0x2F,
        0x98, 0xB0, 0x93, 0x1C, 0x98, 0xCE, 0x5E, 0x89,
        0x0D, 0x95, 0x7B, 0x98, 0xE1, 0xEA, 0xDC, 0xB7,
        0xFF, 0x22, 0xC5, 0x31, 0x40, 0x9E, 0x1C, 0x80,
        0x59, 0x47, 0x01, 0x49, 0xEC, 0x81, 0xEF, 0x16,
        0x32, 0x6B, 0xB0, 0x4E, 0xE2, 0x3B, 0xA3, 0xC1,
        0x03, 0x12, 0x0D, 0xA6, 0x65, 0xDE, 0x8D, 0xB0,
        0xA0, 0xBB, 0x75, 0xEF, 0x5C, 0xDA, 0xF4, 0xEE,
        0x47, 0x6E, 0x55, 0x02, 0x38, 0xCD, 0xC1, 0xAC,
        0xDD, 0x71, 0xA6, 0x34, 0xAB, 0xCE, 0xA5, 0x5C,
        0x90, 0xFF, 0xF8, 0xE0, 0xA7, 0x87, 0xBD, 0x21,
        0x36, 0x91, 0x4F, 0x23, 0xD8, 0x75, 0x58, 0xC5,
        0xF6, 0xBA, 0xAC, 0x54, 0x6C, 0x24, 0xB1, 0x41,
        0x02, 0x02, 0xB9, 0x44, 0x31, 0x0E, 0xC4, 0xC9,
        0xC6, 0x87, 0x85, 0x36, 0x05, 0xC8, 0xAE, 0xC9,
        0xF1, 0xEF, 0x6B, 0x67, 0x52, 0xD3, 0x9A, 0x15,
        0xBF, 0xA2, 0x47, 0xEF, 0x89, 0xFC, 0x06, 0x99,
        0xA1, 0x1A, 0xE4, 0x5A, 0x75, 0xE5, 0x09, 0xD4,
        0x54, 0xE9, 0x89, 0xF2, 0x60, 0x6E, 0xAB, 0x10,
        0xF8, 0x42, 0xE4, 0xAD, 0x57, 0xC6, 0xE3, 0x65,
        0x48, 0x94, 0x14, 0x05, 0x4F, 0x62, 0x20, 0x0F,
        0x3A, 0x1E, 0xC7, 0x62, 0xDC, 0x5C, 0x8E, 0xFA,
        0x19, 0x88, 0x47, 0x5D, 0xE8, 0xC3, 0xD5, 0x8C,
        0x2B, 0x71, 0xBA, 0x11, 0x98, 0x7C, 0x0A, 0xC6,
        0x42, 0x08, 0x3B, 0xAC, 0x76, 0xFB, 0x50, 0x78,
        0x8C, 0x26, 0x8F, 0xEE, 0x7B, 0xE2, 0x59, 0x9B,
        0x34, 0x58, 0x09, 0x2A, 0x8B, 0xCB, 0x1F, 0x31,
        0x94, 0x8F, 0xE4, 0x82, 0xDF, 0x9A, 0x54, 0x5B,
        0x63, 0x85, 0x94, 0xD6, 0x7A, 0x44, 0x06, 0x91,
        0x5C, 0xCD, 0xC7, 0x55, 0x57, 0x47, 0xC0, 0x4E,
        0x72, 0xA5, 0x48, 0xAB, 0x8F, 0xEE, 0x87, 0x6B,
        0x25, 0x82, 0x61, 0x3C, 0xCA, 0xBD, 0xA9, 0x6C,
        0xF1, 0x4A, 0xAA, 0xF6, 0x71, 0x6B, 0x79, 0x0B,
        0xFE, 0x4D, 0x92, 0x32, 0xD9, 0x03, 0x70, 0xD6,
        0x0B, 0xBC, 0x18, 0x4B, 0xA3, 0x3B, 0xCF, 0x77,
        0x83, 0x16, 0xE3, 0x4B, 0x11, 0x83, 0x8D, 0x8F,
        0x71, 0xFE, 0xEA, 0xC0, 0x42, 0xF0, 0x35, 0xB0,
        0x76, 0xEA, 0xC1, 0xC2, 0x62, 0xFA, 0x9C, 0x32,
        0xBC, 0x8D, 0x69, 0xB1, 0x38, 0xB3, 0x51, 0x31,
        0x8E, 0xD1, 0xF3, 0x44, 0x95, 0x95, 0x11, 0x52,
        0x36, 0xF4, 0xCA, 0x7C, 0xBA, 0x2B, 0xA9, 0xE1,
        0x03, 0xF0, 0xF5, 0x09, 0xAB, 0x91, 0x6E, 0x48,
        0xB8, 0xAF, 0x03, 0x9B, 0xDC, 0xD5, 0x1C, 0xAB,
        0xFA, 0xCA, 0xDC, 0xEE, 0x8E, 0x49, 0x84, 0xF5,
        0x61, 0xF9, 0x7D, 0x17, 0xCB, 0xF1, 0xDE, 0x9A,
        0x7A, 0x7B, 0xDA, 0xF3, 0x26, 0xE6, 0xD8, 0xAD,
        0x90, 0xE9, 0x5B, 0xAF, 0x15, 0x45, 0xD3, 0xE2,
        0x46, 0x69, 0xD1, 0xC5, 0xF4, 0x28, 0xE0, 0x7E,
        0x2C, 0x71, 0x10, 0xFF, 0x43, 0x59, 0x80, 0x93,
        0xE6, 0xF9, 0x28, 0xA0, 0x34, 0xC6, 0x86, 0xBA,
        0xE7, 0x5A, 0x56, 0x7A, 0xE4, 0xF5, 0x20, 0xB4,
        0x4D, 0xAC, 0xB4, 0x95, 0xE5, 0xB2, 0xC6, 0x43,
        0x9E, 0x2E, 0x67, 0x8E, 0x7C, 0x05, 0x4F, 0xF7,
        0x60, 0x14, 0x88, 0xC6, 0xAE, 0x4A, 0x05, 0x36,
        0x99, 0x73, 0x55, 0x10, 0xF9, 0xDB, 0xC3, 0x4C,
        0xD7, 0x6A, 0x19, 0x94, 0xC0, 0xFE, 0x74, 0x12,
        0xC0, 0xCE, 0x95, 0x15, 0xBF, 0x60, 0x3A, 0x8E,
        0xB5, 0xFC, 0x8A, 0xBC, 0xAC, 0x9F, 0x15, 0x10,
        0x44, 0x73, 0x58, 0x60, 0x5D, 0xA1, 0x33, 0xFD,
        0xDE, 0xBD, 0xF2, 0x22, 0x69, 0xEE, 0x1D, 0x46,
        0x8E, 0x2E, 0xE8, 0x21, 0x62, 0x1D, 0x27, 0x84,
        0xC4, 0x6D, 0xA8, 0x30, 0x02, 0xA6, 0x26, 0x94,
        0xFA, 0xB1, 0xEF, 0xEC, 0x3B, 0x8D, 0x6F, 0x1B,
        0x2C, 0xCE, 0x2A, 0x4E, 0xC4, 0x28, 0x35, 0x4E,
        0x39, 0xA4, 0xF4, 0x5C, 0x96, 0x65, 0xC1, 0xB8,
        0x55, 0xA5, 0x09, 0x15, 0xBC, 0x4D, 0x3B, 0xD0,
        0x1F, 0x7F, 0xBA, 0x90, 0x20, 0xCD, 0xBD, 0xC2,
        0xC8, 0xE5, 0xC6, 0xB0, 0x6F, 0x14, 0x4E, 0x6B,
        0xEA, 0x8A, 0x24, 0x44, 0xE1, 0x0A, 0xCD, 0xB2,
        0x05, 0xF3, 0x15, 0x71, 0x7C, 0x86, 0xFC, 0xF1,
        0xFD, 0x6B, 0xA6, 0xE3, 0xFC, 0x86, 0xE3, 0xBA,
        0x56, 0x6B, 0x8F, 0xBE, 0x02, 0x9A, 0x03, 0x0C,
        0x8C, 0x69, 0xE5, 0x7C, 0x15, 0xAE, 0x13, 0x12,
        0x25, 0x2B, 0x36, 0xFB, 0x51, 0xA1, 0x61, 0x5E,
        0x37, 0x46, 0x92, 0x0C, 0x0B, 0x71, 0x5C, 0x1D,
        0xA4, 0xDB, 0x04, 0xC1, 0x08, 0xED, 0x5C, 0x44,
        0x80, 0x70, 0xC1, 0x0E, 0x63, 0x6D, 0x92, 0xC2,
        0x1E, 0x18, 0x8E, 0x71, 0x0E, 0x7C, 0x10, 0x21,
        0x1E, 0xC2, 0xCF, 0xD6, 0x38, 0x7A, 0x9B, 0x5C,
        0x9E, 0xE8, 0x82, 0x3D, 0xDD, 0x40, 0x0C, 0x96,
        0x17, 0xEF, 0xB1, 0x25, 0xBA, 0x84, 0x45, 0x4F,
        0x64, 0xA6, 0x8E, 0x2B, 0xBA, 0xF1, 0xED, 0xB3,
        0x4F, 0x92, 0x5F, 0x1A, 0x73, 0x2A, 0x2A, 0x22,
        0x68, 0x19, 0x4C, 0x8A, 0x87, 0x51, 0x75, 0x78,
        0xCF, 0x3C, 0xC5, 0x97, 0xFD, 0x77, 0x43, 0xCB,
        0xAE, 0x3D, 0x9C, 0xB6, 0x45, 0x54, 0x45, 0xF4,
        0x1B, 0x92, 0xEE, 0xF4, 0x9D, 0xC4, 0x32, 0x10,
        0x6A, 0x48, 0xAB, 0xE9, 0x47, 0xBF, 0x2B, 0x92,
        0x49, 0x84, 0x23, 0x52, 0x05, 0xA1, 0x92, 0x3B,
        0xD7, 0x78, 0x2D, 0x9A, 0x15, 0xB4, 0xD9, 0xD3,
        0x45, 0xD0, 0x69, 0xF1, 0x38, 0x4D, 0x39, 0xEA,
        0x49, 0x7E, 0xC0, 0xE7, 0x7A, 0x07, 0x88, 0x1D,
        0x1F, 0xA3, 0xAC, 0xE9, 0xC3, 0xFD, 0x6B, 0x5D,
        0xF6, 0xB2, 0xB9, 0xAA, 0x9A, 0xBE, 0xF4, 0x06,
        0xD9, 0x5E, 0x81, 0xE5, 0x68, 0xDF, 0xEA, 0x20,
        0x4C, 0xEE, 0xED, 0x42, 0xA4, 0xD3, 0x7B, 0xA8,
        0x82, 0x98, 0x0D, 0xB4, 0xC8, 0xC3, 0x43, 0x28,
        0x13, 0xE9, 0x6B, 0x11, 0x0E, 0x54, 0xE6, 0xCD,
        0x11, 0x0A, 0x01, 0x36, 0x41, 0x78, 0xC5, 0x7D,
        0x00, 0xC6, 0x8D, 0xE7, 0x7B, 0x4C, 0xE6, 0x35,
        0x57, 0x8F, 0x56, 0xA9, 0x73, 0x5A, 0xEF, 0x93,
        0xF0, 0xD8, 0x16, 0xE3, 0x44, 0x8A, 0xA0, 0xA9,
        0xF1, 0x9C, 0x2E, 0x02, 0xD1, 0x3C, 0x66, 0xDD,
        0xE5, 0x35, 0xFE, 0x81, 0x77, 0x8D, 0xC2, 0x46,
        0x64, 0x03, 0x23, 0xCC, 0x37, 0x22, 0x60, 0x68,
        0xCC, 0x7F, 0x79, 0xE8, 0x6B, 0xD0, 0xEE, 0x1C,
        0x6A, 0xC3, 0x3C, 0xEB, 0x51, 0x95, 0xFA, 0xE4,
        0x28, 0x17, 0x94, 0x49, 0x22, 0x69, 0x64, 0x98,
        0x82, 0x8B, 0x68, 0x9F, 0x69, 0x35, 0xF9, 0xBF,
        0x33, 0x22, 0xA4, 0x32, 0x0F, 0x4C, 0x26, 0xE4,
        0x8D, 0xDF, 0xAE, 0xBD, 0xF4, 0x4D, 0x01, 0xAF,
        0xA1, 0xFA, 0x3E, 0xCE, 0xD3, 0xB0, 0x5D, 0x02,
        0xDB, 0x3B, 0xB4, 0x23, 0xB8, 0x55, 0x97, 0xB5,
        0x1F, 0x25, 0x64, 0xA7, 0x5D, 0x4A, 0x8C, 0x90,
        0xD4, 0xB6, 0x85, 0x20, 0x32, 0x09, 0x37, 0x26,
        0x00, 0xD5, 0x4D, 0x98, 0x5A, 0xCF, 0x29, 0x3B,
        0x0E, 0xAF, 0x69, 0x88, 0x78, 0x18, 0xAD, 0xD1,
        0xE1, 0xB7, 0xC5, 0xD7, 0xB7, 0x5F, 0xFE, 0xB5,
        0x64, 0xE0, 0x68, 0x0B, 0x4F, 0x46, 0x7B, 0xDE,
        0x0B, 0x11, 0x7A, 0x42, 0x10, 0x86, 0x09, 0x60,
        0xB5, 0xE0, 0x22, 0x17, 0x28, 0x68, 0x7A, 0xE9,
        0xEB, 0xBC, 0x6B, 0xD5, 0x95, 0x4C, 0xE0, 0xAE,
        0x57, 0xB1, 0x45, 0xFF, 0xC2, 0x7E, 0xB6, 0xA0,
        0xD3, 0x8E, 0x46, 0x16, 0xCE, 0xBE, 0x76, 0xCE,
        0x59, 0x5B, 0xA4, 0x96, 0x1E, 0x9F, 0x80, 0xF0,
        0x06, 0x7E, 0xCD, 0x6E, 0x27, 0xB8, 0x7D, 0x26,
        0xB6, 0x60, 0xA3, 0xAB, 0x52, 0xC1, 0x37, 0x9A,
        0xDD, 0x46, 0xF5, 0xB9, 0x39, 0x75, 0xAA, 0x19,
        0xF3, 0xE4, 0xA8, 0x95, 0x4B, 0x25, 0x3F, 0x0B,
        0x44, 0x13, 0xF5, 0x82, 0x10, 0x68, 0x03, 0xD5,
        0x0F, 0x99, 0xB5, 0xB2, 0x8B, 0x85, 0x77, 0x2E,
        0x78, 0x3E, 0xEE, 0x21, 0x6E, 0xAD, 0x2D, 0xCF,
        0x95, 0x62, 0x94, 0x1C, 0x50, 0xAB, 0xC5, 0xFA,
        0x8E, 0x24, 0xB6, 0x14, 0x86, 0x46, 0x8A, 0xAA,
        0x20, 0xDF, 0x15, 0xD1, 0x72, 0xF6, 0xAC, 0x03,
        0xAF, 0xDF, 0xCD, 0x53, 0x81, 0xBA, 0xDB, 0x07,
        0x8B, 0x8E, 0xBB, 0x70, 0x91, 0x57, 0x04, 0xB9,
        0x88, 0xE5, 0x8F, 0x45, 0xD3, 0xD6, 0x31, 0x12,
        0xA5, 0xC1, 0x28, 0xC6, 0x49, 0x90, 0x0F, 0x1D,
        0x69, 0x66, 0xE3, 0x98, 0x56, 0x7D, 0xE3, 0x48,
        0xAC, 0xC0, 0xDE, 0xE4, 0x2B, 0x88, 0x01, 0x19,
        0x4E, 0x99, 0xBB, 0x1A, 0xAF, 0x02, 0x5A, 0x91,
        0xE3, 0x2C, 0xE6, 0x56, 0x4D, 0x05, 0x10, 0xB9,
        0x10, 0xF2, 0x2A, 0x27, 0xDE, 0xCF, 0x9D, 0x2E
    };
    static const byte msg_44[] = {
        0xB1, 0x34, 0x49, 0x15, 0xCC, 0xD6, 0x93, 0x41,
        0x6B, 0x37, 0xFE, 0xBD, 0x8D, 0xC7, 0xC7, 0xDB,
        0x9F, 0x25, 0x3E, 0x9D, 0xF5, 0x3C, 0xEC, 0x51,
        0x49, 0x23, 0xAA, 0xA2, 0x67, 0x6F, 0xBF, 0xA4,
        0xCC, 0x04, 0xFC, 0x68, 0xF9, 0xE3, 0x2F, 0x9E,
        0x86, 0x4C, 0x68, 0x95, 0xDB, 0x37, 0xE9, 0xFF,
        0xEB, 0x80, 0xF0, 0xF6, 0xB8, 0x6C, 0xB6, 0xAD,
        0x9C, 0x42, 0xF8, 0xFC, 0x75, 0x19, 0x8D, 0xD3,
        0xCC, 0xDA, 0xF5, 0x77, 0xC7, 0xB3, 0x5B, 0x8F,
        0x1B, 0xF6, 0x0A, 0xAB, 0xEA, 0x89, 0x94, 0x42,
        0x20, 0x1F, 0xBB, 0xF4, 0x42, 0x8C, 0x7E, 0xC1,
        0x7B, 0xC3, 0x1B, 0x54, 0x72, 0x4B, 0x95, 0x90,
        0xF7, 0x53, 0x1E, 0x6F, 0x79, 0x0A, 0x1F, 0xA7,
        0x74, 0x32, 0x83, 0x37, 0x2D, 0x31, 0x71, 0xB8,
        0x96, 0x6B, 0x47, 0x0A, 0xAA, 0x85, 0x26, 0xEB,
        0x4A, 0x6E, 0x81, 0xE6, 0x5A, 0xD0, 0xC2, 0x9F,
        0x2D, 0x37, 0xDD, 0x5B, 0x41, 0x2B, 0xAE, 0x68,
        0x2A, 0x66, 0x79, 0x68, 0x77, 0xC8, 0x2F, 0xFD,
        0xA9, 0x76, 0x24, 0x34, 0xEA, 0xC2, 0xC7, 0xD4,
        0xAF, 0x60, 0x9B, 0x27, 0x72, 0x49, 0x0D, 0xEE,
        0x9B, 0xFB, 0x00, 0x5D, 0x2F, 0x1A, 0x2E, 0xBB,
        0xA0, 0x32, 0xCD, 0x71, 0x59, 0xD5, 0x4B, 0xE5,
        0x96, 0xF3, 0x30, 0x68, 0xBE, 0x5D, 0x9A, 0x2D,
        0x94, 0x0C, 0x76, 0x70, 0xE6, 0x4E, 0x9A, 0xF7,
        0xD7, 0xD3, 0x3E, 0xC3, 0xAE, 0xC6, 0xF1, 0xD9,
        0xDE, 0xE3, 0x92, 0x84, 0xF0, 0x5C, 0xE0, 0x25,
        0xD1, 0x81, 0x76, 0x0D, 0x40, 0xE5, 0xC2, 0xD9,
        0xBE, 0xAE, 0x24, 0x20, 0xF4, 0x0D, 0x9F, 0x32,
        0xB7, 0xBD, 0xCD, 0x3A, 0xFB, 0x1C, 0x66, 0x0D,
        0x01, 0x71, 0x4D, 0x81, 0x37, 0x58, 0xDB, 0xB8,
        0x2C, 0x6B, 0x7E, 0x85, 0x80, 0x52, 0xB5, 0xA5,
        0x0E, 0x39, 0xE0, 0x15, 0xD3, 0xF2, 0x4A, 0x2C,
        0x64, 0xC9, 0xDD, 0xCC, 0x15, 0x0D, 0x90, 0x4F,
        0x07, 0xF6, 0x5F, 0xF6, 0x8A, 0xD0, 0x12, 0x9E,
        0xC3, 0xF8, 0x12, 0x3F, 0x3A, 0x03, 0xFC, 0x95,
        0x8A, 0xE2, 0x47, 0x8C, 0x6C, 0x6E, 0x03, 0x61,
        0x67, 0xD8, 0x51, 0x49, 0xF7, 0x9F, 0xB0, 0x3F,
        0xAA, 0xB9, 0x89, 0x7C, 0xE7, 0x3F, 0x88, 0x55,
        0xC5, 0x4C, 0x83, 0xD7, 0x53, 0xB1, 0x04, 0xB5,
        0x13, 0xD5, 0x6B, 0xC6, 0x4C, 0x3B, 0x08, 0x91,
        0x73, 0x47, 0x35, 0x13, 0x26, 0xD8, 0xEB, 0x47,
        0xCF, 0x66, 0xF1, 0x3F, 0xB9, 0x0F, 0x6A, 0xF5,
        0xA8, 0x94, 0xC7, 0x75, 0x00, 0x77, 0xA8, 0x9C,
        0xEB, 0x77, 0x22, 0xE2, 0xE6, 0x80, 0xA5, 0x9B,
        0xF8, 0x43, 0x8C, 0x52, 0x35, 0x31, 0xEA, 0x8C,
        0xC2, 0x83, 0x4F, 0xFC, 0x4E, 0xF0, 0x2D, 0x35,
        0xB8, 0x51, 0x46, 0xF2, 0xD6, 0x01, 0xD5, 0x00,
        0x99, 0x6A, 0x44, 0x10, 0x64, 0xAD, 0xCA, 0x1F,
        0x62, 0x3F, 0x2F, 0xE7, 0x45, 0x22, 0x47, 0xEF,
        0x86, 0x9D, 0x76, 0xD5, 0x78, 0x42, 0x07, 0x30,
        0x88, 0x86, 0x90, 0xB1, 0xA0, 0x08, 0xDA, 0x28,
        0x2A, 0xD1, 0x75, 0x7D, 0x21, 0x71, 0x29, 0x38,
        0x59, 0xC7, 0x3F, 0x55, 0x20, 0xB5, 0xBB, 0x48,
        0x03, 0xE7, 0xFA, 0xB0, 0x29, 0x00, 0xD2, 0x0F,
        0xE7, 0x65, 0x81, 0x8E, 0xE6, 0x24, 0xE7, 0xA1,
        0x94, 0x50, 0x9D, 0x01, 0x6B, 0x4B, 0xD7, 0x81,
        0x4E, 0xA0, 0xD5, 0x4A, 0x51, 0xEE, 0x95, 0x0A,
        0x14, 0x76, 0xD5, 0x87, 0xAA, 0x6F, 0x78, 0xC8,
        0xD2, 0xE0, 0xC8, 0xF8, 0xF2, 0x78, 0xD8, 0x2E,
        0x11, 0x90, 0x44, 0xB6, 0xBF, 0xD0, 0xBE, 0xD8,
        0x6F, 0xA4, 0x20, 0xA2, 0xC8, 0xA4, 0xEF, 0xB0,
        0x5D, 0x73, 0x06, 0xBE, 0x52, 0xF9, 0x32, 0xD8,
        0x06, 0x5D, 0xD1, 0x29, 0x23, 0x46, 0x25, 0x6E,
        0x42, 0x9D, 0xEE, 0x41, 0x9E, 0xF3, 0x7D, 0x1B,
        0x35, 0x28, 0x81, 0xDC, 0x47, 0x7F, 0x25, 0xA4,
        0x0A, 0xEB, 0x3E, 0x17, 0xE6, 0x1B, 0xCC, 0x00,
        0xD2, 0xE2, 0xA9, 0x3D, 0xEC, 0xF3, 0x00, 0xF0,
        0x81, 0x68, 0x21, 0xED, 0x49, 0xF9, 0x9B, 0x9B,
        0x8B, 0xED, 0xD9, 0x1E, 0xFA, 0x04, 0xBB, 0xB0,
        0x9A, 0xBD, 0x1D, 0x24, 0x36, 0xA7, 0xD6, 0x64,
        0x8A, 0x38, 0x3A, 0x3A, 0x8F, 0x09, 0x08, 0x0E,
        0x46, 0x7B, 0xE1, 0x03, 0x30, 0xBF, 0x62, 0x27,
        0x10, 0x74, 0xBE, 0xBD, 0x7F, 0x56, 0x39, 0x0D,
        0x1D, 0x39, 0x47, 0xF4, 0x02, 0x47, 0x6B, 0x62,
        0x6B, 0x52, 0xAC, 0xAB, 0x21, 0xAC, 0x10, 0x4A,
        0xAB, 0x59, 0x75, 0x33, 0x11, 0xD9, 0xE9, 0xE2,
        0xB2, 0x20, 0x6B, 0xA1, 0x09, 0x42, 0xB6, 0x37,
        0xE4, 0x5C, 0xE6, 0x9F, 0x54, 0xB4, 0x67, 0xBC,
        0xAE, 0xF3, 0xDC, 0x1A, 0xA2, 0x15, 0x47, 0x7B,
        0x15, 0xC8, 0x00, 0x35, 0x8E, 0x1D, 0x69, 0x04,
        0xD8, 0x9C, 0xA9, 0x6A, 0x03, 0x1A, 0x55, 0x48,
        0x6C, 0x4F, 0xC1, 0x68, 0x27, 0x26, 0x13, 0xAB,
        0x8E, 0x03, 0x50, 0x7B, 0xDD, 0xC2, 0x7E, 0x5C,
        0x8A, 0x6F, 0xBB, 0x5F, 0x8B, 0x22, 0x86, 0xA5,
        0xC5, 0x0E, 0xC5, 0x68, 0x60, 0xF6, 0xBF, 0xFF,
        0x6E, 0xBA, 0xDC, 0x21, 0x71, 0xD2, 0xEB, 0xD1,
        0x27, 0x8C, 0x58, 0x14, 0xC3, 0x2E, 0x13, 0x9E,
        0x04, 0x09, 0x61, 0xC3, 0x19, 0xC3, 0x03, 0x48,
        0x70, 0x33, 0x3B, 0x12, 0xF7, 0x3B, 0x38, 0xE7,
        0x18, 0x14, 0xA9, 0xF1, 0x60, 0x83, 0x65, 0xEB,
        0x32, 0xD5, 0x23, 0x8F, 0x6B, 0xF7, 0xD8, 0x00,
        0x21, 0xBD, 0xA3, 0x98, 0xDE, 0xD7, 0x13, 0x17,
        0xAB, 0x3C, 0xA4, 0xD7, 0xBE, 0x1D, 0xA7, 0x4A,
        0x1B, 0xC4, 0x0C, 0x9B, 0x2E, 0x34, 0x5B, 0xA7,
        0xA2, 0x3F, 0x9B, 0x2D, 0xDB, 0xAF, 0x85, 0x14,
        0x0A, 0xF9, 0x30, 0x9E, 0x86, 0x53, 0xAC, 0x24,
        0xAF, 0xD8, 0x25, 0xBC, 0x2A, 0x07, 0x2B, 0xCD,
        0x02, 0xFE, 0x3E, 0xF0, 0x0B, 0xE3, 0xF9, 0x51,
        0x5C, 0x29, 0xEB, 0x8A, 0xFB, 0xC3, 0xEF, 0xD1,
        0xF9, 0xCF, 0xDF, 0xE9, 0xEB, 0xA9, 0x49, 0x59,
        0xB5, 0x17, 0x7E, 0x28, 0x86, 0xB8, 0xD1, 0x8D,
        0xCA, 0x97, 0xF0, 0xCB, 0x80, 0x7E, 0xE3, 0xEA,
        0xE3, 0x1B, 0x48, 0xCF, 0xAC, 0x61, 0x3C, 0x2E,
        0x00, 0xAB, 0x74, 0xFB, 0x95, 0xF6, 0x64, 0xF3,
        0xCA, 0xBF, 0x6E, 0xEF, 0xCD, 0xDD, 0x6D, 0xA5,
        0xF8, 0x98, 0xEC, 0x38, 0xF2, 0xF0, 0x7D, 0x6D,
        0xCB, 0x75, 0xE0, 0x50, 0x9D, 0x13, 0x19, 0x24,
        0x07, 0x4C, 0x05, 0xF4, 0x5D, 0xCA, 0x25, 0xB7,
        0xCF, 0xE2, 0xBC, 0xFE, 0xEC, 0xAF, 0x5F, 0xC3,
        0x6C, 0xE6, 0xE3, 0xC5, 0x85, 0x43, 0x7B, 0x06,
        0x9F, 0xD2, 0xC6, 0xBB, 0xAD, 0x33, 0xD6, 0x86,
        0xBD, 0x5B, 0x9E, 0x2C, 0xA0, 0xD9, 0x8B, 0xDC,
        0x5E, 0x71, 0x7B, 0x6D, 0xF7, 0x1D, 0x40, 0x91,
        0x30, 0x8E, 0x84, 0x73, 0x9A, 0xD6, 0x7F, 0xA6,
        0x79, 0xA6, 0xCE, 0xE9, 0xA6, 0x83, 0x28, 0x4B,
        0x4F, 0xB3, 0x1B, 0x2C, 0x40, 0x8F, 0x52, 0xF0,
        0x59, 0x7D, 0x9C, 0x04, 0xEA, 0xF4, 0xAC, 0x6D,
        0xBB, 0x6C, 0x3F, 0xD6, 0x7F, 0x25, 0x39, 0xD8,
        0x87, 0xDF, 0xBC, 0xF3, 0xCA, 0xE4, 0x59, 0xFA,
        0x76, 0x66, 0x61, 0xA4, 0x8B, 0xFC, 0xFD, 0x6F,
        0x64, 0x03, 0x99, 0xD3, 0xAF, 0x07, 0x86, 0x35,
        0x99, 0x98, 0xCE, 0xFF, 0x7E, 0x9E, 0xB1, 0xB0,
        0x57, 0xA6, 0x29, 0x3D, 0xFF, 0xB7, 0xF3, 0xF2,
        0x51, 0x4B, 0x0B, 0x70, 0x29, 0x46, 0x06, 0x8A,
        0x6B, 0xBD, 0x75, 0x30, 0xD6, 0x91, 0x7F, 0xB1,
        0x1D, 0xBB, 0xAA, 0xBE, 0xD7, 0xAA, 0x46, 0x81,
        0xD7, 0x8A, 0xEA, 0x91, 0x86, 0x69, 0x2D, 0xDA,
        0x34, 0x70, 0x65, 0x2E, 0xB8, 0xA3, 0xF1, 0x44,
        0x56, 0xA5, 0xAA, 0xC4, 0x20, 0x88, 0x3B, 0x42,
        0x37, 0xB0, 0xA7, 0x2D, 0x91, 0x27, 0x63, 0xB6,
        0x7A, 0xC4, 0x13, 0x1A, 0x8A, 0x5D, 0x2F, 0x16,
        0x82, 0x96, 0xB9, 0x12, 0xD3, 0xB6, 0x61, 0xC4,
        0xE8, 0x3C, 0xE6, 0x3A, 0x61, 0xC0, 0x45, 0xEB,
        0xA5, 0x75, 0xEE, 0xB6, 0x7F, 0xB0, 0x70, 0xED,
        0x82, 0x39, 0xE5, 0x1A, 0x67, 0xD9, 0x80, 0x3C,
        0xE0, 0x0B, 0x85, 0x66, 0x74, 0xE0, 0xB7, 0x26,
        0x66, 0x26, 0xDD, 0x02, 0x15, 0xE5, 0xEF, 0x5F,
        0xDE, 0x7B, 0xF4, 0x0B, 0x99, 0x10, 0x21, 0x08,
        0xFC, 0x2D, 0xF2, 0x8B, 0xDC, 0xC8, 0xEA, 0xC6,
        0x3E, 0xFB, 0x20, 0x50, 0x1F, 0x24, 0x66, 0x99,
        0x80, 0x88, 0xC7, 0xA0, 0xB9, 0x6D, 0x1B, 0x75,
        0xC4, 0xC2, 0xE2, 0x52, 0xA0, 0xBF, 0x38, 0x01,
        0x5C, 0xA5, 0x8A, 0xDA, 0x79, 0x38, 0xAE, 0x2E,
        0xC7, 0x96, 0x6F, 0x30, 0x5B, 0xB4, 0x21, 0xC0,
        0xCD, 0x95, 0xCA, 0xD2, 0x12, 0x7D, 0xAD, 0x87,
        0x08, 0x6C, 0xC3, 0x8B, 0xF6, 0xB1, 0x5D, 0xAD,
        0x2C, 0x7C, 0x04, 0x41, 0xE5, 0x34, 0x2E, 0x4B,
        0x5A, 0xD9, 0x1E, 0x66, 0xF4, 0x23, 0xE2, 0x88,
        0x4D, 0xD9, 0x03, 0xFE, 0x6C, 0x64, 0x7D, 0x61,
        0xE6, 0x70, 0x0E, 0xA8, 0x83, 0x08, 0x07, 0xE6,
        0xFD, 0x64, 0x54, 0x3E, 0x3C, 0x6E, 0x9A, 0xD1,
        0x93, 0x37, 0x36, 0x90, 0xDE, 0x94, 0xF7, 0x16,
        0x15, 0x47, 0x94, 0xFE, 0x97, 0x5B, 0x11, 0x80,
        0xBA, 0x40, 0xAF, 0x7F, 0x05, 0xC1, 0x82, 0x91,
        0x69, 0xFD, 0xFB, 0xEC, 0x3A, 0xF7, 0xCF, 0xE1,
        0xD7, 0x9B, 0x59, 0x7E, 0xE4, 0x38, 0xA2, 0x96,
        0xEF, 0x14, 0x6A, 0x05, 0x99, 0x71, 0xE3, 0xF9,
        0x50, 0x8E, 0x35, 0x0B, 0x50, 0x71, 0x6D, 0xEC,
        0xB5, 0x1B, 0xC8, 0x80, 0x2A, 0xE6, 0x2A, 0x7F,
        0x4C, 0x2E, 0x6F, 0x7B, 0x54, 0x62, 0x0E, 0xF0,
        0x4C, 0x00, 0xF0, 0x72, 0xAE, 0x37, 0xAC, 0x32,
        0x7E, 0x26, 0xD3, 0x65, 0x76, 0x1C, 0x10, 0x46,
        0x17, 0xAE, 0xE0, 0xF3, 0x28, 0xEE, 0x97, 0xE0,
        0x86, 0x18, 0x3D, 0x46, 0xA3, 0x62, 0x1F, 0x23,
        0xF3, 0xAC, 0x27, 0x60, 0xB8, 0x85, 0x9A, 0x96,
        0x0E, 0xF1, 0x6F, 0xC1, 0xC6, 0xB1, 0x97, 0x8A,
        0x74, 0x12, 0xDD, 0x73, 0x85, 0x02, 0x9C, 0x73,
        0x61, 0xA8, 0xF7, 0x49, 0xCE, 0xBA, 0x23, 0xED,
        0xE7, 0x9A, 0x17, 0x0E, 0xA6, 0x84, 0x59, 0xF5,
        0x21, 0x66, 0xF5, 0xC5, 0x61, 0xF8, 0x88, 0x7E,
        0x62, 0x0C, 0x00, 0xC6, 0x4F, 0x06, 0xBD, 0x0A,
        0xBB, 0xCD, 0xE5, 0x11, 0x7A, 0xBC, 0xFD, 0x03,
        0xB6, 0xD1, 0xBA, 0x4F, 0x30, 0xFA, 0x96, 0x75,
        0xD8, 0x2D, 0x7A, 0x43, 0x0D, 0x58, 0x41, 0x46,
        0xBA, 0x72, 0x06, 0xCB, 0xBD, 0xD9, 0xBE, 0xA1,
        0xEA, 0x47, 0x08, 0x3D, 0xF9, 0x32, 0x23, 0x9C,
        0xAA, 0x02, 0x1D, 0xA3, 0x3E, 0x43, 0xF1, 0x68,
        0xD8, 0xBE, 0x9F, 0x0E, 0xA8, 0xA8, 0x52, 0xC4,
        0x0A, 0xDE, 0x43, 0x9D, 0x58, 0xA8, 0x05, 0xD4,
        0x74, 0xF8, 0x93, 0x21, 0x62, 0x6E, 0x33, 0x78,
        0x3C, 0x23, 0xEB, 0x60, 0x1C, 0x4C, 0x25, 0xFE,
        0x0F, 0x5E, 0x73, 0xC3, 0xAD, 0x33, 0x9A, 0x7D,
        0x69, 0x6B, 0xAB, 0x2C, 0xAA, 0x5F, 0xBF, 0x96,
        0x62, 0x3A, 0xF0, 0x63, 0x41, 0x00, 0xC7, 0x4C,
        0x81, 0x4D, 0x42, 0x43, 0x25, 0xBC, 0x30, 0xB6,
        0x0B, 0xEE, 0xFC, 0x18, 0x3E, 0x68, 0x0E, 0x64,
        0x5C, 0xD4, 0x22, 0x2A, 0xBA, 0xB5, 0xC6, 0x7E,
        0x67, 0x11, 0x1C, 0x4C, 0x03, 0x30, 0xEC, 0x0C,
        0x77, 0xB2, 0x2B, 0xBC, 0x98, 0xF7, 0x52, 0x8C,
        0x95, 0x66, 0xE1, 0x71, 0xDD, 0x26, 0xA7, 0x7F,
        0x87, 0xF3, 0x94, 0x2E, 0x0D, 0x3E, 0xFE, 0xAD,
        0x0A, 0xDA, 0x3B, 0x77, 0x49, 0xC5, 0x1D, 0xED,
        0x5F, 0xDA, 0x3F, 0xE6, 0xE7, 0x96, 0x58, 0xF1,
        0x02, 0x30, 0x68, 0xB9, 0x62, 0xD0, 0x58, 0xA2,
        0x89, 0x65, 0x12, 0x20, 0x1E, 0x4C, 0xE7, 0xB6,
        0x98, 0x12, 0x52, 0xF0, 0xE8, 0x55, 0xBC, 0xFE,
        0x1F, 0x44, 0x42, 0x36, 0xC9, 0x30, 0xE4, 0x9A,
        0x13, 0xB3, 0x7A, 0xF4, 0xF5, 0x97, 0xC0, 0x5D,
        0xCA, 0x23, 0xCC, 0x05, 0xC4, 0x3C, 0x32, 0xA2,
        0x11, 0x08, 0x17, 0xCB, 0x30, 0x6B, 0xA4, 0x7D,
        0x24, 0x5E, 0x50, 0x22, 0x2E, 0x23, 0xC6, 0x55,
        0x6B, 0xD7, 0x5D, 0x50, 0xEE, 0xF8, 0xBE, 0xB0,
        0xDE, 0x83, 0x5C, 0x8D, 0xD2, 0xE1, 0x5C, 0x70,
        0x66, 0x70, 0x59, 0x8F, 0x86, 0x50, 0x71, 0x71,
        0x04, 0x69, 0xEC, 0xB3, 0x47, 0x9E, 0xE0, 0x26,
        0xB1, 0x9F, 0xE6, 0x21, 0xAC, 0x99, 0x12, 0x6B,
        0x97, 0x9E, 0x1B, 0xA1, 0xDD, 0xA8, 0xE6, 0x11,
        0x12, 0x97, 0xC1, 0x0E, 0x4A, 0x77, 0xF5, 0x52,
        0xF8, 0x09, 0xE9, 0x01, 0x63, 0x56, 0x4E, 0xFA,
        0x24, 0x39, 0x36, 0xB9, 0xF2, 0x6E, 0x07, 0x28,
        0x7F, 0xA4, 0x07, 0x7C, 0xA2, 0x69, 0x7B, 0xED,
        0x6A, 0x4F, 0x0A, 0x95, 0x99, 0x05, 0x60, 0xE7,
        0x58, 0xD9, 0x90, 0xB4, 0xC1, 0x92, 0x0F, 0x9E,
        0x1A, 0xBE, 0x0B, 0x58, 0x96, 0x50, 0x61, 0x1C,
        0x2D, 0x5A, 0x13, 0xAA, 0x5F, 0x4E, 0x2B, 0x88,
        0xBE, 0xAB, 0x93, 0x72, 0xF4, 0x68, 0xB8, 0x30,
        0x91, 0xCD, 0x0A, 0x53, 0x8A, 0x35, 0x82, 0x93,
        0x4F, 0x66, 0xCA, 0xCD, 0xF2, 0x39, 0x98, 0xFE,
        0xC2, 0xFE, 0xFE, 0x51, 0x35, 0xF1, 0xB5, 0x62,
        0x2D, 0x1A, 0xE9, 0x43, 0x25, 0x5E, 0x05, 0xE4,
        0x8B, 0xFE, 0x91, 0x2F, 0x4F, 0x24, 0x1B, 0x2B,
        0xAC, 0x49, 0x9C, 0x14, 0xB0, 0x58, 0xA3, 0xA8,
        0xEE, 0xB9, 0xD1, 0xFA, 0x4D, 0x44, 0x2E, 0x23,
        0xFC, 0x59, 0x77, 0xA5, 0x60, 0x2E, 0xDC, 0xEB,
        0x7B, 0x7B, 0x26, 0x95, 0xE1, 0x87, 0xB7, 0x94,
        0xF8, 0x4B, 0x96, 0x63, 0x15, 0xB1, 0xBB, 0xA5,
        0xC0, 0x4A, 0x72, 0x02, 0x4A, 0x80, 0x5F, 0xB1,
        0x94, 0x73, 0xB7, 0x06, 0xB8, 0x13, 0x76, 0x42,
        0xAD, 0xB1, 0xC6, 0x6C, 0xFD, 0x64, 0xF2, 0x60,
        0xBB, 0x1B, 0x7A, 0xAD, 0xF6, 0xC2, 0x96, 0xB3,
        0x5F, 0x30, 0xB9, 0xD7, 0x70, 0x8A, 0x9D, 0x41,
        0xE7, 0x23, 0xFA, 0xD4, 0xE8, 0x72, 0xAF, 0x73,
        0xF8, 0x8C, 0x26, 0xAB, 0x65, 0x1B, 0xD5, 0x7A,
        0x21, 0xE2, 0x8C, 0xE8, 0xC2, 0x47, 0xD5, 0x8E,
        0x47, 0x9F, 0x79, 0x68, 0x87, 0x6F, 0xCE, 0xD3,
        0x5D, 0x2B, 0x87, 0xD2, 0xDF, 0x14, 0x43, 0x47,
        0x03, 0x3D, 0xF4, 0xCB, 0x50, 0xDE, 0x52, 0xD8,
        0x98, 0x41, 0x46, 0x3F, 0x5D, 0xFB, 0x6D, 0x6F,
        0xF6, 0xD9, 0xE8, 0x2B, 0xBA, 0xB3, 0xB1, 0xEC,
        0x58, 0x77, 0x8A, 0xB8, 0xF3, 0x6D, 0xBC, 0x68,
        0x22, 0xEA, 0xE3, 0x2F, 0xB6, 0xCB, 0x67, 0x30,
        0xCB, 0x33, 0x1C, 0x39, 0x5C, 0x27, 0x4A, 0xE7,
        0xE3, 0x7B, 0x40, 0x9B, 0x7C, 0x66, 0x32, 0xE7,
        0x6D, 0xAA, 0x97, 0xB8, 0x0F, 0x1E, 0x0C, 0xB4,
        0x7A, 0xA3, 0x66, 0xA8, 0xE3, 0x50, 0xEA, 0x36,
        0x74, 0x65, 0x92, 0xEC, 0x9B, 0x1E, 0x97, 0xF0,
        0x2F, 0x99, 0xD6, 0x00, 0x21, 0x37, 0x0B, 0x89,
        0x93, 0xC6, 0x80, 0xA1, 0x02, 0xDC, 0x96, 0x5D,
        0x20, 0xB7, 0x57, 0xF4, 0x17, 0x7A, 0x81, 0xBA,
        0x7B, 0x61, 0xD2, 0x88, 0xEF, 0xC5, 0xAD, 0xED,
        0x4C, 0x9A, 0x94, 0xA5, 0x7B, 0x2C, 0x6B, 0xD2,
        0x97, 0x7E, 0x23, 0x64, 0x0A, 0x66, 0x98, 0x47,
        0xEE, 0x81, 0xB1, 0x49, 0x0B, 0xE3, 0x8A, 0xC4,
        0x3E, 0x52, 0x2C, 0x8D, 0x09, 0xA2, 0x07, 0xB6,
        0x2A, 0x8B, 0x07, 0x9A, 0x24, 0x84, 0xDE, 0xD1,
        0x00, 0x63, 0xD7, 0xA1, 0x3F, 0xBF, 0x0C, 0xA8,
        0xEE, 0xDC, 0x2B, 0xF6, 0x7B, 0xD8, 0x78, 0x53,
        0x35, 0xB8, 0x29, 0x5A, 0xFE, 0x6B, 0x35, 0x6E,
        0x20, 0x62, 0x24, 0x17, 0x0E, 0x87, 0x23, 0x1A,
        0x77, 0x2D, 0x21, 0x84, 0x37, 0xBF, 0x7D, 0x68,
        0xAC, 0x2A, 0xF9, 0x3F, 0x11, 0x27, 0x18, 0x4F,
        0xA2, 0x15, 0x21, 0x47, 0x9E, 0x56, 0xFF, 0x22,
        0xE8, 0x0F, 0x61, 0xBC, 0x28, 0xB8, 0xD2, 0xE7,
        0x1B, 0x3D, 0x1D, 0x94, 0x28, 0x1B, 0x69, 0x56,
        0x00, 0xC8, 0xB0, 0xFD, 0x8E, 0x1D, 0x7E, 0x81,
        0x1F, 0x4C, 0xCF, 0xE1, 0x6E, 0x3F, 0x57, 0x95,
        0xC2, 0x4A, 0xA0, 0xA0, 0x16, 0x7E, 0x30, 0x5C,
        0x28, 0x87, 0x5C, 0x8F, 0xA9, 0x38, 0x9B, 0x72,
        0xF7, 0x90, 0x86, 0xF6, 0xEC, 0xC1, 0x6C, 0x88,
        0xB0, 0x78, 0x3A, 0x58, 0x15, 0xFB, 0x6F, 0x77,
        0xCD, 0xC7, 0xCC, 0xC3, 0x8D, 0x60, 0xE7, 0x87,
        0xBE, 0x9C, 0xBF, 0xFA, 0xA6, 0x2E, 0xF9, 0x59,
        0xA5, 0xE5, 0xDC, 0xDE, 0xB6, 0x25, 0x5C, 0x8E,
        0x0D, 0x2E, 0x01, 0xFE, 0x05, 0xEF, 0xF9, 0xE7,
        0x81, 0x02, 0xBE, 0xA2, 0x91, 0x40, 0x57, 0xD3,
        0x6E, 0x3D, 0x1B, 0x48, 0x50, 0x7A, 0xB6, 0xB1,
        0x76, 0x40, 0x47, 0x0F, 0xE3, 0xF1, 0x7A, 0x8B,
        0x6A, 0x5E, 0x04, 0xE5, 0x34, 0x56, 0xC5, 0xD9,
        0xE5, 0x0F, 0x74, 0x5D, 0xE0, 0x6F, 0x9A, 0xED,
        0xF4, 0xBF, 0xCF, 0x31, 0xB0, 0xC6, 0xED, 0x12,
        0x13, 0x36, 0x54, 0xCB, 0xC8, 0xDE, 0xF7, 0xF6,
        0x60, 0x9E, 0x12, 0x2C, 0x2E, 0x4C, 0x93, 0x3E,
        0x6F, 0xCB, 0x0F, 0x3D, 0x8C, 0xCA, 0xE8, 0xCA,
        0x0B, 0x10, 0xED, 0xDA, 0xE8, 0xDB, 0x29, 0x7C,
        0x8B, 0x32, 0x31, 0xC8, 0x94, 0x34, 0xA5, 0xF5,
        0x4D, 0x01, 0x28, 0xC8, 0x3A, 0xA6, 0xFD, 0xE2,
        0x9A, 0xB7, 0x0C, 0xDA, 0x43, 0x78, 0x45, 0x45,
        0xFE, 0xE9, 0xFF, 0x6E, 0xD4, 0x44, 0xF8, 0x88,
        0x66, 0x4D, 0xD2, 0x2B, 0x2E, 0x2D, 0xF5, 0x7C,
        0xA6, 0x53, 0xB6, 0xD2, 0x10, 0xE6, 0xB4, 0x0B,
        0x7F, 0xC2, 0x1F, 0xE0, 0x63, 0x90, 0xCA, 0x5D,
        0x5E, 0x60, 0xF5, 0x8A, 0xB1, 0x4C, 0x49, 0x03,
        0xD4, 0x38, 0xAE, 0xEF, 0xB1, 0x7C, 0xA4, 0xB9,
        0x98, 0x70, 0x6A, 0x0E, 0xD6, 0xA4, 0xA6, 0xF4,
        0x74, 0xB1, 0xBA, 0x1D, 0x48, 0xCC, 0xC1, 0x14,
        0x3C, 0x84, 0xA8, 0xD2, 0xE7, 0x8D, 0xEC, 0x11,
        0x61, 0x8C, 0x76, 0xB6, 0xDA, 0x28, 0xBC, 0x39,
        0xDF, 0x68, 0xAD, 0x24, 0xA4, 0x07, 0xE1, 0x07,
        0x33, 0xDD, 0x18, 0x9D, 0x5D, 0xAA, 0x90, 0x4B,
        0xEF, 0x88, 0x18, 0x6E, 0xB6, 0x83, 0x21, 0x45,
        0x94, 0x0F, 0x15, 0xB8, 0xAC, 0xD9, 0xD1, 0x8D,
        0x4F, 0x17, 0xC8, 0xD9, 0x17, 0xB0, 0x9D, 0x54,
        0xF2, 0x5F, 0x56, 0x09, 0xD3, 0x80, 0x20, 0x77,
        0x44, 0x23, 0x90, 0xAB, 0xB6, 0x0B, 0x51, 0xA7,
        0x41, 0xC5, 0xD4, 0x42, 0x5B, 0xD4, 0x67, 0x89,
        0xE6, 0xEC, 0x1E, 0x7D, 0x22, 0xD5, 0x6E, 0x7F,
        0x34, 0xCE, 0x7A, 0x07, 0x2B, 0x63, 0x0A, 0x69,
        0x51, 0x71, 0x8C, 0x13, 0x63, 0xB8, 0x79, 0x6D,
        0x94, 0xEA, 0xAF, 0x86, 0x30, 0xD2, 0x22, 0x6C,
        0x67, 0x82, 0x6C, 0xDE, 0xEA, 0x71, 0xE8, 0xD1,
        0x36, 0xF3, 0x64, 0x2F, 0x79, 0xE6, 0x92, 0xF0,
        0x4B, 0x05, 0x14, 0x7E, 0x40, 0xCE, 0x0C, 0x53,
        0xCA, 0x08, 0xEF, 0x0A, 0xA6, 0xA5, 0x73, 0x99,
        0xFD, 0xF3, 0xED, 0xBD, 0x54, 0x56, 0x6E, 0x66,
        0xEF, 0xCC, 0xE1, 0x6F, 0x0C, 0x44, 0x76, 0x84,
        0xF5, 0x55, 0x2B, 0xA3, 0x6B, 0x20, 0x60, 0x54,
        0x3F, 0xC1, 0x35, 0x58, 0xD8, 0xD8, 0x9E, 0x18,
        0x63, 0x70, 0x73, 0xEF, 0x6A, 0x87, 0x46, 0x77,
        0xA9, 0x7F, 0x9F, 0xA0, 0x23, 0x4B, 0x14, 0x00,
        0x61, 0xC7, 0xE3, 0x44, 0xBE, 0xD6, 0x09, 0x71,
        0xE3, 0x58, 0x44, 0x9A, 0xCD, 0x17, 0xE5, 0x8E,
        0x6D, 0x05, 0xBB, 0x21, 0x44, 0xD7, 0x4B, 0xD8,
        0x9A, 0xE9, 0x7A, 0x75, 0x91, 0x43, 0xAD, 0x84,
        0x5B, 0x02, 0x70, 0xBE, 0x67, 0x0B, 0x1E, 0x1E,
        0x92, 0xB8, 0xC7, 0xB6, 0x5F, 0xE1, 0x60, 0x23,
        0xF5, 0x30, 0xE4, 0xD0, 0xCF, 0x70, 0x03, 0xD1,
        0x85, 0x4A, 0x50, 0xDC, 0xF4, 0x9C, 0x29, 0xAB,
        0x0E, 0xA4, 0x7B, 0x2E, 0x3B, 0xDB, 0xBF, 0x52,
        0xD5, 0x8A, 0x91, 0x47, 0xA9, 0xD1, 0x23, 0xEB,
        0xC5, 0x6F, 0x11, 0xBB, 0xEE, 0xBB, 0x29, 0xD7,
        0x31, 0xAB, 0x99, 0x27, 0x5E, 0xF3, 0xA9, 0x23,
        0xFF, 0x70, 0x87, 0x83, 0xCC, 0x26, 0x92, 0x06,
        0xEC, 0xD3, 0x8C, 0xF9, 0x47, 0x34, 0x7D, 0x1E,
        0x71, 0xAF, 0xCF, 0x9D, 0xBF, 0x29, 0x1B, 0x95,
        0x27, 0x48, 0x55, 0xCE, 0xE2, 0xAC, 0x25, 0x61,
        0x83, 0xD9, 0x7B, 0x26, 0xEF, 0x94, 0x9A, 0x95,
        0x0C, 0xD1, 0xE4, 0x0A, 0x51, 0x50, 0x1F, 0x86,
        0x7A, 0x7B, 0xD3, 0x83, 0x55, 0x2D, 0xFC, 0x7B,
        0x97, 0x77, 0x17, 0x67, 0xBB, 0x9F, 0xD7, 0xD1,
        0xDD, 0xDD, 0x49, 0x67, 0xBB, 0xF7, 0x9A, 0x45,
        0x33, 0x24, 0xCA, 0xBC, 0xA5, 0xB2, 0x0D, 0x3F,
        0xB0, 0x10, 0x6D, 0xB9, 0x7D, 0x03, 0x3F, 0xCD,
        0x40, 0x37, 0x1E, 0x8A, 0xDA, 0xCD, 0xBA, 0xD7,
        0x8D, 0x89, 0xBD, 0x5E, 0x90, 0xCF, 0x97, 0xE8,
        0x35, 0x51, 0x87, 0x94, 0xFA, 0x3D, 0xB2, 0xB5,
        0x01, 0xF2, 0x35, 0x75, 0x77, 0x65, 0x5B, 0x9A,
        0x3C, 0xDA, 0x36, 0x52, 0xDF, 0xCF, 0x96, 0xBA,
        0xB9, 0xC5, 0xF9, 0x57, 0x67, 0x0E, 0x32, 0xE5,
        0x86, 0xE5, 0x1F, 0xD8, 0x9D, 0x7B, 0xA8, 0x76,
        0x89, 0xFD, 0x59, 0x70, 0x88, 0x73, 0x9D, 0x87,
        0xE1, 0x24, 0x6D, 0xC2, 0xB5, 0x1E, 0xCD, 0x54,
        0x29, 0x25, 0x10, 0xA3, 0xB4, 0x3C, 0xB2, 0x5A,
        0x62, 0xBD, 0xE9, 0x14, 0xEC, 0x3C, 0xBF, 0xA9,
        0x9D, 0xEC, 0x70, 0xAC, 0x23, 0xC0, 0xDF, 0xC9,
        0x69, 0xAD, 0x94, 0x1A, 0x69, 0x94, 0xA3, 0x70,
        0xF9, 0x0B, 0x15, 0x5D, 0x25, 0x45, 0x63, 0xFA,
        0xAA, 0x7D, 0x30, 0x67, 0x3C, 0x06, 0x34, 0x75,
        0x3F, 0xD6, 0x57, 0x58, 0x8E, 0xC6, 0x60, 0x3F,
        0x82, 0x35, 0xE9, 0x17, 0x36, 0x5D, 0xD8, 0x93,
        0x25, 0x25, 0x1B, 0x21, 0xB2, 0xFF, 0x80, 0xF5,
        0x44, 0xFE, 0x73, 0x84, 0xFF, 0x62, 0xFE, 0x52,
        0xC4, 0xCA, 0x77, 0x41, 0x28, 0xC8, 0x95, 0x15,
        0x2C, 0xC7, 0x5C, 0xA6, 0x3B, 0xA8, 0xF8, 0x1E,
        0x01, 0x30, 0xC9, 0x3B, 0x59, 0xF9, 0x40, 0xB7,
        0x18, 0x80, 0x21, 0x24, 0xDB, 0x8D, 0x07, 0xDF,
        0xDC, 0x24, 0xBF, 0x2F, 0x7B, 0xD9, 0xC4, 0xEF,
        0x61, 0x74, 0x1A, 0xF2, 0xB6, 0x98, 0x75, 0x66,
        0x22, 0x4F, 0x11, 0x06, 0x41, 0xDB, 0x77, 0x83,
        0xFA, 0xF3, 0x1B, 0xEC, 0xB8, 0xF7, 0x89, 0x47,
        0xBA, 0x12, 0x3F, 0xB0, 0x0E, 0x1B, 0x6D, 0x13,
        0x36, 0x0B, 0x16, 0xD0, 0x7C, 0x3A, 0xAA, 0x33,
        0x6D, 0xDA, 0x1B, 0x65, 0xD4, 0xC2, 0xF2, 0x1B,
        0xD5, 0xCD, 0x4B, 0xE9, 0xED, 0xFA, 0xFA, 0x78,
        0x45, 0x97, 0x2D, 0x60, 0xCC, 0xE3, 0x40, 0x3E,
        0xB5, 0xE5, 0xC8, 0x33, 0xF6, 0x4C, 0x51, 0x45,
        0xDC, 0x08, 0xE7, 0xB3, 0x6F, 0xCF, 0xDE, 0xE8,
        0x73, 0x0B, 0x94, 0x4F, 0x5A, 0x23, 0xF9, 0xFF,
        0x3F, 0x0D, 0x1D, 0xCE, 0x80, 0x86, 0x3B, 0x55,
        0x8D, 0x8A, 0x35, 0xB2, 0xAA, 0x65, 0x27, 0x69,
        0x1D, 0xA5, 0x0C, 0xE6, 0xFA, 0x39, 0x85, 0x62,
        0x65, 0xAD, 0xE6, 0x08, 0x38, 0xCE, 0xC9, 0xEA,
        0x98, 0x73, 0x99, 0x1D, 0xB5, 0x6F, 0xEA, 0xE8,
        0xEE, 0xE2, 0xEC, 0xF4, 0x32, 0x44, 0x96, 0x5A,
        0x13, 0xCC, 0x1D, 0x23, 0x0E, 0x91, 0x72, 0xD8,
        0x2A, 0xD2, 0x3D, 0x6A, 0x6E, 0x2A, 0x37, 0x7A,
        0x7F, 0x67, 0xF6, 0x40, 0xBF, 0x3A, 0x36, 0x3B,
        0xC8, 0x1A, 0x78, 0x6D, 0x12, 0xB0, 0x35, 0xA3,
        0x18, 0x55, 0x33, 0x70, 0x48, 0x48, 0x52, 0x8F,
        0xB4, 0x59, 0x58, 0xEB, 0xAA, 0xB3, 0x03, 0x67,
        0x4F, 0xFF, 0xA5, 0x68, 0xE7, 0xAE, 0xAF, 0x46,
        0x3D, 0x66, 0x6B, 0x60, 0x21, 0x26, 0x31, 0x83,
        0xBE, 0xE8, 0x1E, 0x72, 0x92, 0x87, 0x79, 0x24,
        0xCF, 0xDE, 0xEF, 0x6F, 0x81, 0x73, 0xA1, 0x34,
        0x7B, 0x99, 0x94, 0x43, 0x33, 0xF4, 0x8B, 0x36,
        0xC8, 0xC5, 0xF8, 0xC1, 0x6D, 0x22, 0x6D, 0xA3,
        0xC9, 0xDA, 0x5F, 0x4C, 0xE7, 0x7F, 0x00, 0xE4,
        0x42, 0xD8, 0x5C, 0x73, 0xE5, 0x78, 0x0C, 0x36,
        0x28, 0xD9, 0x83, 0x8F, 0xCA, 0xFA, 0x5D, 0x1D,
        0x34, 0x05, 0xF1, 0x93, 0x6C, 0xBC, 0xFD, 0x2C,
        0x52, 0xD4, 0xE8, 0x8D, 0xA9, 0xC9, 0x0D, 0xFF,
        0x28, 0x5E, 0x3E, 0x91, 0x12, 0xC0, 0x3C, 0xBA,
        0x58, 0x64, 0x7E, 0x6B, 0x4E, 0xC0, 0x77, 0xB1,
        0x67, 0x08, 0x16, 0xF5, 0x7E, 0x29, 0x42, 0x81,
        0x6A, 0x6F, 0x34, 0x21, 0x32, 0x64, 0x9A, 0xA6,
        0x44, 0xD1, 0x4F, 0x41, 0xAB, 0xC5, 0x26, 0x4A,
        0xFA, 0x70, 0xBC, 0xAE, 0x3D, 0x67, 0x9B, 0x86,
        0xF5, 0x1A, 0xF2, 0x44, 0x70, 0x52, 0xD0, 0x78,
        0xA0, 0xEA, 0x56, 0x39, 0x0B, 0x37, 0x2A, 0x15,
        0x13, 0xBC, 0xD2, 0xEA, 0x46, 0x6D, 0xCB, 0x5A,
        0x4D, 0x86, 0x47, 0x4F, 0xA1, 0xE2, 0x6B, 0xC0,
        0xA8, 0x3F, 0x58, 0x5C, 0x79, 0xAD, 0x62, 0x17,
        0xBC, 0x96, 0xAF, 0x77, 0x1F, 0x74, 0xD1, 0x42,
        0xBF, 0x5E, 0x91, 0xA9, 0x28, 0x44, 0xC5, 0x4E,
        0x76, 0x6B, 0xF2, 0xD3, 0x69, 0x8C, 0x0E, 0x4F,
        0x61, 0x76, 0xAD, 0xDC, 0x79, 0xE9, 0x74, 0xA4,
        0x66, 0xFB, 0x2E, 0x0C, 0xBB, 0x42, 0xC5, 0x3F,
        0x59, 0xB0, 0xDC, 0xB0, 0x32, 0xCD, 0x37, 0x56,
        0x1B, 0xD2, 0x46, 0xED, 0x52, 0xC8, 0x12, 0xEA,
        0xA3, 0x6B, 0xB9, 0xE5, 0xB3, 0x2A, 0xF3, 0x9B,
        0x0F, 0xC3, 0x77, 0x5F, 0x9A, 0xE1, 0x20, 0xBC,
        0x59, 0x44, 0x9B, 0x7B, 0x77, 0xB1, 0xBA, 0x1A,
        0x5B, 0x60, 0x06, 0x6C, 0x85, 0x83, 0x68, 0xDD,
        0x5A, 0xC8, 0xEE, 0xDC, 0xFE, 0x1F, 0x83, 0xF5,
        0x2C, 0x53, 0x62, 0xED, 0xE8, 0x93, 0xB7, 0x22,
        0x3E, 0xCB, 0x70, 0xBA, 0xA6, 0x6D, 0xB2, 0x91,
        0x47, 0xB8, 0x04, 0x37, 0x20, 0x1F, 0xEF, 0x71,
        0xB0, 0x5F, 0xF2, 0x51, 0x03, 0x5F, 0x88, 0xCA,
        0xFF, 0x42, 0xE8, 0x2A, 0x43, 0x02, 0xD3, 0x60,
        0x98, 0x26, 0x8B, 0x74, 0xF4, 0x18, 0x3D, 0x4D,
        0x19, 0xF1, 0x3B, 0x87, 0xE9, 0x83, 0x37, 0x15,
        0x7D, 0xA5, 0xEF, 0xBB, 0xF3, 0x4F, 0x48, 0xCA,
        0x40, 0x65, 0xD3, 0xE3, 0xBA, 0xCC, 0x83, 0x83,
        0x3F, 0xEE, 0xBA, 0x57, 0x34, 0x6D, 0x16, 0x9F,
        0x1B, 0xE6, 0xA0, 0x4C, 0x29, 0xC8, 0x2F, 0xD2,
        0x25, 0xA3, 0xF7, 0xC6, 0x85, 0x12, 0x4F, 0x53,
        0x7E, 0xC0, 0xE1, 0x0A, 0xB8, 0x58, 0x34, 0xBA,
        0x3E, 0x65, 0x4F, 0x19, 0x55, 0x5C, 0xB9, 0x74,
        0x6B, 0x74, 0xCE, 0x43, 0xA2, 0xC7, 0x8B, 0x21,
        0x70, 0x8C, 0x3B, 0xEF, 0x87, 0xC1, 0xE8, 0x8F,
        0x08, 0x10, 0xB4, 0xED, 0xE1, 0x81, 0x14, 0xE9,
        0x2A, 0x43, 0x13, 0xB4, 0xEA, 0xA0, 0x5F, 0x60,
        0x93, 0x7E, 0x87, 0x6D, 0xA2, 0x57, 0x63, 0x32,
        0xAE, 0xC3, 0x8C, 0xCD, 0x42, 0x5E, 0xFD, 0x51,
        0x1A, 0x39, 0xB9, 0xB4, 0xBD, 0x4C, 0xF3, 0xF2,
        0xE2, 0x70, 0x9A, 0x05, 0xF9, 0x39, 0xE5, 0xFC,
        0x59, 0x7D, 0x4E, 0x85, 0x12, 0x02, 0xC9, 0xC2,
        0xC5, 0x71, 0x3A, 0xD5, 0x73, 0xF7, 0x5A, 0xC5,
        0x49, 0x0D, 0xEE, 0xCF, 0x9D, 0xB8, 0xDE, 0xE2,
        0x03, 0x99, 0x70, 0x6B, 0x19, 0x29, 0xA4, 0xE8,
        0x99, 0x00, 0xC4, 0x9C, 0x24, 0x46, 0x5E, 0x08,
        0x09, 0x56, 0x6D, 0x9C, 0x2E, 0xF7, 0x8C, 0x52,
        0xDB, 0xB4, 0x2F, 0x9E, 0x22, 0x7E, 0xFD, 0x1E,
        0x1A, 0x72, 0xCB, 0x71, 0x0B, 0xD2, 0x19, 0x33,
        0x0E, 0x69, 0xCC, 0x00, 0x49, 0x36, 0x79, 0x78,
        0xAB, 0x11, 0x4D, 0x9A, 0xD7, 0xF9, 0x55, 0xCF,
        0x0B, 0x7B, 0x3D, 0x32, 0x5C, 0xB3, 0x51, 0x65,
        0x00, 0x0E, 0xD2, 0x9D, 0xBE, 0x0A, 0x19, 0x56,
        0xF1, 0x45, 0x95, 0x83, 0xC6, 0x97, 0xCD, 0x19,
        0xE7, 0x8B, 0x51, 0x74, 0xE4, 0xFD, 0x2C, 0xEC,
        0x10, 0x8A, 0x7C, 0x24, 0x28, 0x0A, 0x78, 0xA3,
        0xEC, 0x93, 0x97, 0x16, 0x4F, 0x60, 0x03, 0xFD,
        0x85, 0x31, 0x98, 0x04, 0xE5, 0x65, 0x5A, 0x87,
        0x9F, 0x66, 0x3D, 0xD4, 0x56, 0x3E, 0xF9, 0x98,
        0x25, 0x21, 0xFE, 0xC2, 0x07, 0x9E, 0x88, 0x89,
        0x49, 0x7B, 0xE9, 0x20, 0x1F, 0x6D, 0x7F, 0x24,
        0x60, 0xA8, 0xB2, 0xDD, 0x96, 0x51, 0x0E, 0x0E,
        0x4C, 0x83, 0xC3, 0xB1, 0x93, 0xC1, 0x1F, 0xD6,
        0xB4, 0xB6, 0x84, 0xCE, 0x85, 0x63, 0xA5, 0x38,
        0x0F, 0x2E, 0x55, 0xF4, 0x74, 0xA6, 0x0B, 0x63,
        0x17, 0xD0, 0x96, 0x76, 0x15, 0xAD, 0x4F, 0xA9,
        0xF0, 0x83, 0x25, 0xAD, 0xD7, 0x97, 0xB7, 0x9E,
        0x6F, 0x5D, 0xC7, 0x2A, 0xD1, 0x97, 0xF5, 0xF6,
        0x1E, 0xC8, 0x8B, 0xE5, 0xFB, 0xFF, 0x92, 0x72,
        0x31, 0x9A, 0x49, 0x4B, 0x60, 0x8F, 0x34, 0x7C,
        0xE1, 0x55, 0x66, 0x7A, 0x59, 0xC3, 0x00, 0x9A,
        0x14, 0x50, 0xF3, 0x06, 0x19, 0x3C, 0xFE, 0x61,
        0x1C, 0xF7, 0x05, 0x49, 0x2A, 0x30, 0xFF, 0x56,
        0xFE, 0x7F, 0x71, 0xD7, 0x32, 0xCC, 0xEF, 0x63,
        0x64, 0xE1, 0x66, 0xCF, 0xF8, 0x12, 0xED, 0x23,
        0x11, 0xB5, 0x16, 0xFA, 0x56, 0x90, 0xF2, 0xA2,
        0x72, 0x7B, 0x18, 0x50, 0xF2, 0x98, 0x5D, 0x48,
        0x25, 0x5E, 0x8C, 0x47, 0xE7, 0x11, 0x50, 0x2A,
        0x4B, 0x4A, 0x97, 0x0B, 0xDF, 0x70, 0xDC, 0x34,
        0x47, 0xF8, 0xE2, 0x88, 0x78, 0x24, 0xB5, 0x8A,
        0xC7, 0x58, 0xE8, 0x83, 0xF7, 0x3B, 0xAD, 0xFC,
        0xED, 0x46, 0x40, 0xD5, 0x46, 0x35, 0x1B, 0xF3,
        0x3E, 0x8F, 0x1E, 0x0B, 0x1B, 0xB9, 0xFB, 0x5A,
        0xFF, 0x0F, 0x8B, 0xA0, 0x95, 0x4A, 0x8E, 0x65,
        0x33, 0xD3, 0x7C, 0x03, 0x04, 0x8E, 0xBA, 0x6A,
        0x55, 0xB3, 0xC5, 0xDA, 0xCB, 0xDC, 0x44, 0xD3,
        0x98, 0x77, 0xD3, 0x07, 0x8A, 0xE9, 0x5E, 0x44,
        0x5B, 0xED, 0x12, 0xB1, 0xA5, 0x03, 0xAF, 0xB2,
        0x20, 0x0C, 0xB1, 0x8B, 0x08, 0xB4, 0x6A, 0x11,
        0x96, 0xA9, 0xF5, 0x7A, 0xFD, 0x56, 0x48, 0x11,
        0xC0, 0x30, 0xA4, 0x45, 0xFC, 0xAE, 0x72, 0xE5,
        0x5E, 0x85, 0xB7, 0x6F, 0xA0, 0x50, 0x13, 0x4B,
        0x2E, 0xC2, 0x31, 0x13, 0xED, 0x04, 0x04, 0x3D,
        0xBC, 0xD0, 0xB6, 0xFC, 0xCE, 0xBD, 0xC9, 0x13,
        0x5C, 0xB2, 0x02, 0xB8, 0x4F, 0xDD, 0x74, 0x51,
        0x1F, 0x9E, 0x8F, 0x0C, 0xF2, 0x26, 0xE1, 0x4C,
        0xA5, 0xC4, 0x38, 0xC7, 0x6A, 0xA5, 0xC3, 0xC2,
        0xE9, 0xF3, 0x22, 0x71, 0x00, 0x91, 0x83, 0xEE,
        0x92, 0xA9, 0x95, 0x81, 0x9D, 0xB9, 0x0F, 0x66,
        0x89, 0x9B, 0xB9, 0xB0, 0xC7, 0xED, 0x31, 0xDF,
        0x41, 0xB6, 0x8E, 0x52, 0xAC, 0x5B, 0xBD, 0xF2,
        0x33, 0x9F, 0x71, 0x5E, 0x43, 0xFE, 0xED, 0xD9,
        0x4F, 0x57, 0xF9, 0x23, 0x05, 0x23, 0x03, 0x34,
        0x17, 0xE4, 0x22, 0x27, 0x97, 0xF7, 0x62, 0x5B,
        0x52, 0x66, 0x70, 0xEE, 0x6B, 0xD3, 0x46, 0x8C,
        0xCD, 0x9B, 0xA4, 0xA1, 0xED, 0x26, 0x4A, 0xAC,
        0xC2, 0x50, 0xA8, 0x2A, 0x48, 0x83, 0x46, 0xB2,
        0xA5, 0xF9, 0x26, 0xF2, 0xE7, 0x8A, 0x8E, 0xD8,
        0x40, 0x5F, 0x85, 0x8E, 0xAB, 0xB0, 0x29, 0xF7,
        0x81, 0x42, 0xA7, 0x4B, 0xD5, 0xA8, 0x2D, 0x3D,
        0xD7, 0x0A, 0xB1, 0x26, 0xCF, 0xA3, 0xBA, 0xD7,
        0xF5, 0x1B, 0x9E, 0x95, 0xCB, 0xC8, 0xCE, 0x75,
        0xE7, 0x7A, 0x4A, 0x1B, 0x63, 0x21, 0xB7, 0x74,
        0x77, 0x78, 0xCD, 0x03, 0x5B, 0x3B, 0xCD, 0x44,
        0x8E, 0xF1, 0xBB, 0xB6, 0xFF, 0x75, 0x52, 0x8A,
        0x7A, 0xE9, 0xAF, 0x62, 0x24, 0xA1, 0x6F, 0x4F,
        0x45, 0x03, 0x87, 0xA3, 0xED, 0xBC, 0x2E, 0x92,
        0xC0, 0xB1, 0x9C, 0x22, 0x2E, 0x35, 0xC1, 0xA5,
        0x7E, 0xC3, 0x36, 0x3B, 0x18, 0x14, 0x78, 0x6E,
        0x1D, 0x37, 0xD7, 0x92, 0xB3, 0x78, 0x26, 0x13,
        0x9A, 0xFB, 0x38, 0x1D, 0xE0, 0x4C, 0x07, 0xC4,
        0x2C, 0xD3, 0xCA, 0x78, 0xE4, 0x70, 0xC2, 0x52,
        0x7C, 0x63, 0xDB, 0x4B, 0xB4, 0x0A, 0x4B, 0x7D,
        0x20, 0x67, 0xF0, 0xF4, 0x80, 0x5B, 0x65, 0x8B,
        0x29, 0x80, 0x92, 0xF0, 0x87, 0x3D, 0x09, 0x5A,
        0x0E, 0xEA, 0x45, 0x63, 0x92, 0x99, 0xD6, 0x0D,
        0x2B, 0x58, 0xEE, 0x19, 0x03, 0x4F, 0x94, 0x2D,
        0xEC, 0xBF, 0x5A, 0xE9, 0xA6, 0x16, 0xAF, 0x72,
        0x37, 0x5C, 0x12, 0xBB, 0x7D, 0xED, 0xAA, 0x6A,
        0x7D, 0xDF, 0x9A, 0x48, 0x37, 0x37, 0x3D, 0x7B,
        0x51, 0x96, 0x0B, 0x30, 0xCE, 0x9C, 0xE7, 0x3B,
        0x3C, 0x10, 0xDE, 0x32, 0xA7, 0x86, 0x39, 0xA9,
        0x33, 0x7D, 0x9B, 0xCF, 0x15, 0x27, 0xA4, 0x36,
        0x88, 0xBD, 0xB6, 0xEB, 0x8B, 0xD0, 0x3D, 0xCA,
        0xF1, 0x02, 0x70, 0xDF, 0xC0, 0xE2, 0xF0, 0xD2,
        0x2C, 0x27, 0xE3, 0x22, 0x24, 0x33, 0x27, 0x34,
        0xCA, 0x26, 0x19, 0x74, 0x02, 0x2F, 0x7E, 0xC1,
        0x76, 0xCB, 0x12, 0xBE, 0x6F, 0x13, 0x62, 0x1F,
        0x32, 0x03, 0x65, 0xCF, 0xBB, 0x03, 0xD0, 0x4C,
        0xF2, 0x9E, 0xFE, 0x93, 0xE9, 0x1B, 0x02, 0x9B,
        0x7B, 0x26, 0xFF, 0xEE, 0xF0, 0x6F, 0xCE, 0x57,
        0xD1, 0x2B, 0xE3, 0x90, 0x2E, 0xE2, 0x71, 0x2A,
        0xBA, 0xCC, 0x3D, 0x27, 0xCE, 0xA3, 0x5A, 0xCA,
        0x15, 0x09, 0xE4, 0xD0, 0x86, 0x4F, 0xEC, 0x5A,
        0x5B, 0x41, 0xA0, 0xE0, 0x3E, 0x1D, 0xEC, 0x6F,
        0x2A, 0x33, 0x72, 0x15, 0xCD, 0xE5, 0x55, 0xD6,
        0x6F, 0x84, 0xE3, 0xD6, 0x75, 0x5D, 0xDC, 0x1C,
        0x07, 0x3D, 0x0C, 0xDC, 0xDE, 0xF8, 0x8A, 0x44,
        0x40, 0xB1, 0x76, 0x84, 0xB8, 0xE0, 0xAF, 0x9D,
        0xA2, 0xB2, 0x84, 0xAA, 0xBF, 0x61, 0x08, 0x21,
        0xE5, 0xC2, 0xC9, 0x11, 0x94, 0x2D, 0x0B, 0xD1,
        0xC6, 0x59, 0xC1, 0xEE, 0xBA, 0x8E, 0x21, 0xAF,
        0xDE, 0x32, 0x77, 0xD5, 0x07, 0x3B, 0x98, 0x39,
        0x95, 0x77, 0x03, 0x80, 0x2F, 0xA2, 0x76, 0xC8,
        0x2C, 0xC6, 0x6A, 0x00, 0xA8, 0x69, 0x77, 0xB8,
        0x87, 0x7D, 0xC0, 0x51, 0x19, 0x45, 0x14, 0xA6,
        0x33, 0xB3, 0x4D, 0x36, 0x29, 0x34, 0xE8, 0x50,
        0xC2, 0x71, 0x7A, 0x0B, 0xE5, 0x92, 0x4E, 0x86,
        0xAA, 0xDA, 0x33, 0xCF, 0x34, 0x54, 0x63, 0x2C,
        0x68, 0xA1, 0x0A, 0xEF, 0x8B, 0x5B, 0xAA, 0x10,
        0x83, 0xE9, 0x13, 0x7D, 0x29, 0x20, 0xA2, 0x5F,
        0x96, 0x9F, 0x54, 0x0B, 0x95, 0xDF, 0x59, 0x91,
        0x6C, 0x4C, 0xAC, 0xC4, 0x55, 0x98, 0x8F, 0x46,
        0x31, 0x77, 0x56, 0xCC, 0x93, 0x7E, 0xF0, 0x17,
        0x7C, 0x0F, 0xEB, 0x3F, 0x23, 0xBB, 0xD3, 0x56,
        0x9E, 0x89, 0x67, 0xC4, 0x9B, 0x95, 0xA3, 0xBF,
        0x6D, 0x9D, 0x6D, 0x7C, 0x72, 0x27, 0x20, 0x6E,
        0x28, 0x37, 0x39, 0xFC, 0x77, 0x41, 0xE9, 0xFE,
        0x64, 0xEF, 0xA0, 0x38, 0x9F, 0xC7, 0x2F, 0xDA,
        0xC8, 0x1F, 0xEB, 0x75, 0x07, 0xB8, 0x7E, 0x6B,
        0x73, 0xCE, 0x0E, 0x7C, 0x7C, 0x54, 0x06, 0x1D,
        0x48, 0x8A, 0x06, 0x53, 0x95, 0x9B, 0x75, 0x8A,
        0xFF, 0x6F, 0x7D, 0x19, 0x00, 0x17, 0x8D, 0x7C,
        0x1A, 0xEA, 0xD0, 0x79, 0x45, 0x68, 0xF9, 0x2F,
        0x8A, 0xCE, 0x98, 0xED, 0xCC, 0xE8, 0x6D, 0xE1,
        0x08, 0xA0, 0x50, 0x2C, 0x43, 0x49, 0xC4, 0x99,
        0x98, 0x31, 0xDE, 0x00, 0xE8, 0x08, 0x39, 0x0B,
        0xBB, 0xDB, 0x65, 0xEA, 0x36, 0x0F, 0xBE, 0x98,
        0xB7, 0x4A, 0x9C, 0x59, 0x34, 0x0E, 0xBB, 0xDD,
        0x6F, 0x65, 0x21, 0x39, 0x23, 0x48, 0x57, 0x7F,
        0xD4, 0x07, 0x89, 0x03, 0x01, 0xB0, 0x79, 0x27,
        0x28, 0xCC, 0xFB, 0x88, 0xC5, 0xDD, 0x47, 0x2A,
        0xDA, 0x73, 0x75, 0x9B, 0xC9, 0x99, 0xA0, 0x21,
        0x34, 0xDF, 0xB1, 0x62, 0x2F, 0x61, 0xD8, 0xB7,
        0x63, 0x2A, 0xC7, 0x7E, 0x3A, 0x98, 0x0B, 0x2C,
        0xE5, 0x66, 0xF3, 0xD5, 0x30, 0xF0, 0xBC, 0x21,
        0xC7, 0x51, 0x9B, 0xFB, 0x00, 0xBB, 0xAA, 0x9C,
        0x85, 0xC3, 0x9B, 0x0C, 0xDC, 0x5F, 0x8D, 0x1B,
        0xA1, 0x2B, 0x78, 0x82, 0xFE, 0x0F, 0x7C, 0x75,
        0x6E, 0x75, 0x56, 0x74, 0x35, 0x25, 0xE5, 0xD0,
        0xEC, 0x8E, 0xC1, 0xBD, 0x7D, 0x7A, 0xE3, 0xDC,
        0xAD, 0xC6, 0x8D, 0xB6, 0x0D, 0x7A, 0xA1, 0x3C,
        0xDB, 0x29, 0xFA, 0x15, 0xC0, 0xA9, 0xAF, 0x89,
        0x0F, 0x18, 0x75, 0xE3, 0x97, 0x58, 0x62, 0x12,
        0x79, 0xA9, 0x87, 0x7D, 0x9C, 0x69, 0x44, 0x9C,
        0x41, 0x39, 0x2C, 0xAD, 0x98, 0x8B, 0x8D, 0xE4,
        0x58, 0xEE, 0xCD, 0x98, 0x38, 0x5F, 0x79, 0x73,
        0x0B, 0x5E, 0x26, 0xC1, 0x16, 0x24, 0x15, 0xD9,
        0x73, 0x26, 0x41, 0x9B, 0x5F, 0xF9, 0x2A, 0xA8,
        0xC1, 0x33, 0x74, 0x39, 0x1D, 0xBB, 0xE7, 0x36,
        0xD9, 0x8C, 0x07, 0xAD, 0x32, 0xD6, 0x38, 0xBB,
        0x44, 0xE6, 0x77, 0xC7, 0x11, 0x05, 0xCF, 0xB5,
        0x72, 0x49, 0x68, 0x80, 0xC1, 0x67, 0x71, 0x5F,
        0x9B, 0xFF, 0x6E, 0x71, 0x1A, 0xBE, 0x5A, 0x83,
        0x25, 0x38, 0xC7, 0xE6, 0xDA, 0x88, 0x22, 0xDC,
        0xA6, 0x03, 0x02, 0xD1, 0x59, 0xC6, 0xA8, 0x2F,
        0xA4, 0x8F, 0xF8, 0x77, 0x3E, 0x0C, 0x6F, 0xA1,
        0x73, 0xE1, 0x35, 0x55, 0xB2, 0xDF, 0xBF, 0x47,
        0xB7, 0xD0, 0x8D, 0xBA, 0x35, 0x74, 0x44, 0x6B,
        0xC0, 0xA7, 0x8D, 0x30, 0x08, 0xE4, 0x41, 0xD1,
        0x55, 0x21, 0x50, 0xD9, 0x06, 0x12, 0x54, 0xB2,
        0xF3, 0xFC, 0x5A, 0x1E, 0xF3, 0xE3, 0x84, 0x33,
        0x34, 0x0B, 0xB5, 0x9A, 0x97, 0xFD, 0x51, 0xF4,
        0x68, 0xFE, 0x8A, 0x92, 0xBF, 0x62, 0x9D, 0xCD,
        0x00, 0x29, 0x39, 0x37, 0x12, 0xF3, 0x53, 0x6D,
        0x6B, 0x24, 0xB8, 0x86, 0x68, 0xAD, 0x6A, 0x4B,
        0x3A, 0x4C, 0x93, 0xA6, 0xB1, 0x41, 0xFA, 0x8E,
        0x58, 0x63, 0xCD, 0x59, 0x80, 0xBF, 0xD7, 0xAB,
        0x83, 0xC3, 0xCC, 0x5D, 0x2F, 0xBE, 0x80, 0xC7,
        0xB1, 0x67, 0xDC, 0x92, 0x8C, 0xA9, 0x57, 0x36,
        0x58, 0x0A, 0x52, 0x96, 0x0E, 0x20, 0x90, 0xCD,
        0x87, 0x68, 0xF5, 0x93, 0xBB, 0x04, 0xD4, 0x48,
        0xB6, 0x45, 0x30, 0xC0, 0xE3, 0xC2, 0x56, 0x8C,
        0xE3, 0xA2, 0xC6, 0x42, 0x0F, 0x81, 0xF7, 0x4D,
        0xF6, 0x88, 0x5D, 0x55, 0x07, 0x8E, 0xF1, 0xB3,
        0x83, 0xB0, 0x20, 0x85, 0x4A, 0x63, 0x6A, 0x78,
        0xA9, 0xEC, 0x13, 0x84, 0xF7, 0x4E, 0xBE, 0xB6,
        0x5F, 0x5A, 0x25, 0xFF, 0xD4, 0x14, 0x7D, 0xA7,
        0xEE, 0x40, 0xF6, 0x25, 0x7C, 0x7E, 0x34, 0xCA,
        0xC9, 0x27, 0x0E, 0xA2, 0x78, 0xB6, 0xE6, 0x08,
        0xA1, 0x9B, 0x56, 0x8D, 0x29, 0xE5, 0x8D, 0xEC,
        0xAD, 0xDA, 0xD3, 0x3C, 0x59, 0xBA, 0xDB, 0x92,
        0x52, 0x99, 0x3B, 0x31, 0x6B, 0x0B, 0x13, 0x00,
        0x79, 0x3D, 0x69, 0x85, 0x3A, 0x6B, 0x90, 0x33,
        0x96
    };
    static const byte rnd_44[] = {
        0x08, 0x34, 0x57, 0xD4, 0x0E, 0x25, 0x04, 0x88,
        0xA6, 0x0E, 0x76, 0x34, 0xA0, 0x1D, 0x43, 0x0A,
        0x60, 0xE8, 0x57, 0x2B, 0xA8, 0x8A, 0xED, 0xC5,
        0x54, 0x49, 0x18, 0x81, 0x37, 0x13, 0xA0, 0xB1
    };
    static const byte sig_44[] = {
        0x63, 0xA8, 0x23, 0x20, 0xD4, 0xCE, 0x09, 0xC4,
        0x7A, 0xD1, 0x27, 0xC5, 0xBB, 0x7F, 0x6C, 0x2D,
        0xFF, 0x15, 0x29, 0xCD, 0xAF, 0x9F, 0x74, 0x56,
        0xFF, 0xC2, 0xC6, 0xED, 0x90, 0x51, 0x17, 0xDC,
        0xAD, 0x8C, 0x08, 0x7A, 0xC0, 0xD8, 0x9E, 0x0C,
        0xE9, 0x61, 0xC0, 0x94, 0xFA, 0x9C, 0x2E, 0xDE,
        0x27, 0x9C, 0x65, 0xE6, 0x99, 0xD1, 0xD1, 0x7E,
        0xA6, 0x95, 0x98, 0x8F, 0xA1, 0xC4, 0x98, 0x3F,
        0x7E, 0x1F, 0x18, 0x86, 0x2A, 0xFE, 0xB2, 0xEC,
        0x9D, 0x0F, 0x5B, 0x0C, 0x11, 0xB2, 0xAA, 0x0B,
        0xDE, 0x95, 0x7C, 0x40, 0xA1, 0x5B, 0xFF, 0x97,
        0xD7, 0xCB, 0xCF, 0x4E, 0x59, 0xDA, 0xE9, 0xD5,
        0xA3, 0xC9, 0xF8, 0x7D, 0xDD, 0xA5, 0xB9, 0x06,
        0x9D, 0x82, 0xCC, 0x18, 0x10, 0x20, 0x80, 0x92,
        0xBC, 0xBA, 0x1C, 0x43, 0x73, 0xF2, 0xA8, 0x3E,
        0x19, 0x15, 0x80, 0x9E, 0x81, 0xD8, 0xD2, 0x06,
        0xEA, 0x78, 0x10, 0x3F, 0x68, 0x66, 0x3D, 0xBE,
        0xB1, 0x79, 0xB0, 0x28, 0x83, 0xCD, 0xD3, 0x33,
        0xEE, 0xFE, 0x6D, 0x02, 0x39, 0x17, 0xC6, 0xF2,
        0xA4, 0x6E, 0x5A, 0x5C, 0x45, 0x14, 0xF5, 0x7D,
        0xCA, 0x7B, 0x62, 0x4A, 0xF4, 0xE7, 0x71, 0x7B,
        0xD7, 0x1B, 0x51, 0x26, 0xE6, 0xDE, 0x2D, 0xC9,
        0x65, 0x24, 0x30, 0x2C, 0x08, 0x04, 0xD7, 0xBE,
        0x3A, 0xDA, 0x64, 0xAF, 0x11, 0x6F, 0xC6, 0xE7,
        0x38, 0xEF, 0xA6, 0xE6, 0x5E, 0x87, 0x90, 0xB4,
        0x0E, 0xB1, 0xB4, 0x83, 0x64, 0xD2, 0x15, 0xEF,
        0xD6, 0x1F, 0x7A, 0x44, 0x75, 0x3A, 0x95, 0x50,
        0x6E, 0x52, 0xC9, 0x9C, 0xE9, 0xB4, 0x56, 0xDC,
        0x93, 0x85, 0x92, 0xF1, 0x35, 0xEC, 0x50, 0x1B,
        0x3B, 0xCF, 0x82, 0xDA, 0x69, 0xA1, 0xDD, 0x44,
        0xE8, 0xB3, 0xC1, 0xCB, 0x8D, 0xD5, 0x13, 0xD0,
        0xF3, 0x14, 0x2C, 0x80, 0x82, 0x2C, 0x31, 0xBF,
        0x75, 0x20, 0x14, 0x39, 0x9F, 0x81, 0x79, 0x76,
        0x0F, 0xB6, 0x7D, 0xB6, 0x58, 0x1C, 0xF3, 0xE6,
        0x93, 0x5A, 0x9B, 0xE1, 0x8B, 0x92, 0xC2, 0xDB,
        0xF1, 0x89, 0xAA, 0x46, 0x67, 0xFA, 0x80, 0x45,
        0x72, 0xAA, 0xB4, 0xE2, 0x5E, 0xE9, 0xD1, 0xA7,
        0xA0, 0xD7, 0x05, 0x5C, 0xC6, 0xC7, 0x6D, 0x1D,
        0x66, 0x3D, 0x35, 0x0C, 0xB7, 0x1A, 0xFA, 0xB1,
        0xDB, 0xD0, 0xCB, 0x3A, 0x8B, 0xB7, 0x1B, 0x03,
        0x60, 0xA0, 0xA4, 0xDA, 0xD0, 0xE2, 0x3A, 0x1E,
        0xB5, 0xE4, 0x59, 0x68, 0x6A, 0x02, 0x94, 0x66,
        0x05, 0x60, 0x08, 0x64, 0xB4, 0xEE, 0x0F, 0x3A,
        0xCE, 0xFD, 0x40, 0x7B, 0x6F, 0xF5, 0x8D, 0x1E,
        0xFF, 0x0C, 0x75, 0xAF, 0xC1, 0x41, 0xC6, 0x24,
        0x1D, 0xF3, 0x76, 0x02, 0x48, 0x6B, 0xBA, 0x58,
        0xBC, 0xBB, 0xFE, 0xD3, 0x51, 0xC2, 0x68, 0x21,
        0x4B, 0x20, 0x4E, 0xAF, 0x8A, 0x0C, 0x74, 0x7F,
        0x5F, 0xB7, 0xAA, 0x43, 0xFC, 0x5A, 0x77, 0xA1,
        0x81, 0xCD, 0xBA, 0xE1, 0x31, 0x87, 0x1F, 0xA8,
        0x1F, 0x76, 0x30, 0x6C, 0xE0, 0x84, 0xCD, 0x14,
        0x4A, 0xDB, 0x67, 0xFD, 0x65, 0x8C, 0x35, 0xC0,
        0x91, 0x6C, 0x2B, 0xCF, 0x5B, 0x89, 0x29, 0x58,
        0x42, 0x9B, 0x65, 0xDB, 0x34, 0x7D, 0xD8, 0x31,
        0xC9, 0xB8, 0x0D, 0x07, 0xD1, 0x94, 0x60, 0x63,
        0x65, 0xDC, 0xB3, 0x70, 0x48, 0x46, 0x37, 0x18,
        0x4D, 0x5D, 0xE0, 0xAC, 0x77, 0xD0, 0x9E, 0xE1,
        0xD9, 0xB2, 0x2D, 0x09, 0xD6, 0xF8, 0x94, 0x96,
        0x7B, 0x43, 0xD9, 0x76, 0x36, 0xE6, 0x24, 0xA4,
        0x4A, 0xFF, 0x12, 0xFE, 0x30, 0x95, 0xD7, 0xCB,
        0xA9, 0xA0, 0x3A, 0xCA, 0xFC, 0x52, 0x57, 0xB8,
        0x20, 0x80, 0xF2, 0xD8, 0xAE, 0x3E, 0x18, 0xFC,
        0x0D, 0xE0, 0x9D, 0x01, 0x7B, 0x03, 0xAD, 0x6B,
        0xEE, 0xA4, 0xEC, 0x38, 0x40, 0xAC, 0x85, 0x42,
        0xF8, 0xCF, 0x93, 0x10, 0x8F, 0x8C, 0xFE, 0xF8,
        0x22, 0x64, 0xFC, 0xDD, 0x2C, 0xDD, 0x86, 0x97,
        0x5B, 0x3F, 0x8F, 0xDF, 0x1F, 0x58, 0x22, 0x08,
        0x26, 0x8A, 0x76, 0xE6, 0xC9, 0xFE, 0xDF, 0x42,
        0x90, 0x8D, 0x52, 0x78, 0xA2, 0xBF, 0xBD, 0x3F,
        0xD5, 0xD5, 0xDB, 0xAF, 0xDD, 0x5E, 0x2C, 0x2B,
        0x9F, 0x2E, 0xDC, 0xC1, 0xC4, 0x52, 0x96, 0x38,
        0x49, 0xCB, 0x34, 0xEC, 0x51, 0x00, 0x8D, 0x1B,
        0xF6, 0xDA, 0x50, 0xA0, 0xD1, 0x9D, 0x82, 0x34,
        0x5B, 0x78, 0x8C, 0x05, 0x40, 0xE1, 0x7B, 0x25,
        0xFF, 0xDC, 0xE8, 0xD4, 0x45, 0x3B, 0xBE, 0x75,
        0x1E, 0xDA, 0x96, 0xA4, 0x4C, 0x75, 0xFD, 0xD9,
        0x00, 0x81, 0x85, 0x7D, 0xC0, 0xF8, 0x26, 0x2A,
        0x30, 0x7B, 0x34, 0xCB, 0xEC, 0xD1, 0x56, 0x58,
        0x69, 0xA3, 0x14, 0xD6, 0x4C, 0x09, 0xDC, 0x9D,
        0x4A, 0x80, 0x26, 0x52, 0x2F, 0xDF, 0xE4, 0xCB,
        0x5B, 0x8B, 0x11, 0x05, 0xDA, 0xE0, 0xDB, 0x66,
        0xC8, 0x5B, 0xB4, 0x32, 0x1D, 0xBE, 0x76, 0x84,
        0xEB, 0x6B, 0x6F, 0x85, 0x87, 0xD8, 0x32, 0x0C,
        0x6D, 0xB3, 0x8D, 0xED, 0xD6, 0x18, 0x96, 0xED,
        0x51, 0xAB, 0x0C, 0x7F, 0x42, 0x8F, 0x19, 0xD2,
        0x55, 0xC6, 0xB0, 0xFD, 0xF5, 0x89, 0x51, 0xE5,
        0xCD, 0xB1, 0x96, 0x9C, 0xD9, 0xA7, 0x93, 0x4E,
        0xFD, 0xB9, 0xC8, 0x2E, 0x1E, 0x8D, 0x2A, 0x59,
        0xC9, 0xF7, 0x9D, 0xF1, 0xAA, 0x93, 0xE5, 0x07,
        0x1E, 0x3F, 0xAC, 0x73, 0x19, 0xFF, 0x68, 0x87,
        0x8C, 0xF2, 0x49, 0xDC, 0xBD, 0xCD, 0x10, 0x46,
        0x16, 0xCC, 0xC1, 0xC1, 0xFB, 0xD7, 0x85, 0x56,
        0x9F, 0x55, 0x87, 0x10, 0x44, 0x1B, 0x31, 0xCA,
        0xE3, 0x16, 0x7A, 0x4C, 0xD7, 0xDD, 0xD1, 0x86,
        0x26, 0xC5, 0x43, 0x62, 0x96, 0x20, 0x32, 0xE6,
        0xB7, 0xA2, 0x76, 0x05, 0x61, 0x96, 0xFC, 0x22,
        0x96, 0x7E, 0x90, 0x7C, 0x32, 0x0A, 0x7A, 0xF5,
        0x8C, 0xE3, 0xF5, 0x01, 0xC4, 0xCD, 0x31, 0x8A,
        0x70, 0x75, 0x04, 0xF1, 0xC2, 0x59, 0xE5, 0x07,
        0xA0, 0xD4, 0x7D, 0x25, 0x8E, 0x2F, 0x38, 0xE2,
        0x6A, 0x53, 0x41, 0x34, 0x7A, 0x06, 0xB5, 0x8B,
        0xB0, 0xBF, 0x21, 0xDE, 0xE6, 0x5F, 0x55, 0x6A,
        0xD4, 0x88, 0xA7, 0x36, 0xD4, 0xC6, 0x5C, 0x82,
        0xC6, 0x73, 0xC0, 0x60, 0xD7, 0xA6, 0xA0, 0x77,
        0x5C, 0xF8, 0xC3, 0x9A, 0xA1, 0x31, 0xFD, 0x64,
        0xDB, 0xB1, 0x7B, 0x72, 0x70, 0x4B, 0x7D, 0x1D,
        0x24, 0xBC, 0x5F, 0x84, 0x08, 0x3B, 0xF8, 0xA6,
        0x47, 0xEB, 0xED, 0xCF, 0xDD, 0xA0, 0x91, 0x14,
        0x26, 0x7D, 0x77, 0xCF, 0xBF, 0x39, 0x9B, 0xD9,
        0x2F, 0x3B, 0x2A, 0xA7, 0x2B, 0xBC, 0xF7, 0xDE,
        0x9D, 0x69, 0xBF, 0x90, 0xA4, 0xDE, 0x2C, 0xF8,
        0x24, 0x92, 0x7D, 0xE2, 0xB8, 0xBD, 0xF4, 0x6B,
        0x10, 0x9E, 0xD6, 0x08, 0x51, 0xC5, 0x9C, 0x44,
        0x8E, 0xCB, 0x44, 0x3F, 0x00, 0x26, 0x3C, 0x9C,
        0x25, 0xF4, 0x62, 0x74, 0xD1, 0x7C, 0x29, 0x4C,
        0xEB, 0xF2, 0x53, 0x7D, 0x8F, 0xEA, 0xBD, 0x78,
        0xEE, 0xBC, 0xBA, 0x72, 0x64, 0xA5, 0xB9, 0x45,
        0x08, 0xE0, 0xBF, 0x62, 0xEF, 0xC2, 0x1E, 0x06,
        0xE1, 0xE2, 0xFB, 0x14, 0x44, 0xC5, 0xAB, 0x6F,
        0x84, 0x7F, 0x52, 0x2F, 0x8A, 0xBE, 0xED, 0x04,
        0x6D, 0x6D, 0xDC, 0xFF, 0xBC, 0xB8, 0xC8, 0x1F,
        0xD0, 0x5D, 0x4D, 0x7F, 0x2E, 0x1B, 0xC9, 0x9B,
        0xEA, 0xF8, 0xC1, 0xAF, 0xE3, 0xE0, 0x5B, 0x36,
        0x90, 0xFE, 0xE4, 0xAA, 0x37, 0x5A, 0x3D, 0xCB,
        0x77, 0x57, 0x7C, 0xCC, 0x6E, 0x3E, 0xBE, 0x8A,
        0x98, 0x7C, 0x6D, 0x7E, 0x89, 0x60, 0x73, 0xC0,
        0xCC, 0x0C, 0x48, 0x25, 0x46, 0xB5, 0x39, 0xB4,
        0xFD, 0xF0, 0x4E, 0xED, 0x8E, 0x87, 0xF8, 0x5B,
        0x00, 0xBE, 0x43, 0xA6, 0x0B, 0x21, 0x7E, 0x96,
        0x88, 0x3B, 0x91, 0xD7, 0x88, 0x1A, 0xA0, 0xDD,
        0x3E, 0xBF, 0x5B, 0x0D, 0x08, 0xD0, 0x85, 0x4E,
        0xD4, 0x27, 0x8F, 0xC9, 0x02, 0xE0, 0x60, 0xEA,
        0x16, 0xFB, 0xC2, 0x54, 0xA5, 0x08, 0xC8, 0x6F,
        0x7A, 0xE7, 0x54, 0x93, 0xB8, 0xDD, 0xA0, 0x86,
        0xE9, 0xC1, 0xB2, 0x17, 0xF5, 0xC9, 0x11, 0x97,
        0x83, 0x66, 0x88, 0xCD, 0x2D, 0x0B, 0xB8, 0xE5,
        0x52, 0xD1, 0x13, 0x7A, 0xA7, 0xEB, 0xD5, 0xD5,
        0x60, 0x53, 0x8E, 0x9B, 0xB6, 0xB4, 0x1D, 0x06,
        0x90, 0xB0, 0x6C, 0x66, 0xD1, 0x57, 0x5B, 0x86,
        0x1C, 0x8A, 0x7D, 0x3A, 0x88, 0x4C, 0xC9, 0x88,
        0x1A, 0xC3, 0x00, 0x1F, 0x30, 0x0D, 0xF3, 0x47,
        0x62, 0x79, 0x85, 0x89, 0xF9, 0xEE, 0x5C, 0x92,
        0x43, 0x61, 0x53, 0xD8, 0xC7, 0x32, 0x55, 0x9B,
        0x33, 0x3D, 0x69, 0x8F, 0x3E, 0xC5, 0x82, 0x0E,
        0x8A, 0xA5, 0xF2, 0xE5, 0xA7, 0x69, 0xC2, 0xB4,
        0x7A, 0xFA, 0x27, 0x5F, 0xE4, 0x74, 0xAF, 0x81,
        0x37, 0xC7, 0x01, 0x9A, 0xF2, 0xE6, 0x0C, 0xA7,
        0x5E, 0xDB, 0xE4, 0x8F, 0x81, 0xA6, 0x51, 0xCE,
        0x6B, 0xAB, 0xD3, 0x37, 0x4C, 0x07, 0x72, 0xA8,
        0xAC, 0x36, 0x77, 0xB1, 0x0F, 0x54, 0x77, 0x17,
        0xC9, 0x67, 0x50, 0xDA, 0x44, 0x8B, 0xD9, 0xC7,
        0x93, 0x8C, 0x66, 0xCD, 0x6F, 0xB7, 0x5D, 0x73,
        0x2D, 0xAC, 0x83, 0x1A, 0xDC, 0xE9, 0x17, 0x6D,
        0x94, 0x85, 0x6E, 0x1B, 0xF6, 0x08, 0x38, 0xD0,
        0x9E, 0x63, 0x23, 0xA2, 0x7B, 0x16, 0x09, 0xF9,
        0xC1, 0x21, 0xF4, 0x98, 0xD2, 0xBB, 0x68, 0x58,
        0x18, 0xA0, 0x0D, 0xE7, 0xBA, 0x6B, 0x28, 0x47,
        0xC5, 0x16, 0x14, 0x9F, 0x35, 0x6E, 0xCE, 0xF0,
        0x4F, 0x34, 0xEA, 0x48, 0x35, 0x46, 0xFE, 0xEB,
        0x12, 0xEA, 0x40, 0x77, 0x62, 0x04, 0x30, 0xC3,
        0x9D, 0xBF, 0x47, 0xC0, 0x5E, 0xED, 0x5E, 0xD5,
        0x87, 0xFF, 0xF5, 0x92, 0x21, 0x7C, 0xA9, 0x5A,
        0x2C, 0x3D, 0x1E, 0x6F, 0x6F, 0xF9, 0xFF, 0x20,
        0x9F, 0x8B, 0x30, 0xA9, 0x9D, 0x56, 0xA3, 0x97,
        0x7A, 0x33, 0x17, 0x49, 0x0B, 0x2B, 0x00, 0x1F,
        0x43, 0xCD, 0x8D, 0xDD, 0x1D, 0x8F, 0xC1, 0x6A,
        0x3F, 0xA9, 0xB4, 0x31, 0x54, 0x62, 0x84, 0x5B,
        0x99, 0x5D, 0x2A, 0xB7, 0x6E, 0xA5, 0x39, 0xC7,
        0xF0, 0x4C, 0x31, 0x6C, 0x71, 0xD6, 0x00, 0xE1,
        0xAC, 0x4F, 0xD5, 0xC8, 0xC6, 0x34, 0x3B, 0xC8,
        0x05, 0x5F, 0x17, 0x00, 0xB4, 0x0E, 0xA2, 0xF1,
        0xAB, 0xE9, 0x4B, 0xE0, 0x06, 0x01, 0x3A, 0xA2,
        0x61, 0xF0, 0x72, 0x0A, 0xB7, 0x99, 0xD0, 0xFC,
        0x6D, 0xB5, 0xE9, 0xA4, 0xC3, 0xC5, 0xA7, 0xF8,
        0x2D, 0x70, 0xD2, 0x8E, 0x41, 0x0D, 0xD1, 0x64,
        0xE3, 0xE4, 0x61, 0xA4, 0x6E, 0x81, 0xFB, 0xDC,
        0xB8, 0x10, 0x84, 0x8B, 0xCE, 0xE0, 0x6F, 0x88,
        0x33, 0x25, 0x64, 0x6E, 0x1E, 0x2A, 0x69, 0x3F,
        0xA5, 0xDA, 0x7C, 0x25, 0xEB, 0x21, 0xC4, 0xEA,
        0xB8, 0x7D, 0xC7, 0x87, 0xA2, 0x67, 0x7C, 0xEB,
        0x6A, 0x26, 0xE1, 0x06, 0xFE, 0x78, 0xE1, 0x18,
        0xFF, 0x54, 0x71, 0x3E, 0x00, 0x59, 0x7B, 0xFA,
        0x52, 0x8C, 0x2A, 0xED, 0x06, 0x9A, 0x12, 0x6D,
        0xE3, 0x74, 0x6F, 0x06, 0x65, 0xE1, 0x75, 0x80,
        0x63, 0x0F, 0x70, 0x2F, 0xAB, 0xC0, 0xF1, 0xCD,
        0x7F, 0x57, 0xAA, 0x71, 0xF6, 0x38, 0xD8, 0xAF,
        0x37, 0xD3, 0xD9, 0xE0, 0xA7, 0xE9, 0x05, 0x5D,
        0xA3, 0xDF, 0x86, 0x48, 0x3F, 0x25, 0xDE, 0xBA,
        0x18, 0xCE, 0xF6, 0x99, 0xEB, 0x87, 0x70, 0xC7,
        0x85, 0x84, 0x79, 0x8A, 0xD8, 0x02, 0x8B, 0xAD,
        0xC5, 0x9D, 0x2A, 0xF9, 0xAE, 0xAE, 0x37, 0xEC,
        0x93, 0x91, 0x16, 0x10, 0x5F, 0x9F, 0x64, 0xEF,
        0x82, 0x78, 0xC6, 0x4D, 0xED, 0x3F, 0xD4, 0x33,
        0xA7, 0xB8, 0x82, 0x09, 0x16, 0xBE, 0xDC, 0x6B,
        0x7A, 0x75, 0x69, 0x8A, 0xDE, 0xD3, 0xFD, 0xE8,
        0x86, 0x75, 0x42, 0x83, 0x03, 0x57, 0x30, 0x70,
        0xA5, 0xA3, 0x85, 0x1F, 0x9F, 0x21, 0xEA, 0xC7,
        0x80, 0xFA, 0x8A, 0xA4, 0x02, 0x3E, 0x39, 0x11,
        0x48, 0x7D, 0x85, 0x2A, 0x53, 0x77, 0x43, 0x5A,
        0x5F, 0xFF, 0x9C, 0x60, 0x4B, 0x5D, 0x95, 0xB0,
        0x96, 0x8A, 0xE0, 0xEC, 0xF4, 0x43, 0x1B, 0x10,
        0x3F, 0xA6, 0xBA, 0x71, 0xC4, 0xDC, 0x81, 0x73,
        0xA2, 0xDE, 0x1F, 0x79, 0xDD, 0xB6, 0x0D, 0x2D,
        0x0C, 0x8E, 0x56, 0x55, 0xD0, 0x94, 0x44, 0x29,
        0x16, 0x92, 0x99, 0x2D, 0x99, 0xFC, 0x48, 0xF2,
        0x16, 0x0E, 0xC0, 0xAC, 0xE4, 0xC4, 0x92, 0x07,
        0xBB, 0xB7, 0x6D, 0x7F, 0x2A, 0x85, 0xE1, 0x81,
        0x02, 0xB9, 0x5A, 0x51, 0x45, 0x88, 0xF5, 0x9F,
        0x16, 0x2D, 0x33, 0xCE, 0xD6, 0x18, 0x07, 0x03,
        0xED, 0xC3, 0x6C, 0x8B, 0x33, 0x94, 0x88, 0x81,
        0x0D, 0x2E, 0xAE, 0x96, 0x25, 0xCE, 0xE3, 0x83,
        0x27, 0x1C, 0x71, 0x72, 0xEE, 0xD6, 0xB5, 0x48,
        0x69, 0x60, 0xE8, 0x99, 0x18, 0x74, 0xB0, 0x13,
        0x53, 0x59, 0x3D, 0x70, 0x70, 0xBD, 0xEB, 0x7A,
        0x9F, 0x92, 0x29, 0xAB, 0x77, 0x0E, 0xEB, 0x46,
        0x37, 0x8D, 0x57, 0xD9, 0x56, 0xDF, 0x7A, 0x86,
        0x40, 0x04, 0x02, 0x98, 0xF7, 0x00, 0xF4, 0x41,
        0x5B, 0xDD, 0x3A, 0x96, 0x15, 0xA4, 0x65, 0xDB,
        0x01, 0x28, 0x22, 0x12, 0xCF, 0x1A, 0xEC, 0x4B,
        0x0B, 0x8C, 0xB3, 0xB1, 0x7E, 0x5E, 0xFA, 0x28,
        0x6C, 0x6C, 0x04, 0x5B, 0x43, 0x9C, 0x74, 0x9F,
        0xE1, 0xD4, 0x50, 0x75, 0xD8, 0xE7, 0xA0, 0x0F,
        0xBE, 0x84, 0x48, 0xFC, 0xAC, 0xAA, 0x15, 0x3D,
        0x69, 0x70, 0x9D, 0x9F, 0xF2, 0xB9, 0x7C, 0xDB,
        0x26, 0xC0, 0xC3, 0x79, 0x28, 0x7C, 0xE6, 0x48,
        0x61, 0xAD, 0xD7, 0x89, 0xD0, 0xC8, 0x93, 0x9A,
        0x14, 0x21, 0xB0, 0x85, 0xD6, 0x23, 0x4C, 0xE1,
        0xA7, 0x49, 0xDE, 0x3D, 0xCB, 0xE8, 0xE0, 0x61,
        0x5C, 0xB3, 0xBC, 0xDC, 0x6A, 0x81, 0xA5, 0xC4,
        0x9D, 0x92, 0x85, 0x74, 0x5F, 0x1C, 0xA8, 0xA0,
        0x64, 0x1E, 0x32, 0x68, 0x83, 0x41, 0x93, 0x34,
        0x82, 0x18, 0x3E, 0x24, 0x5C, 0x1F, 0x9C, 0xD2,
        0x80, 0x28, 0xC3, 0x8A, 0x23, 0x18, 0x1A, 0x44,
        0x5A, 0xA6, 0xEA, 0xCC, 0xE2, 0x06, 0x06, 0xE6,
        0xF7, 0xF1, 0xDF, 0x70, 0x68, 0x83, 0xCD, 0xA5,
        0x2F, 0x3F, 0x2B, 0x68, 0xDE, 0x26, 0xDD, 0x37,
        0x71, 0xE9, 0x50, 0x03, 0x2C, 0xC7, 0x20, 0x0C,
        0x20, 0x23, 0xC8, 0x24, 0x96, 0x50, 0x82, 0x82,
        0xCD, 0x3B, 0xC4, 0x7F, 0xEC, 0xE5, 0xD9, 0x7C,
        0xA1, 0xCE, 0x35, 0x74, 0x4D, 0x03, 0xD7, 0xA4,
        0x28, 0xB7, 0xAF, 0x12, 0xB0, 0xCB, 0x8E, 0x65,
        0x7C, 0x01, 0x30, 0xF8, 0xA3, 0xA2, 0x54, 0x97,
        0x6E, 0xC8, 0xF7, 0xDC, 0xCF, 0x3A, 0xBF, 0x31,
        0xF4, 0xB0, 0xB3, 0xF7, 0x12, 0x6F, 0xFC, 0x48,
        0x77, 0xF3, 0xD1, 0xA0, 0x66, 0xD2, 0x6A, 0x23,
        0x2F, 0xA9, 0x99, 0x21, 0x61, 0x22, 0x54, 0x11,
        0xED, 0x7D, 0xDB, 0x93, 0xC3, 0x5C, 0x6A, 0x37,
        0x7F, 0x30, 0xCF, 0x22, 0xAA, 0x39, 0x2D, 0x5C,
        0x4F, 0xEE, 0x4F, 0x73, 0xC9, 0xEF, 0x6E, 0xD3,
        0xA0, 0x27, 0x97, 0x14, 0x52, 0x3B, 0x19, 0x18,
        0x65, 0x1E, 0x9B, 0x0F, 0xFA, 0x55, 0x0F, 0x16,
        0x10, 0x53, 0xEE, 0x78, 0x01, 0x39, 0x7B, 0x4C,
        0x18, 0x49, 0x98, 0x7C, 0x17, 0x9E, 0x76, 0x3E,
        0xCC, 0x60, 0xA4, 0xE4, 0xC5, 0x36, 0xB7, 0xE2,
        0x66, 0x3E, 0x4C, 0x72, 0x67, 0x14, 0xB0, 0x2E,
        0xC3, 0x16, 0x9E, 0x84, 0x07, 0xBA, 0x59, 0x2B,
        0x0E, 0xB8, 0x46, 0xF3, 0x69, 0x2D, 0xD4, 0x46,
        0x51, 0xEE, 0x08, 0x47, 0x21, 0xCA, 0xC0, 0xFE,
        0x1C, 0xCC, 0x30, 0x27, 0x07, 0xEF, 0xE2, 0x46,
        0x64, 0xE0, 0x5B, 0xDC, 0x69, 0xC8, 0x39, 0x04,
        0xAC, 0xB8, 0xCF, 0x97, 0x12, 0x1C, 0x7E, 0x5C,
        0x6D, 0xB2, 0x7E, 0xA2, 0x8E, 0x77, 0xBC, 0xDA,
        0x55, 0xD2, 0xBC, 0xC1, 0xC5, 0xFC, 0xC5, 0x52,
        0xAB, 0x83, 0xBC, 0xE4, 0x23, 0x8C, 0xA1, 0x80,
        0x62, 0xC2, 0xD2, 0x3A, 0x8B, 0x80, 0x0C, 0x82,
        0x09, 0xC3, 0xA4, 0xCD, 0xDA, 0xF1, 0x16, 0x16,
        0x57, 0x8A, 0x84, 0x55, 0x66, 0xFC, 0x28, 0x9A,
        0x8E, 0x3C, 0x88, 0xF5, 0x54, 0xC4, 0x92, 0x60,
        0x71, 0xDA, 0x89, 0x32, 0x6B, 0xEB, 0x25, 0x9A,
        0x0E, 0x1F, 0x6D, 0x84, 0x4E, 0xBF, 0x7B, 0x28,
        0x1F, 0x9F, 0xC3, 0x74, 0x3A, 0x65, 0x49, 0x9E,
        0x73, 0x94, 0x63, 0x48, 0x18, 0xE1, 0x33, 0xFA,
        0xC6, 0x64, 0xFA, 0x0C, 0x88, 0xF1, 0x01, 0xCE,
        0xC3, 0xFE, 0xD8, 0x79, 0x29, 0x50, 0xBF, 0x6E,
        0x49, 0x74, 0x84, 0x9E, 0x1E, 0xBD, 0x27, 0x69,
        0x1B, 0xF5, 0x51, 0x9B, 0x70, 0x2E, 0x1A, 0xA4,
        0xB3, 0xDB, 0xAD, 0xAB, 0x5D, 0xFA, 0x34, 0xFB,
        0x0E, 0xD9, 0xD4, 0xA9, 0xDF, 0x4B, 0x6B, 0x63,
        0xCA, 0x71, 0x65, 0xE2, 0xA9, 0x08, 0x27, 0x40,
        0x8C, 0x48, 0x2D, 0x9D, 0xBC, 0x97, 0x24, 0x68,
        0x58, 0x4F, 0x42, 0x37, 0x60, 0x04, 0xE7, 0x8B,
        0xE0, 0x67, 0x00, 0x9E, 0x43, 0x30, 0x4B, 0xED,
        0xC1, 0x07, 0xA4, 0xE2, 0xA8, 0x9C, 0xAF, 0x18,
        0x5C, 0x9B, 0xB7, 0xE9, 0xFD, 0x2C, 0xB9, 0x2A,
        0xEF, 0x36, 0x3B, 0xD7, 0x96, 0xF3, 0x60, 0x4E,
        0xDC, 0x08, 0xA7, 0xC5, 0x45, 0xB8, 0x37, 0x02,
        0xD3, 0xCF, 0x80, 0x88, 0x52, 0x10, 0x3E, 0x01,
        0x3B, 0xFE, 0xA1, 0x61, 0xAF, 0x25, 0x0B, 0xCC,
        0x72, 0x77, 0x1D, 0x0C, 0x48, 0x4D, 0xD5, 0x55,
        0x41, 0x72, 0x3A, 0x21, 0x0D, 0x68, 0x3B, 0x99,
        0x8C, 0xDB, 0xAF, 0x3D, 0x9A, 0x5E, 0x71, 0x78,
        0x6F, 0x1C, 0xF4, 0x7B, 0x86, 0x22, 0x51, 0xB5,
        0x16, 0x33, 0x60, 0x87, 0x9A, 0xC0, 0x20, 0x2D,
        0x33, 0x49, 0x51, 0x54, 0x5C, 0x5F, 0x71, 0x76,
        0x7C, 0x8F, 0x96, 0xA9, 0xD6, 0xE4, 0xF2, 0x1F,
        0x28, 0x43, 0x4D, 0x7E, 0x96, 0xBB, 0xC5, 0xE3,
        0xEF, 0xF3, 0xFD, 0x02, 0x0C, 0x17, 0x23, 0x3E,
        0x7F, 0x99, 0xB0, 0xE3, 0xE8, 0xF5, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x06, 0x17, 0x23, 0x2E
    };
#endif
#ifndef WOLFSSL_NO_ML_DSA_65
    static const byte sk_65[] = {
        0xF2, 0x6B, 0xFE, 0x12, 0x68, 0x86, 0xF4, 0x82,
        0x22, 0x94, 0x4D, 0x02, 0x18, 0xFA, 0xC1, 0x7C,
        0xD8, 0xA9, 0xCC, 0x6D, 0x67, 0xA0, 0x23, 0xFD,
        0xC0, 0x7A, 0xFF, 0xC2, 0xD0, 0x25, 0xF7, 0x70,
        0x63, 0x85, 0x0D, 0x88, 0x0E, 0x98, 0xFE, 0xE5,
        0x02, 0xE0, 0x17, 0x32, 0x70, 0x00, 0xCC, 0xAF,
        0x61, 0x45, 0x73, 0xB3, 0x5A, 0xDE, 0xFE, 0xBC,
        0xAC, 0xEE, 0xA4, 0xB2, 0xC4, 0xD0, 0x45, 0xE5,
        0xBB, 0xFD, 0x3E, 0x5A, 0x72, 0xE3, 0x71, 0xAD,
        0x83, 0xB9, 0x94, 0x98, 0x77, 0xD8, 0xE6, 0x56,
        0xD4, 0x6B, 0x47, 0x75, 0x0F, 0x73, 0x0F, 0x96,
        0xDB, 0x43, 0x0B, 0x18, 0x60, 0x88, 0x67, 0x5D,
        0x9A, 0x9B, 0xD7, 0x8E, 0x47, 0xB8, 0x9D, 0x04,
        0xA8, 0x51, 0x7E, 0xD2, 0x22, 0x06, 0x95, 0x33,
        0x9F, 0x99, 0xA9, 0x7F, 0x35, 0x3C, 0xE4, 0x20,
        0x47, 0x77, 0x20, 0x9F, 0x5F, 0x3C, 0x9E, 0x9A,
        0x36, 0x14, 0x54, 0x01, 0x57, 0x48, 0x60, 0x50,
        0x75, 0x28, 0x64, 0x61, 0x72, 0x60, 0x54, 0x20,
        0x75, 0x48, 0x60, 0x32, 0x73, 0x85, 0x34, 0x24,
        0x68, 0x63, 0x71, 0x73, 0x81, 0x26, 0x71, 0x68,
        0x32, 0x61, 0x24, 0x71, 0x14, 0x18, 0x26, 0x15,
        0x05, 0x77, 0x36, 0x27, 0x50, 0x35, 0x21, 0x82,
        0x50, 0x15, 0x31, 0x47, 0x48, 0x24, 0x43, 0x76,
        0x18, 0x85, 0x66, 0x18, 0x05, 0x64, 0x27, 0x01,
        0x06, 0x06, 0x01, 0x45, 0x42, 0x60, 0x80, 0x68,
        0x25, 0x08, 0x08, 0x36, 0x13, 0x05, 0x04, 0x32,
        0x34, 0x87, 0x00, 0x70, 0x71, 0x70, 0x02, 0x51,
        0x37, 0x15, 0x08, 0x28, 0x25, 0x72, 0x61, 0x67,
        0x08, 0x52, 0x63, 0x44, 0x07, 0x88, 0x60, 0x42,
        0x03, 0x17, 0x24, 0x64, 0x80, 0x08, 0x70, 0x23,
        0x56, 0x41, 0x46, 0x17, 0x46, 0x01, 0x57, 0x74,
        0x02, 0x76, 0x31, 0x64, 0x73, 0x83, 0x50, 0x62,
        0x72, 0x61, 0x62, 0x75, 0x45, 0x73, 0x46, 0x33,
        0x65, 0x14, 0x36, 0x46, 0x12, 0x26, 0x04, 0x34,
        0x02, 0x81, 0x20, 0x34, 0x41, 0x88, 0x26, 0x77,
        0x33, 0x40, 0x18, 0x58, 0x03, 0x41, 0x16, 0x58,
        0x88, 0x04, 0x88, 0x32, 0x71, 0x05, 0x85, 0x83,
        0x42, 0x55, 0x34, 0x20, 0x18, 0x46, 0x12, 0x54,
        0x28, 0x03, 0x67, 0x10, 0x84, 0x31, 0x76, 0x00,
        0x40, 0x85, 0x46, 0x71, 0x71, 0x56, 0x00, 0x50,
        0x15, 0x33, 0x43, 0x13, 0x37, 0x57, 0x13, 0x86,
        0x43, 0x77, 0x85, 0x57, 0x54, 0x81, 0x75, 0x60,
        0x37, 0x31, 0x28, 0x52, 0x20, 0x78, 0x65, 0x53,
        0x76, 0x10, 0x84, 0x87, 0x57, 0x13, 0x66, 0x03,
        0x56, 0x81, 0x36, 0x66, 0x68, 0x41, 0x55, 0x64,
        0x63, 0x70, 0x26, 0x21, 0x02, 0x30, 0x28, 0x35,
        0x02, 0x45, 0x88, 0x80, 0x02, 0x06, 0x44, 0x58,
        0x24, 0x13, 0x88, 0x83, 0x22, 0x34, 0x22, 0x50,
        0x47, 0x11, 0x01, 0x86, 0x45, 0x60, 0x67, 0x36,
        0x82, 0x22, 0x18, 0x74, 0x11, 0x60, 0x58, 0x60,
        0x87, 0x26, 0x31, 0x85, 0x12, 0x70, 0x84, 0x83,
        0x88, 0x68, 0x88, 0x51, 0x00, 0x55, 0x02, 0x57,
        0x77, 0x42, 0x13, 0x23, 0x14, 0x04, 0x76, 0x80,
        0x72, 0x25, 0x51, 0x56, 0x10, 0x63, 0x12, 0x21,
        0x03, 0x86, 0x27, 0x30, 0x28, 0x12, 0x01, 0x37,
        0x48, 0x32, 0x53, 0x86, 0x15, 0x46, 0x50, 0x05,
        0x34, 0x87, 0x61, 0x04, 0x88, 0x18, 0x35, 0x85,
        0x44, 0x46, 0x24, 0x67, 0x43, 0x83, 0x02, 0x26,
        0x56, 0x41, 0x41, 0x77, 0x86, 0x56, 0x41, 0x75,
        0x25, 0x61, 0x36, 0x05, 0x47, 0x65, 0x00, 0x14,
        0x32, 0x38, 0x16, 0x81, 0x06, 0x30, 0x61, 0x25,
        0x16, 0x30, 0x50, 0x44, 0x13, 0x08, 0x75, 0x00,
        0x50, 0x20, 0x68, 0x21, 0x55, 0x74, 0x61, 0x18,
        0x62, 0x05, 0x15, 0x51, 0x08, 0x24, 0x01, 0x13,
        0x81, 0x33, 0x64, 0x83, 0x23, 0x00, 0x55, 0x73,
        0x62, 0x40, 0x61, 0x75, 0x15, 0x78, 0x21, 0x14,
        0x13, 0x64, 0x21, 0x47, 0x07, 0x76, 0x80, 0x76,
        0x76, 0x17, 0x75, 0x50, 0x61, 0x14, 0x40, 0x82,
        0x87, 0x83, 0x50, 0x87, 0x30, 0x86, 0x35, 0x30,
        0x28, 0x20, 0x10, 0x01, 0x48, 0x18, 0x34, 0x65,
        0x23, 0x10, 0x25, 0x42, 0x40, 0x22, 0x54, 0x34,
        0x35, 0x33, 0x71, 0x70, 0x20, 0x61, 0x55, 0x74,
        0x33, 0x01, 0x02, 0x60, 0x58, 0x24, 0x80, 0x12,
        0x46, 0x41, 0x38, 0x10, 0x76, 0x67, 0x34, 0x63,
        0x48, 0x85, 0x06, 0x48, 0x04, 0x23, 0x22, 0x66,
        0x57, 0x71, 0x68, 0x18, 0x04, 0x32, 0x01, 0x31,
        0x01, 0x55, 0x22, 0x27, 0x55, 0x72, 0x10, 0x00,
        0x43, 0x88, 0x76, 0x62, 0x84, 0x77, 0x07, 0x77,
        0x14, 0x07, 0x20, 0x53, 0x74, 0x17, 0x51, 0x17,
        0x66, 0x84, 0x47, 0x83, 0x61, 0x03, 0x52, 0x10,
        0x05, 0x40, 0x46, 0x55, 0x61, 0x47, 0x26, 0x70,
        0x40, 0x22, 0x10, 0x34, 0x41, 0x01, 0x03, 0x48,
        0x33, 0x05, 0x72, 0x32, 0x75, 0x82, 0x45, 0x85,
        0x20, 0x70, 0x80, 0x82, 0x20, 0x23, 0x62, 0x81,
        0x15, 0x47, 0x80, 0x23, 0x67, 0x23, 0x73, 0x34,
        0x44, 0x33, 0x85, 0x10, 0x05, 0x50, 0x30, 0x03,
        0x48, 0x13, 0x01, 0x36, 0x45, 0x11, 0x06, 0x33,
        0x82, 0x22, 0x78, 0x75, 0x42, 0x02, 0x40, 0x45,
        0x04, 0x47, 0x43, 0x05, 0x30, 0x44, 0x42, 0x02,
        0x28, 0x26, 0x64, 0x24, 0x74, 0x75, 0x86, 0x11,
        0x85, 0x43, 0x25, 0x46, 0x10, 0x62, 0x82, 0x71,
        0x08, 0x27, 0x45, 0x13, 0x73, 0x18, 0x84, 0x73,
        0x51, 0x51, 0x67, 0x14, 0x70, 0x11, 0x07, 0x08,
        0x62, 0x16, 0x25, 0x27, 0x36, 0x68, 0x44, 0x01,
        0x18, 0x63, 0x74, 0x50, 0x31, 0x13, 0x43, 0x65,
        0x80, 0x11, 0x16, 0x52, 0x86, 0x42, 0x51, 0x81,
        0x51, 0x17, 0x05, 0x68, 0x05, 0x73, 0x60, 0x37,
        0x63, 0x85, 0x86, 0x11, 0x23, 0x23, 0x38, 0x13,
        0x87, 0x48, 0x82, 0x74, 0x71, 0x81, 0x87, 0x65,
        0x58, 0x26, 0x60, 0x34, 0x76, 0x16, 0x15, 0x24,
        0x06, 0x78, 0x16, 0x40, 0x03, 0x45, 0x72, 0x31,
        0x63, 0x73, 0x31, 0x85, 0x02, 0x66, 0x44, 0x36,
        0x24, 0x82, 0x56, 0x38, 0x86, 0x10, 0x40, 0x54,
        0x72, 0x70, 0x24, 0x22, 0x72, 0x78, 0x47, 0x07,
        0x86, 0x30, 0x48, 0x72, 0x84, 0x57, 0x06, 0x34,
        0x78, 0x37, 0x63, 0x25, 0x56, 0x64, 0x81, 0x30,
        0x62, 0x77, 0x22, 0x84, 0x20, 0x10, 0x74, 0x25,
        0x04, 0x21, 0x76, 0x47, 0x72, 0x35, 0x05, 0x06,
        0x22, 0x50, 0x34, 0x11, 0x26, 0x67, 0x03, 0x05,
        0x42, 0x04, 0x16, 0x01, 0x27, 0x17, 0x86, 0x67,
        0x70, 0x51, 0x53, 0x13, 0x12, 0x62, 0x03, 0x25,
        0x05, 0x38, 0x37, 0x44, 0x02, 0x66, 0x84, 0x74,
        0x14, 0x40, 0x35, 0x20, 0x40, 0x30, 0x44, 0x64,
        0x27, 0x50, 0x77, 0x47, 0x06, 0x15, 0x84, 0x48,
        0x13, 0x14, 0x32, 0x48, 0x11, 0x74, 0x80, 0x68,
        0x85, 0x81, 0x17, 0x67, 0x38, 0x22, 0x76, 0x16,
        0x18, 0x44, 0x55, 0x47, 0x85, 0x36, 0x44, 0x11,
        0x52, 0x01, 0x81, 0x50, 0x41, 0x00, 0x00, 0x25,
        0x83, 0x41, 0x62, 0x22, 0x12, 0x54, 0x88, 0x77,
        0x70, 0x48, 0x84, 0x25, 0x77, 0x75, 0x40, 0x16,
        0x46, 0x24, 0x88, 0x81, 0x65, 0x70, 0x02, 0x66,
        0x28, 0x64, 0x12, 0x40, 0x30, 0x60, 0x53, 0x06,
        0x44, 0x02, 0x48, 0x78, 0x75, 0x68, 0x21, 0x23,
        0x30, 0x05, 0x81, 0x17, 0x72, 0x66, 0x88, 0x71,
        0x50, 0x25, 0x03, 0x51, 0x42, 0x27, 0x20, 0x81,
        0x03, 0x52, 0x73, 0x53, 0x63, 0x57, 0x13, 0x60,
        0x41, 0x20, 0x47, 0x12, 0x55, 0x57, 0x58, 0x16,
        0x38, 0x63, 0x21, 0x34, 0x51, 0x76, 0x33, 0x26,
        0x70, 0x41, 0x18, 0x11, 0x07, 0x37, 0x16, 0x12,
        0x01, 0x14, 0x28, 0x56, 0x78, 0x10, 0x86, 0x24,
        0x24, 0x32, 0x01, 0x13, 0x57, 0x53, 0x46, 0x46,
        0x24, 0x05, 0x20, 0x16, 0x56, 0x83, 0x30, 0x30,
        0x61, 0x20, 0x75, 0x07, 0x05, 0x74, 0x14, 0x17,
        0x43, 0x72, 0x23, 0x04, 0x18, 0x61, 0x50, 0x13,
        0x67, 0x31, 0x75, 0x36, 0x71, 0x02, 0x38, 0x74,
        0x21, 0x80, 0x20, 0x48, 0x66, 0x23, 0x52, 0x54,
        0x77, 0x27, 0x45, 0x73, 0x23, 0x88, 0x60, 0x50,
        0x88, 0x82, 0x70, 0x23, 0x72, 0x08, 0x44, 0x66,
        0x44, 0x36, 0x12, 0x57, 0x66, 0x14, 0x25, 0x12,
        0x17, 0x34, 0x64, 0x82, 0x01, 0x54, 0x61, 0x57,
        0x50, 0x31, 0x65, 0x64, 0x75, 0x44, 0x76, 0x48,
        0x16, 0x44, 0x46, 0x55, 0x80, 0x64, 0x26, 0x53,
        0x27, 0x22, 0x10, 0x87, 0x84, 0x03, 0x15, 0x35,
        0x15, 0x20, 0x86, 0x14, 0x04, 0x03, 0x26, 0x43,
        0x31, 0x43, 0x31, 0x45, 0x46, 0x34, 0x36, 0x87,
        0x44, 0x41, 0x21, 0x77, 0x61, 0x20, 0x85, 0x06,
        0x28, 0x51, 0x15, 0x62, 0x77, 0x20, 0x38, 0x58,
        0x78, 0x27, 0x12, 0x22, 0x46, 0x71, 0x51, 0x38,
        0x11, 0x15, 0x40, 0x03, 0x78, 0x36, 0x15, 0x57,
        0x34, 0x28, 0x53, 0x21, 0x37, 0x35, 0x04, 0x76,
        0x00, 0x56, 0x72, 0x48, 0x46, 0x01, 0x56, 0x67,
        0x62, 0x36, 0x14, 0x51, 0x23, 0x54, 0x32, 0x35,
        0x82, 0x83, 0x21, 0x60, 0x38, 0x62, 0x21, 0x03,
        0x62, 0x76, 0x40, 0x34, 0x66, 0x88, 0x50, 0x73,
        0x00, 0x53, 0x87, 0x31, 0x37, 0x50, 0x11, 0x32,
        0x86, 0x52, 0x18, 0x64, 0x16, 0x63, 0x48, 0x71,
        0x70, 0x47, 0x24, 0x85, 0x31, 0x86, 0x60, 0x86,
        0x33, 0x52, 0x85, 0x82, 0x68, 0x17, 0x70, 0x88,
        0x84, 0x56, 0x52, 0x77, 0x04, 0x48, 0x22, 0x22,
        0x54, 0x57, 0x20, 0x31, 0x76, 0x47, 0x26, 0x25,
        0x04, 0x35, 0x38, 0x44, 0x55, 0x21, 0x14, 0x02,
        0x13, 0x64, 0x74, 0x87, 0x68, 0x68, 0x73, 0x05,
        0x22, 0x45, 0x54, 0x45, 0x83, 0x46, 0x64, 0x54,
        0x80, 0x07, 0x32, 0x87, 0x52, 0x43, 0x54, 0x54,
        0x14, 0x73, 0x24, 0x87, 0x36, 0x41, 0x74, 0x84,
        0x06, 0x35, 0x13, 0x40, 0x61, 0x54, 0x21, 0x31,
        0x48, 0x63, 0x05, 0x74, 0x24, 0x84, 0x74, 0x76,
        0x11, 0x10, 0x16, 0x63, 0x77, 0x12, 0x26, 0x61,
        0x31, 0x28, 0x70, 0x34, 0x25, 0x01, 0x30, 0x76,
        0x76, 0x06, 0x21, 0x58, 0x42, 0x87, 0x31, 0x72,
        0x76, 0x03, 0x76, 0x26, 0x78, 0x05, 0x88, 0x25,
        0x25, 0x86, 0x17, 0x02, 0x85, 0x88, 0x76, 0x20,
        0x36, 0x57, 0x30, 0x81, 0x83, 0x61, 0x05, 0x80,
        0x21, 0x45, 0x74, 0x01, 0x12, 0x74, 0x51, 0x28,
        0x77, 0x26, 0x30, 0x14, 0x54, 0x84, 0x13, 0x78,
        0x06, 0x00, 0x12, 0x64, 0x00, 0x37, 0x44, 0x68,
        0x40, 0x57, 0x05, 0x27, 0x07, 0x41, 0x56, 0x22,
        0x31, 0x40, 0x23, 0x26, 0x55, 0x42, 0x55, 0x16,
        0x02, 0x65, 0x32, 0x16, 0x33, 0x44, 0x46, 0x48,
        0x04, 0x52, 0x06, 0x53, 0x44, 0x40, 0x11, 0x28,
        0x46, 0x67, 0x56, 0x81, 0x72, 0x75, 0x51, 0x38,
        0x21, 0x86, 0x46, 0x03, 0x22, 0x87, 0x21, 0x70,
        0x68, 0x50, 0x75, 0x13, 0x11, 0x44, 0x35, 0x12,
        0x60, 0x02, 0x13, 0x47, 0x18, 0x38, 0x78, 0x86,
        0x38, 0x58, 0x45, 0x57, 0x23, 0x03, 0x88, 0x66,
        0x56, 0x82, 0x18, 0x31, 0x20, 0x08, 0x61, 0x47,
        0x78, 0x08, 0x68, 0x37, 0x21, 0x04, 0x65, 0x47,
        0x58, 0x70, 0x34, 0x58, 0x73, 0x24, 0x22, 0x30,
        0x66, 0x05, 0x01, 0x28, 0x87, 0x85, 0x77, 0x74,
        0x23, 0x86, 0x65, 0x84, 0x85, 0x57, 0x85, 0x63,
        0x06, 0x55, 0x61, 0x75, 0x46, 0x22, 0x87, 0x00,
        0x18, 0x53, 0x08, 0x03, 0x07, 0x50, 0x42, 0x70,
        0xFC, 0xB8, 0x7B, 0x22, 0x3D, 0x24, 0xAE, 0x5D,
        0xB1, 0x89, 0x04, 0x21, 0xC3, 0xFF, 0x1D, 0x59,
        0xB8, 0x4B, 0x19, 0xE2, 0x4D, 0x14, 0x36, 0x99,
        0x19, 0x1C, 0x7E, 0x9A, 0x46, 0x48, 0x42, 0x20,
        0x6B, 0xBA, 0x24, 0x7E, 0x8C, 0x6B, 0x27, 0xBA,
        0x26, 0xE6, 0x8A, 0xD5, 0xA7, 0x1D, 0x03, 0x61,
        0xCD, 0x5C, 0x74, 0xCE, 0x50, 0xC2, 0xCE, 0xF1,
        0x91, 0x31, 0xEF, 0x54, 0x66, 0x23, 0x7F, 0xFE,
        0xF7, 0xFE, 0x6B, 0x5F, 0xD1, 0x98, 0x23, 0x8E,
        0x1C, 0xA0, 0xB1, 0x01, 0x30, 0xC6, 0x29, 0xCC,
        0x91, 0x91, 0xF5, 0x78, 0x6F, 0x5C, 0xD6, 0x28,
        0xA4, 0x22, 0x56, 0xCB, 0x6F, 0xC7, 0xD7, 0x09,
        0x56, 0x88, 0xAF, 0x1B, 0xC8, 0x43, 0x51, 0xA4,
        0x7B, 0x4B, 0x38, 0x2E, 0xF6, 0x1F, 0xD6, 0x5C,
        0x9E, 0xC2, 0x26, 0xF4, 0x2B, 0x0A, 0x19, 0x7C,
        0x6A, 0xD8, 0xF0, 0xB0, 0x15, 0xD0, 0xB1, 0xC7,
        0xE0, 0x14, 0x28, 0x95, 0x6A, 0x9B, 0xB2, 0xDE,
        0x9A, 0x97, 0xE5, 0x75, 0x66, 0xF8, 0xF5, 0x66,
        0x86, 0xA1, 0xF4, 0x68, 0x0C, 0xEC, 0xEA, 0x87,
        0x3B, 0x69, 0x1C, 0xF8, 0xBD, 0x63, 0xAB, 0x73,
        0x73, 0xBA, 0xE8, 0x09, 0x5B, 0xA7, 0x76, 0x3E,
        0x50, 0xD6, 0x83, 0x9D, 0x00, 0x35, 0xBB, 0xFB,
        0x91, 0xBA, 0x60, 0x72, 0x17, 0x98, 0xFB, 0x2C,
        0x80, 0x2C, 0x60, 0x3A, 0x08, 0xA1, 0x24, 0x05,
        0xE0, 0xB5, 0x20, 0xEA, 0x41, 0x43, 0x8F, 0xEA,
        0xEF, 0xA5, 0x62, 0xDC, 0x78, 0x92, 0xF4, 0x58,
        0x9F, 0x8D, 0x2B, 0x96, 0x5E, 0xE5, 0x49, 0x73,
        0xA7, 0x2C, 0x8D, 0x33, 0x5C, 0x62, 0x61, 0x98,
        0x80, 0x64, 0x13, 0x31, 0x03, 0x10, 0xE3, 0x2E,
        0xFE, 0x6B, 0x39, 0xB5, 0xCF, 0xB1, 0xD1, 0x33,
        0xAD, 0xE0, 0x1B, 0xCE, 0x94, 0x21, 0x6C, 0xF4,
        0xCD, 0x8F, 0x86, 0x43, 0x03, 0x1D, 0xB8, 0xC2,
        0x47, 0xB5, 0x73, 0x21, 0xCA, 0x1E, 0xFB, 0xB8,
        0x53, 0x63, 0x7D, 0x0C, 0x57, 0x52, 0x14, 0xFC,
        0x77, 0xA5, 0xA6, 0x84, 0xD5, 0x0A, 0xBF, 0xE4,
        0xE9, 0x71, 0x99, 0x8E, 0x06, 0x6E, 0x50, 0x24,
        0xDA, 0x02, 0x76, 0x8A, 0xED, 0xE1, 0x3E, 0x83,
        0xF0, 0x51, 0x54, 0xA9, 0x99, 0x29, 0x48, 0x42,
        0x7A, 0xA9, 0x8C, 0x87, 0x42, 0x51, 0xAF, 0x56,
        0x94, 0x23, 0x53, 0x89, 0x44, 0xFA, 0xD8, 0x93,
        0xFC, 0x65, 0x6E, 0x9C, 0xED, 0x80, 0x6A, 0x85,
        0xD9, 0xC3, 0x36, 0x71, 0x02, 0x25, 0x29, 0x36,
        0x8E, 0x7E, 0xC7, 0x0C, 0x9E, 0xE9, 0x74, 0x30,
        0x1C, 0x08, 0xCB, 0xE6, 0xAC, 0x5E, 0x88, 0xE6,
        0x37, 0x79, 0x5C, 0xB2, 0xA2, 0x15, 0xFF, 0xAA,
        0x08, 0xED, 0xDE, 0x40, 0xAC, 0xFA, 0xEE, 0x2A,
        0x40, 0xD5, 0x05, 0xCF, 0x58, 0xA6, 0x69, 0x66,
        0x31, 0x5A, 0x68, 0x98, 0x24, 0x03, 0xD8, 0x1B,
        0xFA, 0x89, 0xE3, 0x7C, 0x9E, 0x42, 0x1D, 0xA5,
        0x88, 0xBA, 0x7E, 0x42, 0x2A, 0xC7, 0x44, 0x6A,
        0x1E, 0x61, 0xC8, 0x22, 0x29, 0x9D, 0xFC, 0x34,
        0xEC, 0xFA, 0xBE, 0x5C, 0xB6, 0x26, 0xB9, 0x6C,
        0x8E, 0xA6, 0xC9, 0x3B, 0xDB, 0xD2, 0xD5, 0xBD,
        0x70, 0xC5, 0xF8, 0x26, 0x7A, 0x84, 0xE0, 0x07,
        0xA7, 0x11, 0x5E, 0x5B, 0xE5, 0xF1, 0x20, 0x32,
        0xA3, 0x7C, 0xAB, 0x05, 0xD5, 0x41, 0xE3, 0xDE,
        0xA5, 0x1A, 0x83, 0x2E, 0xDE, 0x8D, 0x34, 0x9A,
        0xFD, 0xD5, 0xE6, 0xFC, 0xFC, 0x83, 0x46, 0xE3,
        0xD4, 0x7C, 0xF1, 0x7F, 0xEA, 0x87, 0x5E, 0x38,
        0x5D, 0xB9, 0x8A, 0xC2, 0xDB, 0xE8, 0xB4, 0xF8,
        0x05, 0x37, 0x31, 0x0D, 0xD9, 0x4C, 0xD0, 0xB6,
        0x25, 0xE9, 0x97, 0x85, 0xDB, 0x04, 0x9A, 0x01,
        0xF5, 0x4B, 0xA1, 0xF4, 0x2A, 0xDF, 0xEC, 0xAE,
        0x24, 0x11, 0xD3, 0x2B, 0x2F, 0x84, 0x6C, 0x88,
        0xA3, 0x0C, 0x76, 0xEA, 0x0A, 0x38, 0xB2, 0x71,
        0xB6, 0xAC, 0xA8, 0x23, 0x6E, 0x61, 0xEB, 0xB8,
        0x4A, 0x9D, 0xC4, 0x9E, 0x5C, 0x5B, 0xEE, 0x7E,
        0x7D, 0x8D, 0xA2, 0xC1, 0xA1, 0xA0, 0xA3, 0x14,
        0x50, 0xE0, 0x8F, 0xAB, 0xBB, 0x1B, 0x1F, 0x05,
        0xAA, 0xE3, 0x00, 0xD8, 0xCD, 0xE7, 0x35, 0xB4,
        0x7B, 0xBD, 0xB0, 0x5C, 0xCC, 0x0C, 0x05, 0x33,
        0x6B, 0xE4, 0x51, 0x73, 0x1B, 0x6B, 0x77, 0x7B,
        0xE5, 0xCB, 0xAF, 0x98, 0x53, 0x5F, 0x7E, 0x08,
        0xFF, 0xCD, 0x8A, 0x44, 0x9E, 0x1D, 0x43, 0x6A,
        0x4F, 0x05, 0x99, 0x01, 0xF5, 0x6F, 0x01, 0x30,
        0xBD, 0x15, 0xD7, 0x51, 0x16, 0x45, 0x40, 0x6B,
        0xF3, 0x13, 0xCA, 0x1F, 0x22, 0x02, 0xA4, 0xA8,
        0x6A, 0x1D, 0x04, 0x7F, 0xD5, 0x8A, 0x3E, 0x87,
        0x7F, 0x1D, 0x5A, 0x79, 0x75, 0xD1, 0x6D, 0x67,
        0xB3, 0x23, 0xC6, 0x28, 0x7B, 0x9C, 0xCE, 0xEE,
        0x98, 0x9E, 0xE8, 0x44, 0xA9, 0x3E, 0x7E, 0xFD,
        0x3B, 0xD9, 0xD8, 0x31, 0x6D, 0xA3, 0x77, 0xDF,
        0x0B, 0xB9, 0xE2, 0x61, 0xA2, 0x71, 0xD5, 0x0C,
        0xB7, 0x01, 0x67, 0xC3, 0x0D, 0x19, 0x2D, 0xAA,
        0xDE, 0x96, 0x0E, 0xEA, 0x33, 0x5E, 0xEC, 0x52,
        0xE5, 0x2D, 0x95, 0x39, 0xE1, 0xF9, 0x5D, 0x9E,
        0xB6, 0x5E, 0x54, 0x8F, 0x16, 0x60, 0x99, 0xED,
        0x88, 0x2C, 0x30, 0x72, 0x53, 0x6A, 0x6C, 0xAA,
        0x05, 0x21, 0xA5, 0xAA, 0x7C, 0x64, 0x72, 0xA0,
        0xC0, 0x4F, 0x80, 0xDA, 0x20, 0x5D, 0x52, 0x18,
        0x77, 0x07, 0xDF, 0x5C, 0x2F, 0x2E, 0xA2, 0x5F,
        0xEF, 0x00, 0xCA, 0x7B, 0xF0, 0xD3, 0xB7, 0xF8,
        0x1E, 0x31, 0x9E, 0x61, 0xCA, 0x2C, 0xC5, 0xA5,
        0x25, 0xA2, 0x7B, 0x56, 0xAA, 0xBA, 0xE4, 0xD5,
        0x35, 0xE5, 0xEC, 0x24, 0x2D, 0x81, 0x1A, 0x24,
        0xD7, 0x45, 0x76, 0xBF, 0x4B, 0x8A, 0x72, 0xFA,
        0x5F, 0xAE, 0xC1, 0xA2, 0x83, 0xB6, 0x1D, 0x60,
        0x28, 0x7E, 0x1E, 0x2E, 0xC8, 0xC6, 0xAB, 0x04,
        0x56, 0x5F, 0xD5, 0xCD, 0x64, 0x26, 0x34, 0x94,
        0xE8, 0x03, 0x41, 0x63, 0x35, 0x5B, 0x45, 0x84,
        0xCE, 0xFA, 0x0B, 0x66, 0x40, 0x85, 0x1A, 0xE1,
        0x23, 0xE9, 0x8F, 0xBD, 0xA9, 0x23, 0xFC, 0xA3,
        0x8E, 0x38, 0xB3, 0x84, 0xE2, 0xB9, 0x54, 0x41,
        0x4B, 0x36, 0x4F, 0xB8, 0xB0, 0x87, 0x56, 0x04,
        0x8B, 0x75, 0xC7, 0x85, 0x31, 0xD4, 0xA5, 0x12,
        0x99, 0xC4, 0x9D, 0xEA, 0x4B, 0x36, 0x8C, 0x19,
        0x82, 0xFE, 0xAD, 0x4A, 0xB1, 0xAA, 0x52, 0x35,
        0xA4, 0xA1, 0x7F, 0xB0, 0x64, 0x6F, 0x04, 0x04,
        0x7B, 0xF0, 0x80, 0x48, 0xA1, 0x1C, 0xF8, 0x95,
        0x8B, 0x68, 0x34, 0xB7, 0xFD, 0x00, 0x31, 0x30,
        0x6A, 0x39, 0xC8, 0xAE, 0x68, 0xC3, 0x53, 0x65,
        0x19, 0x7C, 0x1E, 0x57, 0x97, 0xFC, 0x47, 0x3E,
        0xB1, 0x94, 0x54, 0x48, 0x6F, 0xEB, 0xAA, 0xEC,
        0x5C, 0x2E, 0xE9, 0x2C, 0xCC, 0x3A, 0xF3, 0xC7,
        0x43, 0x08, 0x7D, 0x2D, 0x56, 0x4B, 0x7D, 0xE9,
        0xE5, 0x96, 0xF3, 0x12, 0x4B, 0xE9, 0x08, 0xF3,
        0x04, 0x5A, 0x75, 0x1A, 0x7D, 0x7E, 0x37, 0xE6,
        0xC8, 0xC1, 0xFE, 0xF3, 0x32, 0x63, 0x2D, 0x0B,
        0xBE, 0x05, 0x13, 0x6A, 0x44, 0x58, 0x7F, 0x54,
        0x5F, 0x5F, 0xF5, 0x2F, 0xB8, 0x0B, 0xF2, 0xBF,
        0x0B, 0xF4, 0x30, 0x2F, 0xCF, 0xEC, 0xFE, 0x08,
        0xEC, 0x51, 0xF2, 0x29, 0xD7, 0xAC, 0x28, 0xE1,
        0x75, 0x42, 0x61, 0xBC, 0xE7, 0xB1, 0x53, 0x4F,
        0x7D, 0x3B, 0xB0, 0x8D, 0x01, 0x15, 0x1E, 0xBE,
        0xEC, 0xD9, 0x54, 0xC2, 0x4E, 0x70, 0x3E, 0xEA,
        0x39, 0x14, 0x26, 0xB7, 0x01, 0x79, 0x5D, 0x06,
        0x93, 0x85, 0x99, 0xAA, 0x7D, 0xDC, 0xF9, 0x2E,
        0x44, 0x56, 0x9B, 0xFA, 0x9D, 0x91, 0x2A, 0x8E,
        0x89, 0x48, 0x51, 0xE3, 0xD0, 0x53, 0xB3, 0xAD,
        0x43, 0x29, 0xB7, 0x6A, 0x50, 0xC0, 0x78, 0x4D,
        0x42, 0xF3, 0x7C, 0x5F, 0x90, 0x06, 0xAC, 0x2A,
        0x9D, 0x5D, 0xE5, 0x18, 0x3F, 0xA3, 0xC6, 0x5E,
        0xCD, 0xB6, 0xCF, 0x31, 0x67, 0xA4, 0x7A, 0x8F,
        0x5C, 0x59, 0xBD, 0xD7, 0x9B, 0x7C, 0x24, 0x06,
        0x97, 0xE1, 0x59, 0x72, 0x85, 0x02, 0x74, 0xFE,
        0x41, 0xAD, 0x84, 0xD9, 0x0D, 0xCB, 0x34, 0x16,
        0x11, 0xE7, 0x66, 0xD2, 0x12, 0xDC, 0x76, 0x3C,
        0xF9, 0x4C, 0x8C, 0x41, 0x94, 0xCC, 0xA9, 0x1B,
        0x21, 0x03, 0x28, 0xE4, 0xA3, 0x37, 0x4E, 0x29,
        0xD2, 0x48, 0x11, 0x2B, 0xB6, 0x68, 0xA3, 0x92,
        0xC2, 0x0D, 0x87, 0x91, 0x03, 0x76, 0xB5, 0x00,
        0x1F, 0x3F, 0xFB, 0xBE, 0xC3, 0xE0, 0x08, 0xBF,
        0x2F, 0x46, 0xF7, 0x40, 0x73, 0x83, 0xA8, 0x0D,
        0xDA, 0x08, 0x2B, 0xDB, 0x8F, 0xE9, 0x25, 0xE4,
        0xF1, 0x2B, 0x37, 0x92, 0x27, 0x0E, 0x5A, 0x46,
        0xB8, 0xC5, 0x7B, 0x6E, 0x5A, 0x4B, 0x95, 0x58,
        0x4E, 0xF3, 0x80, 0xED, 0x49, 0x93, 0xEC, 0x52,
        0x9F, 0xF2, 0xAA, 0x39, 0xDD, 0x6D, 0xFE, 0x88,
        0xFD, 0xEB, 0x6E, 0xDA, 0x0E, 0x8D, 0xA7, 0x95,
        0x66, 0xB0, 0x7D, 0x37, 0xAE, 0xCC, 0x64, 0x37,
        0x25, 0x95, 0x18, 0xF9, 0x7E, 0x6C, 0x86, 0x12,
        0xB3, 0xC3, 0x57, 0x03, 0xBF, 0xF9, 0x92, 0x15,
        0x3E, 0x66, 0x0E, 0x2E, 0x20, 0x77, 0xA0, 0x5F,
        0x26, 0x5F, 0xB5, 0x12, 0x1D, 0xD7, 0x9F, 0x0A,
        0x33, 0xBC, 0x38, 0xEC, 0x83, 0x08, 0xE2, 0xA9,
        0x84, 0xCD, 0x3D, 0x8A, 0xC6, 0x09, 0x30, 0x6F,
        0x77, 0x93, 0xD7, 0xDE, 0x08, 0xD8, 0x45, 0xA4,
        0x21, 0x28, 0x26, 0x4E, 0x5C, 0x17, 0x77, 0x74,
        0xE3, 0x5D, 0x58, 0x7C, 0x96, 0xB2, 0x47, 0x05,
        0x42, 0x21, 0x78, 0x5D, 0xB3, 0x8D, 0xDC, 0x6F,
        0xDB, 0xF7, 0xBF, 0x6F, 0x66, 0x4B, 0xD6, 0x30,
        0x14, 0xC0, 0xBF, 0x94, 0x2A, 0x83, 0x91, 0x6C,
        0xBF, 0x2C, 0x42, 0x85, 0x41, 0xED, 0xA2, 0xBB,
        0xCB, 0xFC, 0xF9, 0x35, 0xDE, 0xFC, 0xB3, 0x63,
        0xE1, 0x64, 0xAA, 0x51, 0x2D, 0xD5, 0xFA, 0x79,
        0x53, 0x31, 0x40, 0x0B, 0x9B, 0xD0, 0x3C, 0xE3,
        0xD7, 0x2D, 0x91, 0x05, 0x62, 0xC3, 0x81, 0xFE,
        0x93, 0x1E, 0x8C, 0x37, 0x9E, 0x30, 0x23, 0x73,
        0x3A, 0xB9, 0x18, 0x6E, 0x5D, 0xEF, 0x31, 0xE9,
        0xF6, 0x25, 0x7F, 0xB8, 0x47, 0x74, 0xCE, 0x28,
        0x23, 0xD4, 0x4F, 0xC1, 0x42, 0xCB, 0xEB, 0x59,
        0x8A, 0x68, 0xFD, 0x39, 0x48, 0x37, 0x1A, 0x5D,
        0x0C, 0x09, 0x64, 0xC6, 0xE1, 0x21, 0x5D, 0x89,
        0xF6, 0x58, 0xE5, 0x50, 0x4A, 0xD0, 0x93, 0xBC,
        0x86, 0x02, 0xBA, 0xD2, 0x36, 0x24, 0x9D, 0x7E,
        0xAF, 0xB6, 0xA1, 0xA0, 0x7C, 0xA7, 0xC7, 0x4D,
        0xAC, 0x30, 0x7A, 0x70, 0x0F, 0x2F, 0x81, 0x40,
        0xC1, 0x08, 0x6B, 0x21, 0xF2, 0xE1, 0x51, 0x9C,
        0x1D, 0x46, 0x94, 0x93, 0x2A, 0x1C, 0x18, 0xCB,
        0xED, 0x0D, 0x0E, 0x29, 0xDE, 0xFC, 0x52, 0x52,
        0x97, 0x93, 0x70, 0x85, 0xE2, 0x63, 0x0D, 0xC6,
        0x2C, 0x0C, 0x05, 0x0C, 0x4F, 0xF2, 0x70, 0x87,
        0x2B, 0xE7, 0xBB, 0x52, 0x2D, 0xD6, 0x99, 0x1B,
        0x59, 0x6F, 0xC2, 0x92, 0x11, 0x72, 0x5D, 0x99,
        0x60, 0xB1, 0x6A, 0x52, 0xEA, 0x91, 0x78, 0x19,
        0x23, 0xC0, 0x3B, 0x71, 0x9D, 0x09, 0xD6, 0xE7,
        0x10, 0x6D, 0xC5, 0x70, 0x55, 0xC1, 0x9E, 0xF8,
        0x76, 0xE5, 0xEC, 0x23, 0x17, 0xE7, 0xE4, 0x23,
        0xC9, 0x71, 0x45, 0x40, 0x72, 0x01, 0x9E, 0x28,
        0xE6, 0x5C, 0x81, 0xED, 0x52, 0x7A, 0xF1, 0x89,
        0xBD, 0xFC, 0xF5, 0x21, 0xC9, 0x23, 0x40, 0x75,
        0x54, 0xAC, 0xBF, 0x69, 0x45, 0xD1, 0x85, 0x44,
        0x3D, 0xAC, 0x1A, 0x1A, 0x08, 0x8A, 0x68, 0xB5,
        0x17, 0xD5, 0xD9, 0x90, 0xE1, 0x10, 0x30, 0xDE,
        0x4F, 0x75, 0x09, 0xE8, 0x7A, 0x77, 0xB3, 0x7C,
        0xF2, 0x0A, 0x78, 0xE2, 0xCD, 0x48, 0x94, 0x17,
        0x3C, 0x32, 0xA3, 0x27, 0x35, 0x51, 0x16, 0xB7,
        0x18, 0x51, 0x44, 0x42, 0x65, 0x60, 0x6A, 0x0A,
        0x9A, 0x6D, 0x94, 0x61, 0xCC, 0x5D, 0xD8, 0x3B,
        0x52, 0x7E, 0x4D, 0xBD, 0x6A, 0xEE, 0x03, 0x3D,
        0x66, 0x1C, 0x3D, 0xE8, 0xC1, 0x82, 0x97, 0xE5,
        0xD1, 0x31, 0xDB, 0xC8, 0xF6, 0x96, 0xE9, 0x47,
        0xC9, 0x5C, 0x71, 0x77, 0x2B, 0x62, 0x44, 0x74,
        0x4D, 0x06, 0x1E, 0x14, 0x45, 0x3B, 0x9F, 0xB1,
        0x17, 0x34, 0x80, 0x2D, 0xBA, 0x6F, 0x81, 0x79,
        0xB8, 0x0D, 0xAC, 0xFE, 0xB6, 0xBA, 0xDF, 0xD1,
        0x4E, 0x05, 0x76, 0x73, 0x6F, 0x80, 0x10, 0xC5,
        0x32, 0x87, 0xA3, 0xD3, 0x93, 0x18, 0x79, 0xEF,
        0x27, 0x3B, 0xBF, 0xCD, 0xB5, 0xDE, 0x5B, 0x88,
        0xAF, 0x51, 0xFD, 0x8A, 0x8C, 0x8F, 0x0A, 0x58,
        0x94, 0xE2, 0x25, 0xDF, 0xE8, 0x73, 0xFC, 0xC0,
        0x3C, 0xB1, 0xC9, 0xB5, 0x78, 0x25, 0xF1, 0x11,
        0x75, 0xC8, 0x7D, 0x08, 0x78, 0xB9, 0xE6, 0x15,
        0x6B, 0x40, 0x1B, 0x2F, 0xBE, 0x30, 0x03, 0x6B,
        0xFC, 0x7D, 0xB1, 0x00, 0x02, 0x71, 0xB7, 0xFF,
        0x5D, 0x63, 0xA8, 0x09, 0x50, 0x75, 0xEF, 0xBD,
        0x34, 0xEE, 0x73, 0xDE, 0x60, 0x14, 0x95, 0x2D,
        0x15, 0xBC, 0x30, 0x23, 0x07, 0x02, 0xD8, 0x7C,
        0x9A, 0x96, 0xD5, 0xE9, 0xF1, 0xF0, 0xF9, 0x26,
        0x25, 0x96, 0xAA, 0x58, 0xB7, 0xE4, 0x1A, 0xD9,
        0xA0, 0x9E, 0xAD, 0xB9, 0x44, 0xB6, 0x3F, 0xD9,
        0x8B, 0x34, 0x7D, 0x11, 0xBD, 0x52, 0x97, 0xC3,
        0xBE, 0x28, 0x23, 0x85, 0x9F, 0x2F, 0x35, 0xA4,
        0xE5, 0x4E, 0x13, 0x68, 0x89, 0x09, 0xC3, 0x1A,
        0x83, 0xE7, 0xDE, 0xCE, 0x4B, 0xDF, 0x31, 0x03,
        0x9C, 0x72, 0xBA, 0x54, 0xA1, 0x20, 0x2D, 0x17,
        0x2A, 0x6B, 0x8A, 0x2C, 0xE9, 0x6D, 0xED, 0xCA,
        0x5B, 0x24, 0xF7, 0xB9, 0x42, 0xC1, 0x4E, 0x13,
        0x3D, 0xAA, 0x8A, 0xB8, 0xCB, 0xD2, 0x4C, 0x1F,
        0x0B, 0xBE, 0xB1, 0x27, 0x97, 0x67, 0x26, 0x72,
        0xE2, 0x2C, 0xE6, 0xC2, 0x12, 0x37, 0xB2, 0x79,
        0x7D, 0x8E, 0x54, 0xCC, 0x8F, 0xC7, 0x6C, 0x43,
        0xB4, 0x75, 0x29, 0x66, 0xA3, 0xA4, 0x09, 0x44,
        0xE7, 0x2D, 0x37, 0x3F, 0x0D, 0x3E, 0x84, 0xF9,
        0xA3, 0x30, 0x1E, 0xAE, 0x9E, 0xDA, 0x35, 0x44,
        0x4B, 0x1E, 0x49, 0xE6, 0x61, 0x18, 0x20, 0x6A,
        0x56, 0xEB, 0x46, 0xD4, 0x8D, 0x20, 0x95, 0x4A,
        0x77, 0x9A, 0x1E, 0x74, 0xE3, 0xE3, 0xB2, 0xBD,
        0x40, 0x3D, 0x46, 0xB3, 0x35, 0x10, 0x11, 0xCB,
        0x6F, 0x8A, 0x86, 0x72, 0xB2, 0xF3, 0xD9, 0x90,
        0x31, 0x47, 0x55, 0x77, 0x6C, 0xE3, 0x23, 0x7F,
        0x0A, 0x50, 0xE7, 0x71, 0x20, 0x53, 0x09, 0xC0,
        0x5D, 0x9A, 0x78, 0xD3, 0x68, 0x88, 0xA8, 0x3B,
        0xAD, 0x78, 0xE8, 0x6E, 0xDF, 0x36, 0xA8, 0x8D,
        0xC7, 0x1C, 0x5F, 0x11, 0x56, 0x83, 0x90, 0xD0,
        0xB5, 0x92, 0x02, 0xE2, 0x9E, 0xE1, 0x1E, 0xCB,
        0x9F, 0x56, 0x89, 0x63, 0xE8, 0x17, 0x70, 0x83,
        0x9F, 0xF2, 0x39, 0xAD, 0x03, 0x15, 0x6C, 0xC0,
        0x71, 0xE8, 0xB7, 0x40, 0x15, 0x95, 0xEC, 0xEE,
        0x62, 0x34, 0xAC, 0x34, 0xB7, 0x11, 0x70, 0x3D,
        0x68, 0xC6, 0x7A, 0x28, 0x83, 0xBE, 0x9C, 0x18,
        0xAB, 0x7F, 0x1A, 0x1B, 0x2E, 0x5C, 0x90, 0xA2,
        0x32, 0x3C, 0xDF, 0x1E, 0xD4, 0x98, 0x50, 0xB8,
        0x39, 0x38, 0x19, 0x2F, 0x62, 0x8C, 0x9E, 0xF6,
        0x5B, 0x77, 0x93, 0x95, 0xEE, 0x37, 0x34, 0xC7,
        0xA9, 0x01, 0xF7, 0x47, 0x38, 0x86, 0xD7, 0x12,
        0xD2, 0x15, 0x41, 0x68, 0x16, 0xC3, 0x01, 0x6C,
        0xC2, 0x83, 0x83, 0xD4, 0x78, 0x7B, 0x46, 0xF6,
        0x89, 0xDC, 0xE1, 0x11, 0xDA, 0x4D, 0xB8, 0xAC,
        0x10, 0xE8, 0x4F, 0x66, 0xA5, 0xC2, 0xBD, 0xA1,
        0xB3, 0xFC, 0x97, 0x7F, 0x6A, 0x0F, 0x73, 0x2E,
        0xDA, 0x4F, 0x69, 0xB9, 0x75, 0x51, 0xA4, 0xB8,
        0xB2, 0x61, 0xD6, 0x88, 0x71, 0x94, 0xD3, 0xAF,
        0xE7, 0xF4, 0xB8, 0x7F, 0xB3, 0xD4, 0x1A, 0xC6,
        0xDC, 0xDB, 0x8F, 0xD3, 0x9B, 0xE5, 0x0F, 0x2F,
        0x38, 0x2B, 0xAA, 0x4D, 0x19, 0xC7, 0x45, 0x0A,
        0xB3, 0xA1, 0xAC, 0x4C, 0x63, 0xCF, 0x93, 0x0A,
        0xAA, 0x51, 0x7A, 0x15, 0xD5, 0xC0, 0xD5, 0x49,
        0xFE, 0x03, 0x22, 0x00, 0x71, 0xD3, 0x69, 0x22,
        0x3E, 0x51, 0x29, 0x6E, 0xCB, 0xF8, 0x0D, 0xCD,
        0x79, 0xFB, 0xDF, 0xB8, 0xDF, 0x62, 0x90, 0x4D,
        0x5A, 0x36, 0x20, 0x0F, 0x29, 0xCC, 0x47, 0xE8,
        0x0C, 0x86, 0x15, 0xEF, 0x1B, 0x78, 0xDB, 0xB2,
        0x6A, 0x1A, 0xA7, 0xA6, 0x6E, 0x4D, 0x9A, 0x51,
        0xC9, 0x72, 0xAC, 0x9C, 0x94, 0xEA, 0xB9, 0x95,
        0x14, 0xB5, 0xAD, 0xAE, 0x62, 0x51, 0xE8, 0xAA,
        0x30, 0xA5, 0xE5, 0x87, 0x42, 0x4E, 0x3B, 0x7B,
        0xCC, 0x42, 0xEB, 0xE7, 0x33, 0x3D, 0x92, 0x10,
        0x97, 0x26, 0x53, 0xF8, 0x11, 0x8B, 0x83, 0xAB,
        0xE1, 0xBF, 0x7E, 0x9E, 0xE9, 0xCD, 0xAC, 0x28,
        0x99, 0x7D, 0x14, 0x4C, 0x34, 0xDE, 0xA6, 0x5B,
        0x59, 0x51, 0x2C, 0x73, 0x29, 0x27, 0xDB, 0xA8,
        0x20, 0x7D, 0x56, 0x91, 0x98, 0x47, 0x21, 0xB7,
        0x27, 0x9A, 0xFC, 0xDD, 0xE0, 0x6A, 0x6B, 0xD2,
        0x68, 0x0E, 0xBB, 0x9B, 0x2E, 0x3C, 0xFE, 0xE9,
        0xA6, 0x6D, 0x73, 0xD0, 0xC0, 0xDE, 0xD6, 0x53,
        0x70, 0x8B, 0x09, 0x0B, 0x82, 0x30, 0x65, 0xF9,
        0x70, 0x78, 0x49, 0xE3, 0xB3, 0x7D, 0x41, 0x25,
        0xCA, 0x69, 0x3E, 0x74, 0x2E, 0x02, 0x3F, 0x05,
        0x8A, 0xDC, 0x95, 0x07, 0x9B, 0xB0, 0x0C, 0x56,
        0xBE, 0x0D, 0x2F, 0x07, 0x81, 0x82, 0xEF, 0xAB,
        0x30, 0x72, 0xB0, 0xFD, 0x09, 0x76, 0x7B, 0x8A,
        0x13, 0xC2, 0x80, 0x5A, 0x75, 0x91, 0xB5, 0xB2,
        0xE1, 0x24, 0x75, 0xB5, 0xC8, 0x24, 0xDB, 0xEB,
        0x15, 0x79, 0x30, 0xAB, 0x38, 0x9F, 0x91, 0x5F,
        0xCC, 0xEC, 0x8F, 0x48, 0x64, 0x7E, 0xE4, 0xB6,
        0x6A, 0xB6, 0xB5, 0x36, 0xC2, 0x2D, 0xE3, 0xE5,
        0xEE, 0x4A, 0xBB, 0x42, 0xF8, 0xE0, 0x00, 0x9A,
        0xF0, 0x45, 0x54, 0xF1, 0x28, 0xAC, 0xA3, 0xCC,
        0xE4, 0x03, 0xBB, 0x01, 0xFD, 0xB7, 0xB5, 0xE2,
        0xA7, 0x2B, 0x82, 0x91, 0x1C, 0x1F, 0xD0, 0x65,
        0x23, 0xFF, 0x90, 0x19, 0x21, 0x41, 0xC6, 0x89,
        0xEC, 0xCB, 0x0B, 0xE6, 0x1B, 0x4C, 0x6D, 0x77,
        0x06, 0x29, 0x59, 0x02, 0x18, 0xA4, 0x01, 0x1A,
        0x68, 0xB8, 0x6F, 0xF5, 0x0D, 0x23, 0x03, 0x9C,
        0x9B, 0xCD, 0x43, 0x61, 0xF6, 0x98, 0x0A, 0x60,
        0xEF, 0x88, 0xD1, 0x44, 0x0D, 0x30, 0x4C, 0x5B,
        0x4B, 0x52, 0xD6, 0xED, 0xC2, 0x91, 0x12, 0xDC,
        0x3A, 0x8A, 0xF2, 0x85, 0x89, 0xE8, 0xF6, 0x29,
        0x48, 0xED, 0xB6, 0xBE, 0x76, 0x64, 0x6D, 0x59,
        0x66, 0x06, 0xB9, 0xE7, 0x05, 0xFE, 0xE3, 0xF1,
        0x44, 0xA0, 0x7B, 0xC9, 0xED, 0x1D, 0x40, 0x0C
    };
    static const byte msg_65[] = {
        0x88, 0x5A, 0x0B, 0xDD, 0x8D, 0xE7, 0x4B, 0xC7,
        0x11, 0x69, 0x0A, 0xA6, 0x14, 0xDD, 0xA5, 0x32,
        0xF4, 0xD8, 0xC7, 0xEA, 0x2C, 0x27, 0x85, 0x5A,
        0x57, 0x8E, 0x63, 0x61, 0xCA, 0xAE, 0x2C, 0x0B,
        0xF7, 0xE7, 0x73, 0xB4, 0x90, 0x0A, 0x32, 0x93,
        0x12, 0x1A, 0x6E, 0x0D, 0xD6, 0x10, 0x10, 0x7A,
        0x7A, 0x65, 0xBD, 0x6E, 0x11, 0xF6, 0x19, 0xFC,
        0x0E, 0x9C, 0xE7, 0xBF, 0x7B, 0x5D, 0xE1, 0x80,
        0x76, 0xE1, 0xB7, 0x25, 0x57, 0x20, 0x97, 0xB2,
        0x47, 0xD8, 0xE0, 0x46, 0x24, 0x94, 0xF6, 0x3F,
        0x4E, 0xDF, 0xBE, 0xAC, 0x2F, 0xA2, 0xEC, 0xAE,
        0x0C, 0xCA, 0xD4, 0x28, 0xBD, 0x79, 0x6C, 0xF2,
        0x60, 0x92, 0xA1, 0xCD, 0x50, 0x5F, 0x59, 0x39,
        0x11, 0xED, 0x10, 0xFD, 0xA4, 0x26, 0xC7, 0xE3,
        0xC5, 0xA4, 0x39, 0xE8, 0x50, 0x42, 0x13, 0x18,
        0xAE, 0x07, 0x85, 0xB0, 0x5A, 0xA9, 0x9F, 0x58,
        0xD6, 0x85, 0x6D, 0xEB, 0x78, 0xBB, 0xE4, 0x88,
        0xC7, 0x0E, 0xEE, 0x42, 0xBB, 0x9A, 0xB5, 0x92,
        0x7B, 0x2E, 0xD2, 0x5C, 0xD1, 0x43, 0x77, 0xCD,
        0x7E, 0x1A, 0x88, 0x34, 0xE8, 0x21, 0x48, 0x00,
        0x2F, 0xCB, 0x98, 0x5A, 0xB9, 0x43, 0x12, 0x97,
        0x01, 0x0B, 0x2B, 0xC7, 0x0F, 0x91, 0x32, 0x37,
        0x3C, 0x6D, 0xD2, 0xA2, 0xA9, 0xCF, 0x24, 0x6F,
        0xE0, 0x26, 0x2E, 0x8B, 0x53, 0xE6, 0x93, 0xF3,
        0xD6, 0xFE, 0xD3, 0xED, 0xD1, 0xF2, 0x00, 0x4E,
        0xD1, 0x7C, 0x2C, 0xF5, 0xB2, 0x57, 0xF4, 0xAD,
        0xA5, 0xDC, 0x1A, 0x7C, 0x15, 0x1F, 0xFE, 0x03,
        0xB9, 0x6A, 0x4D, 0xB9, 0x91, 0xE4, 0x13, 0x2D,
        0x01, 0xDE, 0x1F, 0x03, 0x3E, 0xD8, 0x13, 0x57,
        0xEA, 0xE7, 0xC1, 0xA8, 0xD2, 0xDD, 0xD9, 0x2D,
        0xDF, 0xC0, 0x6F, 0x67, 0x13, 0x94, 0xD2, 0xF6,
        0x02, 0x12, 0xC6, 0xE4, 0x49, 0xEA, 0x35, 0x93,
        0x24, 0xFE, 0xD3, 0x8C, 0x84, 0xD3, 0x6D, 0x15,
        0x43, 0x2E, 0x11, 0xE7, 0x15, 0x00, 0x15, 0x80,
        0x4F, 0x97, 0xA3, 0xC6, 0x77, 0x38, 0x2C, 0xD4,
        0x6A, 0xA4, 0xD7, 0xAC, 0xEE, 0x56, 0x86, 0xFB,
        0xCE, 0xD7, 0xA9, 0xE8, 0x5D, 0x29, 0xC4, 0x83,
        0x86, 0xE6, 0x9F, 0x40, 0x69, 0x3D, 0x9A, 0xDA,
        0xBE, 0xB4, 0x3B, 0xD0, 0xE5, 0x03, 0x6A, 0xCD,
        0xE6, 0x31, 0xB5, 0x49, 0x57, 0xF4, 0xFC, 0xE2,
        0x6F, 0x7A, 0x24, 0xB0, 0xDA, 0xD4, 0x34, 0x8A,
        0x67, 0x89, 0xCA, 0xE1, 0x06, 0x13, 0x06, 0x20,
        0xED, 0x2F, 0xA0, 0xEA, 0x38, 0xF5, 0x75, 0xF2,
        0x87, 0x83, 0xBC, 0x92, 0xB3, 0x2B, 0x0C, 0x51,
        0xC8, 0xA6, 0x54, 0x6F, 0x5D, 0x88, 0x09, 0x5F,
        0x9F, 0x73, 0xC6, 0x5B, 0xF6, 0xF2, 0x51, 0xA2,
        0xC4, 0x69, 0x74, 0x64, 0x45, 0xC5, 0x88, 0xC3,
        0xEA, 0x81, 0x39, 0xE4, 0x33, 0xD4, 0xFE, 0x2D,
        0xE4, 0xC0, 0xD3, 0x58, 0xB6, 0xCA, 0x8A, 0x62,
        0x94, 0xE6, 0xAF, 0xC1, 0xB9, 0x60, 0x74, 0xC0,
        0x68, 0xEF, 0x67, 0xB1, 0x58, 0xF1, 0x12, 0x9C,
        0xFE, 0x0A, 0x3A, 0xE7, 0xEB, 0x9D, 0x45, 0x4F,
        0x35, 0x7F, 0xBB, 0x6A, 0xB3, 0xB9, 0x92, 0x2B,
        0x1B, 0xCD, 0x55, 0x58, 0x61, 0x87, 0xCD, 0x24,
        0x69, 0x24, 0x82, 0x78, 0x23, 0x34, 0xAC, 0x9F,
        0x2B, 0x86, 0x12, 0x48, 0xF6, 0xA5, 0x30, 0xE9,
        0x3E, 0x11, 0x48, 0x87, 0x84, 0xDD, 0xE5, 0xEA,
        0x67, 0x8A, 0xE5, 0x05, 0x90, 0x3E, 0x23, 0x10,
        0x53, 0x30, 0x8C, 0x1B, 0x87, 0x84, 0x60, 0x7E,
        0x06, 0x3F, 0x48, 0x98, 0xA4, 0xFA, 0xB6, 0x01,
        0xD3, 0xE6, 0x96, 0x85, 0x97, 0x21, 0x55, 0xF6,
        0x3F, 0x09, 0xFD, 0x84, 0xB2, 0xB3, 0xDF, 0x74,
        0x1F, 0xB6, 0x42, 0xAC, 0xA6, 0x03, 0xD0, 0xD5,
        0x96, 0xE0, 0xA8, 0xDA, 0xD4, 0x24, 0xF4, 0x64,
        0x0F, 0x98, 0xB9, 0x6F, 0xB2, 0x42, 0xC6, 0x95,
        0xDC, 0x33, 0x1F, 0x57, 0x59, 0xF7, 0x5E, 0xAF,
        0x19, 0x1C, 0xBD, 0x98, 0x5E, 0xC5, 0x99, 0x8D,
        0x56, 0x48, 0xC8, 0x5E, 0xB6, 0x31, 0x29, 0x5F,
        0x61, 0x56, 0x7C, 0x11, 0x63, 0xF9, 0x90, 0xDC,
        0x4F, 0xA1, 0x71, 0x40, 0x91, 0x26, 0x1E, 0x5F,
        0x3E, 0x5F, 0x0B, 0xFE, 0x84, 0x55, 0xBB, 0x8B,
        0xAA, 0x1D, 0x69, 0x42, 0x1F, 0x15, 0x37, 0x4E,
        0x73, 0xB0, 0x7E, 0x78, 0x57, 0x9D, 0x0E, 0x25,
        0x1A, 0x41, 0xEE, 0x1A, 0x50, 0x43, 0xAA, 0xBF,
        0x8B, 0xE7, 0x73, 0xEE, 0x7F, 0x9D, 0x0F, 0xDF,
        0xCF, 0xD3, 0xAE, 0x71, 0x1F, 0xAB, 0x1D, 0x3D,
        0xBC, 0xC2, 0x84, 0x3B, 0xE5, 0xA9, 0x46, 0xB2,
        0x4D, 0x8B, 0x9B, 0x94, 0x35, 0x8B, 0x5F, 0x59,
        0x8E, 0x88, 0xED, 0x3D, 0x53, 0xF3, 0x10, 0xF8,
        0xEC, 0x63, 0x22, 0x9D, 0x4F, 0x5B, 0xB1, 0xB6,
        0xD5, 0x24, 0xA5, 0xAF, 0x9C, 0x39, 0x47, 0x79,
        0x25, 0xC7, 0xE2, 0x90, 0x95, 0xFC, 0x43, 0xF1,
        0x71, 0xFE, 0xCD, 0xD0, 0x61, 0xF3, 0x62, 0x62,
        0x71, 0x21, 0x75, 0x2C, 0x23, 0x6B, 0x79, 0x2F,
        0x1B, 0x31, 0x90, 0x79, 0x7C, 0xD0, 0x57, 0x5C,
        0x58, 0x4F, 0x30, 0xB5, 0x56, 0x81, 0x19, 0x61,
        0x90, 0x45, 0x09, 0xC9, 0x8B, 0xCD, 0xE8, 0x65,
        0x9D, 0x22, 0x80, 0xF4, 0x95, 0xA0, 0xC9, 0x55,
        0x7D, 0x38, 0x11, 0xAF, 0x5E, 0xD4, 0x37, 0x7B,
        0xC7, 0x59, 0x9E, 0x49, 0x59, 0xFF, 0x85, 0xF2,
        0x15, 0x0A, 0xCD, 0xEC, 0xC1, 0xF7, 0x67, 0x2D,
        0xE1, 0xEE, 0x4D, 0xB4, 0x4C, 0x1F, 0xB5, 0xF7,
        0x99, 0x8A, 0xB5, 0xDB, 0x74, 0x2F, 0x6C, 0x5D,
        0x32, 0xCB, 0xC0, 0xF2, 0xFB, 0xC9, 0x54, 0xEA,
        0xD6, 0xCC, 0x13, 0x4B, 0x97, 0x62, 0xDF, 0x33,
        0x13, 0x86, 0xDE, 0xCA, 0x31, 0x69, 0x47, 0x88,
        0x4B, 0x9A, 0x13, 0xAD, 0xEA, 0x5C, 0xBE, 0x29,
        0x56, 0x64, 0x4F, 0xA1, 0x2A, 0x7B, 0xB3, 0xBF,
        0xB9, 0x7E, 0x1D, 0x93, 0xA7, 0x01, 0x91, 0xAC,
        0x38, 0xA0, 0x37, 0x32, 0x58, 0xC2, 0xC2, 0x81,
        0x6D, 0xEA, 0x6E, 0xAF, 0x88, 0x0D, 0x69, 0xF4,
        0x5F, 0xBA, 0x4C, 0x29, 0x0F, 0x18, 0xD3, 0x4B,
        0xB8, 0x36, 0x8C, 0xF4, 0xEB, 0xB4, 0x72, 0xBA,
        0x49, 0x9C, 0xBB, 0x54, 0x50, 0x1E, 0xE3, 0xA2,
        0x8E, 0x5F, 0xB9, 0xFD, 0xC6, 0x6C, 0xF6, 0x45,
        0x72, 0x09, 0x47, 0x19, 0xBB, 0xDB, 0x48, 0xF3,
        0xF4, 0x88, 0x51, 0x3B, 0x65, 0x50, 0xE1, 0x27,
        0xE8, 0x34, 0x1C, 0x7E, 0x53, 0xDC, 0xFD, 0xA7,
        0xD4, 0x08, 0x05, 0x58, 0x0B, 0xC7, 0xD3, 0x0A,
        0x72, 0xF2, 0x44, 0xCC, 0xDB, 0x5A, 0xEF, 0x66,
        0x1B, 0x0F, 0x30, 0x4E, 0xC5, 0xB7, 0xAB, 0x93,
        0xB8, 0xC5, 0xC4, 0x9A, 0x77, 0x68, 0x38, 0xB7,
        0xD5, 0x23, 0x74, 0xAA, 0x41, 0x63, 0x02, 0x24,
        0xD6, 0x16, 0xF3, 0x10, 0xE4, 0x99, 0xEC, 0xAD,
        0xCE, 0x93, 0xE7, 0x8B, 0x94, 0xD3, 0xCA, 0x48,
        0xB3, 0x47, 0xBC, 0x0E, 0xEC, 0xAA, 0x20, 0x66,
        0x02, 0x29, 0x65, 0xC8, 0x07, 0xBE, 0xF9, 0x02,
        0x9B, 0xC5, 0x22, 0x8F, 0x00, 0x5E, 0xDB, 0x74,
        0xD4, 0xB1, 0x44, 0x98, 0xCE, 0x3A, 0xE1, 0x3B,
        0xEB, 0x7C, 0x69, 0x3B, 0x66, 0x9E, 0xE9, 0xF9,
        0xA6, 0xF4, 0x6F, 0xC0, 0x0E, 0xC0, 0x5E, 0x13,
        0x2B, 0xB6, 0xC6, 0x76, 0x0F, 0xB5, 0xC5, 0x1C,
        0x83, 0x23, 0xAC, 0xD6, 0xA3, 0xC7, 0x5A, 0x72,
        0xE9, 0x73, 0x89, 0x66, 0xD1, 0x25, 0xB9, 0x61,
        0x3B, 0x31, 0x45, 0xC6, 0x7B, 0x5E, 0x98, 0x81,
        0x87, 0xE8, 0x5F, 0x29, 0xAD, 0xCB, 0xAF, 0x74,
        0xE3, 0x3A, 0x61, 0x1F, 0xFF, 0x25, 0x2A, 0xEB,
        0xBA, 0xEB, 0x1E, 0xA6, 0x41, 0xE6, 0xFC, 0x8B,
        0xDF, 0x73, 0x41, 0xBE, 0x2A, 0xA8, 0x57, 0xE4,
        0x43, 0xAC, 0xFB, 0xCE, 0xB2, 0x15, 0x5D, 0x08,
        0x1A, 0xCB, 0x4C, 0xCD, 0xB0, 0x98, 0xD5, 0x7C,
        0xEF, 0x6F, 0x6F, 0xD3, 0x42, 0xDB, 0x2D, 0x83,
        0xB6, 0x12, 0x3E, 0x0A, 0xD3, 0xC9, 0x3F, 0x30,
        0x08, 0x11, 0xB8, 0xD5, 0xA1, 0x1A, 0x5A, 0x29,
        0xBE, 0x60, 0x81, 0x6F, 0x69, 0xB2, 0x9D, 0x1D,
        0x7E, 0x15, 0x88, 0x69, 0xD8, 0x60, 0xF6, 0xFB,
        0x82, 0x9D, 0xE8, 0x0D, 0x3E, 0x1B, 0x69, 0x9C,
        0x3A, 0xB6, 0x80, 0x4E, 0xB6, 0x54, 0x91, 0x78,
        0xD9, 0x47, 0x33, 0x38, 0xD6, 0xAF, 0x20, 0x9E,
        0x1F, 0x7D, 0x26, 0x3C, 0x66, 0x7A, 0xE6, 0x89,
        0x5F, 0x6E, 0x29, 0x33, 0x92, 0x34, 0x71, 0xF1,
        0x99, 0x58, 0x1F, 0x8A, 0x51, 0xBD, 0x9A, 0xA4,
        0x52, 0xEE, 0xE4, 0xBF, 0xE9, 0x56, 0x69, 0xAC,
        0xD0, 0x7B, 0x41, 0xB0, 0x0C, 0x03, 0xF5, 0x5A,
        0x40, 0xD1, 0x0B, 0x50, 0xF8, 0xE4, 0x67, 0xBD,
        0x07, 0x1C, 0x8F, 0x40, 0x5C, 0xF1, 0x19, 0x61,
        0x2D, 0x32, 0x40, 0x5B, 0xD5, 0x27, 0x5A, 0x6B,
        0xBF, 0x22, 0x17, 0xF9, 0xF1, 0x79, 0x0D, 0x29,
        0x99, 0x7B, 0x7B, 0x6B, 0x1E, 0xC8, 0xD7, 0x92,
        0x4A, 0xB9, 0xE6, 0x44, 0xC1, 0x29, 0xCE, 0xE8,
        0x74, 0x33, 0x29, 0x1A, 0x2C, 0x8E, 0xD6, 0xBC,
        0x3C, 0x2A, 0x19, 0xD0, 0x76, 0xB1, 0x77, 0xEE,
        0x60, 0x50, 0x69, 0x2A, 0xDA, 0x8E, 0x95, 0x57,
        0x4D, 0x6C, 0xE9, 0xAB, 0xE4, 0x97, 0x95, 0xD8,
        0xF2, 0x8E, 0xAB, 0x69, 0x67, 0x6E, 0x79, 0x03,
        0xA6, 0x56, 0xFA, 0xB3, 0x20, 0x25, 0xFE, 0x34,
        0x65, 0xCB, 0xDB, 0x57, 0x01, 0xC1, 0x77, 0x20,
        0x9D, 0x91, 0x89, 0xA5, 0x91, 0x7C, 0x13, 0x37,
        0xDE, 0x39, 0xF5, 0x75, 0xE5, 0xDD, 0xB9, 0x3C,
        0xA7, 0x6B, 0xEB, 0x52, 0xAF, 0x32, 0xE8, 0xD7,
        0x12, 0x7B, 0x28, 0xF7, 0xCE, 0x73, 0x12, 0xE8,
        0x03, 0x90, 0x47, 0x21, 0xAB, 0x21, 0x6E, 0x92,
        0xA8, 0xA9, 0xE6, 0x09, 0xFC, 0x10, 0xAF, 0x8D,
        0xC2, 0xAA, 0xCA, 0x14, 0xA9, 0x7B, 0xB0, 0xE4,
        0xB2, 0x34, 0xC7, 0x00, 0x0E, 0xBB, 0xE0, 0xC4,
        0x42, 0xF1, 0x85, 0x94, 0x6B, 0x7C, 0xE7, 0x72,
        0x80, 0x95, 0xCD, 0x60, 0x16, 0x9B, 0x0B, 0xD9,
        0x7B, 0x36, 0xB3, 0xAE, 0x38, 0x55, 0xD9, 0x89,
        0x25, 0xB2, 0x9D, 0x92, 0x94, 0xEF, 0x27, 0x75,
        0x09, 0xFC, 0xA4, 0x07, 0xEA, 0x2B, 0xC4, 0x76,
        0x59, 0x02, 0x6A, 0x82, 0x04, 0xD6, 0x96, 0x4F,
        0xC6, 0x5B, 0xEF, 0x35, 0x31, 0xE9, 0xC1, 0xE6,
        0xF9, 0x70, 0xBF, 0x2F, 0xF2, 0x40, 0x75, 0xEA,
        0x17, 0xD1, 0x36, 0xAD, 0xEA, 0xD2, 0x35, 0x6B,
        0x6C, 0xE4, 0x98, 0xF9, 0x3C, 0xD2, 0xF9, 0xE5,
        0xE1, 0x90, 0xD2, 0x09, 0xD9, 0x3E, 0x47, 0x3F,
        0xAA, 0x8E, 0xD9, 0x20, 0x96, 0x31, 0x5B, 0xF1,
        0xFC, 0xA6, 0x55, 0xFE, 0xBC, 0x78, 0xE0, 0x99,
        0x65, 0xC9, 0x74, 0x78, 0x29, 0x6B, 0x75, 0xD3,
        0x90, 0x56, 0x60, 0x4D, 0x32, 0x71, 0x91, 0x6D,
        0xCF, 0xF2, 0x25, 0xCB, 0x6B, 0x9A, 0x34, 0xE1,
        0x5D, 0xC1, 0x64, 0xB2, 0xA6, 0x8A, 0x3B, 0x42,
        0xDE, 0x05, 0x7A, 0x6B, 0xAC, 0x17, 0x32, 0xCF,
        0x59, 0x45, 0xBB, 0xCA, 0x12, 0xB8, 0xB3, 0x61,
        0x59, 0xFB, 0x89, 0xF7, 0xBB, 0xBE, 0x9F, 0xE0,
        0x34, 0x21, 0x8F, 0x5B, 0x3B, 0xCF, 0x18, 0x4C,
        0x20, 0x73, 0x06, 0xE6, 0xD2, 0xEA, 0x69, 0x59,
        0xEA, 0xE0, 0x89, 0x0A, 0x7B, 0x68, 0x02, 0xEC,
        0x1D, 0xA0, 0x82, 0xBE, 0xD6, 0x5B, 0xB6, 0xE4,
        0xEB, 0x4D, 0x56, 0x15, 0x70, 0x1C, 0xB0, 0xE3,
        0x50, 0x36, 0x33, 0x14, 0xA4, 0xD1, 0x01, 0xDB,
        0xBA, 0x60, 0x53, 0x71, 0xA3, 0x8B, 0x2D, 0x8A,
        0x37, 0xFF, 0x78, 0xEB, 0xB3, 0x69, 0x82, 0x53,
        0x88, 0xAA, 0xB7, 0xD3, 0xC6, 0x23, 0xB9, 0x3E,
        0x51, 0x2D, 0x96, 0xA9, 0xF3, 0x39, 0xEC, 0x96,
        0x8B, 0x35, 0x27, 0x59, 0xAF, 0x3E, 0x8F, 0xA3,
        0x21, 0x1C, 0x39, 0x29, 0x5B, 0x01, 0x10, 0xE6,
        0xDF, 0x26, 0x4E, 0x90, 0x67, 0x8C, 0x11, 0xE2,
        0xB9, 0x03, 0xAF, 0x32, 0x2E, 0x4F, 0xA7, 0x70,
        0x28, 0xD3, 0xEC, 0xC4, 0x4F, 0x62, 0x79, 0xD6,
        0x3B, 0x1E, 0x60, 0xD8, 0x06, 0x72, 0x41, 0x01,
        0x5F, 0xC4, 0xF8, 0x9B, 0xAA, 0x15, 0x6A, 0x78,
        0xFA, 0x77, 0xBB, 0x29, 0x14, 0xCA, 0xC2, 0x81,
        0xF4, 0x40, 0x9C, 0x9C, 0x03, 0x70, 0xAB, 0xD7,
        0xC1, 0xF8, 0xA5, 0xD1, 0x04, 0x0B, 0x59, 0x75,
        0x2C, 0xC4, 0xFD, 0xF0, 0xD1, 0x9C, 0xB0, 0xC5,
        0x6F, 0xEF, 0x34, 0xFA, 0x3A, 0x3B, 0xCE, 0xE1,
        0xF0, 0x64, 0xE3, 0x60, 0xE8, 0x6D, 0xC5, 0x5D,
        0xB5, 0xC9, 0x37, 0x5B, 0xDA, 0xDA, 0x67, 0x2E,
        0x72, 0xF6, 0x64, 0xE3, 0xAC, 0xB2, 0xE6, 0xD8,
        0xA0, 0x84, 0x09, 0xC8, 0xCD, 0x60, 0xA1, 0xF9,
        0x53, 0x80, 0xAB, 0x6C, 0x3A, 0xCB, 0x6B, 0x91,
        0xA8, 0xA9, 0xA3, 0xB7, 0x75, 0x50, 0x49, 0x79,
        0xB8, 0x02, 0x5A, 0xDB, 0x34, 0x22, 0x61, 0x9B,
        0xD1, 0x1E, 0x2B, 0x54, 0xFE, 0x6D, 0x07, 0x58,
        0x81, 0xAC, 0xAC, 0x24, 0x53, 0x20, 0x31, 0xCC,
        0xD2, 0x99, 0x06, 0x0E, 0x4E, 0xB7, 0xF7, 0xCB,
        0xD8, 0x08, 0x36, 0xD4, 0xB8, 0x23, 0xA5, 0xFF,
        0xA4, 0xFE, 0x8C, 0x6B, 0x98, 0x3D, 0x2A, 0xAE,
        0xB8, 0xF1, 0x6F, 0x6C, 0x1C, 0x22, 0x81, 0xEF,
        0xD7, 0x13, 0xFF, 0xDA, 0x22, 0x06, 0x9A, 0x5D,
        0x8A, 0xC4, 0x91, 0x29, 0x1C, 0xBF, 0x49, 0xF1,
        0x18, 0xC9, 0x46, 0xD5, 0x0F, 0x08, 0xE0, 0xD1,
        0x73, 0x28, 0x14, 0xE8, 0x15, 0x81, 0x90, 0x6A,
        0x31, 0x53, 0x94, 0x01, 0x14, 0xBE, 0xC8, 0xEB,
        0xD4, 0x9C, 0x73, 0x79, 0x0F, 0x9E, 0xD7, 0xCC,
        0xD9, 0x85, 0xED, 0xAD, 0x8D, 0xB3, 0x42, 0x6B,
        0x15, 0x13, 0x98, 0xEB, 0xF1, 0x6E, 0xFA, 0xFE,
        0x3D, 0xA0, 0xC7, 0xF3, 0x8B, 0x22, 0x76, 0x05,
        0x76, 0xD4, 0x88, 0x52, 0x73, 0xF5, 0xE4, 0x0B,
        0x14, 0x05, 0x57, 0x10, 0x7F, 0xCE, 0x0B, 0xF8,
        0x46, 0x1F, 0x24, 0x8B, 0xC4, 0x3F, 0xBF, 0x5C,
        0xEE, 0xE7, 0x6E, 0xF3, 0xA9, 0xEB, 0xD2, 0x30,
        0x95, 0x6C, 0x7B, 0x98, 0xAC, 0x89, 0x8A, 0x39,
        0x9E, 0x5C, 0x2A, 0xB0, 0xCB, 0xE9, 0xE5, 0xAB,
        0x94, 0x71, 0xDF, 0x5E, 0x53, 0x0C, 0x72, 0xF2,
        0x6C, 0x34, 0xDB, 0xFE, 0x2F, 0x83, 0x68, 0x3E,
        0xB6, 0x22, 0xF9, 0x64, 0x7A, 0xA0, 0x6A, 0x26,
        0x7D, 0x78, 0x97, 0x36, 0x31, 0x2C, 0x90, 0xC9,
        0xE5, 0x9D, 0x77, 0x12, 0x2A, 0x88, 0x53, 0x8F,
        0xD0, 0xF5, 0x39, 0x16, 0xAF, 0x08, 0xB2, 0x36,
        0x93, 0x5C, 0xDC, 0x5B, 0xB3, 0xCB, 0x49, 0x0C,
        0x83, 0x09, 0xE6, 0xA7, 0x9B, 0x43, 0xE7, 0xA5,
        0x4A, 0x8A, 0x07, 0xE1, 0xBA, 0xFB, 0x9B, 0x93,
        0x7E, 0xAC, 0x2F, 0xC3, 0xAC, 0xED, 0x30, 0x64,
        0x1F, 0x33, 0x79, 0x19, 0xD2, 0xDB, 0x54, 0xEC,
        0x7F, 0x32, 0x0E, 0xC5, 0x1C, 0xD1, 0x3C, 0x00,
        0xB9, 0xE6, 0x03, 0xDF, 0x6D, 0xD2, 0x69, 0x0C,
        0x75, 0xAF, 0x37, 0x07, 0xB7, 0xC9, 0x3E, 0x91,
        0xCF, 0x02, 0x78, 0xD7, 0x43, 0xA1, 0x8B, 0x4E,
        0x69, 0x74, 0xB4, 0x24, 0x08, 0x10, 0x42, 0xB5,
        0xB4, 0xE7, 0x8C, 0xEB, 0x7F, 0xFF, 0x67, 0x98,
        0x0B, 0xBC, 0xBA, 0x5E, 0x29, 0xBE, 0x61, 0x33,
        0x56, 0x16, 0xD6, 0x5E, 0x86, 0xF0, 0xE7, 0x46,
        0xD1, 0x83, 0xDF, 0xD4, 0x6B, 0x75, 0xC9, 0x30,
        0x0D, 0x60, 0xC5, 0x19, 0xFD, 0x95, 0xA8, 0xA6,
        0x61, 0xFF, 0xC8, 0x2A, 0xE7, 0x5D, 0xD1, 0x49,
        0x49, 0x1F, 0x99, 0xD1, 0x41, 0x4F, 0x15, 0x79,
        0x00, 0x8A, 0x80, 0x27, 0xA6, 0xC9, 0x98, 0xD3,
        0xE7, 0xA2, 0xBB, 0xFA, 0x07, 0xAB, 0x53, 0xEF,
        0xE8, 0x17, 0xAE, 0x9C, 0x6A, 0xE8, 0xD0, 0x52,
        0xAA, 0x85, 0x9D, 0x03, 0x48, 0xB0, 0xD2, 0xC8,
        0x5B, 0xCC, 0xC4, 0x50, 0x84, 0x90, 0xBE, 0x0F,
        0x9B, 0x32, 0x13, 0xB8, 0xAF, 0x7C, 0xCE, 0xE7,
        0x22, 0xE2, 0x82, 0x13, 0x18, 0x71, 0x46, 0xC5,
        0xDA, 0x05, 0xB7, 0x65, 0xD8, 0x33, 0x06, 0xFA,
        0x5A, 0x6B, 0x76, 0xD6, 0x92, 0x76, 0xD1, 0x6A,
        0x2B, 0xC6, 0x0D, 0xB1, 0xAD, 0xAB, 0x57, 0x62,
        0xEA, 0x76, 0x37, 0x4E, 0xAB, 0x2D, 0x34, 0xD2,
        0xA3, 0x57, 0xC7, 0x56, 0xFB, 0xEA, 0xD6, 0xA9,
        0xE3, 0xC1, 0x63, 0x07, 0xDE, 0xB9, 0x5E, 0x5A,
        0x30, 0x2E, 0x41, 0x4D, 0x43, 0xE9, 0x1C, 0xA1,
        0x5B, 0xB2, 0x4F, 0xAF, 0xDC, 0xE9, 0xBB, 0xBE,
        0x73, 0x55, 0x90, 0xF0, 0xD0, 0x02, 0x98, 0x6D,
        0x13, 0x50, 0x9A, 0xCA, 0x4C, 0xB3, 0x15, 0x3A,
        0x26, 0x14, 0x38, 0x67, 0xEB, 0xA7, 0x27, 0x33,
        0x48, 0x97, 0x58, 0x94, 0x57, 0xEA, 0xF9, 0x7E,
        0x8B, 0xB0, 0xBB, 0xF3, 0xF4, 0x84, 0x6E, 0x69,
        0x95, 0x2C, 0xF4, 0x6B, 0x1C, 0x65, 0x39, 0xB4,
        0x46, 0xA7, 0x99, 0xD6, 0x68, 0x47, 0x6E, 0x2E,
        0x49, 0x84, 0x75, 0x3E, 0x6C, 0x2E, 0x9A, 0x08,
        0xBC, 0xB7, 0x2F, 0x86, 0x68, 0x5C, 0xE1, 0xBF,
        0xEA, 0xA1, 0xAF, 0x59, 0xD6, 0x71, 0xB7, 0xBD,
        0xD6, 0xC5, 0xC2, 0xF2, 0xF3, 0xB5, 0x36, 0xBB,
        0x36, 0x23, 0x4F, 0xD6, 0x44, 0x59, 0x0A, 0x44,
        0x86, 0xCA, 0xDC, 0xD4, 0x22, 0x0F, 0x79, 0x09,
        0x99, 0x8C, 0x8C, 0x9E, 0x03, 0xA4, 0x51, 0x99,
        0x5A, 0xB9, 0x97, 0x76, 0x73, 0x20, 0xD3, 0x98,
        0x8C, 0x52, 0x96, 0xE1, 0x65, 0x7B, 0x4C, 0x77,
        0x40, 0xB2, 0xFE, 0x27, 0x0A, 0x11, 0x76, 0x6E,
        0x3B, 0x35, 0x12, 0xC6, 0x4E, 0xC2, 0x0E, 0xCC,
        0x04, 0xB5, 0x51, 0x91, 0xD0, 0x4A, 0xF7, 0x84,
        0xF2, 0xE7, 0xE5, 0x99, 0x7E, 0xB5, 0x3E, 0xAC,
        0x53, 0xDB, 0x61, 0x11, 0x71, 0x56, 0x4E, 0xAB,
        0x4A, 0x68, 0xC1, 0x6A, 0xA5, 0xC5, 0x7F, 0x72,
        0xEB, 0x14, 0x97, 0xA4, 0x27, 0xA0, 0x53, 0xA1,
        0xC4, 0x70, 0x7D, 0x58, 0xBD, 0xC1, 0xD7, 0xFD,
        0x9F, 0xB8, 0x8C, 0xCE, 0x34, 0xF9, 0xE1, 0x9C,
        0x59, 0x79, 0x31, 0x24, 0xEC, 0xBB, 0xF5, 0x6F,
        0x3F, 0xA3, 0x5A, 0x55, 0xB3, 0xDE, 0x64, 0xDF,
        0xA9, 0x95, 0x0B, 0x53, 0xF2, 0xA7, 0x25, 0x7B,
        0x8C, 0xAD, 0x25, 0x9A, 0x35, 0xBF, 0x15, 0x46,
        0x69, 0x4A, 0x83, 0x8C, 0x80, 0xFC, 0x37, 0xD0,
        0xC3, 0x6F, 0x00, 0xE2, 0x3C, 0x63, 0xAB, 0xC5,
        0x53, 0xC1, 0x8D, 0x4A, 0x40, 0x4B, 0xE6, 0xDC,
        0x05, 0xB1, 0x20, 0x23, 0x8B, 0xB8, 0xDF, 0x40,
        0x86, 0x97, 0xB9, 0x5E, 0xA4, 0xB7, 0xA1, 0x37,
        0xE0, 0x4B, 0x9E, 0xD9, 0x84, 0x2B, 0x2D, 0xAD,
        0xD1, 0xB1, 0x52, 0x15, 0x00, 0x9B, 0xDD, 0x23,
        0xA9, 0x27, 0x44, 0x21, 0x33, 0x17, 0x1C, 0x61,
        0x49, 0x84, 0x0D, 0x6A, 0x11, 0x7C, 0x77, 0xA5,
        0xD6, 0x8E, 0xE6, 0x1D, 0x6E, 0x90, 0x04, 0x4A,
        0xD3, 0x54, 0x3A, 0xA7, 0x1A, 0x28, 0xC5, 0x94,
        0x01, 0xCA, 0xDB, 0x1B, 0x5D, 0x78, 0xC5, 0xC6,
        0x69, 0x0D, 0x69, 0x88, 0x75, 0x00, 0x02, 0x0B,
        0x59, 0x6C, 0x3E, 0xC5, 0x30, 0xDF, 0xEE, 0x85,
        0x43, 0xA2, 0x9A, 0xF9, 0xDD, 0x85, 0x6E, 0xB3,
        0x0D, 0x83, 0x6A, 0x13, 0x88, 0xD0, 0x12, 0x15,
        0x53, 0x16, 0xFC, 0x5C, 0x15, 0x47, 0xEC, 0x6D,
        0x4D, 0x18, 0x2D, 0x88, 0xDB, 0xD2, 0x17, 0x6C,
        0xDE, 0x64, 0xEC, 0x70, 0x8D, 0x19, 0xDC, 0x66,
        0x69, 0x7F, 0xCF, 0x61, 0x6E, 0x4F, 0x23, 0x86,
        0xF5, 0x1A, 0x98, 0x47, 0x4B, 0xCC, 0xE9, 0x2F,
        0x12, 0x28, 0x12, 0xB9, 0xEB, 0xD8, 0x32, 0xDC,
        0xE4, 0xD8, 0x63, 0xAC, 0x56, 0x08, 0x2F, 0xEC,
        0x5E, 0x47, 0x29, 0xFF, 0x76, 0xFE, 0x95, 0x60,
        0xD2, 0x19, 0x61, 0x0E, 0xAF, 0xFC, 0x44, 0x42,
        0x11, 0x42, 0x79, 0xBC, 0x06, 0x3A, 0xAD, 0x93,
        0x7E, 0x46, 0x60, 0x03, 0xB0, 0xF5, 0x9F, 0x57,
        0x28, 0x48, 0x44, 0x8F, 0x0E, 0xFA, 0x72, 0x8C,
        0xE4, 0x18, 0xF4, 0x99, 0x6B, 0xB1, 0x23, 0x45,
        0xDC, 0x13, 0xA2, 0xF6, 0x5F, 0x57, 0x35, 0xA2,
        0xD7, 0x38, 0xF9, 0xE9, 0x8A, 0x7A, 0x79, 0xC6,
        0xB2, 0xCD, 0xBF, 0xD3, 0x41, 0x21, 0x56, 0xB3,
        0x39, 0xD9, 0x14, 0x3B, 0xDD, 0x85, 0xCB, 0x78,
        0x2F, 0xEB, 0x7E, 0x29, 0xBC, 0x52, 0x24, 0xE7,
        0x1B, 0x85, 0xB1, 0x65, 0xAE, 0xAB, 0x65, 0xF9,
        0x54, 0xD2, 0x1F, 0x37, 0x29, 0x52, 0x30, 0x5B,
        0x3D, 0x5F, 0x48, 0x84, 0x3F, 0x51, 0x27, 0x88,
        0x9D, 0xA7, 0x94, 0xF0, 0x73, 0xCD, 0x98, 0xD2,
        0x05, 0xE8, 0x25, 0x71, 0x7C, 0x93, 0x13, 0x82,
        0x5D, 0x53, 0x8D, 0x05, 0x0E, 0x69, 0x20, 0xC4,
        0xDB, 0xF2, 0xF6, 0x55, 0x24, 0x29, 0xD0, 0x41,
        0xF6, 0x2D, 0xF8, 0xC1, 0x2E, 0xC2, 0x4D, 0xE1,
        0xD7, 0x2D, 0xA0, 0x49, 0x16, 0x0B, 0x4D, 0x34,
        0xB5, 0x6D, 0xAE, 0x10, 0x93, 0x1E, 0xB6, 0x95,
        0x69, 0xC2, 0xB3, 0xC0, 0xAF, 0x6F, 0xFF, 0xA5,
        0x32, 0x3C, 0x7D, 0xC9, 0xC7, 0xC8, 0xEF, 0x0C,
        0x64, 0x20, 0x23, 0xC4, 0xFE, 0x89, 0x87, 0x8E,
        0xB3, 0xA6, 0xC5, 0x24, 0xCF, 0x03, 0x7E, 0x74,
        0xF7, 0xBF, 0x89, 0x1E, 0xCF, 0xB1, 0x02, 0xFA,
        0xF2, 0x9F, 0xD3, 0x9D, 0x99, 0x00, 0xDA, 0x7A,
        0x92, 0x7D, 0x13, 0x11, 0x92, 0xAD, 0x55, 0xF2,
        0xE1, 0x82, 0x72, 0xB1, 0x6A, 0xF1, 0x45, 0x05,
        0xDA, 0x17, 0xC9, 0xA1, 0x42, 0x82, 0x89, 0x77,
        0x31, 0xB6, 0x72, 0x54, 0x7C, 0x68, 0x10, 0x25,
        0x57, 0x30, 0x16, 0x15, 0x08, 0x58, 0x8B, 0xC1,
        0x61, 0xCB, 0xA0, 0x58, 0x29, 0x33, 0xB1, 0x64,
        0xF4, 0x4F, 0x06, 0xAA, 0x25, 0x31, 0xAA, 0xA8,
        0x92, 0x1C, 0x69, 0x1E, 0x6E, 0xB6, 0xBE, 0x81,
        0xDA, 0x9B, 0xE5, 0x1C, 0x56, 0x39, 0x55, 0xE0,
        0xC1, 0xEF, 0xD3, 0xED, 0x2A, 0x1C, 0x94, 0x9B,
        0xD4, 0xE0, 0x0B, 0x3A, 0xE9, 0xEB, 0xC1, 0x3C,
        0x4C, 0x6C, 0x4E, 0x5E, 0x39, 0x4C, 0xB0, 0x34,
        0xB9, 0xCB, 0x75, 0xBE, 0xCE, 0x86, 0x44, 0xFF,
        0x89, 0xEF, 0x95, 0xE7, 0x6E, 0xF7, 0x15, 0xE1,
        0x7A, 0xA2, 0x6B, 0x1F, 0xEB, 0x77, 0x4C, 0x50,
        0x59, 0xB3, 0xA3, 0x9A, 0x38, 0xDF, 0xD0, 0x57,
        0xD6, 0x41, 0xE4, 0x3F, 0xFE, 0x0F, 0x3E, 0x40,
        0xFF, 0xF6, 0xB2, 0x36, 0x3C, 0x1B, 0xF0, 0xEF,
        0x07, 0x87, 0x3D, 0x09, 0xA4, 0x87, 0x76, 0x9D,
        0x0A, 0x73, 0xCD, 0x0C, 0xC6, 0x44, 0xF5, 0x3C,
        0x25, 0xD2, 0x02, 0x5E, 0xE7, 0x1C, 0x69, 0xB7,
        0xAC, 0x0F, 0xA6, 0x61, 0x15, 0x57, 0xC4, 0x27,
        0xC0, 0x69, 0xDF, 0x2E, 0x1B, 0xF6, 0x29, 0xD9,
        0xA0, 0xCB, 0x5C, 0x67, 0xC7, 0xEA, 0x4F, 0xA6,
        0x58, 0xC7, 0x8D, 0x00, 0x42, 0xB0, 0x59, 0xE6,
        0xB6, 0x58, 0xFF, 0xCE, 0x60, 0x16, 0x69, 0x67,
        0xDB, 0x94, 0xF7, 0x16, 0xEB, 0x4D, 0x04, 0xB3,
        0xD2, 0x45, 0x0F, 0x40, 0x03, 0x1F, 0x10, 0xAC,
        0xDD, 0x07, 0x77, 0x7F, 0xBE, 0x9F, 0xBB, 0xB7,
        0x7F, 0xCB, 0x7C, 0x1F, 0xA9, 0xFC, 0x1E, 0xAF,
        0x0C, 0x5F, 0x86, 0xD7, 0x96, 0x2D, 0xAE, 0xD0,
        0x47, 0x4B, 0xA0, 0xFE, 0x68, 0xD9, 0xB2, 0x32,
        0x77, 0xA9, 0xCA, 0x7F, 0xC6, 0x76, 0xC6, 0x61,
        0x6B, 0x8E, 0x43, 0x9A, 0x1D, 0x4B, 0xFF, 0x72,
        0x43, 0x78, 0x19, 0xB5, 0x51, 0x87, 0x56, 0xA7,
        0x87, 0x3E, 0xF5, 0x84, 0x01, 0x26, 0x46, 0xC3,
        0x65, 0x9A, 0x6B, 0xA8, 0x6E, 0x62, 0x27, 0x26,
        0x14, 0xD8, 0x5E, 0xEC, 0xD5, 0x35, 0x0E, 0x3C,
        0xD0, 0xA1, 0x25, 0xAE, 0x9C, 0x17, 0xCC, 0xE2,
        0x52, 0x39, 0xE1, 0xEE, 0x9C, 0xDB, 0x39, 0xCA,
        0x7B, 0x18, 0xCF, 0x2C, 0x88, 0xCF, 0x14, 0x68,
        0x26, 0xB6, 0xCC, 0x1E, 0x6A, 0xA8, 0xE1, 0x69,
        0x2C, 0x91, 0x5F, 0x3B, 0xF1, 0xC1, 0xDB, 0x34,
        0xC6, 0xF3, 0x78, 0x83, 0xCB, 0x4E, 0xDC, 0xE0,
        0xF7, 0xC9, 0x95, 0xB6, 0x9E, 0x3A, 0xCE, 0x30,
        0xDC, 0x16, 0x6F, 0x78, 0x4C, 0x93, 0xD6, 0xCB,
        0xBC, 0xAC, 0x3C, 0x79, 0xBC, 0x31, 0x93, 0x10,
        0xCE, 0x6E, 0x66, 0x57, 0x00, 0xF1, 0x7F, 0x96,
        0x2F, 0x18, 0xB2, 0x40, 0x73, 0x9D, 0x15, 0x69,
        0x0B, 0x1B, 0x6C, 0x85, 0xD1, 0xAA, 0xA3, 0x2D,
        0x4A, 0x79, 0x74, 0x4A, 0xE5, 0x0C, 0xF9, 0xA9,
        0x0A, 0x09, 0x54, 0xB4, 0xA4, 0xD9, 0x4C, 0x49,
        0x9B, 0x41, 0x23, 0xEF, 0xC0, 0x20, 0x44, 0x31,
        0xF7, 0x22, 0x85, 0xB5, 0xDA, 0x9E, 0x19, 0x22,
        0x23, 0x0A, 0x30, 0x4D, 0x3A, 0x1B, 0xD8, 0x52,
        0x08, 0x72, 0x61, 0xB7, 0xCF, 0x0D, 0x8B, 0x90,
        0xD1, 0x46, 0x23, 0xEB, 0xCD, 0xC6, 0x38, 0x7B,
        0xC6, 0xAF, 0x65, 0xBE, 0x5F, 0x01, 0x1B, 0x6B,
        0xC1, 0x23, 0xC1, 0x30, 0x6A, 0x1E, 0x8F, 0xBF,
        0x2D, 0xF0, 0xB6, 0xF8, 0x9B, 0x0A, 0xE0, 0x5D,
        0xE0, 0xE4, 0xB7, 0xF5, 0x0A, 0xDA, 0x46, 0xE5,
        0x3A, 0x9B, 0x6B, 0xCA, 0xDA, 0x06, 0x43, 0xBE,
        0x6B, 0xFD, 0xC2, 0xB0, 0x6A, 0x6C, 0x75, 0x88,
        0x3C, 0x2D, 0xC6, 0x13, 0xAC, 0x72, 0x16, 0x31,
        0x7A, 0x40, 0xC4, 0xA2, 0xC0, 0x86, 0x69, 0x83,
        0xD3, 0x2C, 0x9C, 0xE0, 0xA6, 0xCC, 0xED, 0xF4,
        0x03, 0x62, 0x6B, 0xB2, 0x3B, 0x5B, 0x9D, 0xA5,
        0x86, 0x77, 0x7C, 0x73, 0x5E, 0x19, 0x11, 0xD7,
        0x7B, 0x11, 0x96, 0xC8, 0xFA, 0x47, 0x21, 0xD6,
        0xB0, 0xFE, 0x0B, 0x08, 0x11, 0xFC, 0x00, 0xB9,
        0xA1, 0x24, 0x2C, 0xBD, 0x4A, 0x92, 0x43, 0x10,
        0x08, 0xBE, 0xE9, 0xE1, 0x5D, 0x19, 0x82, 0xDE,
        0x34, 0xAE, 0xDC, 0xA6, 0x85, 0x8F, 0x19, 0x30,
        0x20, 0xB6, 0x44, 0x7F, 0x6B, 0xA6, 0x63, 0x70,
        0x59, 0xDA, 0x8D, 0xE0, 0xF8, 0x46, 0x86, 0x57,
        0xB8, 0x1C, 0x57, 0x13, 0x78, 0x41, 0x8C, 0xF5,
        0x7D, 0x77, 0xAE, 0x75, 0x6C, 0x59, 0x93, 0x2E,
        0x05, 0x25, 0x03, 0xD1, 0xEA, 0xFB, 0x2D, 0x60,
        0xD2, 0x61, 0x23, 0xEA, 0x0E, 0xFF, 0x55, 0xE3,
        0x24, 0x49, 0x00, 0x19, 0xBD, 0x1E, 0x56, 0x24,
        0x87, 0x2F, 0x7B, 0x98, 0x07, 0x36, 0xD2, 0x7C,
        0xC5, 0x9B, 0xE0, 0x4E, 0x29, 0xAB, 0xA1, 0xB8,
        0x35, 0x15, 0x31, 0xCE, 0x65, 0x14, 0x24, 0xF8,
        0x10, 0xB5, 0xAB, 0x3E, 0xD5, 0x58, 0xCA, 0xE5,
        0x73, 0x2D, 0x7C, 0x8B, 0xB4, 0x62, 0x75, 0x03,
        0x30, 0x89, 0xFE, 0x32, 0xF8, 0x65, 0x99, 0xD0,
        0x88, 0xD5, 0x72, 0x88, 0x03, 0xC9, 0x51, 0x03,
        0xBA, 0x2F, 0xFB, 0x7C, 0x39, 0x02, 0x05, 0xC4,
        0xCE, 0xD8, 0xB3, 0xC2, 0x7B, 0x29, 0x8E, 0xA7,
        0x9D, 0x35, 0x97, 0xB7, 0x17, 0xDE, 0x28, 0x0B,
        0x32, 0xE5, 0x41, 0xDA, 0x1D, 0x98, 0xBD, 0x27,
        0xEF, 0xF7, 0xB4, 0x43, 0x09, 0x13, 0x39, 0xC7,
        0x40, 0x16, 0x11, 0x20, 0x71, 0xCB, 0xB6, 0xC9,
        0xB0, 0x8F, 0x20, 0xC1, 0xF0, 0x40, 0xFB, 0x6E,
        0x73, 0x04, 0x8F, 0x73, 0xCA, 0x45, 0xDB, 0xE0,
        0xF9, 0x25, 0x8D, 0x32, 0xF2, 0x3E, 0x36, 0xBE,
        0xF7, 0x88, 0xF8, 0x13, 0x4D, 0x9B, 0x10, 0xC2,
        0x58, 0x0B, 0x20, 0xF8, 0x78, 0xB6, 0x4C, 0x7D,
        0x2A, 0xA6, 0x81, 0x40, 0xD1, 0x30, 0x50, 0x38,
        0x2A, 0x5F, 0xBC, 0x81, 0x8E, 0x0F, 0xD4, 0xD0,
        0x87, 0x99, 0x78, 0x3D, 0xBE, 0x25, 0x15, 0xF4,
        0x45, 0x61, 0xA3, 0x1A, 0x7D, 0x05, 0x3F, 0xB5,
        0xA6, 0x1C, 0x41, 0xC6, 0x0E, 0xBE, 0x57, 0x6F,
        0xC5, 0xB6, 0x38, 0x63, 0x90, 0x55, 0x23, 0xFC,
        0x26, 0x9E, 0xFD, 0xB8, 0x6C, 0xF2, 0x99, 0x6B,
        0x6D, 0x90, 0xFE, 0x28, 0xA0, 0x16, 0xEE, 0x63,
        0xC2, 0x4C, 0xD6, 0xB2, 0x0C, 0xFA, 0x6E, 0x85,
        0x51, 0xE4, 0x2F, 0x57, 0x91, 0x82, 0x84, 0x43,
        0x8A, 0x44, 0x31, 0x6C, 0x68, 0x02, 0x01, 0x7C,
        0xCE, 0x4D, 0xC0, 0x7C, 0x43, 0xA9, 0x54, 0xF5,
        0x0E, 0xCA, 0xE6, 0x15, 0x98, 0xAE, 0x41, 0x57,
        0x0A, 0x66, 0xBA, 0x6D, 0x6E, 0x68, 0xB9, 0x2E,
        0x0D, 0x42, 0xD2, 0xF5, 0x0B, 0xFC, 0x2D, 0xA8,
        0x61, 0x6E, 0x60, 0x4E, 0x51, 0x78, 0xEB, 0x0C,
        0x52, 0x9E, 0xC0, 0x4A, 0xB0, 0x92, 0x85, 0x5C,
        0x3A, 0x3D, 0x69, 0x95, 0xAB, 0x62, 0xEB, 0x2F,
        0x9B, 0x12, 0xF5, 0x2E, 0xB5, 0xA6, 0x93, 0xCE,
        0x14, 0x97, 0xA7, 0x1E, 0x0A, 0x7B, 0x94, 0x74,
        0xFB, 0x65, 0xD0, 0x5A, 0x97, 0x55, 0x40, 0x02,
        0x71, 0x87, 0x9C, 0x9F, 0xCB, 0x41, 0x3F, 0x08,
        0x8D, 0x6A, 0xCA, 0xE6, 0xEC, 0xE6, 0x71, 0x22,
        0xF8, 0x58, 0x9F, 0xF1, 0x94, 0xF6, 0xE4, 0xD6,
        0xDC, 0x35, 0xD7, 0xEB, 0x6B, 0x78, 0x99, 0x66,
        0xF9, 0xE2, 0x15, 0x27, 0xC9, 0x8C, 0x27, 0xB4,
        0x89, 0x3C, 0x15, 0xEE, 0x52, 0x71, 0xA9, 0xD2,
        0x50, 0x3C, 0xD2, 0x31, 0xBB, 0x3A, 0xE5, 0x87,
        0xAF, 0x65, 0x2B, 0xF2, 0xF5, 0xC9, 0x44, 0xA2,
        0x59, 0x1C, 0x57, 0x96, 0xB9, 0xC2, 0x5E, 0xCB,
        0x8A, 0x5B, 0x2B, 0x7A, 0x7E, 0x93, 0x3C, 0x08,
        0x27, 0xCD, 0xB4, 0xB0, 0x1B, 0xF3, 0x82, 0x50,
        0x78, 0xCF, 0xEA, 0x28, 0x57, 0xB1, 0x0F, 0xB4,
        0xB6, 0x93, 0x82, 0x8E, 0x7A, 0xD1, 0x9F, 0x04,
        0xEC, 0xEE, 0x24, 0x3D, 0x8A, 0x5E, 0x56, 0x99,
        0x8D, 0x83, 0xA4, 0x05, 0x7D, 0xFB, 0x36, 0xDB,
        0xAB, 0xD1, 0x67, 0x59, 0xC7, 0x4A, 0xB9, 0xAF,
        0x99, 0xB6, 0xD8, 0xD4, 0x2C, 0xCA, 0x8C, 0xCC,
        0xD2, 0x32, 0xAB, 0x51, 0xCE, 0x2D, 0x22, 0xE0,
        0x29, 0xB1, 0x73, 0x10, 0x60, 0xA8, 0x6B, 0x8F,
        0x68, 0xAF, 0x58, 0x06, 0x9D, 0x72, 0x36, 0x98,
        0x3F, 0xF3, 0x6B, 0xAD, 0x3E, 0x7F, 0x4A, 0x00,
        0x94, 0x04, 0xAE, 0xE9, 0x8A, 0x9E, 0x8A, 0x03,
        0xD8, 0x04, 0xCC, 0xFE, 0xE3, 0xF8, 0xA2, 0x04,
        0x64, 0x17, 0x54, 0x77, 0xCA, 0x20, 0xD0, 0x80,
        0x1B, 0x36, 0xEF, 0x59, 0x31, 0xFA, 0xE4, 0xF5,
        0xAF, 0x56, 0x09, 0x02, 0xAD, 0xCF, 0xA6, 0xBC,
        0x26, 0x23, 0x27, 0x6D, 0xF3, 0x52, 0xCE, 0x2F,
        0x4C, 0x9C, 0xA8, 0x23, 0x75, 0xFA, 0x56, 0x9E,
        0x07, 0x5B, 0xB9, 0x30, 0x5A, 0xB1, 0x27, 0xFF,
        0x72, 0xBF, 0x50, 0xB1, 0x27, 0xEF, 0xA1, 0x0C,
        0x3A, 0xC9, 0x72, 0x21, 0xBE, 0xD8, 0xDC, 0xD5,
        0x66, 0x4A, 0x0A, 0x58, 0xFA, 0x57, 0xB4, 0x00,
        0x07, 0x31, 0xF2, 0x4E, 0xDC, 0xE0, 0x86, 0x99,
        0x45, 0xE5, 0x45, 0xCF, 0x27, 0x35, 0x79, 0x57,
        0xF5, 0xA2, 0x7A, 0x29, 0xFA, 0x5E, 0xCF, 0xF9,
        0xA9, 0x96, 0x11, 0xE1, 0x4A, 0x6C, 0xE5, 0xB8,
        0x8E, 0x78, 0xE6, 0xA1, 0x46, 0x97, 0xAE, 0xB4,
        0xF3, 0x6D, 0x7F, 0x8E, 0xD1, 0x86, 0x6B, 0x78,
        0x2B, 0x55, 0xC5, 0xDF, 0x0F, 0x43, 0x78, 0xED,
        0xD2, 0x38, 0xE5, 0x8B, 0x94, 0x7A, 0x06, 0xC5,
        0x73, 0x17, 0x55, 0x93, 0xAD, 0xA5, 0xAC, 0xBA,
        0x81, 0x8A, 0x6D, 0x73, 0x4B, 0xA1, 0x32, 0x8F,
        0x21, 0xA6, 0x5B, 0x51, 0x31, 0x58, 0xD0, 0xE4,
        0x0B, 0x93, 0x46, 0xF2, 0x51, 0x30, 0x3E, 0x60,
        0xE1, 0xCB, 0x30, 0x04, 0x15, 0x8D, 0x1E, 0x87,
        0xA6, 0xF6, 0x38, 0xE0, 0x27, 0x84, 0x81, 0x18,
        0x2B, 0x37, 0xBB, 0xD3, 0xDB, 0xE7, 0x91, 0xA3,
        0x1B, 0x6B, 0x20, 0xCB, 0x2C, 0x52, 0xB1, 0xB9,
        0x6A, 0x94, 0xF8, 0xCD, 0xBA, 0x5D, 0xC7, 0xDD,
        0x79, 0x36, 0x38, 0xC2, 0xFC, 0xEC, 0x4F, 0x2B,
        0x5F, 0x73, 0x44, 0x03, 0xE9, 0xA9, 0xF5, 0xD9,
        0x99, 0xEA, 0x61, 0xDC, 0x6A, 0x98, 0xBE, 0xDE,
        0xB9, 0x34, 0xCC, 0x76, 0xB0, 0xE1, 0x8C, 0x70,
        0x3A, 0xA5, 0x7C, 0xD1, 0xC0, 0x2A, 0x8E, 0x7D,
        0x47, 0x8A, 0x63, 0xEA, 0x30, 0x6B, 0xEE, 0x36,
        0x0B, 0xA8, 0xAE, 0x46, 0xCD, 0x01, 0x83, 0xF6,
        0x07, 0xF9, 0xED, 0x8B, 0x69, 0x97, 0xB6, 0xC3,
        0x5D, 0x75, 0x6E, 0xD8, 0xDF, 0x01, 0x82, 0x48,
        0x31, 0x2F, 0xDE, 0xED, 0x8E, 0xC5, 0xD8, 0xA6,
        0xC0, 0x36, 0x0E, 0x66, 0xA4, 0xE9, 0xE5, 0xA9,
        0x7D, 0x5C, 0xD2, 0x43, 0x72, 0xC0, 0xAD, 0x26,
        0x78, 0xF2, 0xB0, 0x08, 0x12, 0xAE, 0x6C, 0x1A,
        0x0F, 0x53, 0x30, 0xB3, 0xAB, 0x01, 0x53, 0xDA,
        0x3C, 0x5F, 0x4C, 0x17, 0xBD, 0x2F, 0xB6, 0x0E,
        0x7E, 0x80, 0x87, 0x4C, 0x1B, 0x92, 0x9B, 0x62,
        0xE3, 0x89, 0xEE, 0xE2, 0xA0, 0x14, 0x06, 0x0D,
        0x4D, 0xCC, 0x96, 0x5A, 0xF8, 0x64, 0x2A, 0x05,
        0xA9, 0xEE, 0xD5, 0x0D, 0x23, 0x90, 0xB0, 0x67,
        0xD5, 0x51, 0x1D, 0x18, 0xBC, 0xBA, 0xE6, 0xA5,
        0xAD, 0x29, 0x18, 0xD5, 0x06, 0xFC, 0xC9, 0x12,
        0x6D, 0x70, 0xA8, 0x6E, 0x96, 0x8B, 0x5F, 0x9C,
        0x99, 0x43, 0x07, 0x02, 0x37, 0x48, 0x8C, 0xFB,
        0x5F, 0xF5, 0xDE, 0x69, 0x26, 0x73, 0x7D, 0xF6,
        0x3A, 0x2C, 0xE5, 0x58, 0x01, 0xC3, 0x48, 0xB0,
        0xF0, 0x0D, 0x56, 0xAF, 0x8C, 0x0F, 0x5C, 0xB3,
        0xBA, 0x44, 0x8C, 0x39, 0xB0, 0x20, 0xD2, 0x93,
        0x81, 0x19, 0x99, 0x4E, 0xAC, 0xB9, 0x1F, 0xC3,
        0x1F, 0x34, 0x7D, 0xF3, 0x3E, 0x1A, 0xE1, 0x26,
        0x7C, 0xB7, 0x22, 0x0A, 0xDC, 0x0D, 0x14, 0xF8,
        0x43, 0x8A, 0x23, 0x46, 0x37, 0x9C, 0x2A, 0xB8,
        0x1F, 0x24, 0x72, 0xE2, 0xEA, 0xC4, 0x67, 0x13,
        0x17, 0x33, 0xBD, 0xA0, 0x07, 0xA0, 0x3E, 0xDE,
        0x8B, 0xC4, 0xD6, 0xDB, 0xD9, 0xF1, 0xB8, 0xF4,
        0xFB, 0x83, 0x13, 0x14, 0xCD, 0x36, 0xF6, 0xDC,
        0xD5, 0x85, 0x93, 0x7C, 0xF9, 0x6C, 0xEA, 0x52,
        0x92, 0xFB, 0xFC, 0x95, 0x02, 0x10, 0x7B, 0x57,
        0x9F, 0xF0, 0x7C, 0x2E, 0x79, 0x00, 0x3D, 0xB2,
        0xA1, 0x6C, 0x4E, 0xD4, 0x17, 0xFA, 0x0F, 0x13,
        0xC8, 0xBF, 0xB1, 0x82, 0xF7, 0xDD, 0xCF, 0x08,
        0xF2, 0x50, 0xDB, 0x16, 0xA4, 0x5A, 0x60, 0x4A,
        0x57, 0x2B, 0x0E, 0xDC, 0x4A, 0xBF, 0x9C, 0x86,
        0x08, 0x8A, 0x5A, 0xC8, 0x74, 0xDD, 0xA2, 0x6E,
        0x12, 0xA0, 0xEF, 0x63, 0x5A, 0xD2, 0x82, 0xAD,
        0xCD, 0xC7, 0xED, 0x16, 0x86, 0x45, 0x3D, 0xFB,
        0x35, 0xC3, 0xB1, 0xBA, 0x68, 0x21, 0xB4, 0xB7,
        0x22, 0x0B, 0x55, 0x79, 0x8B, 0x9C, 0xCF, 0xE0,
        0x66, 0x61, 0x5C, 0xE2, 0x55, 0x96, 0x0D, 0x09,
        0xE6, 0x77, 0xFE, 0xFE, 0x76, 0xBE, 0x91, 0x5E,
        0x04, 0xE5, 0x65, 0x44, 0xBD, 0x09, 0xD0, 0x6F,
        0x83, 0x44, 0xF9, 0x68, 0xDC, 0x68, 0x25, 0xCB,
        0xC6, 0x64, 0xD5, 0x18, 0xA4, 0x41, 0xE1, 0x9B,
        0x07, 0x6F, 0xC3, 0x38, 0x91, 0x37, 0xFC, 0x1B,
        0x73, 0x32, 0xE2, 0xB0, 0x68, 0x95, 0x44, 0x3B,
        0x7A, 0x00, 0x23, 0x36, 0x31, 0x15, 0x79, 0xA9,
        0xB0, 0x8F, 0x36, 0x73, 0xDA, 0x05, 0x90, 0xE6,
        0x96, 0xCE, 0xD9, 0x01, 0x44, 0x4A, 0x70, 0xA6,
        0x7B, 0x2A, 0x7D, 0x55, 0x12, 0xD6, 0x5B, 0xFC,
        0xD7, 0xAF, 0x1E, 0x34, 0x27, 0x77, 0x69, 0xE1,
        0x71, 0x08, 0x83, 0x01, 0xDE, 0x78, 0x46, 0xF0,
        0x88, 0xF4, 0x87, 0xC4, 0x92, 0x1B, 0xEB, 0x98,
        0x35, 0x4B, 0xAE, 0x9A, 0xF6, 0xEA, 0xB2, 0x34,
        0x91, 0x14, 0xEB, 0x21, 0xF6, 0x18, 0xDB, 0x1D,
        0x92, 0x6C, 0x1D, 0x2F, 0xE3, 0xA5, 0xF2, 0x29,
        0xC5, 0x73, 0x40, 0xC4, 0x0A, 0xEC, 0x11, 0xC2,
        0xD0, 0x14, 0x4D, 0x03, 0x94, 0xFC, 0x4D, 0x8E,
        0x38, 0x66, 0xA7, 0xD0, 0xA1, 0x0B, 0x64, 0xC8,
        0xB9, 0x92, 0xB0, 0xA4, 0xDD, 0xBC, 0xAD, 0x82,
        0x4E, 0x43, 0x97, 0x43, 0x78, 0xEA, 0x9A, 0x38,
        0xE5, 0x8C, 0x2C, 0x5A, 0xE1, 0x94, 0xAF, 0x43,
        0x10, 0xFB, 0xEC, 0x90, 0x28, 0x41, 0x6C, 0x5C,
        0xB7, 0xB8, 0xAF, 0xA5, 0x24, 0xF7, 0x4F, 0xFD,
        0x6F, 0x2E, 0x98, 0x44, 0x3F, 0x5E, 0x89, 0x24,
        0xF6, 0xCF, 0x11, 0x0E, 0x67, 0x1B, 0x81, 0x68,
        0x37, 0xD5, 0x9B, 0x2D, 0xB9, 0x1C, 0xB1, 0xE6,
        0x87, 0xD6, 0xA2, 0x02, 0x0F, 0x91, 0x08, 0xF6,
        0x9B, 0x94, 0x76, 0x62, 0xFD, 0xE7, 0x18, 0xAC,
        0x28, 0xA6, 0xAC, 0xDA, 0x27, 0xF4, 0x33, 0x59,
        0xBB, 0xBE, 0x36, 0x2C, 0xEE, 0xEA, 0x91, 0xE6,
        0x91, 0x95, 0x2C, 0x58, 0x0A, 0xB2, 0xCA, 0xA3,
        0xAA, 0x39, 0x03, 0x9A, 0x75, 0x3C, 0x27, 0x6E,
        0x02, 0x89, 0x17, 0x4B, 0x02, 0x42, 0x7C, 0xB4,
        0x2E, 0xAD, 0xB4, 0xD9, 0x35, 0xB2, 0x30, 0x9E,
        0x2F, 0xEC, 0x9F, 0x25, 0x56, 0x1A, 0x35, 0x40,
        0xF1, 0xAF, 0x1D, 0xA4, 0xA8, 0x62, 0x07, 0x70,
        0x98, 0x6C, 0xDE, 0x1E, 0x89, 0xC1, 0xD3, 0x30,
        0xBB, 0x82, 0x72, 0x40, 0xF2, 0xBC, 0x53, 0xC7,
        0xDE, 0xAB, 0xFC, 0x7D, 0xAD, 0xBF, 0xDA, 0xE0,
        0xA7, 0xA1, 0x0C, 0xD6, 0x73, 0x37, 0x36, 0xA1,
        0xEE, 0xA6, 0x96, 0x88, 0x79, 0x0E, 0x4A, 0x2C,
        0x69, 0x4C, 0xE5, 0x30, 0xFB, 0xDD, 0xE1, 0xFE,
        0x86, 0x90, 0xDC, 0xDF, 0x03, 0xF5, 0x17, 0x2F,
        0xF4, 0x58, 0x2D, 0xD3, 0xED, 0x3D, 0x7D, 0xA0,
        0xB3, 0x6E, 0x1E, 0xD3, 0xBB, 0xD9, 0x57, 0xBA,
        0x8B, 0x00, 0x72, 0xC4, 0xEE, 0xCF, 0x39, 0xD5,
        0x74, 0xFA, 0x13, 0xF0, 0xD7, 0xE9, 0x10, 0x0C,
        0x7A, 0x52, 0x62, 0xD0, 0xC9, 0xD5, 0x2D, 0xDC,
        0x11, 0xD4, 0xFF, 0x34, 0xB2, 0x55, 0xF9, 0x99,
        0x81, 0xB4, 0xC9, 0x14, 0x02, 0x91, 0x81, 0x56,
        0x29, 0xF6, 0xA9, 0x1A, 0x19, 0x8E, 0x74, 0xB3,
        0xA3, 0xD1, 0x28, 0xB5, 0x72, 0xD8, 0x6F, 0x54,
        0x15, 0x74, 0x55, 0x70, 0x26, 0x62, 0xCB, 0x1D,
        0x15, 0x2C, 0x7F, 0x4C, 0x9C, 0xB4, 0xDE, 0xA2,
        0x07, 0xD5, 0xA9, 0x38, 0x29, 0x42, 0x51, 0x67,
        0x44, 0x26, 0x97, 0x7E, 0x73, 0x0E, 0xC6, 0x01,
        0x00, 0x65, 0xC8, 0xE0, 0x34, 0x88, 0x2B, 0xD3,
        0x2F, 0xD3, 0x5C, 0x6A, 0xF6, 0xB8, 0xD9, 0x3A,
        0x50, 0x9C, 0xC3, 0x39, 0xD9, 0x6F, 0xB9, 0xDD,
        0x55, 0x8A, 0xF9, 0x52, 0x35, 0xFB, 0xF1, 0x71,
        0x97, 0x76, 0x04, 0x75, 0xEE, 0x2E, 0x3F, 0xCA,
        0x0E, 0x83, 0xA8, 0xE3, 0x1F, 0xA7, 0xF1, 0x3D,
        0x78, 0xCC, 0x79, 0x64, 0x80, 0x5E, 0x77, 0x05,
        0xDB, 0xB7, 0x0F, 0x73, 0x53, 0x3A, 0x56, 0xD8,
        0xB7, 0x7C, 0x12, 0xE8, 0xF6, 0x51, 0x07, 0xC9,
        0x01, 0x43, 0x97, 0x51, 0x75, 0x95, 0x94, 0x65,
        0xFD, 0x4D, 0x8C, 0x8C, 0xD3, 0xA8, 0xEE, 0xA9,
        0x5E, 0xFB, 0xC7, 0xF6, 0xF8, 0x40, 0x0E, 0xA5,
        0xD5, 0x1E, 0x79, 0xB4, 0x0C, 0xEF, 0x8B, 0x04,
        0x59, 0x4D, 0x0C, 0x6F, 0x08, 0xD5, 0x00, 0xA2,
        0xAD, 0x08, 0xB4, 0x62, 0xE0, 0x2C, 0xF6, 0x30,
        0x31, 0x1E, 0xD7, 0x81, 0x56, 0x61, 0x17, 0x0D,
        0xB3, 0x9F, 0x27, 0x75, 0x38, 0x42, 0x6E, 0xB2,
        0xB0, 0x6C, 0xB8, 0xC9, 0xD8, 0x20, 0xC8, 0x36,
        0x7D, 0x1D, 0x57, 0x10, 0x4E, 0xC1, 0x45, 0xFC,
        0x93, 0xB1, 0xF7, 0x7B, 0xA1, 0x3B, 0x71, 0x12,
        0x16, 0xE5, 0x8F, 0xD0, 0x0C, 0x7D, 0xC0, 0x05,
        0x18, 0x02, 0x24, 0x25, 0x28, 0x8A, 0xE1, 0x29,
        0x9A, 0x79, 0xBD, 0xC7, 0x73, 0x2D, 0xF3, 0x42,
        0x70, 0x33, 0xF3, 0xF8, 0x48, 0x87, 0xB4, 0xD4,
        0x91, 0xE1, 0x53, 0xBA, 0x4A, 0x63, 0xAF, 0x3A,
        0xE5, 0xCB, 0x3D, 0x41, 0x04, 0xB5, 0x30, 0x87,
        0xAA, 0x40, 0x03, 0x56, 0x10, 0x02, 0xF3, 0x6A,
        0x9F, 0xDA, 0x33, 0xBC, 0xB8, 0xA5, 0xD0, 0x56,
        0x43, 0x29, 0xDA, 0x58, 0x12, 0x8B, 0x6A, 0x9D,
        0xCF, 0xCD, 0xCA, 0x66, 0x98, 0x92, 0x1D, 0xA4,
        0xEF, 0xAC, 0x9E, 0x19, 0xDE, 0xF7, 0xFE, 0x6C,
        0x3A, 0x66, 0x46, 0xB4, 0x00, 0x7F, 0x08, 0xAF,
        0x31, 0xD6, 0xD3, 0x22, 0x59, 0x1F, 0x34, 0x48,
        0x5A, 0xE1, 0x4E, 0x0F, 0x6F, 0x2D, 0xD0, 0xE5,
        0x8E, 0x34, 0x3B, 0xC0, 0x55, 0x02, 0x2D, 0x17,
        0x4B, 0x34, 0x78, 0x46, 0xD4, 0xC4, 0x7F, 0x1D,
        0xDC, 0x39, 0x94, 0x69, 0x78, 0xAB, 0xD8, 0x2B,
        0x6D, 0xF3, 0x1C, 0x0B, 0x0F, 0x4A, 0xA0, 0xB2,
        0xAC, 0x1A, 0x79, 0x7F, 0x9D, 0xE5, 0xE8, 0xC6,
        0x40, 0x4B, 0xCE, 0x32, 0x4B, 0xA1, 0x3C, 0x77,
        0xED, 0x5D, 0x59, 0x0F, 0xE0, 0x7D, 0x00, 0x07,
        0xB4, 0xD8, 0xA6, 0x3E, 0xC9, 0x6D, 0x62, 0x19,
        0x66, 0xC3, 0xE7, 0x10, 0x3B, 0x6C, 0x7A, 0x36,
        0x49, 0x75, 0xE6, 0x78, 0xB3, 0x8D, 0x04, 0x13,
        0x31, 0xE6, 0x79, 0x72, 0x64, 0x07, 0x76, 0x94,
        0x2B, 0xB4, 0xEC, 0x18, 0x1C, 0x32, 0x3C, 0x26,
        0xC4, 0x81, 0xBF, 0x4F, 0xB5, 0x6E, 0x5D, 0x67,
        0xCF, 0xBE, 0x17, 0x57, 0x11, 0x2B, 0xBC, 0xA0,
        0xF0, 0xC2, 0x70, 0x06, 0x94, 0x26, 0x9B, 0x26,
        0x12, 0x9C, 0x7F, 0x99, 0xD4, 0x4A, 0xF5, 0x60,
        0xCD, 0xF7, 0xA4, 0x70, 0x2E, 0xF5, 0xD6, 0xA2,
        0xEC, 0x0E, 0x99, 0x00, 0x2E, 0x89, 0x30, 0xAA,
        0x4E, 0xC0, 0x62, 0x11, 0x93, 0x0A, 0x1E, 0x68,
        0xF2, 0xED, 0x44, 0x8B, 0x10, 0x4A, 0x75, 0x68,
        0xBF, 0x46, 0xE1, 0x41, 0xD6, 0x0B, 0x61, 0x53,
        0xD4, 0x03, 0x10, 0xB3, 0x8F, 0x8E, 0x14, 0x57,
        0x27, 0x8F, 0xE3, 0x49, 0xB2, 0xB4, 0xA7, 0xAE,
        0x39, 0x7A, 0x7B, 0x8F, 0x48, 0xAA, 0xA5, 0xFD,
        0xC1, 0x28, 0x8E, 0x43, 0xE0, 0x58, 0x39, 0x32,
        0x0A, 0x14, 0xC6, 0x3A, 0xB8, 0x58, 0xE2, 0x6E,
        0x7D, 0x8C, 0x35, 0xB6, 0x47, 0x37, 0x90, 0x4D,
        0x89, 0xC1, 0x9A, 0x10, 0x3D, 0x6B, 0x68, 0x9A,
        0x3D, 0xC9, 0x0C, 0x72, 0xFC, 0x92, 0xE3, 0x5D,
        0x45, 0x2B, 0x81, 0x43, 0x02, 0x30, 0x70, 0xD4,
        0x8B, 0xB9, 0xFB, 0xB0, 0x45, 0xE3, 0xC6, 0xCE,
        0x9A, 0x8B, 0xD5, 0xC4, 0xB6, 0x7F, 0x5D, 0x8B,
        0x58, 0xC9, 0x6A, 0x28, 0x2D, 0x6E, 0x27, 0x78,
        0x3D, 0x7B, 0x99, 0x0E, 0x05, 0x2B, 0xD9, 0x5E,
        0x86, 0x50, 0x8F, 0x9B, 0xF7, 0xC0, 0x64, 0xA8,
        0xF2, 0x39, 0xE0, 0x24, 0x0A, 0x20, 0xD8, 0xDF,
        0x3A, 0x87, 0x6E, 0xDC, 0x8F, 0xF6, 0x24, 0x1B,
        0x54, 0xF2, 0x70, 0xA9, 0x8C, 0xB8, 0x07, 0x7A,
        0xAF, 0xE0, 0xE5, 0x8E, 0x5E, 0x98, 0x13, 0xC6,
        0xA5, 0xF9, 0x1F, 0x52, 0x89, 0x7B, 0x6A, 0xAD,
        0x24, 0x26, 0xC6, 0x0D, 0xA5, 0x88, 0x3E, 0x6B,
        0xDF, 0xEE, 0x33, 0x0A, 0x86, 0x09, 0xA2, 0x11,
        0x8B, 0x69, 0x9F, 0x75, 0xCE, 0xFD, 0x05, 0x01,
        0x95, 0x14, 0x64, 0xCD, 0x62, 0x04, 0x09, 0x87,
        0xFC, 0xF6, 0xB2, 0x2E, 0xCA, 0x92, 0xE4, 0x4F,
        0x55, 0xB3, 0x8C, 0x64, 0x99, 0xA8, 0xDA, 0x0A,
        0xC7, 0x82, 0x56, 0x93, 0x03, 0x67, 0xA4, 0xD7,
        0x54, 0x91, 0xA0, 0x89, 0xD8, 0x94, 0x1F, 0x6C,
        0x53, 0xCC, 0xB2, 0x60, 0x13, 0x6A, 0x93, 0xE1,
        0xFC, 0xA3, 0xDD, 0x72, 0xD5, 0x5A, 0x92, 0x35,
        0x9E, 0x3D, 0x62, 0x82, 0x70, 0x5D, 0x54, 0xAF,
        0x57, 0xC6, 0x98, 0x5E, 0x74, 0xE0, 0xF2, 0x33,
        0x26, 0x61, 0xBF, 0x2B, 0xDD, 0x78, 0x47, 0x29,
        0x04, 0xC7, 0xF0, 0x58, 0x17, 0xFC, 0x9D, 0xED,
        0xEF, 0x15, 0x6A, 0xCA, 0xC7, 0x46, 0xCE, 0x12,
        0xF8, 0x90, 0xD8, 0x5A, 0x93, 0x98, 0xA9, 0xED,
        0xFB, 0xF4, 0x6E, 0x73, 0x48, 0x81, 0x4A, 0x08,
        0x07, 0x29, 0xC8, 0x3E, 0x70, 0x4C, 0x40, 0x30,
        0x20, 0x2C, 0xF6, 0x1E, 0xCD, 0xEE, 0x27, 0x95,
        0xD5, 0x07, 0xAC, 0x28, 0x81, 0x4F, 0x53, 0xCD,
        0x06, 0x60, 0xA5, 0x57, 0x2C, 0xBE, 0x1A, 0xE5,
        0x33, 0x38, 0xB8, 0xEF, 0xDC, 0xA3, 0x1A, 0xA5,
        0xB9, 0x5A, 0xA9, 0xE7, 0x65, 0xAF, 0x4D, 0xA0,
        0x4C, 0x9B, 0x31, 0x62, 0x67, 0x7E, 0x41, 0xC0,
        0x18, 0xA5, 0xE1, 0x8A, 0xF2, 0xF9, 0x8A, 0xCA,
        0x14, 0x5C, 0xCD, 0x1B, 0x8F, 0x74, 0x31, 0x07,
        0x6A, 0x14, 0xA7, 0xC2, 0x0F, 0x6C, 0x72, 0xE8,
        0xEB, 0x97, 0x51, 0xB7, 0x89, 0x2E, 0x41, 0x01,
        0x54, 0x47, 0x63, 0x0E, 0xAA, 0x84, 0xB9, 0x60,
        0x1C, 0xB9, 0x54, 0xD8, 0x97, 0x39, 0x38, 0x9D,
        0x52, 0xBB, 0x91, 0xA9, 0x7F, 0x96, 0x08, 0x7C,
        0xB3, 0x8B, 0x0E, 0xAB, 0x59, 0xA7, 0x84, 0x68,
        0x34, 0x65, 0x55, 0xC7, 0x12, 0x84, 0xC2, 0xFB,
        0xBD, 0x27, 0x58, 0x18, 0xE9, 0x26, 0x73, 0xFA,
        0x42, 0xAB, 0x5E, 0x0D, 0x97, 0x76, 0x67, 0xA9,
        0x0F, 0x75, 0x92, 0x6C, 0x80, 0x76, 0x87, 0x75,
        0xD2, 0x3D, 0xFE, 0x0B, 0x33, 0x7B, 0x48, 0xB0,
        0xC8, 0x28, 0x1F, 0xE6, 0x3F, 0x18, 0xF2, 0x45,
        0xF8, 0x8F, 0x21, 0xE1, 0x1C, 0x56, 0xA5, 0x33,
        0x71, 0x88, 0x42, 0x5A, 0x34, 0x8B, 0x24, 0xDD,
        0x0E, 0x98, 0x30, 0xDB, 0x6B, 0x6C, 0x89, 0x64,
        0x8C, 0x7A, 0x63, 0x3C, 0xA9, 0xD8, 0x32, 0x51,
        0xD0, 0xC6, 0xF7, 0xA4, 0x53, 0x95, 0x0D, 0x02,
        0x19, 0x6A, 0x77, 0xBC, 0xDF, 0xD5, 0x2B, 0x2C,
        0x65, 0xC9, 0xBF, 0x72, 0x69, 0xC3, 0x0C, 0xEF,
        0x34, 0x75, 0x76, 0x29, 0x59, 0xBE, 0x9D, 0xE9,
        0x44, 0x21, 0x2F, 0x5F, 0xB7, 0x89, 0xA6, 0xCD,
        0x0A, 0x9A, 0x9E, 0x77, 0x5B, 0xBD, 0xDA, 0x03,
        0xA4, 0xBC, 0xFB, 0x47, 0xC1, 0x77, 0x73, 0x00,
        0x26, 0xAE, 0x2E, 0xFA, 0x62, 0x18, 0x9D, 0xB8,
        0xE2, 0xD3, 0x7A, 0xB9, 0xD8, 0xCF, 0xE9, 0x61,
        0x11, 0x80, 0xE9, 0xDC, 0xC3, 0x32, 0x9E, 0x63,
        0x6F, 0xD9, 0x42, 0xF6, 0x76, 0x7F, 0xBC, 0xBF,
        0xDB, 0x08, 0x2F, 0xA0, 0xEB, 0xB8, 0x4D, 0xF3,
        0x76, 0x62, 0xAA, 0xFA, 0x20, 0x4A, 0xDD, 0xE6,
        0xB3, 0x72, 0xC7, 0x7D, 0x36, 0x4F, 0x08, 0x56,
        0x4F, 0x19, 0xB2, 0xB0, 0x0C, 0x13, 0x1A, 0x8C,
        0xCE, 0x9A, 0x04, 0xB5, 0xB6, 0x9C, 0xD3, 0xD8,
        0xFE, 0x1F, 0x2C, 0xCC, 0x89, 0xEE, 0x7D, 0x22,
        0x8A, 0x4E, 0x0A, 0x91, 0x0C, 0x8B, 0x5A, 0xE0,
        0xBD, 0xE5, 0x3D, 0xBE, 0x90, 0x4B, 0x13, 0xA3,
        0x2F, 0x33, 0xE9, 0x9D, 0x6C, 0x67, 0x35, 0xBD,
        0x03, 0xD4, 0x09, 0x90, 0x2F, 0xC6, 0x3C, 0x8D,
        0xD8, 0x43, 0xFC, 0x1F, 0xB7, 0x49, 0xC0, 0xB7,
        0x38, 0x70, 0x1D, 0xEB, 0x5A, 0xD7, 0xAC, 0x07,
        0xAF, 0x5B, 0x93, 0xC5, 0x7B, 0x55, 0x65, 0x86,
        0x6E, 0xC1, 0xDB, 0xCD, 0x42, 0x92, 0x50, 0xDB,
        0xD1, 0x97, 0x95, 0x3D, 0x53, 0xC3, 0xFE, 0xC2,
        0xF9, 0x65, 0xF3, 0xD2, 0xEE, 0xA4, 0x7E, 0xDE,
        0xA1, 0x4B, 0x23, 0x7F, 0xA1, 0x0D, 0x25, 0x6E,
        0x80, 0x4F, 0xE3, 0xB5, 0x0C, 0xBA, 0x1C, 0x2B,
        0x42, 0x0B, 0x8F, 0xD9, 0xB6, 0x4E, 0x52, 0xD2,
        0xDB, 0x35, 0xD2, 0xA1, 0xC4, 0xE6, 0xD6, 0x51,
        0x76, 0xE7, 0x87, 0x5E, 0xBE, 0x93, 0xE6, 0x61,
        0x71, 0x4C, 0x8B, 0xA6, 0x96, 0xDA, 0xF7, 0xCB,
        0x06, 0xB7, 0xB8, 0xC4, 0xF6, 0xF5, 0xC6, 0x29,
        0xAA, 0xE1, 0x13, 0x87, 0x6F, 0x96, 0xBA, 0x0C,
        0xF6, 0x79, 0x8F, 0x03, 0x86, 0x22, 0xE3, 0xFB,
        0xCF, 0x86, 0xCF, 0x7C, 0x77, 0xFD, 0xB4, 0xEE,
        0xBD, 0x42, 0x38, 0x7F, 0xF2, 0xCC, 0xCB, 0x06,
        0xEA, 0x0D, 0x81, 0xA1, 0x8E, 0xB5, 0xE7, 0x40,
        0xC8, 0x03, 0xA3, 0x4B, 0xC8, 0xB4, 0x0E, 0x3E,
        0x36, 0xAB, 0x90, 0xC1, 0xFC, 0xB0, 0x37, 0x2B,
        0x83, 0xA1, 0x3D, 0x56, 0xD6, 0x83, 0x0F, 0x99,
        0xC4, 0x58, 0xB8, 0x94, 0x61, 0x19, 0xA6, 0x60,
        0x47, 0xCB, 0x2D, 0xAF, 0x29, 0x38, 0x90, 0xFA,
        0x99, 0x0F, 0x02, 0x02, 0x65, 0x90, 0x5F, 0xA2,
        0xA2, 0xE3, 0xBB, 0x34, 0x15, 0x2F, 0x0B, 0xF5,
        0xB2, 0xCC, 0x83, 0x59, 0xAF, 0xA7, 0x4D, 0x38,
        0xAD, 0xF6, 0x52, 0x5C, 0x53, 0xD9, 0x0E, 0x3F,
        0xD6, 0x53, 0x86, 0xE2, 0x79, 0xC2, 0x65, 0x48,
        0xB2, 0x67, 0x3B, 0xAF, 0x52, 0x53, 0x57, 0x9A,
        0x27, 0x80, 0x88, 0x37, 0x77, 0x67, 0x4E, 0x1F,
        0xF1, 0x7B, 0xC5, 0xCB, 0xD8, 0x11, 0x0A, 0xDD,
        0x92, 0x0E, 0x88, 0x6C, 0xCA, 0x33, 0x76, 0x3B,
        0x04, 0xFA, 0xC0, 0xFD, 0xC6, 0x3F, 0xB4, 0x72,
        0xC2, 0x2B, 0x6D, 0x5E, 0xB6, 0xA1, 0x4E, 0x5F,
        0xC0, 0x50, 0x16, 0xEF, 0xFE, 0x6A, 0x42, 0x72,
        0x65, 0x02, 0xEE, 0x07, 0xC6, 0x19, 0xC6, 0x95,
        0xDE, 0x3F, 0xD9, 0xC5, 0xC6, 0x0E, 0x70, 0x07,
        0x6A, 0xC3, 0x36, 0x1B, 0x84, 0x6F, 0xDF, 0x80,
        0x16, 0x4E, 0x86, 0x90, 0xC8, 0x55, 0x7B, 0xDD,
        0xC0, 0x86, 0x0C, 0x37, 0x47, 0x1F, 0x35, 0xF8,
        0x47, 0xF2, 0xCD, 0x96, 0x21, 0x64, 0xAD, 0x46,
        0xE1, 0xDF, 0x44, 0x79, 0x48, 0x02, 0xF9, 0x71,
        0x39, 0x35, 0x26, 0xFC, 0x12, 0x0D, 0x88, 0xAC,
        0xD6, 0xFA, 0x29, 0x74, 0x55, 0x51, 0xE7, 0xAF,
        0x3D, 0x7E, 0x1E, 0x7E, 0xE0, 0x18, 0xB6, 0x3C,
        0x4B, 0x99, 0x9D, 0x51, 0x02, 0x51, 0xD8, 0xE9,
        0xFA, 0x61, 0x88, 0x2E, 0xCF, 0x73, 0x77, 0x65,
        0x71, 0xAE, 0xAE, 0xD7, 0xA1, 0xF9, 0xE0, 0x7F,
        0x30, 0x46, 0xCB, 0x20, 0xEC, 0xF4, 0xD2, 0xC1,
        0x63, 0xF5, 0x6F, 0x8A, 0x72, 0xF9, 0x5B, 0x85,
        0xD2, 0xCA, 0x6D, 0x35, 0xD1, 0x17, 0xF6, 0x08,
        0x9E, 0x0A, 0x73, 0xB3, 0xDA, 0x1A, 0x32, 0xBA,
        0x23, 0x10, 0x4A, 0x5D, 0xD7, 0xAA, 0xB4, 0x68,
        0x97, 0x59, 0x45, 0xC5, 0x7C, 0x16, 0x6F, 0xE4,
        0x62, 0x89, 0xF1, 0xD3, 0xB4, 0x03, 0x90, 0x7B,
        0xA4, 0xA2, 0xCA, 0xA0, 0x5D, 0x69, 0x1B, 0xA9,
        0xBB, 0xEB, 0xA0, 0xE2, 0xDE, 0xBE, 0x0E, 0xC4,
        0x9E, 0x21, 0x38, 0x61, 0x92, 0x9B, 0xAB, 0x69,
        0xAA, 0xD0, 0x1D, 0xF6, 0xC3, 0xEE, 0xA6, 0xC3,
        0xF3, 0x29, 0x1B, 0xE5, 0x6E, 0x52, 0x89, 0xD0,
        0xBA, 0xD8, 0x60, 0x27, 0x80, 0x1A, 0xB5, 0x7F,
        0x7F, 0xB5, 0xC2, 0x5A, 0xC6, 0x83, 0xA4, 0xC0,
        0x88, 0x39, 0xF3, 0xE7, 0x39, 0xD6, 0x81, 0x1C,
        0x13, 0x20, 0xFD, 0x93, 0x3D, 0x8E, 0x79, 0x60,
        0x7C, 0xFF, 0xE4, 0x37, 0x5B, 0x33, 0xA3, 0x9D,
        0xB7, 0x57, 0xCD, 0x45, 0x0A, 0xB9, 0xE4, 0xF1,
        0xBC, 0x59, 0x74, 0xE8, 0xB3, 0x06, 0xD0, 0x9F,
        0x0F, 0xBC, 0x5B, 0x23, 0xB8, 0x6C, 0xD6, 0x4D,
        0xFA, 0xCC, 0x14, 0xAB, 0x74, 0x61, 0x1A, 0xFC,
        0x22, 0xA6, 0xED, 0x09, 0x76, 0x91, 0xD8, 0x6E,
        0x44, 0xB6, 0x00, 0x14, 0xDC, 0x74, 0x2D, 0x90,
        0xAA, 0x59, 0x98, 0x76, 0x30, 0xC5, 0x44, 0xA4,
        0x61, 0x43, 0xD6, 0xE2, 0x28, 0x28, 0xA7, 0xBD,
        0x6E, 0x50, 0x5C, 0xE1, 0x96, 0x7A, 0xF8, 0xA8,
        0x32, 0x8C, 0xE9, 0xFD, 0x11, 0x37, 0x91, 0xD1,
        0xAF, 0x3C, 0xD3, 0x1C, 0x1E, 0x88, 0x4D, 0x7E,
        0x87, 0x84, 0x84, 0x6F, 0x39, 0x0B, 0xFB, 0x2D,
        0xB3, 0x12, 0x4C, 0x6D, 0x45, 0xDD, 0xCD, 0x7D,
        0x75, 0xB7, 0xFE, 0x7E, 0x44, 0xCC, 0x29, 0xE5,
        0xB3, 0x10, 0xEE, 0x23, 0x55, 0x5B, 0xCF, 0xBA,
        0xBD, 0xA1, 0xBE, 0x64, 0xF8, 0x6E, 0x60, 0x31,
        0x0A, 0x2D, 0xC9, 0x3B, 0x1D, 0x44, 0xE1, 0x9D,
        0x60, 0x28, 0x77, 0xEE
    };
    static const byte rnd_65[] = {
        0x4E, 0x7A, 0x01, 0x7C, 0x15, 0x03, 0x9D, 0xC2,
        0x00, 0x51, 0xD2, 0x96, 0x0E, 0x5E, 0x15, 0x59,
        0xCC, 0x27, 0xED, 0x46, 0x87, 0x7C, 0xB9, 0x81,
        0x16, 0x19, 0x9A, 0x0F, 0x41, 0x05, 0xFE, 0x32
    };
    static const byte sig_65[] = {
        0xB8, 0x65, 0xB0, 0x0B, 0x21, 0x18, 0xDB, 0xB0,
        0x0B, 0x70, 0x1C, 0x66, 0x45, 0x65, 0x5E, 0x8A,
        0xCF, 0xA8, 0x4E, 0xA7, 0x92, 0xB4, 0x48, 0x64,
        0x2E, 0x18, 0x32, 0xC3, 0x70, 0x7C, 0x87, 0xCF,
        0x09, 0xFB, 0xE7, 0x72, 0xF1, 0xD4, 0x38, 0x5B,
        0xFB, 0xE5, 0xE6, 0xCF, 0xBB, 0xE2, 0x6C, 0x10,
        0xED, 0x6E, 0xB8, 0x65, 0xC8, 0x87, 0xF8, 0x69,
        0x39, 0x43, 0x9A, 0x9B, 0xF7, 0x68, 0xBF, 0x03,
        0x9D, 0x73, 0xE3, 0xEA, 0x83, 0xBD, 0xF1, 0x85,
        0x03, 0xB5, 0xD1, 0xB3, 0x91, 0x79, 0xA8, 0x27,
        0xB0, 0xD7, 0x80, 0x5F, 0x98, 0x42, 0x8B, 0xD8,
        0x7C, 0xEA, 0x6B, 0x06, 0x96, 0x0C, 0x78, 0xB4,
        0xB5, 0x86, 0xFB, 0x0D, 0x5E, 0xDA, 0x9F, 0xAA,
        0xC0, 0x25, 0x6E, 0x38, 0x82, 0x35, 0x62, 0xA3,
        0x07, 0x96, 0x61, 0x17, 0x00, 0x5A, 0xA4, 0x2F,
        0x1B, 0x65, 0x54, 0xA0, 0x48, 0x75, 0xF8, 0x5C,
        0x2E, 0x3F, 0xAF, 0xA6, 0x52, 0x47, 0x1D, 0x4E,
        0x98, 0x06, 0x54, 0x82, 0xFC, 0x7D, 0xF4, 0x9B,
        0x2C, 0x40, 0xD0, 0xE7, 0xB9, 0x82, 0x38, 0xDF,
        0xBE, 0x85, 0x3D, 0x16, 0xBF, 0x99, 0x92, 0xBB,
        0x08, 0xC1, 0x92, 0x59, 0xF9, 0xB5, 0x75, 0xEA,
        0x7A, 0x4A, 0x80, 0x09, 0x3A, 0x64, 0xA9, 0x26,
        0x71, 0x85, 0x7A, 0x50, 0x89, 0x20, 0xD6, 0x0F,
        0xF6, 0xFB, 0xF3, 0x83, 0x41, 0xC5, 0x59, 0x01,
        0x05, 0x63, 0x3A, 0x42, 0x6D, 0x60, 0x2D, 0xAC,
        0x06, 0x4D, 0xD7, 0xA7, 0xF1, 0x1A, 0x60, 0x21,
        0x5C, 0x35, 0xB7, 0xB9, 0xC0, 0x0E, 0x9D, 0x84,
        0x63, 0x98, 0x8C, 0xF4, 0x72, 0xCD, 0x6A, 0xCF,
        0xB7, 0xF7, 0x22, 0xB8, 0xC4, 0xC6, 0x27, 0x02,
        0x60, 0x7A, 0x67, 0x48, 0x80, 0xAC, 0xB3, 0xD6,
        0xC6, 0x25, 0x3E, 0x71, 0x17, 0x5A, 0x05, 0xB3,
        0x92, 0xCA, 0xB4, 0xBB, 0x14, 0xCE, 0x86, 0xA5,
        0x98, 0xAB, 0xC7, 0x88, 0xD0, 0xFF, 0x4D, 0x82,
        0x77, 0x5E, 0x4E, 0xA0, 0xFC, 0x36, 0x36, 0x3C,
        0xD0, 0xE9, 0x7B, 0x78, 0xA6, 0xAE, 0x4D, 0xA8,
        0xE9, 0x8C, 0xA6, 0x12, 0x77, 0x2D, 0x56, 0xB5,
        0x82, 0xF8, 0x2C, 0x07, 0x09, 0xBE, 0xAE, 0x46,
        0x67, 0x3B, 0xDD, 0x80, 0x42, 0x86, 0x5C, 0xFA,
        0x95, 0xBF, 0x53, 0x38, 0xCF, 0xEA, 0x60, 0x6A,
        0x6E, 0xF3, 0x16, 0x38, 0x46, 0xAE, 0x83, 0xB2,
        0x5E, 0x5F, 0x5B, 0xD3, 0x1C, 0x83, 0xF1, 0x36,
        0x72, 0x9A, 0x8E, 0xA6, 0x27, 0x4F, 0x99, 0x4F,
        0xA9, 0x04, 0x5F, 0xA8, 0xA9, 0x0F, 0xF8, 0x54,
        0xB8, 0x71, 0xCF, 0x82, 0xE2, 0xB7, 0x01, 0xE8,
        0xF4, 0xAC, 0x04, 0xFE, 0x9E, 0x28, 0x49, 0x1B,
        0x9A, 0x25, 0xFF, 0x26, 0x3E, 0x2C, 0xF7, 0x54,
        0x99, 0xE0, 0x09, 0xFD, 0x02, 0x29, 0xFB, 0xF7,
        0xE5, 0xE4, 0x60, 0x44, 0x34, 0x4B, 0x07, 0xD7,
        0x22, 0x14, 0xA9, 0xAC, 0xB4, 0xFF, 0x61, 0x02,
        0xAB, 0xC1, 0x26, 0x2B, 0xC2, 0xE1, 0xCD, 0x24,
        0x91, 0x60, 0x7A, 0xE7, 0xAA, 0xEC, 0xF4, 0xC3,
        0x51, 0x75, 0xCF, 0xA4, 0x38, 0x3A, 0xA8, 0x6A,
        0xF1, 0xE6, 0x2E, 0xD0, 0x63, 0x87, 0xCC, 0x59,
        0x48, 0x36, 0x46, 0x7F, 0x41, 0xDF, 0xCA, 0x8F,
        0xA0, 0xCA, 0x71, 0x28, 0x0B, 0xFB, 0x1C, 0x25,
        0x60, 0xC8, 0x99, 0x55, 0x36, 0xF8, 0x42, 0x74,
        0x70, 0x45, 0x59, 0x14, 0x53, 0x74, 0x5F, 0x26,
        0x03, 0x82, 0xE3, 0xDA, 0x50, 0x79, 0x3F, 0xD7,
        0xCA, 0x76, 0x27, 0x18, 0x5D, 0xBD, 0xCE, 0xDD,
        0xF6, 0x9B, 0x2D, 0x3E, 0x15, 0x1C, 0x7F, 0x97,
        0x28, 0x8A, 0x38, 0x2A, 0x92, 0xB0, 0x50, 0xF7,
        0x91, 0xF9, 0x58, 0x7D, 0x77, 0xC6, 0x4D, 0x8B,
        0x5D, 0x40, 0xAA, 0x19, 0x9D, 0x49, 0x66, 0xBE,
        0x2D, 0x52, 0x4F, 0x96, 0x10, 0xF2, 0xFA, 0x02,
        0xED, 0x23, 0x17, 0x63, 0x69, 0xDB, 0x93, 0x93,
        0x50, 0xDA, 0x60, 0x1E, 0xA6, 0x67, 0x70, 0x95,
        0x2E, 0x0F, 0x23, 0xED, 0xA6, 0x8A, 0x73, 0x75,
        0x6E, 0xFF, 0x61, 0x0E, 0x8D, 0x6A, 0x9F, 0x49,
        0x34, 0x56, 0x58, 0x54, 0x42, 0x82, 0x45, 0x3B,
        0x5E, 0x73, 0xA3, 0x22, 0xA0, 0x32, 0x67, 0xC9,
        0x69, 0xB5, 0x07, 0x34, 0xF2, 0xEC, 0xD4, 0xEC,
        0x90, 0x55, 0x76, 0x0D, 0x92, 0x86, 0x10, 0xE9,
        0x4E, 0x0B, 0x16, 0x28, 0xD6, 0xAF, 0x1B, 0x27,
        0xAB, 0x13, 0x82, 0x9F, 0x7F, 0x8E, 0xF5, 0x0D,
        0x9E, 0x29, 0x96, 0xFC, 0x64, 0xB0, 0x6A, 0xC8,
        0x94, 0x61, 0x14, 0x76, 0x6D, 0xAD, 0x8D, 0xFF,
        0xE6, 0x34, 0xF4, 0x7E, 0x9D, 0x85, 0x69, 0x96,
        0x6C, 0x6F, 0x69, 0x68, 0x21, 0x8C, 0x5B, 0x86,
        0x33, 0x61, 0x1B, 0xF4, 0x2B, 0x4F, 0xC0, 0xE7,
        0x8D, 0x0C, 0x02, 0x9E, 0xAB, 0x85, 0xF2, 0x2F,
        0x16, 0x17, 0x19, 0x80, 0xCC, 0x65, 0xF2, 0x84,
        0x45, 0xA1, 0x1A, 0x08, 0x3A, 0xA0, 0x29, 0x77,
        0xC2, 0xE8, 0x88, 0x6E, 0xD2, 0x70, 0x67, 0x2E,
        0x51, 0x2A, 0xE8, 0x9C, 0x6A, 0x26, 0xFC, 0xAD,
        0x1E, 0xC7, 0x2B, 0x9E, 0xCF, 0xA5, 0xA5, 0xEF,
        0xC7, 0x0F, 0xF0, 0xBA, 0xB2, 0x8F, 0x11, 0x4F,
        0x4D, 0xA8, 0x17, 0x0F, 0xE8, 0xB6, 0x3C, 0x2E,
        0x11, 0xBE, 0x7A, 0x35, 0x46, 0x6E, 0x97, 0x9A,
        0x12, 0x7E, 0xC0, 0xD2, 0x03, 0x23, 0xD5, 0x02,
        0x73, 0x0A, 0xBC, 0xE6, 0x40, 0xA2, 0x44, 0x1C,
        0xDD, 0xAB, 0xA3, 0x26, 0xD6, 0x78, 0x3D, 0x01,
        0x92, 0xDB, 0xA9, 0xE9, 0x3F, 0xE5, 0x07, 0xC6,
        0xA7, 0x37, 0x67, 0xBE, 0x56, 0xE2, 0x77, 0x65,
        0x76, 0xEF, 0xEF, 0xF1, 0xCA, 0x17, 0x9D, 0x83,
        0x34, 0x3E, 0x38, 0xC6, 0xA9, 0xC2, 0xFE, 0x72,
        0x5D, 0xDE, 0x80, 0x7D, 0x21, 0x72, 0x5E, 0x73,
        0x08, 0x72, 0xE2, 0xAB, 0x3D, 0x90, 0x11, 0x61,
        0xF4, 0x55, 0xBC, 0xAD, 0x23, 0xA8, 0x43, 0x3A,
        0x41, 0x31, 0x51, 0xFD, 0x22, 0x17, 0x14, 0x31,
        0x0E, 0x4D, 0x0B, 0x6A, 0x1E, 0x1B, 0x2C, 0xAC,
        0xA4, 0x99, 0xEE, 0xE8, 0x05, 0xA1, 0x64, 0xF2,
        0x91, 0xD5, 0x07, 0x5E, 0x6B, 0x65, 0xA7, 0x9C,
        0x2B, 0xCA, 0xD9, 0x17, 0xB1, 0x22, 0xFE, 0x1A,
        0xC4, 0xFB, 0xB4, 0x10, 0x21, 0x1B, 0xA0, 0xA1,
        0x99, 0x7A, 0x31, 0x30, 0x7C, 0x01, 0xF0, 0xFE,
        0xD3, 0xB3, 0x14, 0x3D, 0x28, 0x34, 0x0F, 0xAC,
        0xF0, 0x93, 0x37, 0xC4, 0xEF, 0x04, 0x74, 0x80,
        0xA2, 0x90, 0xAE, 0x02, 0xB2, 0xF7, 0xD8, 0x7B,
        0x8C, 0x29, 0xA0, 0xAE, 0xAE, 0x2E, 0x92, 0xC9,
        0xC5, 0x44, 0x7D, 0x66, 0xC5, 0x5C, 0x1D, 0x1E,
        0x25, 0x88, 0x5D, 0x10, 0x37, 0xFB, 0x5F, 0xCC,
        0x80, 0x15, 0x4F, 0x1D, 0x23, 0xB4, 0xF2, 0x7B,
        0x5B, 0xAC, 0x89, 0xBE, 0x1C, 0x36, 0x3C, 0xFF,
        0x8E, 0xA7, 0x58, 0x73, 0xAC, 0x3F, 0x63, 0x33,
        0xE8, 0x6C, 0x53, 0xEC, 0xA5, 0x5D, 0xBE, 0xD5,
        0xE1, 0xF1, 0x12, 0x6B, 0x12, 0x78, 0xC7, 0x29,
        0xC9, 0xA8, 0x4C, 0x4A, 0x1B, 0x7F, 0x15, 0x11,
        0x93, 0x01, 0xC8, 0x0B, 0xE2, 0x2F, 0xE9, 0xBE,
        0xBA, 0x17, 0x59, 0x45, 0xB2, 0x61, 0x2B, 0x66,
        0xDD, 0xCE, 0xDF, 0x9A, 0x2A, 0x4D, 0x5F, 0x24,
        0xF9, 0x02, 0xBB, 0xA6, 0x8D, 0xA7, 0x5D, 0x95,
        0x97, 0x2E, 0x28, 0xD6, 0xCB, 0x70, 0x17, 0xCA,
        0x51, 0xED, 0x58, 0x73, 0xAB, 0x03, 0xDD, 0x2E,
        0x92, 0x6C, 0x15, 0x64, 0x2C, 0x9D, 0x6E, 0x64,
        0x27, 0xFC, 0xE8, 0x0F, 0xC3, 0x8B, 0x34, 0xFE,
        0xB3, 0xC1, 0x55, 0x13, 0xA6, 0x87, 0xC3, 0x5B,
        0x94, 0xEB, 0x83, 0xE4, 0xAB, 0x3E, 0x18, 0x76,
        0x67, 0x92, 0x70, 0xF5, 0xA9, 0x8F, 0x18, 0xA6,
        0x5F, 0x57, 0x41, 0x76, 0x55, 0xFD, 0xA9, 0x99,
        0x4E, 0x8F, 0xCC, 0x61, 0x6C, 0x6C, 0x60, 0x06,
        0x10, 0x40, 0x26, 0xD6, 0xCD, 0x7A, 0xA0, 0x56,
        0x3D, 0x51, 0x07, 0x25, 0x76, 0x00, 0x05, 0xF5,
        0xFD, 0x39, 0xE7, 0x59, 0x24, 0x90, 0x29, 0xF0,
        0x3D, 0x9F, 0x00, 0x67, 0x10, 0x3F, 0xA0, 0x45,
        0x21, 0x14, 0xDF, 0x24, 0x40, 0xE8, 0xC6, 0xDB,
        0x65, 0xE2, 0x39, 0x56, 0xEB, 0x1B, 0xEE, 0xB2,
        0xC3, 0x4E, 0x5B, 0x20, 0xAC, 0x31, 0x6A, 0x03,
        0xA9, 0x54, 0x36, 0x66, 0x62, 0x68, 0xC3, 0xD8,
        0x22, 0x8F, 0x62, 0xEB, 0x56, 0x67, 0xB3, 0xB6,
        0xBB, 0x85, 0x7D, 0xD0, 0x73, 0x7B, 0x69, 0x05,
        0x1E, 0x9F, 0x26, 0xEE, 0x02, 0x36, 0x71, 0xCE,
        0xAD, 0xFA, 0xCA, 0xF9, 0x49, 0x7F, 0x1A, 0xDE,
        0x58, 0x7A, 0x69, 0x3E, 0xEF, 0xFB, 0xFC, 0xD5,
        0x50, 0xEC, 0x20, 0x8C, 0x23, 0x56, 0x91, 0xE8,
        0xE3, 0x66, 0xD9, 0x65, 0xB6, 0x2B, 0xEC, 0x16,
        0xA6, 0x61, 0xCD, 0x5D, 0xE2, 0x87, 0x93, 0x22,
        0x0D, 0x66, 0xF2, 0x64, 0x55, 0x05, 0xB8, 0x52,
        0x41, 0x2F, 0xAE, 0x7B, 0x9D, 0x98, 0x29, 0xBF,
        0x61, 0x5F, 0x7C, 0xBD, 0x59, 0xA7, 0xBC, 0x1D,
        0x03, 0x4E, 0x6A, 0x25, 0x52, 0x9C, 0xFB, 0x48,
        0x6A, 0xF2, 0x01, 0xDE, 0xB7, 0xEA, 0x95, 0xBA,
        0x70, 0x8A, 0x31, 0x59, 0x17, 0x16, 0x74, 0x34,
        0x53, 0x09, 0xDB, 0x81, 0x50, 0xE6, 0x7E, 0xBB,
        0x30, 0xA7, 0xFF, 0x80, 0xCA, 0xC9, 0xAB, 0x13,
        0x92, 0x50, 0x0A, 0x83, 0xE6, 0x3B, 0xBF, 0x7C,
        0x42, 0xEB, 0x94, 0x53, 0xC2, 0xC9, 0xAC, 0xDA,
        0x02, 0xBE, 0x53, 0x82, 0x34, 0xAA, 0xA7, 0xDB,
        0x5A, 0x7F, 0x58, 0x8F, 0xC9, 0x1B, 0x90, 0xEE,
        0x24, 0x77, 0xF2, 0xB6, 0x1C, 0xD1, 0x06, 0x2A,
        0x7E, 0xF1, 0xE6, 0xE4, 0xDC, 0x54, 0xB3, 0x6D,
        0x0E, 0x19, 0x93, 0x3E, 0x98, 0x1C, 0xB7, 0x63,
        0xA9, 0xE1, 0x07, 0xE0, 0x1D, 0xA9, 0x42, 0x0F,
        0x82, 0xCA, 0x79, 0x35, 0x92, 0xA4, 0x7C, 0x4B,
        0x97, 0x7F, 0xF2, 0xC8, 0x84, 0x98, 0xDA, 0x95,
        0xC4, 0x3D, 0x23, 0x2F, 0x42, 0xAF, 0x99, 0x48,
        0x0B, 0xF0, 0xA4, 0xF8, 0xB7, 0xC4, 0x94, 0x9D,
        0x1A, 0xE1, 0xD4, 0xFA, 0x8E, 0x1D, 0x1A, 0x8C,
        0xD0, 0xF9, 0xED, 0x00, 0xDA, 0x59, 0x5E, 0xFD,
        0x2B, 0x76, 0x6F, 0x0B, 0x79, 0xD4, 0x49, 0x0D,
        0xB9, 0x28, 0xEC, 0x44, 0xB5, 0x03, 0x0A, 0x74,
        0xCA, 0x42, 0x81, 0x1A, 0x5B, 0x5A, 0xE5, 0x22,
        0xC7, 0x76, 0x4D, 0xDF, 0xD9, 0xFD, 0x92, 0xF0,
        0x06, 0xE9, 0x4B, 0x35, 0xA7, 0xEF, 0x01, 0x42,
        0xDA, 0x71, 0x78, 0xC2, 0xF5, 0x30, 0x74, 0xD0,
        0x74, 0x51, 0xB1, 0x55, 0x65, 0xA9, 0xE0, 0xC5,
        0x7E, 0xA1, 0xB9, 0x4C, 0x88, 0xEA, 0xE7, 0x41,
        0xB1, 0xF5, 0x01, 0xC4, 0xD3, 0x70, 0x72, 0x7D,
        0xAD, 0x27, 0x65, 0xF7, 0x95, 0xAD, 0x41, 0x46,
        0x35, 0x80, 0x0E, 0xC1, 0x94, 0x9D, 0x03, 0x71,
        0x39, 0xDE, 0x26, 0xAF, 0xCF, 0x93, 0x3D, 0x9A,
        0x09, 0xC1, 0x27, 0xFC, 0x6B, 0x36, 0xE5, 0x18,
        0xC6, 0xDE, 0x94, 0x92, 0xBA, 0x70, 0x82, 0x7B,
        0x68, 0x1C, 0x2D, 0x18, 0xA4, 0x01, 0x23, 0xB6,
        0xC5, 0xF6, 0x17, 0x37, 0xCB, 0x9D, 0xC6, 0xAA,
        0x9C, 0xE1, 0x7D, 0x16, 0x8E, 0xBB, 0xDD, 0xD6,
        0x3C, 0x07, 0x60, 0x19, 0x3C, 0x97, 0x49, 0x33,
        0xDB, 0x47, 0x4A, 0xA8, 0x9A, 0xF3, 0x0E, 0x16,
        0x29, 0x38, 0xF6, 0xDB, 0x78, 0x65, 0xDE, 0x23,
        0x1F, 0x86, 0x16, 0x9C, 0x9E, 0x2A, 0x30, 0x2F,
        0xC4, 0x1F, 0x1B, 0xE5, 0xF3, 0x6C, 0x55, 0x83,
        0xFC, 0xD9, 0x1E, 0x21, 0xCB, 0x8A, 0x67, 0x57,
        0xD3, 0x0A, 0x4B, 0xAC, 0xDB, 0x67, 0xE7, 0xA6,
        0x1B, 0x0C, 0x8E, 0x21, 0x7E, 0x0C, 0xCB, 0xF5,
        0x0E, 0xA6, 0x42, 0xCD, 0xE3, 0xFC, 0x74, 0xC7,
        0xF9, 0xFF, 0xBD, 0xA9, 0xA1, 0xE6, 0x84, 0xBB,
        0xC9, 0xA8, 0xF7, 0xCD, 0x3F, 0x1B, 0xD0, 0xDB,
        0x63, 0xDD, 0xDF, 0x4E, 0xA4, 0x79, 0xC2, 0x35,
        0x65, 0x2C, 0x5D, 0xCB, 0xCA, 0x7B, 0xDD, 0x4E,
        0x2F, 0x33, 0xE8, 0x71, 0x72, 0xC1, 0x8B, 0x5F,
        0xF3, 0x90, 0x99, 0x40, 0x8D, 0x27, 0x2F, 0xD0,
        0xFB, 0x0D, 0x6A, 0x23, 0xB1, 0x43, 0x00, 0xDF,
        0xC6, 0x4C, 0x02, 0x74, 0x3E, 0x52, 0x36, 0x08,
        0xE9, 0x73, 0x61, 0x3D, 0xCA, 0xAC, 0x9D, 0x1D,
        0x14, 0xB3, 0xA6, 0x24, 0x0E, 0xC2, 0xF2, 0x29,
        0x39, 0x91, 0xF6, 0x90, 0x6A, 0xE3, 0x6C, 0x04,
        0x69, 0xF3, 0x09, 0x11, 0x34, 0x8E, 0xC1, 0x2D,
        0xDB, 0xA6, 0xC3, 0xCA, 0x19, 0xBC, 0x69, 0x5F,
        0xCD, 0x16, 0xE5, 0xAE, 0xF2, 0xAD, 0x7C, 0x73,
        0x25, 0x15, 0x70, 0xB5, 0xD0, 0x49, 0xA6, 0xC3,
        0xA5, 0x2F, 0xA3, 0xFC, 0x9E, 0xD5, 0x4E, 0x54,
        0x97, 0x3A, 0xE7, 0x89, 0xB0, 0xBF, 0xD6, 0xF8,
        0xCC, 0x26, 0x44, 0xA9, 0xF8, 0x5A, 0xCE, 0x06,
        0x78, 0xD8, 0x9E, 0xFC, 0x12, 0xB6, 0x11, 0xC3,
        0xDF, 0xAE, 0x3F, 0x94, 0x50, 0x34, 0xB8, 0x99,
        0xBE, 0x99, 0xA7, 0x32, 0x88, 0x9F, 0x17, 0xD2,
        0x08, 0xDC, 0xD7, 0xEE, 0x95, 0x9D, 0x1A, 0xC7,
        0x61, 0xDB, 0xA4, 0x86, 0x4C, 0x14, 0xB0, 0xA3,
        0x5E, 0x4C, 0x7B, 0xBD, 0xA0, 0x96, 0xFB, 0x8A,
        0xB3, 0x22, 0x69, 0x26, 0xC8, 0x9E, 0x7C, 0xDA,
        0x92, 0x9E, 0xF1, 0x30, 0xC6, 0x92, 0xC9, 0x26,
        0x59, 0xE6, 0xF4, 0x65, 0x2B, 0xF2, 0x15, 0x63,
        0x61, 0xC7, 0x7D, 0xBE, 0xEF, 0x5A, 0x06, 0x23,
        0xA0, 0x67, 0x04, 0x99, 0x0E, 0x19, 0x8A, 0x13,
        0x67, 0x30, 0x54, 0x32, 0x4B, 0xBB, 0xAA, 0x64,
        0x36, 0x92, 0xF2, 0x43, 0xD6, 0x7C, 0x1B, 0x4F,
        0x95, 0xB9, 0x28, 0xAC, 0xF1, 0x68, 0x6F, 0x60,
        0xC1, 0x44, 0x87, 0xD6, 0xDD, 0x7F, 0x88, 0x01,
        0xEF, 0x20, 0x93, 0x9E, 0x03, 0xA1, 0xCA, 0x7D,
        0x74, 0x32, 0xDC, 0xF5, 0x95, 0xF1, 0xE9, 0xED,
        0xF2, 0xB2, 0x93, 0x57, 0xA1, 0xD4, 0xC7, 0xDA,
        0x33, 0x51, 0x2C, 0x45, 0x1A, 0x7C, 0x66, 0x04,
        0x38, 0x2D, 0x90, 0xC3, 0x30, 0x79, 0xD9, 0x57,
        0x38, 0xE4, 0x71, 0x89, 0xD8, 0x54, 0x9E, 0x43,
        0xD2, 0x94, 0xE7, 0x3D, 0x1C, 0xA7, 0x48, 0x7B,
        0x50, 0xD0, 0xED, 0x7C, 0xC6, 0xF9, 0x6B, 0xEE,
        0xA7, 0x6C, 0xCE, 0xB9, 0x6D, 0x37, 0x92, 0x00,
        0x4E, 0xB3, 0xE5, 0x49, 0x16, 0x35, 0xA6, 0x7F,
        0x6F, 0xFA, 0x1F, 0x1D, 0xF6, 0xA1, 0xF2, 0xFD,
        0xEE, 0x77, 0x84, 0x17, 0x80, 0xAE, 0x08, 0x09,
        0xD2, 0x92, 0xED, 0x7B, 0x00, 0xF4, 0x2D, 0x80,
        0x91, 0x19, 0x09, 0xB5, 0x1C, 0x9A, 0x3A, 0xE5,
        0x4B, 0x7A, 0x6D, 0x7D, 0x29, 0xD2, 0x00, 0x05,
        0x22, 0xD4, 0xF8, 0x76, 0xE2, 0x5C, 0x0D, 0x6A,
        0x15, 0x77, 0x22, 0x18, 0x85, 0xFD, 0x30, 0x74,
        0xF3, 0x3B, 0xDC, 0xD9, 0x6C, 0xDE, 0x80, 0x40,
        0x4A, 0x37, 0xE1, 0x60, 0x9F, 0x26, 0xCF, 0xBE,
        0x24, 0xA1, 0xFB, 0xF9, 0x76, 0x2A, 0x1A, 0x23,
        0x32, 0xE7, 0xA2, 0xD8, 0x2D, 0xF9, 0xD2, 0x0F,
        0x08, 0x3A, 0xDB, 0x35, 0x35, 0x33, 0x59, 0x0B,
        0xB1, 0xF9, 0x54, 0x33, 0x49, 0x36, 0x9E, 0x21,
        0xEC, 0xF5, 0x94, 0xE2, 0x78, 0x07, 0xA5, 0x63,
        0x50, 0xD6, 0x23, 0x84, 0xDE, 0xAD, 0xA7, 0x89,
        0xBE, 0x92, 0xF0, 0x12, 0xC1, 0xF8, 0xA7, 0x2D,
        0x8B, 0xE0, 0x79, 0xF8, 0xD7, 0xBD, 0x04, 0x0B,
        0xC5, 0xF2, 0x23, 0x36, 0x11, 0x6D, 0x6F, 0x37,
        0xDB, 0xFB, 0xD2, 0xC7, 0x44, 0xC3, 0xAE, 0x78,
        0xEC, 0xB4, 0xE0, 0x5A, 0x55, 0xB3, 0xFC, 0xC3,
        0x1B, 0x8C, 0xA6, 0xDB, 0xE8, 0x95, 0x72, 0x44,
        0x90, 0x8F, 0x4E, 0xD1, 0xD3, 0x46, 0x6C, 0x9E,
        0x00, 0xC6, 0xCC, 0xAE, 0xFC, 0x95, 0x4D, 0x85,
        0x7C, 0x65, 0x5F, 0x74, 0x71, 0xE3, 0x80, 0x88,
        0xCF, 0x1E, 0xB8, 0xBE, 0xED, 0x8D, 0xC4, 0xFB,
        0x3E, 0x36, 0xF3, 0xB8, 0x42, 0x1F, 0x37, 0x31,
        0x8D, 0xA2, 0x35, 0x36, 0x9E, 0x92, 0x3D, 0xD8,
        0xEA, 0xA7, 0xA2, 0x29, 0x0E, 0x14, 0xBF, 0x59,
        0x1E, 0x1D, 0x98, 0x27, 0x30, 0x3B, 0xF3, 0x57,
        0x69, 0x75, 0xCC, 0x3A, 0xB3, 0x49, 0x99, 0x70,
        0x19, 0x50, 0xAB, 0xF6, 0x7F, 0xF6, 0x55, 0x1A,
        0xCA, 0x2D, 0xA0, 0x73, 0x50, 0xE0, 0x9C, 0xEE,
        0x07, 0xEC, 0x37, 0x26, 0x6B, 0xAA, 0xA5, 0x34,
        0xFD, 0x7B, 0x1A, 0x92, 0x4E, 0xE7, 0x36, 0x1A,
        0xEB, 0x35, 0xCC, 0x5A, 0x5C, 0x06, 0x7F, 0x77,
        0xCE, 0x52, 0x33, 0x57, 0x73, 0x9D, 0xEC, 0x2D,
        0x28, 0x0C, 0xC9, 0xBF, 0x06, 0x9E, 0xA7, 0x7C,
        0x36, 0xF9, 0x0B, 0xC6, 0x7F, 0x0F, 0x66, 0x24,
        0x65, 0x2D, 0x30, 0x2B, 0xD7, 0x7F, 0x07, 0xD3,
        0x57, 0xC8, 0x4B, 0xC3, 0x0C, 0xA3, 0x5B, 0xAA,
        0xAF, 0xEA, 0xF3, 0xA3, 0x9E, 0x9E, 0xD4, 0x63,
        0xCD, 0x82, 0x8B, 0xBC, 0x5D, 0xEF, 0xE6, 0x2A,
        0x4D, 0x5B, 0x95, 0x13, 0x17, 0x98, 0xD3, 0x67,
        0x66, 0x04, 0x9E, 0x71, 0x71, 0xE6, 0xBD, 0x44,
        0x15, 0x6B, 0x29, 0x76, 0xE4, 0x62, 0x01, 0x99,
        0xEB, 0xF4, 0x2E, 0x14, 0x29, 0x0D, 0xBF, 0x8A,
        0x02, 0x30, 0x4A, 0xE7, 0x0D, 0x25, 0x42, 0x9E,
        0xD7, 0x0C, 0xAD, 0x30, 0xC6, 0xA3, 0x49, 0xF9,
        0x90, 0x0C, 0x46, 0x5B, 0x77, 0x67, 0x5F, 0x0B,
        0xE9, 0xA9, 0xFE, 0xFA, 0xC8, 0x5F, 0x19, 0xF7,
        0x35, 0x09, 0xF7, 0xB5, 0x6D, 0x51, 0x32, 0x17,
        0xBE, 0xE6, 0xC3, 0xBE, 0x4A, 0x9A, 0x33, 0xDA,
        0xC6, 0x90, 0xB7, 0xA7, 0x6F, 0x97, 0x9E, 0xD5,
        0x80, 0xE5, 0x02, 0x9E, 0x58, 0xD6, 0x45, 0x34,
        0x4D, 0x61, 0x71, 0x19, 0x07, 0x69, 0x1F, 0xAF,
        0xFF, 0x9F, 0xDE, 0x97, 0x13, 0xA1, 0xDF, 0x47,
        0x0E, 0x8B, 0xD6, 0xD0, 0x75, 0x40, 0x08, 0x59,
        0x7D, 0xFB, 0x74, 0x74, 0xF2, 0x48, 0xF4, 0x23,
        0x1B, 0x5E, 0x18, 0x4E, 0x2D, 0x2D, 0xC5, 0x40,
        0xD0, 0x90, 0x4F, 0x95, 0x69, 0xC4, 0xDA, 0xFB,
        0x39, 0x4B, 0x12, 0x7D, 0x22, 0x1E, 0x9A, 0x68,
        0x5B, 0x68, 0x2E, 0x47, 0x23, 0xB9, 0x6A, 0xBF,
        0xF7, 0xE2, 0x56, 0x79, 0xDD, 0x7A, 0x72, 0xF9,
        0x5F, 0x20, 0x6B, 0x29, 0x56, 0xEE, 0x04, 0x11,
        0x4C, 0x16, 0x34, 0x04, 0x14, 0x54, 0xB5, 0x21,
        0xAA, 0x6A, 0x46, 0x40, 0xE4, 0xF1, 0x78, 0x7C,
        0x50, 0xF3, 0x4D, 0xBC, 0x57, 0x34, 0x7C, 0x6A,
        0xBD, 0x9B, 0xEF, 0x03, 0x80, 0x7D, 0xAB, 0x20,
        0x0F, 0x77, 0x87, 0x6F, 0x93, 0xFB, 0x24, 0x20,
        0x82, 0xC7, 0x7E, 0xFB, 0x43, 0x2D, 0xC6, 0xD4,
        0xE9, 0x27, 0x8C, 0x66, 0xA8, 0x5A, 0x58, 0xC8,
        0xD8, 0x9A, 0xA8, 0x50, 0x5F, 0x3A, 0x3D, 0x0B,
        0xC3, 0x4F, 0xCE, 0x94, 0xE0, 0x0D, 0x16, 0xCB,
        0x20, 0xE0, 0xF5, 0x1A, 0x13, 0x6E, 0x28, 0xA6,
        0x42, 0xB2, 0xB1, 0x30, 0x1D, 0x56, 0x28, 0xCD,
        0xF3, 0x4E, 0xA7, 0x3E, 0x74, 0x04, 0x7D, 0xA5,
        0x86, 0xD9, 0x1A, 0xDF, 0x07, 0xBC, 0x2C, 0x59,
        0xB1, 0x91, 0x6D, 0x9B, 0xA2, 0xD0, 0x72, 0xE7,
        0xA5, 0x56, 0x4A, 0x27, 0x56, 0x1F, 0x65, 0xCD,
        0x90, 0x7B, 0xB7, 0x5A, 0x51, 0x25, 0x75, 0x1B,
        0xD9, 0xD4, 0xC7, 0x19, 0x8A, 0xB0, 0x3D, 0x38,
        0x22, 0x61, 0xCF, 0xD9, 0x66, 0xED, 0xF5, 0xB8,
        0xF5, 0x86, 0xFF, 0x98, 0x1A, 0xB7, 0xFB, 0x67,
        0xED, 0x25, 0x52, 0xD9, 0x2F, 0x84, 0xDC, 0x96,
        0x89, 0x2C, 0x52, 0xCF, 0x5F, 0xA0, 0xEA, 0xD0,
        0xB3, 0x38, 0x98, 0xFC, 0xD7, 0x50, 0x84, 0xCF,
        0xA5, 0xE9, 0x53, 0x8B, 0x44, 0x38, 0xB5, 0x7D,
        0xD8, 0xAD, 0x0A, 0xE5, 0x35, 0x78, 0x29, 0xBF,
        0x9F, 0x6B, 0x2C, 0xBB, 0x97, 0x9D, 0xD3, 0x64,
        0x23, 0x2B, 0xA8, 0xA4, 0x71, 0xE3, 0xF1, 0x2F,
        0x61, 0xC9, 0x68, 0xD2, 0x06, 0xD0, 0x4E, 0x87,
        0x03, 0x99, 0xCC, 0xB1, 0x83, 0xB6, 0x94, 0x61,
        0x3C, 0xE9, 0xE0, 0x7D, 0x13, 0xAF, 0xCF, 0xE4,
        0xA6, 0x42, 0x7F, 0x62, 0x8F, 0xFC, 0x10, 0xF1,
        0x08, 0x4D, 0x1D, 0xFC, 0x0F, 0x37, 0x11, 0xBE,
        0xD7, 0xF1, 0x80, 0x46, 0xAF, 0xFA, 0x13, 0x65,
        0x99, 0xAE, 0xF9, 0xD0, 0x13, 0xA7, 0xC7, 0x3A,
        0xD2, 0xC1, 0x9B, 0x5A, 0xB8, 0xC3, 0x08, 0x13,
        0x49, 0x40, 0x33, 0x0D, 0x1F, 0x93, 0x5D, 0x10,
        0x49, 0x3E, 0x4F, 0x90, 0x34, 0xC5, 0xEA, 0xF7,
        0x24, 0xFF, 0xF3, 0xC5, 0x95, 0xF7, 0x1F, 0x13,
        0x9A, 0xE0, 0x0C, 0xCD, 0x61, 0x93, 0x39, 0xE6,
        0xAF, 0xD5, 0x3E, 0xA9, 0xD8, 0xC4, 0x8F, 0x64,
        0x05, 0x09, 0x45, 0x2A, 0xEB, 0x12, 0xC5, 0x51,
        0x58, 0x1C, 0x55, 0x20, 0xE9, 0x29, 0x74, 0xC7,
        0x10, 0x01, 0xF3, 0xA4, 0x56, 0xB4, 0x14, 0xFE,
        0x9C, 0x10, 0x2F, 0xF8, 0xBF, 0xB5, 0x9C, 0x6E,
        0xBB, 0xE6, 0x52, 0xE7, 0xAC, 0xA7, 0xCE, 0x41,
        0x6E, 0x00, 0x66, 0x0A, 0x2F, 0x46, 0x71, 0xB8,
        0x8F, 0x45, 0x89, 0x26, 0x68, 0xCD, 0x49, 0xDF,
        0xCB, 0xCD, 0xD6, 0x66, 0xC6, 0xA7, 0x8E, 0xB3,
        0xE4, 0x72, 0xEF, 0xBA, 0xA6, 0x6D, 0x7A, 0xB7,
        0xE9, 0xD9, 0xB2, 0x60, 0xB5, 0x82, 0x77, 0x20,
        0x2A, 0xFA, 0xE3, 0xCB, 0xF5, 0x30, 0x50, 0x30,
        0xC6, 0x19, 0x67, 0xA8, 0xB8, 0xFA, 0xFE, 0xB6,
        0xDA, 0xB6, 0xB6, 0xBF, 0x07, 0x90, 0x40, 0xD8,
        0x5B, 0x15, 0x48, 0x39, 0xCD, 0x99, 0x0F, 0x3A,
        0x28, 0xD2, 0x2E, 0xBA, 0xAC, 0x6D, 0xA3, 0xF8,
        0x53, 0x88, 0xF0, 0x86, 0x87, 0x70, 0xF5, 0x07,
        0xD2, 0x99, 0xC4, 0xCA, 0xDD, 0xD8, 0x8C, 0xEB,
        0x00, 0x96, 0xB4, 0x62, 0xA3, 0x7B, 0x79, 0x31,
        0xB2, 0x85, 0xB0, 0x61, 0x39, 0xF2, 0xBC, 0x1D,
        0x31, 0xC3, 0x0C, 0x7F, 0x70, 0x9A, 0x63, 0x74,
        0xC6, 0xCB, 0xD3, 0x93, 0x0D, 0x43, 0x7F, 0x80,
        0x85, 0x87, 0x72, 0x98, 0xE1, 0x6E, 0x9A, 0x59,
        0x2E, 0x6C, 0xA8, 0x9E, 0xC2, 0xC0, 0x72, 0xFE,
        0x26, 0xE8, 0xAF, 0x89, 0x61, 0xCA, 0x0D, 0x15,
        0xCC, 0xB0, 0xBA, 0x10, 0xB8, 0x9D, 0x77, 0x2C,
        0x6C, 0x28, 0xCC, 0x70, 0x5B, 0x1F, 0x5D, 0x68,
        0xD4, 0xC8, 0x1F, 0x0F, 0x67, 0xF5, 0x3E, 0x5C,
        0x70, 0x50, 0x4B, 0x32, 0x12, 0xE6, 0x1A, 0xCE,
        0xB8, 0x32, 0x5F, 0x1D, 0xC5, 0xFB, 0x07, 0x77,
        0xAD, 0x85, 0x45, 0x95, 0x04, 0x0D, 0x94, 0x7A,
        0x1F, 0xDD, 0x05, 0x74, 0x14, 0xA5, 0x9A, 0x66,
        0xF4, 0x93, 0xBE, 0xF2, 0xA9, 0x5B, 0xCD, 0xAB,
        0xC7, 0x82, 0xF7, 0xE7, 0x4A, 0x1C, 0x90, 0x6B,
        0x9A, 0xBD, 0x93, 0xDD, 0x41, 0x56, 0xDA, 0xA5,
        0x0F, 0x5D, 0x57, 0x2C, 0xBA, 0x07, 0x07, 0x4B,
        0x91, 0x33, 0xE6, 0x1B, 0x0E, 0x25, 0x9E, 0x36,
        0xBF, 0xCA, 0x21, 0xCE, 0xC6, 0x82, 0x33, 0x4D,
        0x42, 0x4F, 0x2E, 0x71, 0xC2, 0xE7, 0x6F, 0x16,
        0xF6, 0xB7, 0x30, 0x1C, 0xA1, 0xA8, 0xE3, 0xE7,
        0xB1, 0x71, 0xDD, 0x9F, 0x90, 0x1F, 0x01, 0x1D,
        0x0A, 0xBD, 0x2C, 0x4A, 0x22, 0x84, 0x5C, 0xBF,
        0x61, 0x07, 0x24, 0xC4, 0x0D, 0x23, 0xDB, 0xC6,
        0x28, 0xB1, 0x27, 0xCB, 0x7E, 0x06, 0xF8, 0x3C,
        0x42, 0xF9, 0x51, 0x2F, 0x21, 0xC5, 0x80, 0x98,
        0x08, 0x2F, 0x56, 0x58, 0xD7, 0xE0, 0xDA, 0xC4,
        0x24, 0x0C, 0xE8, 0xFA, 0x94, 0x23, 0x57, 0xA6,
        0xD8, 0xE2, 0xC5, 0xCC, 0x16, 0x70, 0x55, 0x57,
        0xC4, 0x52, 0x2D, 0x94, 0xCE, 0x5B, 0x22, 0x8E,
        0x6C, 0x3D, 0x8E, 0x74, 0x9D, 0xFD, 0x47, 0xC7,
        0x42, 0x11, 0x41, 0x9F, 0x6A, 0x0A, 0xF6, 0x16,
        0x97, 0xB1, 0x24, 0xC4, 0x6C, 0x98, 0xF8, 0x62,
        0x51, 0xE9, 0x67, 0x6D, 0x39, 0x2B, 0x76, 0x19,
        0x5F, 0x41, 0xF4, 0x82, 0x51, 0x87, 0xFF, 0xAA,
        0x87, 0xE3, 0x46, 0x87, 0xC0, 0xC9, 0xBB, 0xB5,
        0xAC, 0xA0, 0xD1, 0x56, 0x54, 0xC2, 0x2C, 0x59,
        0x9E, 0x78, 0xF9, 0xA6, 0xBA, 0xCB, 0xE2, 0x45,
        0x8A, 0xC1, 0xE5, 0xDF, 0xC3, 0x81, 0x91, 0xDB,
        0xDB, 0x9E, 0xE2, 0x9C, 0xB9, 0x44, 0x5F, 0x5D,
        0x6D, 0x83, 0x8D, 0x2D, 0x3E, 0x72, 0x2F, 0x98,
        0xFC, 0xFA, 0x5F, 0xC0, 0xF0, 0x03, 0x4A, 0x42,
        0x19, 0x67, 0x48, 0x24, 0x70, 0x35, 0xAE, 0x37,
        0x34, 0x27, 0xAB, 0xD6, 0x92, 0xB8, 0xB4, 0x52,
        0xC9, 0xD1, 0xF0, 0x5C, 0xAC, 0xFA, 0xB9, 0x2D,
        0xCE, 0xF2, 0x24, 0xE3, 0x53, 0xF4, 0x2D, 0x65,
        0x8D, 0xBF, 0x27, 0x3F, 0xAF, 0x62, 0xE0, 0x27,
        0xBE, 0x12, 0xCB, 0x40, 0xA4, 0x99, 0xAF, 0x47,
        0x19, 0x5F, 0x68, 0x69, 0x7F, 0x8C, 0xD2, 0x1E,
        0x4A, 0xA1, 0xA4, 0x3D, 0x5A, 0x62, 0x6F, 0x78,
        0x87, 0x8E, 0xA0, 0xC0, 0xF3, 0x2C, 0x60, 0xC3,
        0xCE, 0xDD, 0xED, 0x7C, 0xAF, 0xE0, 0x0B, 0x72,
        0x9D, 0xBA, 0xC6, 0xEE, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
        0x0B, 0x15, 0x1B, 0x1E, 0x24
    };
#endif
#ifndef WOLFSSL_NO_ML_DSA_87
    static const byte sk_87[] = {
        0xF1, 0x79, 0x16, 0xD9, 0x5C, 0x51, 0x2F, 0xEC,
        0x0C, 0xEF, 0xA6, 0xA1, 0x5C, 0x9F, 0xB3, 0xBF,
        0x84, 0xFF, 0x8D, 0x7F, 0xA3, 0x55, 0x22, 0xEB,
        0x1C, 0x91, 0x5C, 0x4D, 0x25, 0x4E, 0x89, 0x35,
        0x24, 0x8E, 0x3C, 0x08, 0x58, 0x2B, 0x74, 0x5E,
        0xB2, 0xFD, 0x13, 0x15, 0x2B, 0x5D, 0xAE, 0xEA,
        0xB0, 0x72, 0x80, 0x42, 0xB0, 0x08, 0x85, 0xBB,
        0x92, 0xF8, 0x44, 0xA8, 0x6B, 0x42, 0x62, 0x03,
        0x5C, 0x9F, 0x44, 0x8A, 0x2B, 0x78, 0xEF, 0x5D,
        0xB3, 0x47, 0xE0, 0x25, 0x04, 0x15, 0xE1, 0x01,
        0x5F, 0xBB, 0x34, 0x31, 0x91, 0x24, 0x07, 0xC8,
        0x5A, 0x2F, 0x36, 0x2A, 0x85, 0xA9, 0xAE, 0x42,
        0x77, 0x23, 0xBF, 0x62, 0x69, 0x7B, 0x77, 0x99,
        0x1B, 0x3E, 0x93, 0xA3, 0x81, 0x13, 0x3F, 0x95,
        0x0D, 0x40, 0xE7, 0xC1, 0xAC, 0xBC, 0x17, 0xE4,
        0xF1, 0xD1, 0x0C, 0xD1, 0x27, 0x4C, 0x8D, 0x3C,
        0x84, 0x02, 0x02, 0x0A, 0xC5, 0x10, 0x1C, 0xC3,
        0x4D, 0xD0, 0x94, 0x70, 0x24, 0xC0, 0x89, 0x94,
        0x08, 0x4D, 0xC2, 0x30, 0x20, 0x63, 0xC0, 0x24,
        0xE1, 0x80, 0x40, 0xD0, 0x26, 0x68, 0x10, 0x97,
        0x01, 0x83, 0xC2, 0x91, 0x5A, 0x90, 0x2D, 0x44,
        0x94, 0x6D, 0x10, 0x09, 0x50, 0x11, 0xA7, 0x0D,
        0xE4, 0x04, 0x89, 0x9B, 0x80, 0x8D, 0x40, 0xB8,
        0x45, 0x4B, 0x86, 0x0D, 0xC8, 0xB6, 0x05, 0xC0,
        0xC0, 0x71, 0x02, 0x09, 0x06, 0xA2, 0x00, 0x2D,
        0x0B, 0x24, 0x86, 0xA0, 0x90, 0x11, 0x20, 0x16,
        0x82, 0x1B, 0x24, 0x42, 0xCB, 0xB6, 0x70, 0x43,
        0x36, 0x05, 0xDA, 0x16, 0x25, 0x9A, 0x34, 0x6C,
        0xCB, 0xB4, 0x08, 0xC4, 0x16, 0x90, 0x24, 0x29,
        0x6C, 0x42, 0x90, 0x04, 0x24, 0x06, 0x46, 0x84,
        0x12, 0x6D, 0xC2, 0x26, 0x00, 0x88, 0x40, 0x02,
        0x51, 0xC8, 0x40, 0x9C, 0x16, 0x24, 0x82, 0x18,
        0x26, 0x21, 0x06, 0x0C, 0x12, 0xC2, 0x71, 0x50,
        0x98, 0x91, 0x4A, 0x40, 0x28, 0x48, 0x48, 0x21,
        0x5A, 0x18, 0x49, 0x1B, 0xB7, 0x01, 0x5A, 0xC6,
        0x48, 0xA1, 0x90, 0x2C, 0x14, 0x18, 0x2D, 0xD2,
        0x20, 0x62, 0xDC, 0xB6, 0x49, 0x00, 0x09, 0x6D,
        0x40, 0xA8, 0x4D, 0x24, 0xC8, 0x24, 0x4C, 0x06,
        0x08, 0x80, 0x40, 0x4E, 0xD3, 0x18, 0x88, 0x12,
        0x09, 0x91, 0x8B, 0x12, 0x31, 0xC9, 0x16, 0x04,
        0x64, 0x10, 0x72, 0xDA, 0x84, 0x91, 0x92, 0xC6,
        0x65, 0x22, 0x10, 0x48, 0x18, 0xC9, 0x00, 0x14,
        0x44, 0x62, 0x24, 0xC1, 0x60, 0x40, 0xC6, 0x10,
        0x4A, 0x48, 0x28, 0x9B, 0x44, 0x66, 0x91, 0x10,
        0x52, 0xD3, 0x26, 0x52, 0xD8, 0xA6, 0x0C, 0x0A,
        0xA8, 0x44, 0xD8, 0x26, 0x0C, 0x64, 0x86, 0x45,
        0x44, 0x20, 0x00, 0xD2, 0x48, 0x85, 0xDC, 0x46,
        0x32, 0xC8, 0x22, 0x45, 0x5B, 0x00, 0x8D, 0x20,
        0xA5, 0x45, 0x01, 0xC1, 0x91, 0xA2, 0x12, 0x84,
        0x20, 0x47, 0x0E, 0x98, 0xA8, 0x25, 0xD9, 0xA0,
        0x4D, 0xA4, 0x06, 0x2D, 0x5B, 0xB0, 0x08, 0x21,
        0xB0, 0x80, 0x4C, 0x10, 0x2C, 0xC4, 0x98, 0x71,
        0x99, 0x24, 0x24, 0xA4, 0x36, 0x71, 0x4B, 0xB6,
        0x49, 0xE1, 0x92, 0x00, 0x09, 0x92, 0x4C, 0x89,
        0x12, 0x49, 0x1A, 0x39, 0x2A, 0xE0, 0x22, 0x69,
        0x61, 0xB2, 0x50, 0x40, 0x26, 0x8E, 0xC9, 0xA2,
        0x08, 0x0A, 0x90, 0x24, 0x13, 0x35, 0x06, 0x21,
        0x24, 0x62, 0x60, 0xB0, 0x01, 0xE3, 0xC6, 0x29,
        0x5B, 0x28, 0x89, 0x20, 0x90, 0x70, 0xC4, 0xA4,
        0x31, 0x08, 0x42, 0x11, 0x10, 0xC0, 0x71, 0x98,
        0x98, 0x20, 0xC4, 0xA8, 0x29, 0x1A, 0x15, 0x32,
        0xC4, 0x86, 0x6C, 0x18, 0x14, 0x6A, 0x02, 0x46,
        0x46, 0xDC, 0xC2, 0x4C, 0x81, 0x02, 0x6D, 0x49,
        0x16, 0x48, 0x10, 0x94, 0x6C, 0x0A, 0x85, 0x90,
        0x9C, 0x34, 0x84, 0x54, 0x24, 0x25, 0x49, 0xA8,
        0x21, 0x04, 0xA6, 0x2C, 0x61, 0x00, 0x01, 0x61,
        0x46, 0x92, 0xE0, 0xA6, 0x44, 0xE2, 0x00, 0x90,
        0xC8, 0x06, 0x06, 0x90, 0xB8, 0x2D, 0x0B, 0x85,
        0x85, 0x20, 0x23, 0x0D, 0x83, 0x94, 0x04, 0x54,
        0x26, 0x50, 0x41, 0x92, 0x29, 0x09, 0x16, 0x20,
        0x54, 0xC6, 0x2D, 0x81, 0xC8, 0x8C, 0x09, 0x44,
        0x44, 0xE2, 0x06, 0x30, 0x13, 0x92, 0x49, 0x0B,
        0x17, 0x48, 0x93, 0x28, 0x86, 0xD8, 0xA4, 0x50,
        0xD1, 0x32, 0x91, 0x08, 0xB8, 0x05, 0xA4, 0x02,
        0x62, 0x01, 0x15, 0x82, 0xE3, 0x18, 0x42, 0x83,
        0xC6, 0x44, 0x43, 0x02, 0x81, 0x53, 0x88, 0x04,
        0x04, 0x98, 0x31, 0x19, 0x18, 0x46, 0xDB, 0x02,
        0x89, 0x10, 0x23, 0x81, 0x03, 0x90, 0x71, 0x83,
        0x26, 0x89, 0x1A, 0x01, 0x05, 0xCA, 0xB0, 0x01,
        0x4C, 0x84, 0x09, 0x10, 0x11, 0x84, 0x13, 0xB1,
        0x20, 0x61, 0xB8, 0x41, 0x1B, 0x02, 0x8C, 0x09,
        0x98, 0x61, 0x83, 0x18, 0x61, 0x08, 0xC1, 0x6D,
        0x44, 0x86, 0x09, 0xCB, 0x88, 0x8D, 0x93, 0xB4,
        0x41, 0x58, 0x90, 0x81, 0x04, 0x31, 0x08, 0xD1,
        0xC4, 0x04, 0x19, 0xB4, 0x4C, 0x1C, 0x88, 0x20,
        0xCA, 0x30, 0x72, 0x1C, 0xB5, 0x85, 0x13, 0x27,
        0x32, 0x84, 0xB4, 0x44, 0x04, 0x42, 0x20, 0x61,
        0x18, 0x52, 0x50, 0x96, 0x44, 0x03, 0x38, 0x86,
        0xE3, 0x48, 0x31, 0x02, 0x82, 0x68, 0x98, 0x06,
        0x90, 0x23, 0x28, 0x04, 0x10, 0x18, 0x0D, 0x10,
        0x28, 0x45, 0x4C, 0x84, 0x6C, 0x09, 0x36, 0x71,
        0x82, 0x26, 0x64, 0x18, 0xC6, 0x21, 0x90, 0x18,
        0x22, 0x0A, 0x37, 0x08, 0xC4, 0x94, 0x28, 0xE2,
        0x30, 0x2C, 0x92, 0xB4, 0x24, 0x63, 0x46, 0x70,
        0x52, 0x96, 0x0C, 0x8B, 0xA4, 0x05, 0xD3, 0x02,
        0x85, 0x09, 0x32, 0x92, 0x49, 0x12, 0x21, 0x18,
        0x43, 0x28, 0x01, 0x32, 0x45, 0x0B, 0xA5, 0x50,
        0x14, 0x16, 0x65, 0x91, 0x80, 0x65, 0x0A, 0x44,
        0x66, 0x13, 0xB6, 0x4C, 0x01, 0x38, 0x71, 0x11,
        0x49, 0x28, 0x22, 0x43, 0x02, 0x0B, 0x34, 0x04,
        0x01, 0x16, 0x91, 0x80, 0x14, 0x0E, 0x12, 0x93,
        0x01, 0x00, 0x11, 0x80, 0xDC, 0x28, 0x51, 0x11,
        0x87, 0x85, 0xC1, 0x34, 0x28, 0x02, 0xA2, 0x11,
        0x02, 0x38, 0x44, 0x52, 0x14, 0x64, 0xC2, 0xA0,
        0x01, 0x1B, 0x42, 0x8C, 0xC2, 0xB2, 0x71, 0xCB,
        0x16, 0x00, 0xCC, 0x10, 0x21, 0x04, 0x12, 0x52,
        0x84, 0x24, 0x2A, 0xD3, 0x48, 0x12, 0x08, 0x44,
        0x08, 0x81, 0x88, 0x44, 0x01, 0x23, 0x50, 0xC0,
        0xA2, 0x09, 0x81, 0x94, 0x50, 0x02, 0x89, 0x61,
        0x01, 0x31, 0x88, 0x1B, 0xA2, 0x61, 0x90, 0x94,
        0x84, 0x91, 0x24, 0x09, 0x03, 0x18, 0x22, 0xA3,
        0x46, 0x60, 0x10, 0x16, 0x4D, 0x48, 0x84, 0x89,
        0x11, 0x00, 0x2E, 0xCC, 0xC0, 0x40, 0x8C, 0xC0,
        0x51, 0xE4, 0x42, 0x62, 0xDA, 0x24, 0x11, 0x13,
        0x19, 0x46, 0x93, 0x34, 0x4C, 0x42, 0x42, 0x24,
        0xC4, 0x48, 0x90, 0x00, 0x35, 0x80, 0x1B, 0x98,
        0x51, 0x0B, 0x41, 0x60, 0x0C, 0x25, 0x46, 0x9A,
        0xA8, 0x89, 0x12, 0x86, 0x4C, 0xE3, 0x16, 0x09,
        0x14, 0x27, 0x24, 0x51, 0x26, 0x4D, 0x1B, 0x02,
        0x10, 0x00, 0x17, 0x28, 0xD4, 0xA8, 0x45, 0x48,
        0x88, 0x48, 0x01, 0xC7, 0x0D, 0x93, 0xC8, 0x40,
        0x5B, 0x02, 0x49, 0x51, 0x02, 0x4A, 0x01, 0x42,
        0x10, 0xE1, 0x08, 0x90, 0x03, 0x85, 0x48, 0x11,
        0xA8, 0x68, 0x8B, 0x90, 0x08, 0x5A, 0x02, 0x0C,
        0x5A, 0x18, 0x50, 0x11, 0x87, 0x51, 0x9C, 0x38,
        0x92, 0xD0, 0x44, 0x82, 0x10, 0x33, 0x21, 0x88,
        0x44, 0x2D, 0x24, 0x28, 0x0D, 0x22, 0xA3, 0x30,
        0x49, 0x88, 0x25, 0xA1, 0xB2, 0x01, 0x5C, 0x40,
        0x20, 0x1C, 0x03, 0x72, 0xCC, 0x96, 0x8C, 0x51,
        0xA6, 0x88, 0xE3, 0x92, 0x08, 0x13, 0xB0, 0x08,
        0x5C, 0x38, 0x44, 0x03, 0x47, 0x8E, 0x93, 0x12,
        0x4A, 0x88, 0x20, 0x48, 0xE0, 0x42, 0x20, 0x81,
        0x90, 0x09, 0x4B, 0x06, 0x6D, 0xD2, 0x90, 0x10,
        0x01, 0x82, 0x49, 0x19, 0x28, 0x91, 0xDA, 0x20,
        0x2A, 0x20, 0x85, 0x40, 0x0A, 0x16, 0x8A, 0x1C,
        0x83, 0x60, 0xCA, 0x48, 0x4A, 0xA2, 0xC8, 0x50,
        0xE4, 0x02, 0x31, 0x88, 0x86, 0x88, 0x53, 0x00,
        0x89, 0x60, 0x08, 0x8A, 0xA2, 0x02, 0x0A, 0x0A,
        0x34, 0x45, 0x03, 0x04, 0x42, 0x1B, 0x40, 0x09,
        0x89, 0xA0, 0x69, 0x42, 0x18, 0x49, 0x4A, 0xA8,
        0x8C, 0x99, 0x90, 0x30, 0xCA, 0x38, 0x91, 0x09,
        0x31, 0x72, 0x8B, 0x44, 0x29, 0x52, 0xA2, 0x8D,
        0x08, 0x14, 0x6E, 0xA1, 0x84, 0x50, 0x1C, 0x31,
        0x46, 0x19, 0xB7, 0x01, 0xCC, 0x06, 0x29, 0x11,
        0x09, 0x20, 0x4B, 0x40, 0x66, 0x40, 0xC4, 0x49,
        0x00, 0x13, 0x24, 0xD0, 0xA2, 0x84, 0xCA, 0x16,
        0x29, 0xD0, 0xC0, 0x84, 0xC8, 0x88, 0x44, 0xE1,
        0x20, 0x29, 0x1A, 0x97, 0x05, 0x90, 0x42, 0x90,
        0x04, 0x40, 0x71, 0x9C, 0x32, 0x4E, 0x64, 0x26,
        0x22, 0x93, 0x36, 0x66, 0xD3, 0x06, 0x49, 0xA3,
        0x26, 0x51, 0x4C, 0xA6, 0x89, 0x84, 0x36, 0x84,
        0x93, 0x46, 0x6D, 0x14, 0x07, 0x8D, 0x18, 0x29,
        0x42, 0x52, 0x34, 0x72, 0x44, 0x10, 0x90, 0x12,
        0x37, 0x81, 0xD4, 0x10, 0x64, 0x04, 0xA5, 0x08,
        0x84, 0x24, 0x09, 0x1C, 0x08, 0x8D, 0x02, 0x99,
        0x6C, 0x1B, 0x30, 0x50, 0x09, 0x89, 0x81, 0x19,
        0x30, 0x48, 0x5B, 0x14, 0x4D, 0xD9, 0x20, 0x20,
        0x0C, 0x01, 0x2A, 0x00, 0x90, 0x4D, 0xA1, 0x02,
        0x64, 0x1C, 0x03, 0x01, 0xC2, 0x26, 0x8C, 0x14,
        0x08, 0x45, 0xE3, 0x12, 0x48, 0x09, 0x20, 0x09,
        0x41, 0x40, 0x61, 0x90, 0x44, 0x21, 0x49, 0x06,
        0x91, 0x4B, 0xC0, 0x84, 0x22, 0x95, 0x51, 0x23,
        0x38, 0x0E, 0x5C, 0x28, 0x70, 0xC2, 0x40, 0x2C,
        0x94, 0x18, 0x62, 0x9A, 0x30, 0x4A, 0xE2, 0x86,
        0x4C, 0x5C, 0x10, 0x8D, 0xC2, 0x12, 0x21, 0x9C,
        0xC4, 0x4D, 0xD9, 0x96, 0x88, 0x0C, 0x29, 0x45,
        0x1B, 0x45, 0x6A, 0x1A, 0x00, 0x60, 0x91, 0x30,
        0x0C, 0x12, 0x00, 0x69, 0xA2, 0xA0, 0x04, 0x81,
        0x00, 0x65, 0x5C, 0x38, 0x8A, 0x18, 0x05, 0x89,
        0x48, 0x32, 0x24, 0x81, 0xC6, 0x4D, 0x60, 0x90,
        0x31, 0x83, 0x22, 0x12, 0xE1, 0xC2, 0x6C, 0x89,
        0x00, 0x90, 0x14, 0xB4, 0x40, 0xD3, 0xB8, 0x45,
        0x89, 0x24, 0x70, 0x09, 0x26, 0x6C, 0xD9, 0x32,
        0x8A, 0x83, 0x44, 0x0E, 0x21, 0x44, 0x61, 0x99,
        0xA4, 0x20, 0x44, 0x16, 0x2E, 0x1A, 0xC2, 0x08,
        0x09, 0x98, 0x6C, 0x8C, 0x18, 0x8C, 0x0C, 0x30,
        0x62, 0x8B, 0x46, 0x45, 0x80, 0x10, 0x21, 0x20,
        0x33, 0x32, 0x5A, 0x38, 0x4C, 0x98, 0x06, 0x45,
        0x1A, 0x33, 0x09, 0x82, 0x34, 0x44, 0x02, 0x20,
        0x09, 0x59, 0x00, 0x41, 0x08, 0x13, 0x08, 0xDC,
        0x18, 0x68, 0x12, 0x47, 0x86, 0x43, 0xB8, 0x21,
        0x62, 0x02, 0x8D, 0x5C, 0x10, 0x0D, 0x60, 0x96,
        0x65, 0xA2, 0x22, 0x4C, 0x83, 0x18, 0x09, 0x41,
        0x08, 0x41, 0x63, 0xC2, 0x80, 0x13, 0x81, 0x65,
        0x22, 0x03, 0x92, 0x04, 0xA9, 0x4D, 0x1C, 0xB0,
        0x44, 0x80, 0xC6, 0x24, 0x00, 0x01, 0x44, 0x22,
        0x11, 0x80, 0x21, 0x95, 0x64, 0x09, 0x99, 0x8C,
        0xD3, 0x14, 0x4A, 0xD1, 0x98, 0x2D, 0x19, 0x31,
        0x4C, 0x0A, 0x92, 0x40, 0x13, 0x98, 0x48, 0x14,
        0x89, 0x20, 0x23, 0xB3, 0x0D, 0x14, 0x98, 0x6D,
        0x12, 0x98, 0x05, 0x9B, 0x14, 0x06, 0x5B, 0x26,
        0x91, 0x0A, 0x38, 0x09, 0x08, 0x98, 0x2C, 0x19,
        0xA0, 0x45, 0x44, 0x26, 0x00, 0x0A, 0x05, 0x21,
        0xDB, 0xA0, 0x69, 0x51, 0x42, 0x92, 0x0B, 0x43,
        0x00, 0xD1, 0x42, 0x0D, 0x81, 0x30, 0x28, 0x13,
        0xC2, 0x20, 0x03, 0x27, 0x60, 0x10, 0x83, 0x91,
        0x0A, 0x53, 0x7E, 0xA1, 0x4F, 0x11, 0x54, 0x5E,
        0x25, 0x4F, 0xCF, 0x28, 0x03, 0x95, 0x2A, 0x58,
        0x0A, 0x4B, 0x6C, 0x9B, 0x29, 0x10, 0x3D, 0x97,
        0x43, 0x6C, 0x00, 0x3E, 0x2E, 0xCE, 0xAE, 0x20,
        0x28, 0x01, 0x7F, 0xF1, 0xD5, 0x18, 0xB0, 0xB5,
        0xD5, 0xE6, 0x24, 0x26, 0x64, 0xED, 0x33, 0x7C,
        0xCA, 0x45, 0x26, 0xED, 0x5D, 0xB5, 0xEA, 0xD8,
        0xBB, 0x31, 0x16, 0x94, 0x1C, 0xD0, 0xC8, 0xF0,
        0xA7, 0xED, 0x5A, 0x1A, 0x5A, 0x00, 0xB9, 0x8C,
        0x33, 0x6A, 0x9B, 0xC8, 0xEB, 0x6B, 0x3A, 0x30,
        0x83, 0x16, 0xF1, 0x17, 0xEA, 0xA8, 0x0D, 0x4B,
        0x77, 0x56, 0xDD, 0x4A, 0x91, 0xDA, 0xA5, 0x8E,
        0x80, 0xD7, 0xB5, 0x77, 0x55, 0x83, 0x97, 0xAF,
        0x90, 0x5B, 0x67, 0xC5, 0x9F, 0x14, 0xE1, 0x2C,
        0x15, 0x8D, 0x29, 0x2C, 0xA6, 0xB6, 0x41, 0xED,
        0x0C, 0x75, 0xE3, 0x9A, 0x91, 0x4F, 0xFA, 0x1A,
        0x9F, 0x24, 0xCA, 0x28, 0xF2, 0x00, 0xC7, 0x48,
        0xDE, 0x70, 0x9D, 0x15, 0xD7, 0x22, 0xE7, 0xED,
        0x2C, 0x91, 0x8D, 0xEF, 0x08, 0xCF, 0xAF, 0x9B,
        0x7E, 0x24, 0xDE, 0xF2, 0xD5, 0x1A, 0x4D, 0x42,
        0x0E, 0x7E, 0x89, 0x06, 0xFA, 0xCD, 0x9A, 0x5A,
        0x98, 0xB0, 0xD1, 0xD5, 0x34, 0x5C, 0x8B, 0x9A,
        0xC0, 0xBB, 0xF4, 0xB1, 0x5E, 0xF0, 0xB4, 0x6A,
        0x8E, 0x3B, 0x6B, 0xAE, 0x0C, 0x6E, 0x9F, 0x09,
        0x2E, 0xB3, 0xEF, 0x1D, 0x49, 0x62, 0x0B, 0x65,
        0xE7, 0xDE, 0xDB, 0xEF, 0x68, 0x7E, 0xBD, 0x0E,
        0xA0, 0x95, 0x97, 0x2A, 0x56, 0xA0, 0xEA, 0xFB,
        0x2D, 0x75, 0xF4, 0x32, 0x1B, 0x80, 0xAC, 0xBC,
        0xA3, 0x2B, 0x1B, 0x11, 0xAA, 0x57, 0x6F, 0xE4,
        0xE0, 0xCC, 0xCC, 0x20, 0x52, 0x12, 0x65, 0x42,
        0x96, 0xF0, 0x60, 0x8F, 0xF3, 0x83, 0x69, 0xAF,
        0x19, 0x80, 0x75, 0x68, 0xDB, 0xE1, 0x71, 0xDB,
        0x79, 0xEB, 0x8C, 0x1C, 0xB7, 0x6A, 0x8E, 0xB9,
        0x5B, 0x28, 0x8C, 0x9D, 0xCC, 0x62, 0x0B, 0xEF,
        0xCE, 0x96, 0x06, 0x0F, 0x45, 0xA6, 0xA2, 0xDA,
        0xC2, 0x2F, 0x55, 0xE4, 0x7D, 0xC7, 0xBA, 0xB4,
        0xA7, 0x93, 0xD9, 0x65, 0x8F, 0xE2, 0x7C, 0x66,
        0x2C, 0xA6, 0x37, 0x00, 0x81, 0x30, 0xF1, 0x00,
        0xD9, 0x65, 0xB4, 0x78, 0x17, 0x7A, 0xC6, 0xDC,
        0x35, 0x93, 0x1A, 0x5E, 0xCC, 0x5F, 0x93, 0x31,
        0x22, 0x40, 0x2C, 0x17, 0x0E, 0xB8, 0xE0, 0xA4,
        0x1C, 0xB6, 0x3F, 0xE5, 0x60, 0x2F, 0x7B, 0x18,
        0xE1, 0xDB, 0xB6, 0xDB, 0x30, 0xA7, 0x61, 0x55,
        0xC6, 0xCF, 0x03, 0x0F, 0x73, 0x8D, 0xC0, 0x91,
        0x6D, 0xB1, 0x80, 0xF8, 0x3F, 0x02, 0x90, 0x93,
        0x11, 0xCB, 0x6B, 0x3B, 0x9E, 0x55, 0x3F, 0xAC,
        0xA0, 0x52, 0x23, 0xB3, 0x3C, 0x69, 0x60, 0x2D,
        0x0F, 0x05, 0xA0, 0x8B, 0xEB, 0x84, 0x80, 0x96,
        0x51, 0x99, 0x9A, 0x55, 0x26, 0xE7, 0x76, 0xF3,
        0xDE, 0x39, 0x30, 0x4A, 0x5F, 0xEF, 0x00, 0x95,
        0x0A, 0x9A, 0x81, 0x0D, 0x12, 0xE0, 0x1D, 0x15,
        0xD8, 0x86, 0xDB, 0x26, 0x75, 0xF6, 0x54, 0xCA,
        0x17, 0xFA, 0xAE, 0xEB, 0xD1, 0xF5, 0x61, 0xF9,
        0xD1, 0xA9, 0x5E, 0x0B, 0xAD, 0xF7, 0xC3, 0x31,
        0x5A, 0xFA, 0xBA, 0x8D, 0x4B, 0xEC, 0x1F, 0x05,
        0x42, 0xA8, 0xF1, 0x0A, 0xC6, 0x66, 0xFD, 0x8D,
        0x0C, 0x5A, 0xF1, 0xD6, 0x86, 0x7A, 0x9D, 0x82,
        0x6B, 0xFB, 0x6B, 0x03, 0x0B, 0x58, 0xEC, 0xEF,
        0x67, 0x78, 0xD2, 0xC5, 0x2B, 0xF6, 0x2C, 0xB3,
        0x4B, 0x81, 0xFF, 0x93, 0x6D, 0xA3, 0x3E, 0xDA,
        0xB3, 0x1D, 0xB3, 0x9A, 0xB7, 0x63, 0x66, 0xD0,
        0x94, 0x36, 0x2F, 0x04, 0x6D, 0x50, 0x78, 0xB4,
        0x22, 0x35, 0x04, 0xA1, 0x2B, 0xA0, 0xC7, 0xB8,
        0xE8, 0x83, 0x72, 0x77, 0x18, 0x50, 0x9B, 0xD4,
        0x7A, 0x69, 0x6E, 0xE9, 0x88, 0x0C, 0xAF, 0xF6,
        0x63, 0x61, 0x2B, 0x95, 0x86, 0x30, 0x3D, 0x6D,
        0xE0, 0xD2, 0x1F, 0x9A, 0x21, 0x96, 0x22, 0x78,
        0xEB, 0xCE, 0x60, 0xA6, 0xD4, 0x68, 0x44, 0x09,
        0x5C, 0x5F, 0x89, 0x2D, 0xAC, 0xA4, 0x8D, 0x78,
        0x28, 0x22, 0x45, 0x38, 0x34, 0xB4, 0xE4, 0x2C,
        0xD3, 0xA1, 0xFE, 0x39, 0x87, 0x35, 0x6E, 0xAB,
        0x11, 0xEF, 0xB8, 0xEE, 0xCD, 0x8E, 0x9C, 0xC8,
        0xF3, 0x9A, 0x0F, 0xF1, 0xFF, 0xB8, 0x06, 0x9A,
        0x44, 0x1F, 0x85, 0x1E, 0xB4, 0x38, 0xE9, 0xC0,
        0xB5, 0x7E, 0x88, 0x18, 0xA3, 0x22, 0x65, 0x1E,
        0x60, 0xF4, 0xB6, 0x78, 0x90, 0xE5, 0xED, 0x7A,
        0x0F, 0xBF, 0x75, 0x36, 0xC3, 0xFD, 0x50, 0xD0,
        0xB0, 0x65, 0x8D, 0x7C, 0xCF, 0x27, 0x5E, 0x8A,
        0x9E, 0x9F, 0xBB, 0x99, 0xBE, 0x2E, 0x5F, 0x5E,
        0x16, 0x7B, 0xE2, 0x90, 0xB7, 0xE9, 0x67, 0x32,
        0xF8, 0x9E, 0x40, 0xD7, 0x85, 0xAF, 0x25, 0xC1,
        0xBA, 0x61, 0xA7, 0x78, 0x6D, 0x3E, 0xF2, 0xD0,
        0xC1, 0x14, 0xD1, 0x04, 0x8E, 0x76, 0x46, 0xDF,
        0xA3, 0x03, 0x2B, 0xFB, 0x7A, 0x51, 0xA6, 0x36,
        0x05, 0xDC, 0xE3, 0xE1, 0xD8, 0x98, 0x95, 0x00,
        0xD6, 0xE5, 0x8E, 0x96, 0x05, 0x19, 0x93, 0x1D,
        0xAC, 0x9F, 0x14, 0xDD, 0xA4, 0x28, 0xF5, 0xA2,
        0xC9, 0xC7, 0x4D, 0x91, 0x6D, 0x90, 0x77, 0x07,
        0xB5, 0x3E, 0xB5, 0x2C, 0x44, 0xAD, 0x71, 0xD7,
        0x27, 0x82, 0x6E, 0xB2, 0xCA, 0x68, 0x07, 0x0A,
        0x6F, 0x0E, 0x47, 0xFA, 0x16, 0xE5, 0x2E, 0x96,
        0x29, 0xB7, 0xAA, 0x82, 0x41, 0xDA, 0xAB, 0xB1,
        0x94, 0x97, 0xA5, 0x82, 0x4E, 0x58, 0xD7, 0x26,
        0x75, 0xC3, 0xA6, 0x7E, 0x10, 0xA1, 0x19, 0xB2,
        0x74, 0xB8, 0x4D, 0x9B, 0xEE, 0x28, 0x71, 0x72,
        0x8E, 0xD2, 0xF9, 0x4F, 0x85, 0x59, 0xB9, 0x7F,
        0x97, 0x9A, 0xE8, 0x82, 0xEA, 0x54, 0x99, 0x28,
        0xD6, 0xB1, 0xA9, 0xA4, 0xE4, 0xA2, 0x29, 0xF6,
        0xEB, 0x3F, 0xB1, 0xA4, 0x34, 0xA0, 0xFA, 0xED,
        0xAD, 0x62, 0xB7, 0x03, 0x30, 0xCF, 0xCB, 0x24,
        0xCB, 0x34, 0x98, 0x80, 0x2A, 0x67, 0x9F, 0x8F,
        0x54, 0xBF, 0x83, 0xEF, 0x34, 0x47, 0x22, 0x96,
        0x91, 0x98, 0x31, 0xCA, 0xAD, 0x59, 0xEB, 0xE8,
        0x30, 0x82, 0xEA, 0xB6, 0x7D, 0x4A, 0xBD, 0x90,
        0x22, 0x9A, 0x5E, 0x93, 0xA0, 0xB5, 0x80, 0x97,
        0x7F, 0x08, 0x13, 0xCC, 0xB1, 0x5E, 0xCD, 0x74,
        0xFF, 0x71, 0x5F, 0xE8, 0xDB, 0x5B, 0x05, 0xCE,
        0xF3, 0x7D, 0x34, 0x93, 0xBE, 0xDA, 0x27, 0x05,
        0x84, 0x94, 0x4C, 0x02, 0x09, 0x86, 0x34, 0x51,
        0x4D, 0xAA, 0xCE, 0x70, 0x47, 0xE4, 0x74, 0x32,
        0xF9, 0x2A, 0xDC, 0xA4, 0x91, 0xA3, 0xE0, 0x96,
        0x1A, 0x5D, 0x9F, 0x01, 0x44, 0x85, 0x2E, 0x46,
        0x32, 0x63, 0x35, 0xE2, 0x15, 0x24, 0x3D, 0xAA,
        0xE8, 0x37, 0x92, 0x7F, 0xBF, 0xDC, 0xE6, 0x91,
        0xF4, 0x98, 0x59, 0x26, 0x6E, 0x90, 0x08, 0x16,
        0x8C, 0x6A, 0x5E, 0x2F, 0x60, 0x9C, 0x80, 0xC6,
        0x8E, 0x08, 0x20, 0xE7, 0x27, 0x19, 0xE9, 0xB5,
        0x87, 0x3F, 0xA1, 0x99, 0xE1, 0x97, 0xF9, 0xC4,
        0x94, 0xAA, 0x8A, 0x3A, 0x65, 0x26, 0x9E, 0x95,
        0xB7, 0x61, 0xB6, 0x7B, 0xEC, 0x61, 0x13, 0xC1,
        0x44, 0xA5, 0x69, 0x89, 0xC5, 0x75, 0x0D, 0x45,
        0x05, 0x42, 0xCC, 0xF8, 0x1B, 0x24, 0x62, 0x09,
        0x2F, 0x70, 0x71, 0x5D, 0x49, 0x14, 0xEB, 0x2C,
        0xAA, 0x31, 0x74, 0xBC, 0x9E, 0xEB, 0x20, 0xAA,
        0xB6, 0xC6, 0x40, 0xF8, 0xB5, 0xD9, 0xC6, 0xA0,
        0xDC, 0xC6, 0xF0, 0xAE, 0xC9, 0x7B, 0x3A, 0xF6,
        0x47, 0xEB, 0xF8, 0x00, 0x34, 0xA4, 0x3B, 0xF3,
        0x19, 0xBF, 0x40, 0xAD, 0xF7, 0x9A, 0xFE, 0xAB,
        0x58, 0x90, 0xD2, 0x02, 0x3B, 0xAE, 0x02, 0xC9,
        0xFD, 0x02, 0xC5, 0xBB, 0x65, 0x87, 0x9C, 0x1B,
        0x5E, 0xA4, 0x06, 0x02, 0x9A, 0xE7, 0x78, 0x45,
        0xCB, 0x99, 0x4D, 0xB8, 0xC3, 0x52, 0x11, 0xCA,
        0x1D, 0xC8, 0x81, 0xF7, 0xF2, 0x0A, 0x47, 0x06,
        0x50, 0x5F, 0x29, 0xD9, 0xCD, 0x19, 0x89, 0xAD,
        0x42, 0xB0, 0x7E, 0xF5, 0x2D, 0x96, 0x54, 0xE2,
        0x8E, 0x3D, 0xCB, 0x83, 0x00, 0x08, 0xA1, 0xBE,
        0x31, 0x99, 0x38, 0x7E, 0x06, 0x6B, 0x28, 0xB3,
        0x15, 0xCA, 0x19, 0x02, 0xF4, 0xBB, 0x0E, 0xE6,
        0x3F, 0xDC, 0x4C, 0x93, 0xE1, 0xAB, 0x88, 0x6F,
        0xD7, 0x42, 0x52, 0x61, 0xC3, 0x7A, 0xC5, 0x87,
        0x62, 0xD0, 0x3D, 0xB6, 0x07, 0x06, 0x88, 0x7E,
        0x72, 0xCF, 0x74, 0x5A, 0x44, 0x6D, 0xF6, 0xC6,
        0x66, 0x2F, 0x53, 0xDD, 0x61, 0x24, 0x71, 0xA4,
        0x34, 0xAC, 0x56, 0xC4, 0xBE, 0xDB, 0x3C, 0x9F,
        0x36, 0x47, 0xE6, 0x03, 0x2B, 0x3C, 0xC0, 0x99,
        0x0A, 0x3A, 0x2E, 0x87, 0x05, 0x2B, 0x36, 0xD4,
        0xA1, 0x62, 0x42, 0x4E, 0x2D, 0x39, 0x9E, 0x1B,
        0xC2, 0x37, 0x92, 0x8D, 0x0B, 0xD7, 0x71, 0x58,
        0x07, 0x9C, 0xCB, 0x20, 0x8B, 0x71, 0x95, 0x07,
        0x96, 0x55, 0xBD, 0xB7, 0x6C, 0xBA, 0xFF, 0x44,
        0x7C, 0x34, 0xC5, 0x82, 0x9F, 0xAC, 0x19, 0x9B,
        0xB0, 0x27, 0xA0, 0x80, 0x06, 0x50, 0x8D, 0x56,
        0xC8, 0x1D, 0x18, 0x70, 0x90, 0xE7, 0x10, 0x24,
        0xDB, 0x7F, 0xBF, 0x3A, 0x7D, 0x64, 0xD8, 0xFA,
        0x48, 0x74, 0xA8, 0xF4, 0x70, 0x37, 0x7B, 0x15,
        0x38, 0x00, 0x96, 0x82, 0x2F, 0xFE, 0x46, 0x55,
        0x71, 0xB5, 0x0C, 0x54, 0x05, 0x58, 0xBA, 0x50,
        0xE9, 0x0E, 0xB8, 0x14, 0x52, 0xF4, 0x12, 0x75,
        0xC2, 0x51, 0x5B, 0xAE, 0x05, 0x92, 0xD5, 0x3F,
        0x6A, 0x6A, 0x34, 0xD2, 0xA3, 0x4D, 0x8E, 0xAC,
        0x6E, 0x7A, 0x03, 0xFB, 0xDB, 0x52, 0x49, 0x4F,
        0x4B, 0x98, 0x1B, 0x56, 0xC0, 0x96, 0x26, 0x08,
        0x48, 0x50, 0xC7, 0xCF, 0x96, 0x2F, 0x93, 0x10,
        0x72, 0x25, 0x15, 0xA6, 0x2A, 0xC0, 0x85, 0xA6,
        0x18, 0x9A, 0xDD, 0xEA, 0x38, 0x12, 0x91, 0x13,
        0x57, 0x31, 0xB2, 0xEE, 0x83, 0xA4, 0xF1, 0xEB,
        0xFA, 0x09, 0xAF, 0x80, 0xA9, 0x12, 0x68, 0xA8,
        0x76, 0x23, 0xCB, 0x55, 0x7C, 0x9F, 0x66, 0xDE,
        0xB4, 0x54, 0xFB, 0x2F, 0x4F, 0xC2, 0x64, 0x8F,
        0x44, 0x41, 0x5A, 0x7B, 0xEF, 0x29, 0x96, 0x2D,
        0x5F, 0x7C, 0x16, 0xE7, 0x85, 0x79, 0xF5, 0x26,
        0xDD, 0x20, 0xE9, 0x20, 0x9B, 0x6C, 0xA6, 0xDF,
        0xD1, 0x30, 0xF9, 0x2E, 0xF7, 0x24, 0x64, 0x5B,
        0x5B, 0x84, 0xD8, 0x72, 0x4F, 0x3C, 0xF6, 0xF3,
        0xA3, 0xB2, 0xA9, 0xCF, 0x61, 0x24, 0x7A, 0x54,
        0xBA, 0x92, 0x8F, 0x53, 0xEA, 0xCB, 0xA7, 0xE6,
        0xD6, 0xB8, 0x12, 0xC4, 0xCE, 0x21, 0xA1, 0x8B,
        0xA8, 0xD1, 0x14, 0x50, 0xE7, 0x04, 0x89, 0xBA,
        0x57, 0x2E, 0x5E, 0xB9, 0xA7, 0x72, 0x2D, 0x9D,
        0xC6, 0xAA, 0xE4, 0xF9, 0x57, 0x93, 0x60, 0x09,
        0xE2, 0x6E, 0xB3, 0xE7, 0x4D, 0x9F, 0x99, 0x33,
        0xF3, 0xDB, 0x4D, 0xA0, 0xA1, 0xF5, 0x44, 0x93,
        0x99, 0xB5, 0xE1, 0x01, 0x03, 0x11, 0xF8, 0x7D,
        0x92, 0xC1, 0x87, 0xAD, 0x2E, 0xFA, 0xBB, 0x0A,
        0x2C, 0x86, 0xB7, 0xD7, 0xF9, 0xA0, 0x72, 0xAB,
        0xC0, 0xC6, 0x60, 0x6D, 0xBC, 0xD9, 0x20, 0x17,
        0x7A, 0x22, 0x57, 0x20, 0xA7, 0x05, 0x76, 0xB8,
        0xE8, 0x2D, 0x7D, 0x53, 0xC1, 0xDF, 0xA4, 0x8E,
        0xA7, 0x31, 0x81, 0xAF, 0x0A, 0xF0, 0x86, 0xB6,
        0xAA, 0xF8, 0x0A, 0xB2, 0x49, 0x81, 0xF2, 0x75,
        0xD6, 0x6D, 0x4F, 0xBD, 0xE2, 0xC5, 0x1A, 0xE8,
        0xE8, 0xD4, 0x58, 0x33, 0x72, 0x9F, 0x45, 0x03,
        0x01, 0x30, 0xBC, 0x85, 0xB2, 0xBD, 0x9A, 0x14,
        0xC8, 0x13, 0xA3, 0x7F, 0x1F, 0xA1, 0x47, 0xF8,
        0x15, 0x48, 0x8D, 0x7A, 0x17, 0xC0, 0xC0, 0x39,
        0xEA, 0xF8, 0x66, 0xCE, 0xA7, 0x5F, 0x5B, 0x2E,
        0xBE, 0x05, 0xEF, 0x31, 0x09, 0x47, 0x2B, 0xA5,
        0xF7, 0xCF, 0xCE, 0x4C, 0x35, 0x8B, 0x60, 0x80,
        0x40, 0x0C, 0x5C, 0xC0, 0x85, 0x15, 0x14, 0x92,
        0xD1, 0x3A, 0x5B, 0x00, 0x96, 0xA0, 0x63, 0x1F,
        0xAA, 0x30, 0xCB, 0x48, 0xF2, 0xDA, 0x87, 0x3B,
        0x85, 0x7D, 0xFD, 0xB3, 0x86, 0xD9, 0x33, 0x98,
        0x18, 0x07, 0x34, 0x92, 0x55, 0x9A, 0x0E, 0xC2,
        0xDA, 0xF3, 0x73, 0x8E, 0x15, 0x88, 0xB0, 0x98,
        0x75, 0x1F, 0xF0, 0xFA, 0x1C, 0x87, 0x1B, 0x22,
        0x23, 0x7E, 0x5C, 0xD1, 0x5B, 0x0E, 0x17, 0x28,
        0xEA, 0x26, 0x71, 0x66, 0xC3, 0x8A, 0x71, 0x97,
        0xB6, 0xCC, 0x7D, 0xAD, 0x39, 0x11, 0x6B, 0xE6,
        0x1D, 0xF4, 0x33, 0x3C, 0xD7, 0xC2, 0xA4, 0x13,
        0xDB, 0x30, 0x63, 0xD7, 0xF0, 0x22, 0x8C, 0x61,
        0xFA, 0xDA, 0xC3, 0xF8, 0xC3, 0x31, 0xF4, 0x45,
        0x09, 0xB4, 0xD6, 0x08, 0x53, 0x1F, 0x99, 0x5D,
        0x15, 0xFA, 0xB1, 0x19, 0xD8, 0x47, 0xE6, 0xD8,
        0x54, 0x95, 0x75, 0xB7, 0xD8, 0x50, 0xB2, 0x60,
        0x0E, 0x4D, 0x13, 0x64, 0x6C, 0xF9, 0x6B, 0x6B,
        0x9D, 0xA6, 0xC6, 0x2F, 0x2A, 0x80, 0xAE, 0x02,
        0x58, 0xA8, 0xCD, 0x6E, 0xF4, 0xC5, 0x5E, 0xEA,
        0x7E, 0x78, 0xD2, 0x0A, 0x46, 0x4A, 0x19, 0x4C,
        0xEC, 0xBB, 0x01, 0xE7, 0x3F, 0x32, 0x76, 0xD6,
        0x6E, 0x12, 0xAD, 0x37, 0x74, 0x51, 0xBB, 0xB9,
        0x4E, 0x5C, 0x94, 0x88, 0x32, 0x59, 0x5F, 0x6B,
        0x6E, 0x38, 0x2A, 0xD1, 0x42, 0xD9, 0xF1, 0xB8,
        0x68, 0x97, 0x95, 0xE9, 0xEB, 0xC3, 0x2A, 0x5A,
        0x10, 0x1E, 0x69, 0x6C, 0xA3, 0x4A, 0xBA, 0x00,
        0x5B, 0x4C, 0xED, 0xA2, 0x7D, 0x12, 0x00, 0xFE,
        0x48, 0xFD, 0x82, 0xC1, 0x72, 0x17, 0xE5, 0x08,
        0xA8, 0x48, 0x4F, 0x03, 0x88, 0x34, 0x5C, 0x9D,
        0xED, 0xE2, 0xA1, 0x39, 0x28, 0xFA, 0xC3, 0x29,
        0x21, 0x84, 0x2F, 0x6E, 0x6A, 0xA5, 0xCF, 0xBF,
        0x57, 0xFA, 0xA2, 0x8F, 0x43, 0xE0, 0x5E, 0x9A,
        0x45, 0x23, 0x12, 0x50, 0x29, 0x11, 0xEF, 0x9C,
        0x33, 0xC8, 0x11, 0xEB, 0xE7, 0xCA, 0xD7, 0x30,
        0x62, 0x3D, 0xB7, 0x04, 0x8E, 0xC2, 0x18, 0xC7,
        0xEA, 0x9D, 0xFC, 0x6E, 0x19, 0x65, 0xA9, 0x85,
        0x7E, 0x92, 0x94, 0xC4, 0xE4, 0x7F, 0x4D, 0x96,
        0x23, 0xCB, 0x74, 0xB6, 0x5F, 0x7B, 0xB5, 0x86,
        0x22, 0x83, 0x8D, 0xC4, 0x4E, 0x16, 0xD9, 0x15,
        0xD9, 0x59, 0x65, 0x55, 0xCA, 0x3D, 0x26, 0x1C,
        0x9C, 0x2A, 0xFC, 0xCB, 0xAF, 0x5A, 0xC0, 0x3D,
        0xE0, 0x91, 0xF0, 0xDB, 0xEA, 0xE1, 0xB4, 0xA7,
        0xE3, 0xDE, 0xC4, 0x39, 0x09, 0x89, 0x67, 0x65,
        0x77, 0xA0, 0x53, 0x68, 0x4F, 0x57, 0x86, 0x8D,
        0x91, 0xFE, 0x6A, 0x5B, 0x7D, 0x3D, 0x7C, 0x79,
        0x50, 0x78, 0x9E, 0x89, 0xD8, 0x38, 0x83, 0xBC,
        0x3D, 0xAE, 0x55, 0xCA, 0x30, 0x78, 0xB0, 0x8D,
        0x99, 0x18, 0x31, 0xBA, 0x91, 0x50, 0x2A, 0x5A,
        0x33, 0x54, 0xB8, 0x8E, 0x15, 0x9B, 0x0A, 0xFF,
        0xD2, 0x5B, 0x0D, 0xBB, 0x72, 0xBC, 0xD6, 0xF4,
        0x04, 0x65, 0xDD, 0xFC, 0x00, 0xFF, 0x8B, 0x63,
        0x39, 0xC0, 0x67, 0x09, 0x5D, 0x6C, 0x7C, 0xB0,
        0x6F, 0x3B, 0xE7, 0x59, 0xC5, 0x27, 0x40, 0x39,
        0x5D, 0xD1, 0x08, 0x29, 0x6F, 0x2B, 0xBC, 0x2E,
        0x7A, 0x5D, 0xDD, 0xE3, 0xD1, 0xC3, 0x5D, 0x18,
        0xBF, 0xBE, 0x39, 0x68, 0xEC, 0x59, 0xAB, 0xF8,
        0x5C, 0x1B, 0xD2, 0x92, 0x8A, 0xB2, 0xAA, 0x67,
        0x8A, 0x78, 0x91, 0x74, 0x6E, 0x88, 0xF4, 0x39,
        0xF8, 0xB4, 0x38, 0x40, 0x31, 0xC3, 0xED, 0xB7,
        0x31, 0x97, 0xE5, 0x2A, 0x4E, 0x77, 0x3D, 0x2D,
        0x8B, 0x7B, 0xAD, 0xDC, 0x5D, 0xD0, 0xA7, 0xE4,
        0x4C, 0x80, 0x8D, 0x73, 0xB8, 0x18, 0x1D, 0x19,
        0x1C, 0x3C, 0x89, 0xFE, 0x15, 0xEA, 0x90, 0xD7,
        0x56, 0x7E, 0x89, 0x16, 0xA3, 0x37, 0x83, 0x03,
        0x05, 0x04, 0x1B, 0x1E, 0x94, 0xB3, 0xB4, 0x06,
        0xDA, 0x4C, 0x36, 0xBE, 0xF0, 0x5D, 0x91, 0x00,
        0xAB, 0x99, 0x2A, 0x4D, 0x56, 0x25, 0x33, 0x73,
        0x0E, 0x0D, 0x8C, 0x05, 0x2B, 0x3A, 0x62, 0xD3,
        0xF6, 0x9A, 0x83, 0xA0, 0xC9, 0xB2, 0x12, 0x4F,
        0x12, 0xAE, 0x7D, 0xAC, 0xC9, 0x78, 0xC4, 0xA0,
        0xAD, 0xCC, 0x2E, 0xBA, 0x2D, 0x80, 0xF4, 0x94,
        0xAA, 0x16, 0xEC, 0x1E, 0x8E, 0x71, 0xC7, 0x9B,
        0x02, 0xF3, 0x26, 0x1B, 0x6F, 0x98, 0x68, 0xB8,
        0xD5, 0x7E, 0x9D, 0x16, 0xF4, 0x2B, 0x7C, 0xC6,
        0x64, 0x06, 0x54, 0x9A, 0x27, 0x6D, 0x37, 0x14,
        0x37, 0xDE, 0x88, 0xB7, 0xF3, 0x9E, 0x74, 0x08,
        0x7C, 0xBB, 0xC5, 0x61, 0x16, 0x80, 0x31, 0x2D,
        0xE8, 0xF0, 0xC3, 0x68, 0x14, 0xE1, 0x74, 0xF9,
        0x1E, 0xB6, 0x00, 0xCC, 0x96, 0xE3, 0xCF, 0x51,
        0xBB, 0x20, 0x25, 0x88, 0x77, 0xA2, 0xAA, 0xEB,
        0x82, 0x7F, 0x7F, 0x5A, 0xDA, 0x80, 0x78, 0x6B,
        0x50, 0x84, 0xC8, 0x02, 0xE6, 0x06, 0xDE, 0xF3,
        0x88, 0xA3, 0x9C, 0xE4, 0xF0, 0xD5, 0xBC, 0x19,
        0x39, 0x4C, 0xE8, 0x41, 0xE2, 0xD2, 0xAA, 0x74,
        0x25, 0x23, 0x05, 0x80, 0xFA, 0x66, 0x75, 0xC5,
        0x17, 0x41, 0xD1, 0x75, 0x87, 0x9B, 0x4D, 0x03,
        0xC3, 0x90, 0xF6, 0x52, 0xA5, 0x03, 0xA7, 0x51,
        0x6A, 0x1F, 0x07, 0x5E, 0x30, 0x82, 0xD5, 0x2C,
        0x60, 0xB8, 0x64, 0x2A, 0x82, 0x40, 0xEE, 0x94,
        0x4D, 0x5F, 0xB4, 0x27, 0x37, 0x6B, 0x40, 0xB0,
        0xB2, 0x82, 0xE1, 0x9A, 0xB9, 0x08, 0xCC, 0xF2,
        0x0C, 0xA9, 0x26, 0x11, 0x64, 0x90, 0xAF, 0xED,
        0x57, 0xEA, 0xD0, 0xDC, 0x0C, 0x8E, 0x29, 0x6C,
        0x79, 0xA4, 0x8D, 0x08, 0x8E, 0x83, 0x7A, 0xF0,
        0x67, 0xDC, 0x02, 0x9E, 0xC6, 0x31, 0xF9, 0x93,
        0x3E, 0xE4, 0xD2, 0x07, 0x46, 0xE6, 0x4E, 0x5F,
        0x21, 0x67, 0x55, 0xA1, 0x38, 0x97, 0x4D, 0x30,
        0x82, 0x93, 0x73, 0x6D, 0xC1, 0x86, 0x04, 0x27,
        0x6C, 0xC4, 0x18, 0xBA, 0x69, 0xF8, 0x72, 0xB5,
        0x8E, 0x7F, 0x6E, 0x3A, 0x8B, 0x84, 0x6E, 0xBA,
        0xAE, 0xB3, 0x83, 0xE7, 0xF8, 0x90, 0xF5, 0x4E,
        0x77, 0xF5, 0xD7, 0xF5, 0xD4, 0xA5, 0x8D, 0xB7,
        0x83, 0xEC, 0xA0, 0x49, 0xF1, 0x86, 0x17, 0x12,
        0x82, 0xBA, 0xC2, 0x60, 0x7D, 0x51, 0xB2, 0x98,
        0xB1, 0x49, 0x38, 0xEF, 0xB1, 0x92, 0x8F, 0xC8,
        0xD0, 0x78, 0x06, 0xE8, 0xC3, 0xE7, 0x3B, 0x46,
        0x46, 0xBC, 0xF1, 0x68, 0x90, 0xCC, 0x13, 0x80,
        0xE7, 0xB6, 0x33, 0x50, 0x2B, 0x3E, 0xAD, 0xA4,
        0x47, 0x75, 0x02, 0xE2, 0x46, 0x7C, 0xFD, 0xB9,
        0xAC, 0xBD, 0x1C, 0x72, 0xBC, 0x6A, 0xEB, 0x4F,
        0x41, 0xE1, 0xC2, 0x3C, 0x63, 0x68, 0x39, 0xE3,
        0x57, 0x13, 0x5F, 0x76, 0xBC, 0x39, 0xC4, 0xF9,
        0xAC, 0x1C, 0xE8, 0xF1, 0xBE, 0xEF, 0xEB, 0xFF,
        0x87, 0x59, 0xE8, 0xF7, 0x19, 0x65, 0xD4, 0x85,
        0x4B, 0xEA, 0xAD, 0x0A, 0xFE, 0xDC, 0xA9, 0xD4,
        0xD6, 0xBD, 0x1E, 0x63, 0xD3, 0x48, 0xA4, 0x2C,
        0xEE, 0xFF, 0xC1, 0x70, 0xD0, 0xEE, 0x9F, 0x13,
        0x6F, 0x5B, 0xE9, 0x90, 0x14, 0x66, 0x92, 0x61,
        0x22, 0xF9, 0x48, 0xBD, 0xDE, 0x2A, 0x91, 0x07,
        0xD2, 0xA9, 0x8B, 0xA2, 0xDE, 0xA6, 0xD6, 0xF2,
        0xDA, 0x17, 0x72, 0x47, 0x02, 0xEC, 0x51, 0x8C,
        0x03, 0x75, 0x3D, 0x51, 0xEA, 0x83, 0x1E, 0x95,
        0xCB, 0x87, 0x08, 0xD5, 0xDE, 0xC8, 0x22, 0xDB,
        0x73, 0x7E, 0x44, 0x14, 0x3C, 0x86, 0xF4, 0x71,
        0x77, 0xD8, 0x5C, 0xD0, 0x98, 0xC2, 0x1B, 0x9B,
        0xC8, 0x00, 0xDF, 0xA9, 0xDC, 0x26, 0xFD, 0xC2,
        0x61, 0xE9, 0x21, 0xDE, 0x00, 0x2D, 0x81, 0xC1,
        0x59, 0xF8, 0xEB, 0x1F, 0xEE, 0x67, 0x67, 0x9D,
        0x62, 0x1E, 0xCE, 0x6B, 0x36, 0xD0, 0x1C, 0x77,
        0x5A, 0x16, 0x45, 0xD5, 0x22, 0x92, 0xB4, 0xB2,
        0xB8, 0x22, 0x73, 0x18, 0x77, 0x2A, 0x80, 0x91,
        0xE9, 0xEC, 0x01, 0x70, 0x13, 0xB1, 0x95, 0xEB,
        0xF4, 0xEF, 0x20, 0x1F, 0x4E, 0x88, 0x1C, 0x49,
        0x36, 0x33, 0xC0, 0x7F, 0x27, 0xC9, 0x79, 0x0D,
        0xD8, 0xAE, 0xCC, 0x94, 0x49, 0xCF, 0x63, 0xBC,
        0xB1, 0x19, 0x46, 0x16, 0x9A, 0xCF, 0xF3, 0x95,
        0x42, 0x26, 0x6B, 0x0C, 0x66, 0x85, 0xBB, 0xB0,
        0x80, 0xB5, 0x9F, 0x11, 0x7E, 0xEB, 0x2A, 0x73,
        0x38, 0x2B, 0x3D, 0x18, 0x7C, 0x06, 0x80, 0xC5,
        0xAE, 0x70, 0x90, 0x70, 0xDF, 0x03, 0xA0, 0x08,
        0xA7, 0xAD, 0x13, 0x22, 0x6F, 0x3C, 0x37, 0x15,
        0x39, 0x20, 0x52, 0xF2, 0x44, 0x1B, 0x4A, 0x17,
        0x8D, 0x7C, 0xF7, 0x05, 0x18, 0x33, 0x9C, 0xFF,
        0xBB, 0x54, 0xA6, 0xD9, 0xB9, 0xCD, 0xE3, 0xB0,
        0xB5, 0x7D, 0xBC, 0x79, 0xF4, 0xE4, 0x7A, 0xD6,
        0x27, 0x4C, 0xE2, 0x18, 0x0C, 0x92, 0xAC, 0x64,
        0x10, 0xE5, 0x0D, 0x05, 0xF6, 0x66, 0x5A, 0x57,
        0xD4, 0xD4, 0x47, 0x6C, 0x2C, 0x0E, 0x6E, 0xE0,
        0x75, 0x7A, 0x3A, 0xFE, 0xA2, 0xB1, 0xBF, 0x86,
        0xA5, 0x51, 0xEF, 0x98, 0xAA, 0x1D, 0xFC, 0xBA,
        0x96, 0x31, 0x59, 0x59, 0x45, 0x2B, 0x2B, 0x3A,
        0x2F, 0xCB, 0xBB, 0x95, 0x5C, 0xB3, 0xFA, 0x1E,
        0xEB, 0xBB, 0x83, 0xBD, 0x17, 0x87, 0x67, 0xC0,
        0x2E, 0xFB, 0xBE, 0xFF, 0x6C, 0x7E, 0xEF, 0x94,
        0xB5, 0x5D, 0xF8, 0x83, 0x1D, 0xDF, 0xB7, 0xB2,
        0x02, 0xCE, 0x7D, 0xE0, 0x55, 0xEA, 0xF9, 0x92,
        0x8A, 0xDA, 0xF6, 0xED, 0x0E, 0x31, 0x59, 0xCA,
        0x56, 0xC4, 0x83, 0xFA, 0x3B, 0xA3, 0xD2, 0x47,
        0x8C, 0xA3, 0x94, 0x82, 0x4C, 0xEE, 0x6A, 0xBD,
        0x59, 0x67, 0x09, 0x53, 0xEE, 0x80, 0xD3, 0x83,
        0xAA, 0xA6, 0x08, 0xE1, 0x58, 0x51, 0x13, 0x5C,
        0x1C, 0xDE, 0xEE, 0xB5, 0xF6, 0xA8, 0x89, 0x7C,
        0x3C, 0x9E, 0x06, 0x6A, 0xB4, 0x73, 0x4F, 0xDD,
        0xFA, 0xBC, 0x3B, 0xC3, 0xBA, 0x12, 0x06, 0xBA,
        0x54, 0x34, 0xDC, 0xDE, 0xDB, 0x9D, 0x8B, 0x3A,
        0x81, 0xA2, 0xE6, 0x38, 0x14, 0x6D, 0x83, 0xF1,
        0x4F, 0x06, 0xE5, 0x60, 0x99, 0xC0, 0xC8, 0xA0,
        0xFC, 0xCD, 0xB9, 0xEC, 0xF0, 0xF3, 0xD8, 0x8D,
        0xE3, 0x79, 0x2F, 0x2D, 0x0B, 0x65, 0x1B, 0x61,
        0x9C, 0x57, 0x1B, 0x69, 0xF4, 0xBF, 0x8E, 0x7C,
        0xD1, 0x91, 0x0F, 0x26, 0x6A, 0x4D, 0xAD, 0xF8,
        0xC2, 0xAB, 0xB4, 0xAC, 0x05, 0xBD, 0x1F, 0xBA,
        0x05, 0x8C, 0x03, 0x94, 0xC0, 0x16, 0xDE, 0xE6,
        0x0C, 0x66, 0x40, 0x1A, 0x17, 0xD1, 0x34, 0x59,
        0x54, 0x79, 0x33, 0x38, 0x9A, 0x35, 0x65, 0x69,
        0xAD, 0xA5, 0x32, 0xC9, 0xF4, 0x87, 0x69, 0x88,
        0x55, 0xA4, 0xD7, 0xBC, 0xCD, 0x0E, 0xF6, 0x95,
        0x31, 0x09, 0x4D, 0xA4, 0x08, 0x6F, 0x52, 0xBF,
        0x98, 0xCD, 0xC9, 0xA4, 0xB0, 0xBC, 0x88, 0x8D,
        0xC3, 0x89, 0x1A, 0x76, 0x09, 0x6C, 0x7C, 0x48,
        0x34, 0x90, 0xE9, 0x52, 0x32, 0x6A, 0xE4, 0x02,
        0xD8, 0xDF, 0xD2, 0xF3, 0xDC, 0xCF, 0x1A, 0xA5,
        0xD7, 0xBD, 0x69, 0x8E, 0x2A, 0xA8, 0x8D, 0x29,
        0x48, 0x13, 0xA8, 0x8F, 0xD3, 0x18, 0x66, 0xBC,
        0xA1, 0x1B, 0x3B, 0x91, 0xC0, 0x09, 0xEE, 0xB6,
        0x67, 0x60, 0x1C, 0xEE, 0xAF, 0xAF, 0xE9, 0x7C,
        0x56, 0xFA, 0x33, 0xF9, 0x38, 0x1F, 0x3E, 0x43,
        0x29, 0x90, 0x1A, 0xC3, 0xB7, 0xEA, 0x70, 0x32,
        0xC0, 0x19, 0xE5, 0xC8, 0xA8, 0xEF, 0xD7, 0x04,
        0x4C, 0x97, 0x36, 0x44, 0xAF, 0x2B, 0xE4, 0x20,
        0xA0, 0x33, 0xC6, 0xC2, 0xC7, 0xCE, 0x0C, 0xEA,
        0x39, 0x34, 0xDC, 0x18, 0xB4, 0x2A, 0xDF, 0xD7,
        0xA8, 0x46, 0xF4, 0x2D, 0xD4, 0x06, 0x86, 0x6A,
        0x39, 0x09, 0x29, 0x02, 0x6A, 0xDE, 0x5C, 0x79,
        0x1B, 0x5F, 0x61, 0xF9, 0x42, 0xB1, 0x55, 0x07,
        0x7D, 0x82, 0xF2, 0xAF, 0xCC, 0xFF, 0xF8, 0x5B,
        0x04, 0x06, 0x64, 0x7A, 0x96, 0x27, 0xE3, 0x69,
        0x5D, 0x4B, 0xEA, 0x3D, 0x58, 0xA6, 0x3E, 0x17,
        0x18, 0xD1, 0x84, 0xE4, 0x6B, 0x5F, 0x4B, 0xC8,
        0x41, 0x03, 0x34, 0xA4, 0x09, 0x5D, 0x0F, 0xAF,
        0x30, 0x6F, 0xB9, 0xDC, 0x10, 0x94, 0x25, 0xC3,
        0x16, 0x52, 0xD0, 0x6F, 0xF0, 0x51, 0xA1, 0x62,
        0xEE, 0x2B, 0x7B, 0x1C, 0x54, 0xD6, 0xC7, 0xDE,
        0xD6, 0xE3, 0x95, 0xAA, 0xD1, 0xA8, 0x6D, 0x03,
        0xB1, 0xB6, 0xC8, 0x00, 0x76, 0x7E, 0xC1, 0x44,
        0x12, 0xEE, 0xCE, 0x13, 0x46, 0x20, 0xA6, 0x1D,
        0x36, 0x9A, 0xF4, 0x9E, 0x21, 0xB0, 0xD1, 0x4B,
        0xC4, 0x23, 0x06, 0x49, 0xCD, 0xD3, 0xE9, 0xFD,
        0x84, 0x7A, 0xE5, 0x0B, 0xE9, 0x62, 0xEF, 0xC8,
        0xCB, 0x0F, 0x33, 0x9F, 0x9E, 0x6D, 0x32, 0x47,
        0x53, 0x3B, 0xDE, 0xD8, 0x71, 0x1D, 0x46, 0x1D,
        0x4A, 0xF2, 0xAE, 0x3F, 0xDD, 0x1D, 0x7D, 0x2A,
        0x28, 0x9C, 0x78, 0xCB, 0x19, 0xF3, 0xCD, 0xC2,
        0x14, 0x2B, 0xF5, 0x2B, 0x23, 0xE6, 0xA2, 0x7B,
        0x39, 0xD6, 0x99, 0x54, 0x3C, 0x3D, 0x63, 0x9B,
        0x9C, 0x72, 0xCA, 0x80, 0xB3, 0x7E, 0xA2, 0x77,
        0x5B, 0x5E, 0x26, 0x81, 0xF0, 0xDD, 0x01, 0xDF,
        0xF0, 0xC0, 0x55, 0x13, 0x36, 0x90, 0x62, 0xFE
    };
    static const byte msg_87[] = {
        0x9E, 0xFF, 0x34, 0x15, 0x06, 0xD1, 0x8B, 0xCB,
        0x27, 0xA7, 0xFC, 0x4E, 0xAA, 0xBF, 0x5A, 0x7C,
        0x4A, 0x59, 0x37, 0x77, 0x19, 0x6F, 0x66, 0x4B,
        0xCE, 0x31, 0x6C, 0x95, 0x5B, 0x83, 0x5A, 0xD4,
        0xC9, 0xF5, 0xDE, 0x9A, 0x2B, 0xF8, 0x96, 0x15,
        0xDA, 0xCB, 0x9C, 0x1E, 0x61, 0x8C, 0x78, 0xE7,
        0x11, 0x44, 0xCD, 0x4B, 0x70, 0x46, 0xF4, 0x7D,
        0x9A, 0x60, 0x0E, 0x9C, 0xE6, 0x65, 0x96, 0xC4,
        0xC5, 0x5E, 0xDA, 0x23, 0xA6, 0x6C, 0xC1, 0x18,
        0xA4, 0xA7, 0xBD, 0x0D, 0xED, 0x00, 0xAB, 0xDD,
        0xCE, 0x53, 0xFB, 0xF2, 0x48, 0x20, 0x33, 0xA4,
        0x18, 0x85, 0x06, 0xEC, 0x11, 0x3B, 0xBD, 0x98,
        0xD9, 0x89, 0x1F, 0x0D, 0x69, 0x46, 0x3A, 0x0D,
        0x36, 0x15, 0x6B, 0xA3, 0xEA, 0x0D, 0x02, 0xA1,
        0x4C, 0x1F, 0xD7, 0xA3, 0xFE, 0x70, 0x4E, 0xE5,
        0x6B, 0x44, 0x6A, 0xE1, 0x79, 0xF7, 0x2E, 0x10,
        0x4A, 0xA8, 0x1A, 0xF0, 0xA2, 0xF8, 0xFC, 0xA6,
        0xF6, 0xF9, 0x62, 0x96, 0x05, 0x9E, 0xE8, 0x82,
        0x66, 0x80, 0xE4, 0x3F, 0x4B, 0x07, 0x40, 0xF4,
        0x7A, 0xC1, 0x05, 0x66, 0xED, 0x31, 0x07, 0x99,
        0xAC, 0x71, 0x41, 0xD3, 0x8F, 0x69, 0x21, 0x31,
        0x5F, 0x23, 0xAB, 0x3E, 0x64, 0xC8, 0xA7, 0x70,
        0xAA, 0x57, 0x12, 0x80, 0x90, 0xDB, 0x82, 0x8C,
        0x7B, 0xAA, 0x59, 0xC3, 0x29, 0x5C, 0xCA, 0xA2,
        0x38, 0xC7, 0x5F, 0xAC, 0x0F, 0x93, 0xDA, 0x79,
        0x00, 0x74, 0x1B, 0xCD, 0x94, 0xBB, 0x9F, 0xD3,
        0x85, 0x2E, 0xC2, 0xB7, 0xD3, 0x3F, 0x60, 0x0B,
        0x1D, 0x51, 0x66, 0x6A, 0xE2, 0x22, 0xA5, 0x7A,
        0xF1, 0x40, 0xFA, 0x04, 0x9C, 0x2C, 0x9F, 0x6D,
        0x0F, 0xE6, 0xC0, 0xF1, 0xE7, 0xA0, 0xDD, 0xE1,
        0x14, 0x3B, 0xE5, 0xCE, 0xD7, 0xBB, 0xE2, 0x32,
        0xCB, 0xFB, 0xD8, 0xAE, 0x00, 0xEA, 0x5F, 0xC1,
        0x65, 0x02, 0x6D, 0x72, 0x9D, 0xB3, 0x0F, 0x6A,
        0xFD, 0x99, 0x73, 0xB6, 0x72, 0x2C, 0x07, 0xF6,
        0x00, 0x66, 0x54, 0x41, 0xE3, 0x0B, 0x7C, 0x5F,
        0xB2, 0x97, 0xB8, 0xAB, 0x96, 0x9C, 0x06, 0x83,
        0x9D, 0x33, 0x1D, 0xEE, 0x96, 0xDE, 0x48, 0x68,
        0x7D, 0xC9, 0xDA, 0x53, 0x1A, 0x95, 0xCA, 0x83,
        0xA7, 0x6F, 0x4B, 0x07, 0x6D, 0xFC, 0xF4, 0x83,
        0xF0, 0x04, 0x50, 0xE5, 0x1C, 0x8D, 0x34, 0xD8,
        0xED, 0x8E, 0x4B, 0x3D, 0xAF, 0xAE, 0x66, 0x4B,
        0x6D, 0xC1, 0x3E, 0xD8, 0x8E, 0x6D, 0x63, 0x02,
        0x7D, 0xD4, 0x38, 0xCB, 0x74, 0xF4, 0x12, 0xE8,
        0x70, 0xCC, 0x9D, 0xFD, 0x29, 0xB5, 0x2A, 0xBC,
        0xA1, 0x69, 0xC1, 0x7E, 0x97, 0x47, 0x58, 0xE0,
        0x3A, 0xC0, 0xFB, 0x7F, 0xE5, 0x64, 0x50, 0x8E,
        0x01, 0x7A, 0x9B, 0x47, 0x49, 0xD6, 0x41, 0xAF,
        0x0D, 0xE3, 0x84, 0x08, 0x8F, 0xA0, 0x0C, 0x69,
        0x40, 0x23, 0x3D, 0xDE, 0xFB, 0x65, 0x7C, 0x18,
        0x1C, 0x82, 0xA1, 0xB6, 0xA3, 0x1F, 0xCC, 0xF4,
        0xD5, 0x2C, 0x9D, 0x35, 0x1E, 0x6B, 0xDF, 0xDF,
        0x48, 0xBC, 0xE4, 0x14, 0x60, 0x74, 0x62, 0xDB,
        0x76, 0x9F, 0x9E, 0xB1, 0x59, 0x25, 0xBA, 0x9F,
        0xAF, 0xBA, 0xB2, 0x29, 0xB5, 0x89, 0x6B, 0xF1,
        0xF8, 0xE4, 0x7D, 0xF1, 0x7C, 0x82, 0x08, 0xDF,
        0xD5, 0x96, 0x04, 0xB6, 0x05, 0x2C, 0xD2, 0xCE,
        0xAB, 0x56, 0x40, 0x0F, 0x11, 0xC4, 0xD9, 0x52,
        0x1E, 0x1A, 0xB8, 0x27, 0x4A, 0xB5, 0x76, 0x4C,
        0x73, 0xE9, 0x41, 0x32, 0x42, 0x0E, 0x32, 0xB6,
        0xAE, 0xB0, 0x76, 0x33, 0x78, 0xD9, 0xBA, 0x68,
        0xE1, 0xFC, 0xDE, 0x2B, 0xD6, 0xDE, 0xDA, 0x39,
        0x17, 0xC0, 0x00, 0xAF, 0x39, 0xB7, 0x8F, 0x4C,
        0xCA, 0x7C, 0x8F, 0xBF, 0x94, 0xB4, 0xCB, 0x8A,
        0x81, 0x16, 0xEE, 0xEC, 0xFE, 0xF0, 0x13, 0x1E,
        0xC9, 0xF2, 0xDE, 0xDA, 0x01, 0x40, 0xC9, 0x02,
        0xA8, 0xD6, 0xE6, 0x0E, 0x98, 0xB3, 0xCD, 0x9D,
        0x9C, 0x75, 0x24, 0x8B, 0xF8, 0x84, 0x5A, 0xC0,
        0xD7, 0xE0, 0x6B, 0xA0, 0xE1, 0x83, 0x10, 0xFE,
        0xCE, 0x98, 0x62, 0x07, 0x54, 0x2C, 0xC1, 0xEE,
        0x08, 0x88, 0x43, 0xEF, 0x74, 0xA2, 0x6A, 0xEC,
        0xB6, 0xD0, 0x6F, 0x0F, 0xEF, 0xE1, 0xB7, 0x2C,
        0xF9, 0x33, 0x06, 0xC3, 0x2E, 0xD2, 0x8A, 0xEC,
        0xC5, 0x5B, 0xB1, 0x03, 0xA0, 0x84, 0x6D, 0x0C,
        0x84, 0x13, 0x6D, 0xB0, 0xB0, 0x54, 0xF3, 0xDE,
        0xA3, 0x9A, 0x72, 0x6C, 0x6F, 0xD6, 0x59, 0x7F,
        0x9B, 0x03, 0x8C, 0xC2, 0x38, 0x46, 0x01, 0x76,
        0x38, 0xF4, 0x43, 0x68, 0x81, 0x0D, 0x86, 0x29,
        0x3D, 0xDF, 0xE5, 0x48, 0x61, 0x53, 0x2F, 0x85,
        0xF5, 0x3F, 0x09, 0x30, 0x48, 0xC3, 0xE0, 0x09,
        0xC4, 0x32, 0x11, 0x27, 0xAD, 0xAA, 0xEC, 0x6A,
        0x5C, 0xCE, 0x03, 0xE0, 0xD9, 0xE9, 0x1D, 0xAC,
        0xCA, 0xBB, 0x2F, 0x50, 0xE0, 0x1E, 0xB2, 0xAC,
        0x2B, 0x39, 0x6D, 0x24, 0xB0, 0x5D, 0x45, 0x3B,
        0xD5, 0x1D, 0x52, 0x9F, 0xBA, 0x51, 0xE4, 0x6D,
        0x30, 0xC5, 0x66, 0x13, 0x00, 0x5A, 0xBF, 0x62,
        0x63, 0xB9, 0x8D, 0x8D, 0xFE, 0xB5, 0x26, 0x16,
        0xD1, 0xCB, 0x78, 0x92, 0x18, 0x1C, 0x2F, 0xC2,
        0xE2, 0x04, 0x3B, 0x99, 0x4C, 0x81, 0x66, 0x58,
        0x48, 0x2E, 0x06, 0x06, 0x34, 0x83, 0x78, 0xA3,
        0xCC, 0x85, 0x40, 0xE0, 0x20, 0x27, 0x3F, 0x10,
        0xB6, 0x9E, 0x20, 0x21, 0xA9, 0x2D, 0x9C, 0x36,
        0xCC, 0x9B, 0x97, 0x79, 0xFE, 0x8C, 0xE7, 0xA4,
        0x99, 0xAE, 0xB5, 0x3E, 0xC6, 0xDD, 0xB4, 0xF2,
        0xEC, 0x22, 0xBF, 0xB4, 0x52, 0xFC, 0x5E, 0x79,
        0x7D, 0x3A, 0x25, 0x33, 0x26, 0x00, 0x06, 0xFE,
        0x6D, 0xCC, 0xE4, 0xE9, 0x76, 0x65, 0xC6, 0x8C,
        0x39, 0x93, 0xDC, 0x7E, 0xA0, 0xBD, 0x4B, 0xDC,
        0xD2, 0x47, 0x21, 0xB0, 0x2B, 0x09, 0x02, 0xB1,
        0x84, 0x0D, 0xDE, 0xC5, 0x18, 0x20, 0x38, 0x76,
        0x2D, 0x55, 0xFC, 0x11, 0xB9, 0x87, 0x3A, 0x0D,
        0xD2, 0xEB, 0xBD, 0x55, 0xAD, 0xE3, 0x86, 0x5C,
        0xFF, 0x3D, 0x54, 0x5F, 0x76, 0x33, 0x53, 0x69,
        0xDD, 0x9E, 0x70, 0xB0, 0x73, 0x99, 0x77, 0xF6,
        0xE9, 0x8A, 0x61, 0x27, 0x19, 0x4A, 0x19, 0x26,
        0xA6, 0x97, 0xE4, 0x7F, 0x73, 0xE0, 0x4F, 0xF5,
        0xBD, 0x52, 0x5E, 0x8F, 0x17, 0x22, 0x00, 0x8F,
        0x7C, 0x15, 0x5C, 0xD3, 0xAD, 0xE0, 0xA5, 0xB6,
        0x6A, 0x31, 0x36, 0xFD, 0xD8, 0x44, 0xAE, 0x5E,
        0xCD, 0x6C, 0x82, 0x77, 0xC3, 0xD0, 0x7F, 0x39,
        0x72, 0x1E, 0x91, 0x19, 0x50, 0xE1, 0x28, 0x20,
        0x88, 0x3A, 0x6B, 0xC8, 0xA9, 0xE7, 0x93, 0x28,
        0x0F, 0xA7, 0x4F, 0xF2, 0x1A, 0xC2, 0x13, 0x4E,
        0x6B, 0xAE, 0x71, 0x3F, 0x43, 0x89, 0xC9, 0xE7,
        0xDD, 0x05, 0xBB, 0x41, 0x09, 0xB5, 0x5E, 0xB9,
        0x23, 0x51, 0xC0, 0xEB, 0x92, 0x1A, 0x0C, 0x3F,
        0xAC, 0xC5, 0x00, 0x8C, 0xB8, 0x5C, 0x3F, 0x2D,
        0x5F, 0x9A, 0xCE, 0xAE, 0x9B, 0x4B, 0x71, 0x48,
        0x25, 0xFD, 0xE2, 0xB6, 0x26, 0x3F, 0xEE, 0x10,
        0x33, 0x07, 0x4F, 0x59, 0xF0, 0x73, 0xE9, 0x39,
        0x5C, 0x0D, 0x8B, 0xB5, 0xD1, 0xEF, 0xE5, 0xBF,
        0xBB, 0xE1, 0x80, 0xF7, 0xC5, 0x91, 0xC1, 0x72,
        0xAA, 0xB0, 0x5E, 0x7C, 0x53, 0x69, 0x4C, 0x37,
        0x7A, 0xD2, 0x7B, 0x9D, 0x1C, 0xFA, 0x0F, 0xE0,
        0x92, 0x93, 0x40, 0x5D, 0xBE, 0x1C, 0xF8, 0x84,
        0x7A, 0x35, 0x1F, 0x72, 0x77, 0x68, 0xE2, 0xAF,
        0xA5, 0x6B, 0x54, 0xFF, 0x53, 0x7C, 0xCD, 0x9D,
        0x6A, 0x49, 0xD1, 0xCA, 0x74, 0x5F, 0xF5, 0xDB,
        0x54, 0xF8, 0x60, 0xA7, 0x41, 0x66, 0xDE, 0xFF,
        0xB0, 0xB2, 0xF9, 0x21, 0x06, 0xB7, 0x81, 0x4C,
        0x9C, 0xEF, 0xFD, 0x11, 0xD5, 0x63, 0xD8, 0xF3,
        0x3A, 0x81, 0xC4, 0x9D, 0x1B, 0xA8, 0x37, 0x73,
        0x57, 0x26, 0x29, 0xF8, 0xB4, 0x7F, 0x9F, 0xA2,
        0x7D, 0x2A, 0x63, 0x2C, 0x70, 0x08, 0x1E, 0x2E,
        0xE7, 0xED, 0x73, 0xAB, 0xD2, 0x4C, 0x02, 0x7E,
        0xF1, 0x15, 0x26, 0xE1, 0x09, 0x5C, 0x29, 0x13,
        0xDF, 0x69, 0x29, 0x25, 0xE5, 0x68, 0x39, 0x10,
        0x9B, 0xD0, 0x5E, 0xD8, 0xE2, 0xC9, 0x08, 0x61,
        0x63, 0xCD, 0xF9, 0x45, 0xBC, 0x16, 0xDC, 0x80,
        0x4C, 0x0F, 0x61, 0xEE, 0x8F, 0x3B, 0x72, 0xDB,
        0x02, 0x45, 0xF6, 0x78, 0x69, 0x81, 0xFC, 0xE0,
        0x32, 0x2F, 0xC2, 0xAF, 0xCD, 0x4E, 0x8E, 0x52,
        0x03, 0xB5, 0x1C, 0x7C, 0x37, 0x2C, 0x58, 0xD5,
        0xE2, 0x92, 0xA7, 0xE2, 0x49, 0x6C, 0x3F, 0x5D,
        0x7F, 0x2B, 0x26, 0x70, 0x1C, 0x0C, 0x16, 0x7F,
        0x49, 0x30, 0x71, 0x14, 0xEB, 0xBE, 0x13, 0xF4,
        0xF1, 0xAA, 0x5A, 0xCF, 0x98, 0xF2, 0x07, 0x29,
        0xB5, 0x12, 0x84, 0x80, 0x01, 0x46, 0x11, 0xA4,
        0x44, 0xAE, 0x6D, 0xE0, 0x43, 0x7F, 0xFD, 0x5D,
        0x84, 0xB5, 0x6E, 0x3E, 0x55, 0x0D, 0xE8, 0x66,
        0x13, 0xA9, 0x28, 0x5A, 0x10, 0x84, 0x0B, 0xED,
        0x0B, 0x69, 0xF0, 0x19, 0x69, 0x9B, 0x34, 0xB8,
        0x6F, 0xC6, 0x22, 0xD3, 0x25, 0x26, 0x9D, 0x1A,
        0x04, 0x6B, 0x53, 0xA4, 0xDF, 0x12, 0x93, 0xA5,
        0x2C, 0xEE, 0x1C, 0x35, 0xFE, 0x81, 0x6B, 0x67,
        0x81, 0x92, 0x07, 0xE0, 0x9A, 0x02, 0xC9, 0xD8,
        0x59, 0x4D, 0x51, 0xE8, 0xB3, 0x14, 0x55, 0x2F,
        0xDE, 0x26, 0xDB, 0x7C, 0xEB, 0x8D, 0x80, 0x12,
        0x4A, 0x8A, 0x1C, 0x33, 0x74, 0x8E, 0x05, 0xC1,
        0xAF, 0xD6, 0xE8, 0x7B, 0x56, 0x7C, 0x41, 0xE0,
        0xE7, 0x3F, 0x32, 0x5F, 0x25, 0xDD, 0x2F, 0x48,
        0x21, 0x90, 0xC4, 0x04, 0x42, 0x1A, 0x3D, 0x6A,
        0x0E, 0x5D, 0x5C, 0xDB, 0xE2, 0xB0, 0x18, 0x8B,
        0xAC, 0x77, 0xC6, 0xE3, 0x5D, 0x77, 0xC0, 0xA3,
        0x2B, 0x1D, 0x96, 0x29, 0xF8, 0x8E, 0x70, 0xA7,
        0x65, 0xFE, 0xE3, 0x8C, 0x1A, 0xB2, 0x39, 0x75,
        0xB9, 0x45, 0xF2, 0x16, 0x1F, 0x6C, 0xFE, 0x7E,
        0x68, 0x2A, 0xED, 0x96, 0x84, 0x95, 0x47, 0x05,
        0x1D, 0xDE, 0xB7, 0x7B, 0x90, 0xF6, 0xAF, 0x00,
        0x74, 0x7C, 0x47, 0xE0, 0x2E, 0x80, 0xB6, 0x9A,
        0x0D, 0x4B, 0x78, 0xA4, 0x7D, 0xDD, 0x81, 0xE2,
        0x99, 0x27, 0x1F, 0xA7, 0x8F, 0xE4, 0x23, 0xAD,
        0xDF, 0x12, 0x0D, 0xD0, 0x4D, 0x46, 0xC1, 0x32,
        0xE9, 0x70, 0xF4, 0xA0, 0x4E, 0x97, 0xA5, 0x88,
        0xD2, 0x7C, 0x7B, 0xA8, 0x43, 0x26, 0x18, 0x2A,
        0xAE, 0x04, 0xC2, 0x51, 0x28, 0x99, 0x71, 0x69,
        0x1D, 0x96, 0x78, 0xD4, 0x09, 0x88, 0x16, 0x88,
        0xF3, 0xBC, 0xCB, 0x95, 0x08, 0x30, 0xE6, 0x5B,
        0x78, 0x48, 0x41, 0x00, 0x4E, 0x40, 0x44, 0x58,
        0xE6, 0x16, 0x59, 0x63, 0xCF, 0xB4, 0xEE, 0xB5,
        0x05, 0xFD, 0xD1, 0x35, 0xF3, 0x1E, 0xD0, 0x14,
        0x7C, 0xC9, 0xE9, 0x87, 0x7F, 0xFF, 0x41, 0x07,
        0x68, 0x91, 0x06, 0x17, 0x4E, 0x76, 0x66, 0xEE,
        0xCB, 0x6C, 0xF2, 0xDA, 0x9C, 0x93, 0x51, 0xDC,
        0x43, 0x4A, 0x94, 0x49, 0x38, 0x4E, 0xED, 0x7F,
        0x5F, 0x90, 0x77, 0xB4, 0x2F, 0x0F, 0xC5, 0xD9,
        0xF0, 0xF5, 0xF7, 0x21, 0x91, 0x32, 0xFF, 0x9A,
        0x47, 0x09, 0x83, 0xE1, 0x9D, 0x30, 0xA4, 0xF3,
        0x7D, 0x18, 0x97, 0x44, 0xD8, 0x32, 0xFD, 0x5F,
        0xB3, 0x97, 0x49, 0x4E, 0x11, 0xAD, 0xF7, 0x4F,
        0x4E, 0x90, 0x0A, 0x41, 0x87, 0xCF, 0xF5, 0xDA,
        0x8F, 0x6D, 0x7B, 0x35, 0xAE, 0xA0, 0x16, 0xA8,
        0xDE, 0x88, 0x62, 0x26, 0x5F, 0x13, 0x69, 0xFB,
        0x36, 0x7E, 0xF1, 0x86, 0x0C, 0x8E, 0x07, 0xC3,
        0x3F, 0x32, 0x82, 0xB4, 0xD9, 0x83, 0x7C, 0xDF,
        0x3E, 0xF6, 0x58, 0x42, 0x2D, 0x34, 0xDE, 0xA4,
        0x1E, 0x56, 0xDD, 0x18, 0x70, 0x36, 0x81, 0xD0,
        0x44, 0xE3, 0xC4, 0x03, 0xAF, 0x33, 0xD1, 0xE7,
        0xAF, 0xA9, 0x6A, 0x8C, 0x44, 0x35, 0xFE, 0xBB,
        0xA0, 0xD2, 0x5D, 0xE0, 0xE4, 0xAE, 0xDF, 0xFB,
        0x82, 0xA0, 0xBA, 0xDE, 0x76, 0xB6, 0x6C, 0xA9,
        0xBE, 0xC7, 0xE9, 0xD7, 0x3F, 0x1C, 0xB2, 0x9C,
        0xD7, 0x3C, 0xF0, 0x0C, 0x2F, 0x60, 0x44, 0xD8,
        0x34, 0x53, 0xCE, 0xDD, 0xE0, 0x3F, 0x97, 0x2E,
        0xBB, 0x03, 0x20, 0x62, 0xD0, 0xA8, 0x23, 0x9F,
        0xB6, 0x99, 0xEC, 0x89, 0x0D, 0x32, 0x0F, 0x6F,
        0xAF, 0x3D, 0x20, 0x7B, 0xDC, 0x9A, 0xFE, 0xA2,
        0x02, 0x8B, 0x86, 0x99, 0x56, 0x23, 0x43, 0xAA,
        0x50, 0xF7, 0x0A, 0x4E, 0x8C, 0x62, 0xDA, 0xF8,
        0xB8, 0xCC, 0xA7, 0x2D, 0x02, 0x47, 0x63, 0xBA,
        0xEC, 0x25, 0x00, 0x23, 0xEA, 0xE8, 0x25, 0xC6,
        0x51, 0xAC, 0xC4, 0xAA, 0xA0, 0xDB, 0x6C, 0x5E,
        0xC7, 0xEF, 0xD0, 0x71, 0xED, 0xFB, 0x95, 0xAF,
        0x61, 0x0B, 0x64, 0x01, 0x61, 0x4F, 0x4F, 0xC6,
        0x36, 0x27, 0x75, 0xC3, 0x81, 0x0A, 0x9A, 0x21,
        0x69, 0xF8, 0x4A, 0x21, 0x12, 0x3B, 0x03, 0x1C,
        0xCE, 0x08, 0x7D, 0x52, 0x0E, 0x99, 0xE2, 0x62,
        0xE8, 0x81, 0x2E, 0x84, 0x09, 0x8E, 0xBE, 0x9B,
        0xCE, 0xD6, 0xE6, 0xA4, 0xF7, 0x3B, 0x67, 0x45,
        0x41, 0xDE, 0x0B, 0xCF, 0x5E, 0x7E, 0x31, 0x8F,
        0x90, 0x6D, 0x90, 0x1F, 0xEB, 0x1D, 0x9D, 0x1C,
        0xCB, 0x6C, 0xFF, 0xE8, 0x50, 0xDB, 0xFF, 0x75,
        0xC8, 0xA8, 0x9F, 0x43, 0xCB, 0x94, 0x89, 0x5F,
        0x28, 0x69, 0x6F, 0xAB, 0xB6, 0xAD, 0xCE, 0xE7,
        0x69, 0x7E, 0x60, 0x09, 0x03, 0x87, 0x43, 0x6E,
        0x19, 0xB1, 0x38, 0x81, 0x9B, 0x90, 0xAE, 0xB1,
        0x8A, 0xC2, 0x7D, 0x2C, 0x65, 0x9B, 0x0D, 0xF1,
        0x77, 0x94, 0xA7, 0x2F, 0x8B, 0xB7, 0xCE, 0x03,
        0xEE, 0x9A, 0x78, 0xFE, 0x8C, 0x8A, 0x37, 0x45,
        0xD5, 0x05, 0xDE, 0xD8, 0x85, 0x00, 0xF4, 0xCF,
        0x98, 0xFB, 0x62, 0x85, 0xB0, 0xBD, 0x82, 0xE2,
        0x7D, 0xED, 0x93, 0x3B, 0xCC, 0x18, 0x73, 0xF8,
        0x8A, 0xBD, 0x82, 0x8F, 0x60, 0x47, 0xAC, 0xEC,
        0x47, 0x2D, 0xEA, 0xE8, 0x7D, 0x8A, 0xDE, 0x0A,
        0xD0, 0x73, 0x48, 0xFF, 0xAF, 0x59, 0xC1, 0x70,
        0x29, 0xD8, 0x45, 0x38, 0x77, 0x7F, 0x73, 0xBF,
        0xED, 0x5C, 0x63, 0x63, 0x0B, 0xC4, 0x43, 0xE0,
        0xFA, 0x12, 0xDE, 0x72, 0x2D, 0xAB, 0xBB, 0xC2,
        0x25, 0x0A, 0xBA, 0x3F, 0xD8, 0x61, 0x54, 0xEE,
        0x20, 0x8D, 0x53, 0xA3, 0x27, 0xA7, 0xFF, 0x26,
        0xA0, 0x17, 0x93, 0x39, 0x4D, 0x04, 0x15, 0x8B,
        0xB3, 0x20, 0x60, 0x04, 0x47, 0xE2, 0xFD, 0x7D,
        0x7C, 0x6D, 0xE0, 0x76, 0xA5, 0x13, 0xD6, 0x81,
        0x95, 0xB0, 0x67, 0x20, 0x4F, 0xF6, 0x00, 0x5B,
        0x16, 0x25, 0x54, 0x2B, 0x28, 0x37, 0x2F, 0x06,
        0x80, 0x60, 0x53, 0xAE, 0xE2, 0xEA, 0x9F, 0x88,
        0xAE, 0xA2, 0x9A, 0x27, 0x02, 0x15, 0x4B, 0xF4,
        0x43, 0xBC, 0x70, 0x7D, 0x0A, 0x96, 0xEB, 0x06,
        0xCE, 0x43, 0xEF, 0xE6, 0x6A, 0xAC, 0x1F, 0x16,
        0x95, 0xE2, 0x8C, 0xF1, 0x07, 0x19, 0x3D, 0x06,
        0x2E, 0x71, 0xB6, 0x3A, 0xFD, 0xCF, 0x9E, 0x05,
        0x0B, 0xBE, 0xD7, 0x48, 0x4E, 0xC5, 0xE8, 0x0C,
        0x51, 0x5A, 0xC8, 0x20, 0xF0, 0xCD, 0xF9, 0x65,
        0xDD, 0x97, 0xF7, 0xA1, 0x1B, 0x57, 0xB2, 0x1A,
        0x04, 0xBF, 0x42, 0xF2, 0xA3, 0x3D, 0x61, 0x97,
        0x64, 0xDF, 0xB3, 0x63, 0x11, 0xFD, 0xAD, 0x8C,
        0x83, 0xA7, 0x48, 0xBA, 0x34, 0x42, 0xC5, 0x70,
        0x64, 0x5A, 0x78, 0x5E, 0x67, 0x03, 0xE5, 0xBF,
        0x22, 0xE8, 0x46, 0xFC, 0x51, 0x6C, 0xB4, 0x99,
        0x15, 0xFD, 0x63, 0xB6, 0x3E, 0x5D, 0xBF, 0x56,
        0xF5, 0x5E, 0xA4, 0x01, 0x16, 0xD5, 0x03, 0x4B,
        0xBB, 0x94, 0x5F, 0x58, 0xD6, 0x76, 0x95, 0xC7,
        0x96, 0xF1, 0xC1, 0xD0, 0x53, 0xA3, 0xEB, 0x28,
        0xA9, 0x5E, 0x8F, 0x38, 0x8E, 0x80, 0x04, 0xC3,
        0xB2, 0x4F, 0xD5, 0xFC, 0xCA, 0x7B, 0xB1, 0xE3,
        0xB9, 0x9A, 0x9F, 0x3C, 0x94, 0x5E, 0xF8, 0xA5,
        0x35, 0xF1, 0x37, 0x43, 0x20, 0x71, 0xA5, 0xCA,
        0x5B, 0x6F, 0x7D, 0xC7, 0xB8, 0xBC, 0xE5, 0x5A,
        0xD0, 0xF3, 0xB6, 0xCF, 0x1B, 0xCB, 0xB9, 0xCD,
        0x35, 0xE2, 0x41, 0xF8, 0x6E, 0x46, 0x97, 0x27,
        0x26, 0x48, 0xF4, 0x73, 0xDB, 0xD5, 0xB7, 0x68,
        0x1E, 0xF0, 0xC7, 0x84, 0x49, 0xE6, 0xC5, 0xFA,
        0x93, 0x0D, 0x83, 0x2C, 0x85, 0x1E, 0xED, 0x2A,
        0x65, 0x12, 0x19, 0xD7, 0xD9, 0xC3, 0xBB, 0x23,
        0xF3, 0xC6, 0xAD, 0x7E, 0xB7, 0x78, 0x68, 0x54,
        0x1F, 0x3C, 0xEE, 0x09, 0xF5, 0x1E, 0xE0, 0x4E,
        0xBA, 0x1B, 0xBC, 0x29, 0x69, 0x8A, 0xED, 0xD3,
        0xC7, 0xAC, 0xEC, 0x44, 0x29, 0xD7, 0xA4, 0x0C,
        0xFA, 0xBD, 0xA2, 0x29, 0x34, 0x80, 0x16, 0x4F,
        0x37, 0xEC, 0xB6, 0x73, 0xF2, 0xB5, 0xD7, 0x51,
        0x57, 0x43, 0xAF, 0x7E, 0xD0, 0xB6, 0xE0, 0x96,
        0xF0, 0xE2, 0xFE, 0xCE, 0xC8, 0x9F, 0x40, 0xD6,
        0xAF, 0xE0, 0xBF, 0xCD, 0x70, 0x37, 0x91, 0x69,
        0x99, 0x8C, 0xDF, 0x4A, 0x20, 0xDE, 0xB6, 0xC6,
        0x7A, 0xB4, 0xE3, 0x6A, 0xAD, 0x53, 0xED, 0xB9,
        0x8A, 0x13, 0x61, 0xC5, 0xE9, 0xB0, 0xDC, 0x16,
        0x36, 0xD7, 0x51, 0xA8, 0x7B, 0x52, 0x05, 0x3B,
        0xAD, 0x5C, 0xD2, 0xBD, 0x6F, 0x6B, 0xA9, 0x51,
        0xA7, 0xE8, 0x7E, 0xA4, 0xB6, 0x77, 0xAE, 0x00,
        0x89, 0x3A, 0x1F, 0x76, 0x72, 0x3F, 0xC5, 0x6C,
        0x49, 0x4F, 0xB5, 0xCA, 0x2F, 0x5D, 0xAE, 0xF8,
        0x58, 0x9A, 0xE2, 0x5B, 0x54, 0x76, 0xF4, 0xAA,
        0x89, 0xD4, 0x04, 0xAF, 0x1C, 0x26, 0x65, 0xEC,
        0xA1, 0x81, 0x06, 0x2A, 0x4B, 0x5E, 0xD5, 0x90,
        0xB8, 0x26, 0x33, 0x64, 0x15, 0x33, 0x25, 0xAC,
        0x97, 0x9A, 0xCA, 0x1B, 0x64, 0x50, 0x82, 0x8F,
        0x65, 0x6A, 0xD4, 0x47, 0xCF, 0x7E, 0x93, 0x7D,
        0xB3, 0xCB, 0xFE, 0x55, 0x0A, 0x46, 0x93, 0x22,
        0xB5, 0x46, 0xAB, 0xD6, 0x05, 0x59, 0x14, 0x5E,
        0x1B, 0xD4, 0x2D, 0xAF, 0xA3, 0x18, 0xB7, 0xA0,
        0xD7, 0x11, 0x70, 0xDE, 0x81, 0x8B, 0xD6, 0x64,
        0xFD, 0x38, 0xBD, 0x29, 0x92, 0x41, 0x80, 0xC4,
        0x4A, 0x6D, 0x34, 0x1B, 0xF0, 0x59, 0xA0, 0xD6,
        0x48, 0x55, 0xD2, 0xA5, 0xE2, 0x91, 0xB6, 0x71,
        0xF4, 0x90, 0x97, 0x8B, 0x0A, 0xDD, 0x90, 0xEA,
        0x61, 0x9B, 0x30, 0xA6, 0x2F, 0x5D, 0xB4, 0xEE,
        0x7A, 0x10, 0x40, 0x59, 0x89, 0xAC, 0x30, 0x6E,
        0x9C, 0x7B, 0xBC, 0x11, 0x75, 0x38, 0x00, 0x2E,
        0xDF, 0xED, 0x87, 0x47, 0x30, 0xFB, 0xD4, 0x8A,
        0xC6, 0xBE, 0xC7, 0x20, 0xC8, 0x3D, 0x51, 0x05,
        0x67, 0x48, 0xDE, 0xE2, 0xBF, 0x95, 0x5E, 0x7B,
        0xD7, 0xC7, 0x86, 0xDF, 0x68, 0x57, 0xA9, 0x29,
        0xBC, 0xF8, 0xE3, 0x81, 0x62, 0x1B, 0x37, 0x58,
        0xF2, 0xFF, 0xEE, 0xE8, 0x28, 0x08, 0x36, 0x23,
        0x5B, 0x24, 0x68, 0x1E, 0x62, 0xBD, 0x27, 0xC2,
        0x6F, 0xE9, 0x63, 0x67, 0x53, 0xC7, 0x8A, 0xB5,
        0xA7, 0xEF, 0x29, 0xFE, 0x60, 0xAC, 0x29, 0xCF,
        0x67, 0x40, 0x9F, 0xE6, 0x57, 0xCE, 0x65, 0x3A,
        0x2F, 0xDA, 0xA7, 0xF2, 0x0C, 0x50, 0x19, 0xE6,
        0xF7, 0x43, 0x2E, 0x8C, 0xEB, 0x9E, 0x99, 0x92,
        0xE6, 0x46, 0xB7, 0x8D, 0x43, 0x65, 0xFD, 0x02,
        0x17, 0x74, 0x6F, 0x7B, 0xA3, 0x1E, 0x06, 0x9D,
        0x75, 0x4E, 0x05, 0xED, 0x5A, 0x71, 0xFC, 0x5E,
        0x7D, 0x6D, 0x64, 0x5E, 0xAF, 0x41, 0x44, 0xD6,
        0xBC, 0x43, 0x05, 0x5E, 0x6C, 0xDB, 0x89, 0x34,
        0xC7, 0x02, 0x64, 0x08, 0xAE, 0x96, 0x53, 0x5B,
        0xA2, 0xDE, 0xCD, 0x2F, 0x74, 0x56, 0xD6, 0xEC,
        0xA4, 0x23, 0x68, 0xCD, 0x9A, 0xC5, 0x05, 0x7B,
        0x7D, 0x1E, 0x12, 0xF7, 0x7A, 0xA8, 0x7C, 0x43,
        0x7E, 0x7A, 0x43, 0x31, 0x5D, 0xA0, 0x81, 0xE5,
        0x3A, 0xFE, 0x23, 0xB5, 0xBC, 0xC2, 0xF4, 0xCE,
        0x3A, 0x80, 0x06, 0xE8, 0x1E, 0x08, 0xAF, 0x0A,
        0x33, 0xC1, 0xA9, 0x30, 0x7C, 0x8D, 0x5A, 0xC5,
        0x93, 0x89, 0xF2, 0x69, 0x24, 0x11, 0x6C, 0xAB,
        0x0B, 0x87, 0xD5, 0x49, 0xD0, 0x38, 0x3C, 0x27,
        0x4E, 0x8E, 0x85, 0xD4, 0x6E, 0x0F, 0xCD, 0x70,
        0xE3, 0x68, 0x42, 0xCA, 0x4C, 0x8D, 0x6D, 0x0F,
        0x48, 0xF3, 0xED, 0xF9, 0xE9, 0x43, 0x5D, 0xBF,
        0x55, 0x75, 0xF8, 0xEB, 0x78, 0x93, 0x72, 0x75,
        0x8B, 0xF5, 0xBD, 0xE9, 0x9D, 0xA2, 0xB9, 0x81,
        0x83, 0xDB, 0xAC, 0x82, 0xD1, 0xC1, 0x20, 0x03,
        0x72, 0x4D, 0xDC, 0x42, 0xAE, 0xC8, 0x1C, 0x0C,
        0x78, 0x22, 0x77, 0x27, 0x91, 0x50, 0x4C, 0x90,
        0xEA, 0x13, 0x8B, 0x6C, 0x91, 0xDF, 0x5D, 0x25,
        0x36, 0x9C, 0xC2, 0x06, 0x4F, 0xD5, 0xE2, 0xCC,
        0x9D, 0x89, 0x3B, 0xC4, 0x23, 0x5D, 0x88, 0x17,
        0x62, 0x4E, 0xC9, 0xFA, 0xC8, 0xEF, 0x1D, 0x45,
        0xE1, 0xFB, 0x58, 0xB3, 0x8E, 0xBD, 0x8D, 0xAE,
        0x12, 0xFF, 0xA0, 0x37, 0xE0, 0x7F, 0x5B, 0x41,
        0x1D, 0x40, 0x17, 0xAF, 0x95, 0x2D, 0x8C, 0x42,
        0xC6, 0x1A, 0x2A, 0x1E, 0x8E, 0x70, 0x25, 0xD6,
        0xD3, 0xA2, 0x85, 0xAA, 0x17, 0xFF, 0x0D, 0xB4,
        0x39, 0xD0, 0xF2, 0xAF, 0xA0, 0x4F, 0x31, 0x8D,
        0x6D, 0x57, 0x6A, 0xED, 0xC6, 0xF1, 0xE7, 0x67,
        0xA6, 0x6F, 0xB3, 0x9B, 0x72, 0xC6, 0x7F, 0x05,
        0xAF, 0x40, 0x87, 0x12, 0x0D, 0xC8, 0x98, 0x88,
        0x2D, 0xDE, 0xA1, 0x7C, 0x95, 0x32, 0xB2, 0x7A,
        0xB5, 0x9D, 0xE4, 0x0D, 0x75, 0xD4, 0x17, 0x5B,
        0xB4, 0x92, 0x73, 0xAF, 0x87, 0x3A, 0x92, 0xDA,
        0x4D, 0x87, 0xE2, 0x53, 0xCA, 0xE7, 0x2A, 0x52,
        0x64, 0xE0, 0xC1, 0xDE, 0x4C, 0x9C, 0xF9, 0x1A,
        0x1F, 0x3A, 0xD6, 0x05, 0xA0, 0xCC, 0x8D, 0x91,
        0x93, 0x51, 0xF9, 0x37, 0x1A, 0xFC, 0x68, 0xEF,
        0xBC, 0xED, 0x19, 0x8E, 0x4C, 0xD1, 0xB5, 0x8C,
        0xA2, 0x85, 0xDA, 0x02, 0x65, 0xAB, 0xAC, 0xAE,
        0xCA, 0x8E, 0xAC, 0xF0, 0x2A, 0x4F, 0xC7, 0x67,
        0x16, 0x2E, 0x24, 0x7F, 0x73, 0xCD, 0xD7, 0x3E,
        0xE3, 0x27, 0x8A, 0xF9, 0x4A, 0xC4, 0xA8, 0xCB,
        0x2B, 0x01, 0x55, 0x68, 0x34, 0xA3, 0xC0, 0xB8,
        0xD0, 0x6D, 0x05, 0xF2, 0x3B, 0x4C, 0x17, 0x47,
        0xE7, 0x64, 0x53, 0xF4, 0x9D, 0xE0, 0x8D, 0xF8,
        0xEE, 0x0E, 0xA6, 0x25, 0x64, 0x7D, 0x1B, 0xD0,
        0x80, 0xE7, 0x3C, 0x41, 0x97, 0xAE, 0xCB, 0x6A,
        0x23, 0xC2, 0x5F, 0x00, 0xC6, 0xC5, 0x4C, 0x8A,
        0x4C, 0xEF, 0x76, 0x65, 0x95, 0x28, 0xB3, 0x67,
        0x42, 0xEC, 0x17, 0xFF, 0x0E, 0xE3, 0x7B, 0x30,
        0x6D, 0xCC, 0xB8, 0x87, 0xD6, 0x63, 0x36, 0x5D,
        0xC9, 0xE8, 0x1D, 0x51, 0x47, 0xCF, 0xE5, 0x05,
        0x0D, 0xB4, 0x09, 0xDF, 0xAD, 0x88, 0x9C, 0x38,
        0x6F, 0x12, 0xA5, 0xCD, 0x0C, 0x95, 0x53, 0x41,
        0x13, 0xA6, 0xD0, 0xAB, 0xCB, 0x5A, 0x3F, 0x56,
        0xCE, 0x23, 0xEE, 0x32, 0x61, 0x22, 0x79, 0xE8,
        0xBA, 0x23, 0x94, 0x61, 0x25, 0x8E, 0xD6, 0x3E,
        0x78, 0x83, 0xE1, 0x15, 0xBA, 0x05, 0x81, 0xB8,
        0x1A, 0x7F, 0x73, 0xC1, 0xB7, 0x9F, 0x29, 0xA1,
        0x16, 0x2E, 0x6E, 0x84, 0xC7, 0x15, 0xBC, 0x50,
        0x28, 0x5F, 0xD3, 0x8D, 0x4D, 0x6D, 0xC0, 0x87,
        0x68, 0x88, 0x4B, 0xF4, 0xFB, 0x55, 0x85, 0x3D,
        0xA7, 0xB5, 0x47, 0x1E, 0x73, 0xA1, 0x47, 0x8D,
        0xB1, 0xE1, 0xCF, 0xE6, 0x15, 0x3E, 0xC6, 0xC3,
        0x78, 0xDD, 0x6A, 0x3F, 0x42, 0x29, 0x6E, 0x61,
        0x9D, 0xE7, 0x63, 0xFF, 0x2D, 0xDB, 0x83, 0xE5,
        0x15, 0x84, 0xC2, 0x8D, 0xD8, 0x34, 0x2E, 0x92,
        0x9E, 0x15, 0xB7, 0xBB, 0xCF, 0x5D, 0x6E, 0xCB,
        0x87, 0x79, 0xCF, 0x7F, 0x3A, 0x9A, 0xC1, 0x6A,
        0x43, 0x1F, 0x52, 0xA2, 0x34, 0xE6, 0xA3, 0x69,
        0x9D, 0x9E, 0x44, 0x84, 0x0A, 0x4D, 0x3D, 0x48,
        0x5D, 0xA5, 0xD9, 0x03, 0x94, 0xB1, 0x81, 0xEF,
        0x89, 0x98, 0xE6, 0xD1, 0x44, 0x21, 0x83, 0x59,
        0x09, 0xCD, 0xDB, 0x16, 0x7C, 0x8C, 0x38, 0x78,
        0x19, 0x4B, 0x6D, 0x51, 0x4D, 0xF8, 0x63, 0x6D,
        0x4A, 0x14, 0xA1, 0xBE, 0xF3, 0xCA, 0x38, 0x1E,
        0x36, 0xCF, 0x2E, 0x6D, 0x5F, 0xBC, 0xB4, 0x0A,
        0xF0, 0x91, 0x7D, 0x6D, 0xBB, 0x87, 0x5C, 0xFF,
        0x64, 0xCD, 0xCE, 0xCC, 0xCF, 0xB8, 0xBF, 0xB8,
        0x05, 0x45, 0x8D, 0xF8, 0x2C, 0x74, 0xEB, 0x86,
        0x3A, 0x96, 0x9E, 0xD9, 0x8B, 0x9C, 0x46, 0xE7,
        0x17, 0x3C, 0x09, 0x0D, 0xB0, 0x68, 0xB2, 0xD8,
        0x0C, 0xCE, 0x32, 0xDE, 0x51, 0x72, 0xB5, 0xD4,
        0xA8, 0xB9, 0x09, 0xA5, 0xA4, 0xCC, 0x47, 0xFA,
        0x9F, 0x2E, 0xD6, 0x6E, 0x60, 0x69, 0xCD, 0x96,
        0xAB, 0x1F, 0x3E, 0x84, 0x8C, 0x68, 0x72, 0x0F,
        0xEA, 0x32, 0xC5, 0x73, 0x6E, 0x8A, 0xB5, 0x10,
        0x05, 0xFE, 0x42, 0x58, 0x33, 0xF2, 0x07, 0x56,
        0xC1, 0x96, 0x76, 0x23, 0x77, 0x9D, 0x0A, 0xD2,
        0x42, 0xA1, 0x69, 0x06, 0x83, 0xBA, 0xD2, 0xEB,
        0x12, 0x3D, 0x97, 0xAB, 0x23, 0x08, 0x90, 0x15,
        0x51, 0x4D, 0x0C, 0x6A, 0x3B, 0x0F, 0x37, 0x15,
        0x25, 0xC2, 0x3E, 0x5F, 0x53, 0x84, 0x4C, 0x81,
        0xDD, 0xE8, 0x7C, 0xFE, 0x9F, 0x06, 0x5E, 0x11,
        0x68, 0x7D, 0x68, 0x6B, 0x07, 0x2C, 0x19, 0x00,
        0xF5, 0xC9, 0xA7, 0xC3, 0x1F, 0xE8, 0xBA, 0xBE,
        0x9F, 0x09, 0x0C, 0xE2, 0xCB, 0x3B, 0x68, 0x7B,
        0xA8, 0x9E, 0xD8, 0x3C, 0x08, 0x85, 0xDF, 0xF9,
        0x11, 0x2B, 0x52, 0xF6, 0xCE, 0xD7, 0x1E, 0x32,
        0xA4, 0x0A, 0x9A, 0xBC, 0xFF, 0xF4, 0x20, 0xB6,
        0x24, 0x85, 0x84, 0x7F, 0xFF, 0x70, 0x3C, 0xBB,
        0x74, 0x36, 0x42, 0x25, 0x5F, 0xBD, 0x0A, 0x90,
        0x86, 0xA7, 0xB8, 0x3F, 0x9E, 0xDF, 0x43, 0x24,
        0x88, 0x0C, 0x52, 0x08, 0xF7, 0xDC, 0xB1, 0xEA,
        0xC3, 0x38, 0xF9, 0x13, 0x16, 0x65, 0xA0, 0xCA,
        0x6B, 0xF0, 0xD6, 0x12, 0xFB, 0xA6, 0x3F, 0xF7,
        0x13, 0x91, 0x99, 0xB1, 0xDE, 0xE4, 0xEE, 0x1E,
        0x98, 0x9B, 0xE4, 0xA0, 0x3A, 0xA8, 0xAC, 0x4A,
        0x48, 0x3E, 0xCB, 0x9E, 0xB4, 0x1D, 0x22, 0x1F,
        0x59, 0x97, 0x24, 0x8C, 0xFE, 0xDC, 0xBF, 0x6C,
        0xAD, 0x8D, 0xB0, 0xA3, 0x27, 0xFA, 0x28, 0x8F,
        0xD6, 0xAE, 0x31, 0x39, 0x84, 0xFA, 0x61, 0x8F,
        0x7D, 0xD4, 0xEE, 0xBB, 0x13, 0xED, 0x85, 0xC4,
        0x35, 0xC0, 0xAB, 0x07, 0x73, 0xC5, 0xCD, 0xCA,
        0xD4, 0x69, 0x9B, 0x9C, 0x38, 0x2A, 0x1F, 0x37,
        0xF9, 0xDF, 0x8C, 0x3A, 0xE1, 0x57, 0xDF, 0x05,
        0x9F, 0x97, 0x51, 0xCC, 0xA6, 0x93, 0xD5, 0x49,
        0x2A, 0xE9, 0xCD, 0x46, 0x31, 0x22, 0x6E, 0x62,
        0xE8, 0x13, 0x90, 0x64, 0xFF, 0x00, 0x27, 0xCF,
        0xA1, 0x95, 0x4E, 0xE9, 0x36, 0xAF, 0xAD, 0x02,
        0x06, 0xDD, 0x2A, 0xE2, 0x28, 0xB6, 0xDD, 0x65,
        0xCD, 0x9A, 0x9D, 0x5F, 0xF9, 0xC0, 0xCC, 0x48,
        0xC8, 0xC2, 0xE9, 0x8F, 0x5A, 0xE6, 0xE2, 0xC9,
        0x79, 0x7A, 0x83, 0x84, 0xF8, 0xA3, 0xE3, 0xC7,
        0x48, 0xC7, 0x06, 0xFE, 0x6A, 0x36, 0x25, 0xD2,
        0xA2, 0xEB, 0x4A, 0xE2, 0xCA, 0xA0, 0x49, 0x24,
        0x1A, 0x47, 0x8C, 0x1A, 0x77, 0xF5, 0xC9, 0x0D,
        0xDC, 0x94, 0x18, 0x4D, 0x89, 0x80, 0x50, 0x18,
        0x7D, 0x67, 0x00, 0x43, 0xE4, 0xE7, 0x8F, 0x54,
        0xDC, 0x60, 0x84, 0x24, 0xF3, 0xBF, 0x5E, 0x92,
        0xC7, 0x0C, 0x05, 0x49, 0xBB, 0x61, 0x2F, 0x48,
        0x0A, 0xEB, 0xE5, 0xFA, 0x8B, 0x01, 0x33, 0x27,
        0x10, 0x3E, 0xA1, 0x28, 0x33, 0x11, 0x30, 0x1F,
        0x91, 0x47, 0x7B, 0xA6, 0x3E, 0xD4, 0xF9, 0xC2,
        0x8F, 0xA3, 0x4E, 0xBC, 0xA7, 0x61, 0x56, 0x1F,
        0x90, 0x33, 0x54, 0x15, 0x06, 0x21, 0x9C, 0x57,
        0x07, 0xC2, 0xF8, 0xED, 0x81, 0xED, 0x36, 0x15,
        0xC8, 0xAC, 0xAB, 0x12, 0x80, 0xBF, 0x7C, 0x5E,
        0x00, 0xEC, 0x1B, 0x27, 0x58, 0x3A, 0xE9, 0x09,
        0x2B, 0x23, 0x16, 0x69, 0x26, 0xF9, 0xCC, 0x3C,
        0x5A, 0xFB, 0x66, 0xBA, 0x32, 0xF9, 0xAF, 0xAB,
        0xCB, 0xA7, 0xF7, 0x91, 0x6A, 0x82, 0x42, 0xA7,
        0x9D, 0x7B, 0x0E, 0xD3, 0x5D, 0xF6, 0x52, 0x6D,
        0x7D, 0x2B, 0xE6, 0x30, 0x99, 0x01, 0xBD, 0xC0,
        0x3D, 0x15, 0x95, 0xC2, 0x67, 0x19, 0xD9, 0x0F,
        0xC0, 0x79, 0x1E, 0xAB, 0xA7, 0x67, 0x35, 0x12,
        0x53, 0xB0, 0x6A, 0xE4, 0xB9, 0x0A, 0x52, 0xEF,
        0xBD, 0xCD, 0xD4, 0x0C, 0x09, 0x6F, 0x24, 0xE9,
        0x52, 0x9F, 0xF8, 0x9F, 0x95, 0x95, 0x57, 0x07,
        0x5F, 0xC8, 0xDD, 0xAF, 0xE6, 0x10, 0x3A, 0x51,
        0x38, 0xF0, 0x9F, 0xBD, 0xEB, 0x0F, 0x5F, 0x36,
        0xB5, 0x2A, 0x57, 0xBE, 0x21, 0x39, 0xD8, 0x9D,
        0x29, 0x04, 0xBC, 0xE2, 0xB8, 0x6D, 0x03, 0xF2,
        0x6D, 0x56, 0xF4, 0x18, 0x40, 0x07, 0x1A, 0x15,
        0x8B, 0xF5, 0x46, 0xE1, 0x0C, 0x4D, 0xED, 0x0E,
        0x81, 0xB0, 0x0D, 0x98, 0x88, 0xC5, 0x5D, 0x53,
        0xE1, 0x1D, 0xB7, 0x00, 0x26, 0xC6, 0x46, 0x7E,
        0xD2, 0xAB, 0x0B, 0xD9, 0x1E, 0xE0, 0xE7, 0xC3,
        0xC3, 0xE0, 0x83, 0x7F, 0x8C, 0xB9, 0xBA, 0xE0,
        0x04, 0xE2, 0xA8, 0xFF, 0xEC, 0xD5, 0x9E, 0x79,
        0x2F, 0x13, 0xF9, 0x27, 0xCA, 0xDD, 0xF5, 0x0F,
        0x74, 0xD2, 0x9B, 0xC6, 0x2E, 0xF2, 0xF0, 0x2A,
        0xB0, 0xF9, 0x6E, 0x27, 0x3E, 0x8D, 0x66, 0xDB,
        0x44, 0x82, 0xDD, 0x1B, 0xD5, 0xBB, 0x51, 0x6E,
        0x72, 0x3A, 0xCB, 0x0F, 0x0B, 0x97, 0xBC, 0x32,
        0x07, 0xC1, 0x0C, 0xF3, 0x94, 0xFF, 0x62, 0xE2,
        0xFD, 0x7D, 0xBB, 0x3D, 0x43, 0x11, 0xB3, 0xFA,
        0x22, 0x05, 0xBF, 0x87, 0x0F, 0xFD, 0xD1, 0x81,
        0xC6, 0x30, 0xC6, 0x91, 0xD4, 0xEE, 0xA8, 0x6B,
        0x37, 0xB2, 0x38, 0xF1, 0x87, 0x89, 0xE0, 0x04,
        0x09, 0xED, 0x18, 0xA6, 0x3C, 0x18, 0x9E, 0x38,
        0xCB, 0x9F, 0xFE, 0xB3, 0x03, 0xF4, 0xE4, 0x3F,
        0xB3, 0x94, 0x7C, 0x74, 0x03, 0x6C, 0xCF, 0x16,
        0x24, 0xF8, 0x56, 0xE2, 0x4A, 0x7E, 0x9A, 0x21,
        0xB8, 0xC2, 0x7C, 0xF4, 0x3D, 0x85, 0x15, 0x43,
        0xA5, 0xCA, 0xFD, 0xA3, 0x05, 0xCC, 0x63, 0x8D,
        0x94, 0x82, 0x70
    };
    static const byte rnd_87[] = {
        0x16, 0xB8, 0x2B, 0x9B, 0x0A, 0x90, 0x5B, 0xB3,
        0xD8, 0x7B, 0x4A, 0x1E, 0x40, 0xAE, 0xAD, 0x3C,
        0xDE, 0x63, 0xB2, 0x2C, 0xB7, 0x16, 0xBD, 0x46,
        0x7A, 0x7B, 0xE8, 0x4A, 0xF1, 0x9B, 0x7C, 0xFE
    };
    static const byte sig_87[] = {
        0xE5, 0x5D, 0x62, 0x56, 0x92, 0x73, 0x72, 0x13,
        0xDD, 0x3D, 0x7F, 0x51, 0x42, 0xF3, 0xAA, 0x33,
        0x87, 0x12, 0x2F, 0x20, 0xC9, 0x50, 0x93, 0x0A,
        0x7E, 0x7C, 0xCC, 0x0C, 0x6D, 0x21, 0xB9, 0x5D,
        0x62, 0x47, 0xD5, 0xFB, 0x3A, 0xCC, 0xBC, 0xB8,
        0xA1, 0x5A, 0xDF, 0x97, 0x58, 0xBA, 0x7E, 0x40,
        0x9A, 0x76, 0xD0, 0x1C, 0xBF, 0x0F, 0x14, 0xC3,
        0x23, 0x3B, 0x21, 0xB0, 0x5D, 0x11, 0x3B, 0x1F,
        0x70, 0xCB, 0x21, 0x78, 0x51, 0x68, 0xE2, 0x3A,
        0x29, 0x4A, 0x0D, 0xD0, 0x32, 0x50, 0xDC, 0xBB,
        0xD1, 0xCF, 0x80, 0x19, 0x7A, 0xC7, 0xFC, 0x37,
        0x2D, 0x5A, 0x5A, 0xDF, 0x3E, 0x7E, 0x89, 0x2D,
        0xC6, 0x0E, 0x75, 0x9A, 0xBB, 0xDF, 0x69, 0x82,
        0x28, 0xB6, 0xD0, 0xF3, 0xF4, 0xCB, 0x4F, 0xD5,
        0xDC, 0x5D, 0xFE, 0x8D, 0x01, 0xB4, 0x93, 0x9F,
        0x89, 0x53, 0x18, 0x74, 0x29, 0x20, 0x36, 0xBF,
        0x34, 0xCA, 0x71, 0x2B, 0x01, 0x14, 0xFB, 0x66,
        0x94, 0x28, 0x81, 0xF1, 0xF1, 0x7E, 0x80, 0xB6,
        0x4E, 0x0E, 0x9E, 0x9E, 0x60, 0xD7, 0x6A, 0xFB,
        0x59, 0xC7, 0x96, 0x9F, 0xB4, 0x9C, 0x98, 0x72,
        0x06, 0xC1, 0x6C, 0xAA, 0x8E, 0xC7, 0x48, 0xE6,
        0xC3, 0xAD, 0x8B, 0x4E, 0xF7, 0x81, 0x92, 0x74,
        0xC0, 0x5A, 0x2B, 0x54, 0x8D, 0x47, 0x15, 0xAC,
        0xED, 0x45, 0x69, 0xD0, 0x7C, 0x28, 0x80, 0x18,
        0xA3, 0x9F, 0xB7, 0x14, 0xC6, 0x51, 0xF9, 0x02,
        0x70, 0x98, 0xD9, 0xC1, 0x09, 0xC0, 0xD7, 0xCE,
        0x8B, 0x81, 0x7B, 0x30, 0x99, 0x4C, 0x85, 0x1C,
        0xFA, 0xAE, 0xBF, 0x05, 0x95, 0xBB, 0x6E, 0x01,
        0xE4, 0xFC, 0xE7, 0x11, 0x16, 0x90, 0x28, 0xC3,
        0xC4, 0x36, 0x9F, 0x11, 0xCD, 0xEB, 0xEB, 0x71,
        0x15, 0x08, 0x1D, 0x43, 0x2B, 0x12, 0xA6, 0x4E,
        0xB6, 0xF9, 0x35, 0xE4, 0x37, 0x0D, 0xF7, 0x49,
        0xDF, 0x73, 0x4D, 0xE3, 0x57, 0x33, 0x96, 0x7B,
        0x72, 0x45, 0x2F, 0x92, 0x70, 0xBB, 0x6F, 0xCD,
        0x90, 0x82, 0x67, 0xBB, 0x31, 0x9D, 0x9E, 0x38,
        0x75, 0xCD, 0x5B, 0x55, 0x10, 0x6B, 0xFC, 0x00,
        0x15, 0xC8, 0xCB, 0xFC, 0xE1, 0x18, 0x41, 0xE8,
        0x6E, 0x92, 0xEC, 0x1A, 0x26, 0x88, 0x6C, 0xF6,
        0x2A, 0x5C, 0x05, 0x94, 0xD7, 0xB8, 0xD0, 0x78,
        0x52, 0x68, 0x8D, 0xC5, 0xBD, 0xD6, 0x29, 0xF8,
        0x21, 0xDF, 0xB3, 0x28, 0x43, 0x74, 0xC7, 0x0E,
        0x99, 0xD3, 0x0C, 0xDE, 0xE9, 0x06, 0x44, 0xCD,
        0x77, 0x13, 0x34, 0x82, 0xBA, 0x36, 0x20, 0x71,
        0x02, 0xB1, 0x6E, 0xBA, 0xCF, 0x9F, 0x15, 0x36,
        0xC8, 0xF1, 0x4E, 0x36, 0x30, 0x34, 0x2D, 0x23,
        0x6C, 0x77, 0xEC, 0xCA, 0xBA, 0x7C, 0x17, 0x4F,
        0x3F, 0x22, 0x4A, 0x34, 0xA1, 0x5C, 0xB3, 0x8F,
        0xD8, 0x48, 0xD5, 0x8A, 0x2C, 0x8B, 0x1B, 0xFB,
        0x87, 0xDA, 0xBC, 0xB6, 0xD9, 0x59, 0xD6, 0x9B,
        0xF0, 0x6E, 0x8D, 0xB1, 0x52, 0xE1, 0x8A, 0x36,
        0x31, 0xA7, 0x83, 0xCE, 0xDF, 0x36, 0xEB, 0xBE,
        0xEA, 0xC3, 0xC6, 0xA6, 0x52, 0x2D, 0x89, 0x0B,
        0xF9, 0x5B, 0x1D, 0x14, 0xA9, 0xBF, 0x37, 0x31,
        0xE0, 0x1C, 0xF5, 0x29, 0x95, 0xF0, 0xC0, 0x08,
        0xE8, 0x97, 0xEE, 0x53, 0x27, 0x85, 0x81, 0x7D,
        0x47, 0xE5, 0xAC, 0xC5, 0x1B, 0x48, 0xA5, 0x36,
        0x1E, 0x8A, 0xD7, 0xF5, 0xC9, 0x93, 0x74, 0xCE,
        0x06, 0xEA, 0xC3, 0x26, 0x45, 0xFF, 0xED, 0x39,
        0xC1, 0x0B, 0x7A, 0x59, 0x3C, 0x0F, 0xEE, 0x89,
        0xEF, 0xA4, 0xEC, 0xD0, 0x72, 0x34, 0x95, 0xC9,
        0xC4, 0x78, 0x47, 0xB6, 0xB7, 0xCE, 0xA4, 0xD9,
        0xA1, 0xB6, 0x37, 0xC1, 0xF1, 0xFB, 0x4E, 0x4C,
        0x38, 0xB0, 0x4A, 0xE5, 0x13, 0x63, 0xDC, 0x44,
        0xC4, 0x7E, 0x86, 0x9C, 0xAD, 0x69, 0x29, 0xFD,
        0xA1, 0xFE, 0xAD, 0x3B, 0x59, 0x24, 0x2F, 0x70,
        0xAE, 0x5F, 0x2C, 0x00, 0xFE, 0x01, 0x09, 0xA3,
        0x10, 0x87, 0xF0, 0xAD, 0xFA, 0x9B, 0x83, 0x8F,
        0x48, 0x96, 0x8B, 0x9A, 0x35, 0xE7, 0x4D, 0xAA,
        0xEC, 0xA4, 0xCD, 0x26, 0x7C, 0x3E, 0xAC, 0x93,
        0x26, 0x9D, 0x6B, 0x83, 0x34, 0xC4, 0x71, 0xE1,
        0xC8, 0x93, 0x88, 0x09, 0xAF, 0x00, 0xB5, 0x7F,
        0xD9, 0x5A, 0x8E, 0x36, 0xC1, 0x2E, 0x7E, 0xF1,
        0x0C, 0xC5, 0x2A, 0xB3, 0xE4, 0x48, 0xDF, 0xFB,
        0xFF, 0x99, 0xC9, 0x66, 0xD2, 0x28, 0x46, 0x7C,
        0x43, 0x39, 0x96, 0x69, 0x95, 0x42, 0xAC, 0xE0,
        0xC2, 0x0C, 0x65, 0x99, 0xC8, 0xB0, 0xAE, 0x76,
        0xE8, 0x18, 0x3E, 0xA9, 0x1D, 0x44, 0x81, 0x14,
        0x65, 0xF7, 0xDF, 0xD1, 0xD1, 0x7B, 0x7C, 0x28,
        0xE0, 0x77, 0x9D, 0x79, 0x9C, 0xE4, 0x1A, 0xF1,
        0xD0, 0xFF, 0x8E, 0xEA, 0x58, 0x84, 0xB3, 0x47,
        0xBC, 0xA1, 0x47, 0x48, 0xB7, 0xC3, 0xD5, 0xD1,
        0xF3, 0xDD, 0xA6, 0x3B, 0x15, 0x4C, 0xB3, 0xB5,
        0xFD, 0x52, 0x9D, 0x7E, 0xF0, 0xC7, 0x40, 0x2C,
        0x34, 0xBC, 0xCF, 0x1C, 0x67, 0x30, 0xC0, 0x4D,
        0xA1, 0xC7, 0x5E, 0xAD, 0xAF, 0xCD, 0xFA, 0x21,
        0xE4, 0xB5, 0x33, 0x8B, 0x37, 0x2D, 0xCF, 0x4D,
        0x07, 0x48, 0x61, 0xB0, 0xB6, 0x8B, 0x27, 0x05,
        0xA0, 0x8C, 0x71, 0x95, 0x84, 0x02, 0xB2, 0x1E,
        0x59, 0xBC, 0xB6, 0xE2, 0x2C, 0x3C, 0x20, 0x4C,
        0xDE, 0x1E, 0x35, 0x24, 0xC1, 0x5B, 0x3C, 0xB4,
        0x2A, 0x8C, 0xA7, 0x2D, 0xE3, 0xDC, 0x45, 0x26,
        0x6E, 0x29, 0x52, 0x5D, 0x24, 0x8A, 0xC2, 0x16,
        0x73, 0xDB, 0x80, 0xF2, 0x91, 0xEC, 0x05, 0x3E,
        0x2E, 0x9E, 0x39, 0x12, 0x5E, 0x11, 0x80, 0x24,
        0xF5, 0xFC, 0x86, 0x4C, 0xD9, 0xF9, 0x70, 0x59,
        0xC8, 0xC8, 0x57, 0x5D, 0x0F, 0x68, 0x75, 0x3C,
        0x7A, 0x3D, 0x1B, 0xF7, 0xD0, 0xDF, 0xE2, 0xF9,
        0xBD, 0x44, 0xFD, 0x21, 0x75, 0x86, 0x77, 0x25,
        0xAF, 0xD3, 0x28, 0x55, 0x2A, 0x60, 0x7D, 0x79,
        0x9C, 0x72, 0x2F, 0x6E, 0xAB, 0x2F, 0x26, 0x44,
        0x0C, 0xFF, 0x52, 0xBD, 0xA1, 0xA9, 0x07, 0xBD,
        0x9D, 0x2A, 0x64, 0x2E, 0x0B, 0xA1, 0xB8, 0x78,
        0xD3, 0xC4, 0x84, 0x9A, 0xE1, 0xDB, 0xB4, 0x4A,
        0x4C, 0x45, 0x7A, 0x8E, 0xD5, 0xA3, 0x6B, 0x09,
        0x8D, 0x72, 0x8E, 0x6D, 0x17, 0x34, 0xFF, 0xD6,
        0xED, 0x24, 0x19, 0x7D, 0xC6, 0x2D, 0x5B, 0x82,
        0x68, 0xAE, 0x25, 0x33, 0xBB, 0xCB, 0x7D, 0xFD,
        0x00, 0x15, 0x83, 0xEA, 0xBB, 0xE7, 0x40, 0x3D,
        0x80, 0xD5, 0x9E, 0x6C, 0xE0, 0x3C, 0x7E, 0x3E,
        0x12, 0xC7, 0x36, 0x7E, 0x41, 0x84, 0xE8, 0xB4,
        0x16, 0xCA, 0x4A, 0xB7, 0xEB, 0x16, 0xEC, 0xAB,
        0x5A, 0x69, 0x24, 0x7F, 0x5E, 0x81, 0x86, 0x7D,
        0x30, 0x61, 0x4E, 0x0F, 0x75, 0x39, 0xEE, 0xF2,
        0xF4, 0xDC, 0x5E, 0x23, 0x40, 0xE8, 0x3C, 0xC0,
        0x10, 0xAD, 0x5E, 0xE6, 0x06, 0x8E, 0x5F, 0x55,
        0xC5, 0x69, 0x65, 0x5F, 0xA3, 0x6E, 0x73, 0x86,
        0x82, 0x32, 0x5F, 0x36, 0xA7, 0x6B, 0x2C, 0x26,
        0xCD, 0x64, 0xC8, 0x57, 0x1F, 0x06, 0x7A, 0xAB,
        0x8B, 0xA7, 0xDB, 0x53, 0x48, 0x1A, 0x06, 0x8D,
        0x36, 0xF1, 0x77, 0x74, 0xE6, 0xF5, 0x18, 0x62,
        0x8E, 0x8A, 0xBF, 0xB7, 0x7F, 0x72, 0x44, 0xAC,
        0xC8, 0x9A, 0x0E, 0x60, 0x4B, 0xAB, 0xB2, 0x9E,
        0x95, 0xDF, 0x95, 0x28, 0x98, 0x78, 0xBB, 0xA9,
        0x5D, 0x8E, 0xEE, 0xB4, 0x84, 0xF5, 0x81, 0x7E,
        0xA1, 0x53, 0x3E, 0xBB, 0x43, 0xF6, 0xD4, 0xB7,
        0x60, 0xFD, 0xF4, 0xF8, 0x68, 0xB6, 0x1D, 0x9A,
        0xF7, 0xDA, 0x77, 0xFA, 0xBB, 0x74, 0x44, 0xDE,
        0x7C, 0x32, 0x2D, 0x5C, 0x24, 0xD8, 0x4D, 0xBF,
        0xE0, 0x5C, 0x70, 0x12, 0x3C, 0x43, 0xCC, 0x5F,
        0x00, 0xD5, 0x1F, 0xEA, 0x5D, 0xC9, 0x3A, 0x5C,
        0x32, 0xED, 0xE0, 0xF1, 0x59, 0xA0, 0xB7, 0x71,
        0xDC, 0x65, 0xD2, 0x88, 0x20, 0x20, 0xD8, 0x59,
        0x53, 0x2D, 0x30, 0x2D, 0xFC, 0xA9, 0xEA, 0x45,
        0xB0, 0xF3, 0x1E, 0x66, 0x9F, 0xF6, 0xF1, 0x5E,
        0x9B, 0x67, 0x1D, 0xBF, 0x5E, 0x19, 0xB3, 0x2A,
        0xE8, 0xCE, 0xE5, 0x90, 0xFE, 0x82, 0x5C, 0x19,
        0x7B, 0x84, 0x3E, 0x45, 0xFF, 0x5D, 0xC2, 0x2E,
        0x49, 0x6A, 0xB1, 0x2D, 0x50, 0x2D, 0x21, 0xF7,
        0x2A, 0xA2, 0x39, 0x47, 0x8D, 0xB5, 0x17, 0x64,
        0x3E, 0x96, 0x13, 0x90, 0x53, 0xEA, 0x57, 0x4C,
        0xDB, 0x3D, 0x43, 0xC3, 0xE7, 0xD6, 0x5C, 0x54,
        0x89, 0xDF, 0x6E, 0xF9, 0xE4, 0xC6, 0x64, 0xF0,
        0x88, 0x1C, 0xD0, 0xF6, 0x9D, 0x9E, 0xD7, 0xCD,
        0x2C, 0xFB, 0xCC, 0x54, 0x0E, 0x96, 0xD7, 0x4E,
        0x05, 0xD2, 0xB3, 0x88, 0x85, 0xD8, 0x60, 0xA4,
        0xF2, 0xE4, 0xD7, 0xFF, 0xAF, 0x12, 0x2E, 0xBA,
        0xC4, 0x5A, 0x3A, 0x3E, 0xC5, 0xD7, 0xF3, 0x60,
        0x4F, 0x27, 0xEF, 0xE0, 0x35, 0xAC, 0x4A, 0x8B,
        0x14, 0x7D, 0xC4, 0xEF, 0x61, 0x9A, 0x69, 0x2E,
        0x49, 0x80, 0x04, 0x0C, 0x18, 0xB9, 0x42, 0xC6,
        0x8C, 0x8A, 0x99, 0x43, 0xA6, 0x5A, 0xCD, 0x72,
        0x20, 0xAD, 0xFD, 0x9C, 0xC4, 0xAA, 0xDF, 0x6C,
        0x6C, 0x03, 0xEF, 0x48, 0x3E, 0xFB, 0x4A, 0xBC,
        0xAA, 0x44, 0xEE, 0xC4, 0x25, 0x8F, 0xF9, 0x8A,
        0xC2, 0x24, 0x73, 0x15, 0xFA, 0x0E, 0xCB, 0x00,
        0xEE, 0x9B, 0x39, 0x3F, 0x60, 0x1F, 0x00, 0x95,
        0xCA, 0xFE, 0xC2, 0x2C, 0x35, 0x5F, 0xD9, 0xD1,
        0x29, 0xB5, 0x4D, 0xC1, 0x66, 0x51, 0x8F, 0x17,
        0x3B, 0xF4, 0xF1, 0x49, 0x42, 0x36, 0x0C, 0x5B,
        0x58, 0xF2, 0x9B, 0x59, 0x01, 0xFB, 0x15, 0x7F,
        0x21, 0x90, 0x1F, 0x56, 0x69, 0x8B, 0xE2, 0xA5,
        0x44, 0xCB, 0x84, 0x98, 0x4B, 0x75, 0xA8, 0xCB,
        0x83, 0x0D, 0xE8, 0x1C, 0x91, 0x7F, 0xE4, 0x57,
        0x81, 0x16, 0x34, 0x2F, 0xCE, 0x01, 0xAA, 0x62,
        0x54, 0x44, 0xB7, 0xD6, 0xC7, 0xF1, 0x68, 0x9A,
        0x00, 0x3B, 0x71, 0x16, 0xF9, 0x96, 0x6A, 0x90,
        0x6C, 0x2C, 0x4E, 0x58, 0xBC, 0xDD, 0xE9, 0x3B,
        0x60, 0xB7, 0xA0, 0x97, 0xEE, 0xD6, 0x34, 0xDD,
        0x49, 0x4A, 0xD9, 0x85, 0xD1, 0xB7, 0x95, 0x14,
        0xEC, 0x6A, 0x40, 0xE8, 0x31, 0x80, 0xF1, 0xD8,
        0x5F, 0x75, 0xF6, 0x92, 0x3A, 0x4F, 0xCD, 0x0A,
        0x6E, 0xBF, 0xA1, 0x27, 0x48, 0x79, 0x27, 0x04,
        0x76, 0x2C, 0xAB, 0x25, 0x06, 0xEB, 0x43, 0xDD,
        0x1B, 0x4B, 0x24, 0xFC, 0x93, 0x51, 0x1C, 0x45,
        0xF6, 0xAE, 0x77, 0xCF, 0xC9, 0xE6, 0x20, 0xE4,
        0xA5, 0x2B, 0x3D, 0x7D, 0xF0, 0xEB, 0x51, 0x7C,
        0xCA, 0xFE, 0x58, 0xBA, 0xC4, 0x07, 0x95, 0x75,
        0x62, 0x0C, 0x50, 0x68, 0x88, 0x1A, 0x8A, 0x0D,
        0x1B, 0x5C, 0x53, 0x1A, 0x9C, 0xA8, 0x4E, 0xFE,
        0x63, 0x9B, 0xDB, 0x05, 0x70, 0x01, 0x75, 0xA1,
        0x3A, 0x08, 0xFA, 0x51, 0xD5, 0xF6, 0x81, 0xDE,
        0x69, 0xE5, 0x40, 0xB3, 0xF8, 0x7C, 0x46, 0x97,
        0xA6, 0x4E, 0xA8, 0x51, 0x47, 0x9C, 0xB9, 0x25,
        0xCD, 0x4E, 0xED, 0xFC, 0xEE, 0x03, 0x6A, 0xCD,
        0x93, 0x65, 0xB3, 0x68, 0x09, 0x6F, 0xE8, 0x00,
        0x6A, 0x3F, 0xBF, 0xE8, 0x6F, 0x09, 0xE9, 0xF2,
        0x6F, 0x44, 0x2E, 0xB1, 0x81, 0x76, 0x04, 0xDD,
        0x6E, 0xF4, 0x93, 0x61, 0xE5, 0x78, 0xD4, 0xDA,
        0xBF, 0x05, 0xA1, 0xF4, 0x9D, 0xFD, 0x57, 0x06,
        0x9C, 0x13, 0x45, 0x97, 0xF2, 0x48, 0xE6, 0x1A,
        0xB5, 0xAD, 0x09, 0x11, 0x04, 0xBB, 0xA0, 0xA8,
        0xA3, 0xA3, 0x33, 0xCD, 0x42, 0x2C, 0x66, 0xC2,
        0x94, 0x80, 0x15, 0x9D, 0x56, 0x74, 0x02, 0xEE,
        0xA7, 0xE4, 0x90, 0xDD, 0xFB, 0x0B, 0x3B, 0xF0,
        0x7A, 0x02, 0x44, 0xE8, 0x11, 0xC4, 0x3A, 0xFE,
        0x73, 0x2A, 0x4C, 0x92, 0x3C, 0x23, 0x37, 0x8B,
        0x4F, 0x28, 0x8E, 0x1C, 0x4E, 0x7D, 0x0D, 0x6B,
        0xFD, 0x20, 0xB5, 0x93, 0xB3, 0x75, 0x30, 0x28,
        0xC7, 0x7E, 0x67, 0xC4, 0xDE, 0xDA, 0x27, 0xA9,
        0xE3, 0xF2, 0xF5, 0x25, 0x98, 0x5F, 0x6B, 0xBE,
        0x11, 0x80, 0x23, 0x49, 0x30, 0xC8, 0x8A, 0x63,
        0xF9, 0xC4, 0x14, 0x77, 0x2A, 0xE2, 0x21, 0x42,
        0x28, 0x1C, 0xEB, 0x9F, 0x7B, 0x70, 0xA8, 0x2B,
        0xFB, 0x25, 0x36, 0xA6, 0xAC, 0xFE, 0x8E, 0xFF,
        0xB6, 0x86, 0x09, 0x15, 0x7E, 0xD9, 0x26, 0x8F,
        0xDB, 0xF2, 0x2D, 0xC2, 0xFA, 0xAE, 0xDA, 0x50,
        0xF6, 0x24, 0x53, 0xDB, 0xBF, 0x92, 0x9D, 0x7E,
        0x48, 0xCC, 0x75, 0xAC, 0xD0, 0xD3, 0x45, 0x09,
        0x2F, 0x01, 0x60, 0xBB, 0xAE, 0xCB, 0xE6, 0xB3,
        0x30, 0xDA, 0xD9, 0xB6, 0x12, 0xCD, 0xF5, 0x11,
        0xCF, 0x2B, 0x2A, 0xC6, 0x61, 0x9A, 0x05, 0x59,
        0x08, 0x58, 0x64, 0xEC, 0xDB, 0x77, 0xCF, 0x64,
        0xE2, 0x4B, 0x6E, 0xF4, 0x07, 0x68, 0x5E, 0xE9,
        0x31, 0xB1, 0x38, 0x67, 0xF9, 0x29, 0x2E, 0x7A,
        0xD2, 0x03, 0xA6, 0x29, 0x3F, 0x22, 0x58, 0x66,
        0x6A, 0x07, 0xD8, 0xFD, 0xC5, 0x03, 0xEE, 0x66,
        0xD4, 0x66, 0x70, 0x6D, 0xA4, 0xC4, 0xA1, 0xEE,
        0xCD, 0x4D, 0xFA, 0x3C, 0x34, 0x36, 0xC2, 0xC5,
        0x1E, 0x86, 0xB8, 0x7B, 0x7C, 0xBC, 0x67, 0x16,
        0xF3, 0x6E, 0xF2, 0xB7, 0xEA, 0x96, 0x1B, 0x0D,
        0xA2, 0xC8, 0x42, 0xBF, 0x30, 0x09, 0x2A, 0x6D,
        0x9D, 0x35, 0xB3, 0x92, 0xBA, 0x3E, 0xE2, 0xE9,
        0xE2, 0xAA, 0x90, 0x70, 0xCE, 0x0F, 0x07, 0xFA,
        0x7C, 0x3B, 0xF7, 0x66, 0x7F, 0x5C, 0xFE, 0xD9,
        0x72, 0x1C, 0x4E, 0xFE, 0x7E, 0x86, 0x8E, 0x7F,
        0x62, 0x8D, 0x41, 0x46, 0x7B, 0x43, 0x17, 0xB9,
        0x44, 0xED, 0x39, 0x1B, 0x3E, 0xF9, 0x2D, 0xC7,
        0x5C, 0x9D, 0xAC, 0x05, 0x00, 0xC6, 0x85, 0x4E,
        0xB8, 0xBC, 0x29, 0xDF, 0x6D, 0x6A, 0xCC, 0xEB,
        0xD6, 0x44, 0x86, 0xAA, 0xC9, 0x55, 0x49, 0xA1,
        0x3F, 0x59, 0x5E, 0xAF, 0xD5, 0xC9, 0x96, 0x19,
        0x84, 0xC0, 0x4D, 0x1B, 0xE5, 0x2C, 0x42, 0x8D,
        0x2C, 0xC8, 0x83, 0x00, 0x26, 0xBF, 0x46, 0x9F,
        0x20, 0x97, 0xEC, 0x2C, 0xA9, 0x2C, 0xF0, 0xA7,
        0x11, 0xED, 0xE2, 0xA2, 0x57, 0x83, 0x40, 0x92,
        0xF3, 0x58, 0xB7, 0x4E, 0xD6, 0x3A, 0x9D, 0xF0,
        0xDD, 0xD4, 0x5F, 0x82, 0x58, 0xD3, 0x72, 0x05,
        0x69, 0xFF, 0x1E, 0xBC, 0x74, 0x90, 0x87, 0xB5,
        0x7A, 0xEE, 0xF8, 0xCE, 0x3F, 0x59, 0xE1, 0xC0,
        0x46, 0x24, 0xF8, 0x9D, 0x93, 0x51, 0x4A, 0x44,
        0xFB, 0xEA, 0x58, 0xA6, 0xAC, 0x9A, 0x7C, 0xA3,
        0x11, 0xA3, 0x47, 0x44, 0x24, 0x11, 0xF5, 0x56,
        0x1A, 0x3B, 0xCF, 0xEC, 0xD9, 0x2B, 0x6C, 0xBA,
        0xA6, 0xA2, 0x67, 0xB9, 0xE0, 0xCB, 0x3F, 0x8D,
        0xA8, 0xC4, 0x8A, 0x45, 0xAB, 0xE2, 0x10, 0x19,
        0x10, 0xC9, 0xDB, 0x01, 0x64, 0xC0, 0x0B, 0x6F,
        0x3B, 0xA1, 0xE9, 0xEB, 0x74, 0x9A, 0x63, 0x93,
        0xE5, 0x74, 0x3F, 0xD3, 0x7B, 0xEA, 0x8C, 0xD6,
        0x7D, 0x66, 0xDD, 0x90, 0x6C, 0x69, 0x67, 0x05,
        0xAD, 0x70, 0xF1, 0xFA, 0x52, 0xBB, 0xD5, 0x3D,
        0x0E, 0x7E, 0x87, 0xE0, 0x98, 0xAF, 0xA6, 0xE6,
        0x0E, 0x25, 0x91, 0x70, 0xCA, 0x36, 0xE4, 0xF8,
        0xF7, 0x95, 0x1C, 0x48, 0xF6, 0x62, 0x9A, 0x4D,
        0xE4, 0xE7, 0x3A, 0x92, 0xC6, 0x2E, 0xAB, 0x8A,
        0x75, 0x7C, 0x45, 0xDA, 0x54, 0xB1, 0x6D, 0x2E,
        0xCC, 0x13, 0x46, 0x67, 0x8F, 0xFF, 0xDA, 0x18,
        0xE1, 0x4C, 0xE4, 0x6A, 0xB6, 0xAC, 0x65, 0x32,
        0x0C, 0x63, 0xD5, 0x43, 0xB5, 0x8B, 0xB1, 0x52,
        0xEE, 0x0C, 0xBB, 0x62, 0x34, 0x30, 0xDB, 0xF7,
        0x08, 0xC6, 0xE8, 0x5B, 0x07, 0x66, 0x6D, 0x4B,
        0x39, 0xC6, 0x94, 0x2B, 0x22, 0x9E, 0x3E, 0x45,
        0x62, 0x3D, 0x05, 0x03, 0x2B, 0x16, 0x71, 0xBB,
        0x85, 0x1B, 0x6E, 0x84, 0xD3, 0x48, 0x4D, 0x63,
        0x26, 0x60, 0x97, 0x45, 0xB8, 0xEA, 0x43, 0x96,
        0x00, 0xFE, 0x0B, 0x85, 0xBD, 0x22, 0x40, 0xA4,
        0xA7, 0x2F, 0xC1, 0xEB, 0xFD, 0xB5, 0x22, 0xD5,
        0x1F, 0xB3, 0xEA, 0x7C, 0x6D, 0x20, 0xFB, 0x98,
        0xA5, 0xF2, 0x84, 0x70, 0xF7, 0xB9, 0x2A, 0x12,
        0x63, 0x0C, 0x2D, 0x97, 0x6C, 0xC2, 0x76, 0xAC,
        0x32, 0xE2, 0xB1, 0x3A, 0xB3, 0xAB, 0x9E, 0xBB,
        0x61, 0xB4, 0x6A, 0x5F, 0x2D, 0x4D, 0xCE, 0x0D,
        0xFB, 0x97, 0x80, 0x89, 0x4A, 0x81, 0xFB, 0xB2,
        0x72, 0x37, 0x66, 0xB9, 0x08, 0xBF, 0xCD, 0x9F,
        0x63, 0xB2, 0xBA, 0x54, 0xF1, 0x9E, 0xEC, 0x11,
        0x67, 0x26, 0xC7, 0x98, 0xDD, 0xA3, 0xC5, 0x50,
        0x86, 0x17, 0xD5, 0xCF, 0x51, 0x97, 0x22, 0x65,
        0x2B, 0x71, 0xF7, 0x34, 0x84, 0x55, 0xC9, 0xD1,
        0xFE, 0x75, 0x42, 0x0A, 0x5A, 0x31, 0x59, 0xE8,
        0x8A, 0x0D, 0xE5, 0x77, 0x1C, 0xF5, 0xFD, 0x27,
        0x05, 0x05, 0xF7, 0x28, 0xDA, 0x54, 0xAB, 0xBD,
        0xDC, 0x50, 0xB8, 0xDB, 0x2E, 0xB4, 0x28, 0x41,
        0x30, 0x04, 0x40, 0xD5, 0xF0, 0x12, 0xD7, 0x16,
        0x3D, 0x8F, 0x41, 0xE7, 0x70, 0x76, 0x82, 0xB9,
        0xC4, 0xB2, 0x1F, 0x57, 0x10, 0xB6, 0xC4, 0x84,
        0x0D, 0xB1, 0xB8, 0x21, 0xB2, 0x77, 0x09, 0xF6,
        0xD5, 0x9C, 0xE4, 0xA2, 0xFA, 0x83, 0x13, 0x56,
        0x94, 0x3F, 0x37, 0x6D, 0x0D, 0x7C, 0x7E, 0xA0,
        0xE5, 0xC8, 0xD9, 0x42, 0x0F, 0x35, 0xB1, 0xDC,
        0xB9, 0x49, 0xD5, 0xED, 0xA8, 0x90, 0x09, 0x14,
        0xAE, 0x63, 0xB5, 0xEA, 0x62, 0x0D, 0x9E, 0x6D,
        0x93, 0xBD, 0x3A, 0xEA, 0x24, 0xB5, 0xAC, 0xC9,
        0xD1, 0x7B, 0xBC, 0xC6, 0xC4, 0xBA, 0x68, 0xB1,
        0x65, 0xFE, 0xAB, 0x30, 0xD4, 0x92, 0xD9, 0xC1,
        0x94, 0x84, 0xE1, 0x20, 0x4E, 0x28, 0x7C, 0x3A,
        0x3E, 0x8B, 0x44, 0x79, 0xC7, 0xB5, 0xA5, 0x95,
        0xC2, 0xC9, 0xA8, 0x3F, 0x92, 0x67, 0x06, 0x9A,
        0x12, 0xD3, 0xAE, 0x78, 0x87, 0x0E, 0x31, 0x54,
        0x26, 0xDF, 0x97, 0xEB, 0x6C, 0xF3, 0xC9, 0x53,
        0x39, 0xED, 0x50, 0x5A, 0xF9, 0x6A, 0x03, 0x27,
        0x8E, 0xC6, 0x79, 0x5B, 0xD4, 0xD3, 0x57, 0x97,
        0xFD, 0xF5, 0xCB, 0x14, 0xDB, 0xBE, 0x39, 0xB9,
        0x64, 0x8A, 0x75, 0xAA, 0xE3, 0x4A, 0x19, 0x59,
        0x69, 0x7D, 0xF8, 0x7D, 0x8C, 0xB8, 0x2F, 0x32,
        0x57, 0xBF, 0x84, 0x9E, 0x45, 0x4E, 0xC4, 0xA0,
        0x65, 0xA4, 0x0B, 0x73, 0x36, 0xC5, 0xD1, 0x07,
        0xF8, 0x1C, 0x91, 0x07, 0xB8, 0x0B, 0x4B, 0xE5,
        0x4F, 0xE6, 0xA1, 0xDF, 0x29, 0x03, 0xE7, 0x68,
        0xA4, 0x32, 0x8E, 0x21, 0x8F, 0x15, 0x51, 0x57,
        0x65, 0x16, 0xF0, 0x55, 0x71, 0x8C, 0x28, 0xD8,
        0x82, 0xDC, 0x8A, 0xC1, 0xE7, 0x5C, 0xF2, 0xD5,
        0xB8, 0x18, 0x16, 0x9F, 0x63, 0x89, 0x21, 0xF1,
        0xA6, 0xED, 0x21, 0xDA, 0xC8, 0x0A, 0x10, 0x21,
        0x18, 0x98, 0xD0, 0xF2, 0x9E, 0xDE, 0x5A, 0xA1,
        0x51, 0xC9, 0x18, 0x3B, 0x68, 0x79, 0x75, 0xE7,
        0xF4, 0xF9, 0xBF, 0x5F, 0xBE, 0x61, 0x35, 0xA9,
        0x02, 0x56, 0x2D, 0x99, 0xD8, 0x95, 0xFA, 0x78,
        0x8A, 0x67, 0x24, 0x1D, 0xDF, 0x13, 0x14, 0xD0,
        0xB4, 0xB6, 0x21, 0x11, 0xB7, 0xA4, 0x06, 0x8D,
        0x1D, 0xF6, 0xD5, 0x50, 0x2A, 0x0A, 0x42, 0x3C,
        0x7C, 0xF1, 0x1F, 0x15, 0x1C, 0x81, 0x69, 0xDA,
        0xCC, 0xAC, 0x8F, 0xB9, 0x08, 0x4E, 0xF8, 0x4E,
        0x3E, 0x77, 0x26, 0x4A, 0x1F, 0x72, 0x89, 0xCA,
        0x91, 0x77, 0x99, 0xBF, 0x28, 0xD2, 0x31, 0x65,
        0x30, 0x37, 0x84, 0x66, 0x8A, 0x1C, 0xC6, 0x59,
        0x7D, 0x48, 0x9B, 0x4D, 0xDC, 0x87, 0x4F, 0xD2,
        0x04, 0xA0, 0x8B, 0x8B, 0x37, 0x3B, 0x1A, 0xDB,
        0xCF, 0x63, 0x39, 0x07, 0xF3, 0x37, 0xCF, 0x0E,
        0x2F, 0xEB, 0xE6, 0x2A, 0xA1, 0x4C, 0xE0, 0x75,
        0x3F, 0xAB, 0xF7, 0xDE, 0x48, 0x83, 0x79, 0x89,
        0x30, 0xA7, 0x1B, 0xE8, 0x73, 0x8E, 0x9D, 0x1D,
        0xF6, 0x5C, 0x91, 0x4F, 0x44, 0x7C, 0x04, 0xA7,
        0x07, 0xC8, 0xCC, 0x4A, 0x5C, 0x81, 0xAD, 0x48,
        0x7C, 0xE5, 0x19, 0x5A, 0xC4, 0x29, 0x80, 0x14,
        0xFA, 0xC2, 0x26, 0x1C, 0x50, 0x28, 0xB9, 0xF6,
        0x7F, 0x8D, 0x51, 0x9A, 0xDA, 0xBB, 0x8E, 0x90,
        0xBA, 0x3B, 0xD9, 0x4D, 0x61, 0xBE, 0xFD, 0x33,
        0xC0, 0xCA, 0x7B, 0x09, 0xFF, 0x36, 0x84, 0x70,
        0x11, 0xB4, 0xBE, 0x81, 0xFE, 0x71, 0xEE, 0x81,
        0xD7, 0x61, 0xBB, 0x83, 0xA6, 0xA0, 0xDC, 0x20,
        0x04, 0x02, 0x4C, 0x1B, 0x4D, 0xED, 0x8A, 0xC1,
        0x38, 0x70, 0xC3, 0x69, 0xC9, 0x50, 0xC2, 0x17,
        0x64, 0xAD, 0x9D, 0x44, 0x63, 0x44, 0xE5, 0x32,
        0x7B, 0x90, 0xE3, 0xEF, 0x45, 0x28, 0xA6, 0x23,
        0x92, 0xCB, 0xA1, 0xFC, 0xA8, 0xB4, 0x39, 0xF1,
        0xB1, 0x00, 0x1F, 0x06, 0xD4, 0x91, 0x5D, 0xDB,
        0xAC, 0x7D, 0x87, 0xD4, 0xEE, 0xCD, 0x4A, 0x06,
        0x3E, 0xB4, 0x84, 0x65, 0xAA, 0x47, 0x05, 0x41,
        0x7C, 0x95, 0x47, 0x3A, 0x49, 0x80, 0xC5, 0xAC,
        0x32, 0x41, 0x6A, 0x3A, 0x2B, 0xB9, 0xD9, 0x21,
        0x80, 0xC7, 0xC1, 0xD0, 0xC9, 0x95, 0x4B, 0xC3,
        0xEA, 0x0D, 0x3F, 0x0E, 0xE4, 0x5A, 0xD8, 0xBD,
        0x11, 0xD0, 0x76, 0x6D, 0x3C, 0xA7, 0x64, 0xD8,
        0xCA, 0x4C, 0x8F, 0x58, 0x2C, 0xDD, 0x95, 0x1F,
        0xBB, 0x76, 0x8D, 0x10, 0xFD, 0xAD, 0x45, 0xCE,
        0x71, 0x6E, 0x27, 0x92, 0xC4, 0xA6, 0x17, 0x46,
        0x95, 0xDB, 0xD8, 0xEA, 0x9A, 0x5F, 0x0E, 0xE0,
        0x0A, 0xA2, 0xF5, 0x79, 0xC3, 0x74, 0xA7, 0x70,
        0x99, 0x3B, 0x23, 0xD7, 0x3E, 0xA4, 0x96, 0xB5,
        0x54, 0x77, 0x71, 0x8D, 0x78, 0x2E, 0xCC, 0x0A,
        0x4E, 0xF8, 0xA9, 0x96, 0xEE, 0xB4, 0x4B, 0x5B,
        0xDC, 0x52, 0x6D, 0xE1, 0x61, 0x36, 0xE1, 0x32,
        0xD6, 0xA2, 0x7B, 0x2E, 0xCC, 0x78, 0x92, 0xA1,
        0x81, 0x59, 0xB8, 0xC7, 0x04, 0x11, 0x3D, 0xF0,
        0xF9, 0xF9, 0x3E, 0x47, 0x3C, 0xEA, 0xD5, 0x30,
        0x2D, 0xAE, 0xC0, 0x47, 0xC8, 0x61, 0xCC, 0x9C,
        0x2E, 0xC0, 0x40, 0x16, 0x11, 0x73, 0x13, 0xF3,
        0x19, 0xAE, 0x72, 0x44, 0x72, 0xC5, 0x59, 0x51,
        0x2E, 0x9F, 0xE3, 0x07, 0xB0, 0xCA, 0x6B, 0xB0,
        0x15, 0x20, 0xB4, 0x25, 0x00, 0xED, 0xFD, 0xAC,
        0xD6, 0x34, 0x8B, 0xCA, 0xE8, 0xC6, 0x3B, 0xFD,
        0x02, 0x22, 0xE6, 0x91, 0x2B, 0x4B, 0x61, 0xDF,
        0x63, 0x5C, 0x2B, 0x5F, 0x82, 0x07, 0x23, 0x59,
        0x82, 0x5E, 0x0E, 0x21, 0xF7, 0x9C, 0x37, 0x1C,
        0x7E, 0x6F, 0xD4, 0xFA, 0x91, 0x40, 0x8B, 0x98,
        0x68, 0xBD, 0x60, 0x2F, 0x0A, 0xC8, 0xC8, 0x99,
        0xA1, 0xC6, 0x10, 0xF1, 0x27, 0x53, 0xD3, 0xFB,
        0x23, 0x02, 0xE7, 0x8E, 0x95, 0xB1, 0xF0, 0x21,
        0xCB, 0x90, 0xEE, 0x8D, 0xE0, 0x27, 0x57, 0xDE,
        0x40, 0xA3, 0xE7, 0x8F, 0x61, 0xC1, 0x8F, 0xC5,
        0x0C, 0x0F, 0xBA, 0x05, 0xA0, 0x58, 0x8E, 0x86,
        0x8A, 0xF5, 0x72, 0xE1, 0x34, 0xB4, 0xF6, 0x8E,
        0x6E, 0xA4, 0x21, 0x75, 0x43, 0x73, 0xE7, 0x32,
        0x72, 0x80, 0x9B, 0xE7, 0x1D, 0x78, 0x8F, 0x0D,
        0x06, 0x47, 0x9E, 0x4D, 0xB4, 0xAC, 0x3E, 0x0D,
        0xB8, 0x11, 0x23, 0xFF, 0xAD, 0xB9, 0x23, 0xE0,
        0xA4, 0x37, 0xA6, 0x3D, 0xC2, 0x15, 0xF4, 0x64,
        0x03, 0x1F, 0x0A, 0x68, 0xED, 0x37, 0x37, 0xE8,
        0x3E, 0x5B, 0x49, 0x78, 0xFC, 0xFC, 0x12, 0x06,
        0xE8, 0xC7, 0xCD, 0x3A, 0xAF, 0xD4, 0x54, 0xA7,
        0x04, 0x7B, 0xFC, 0x66, 0xA6, 0xA8, 0x1C, 0x38,
        0x0C, 0x26, 0x08, 0xE6, 0xEE, 0x47, 0x25, 0x80,
        0x59, 0xA5, 0x39, 0x81, 0x20, 0xEE, 0x5F, 0x49,
        0x9A, 0x01, 0x37, 0xE9, 0x96, 0x18, 0xD0, 0x05,
        0x2D, 0xE3, 0x73, 0xD5, 0x08, 0x3B, 0x18, 0x46,
        0xFE, 0x9E, 0x67, 0x5B, 0x9E, 0xF8, 0x53, 0x05,
        0x2F, 0x96, 0x18, 0x9C, 0x09, 0x0D, 0xA6, 0x05,
        0xB3, 0x9E, 0x2F, 0x0B, 0x5A, 0xF3, 0x93, 0xFF,
        0x29, 0xF3, 0x4F, 0x62, 0xD5, 0x9A, 0xCE, 0x74,
        0x64, 0xD0, 0xBC, 0xB3, 0x08, 0xF1, 0xD3, 0x22,
        0xA5, 0xBE, 0x64, 0x0A, 0xEB, 0xA5, 0xF5, 0x1B,
        0x7E, 0x0A, 0x44, 0x3B, 0x1D, 0xA9, 0x48, 0x9A,
        0x2F, 0xED, 0x05, 0x0F, 0x44, 0xB3, 0x6D, 0xAD,
        0x39, 0x2C, 0xBA, 0x8E, 0x2B, 0xDE, 0x17, 0x38,
        0xD1, 0x69, 0xEA, 0xAE, 0x4E, 0x97, 0xCD, 0x61,
        0xBA, 0x75, 0x39, 0xF2, 0x81, 0xBB, 0xA9, 0x0F,
        0x6F, 0x82, 0xD4, 0xCB, 0xE4, 0x93, 0x82, 0x11,
        0x72, 0x9A, 0xE9, 0x87, 0xEC, 0xCC, 0x6D, 0xA1,
        0x7D, 0x47, 0x60, 0x20, 0xB6, 0xEE, 0xC6, 0xAA,
        0xC0, 0x3C, 0x95, 0x08, 0xA0, 0x8B, 0xFA, 0x04,
        0xF6, 0x6F, 0x65, 0x48, 0xCA, 0xA7, 0xA3, 0xA8,
        0xBB, 0x3B, 0x80, 0x91, 0xB6, 0x6D, 0x2F, 0x9D,
        0x97, 0xBB, 0x52, 0xE6, 0xC4, 0x24, 0x99, 0x97,
        0x63, 0xAD, 0xD2, 0xFD, 0xB3, 0x94, 0x6D, 0xC1,
        0xFB, 0xFA, 0x89, 0x45, 0x78, 0x80, 0x3C, 0xAA,
        0x3F, 0xC0, 0x7E, 0x8D, 0x37, 0x00, 0xA7, 0x70,
        0xD6, 0x57, 0x2A, 0xD3, 0x17, 0xB1, 0x9E, 0xDF,
        0x96, 0x98, 0x40, 0xB8, 0x1C, 0xCC, 0xC6, 0xCD,
        0xCD, 0xB0, 0xF3, 0x23, 0x53, 0xB6, 0x45, 0x78,
        0xA6, 0xA0, 0x88, 0x61, 0x06, 0x04, 0x8E, 0x1B,
        0xCD, 0x12, 0x29, 0x50, 0x0F, 0xD2, 0x8C, 0x89,
        0x51, 0xD1, 0x74, 0x0B, 0xE3, 0xA7, 0x75, 0x8A,
        0x60, 0x95, 0xEF, 0x6A, 0x98, 0xC7, 0x35, 0xA5,
        0xC0, 0xFB, 0x4C, 0x88, 0xA1, 0xDA, 0xCE, 0x79,
        0x3D, 0x4E, 0x4F, 0x91, 0x75, 0x88, 0xE0, 0x5F,
        0x17, 0xF5, 0xEF, 0xF8, 0x49, 0xFE, 0xB1, 0xDB,
        0x0D, 0xE8, 0xB2, 0xF7, 0xD4, 0x90, 0xBD, 0xB0,
        0x6B, 0x3A, 0x1B, 0xB5, 0xC6, 0xFB, 0x93, 0xEF,
        0xF3, 0xDD, 0x60, 0xEA, 0x67, 0x11, 0xFE, 0x6A,
        0xCC, 0x2C, 0x64, 0x2A, 0x85, 0x2E, 0x24, 0x39,
        0x34, 0x6B, 0xBC, 0xF8, 0x89, 0xB3, 0x49, 0x82,
        0x9C, 0xC0, 0x04, 0x29, 0x6D, 0x25, 0xCB, 0x19,
        0xE1, 0x53, 0xC6, 0x10, 0x7D, 0x62, 0x07, 0xD2,
        0x83, 0x8B, 0x89, 0x04, 0x70, 0x06, 0x60, 0x4F,
        0xB6, 0x10, 0x2B, 0xA0, 0x92, 0xF4, 0x1A, 0x7A,
        0xD6, 0x4F, 0xDC, 0x6C, 0x6C, 0x27, 0xE5, 0xEC,
        0x68, 0x1B, 0x95, 0x7C, 0x1C, 0x95, 0x2C, 0xB7,
        0x0A, 0x8D, 0xC7, 0x57, 0x92, 0x00, 0x4D, 0xC0,
        0x5F, 0xD4, 0xF4, 0x88, 0x3F, 0x8D, 0x43, 0x12,
        0x05, 0xE2, 0x14, 0x0E, 0xDD, 0x2C, 0xEC, 0xD5,
        0x2F, 0x1A, 0xE6, 0x97, 0xDC, 0xFE, 0x96, 0x80,
        0x67, 0x3B, 0xD4, 0x63, 0x73, 0xFA, 0xC8, 0x4F,
        0x4C, 0x4F, 0x2D, 0x68, 0x76, 0x44, 0x8E, 0xC2,
        0x19, 0x99, 0x44, 0xEA, 0xF2, 0x33, 0x23, 0x83,
        0xC8, 0xB1, 0x7C, 0x27, 0x43, 0x9B, 0x67, 0xF9,
        0xDE, 0xE1, 0xAE, 0x03, 0xA5, 0xA5, 0x2B, 0x96,
        0xB2, 0xEC, 0x4A, 0x43, 0xA7, 0x6D, 0xF4, 0xDB,
        0x32, 0x5B, 0x54, 0xD6, 0x63, 0xEA, 0x65, 0xC2,
        0xA8, 0x4B, 0x80, 0xCC, 0x65, 0x2D, 0xCE, 0x6F,
        0x61, 0x2F, 0x58, 0xD1, 0xE5, 0x64, 0x8A, 0x42,
        0x8D, 0xBA, 0xFA, 0x35, 0x5C, 0x9E, 0xD5, 0x80,
        0x2D, 0x5C, 0xC3, 0x47, 0xFB, 0x0D, 0x43, 0x20,
        0x7A, 0xA4, 0x37, 0xB2, 0x2F, 0x0B, 0x43, 0xB9,
        0x94, 0xD3, 0xD9, 0xC2, 0xD7, 0x02, 0x5D, 0x6A,
        0x12, 0x99, 0xE7, 0x32, 0x6C, 0xF0, 0x0C, 0x73,
        0x51, 0x33, 0x84, 0xA9, 0x0C, 0x66, 0xC9, 0x19,
        0x88, 0x9A, 0xF1, 0xB6, 0xF8, 0x41, 0xB1, 0xDC,
        0x60, 0xA4, 0x80, 0x73, 0x0B, 0x21, 0xF9, 0xB8,
        0x01, 0x7E, 0x66, 0x0D, 0xB4, 0x2B, 0x53, 0x8D,
        0x7D, 0x0B, 0xE1, 0xA3, 0x0C, 0x27, 0xF6, 0x2F,
        0x27, 0x34, 0x53, 0x75, 0x54, 0xF7, 0x5E, 0x05,
        0x1C, 0x5A, 0x94, 0x08, 0x14, 0xDE, 0xAA, 0x98,
        0xD9, 0xA5, 0xA0, 0xBE, 0x80, 0xC1, 0xEB, 0x3C,
        0xCF, 0x78, 0x88, 0xA4, 0xA2, 0x03, 0xF8, 0x79,
        0x1F, 0x84, 0x84, 0xA7, 0x0E, 0x95, 0x1A, 0x85,
        0xEF, 0x4C, 0xBE, 0xA2, 0x99, 0xAB, 0x10, 0xDD,
        0x85, 0x3F, 0x10, 0x6A, 0x9C, 0xD5, 0xDD, 0x7A,
        0xFB, 0xF5, 0xD9, 0xD9, 0xAA, 0xDF, 0x03, 0x78,
        0xAF, 0x1D, 0xEC, 0x18, 0xEB, 0x00, 0xB6, 0x64,
        0xB5, 0x75, 0xA5, 0x00, 0xDC, 0x36, 0x45, 0xBD,
        0x0C, 0x66, 0xCE, 0xA9, 0xBB, 0xD1, 0xF7, 0xE4,
        0x6A, 0xDA, 0x0E, 0x81, 0x0F, 0x6A, 0x71, 0x60,
        0x5C, 0x41, 0xD2, 0x12, 0x45, 0x14, 0xEF, 0x6F,
        0xEC, 0x22, 0x73, 0x4C, 0xA7, 0x94, 0xDD, 0x1A,
        0x42, 0x22, 0x58, 0x14, 0x0C, 0x4E, 0x6D, 0x77,
        0x7F, 0xF5, 0xC9, 0x69, 0x81, 0xA3, 0xB8, 0x6D,
        0x1C, 0x39, 0x47, 0xA5, 0xC4, 0x61, 0x1C, 0x91,
        0x2F, 0x67, 0xC3, 0x5E, 0x87, 0x1A, 0x85, 0x81,
        0x7D, 0x76, 0xF2, 0xE0, 0xB9, 0xD0, 0x43, 0x33,
        0xF1, 0xC1, 0xBA, 0x48, 0x6F, 0x48, 0xD5, 0xAE,
        0xB6, 0xDC, 0xAA, 0xCA, 0xEB, 0x0B, 0x6B, 0xFE,
        0xF4, 0xF1, 0x6E, 0x5D, 0xE4, 0x90, 0x53, 0xCF,
        0x9E, 0x13, 0x80, 0xCE, 0xE5, 0xDD, 0xA4, 0x01,
        0xBC, 0x16, 0x50, 0xD0, 0x78, 0x96, 0x3F, 0x2B,
        0x7A, 0x71, 0x8E, 0x86, 0xFD, 0x14, 0x21, 0xDF,
        0x4D, 0xD7, 0xDD, 0x42, 0x59, 0xB3, 0xED, 0x81,
        0xE3, 0xAF, 0x71, 0x57, 0xE7, 0x04, 0xD2, 0x26,
        0xA8, 0x83, 0xFC, 0x03, 0x90, 0x8C, 0x88, 0xC4,
        0xBF, 0x74, 0x54, 0x59, 0xD8, 0x66, 0x9F, 0xE2,
        0x7A, 0xCE, 0x5B, 0x9C, 0xC4, 0x37, 0xFA, 0xDB,
        0x40, 0x9A, 0xDD, 0x73, 0x9C, 0x06, 0x5A, 0x21,
        0x43, 0xFB, 0xFA, 0x1B, 0x41, 0x31, 0x9F, 0xF4,
        0x24, 0x09, 0x05, 0xFE, 0x56, 0x17, 0x52, 0x9C,
        0xC7, 0xE2, 0xCA, 0xC9, 0x1F, 0xBE, 0xE2, 0xEB,
        0x92, 0xEE, 0xD4, 0x76, 0x44, 0x9A, 0xFA, 0xFB,
        0x07, 0x62, 0x98, 0xEC, 0xA0, 0xCF, 0xBF, 0xFA,
        0x5E, 0x1B, 0x8B, 0xCD, 0x33, 0xFB, 0x1A, 0x97,
        0xFE, 0x50, 0x65, 0x22, 0x08, 0x9E, 0xC3, 0x87,
        0x88, 0xCA, 0xDD, 0x11, 0x5E, 0xA7, 0xCF, 0xF3,
        0x07, 0x0A, 0x34, 0x0E, 0x30, 0x1B, 0xC5, 0xCE,
        0xF7, 0xA6, 0xA4, 0x31, 0xB5, 0x40, 0xB8, 0x81,
        0xAC, 0xAA, 0x07, 0xE0, 0x7D, 0x5E, 0x6A, 0x25,
        0x85, 0x8D, 0x1D, 0x82, 0x45, 0x82, 0x76, 0xB2,
        0x65, 0x69, 0x3E, 0x88, 0xFE, 0x21, 0xFE, 0x6A,
        0x6B, 0x97, 0xD6, 0x70, 0x70, 0x00, 0x83, 0x18,
        0x39, 0xA6, 0x91, 0x3F, 0xB1, 0xB7, 0xED, 0x11,
        0xD3, 0xF9, 0x74, 0x31, 0xEC, 0x21, 0xA2, 0xEE,
        0x69, 0x04, 0xC0, 0xEA, 0x4A, 0x17, 0x1A, 0xF8,
        0xDA, 0xF1, 0x52, 0xB2, 0x78, 0x69, 0x4F, 0xDF,
        0xE6, 0xB9, 0xF3, 0xE7, 0x48, 0x8B, 0x09, 0x5F,
        0x4A, 0x7A, 0x05, 0x8E, 0xA8, 0xF6, 0x69, 0x3D,
        0x91, 0x7A, 0x6F, 0x6C, 0xAD, 0x03, 0x16, 0xEA,
        0xE0, 0x04, 0xFE, 0x54, 0x71, 0x50, 0x6D, 0x31,
        0xE4, 0x37, 0x76, 0xD6, 0x1B, 0xA9, 0xEE, 0x56,
        0x7A, 0x39, 0x34, 0x24, 0x00, 0x58, 0xE3, 0x2F,
        0xD4, 0x97, 0x57, 0x6F, 0xD8, 0x0E, 0x8B, 0xD3,
        0x88, 0x7F, 0xE8, 0x74, 0x72, 0xF7, 0xBA, 0x26,
        0x25, 0xE4, 0xD5, 0x86, 0xCD, 0xA8, 0x1E, 0x8D,
        0x49, 0xCF, 0x04, 0x92, 0x5B, 0x50, 0xD0, 0x73,
        0x3C, 0xC9, 0x17, 0xC3, 0x0E, 0x67, 0x02, 0xC5,
        0xDE, 0x48, 0x88, 0x0D, 0x2C, 0x0D, 0x68, 0x04,
        0xD5, 0x51, 0xDF, 0x4F, 0x23, 0x89, 0x7A, 0x29,
        0x41, 0xB2, 0x7A, 0xCA, 0x86, 0xA5, 0xCC, 0xC4,
        0xF5, 0xD3, 0xE1, 0xEF, 0xB8, 0xCD, 0x84, 0xB5,
        0x6D, 0xB6, 0x51, 0x1B, 0x81, 0x26, 0x97, 0xAC,
        0x00, 0xFC, 0x76, 0x8D, 0x99, 0xD9, 0x35, 0x8E,
        0x4D, 0x3E, 0xC0, 0xC1, 0x0E, 0x8D, 0x9B, 0xE5,
        0x79, 0xF3, 0xC7, 0xA0, 0xA4, 0xA6, 0xA2, 0xE9,
        0x8B, 0xCD, 0x36, 0x79, 0x76, 0xF1, 0x6A, 0xEE,
        0xCF, 0x91, 0x8D, 0x91, 0xB1, 0xAF, 0xF2, 0xF5,
        0x43, 0xF6, 0xB2, 0x3A, 0x39, 0x9F, 0xBF, 0xDE,
        0x16, 0x03, 0x52, 0x18, 0x62, 0x93, 0xB5, 0x09,
        0xC4, 0xEE, 0x27, 0x9C, 0x56, 0x6F, 0x0C, 0x1C,
        0x12, 0x42, 0xF0, 0x34, 0xBD, 0x44, 0x52, 0x4C,
        0x32, 0x7E, 0x64, 0xDF, 0x78, 0x16, 0xD9, 0x9E,
        0xD7, 0x8A, 0x11, 0x33, 0x65, 0x42, 0xEC, 0x36,
        0x07, 0xEE, 0x3F, 0x19, 0x97, 0x9B, 0x92, 0x9D,
        0x3A, 0xE4, 0x98, 0x83, 0xDB, 0x0C, 0x85, 0x39,
        0xFA, 0x8D, 0x73, 0xF5, 0xBF, 0xE0, 0x75, 0x40,
        0x50, 0x9B, 0xF2, 0xE6, 0xB6, 0xA5, 0x33, 0xD0,
        0xC4, 0xD6, 0xAB, 0xFF, 0x16, 0xDE, 0x30, 0x9C,
        0x68, 0x90, 0xE0, 0x5E, 0xD3, 0xD5, 0xA9, 0xB0,
        0xD9, 0x6B, 0x0A, 0x43, 0x45, 0x9A, 0x3D, 0xE8,
        0xB6, 0x66, 0xE4, 0x57, 0x05, 0x8E, 0x5B, 0x72,
        0xFE, 0x50, 0x44, 0x8C, 0xE4, 0x68, 0x43, 0x51,
        0x0D, 0x9A, 0xD3, 0x36, 0xA9, 0xC7, 0xF6, 0xCF,
        0x6D, 0x2C, 0x95, 0x46, 0x98, 0x6D, 0x9E, 0x78,
        0x90, 0x87, 0x19, 0x64, 0xD5, 0xDE, 0x1D, 0x9B,
        0x37, 0x4E, 0x52, 0xF5, 0x14, 0xAA, 0xEE, 0x31,
        0x83, 0x55, 0x7C, 0x38, 0x0F, 0xB3, 0xF6, 0xF2,
        0x1C, 0x60, 0x71, 0x68, 0x1F, 0x06, 0xBD, 0x99,
        0xFD, 0x42, 0x12, 0x54, 0x3E, 0xBA, 0x4B, 0x60,
        0xFB, 0xFB, 0x51, 0x4D, 0x02, 0xCE, 0xE5, 0x9E,
        0x59, 0xB2, 0xE6, 0x98, 0x67, 0xBB, 0xAB, 0xC8,
        0x08, 0xE4, 0x08, 0x0D, 0xF5, 0x3B, 0x47, 0x78,
        0x39, 0x24, 0x56, 0x80, 0xF0, 0x6A, 0x1D, 0x33,
        0x05, 0x5F, 0xF2, 0xA2, 0x38, 0xAD, 0xDF, 0x5C,
        0xC5, 0xEA, 0x9C, 0xC7, 0x0A, 0x1B, 0x5B, 0x43,
        0xE9, 0x59, 0x3D, 0x68, 0x00, 0x23, 0x32, 0x5D,
        0x25, 0xFD, 0xA7, 0xCA, 0xDA, 0xA1, 0xFD, 0x22,
        0x4E, 0x34, 0x96, 0xE7, 0x0D, 0xFF, 0x89, 0x3B,
        0xA6, 0x56, 0x0D, 0x11, 0x13, 0xA6, 0x9D, 0x3B,
        0xBC, 0x12, 0x97, 0x9A, 0x2B, 0xAA, 0xE9, 0xE2,
        0xCF, 0xD2, 0xD3, 0xEF, 0x95, 0xFC, 0x40, 0x80,
        0x94, 0x48, 0x80, 0x5A, 0x3F, 0x4A, 0xD2, 0xB5,
        0x7D, 0x61, 0xA2, 0x26, 0x7B, 0xDC, 0x32, 0xCB,
        0x84, 0x2E, 0x9B, 0x29, 0x63, 0x45, 0x74, 0x0D,
        0x85, 0x54, 0xB2, 0x16, 0x77, 0x9B, 0x47, 0x51,
        0x63, 0x33, 0xE9, 0x1A, 0x52, 0x9D, 0xEB, 0x26,
        0x06, 0x7F, 0x97, 0xA0, 0xA1, 0xAA, 0x07, 0x0F,
        0x1E, 0x23, 0xAB, 0xCC, 0xD5, 0x0F, 0x3E, 0x88,
        0xAA, 0xC3, 0xED, 0x06, 0x25, 0x3A, 0x4A, 0x62,
        0x85, 0x9F, 0xA7, 0xD3, 0xF5, 0x1C, 0x9A, 0xCC,
        0x52, 0x87, 0x9F, 0xB8, 0xC7, 0xDD, 0xF1, 0x50,
        0x66, 0x70, 0xAC, 0xC6, 0x2C, 0x2E, 0x8C, 0xC9,
        0xD9, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x06, 0x0D, 0x13, 0x1D, 0x20,
        0x27, 0x2C, 0x32
    };
#endif
    byte sig[DILITHIUM_MAX_SIG_SIZE];
    word32 sigLen;

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }

    ExpectIntEQ(wc_dilithium_init_ex(key, NULL, INVALID_DEVID), 0);
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
    ExpectIntEQ(wc_dilithium_import_private(sk_44, (word32)sizeof(sk_44), key),
        0);
    sigLen = PARAMS_ML_DSA_44_SIG_SIZE;
    ExpectIntEQ(wc_dilithium_sign_msg_with_seed(msg_44, (word32)sizeof(msg_44),
        sig, &sigLen, key, rnd_44), 0);
    ExpectIntEQ(sigLen, PARAMS_ML_DSA_44_SIG_SIZE);
    ExpectIntEQ(XMEMCMP(sig, sig_44, sizeof(sig_44)), 0);
#endif
#ifndef WOLFSSL_NO_ML_DSA_65
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
    ExpectIntEQ(wc_dilithium_import_private(sk_65, (word32)sizeof(sk_65), key),
        0);
    sigLen = PARAMS_ML_DSA_65_SIG_SIZE;
    ExpectIntEQ(wc_dilithium_sign_msg_with_seed(msg_65, (word32)sizeof(msg_65),
        sig, &sigLen, key, rnd_65), 0);
    ExpectIntEQ(sigLen, PARAMS_ML_DSA_65_SIG_SIZE);
    ExpectIntEQ(XMEMCMP(sig, sig_65, sizeof(sig_65)), 0);
#endif
#ifndef WOLFSSL_NO_ML_DSA_87
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
    ExpectIntEQ(wc_dilithium_import_private(sk_87, (word32)sizeof(sk_87), key),
        0);
    sigLen = PARAMS_ML_DSA_87_SIG_SIZE;
    ExpectIntEQ(wc_dilithium_sign_msg_with_seed(msg_87, (word32)sizeof(msg_87),
        sig, &sigLen, key, rnd_87), 0);
    ExpectIntEQ(sigLen, PARAMS_ML_DSA_87_SIG_SIZE);
    ExpectIntEQ(XMEMCMP(sig, sig_87, sizeof(sig_87)), 0);
#endif

    wc_dilithium_free(key);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wc_dilithium_verify_kats(void)
{
    EXPECT_DECLS;
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
    !defined(WOLFSSL_DILITHIUM_NO_VERIFY)
    dilithium_key* key;
    int res;
#ifndef WOLFSSL_NO_ML_DSA_44
    static const byte pk_44[] = {
        0x09, 0xB4, 0x88, 0x7D, 0x97, 0xBC, 0xF6, 0x37,
        0x9C, 0xC5, 0x9B, 0x61, 0x62, 0xC1, 0xE8, 0xBF,
        0x05, 0x60, 0xBF, 0x44, 0xD6, 0x18, 0x09, 0x17,
        0x0E, 0x6E, 0x28, 0xF7, 0x06, 0x69, 0xA3, 0xE9,
        0x49, 0x64, 0x38, 0xE8, 0x91, 0x57, 0x35, 0xAD,
        0xAE, 0xB4, 0x45, 0xCF, 0xDB, 0x7D, 0x89, 0xB3,
        0x8C, 0x04, 0x8F, 0x4C, 0x3E, 0x00, 0x58, 0x15,
        0x14, 0xC5, 0xFD, 0x19, 0x8B, 0x2D, 0x17, 0x39,
        0xE8, 0x83, 0xB8, 0x78, 0xD5, 0x6B, 0xB4, 0x12,
        0x64, 0xBE, 0x41, 0xD3, 0xD5, 0x15, 0x65, 0xE2,
        0xE9, 0xCA, 0xE3, 0x31, 0x84, 0xA8, 0x99, 0xF6,
        0x2D, 0xD5, 0x7D, 0x07, 0x40, 0x0E, 0x98, 0xE5,
        0x86, 0x87, 0xA9, 0xB2, 0x2F, 0xA3, 0x17, 0xEE,
        0xD1, 0x34, 0xCA, 0x72, 0x14, 0xBF, 0xF0, 0x21,
        0xDD, 0x21, 0x62, 0xB1, 0x83, 0x09, 0x1D, 0x15,
        0xF2, 0x63, 0xB7, 0x29, 0x82, 0x14, 0x42, 0x3C,
        0x6B, 0xB6, 0x96, 0xD7, 0x5C, 0x20, 0xD9, 0xEA,
        0xCD, 0x0A, 0x03, 0xE4, 0x26, 0x2C, 0x4B, 0x08,
        0xBE, 0x39, 0xFA, 0x21, 0x54, 0xBD, 0x6E, 0x50,
        0x25, 0xFF, 0x79, 0x1E, 0x88, 0x5F, 0x22, 0x26,
        0xE3, 0xCF, 0x48, 0xF7, 0xB5, 0xEB, 0x04, 0xFB,
        0xE9, 0xEC, 0xF7, 0x5B, 0x19, 0xE1, 0xD1, 0x5C,
        0x30, 0x5E, 0x92, 0x26, 0x0A, 0xB0, 0xD6, 0xAE,
        0x7D, 0xBA, 0x7B, 0xBE, 0x73, 0xB6, 0xBC, 0x18,
        0x1C, 0xF9, 0x33, 0x84, 0x0C, 0xC1, 0x0A, 0x00,
        0x05, 0x02, 0x28, 0xFA, 0x46, 0xA2, 0x63, 0x6D,
        0xD9, 0xA9, 0x09, 0x47, 0xE9, 0xF1, 0x3A, 0x93,
        0xEF, 0x4C, 0x62, 0xBE, 0x37, 0x4D, 0x76, 0xD1,
        0xFD, 0xBB, 0xC5, 0xD8, 0xB5, 0x5E, 0x72, 0x9F,
        0xA5, 0x86, 0x65, 0xAA, 0x07, 0xB9, 0x0C, 0x8C,
        0xDD, 0xD6, 0x1C, 0x56, 0x6B, 0x0D, 0x7E, 0xD6,
        0x57, 0x70, 0x49, 0x2E, 0xA0, 0x71, 0x3E, 0x1E,
        0xD4, 0x6A, 0xC7, 0xAD, 0x15, 0x03, 0xC5, 0x6D,
        0x90, 0x52, 0xD2, 0xC9, 0x4D, 0x49, 0xE4, 0x41,
        0x6A, 0xC9, 0x2B, 0x70, 0x39, 0x6F, 0x76, 0xF6,
        0xFB, 0x48, 0x10, 0x45, 0x68, 0x17, 0x25, 0xA6,
        0x8C, 0xB3, 0x56, 0x37, 0x7F, 0xB2, 0x31, 0xAB,
        0x8F, 0x3E, 0xB9, 0xA4, 0x98, 0x2F, 0xFF, 0x18,
        0x36, 0x47, 0x3B, 0xCB, 0xDA, 0xB6, 0x87, 0x2D,
        0x22, 0x94, 0x67, 0xEF, 0xB9, 0x36, 0x62, 0x61,
        0xFE, 0xB1, 0x48, 0xBA, 0x9B, 0x7D, 0xB9, 0xC4,
        0xFE, 0x0B, 0xB8, 0x86, 0x12, 0xAB, 0xB8, 0xFD,
        0x61, 0x09, 0x6F, 0x18, 0x19, 0x60, 0x4D, 0x55,
        0xDF, 0x60, 0x20, 0x46, 0x4D, 0x3F, 0x09, 0x2C,
        0xFC, 0xA5, 0x98, 0x12, 0x08, 0x22, 0x18, 0x56,
        0x68, 0x99, 0xA5, 0x6A, 0x3C, 0x63, 0x3C, 0xC8,
        0x1F, 0x88, 0xAD, 0xB2, 0xE1, 0x41, 0x4E, 0xF3,
        0x85, 0x0D, 0x10, 0xBF, 0x5A, 0x77, 0xAC, 0xE7,
        0x24, 0xD6, 0xC1, 0xF3, 0x88, 0x92, 0x87, 0x44,
        0xB3, 0xE5, 0x42, 0xAE, 0x49, 0x1C, 0xD5, 0x6A,
        0x64, 0x21, 0x3F, 0x1D, 0x3C, 0xC9, 0x0B, 0x29,
        0x10, 0x5F, 0x43, 0xD2, 0x37, 0xC8, 0x3D, 0x5F,
        0xB8, 0x29, 0x32, 0x5C, 0x83, 0xE6, 0x54, 0x57,
        0x77, 0x76, 0x39, 0x2F, 0x85, 0x36, 0xAA, 0x9D,
        0xAE, 0x87, 0x24, 0x07, 0xAB, 0xAA, 0xA9, 0xAC,
        0xC2, 0x2A, 0x68, 0x12, 0xCE, 0xA7, 0x4C, 0x0B,
        0xA6, 0x7E, 0xAF, 0x4A, 0x41, 0x01, 0x52, 0x97,
        0x5E, 0x9A, 0x83, 0xEE, 0x44, 0x69, 0x29, 0x53,
        0x17, 0xBE, 0xD1, 0x05, 0x51, 0xBA, 0x32, 0xE6,
        0x5A, 0xFC, 0x8C, 0x8E, 0x68, 0xDD, 0x55, 0x42,
        0x0C, 0x50, 0x2D, 0x93, 0x7D, 0xAD, 0xD2, 0xEF,
        0xA2, 0xCB, 0xFD, 0x1F, 0x73, 0x9F, 0xC0, 0xAB,
        0x2B, 0x26, 0x54, 0xFA, 0xE0, 0x8C, 0x0C, 0x7F,
        0x8E, 0xDD, 0x43, 0xCF, 0x9F, 0xF0, 0xB0, 0x1D,
        0x98, 0x4D, 0x49, 0x18, 0x52, 0xA3, 0x72, 0xE9,
        0xFE, 0xFD, 0xCC, 0x1B, 0xC1, 0x6C, 0xDB, 0x52,
        0x39, 0xAE, 0x10, 0x01, 0x15, 0x5F, 0x89, 0x56,
        0x30, 0x51, 0xCE, 0x47, 0x99, 0x6C, 0x5A, 0xEE,
        0xB2, 0x19, 0x0E, 0xA1, 0x8F, 0x7F, 0x73, 0x40,
        0x42, 0xDE, 0x68, 0xE9, 0x88, 0x36, 0x7D, 0x89,
        0x35, 0x5D, 0x9D, 0x83, 0x77, 0xBA, 0xF9, 0x64,
        0x79, 0x78, 0xEB, 0x2E, 0x49, 0x2A, 0xD0, 0x21,
        0xC5, 0x69, 0xAE, 0x8B, 0xA6, 0x9B, 0x15, 0xF1,
        0xFC, 0xF7, 0x03, 0x9A, 0x7E, 0x64, 0xAF, 0x10,
        0xAB, 0xF3, 0xEA, 0x45, 0xB7, 0x22, 0x2F, 0x96,
        0x59, 0xE3, 0x33, 0x73, 0x37, 0x2E, 0x1D, 0xB1,
        0x86, 0xD2, 0xC2, 0xA0, 0xD7, 0x54, 0x51, 0xC4,
        0x78, 0xAE, 0xF3, 0x3E, 0x59, 0x49, 0xF2, 0x40,
        0x04, 0x0C, 0x2A, 0xFC, 0x44, 0xB1, 0xD3, 0xA0,
        0x2A, 0x6D, 0x2F, 0x87, 0x90, 0x2A, 0x28, 0x0E,
        0x27, 0xA2, 0x0D, 0x4E, 0x57, 0xF8, 0x89, 0x66,
        0x27, 0x00, 0xDB, 0x8A, 0x9D, 0x24, 0x99, 0x57,
        0xA7, 0xDB, 0x43, 0x7C, 0xD4, 0x80, 0xDD, 0xC0,
        0x58, 0x84, 0xFB, 0x23, 0xF8, 0x68, 0x26, 0x8E,
        0xAC, 0xE3, 0x4E, 0xED, 0x27, 0x4A, 0x92, 0x7D,
        0x9D, 0x84, 0xF1, 0xEA, 0x57, 0xEA, 0xB1, 0xA8,
        0x13, 0xB5, 0xE6, 0xAA, 0xBE, 0x9E, 0xD2, 0x61,
        0x0B, 0xC6, 0xF7, 0x2E, 0x32, 0x0C, 0xDE, 0xC4,
        0xF9, 0x95, 0x23, 0xF9, 0x3F, 0xA4, 0x48, 0xDC,
        0x1F, 0xBB, 0xDD, 0x25, 0x9B, 0x10, 0x2F, 0x5D,
        0xC9, 0x95, 0x5A, 0xFA, 0x0C, 0x41, 0x60, 0x4D,
        0x83, 0xDD, 0x1C, 0x2D, 0x22, 0x95, 0xEF, 0x44,
        0x61, 0x45, 0x6B, 0xAE, 0x86, 0x90, 0x5C, 0x4C,
        0x30, 0xD8, 0xA9, 0xFA, 0x48, 0xC9, 0x0F, 0x37,
        0xA1, 0x9C, 0x41, 0xA2, 0xD5, 0x98, 0x8F, 0x13,
        0xD5, 0x13, 0x44, 0xEC, 0x30, 0xA4, 0xA4, 0x62,
        0x19, 0xFE, 0x84, 0x11, 0x37, 0xD5, 0xAA, 0x1F,
        0x51, 0xE6, 0xC4, 0x44, 0x16, 0x8A, 0xF3, 0x98,
        0x90, 0xB6, 0xFA, 0x40, 0x0D, 0x67, 0xF4, 0x80,
        0x6F, 0x5B, 0xBD, 0x44, 0x47, 0x03, 0x07, 0x4A,
        0x7A, 0x11, 0x39, 0xC7, 0x17, 0x46, 0xD7, 0xC4,
        0xCE, 0xB3, 0xC9, 0x11, 0xF5, 0x25, 0x7E, 0x3E,
        0x53, 0xEB, 0xFA, 0x5A, 0xA8, 0xF2, 0x27, 0x80,
        0x9D, 0x44, 0xEE, 0x7D, 0xE1, 0x3C, 0x02, 0x79,
        0x24, 0xDD, 0x60, 0x15, 0x3B, 0x30, 0xAA, 0x76,
        0xDD, 0x96, 0xA7, 0xC5, 0xAC, 0xC5, 0x9B, 0x62,
        0x79, 0x19, 0x50, 0x7B, 0xF1, 0x42, 0x57, 0xAE,
        0x7A, 0x26, 0x24, 0x3C, 0x16, 0x83, 0xB2, 0x8D,
        0x1B, 0x14, 0xB5, 0x01, 0xAD, 0x05, 0x9B, 0x4D,
        0x52, 0x2A, 0x57, 0x99, 0x1E, 0x55, 0x39, 0xCE,
        0xF1, 0x8C, 0xEB, 0x5C, 0x26, 0xD6, 0x60, 0xB8,
        0x82, 0x24, 0x54, 0xC9, 0xC4, 0x2A, 0x95, 0xE6,
        0xF7, 0x2B, 0x84, 0xF7, 0x8A, 0xB9, 0x9F, 0x51,
        0xEC, 0x49, 0x78, 0x9F, 0x9D, 0xB4, 0xC1, 0x28,
        0xB0, 0x31, 0x8F, 0xFF, 0xC8, 0x2D, 0x95, 0xCA,
        0xD2, 0x77, 0xF1, 0x1E, 0x14, 0xF1, 0xEF, 0x87,
        0x14, 0x14, 0x88, 0x11, 0x22, 0xA9, 0xB1, 0x1B,
        0xDF, 0xAE, 0x4A, 0x7A, 0xBC, 0x8E, 0x75, 0x75,
        0x5A, 0xB1, 0x37, 0x41, 0xDF, 0xAC, 0xD6, 0x64,
        0x29, 0x3D, 0x1A, 0x32, 0x6B, 0xF5, 0xED, 0x5A,
        0xBB, 0xB1, 0x53, 0xEB, 0xE6, 0x99, 0x6D, 0xD6,
        0x22, 0xF0, 0xA8, 0xCB, 0x47, 0x39, 0x69, 0xA5,
        0x03, 0x66, 0xBD, 0x0B, 0x01, 0xC5, 0xC7, 0x3A,
        0x89, 0x2B, 0x8E, 0x26, 0xCE, 0x08, 0xF7, 0x5F,
        0xF8, 0x01, 0xB6, 0xDE, 0xF0, 0x41, 0xE1, 0x71,
        0x3B, 0xE6, 0xDF, 0x0E, 0xFB, 0x51, 0x58, 0x7B,
        0xE5, 0xFB, 0xEA, 0x72, 0x7E, 0x00, 0xD7, 0x17,
        0x64, 0x7D, 0xD5, 0x39, 0x07, 0x9D, 0xE1, 0x8A,
        0xE7, 0xBE, 0xD1, 0x2B, 0x91, 0xAF, 0x8D, 0xBB,
        0x1B, 0x8B, 0x32, 0xD2, 0x86, 0x0B, 0xAF, 0x40,
        0xAF, 0x8A, 0x0B, 0xBF, 0xE0, 0x28, 0x87, 0xEB,
        0x5D, 0xBE, 0x7A, 0xB1, 0xAF, 0xC4, 0x1D, 0xA7,
        0x9B, 0x01, 0x6A, 0xA1, 0x6E, 0xDA, 0x28, 0x13,
        0x21, 0xCA, 0xA5, 0xDA, 0x64, 0x4F, 0xD8, 0x65,
        0x8A, 0x7B, 0x70, 0x21, 0x81, 0x00, 0x14, 0x31,
        0x56, 0x0D, 0xD6, 0x3C, 0xB2, 0x1E, 0x5F, 0xF7,
        0x5C, 0x3F, 0x72, 0x50, 0x45, 0x6B, 0xE0, 0x8C,
        0x0D, 0x5E, 0x34, 0xC3, 0xBD, 0xE2, 0xF6, 0x06,
        0xA2, 0xBF, 0x34, 0x17, 0x76, 0x8D, 0x24, 0xB2,
        0x37, 0x39, 0xEA, 0x86, 0xCB, 0xEF, 0xDD, 0xA3,
        0x43, 0x88, 0xBC, 0x1F, 0x91, 0x8F, 0x95, 0x1E,
        0x15, 0xE4, 0x3B, 0x13, 0x85, 0xA7, 0xBC, 0xC5,
        0x59, 0xF9, 0x49, 0x2C, 0x72, 0x13, 0xA1, 0x42,
        0x27, 0xE0, 0x93, 0xE9, 0x29, 0xF3, 0x2D, 0x1E,
        0xFB, 0xE7, 0xF1, 0xEE, 0x57, 0xC4, 0x9C, 0x90,
        0x55, 0x62, 0x3E, 0xA4, 0x2E, 0xC6, 0xC7, 0x9D,
        0x7F, 0xCE, 0x71, 0xFA, 0x74, 0x76, 0x07, 0x56,
        0x6D, 0xDA, 0x69, 0xF6, 0x9D, 0xAF, 0x68, 0x11,
        0x59, 0x19, 0xC6, 0x32, 0x2E, 0xBB, 0x42, 0xC8,
        0xC0, 0x89, 0x33, 0x8C, 0x9E, 0x0C, 0x53, 0x56,
        0x5B, 0xCB, 0xE7, 0x2F, 0xBE, 0x47, 0x26, 0x68,
        0x7B, 0x07, 0x87, 0x07, 0x18, 0x06, 0xC5, 0xA6,
        0xC1, 0x49, 0xC8, 0x2B, 0x66, 0x8A, 0xA6, 0x4A,
        0x7B, 0xA0, 0xCC, 0xC1, 0xCC, 0x49, 0xA1, 0xEE,
        0xE9, 0x45, 0x3D, 0x04, 0x33, 0x6E, 0x5D, 0xC8,
        0x11, 0xE0, 0x38, 0x92, 0xF7, 0xF4, 0x66, 0x88,
        0xEC, 0xEF, 0xD0, 0x4F, 0x18, 0x76, 0xF7, 0x11,
        0x17, 0x12, 0xB5, 0x95, 0xED, 0x62, 0xDA, 0x00,
        0x67, 0x8F, 0x9E, 0x37, 0x86, 0xB5, 0xC1, 0xA5,
        0x09, 0x5B, 0xE8, 0x71, 0x0D, 0xCF, 0xA4, 0x16,
        0x52, 0x56, 0x50, 0x9E, 0x00, 0x14, 0x3A, 0x6F,
        0x11, 0x72, 0xFA, 0xBE, 0x8B, 0xF2, 0x1E, 0x5F,
        0xCE, 0x7C, 0x79, 0xC1, 0xA4, 0x4B, 0x4B, 0x15,
        0x25, 0xA0, 0x76, 0xFF, 0xB8, 0xDD, 0x90, 0x66
    };
    static const byte msg_44[] = {
        0x3A, 0xFD, 0x7F, 0xF8, 0xCA, 0xD3, 0xAC, 0xBD,
        0xF9, 0x77, 0x31, 0x26, 0x1C, 0x7A, 0x1C, 0x96,
        0x9D, 0x50, 0x16, 0xF1, 0x7D, 0x3E, 0x7F, 0x83,
        0xD2, 0x44, 0x1A, 0xF9, 0x01, 0x4B, 0x63, 0x47,
        0x7B, 0x14, 0xA6, 0x41, 0x31, 0x50, 0xFA, 0xD7,
        0xC8, 0x44, 0x39, 0xBC, 0x88, 0x66, 0x2C, 0x5E,
        0x93, 0x1F, 0x06, 0xB9, 0x51, 0x41, 0x90, 0xE1,
        0x3F, 0xB0, 0x49, 0xC4, 0xAB, 0x74, 0x01, 0x32,
        0x33, 0xB9, 0x8D, 0x48, 0xD9, 0xAF, 0xB6, 0xA3,
        0x0A, 0x67, 0x33, 0x0E, 0x1F, 0xBE, 0x33, 0x1B,
        0x09, 0xC5, 0x6D, 0x03, 0x7E, 0x97, 0x01, 0x08,
        0x5D, 0x80, 0xF1, 0xE7, 0xF4, 0x04, 0x3E, 0xFB,
        0x53, 0x58, 0x7A, 0xBB, 0x82, 0x36, 0x24, 0x01,
        0x23, 0x84, 0x51, 0x52, 0x49, 0xEE, 0x61, 0x30,
        0x97, 0x3D, 0xC9, 0xEA, 0x6F, 0x55, 0x8B, 0xAE,
        0x75, 0x10, 0x7E, 0xFD, 0xB1, 0xD9, 0x28, 0x5B
    };
    static const byte sig_44[] = {
        0x4A, 0x2B, 0x16, 0xCD, 0xB5, 0x52, 0xF9, 0x29,
        0x7F, 0x8E, 0x39, 0x1A, 0xD8, 0xF5, 0xAD, 0xC8,
        0xCC, 0x5D, 0x2C, 0x56, 0xC4, 0x6B, 0x80, 0x0F,
        0x9B, 0x3E, 0xE4, 0xBB, 0xD2, 0xF2, 0xE8, 0xA8,
        0x9D, 0x59, 0x9D, 0x7B, 0x5C, 0xC2, 0xD8, 0x8C,
        0x80, 0xF2, 0x71, 0x85, 0x9B, 0xBC, 0x83, 0x04,
        0x3E, 0xC4, 0xE5, 0x48, 0x12, 0xF5, 0x93, 0x6B,
        0x44, 0x6C, 0x95, 0x13, 0xC8, 0x55, 0x28, 0x9C,
        0x94, 0xB1, 0x15, 0x51, 0xA0, 0xC7, 0x65, 0x3E,
        0x7B, 0xA7, 0x4F, 0xFB, 0x6F, 0x72, 0xD4, 0x65,
        0x2C, 0x91, 0xD3, 0x8D, 0xD1, 0xF9, 0x0D, 0xFE,
        0x44, 0x39, 0xBC, 0x21, 0xCA, 0x53, 0xE0, 0xCC,
        0x7A, 0x7A, 0xA5, 0xB8, 0x75, 0xA5, 0xB9, 0xBA,
        0x42, 0x36, 0x6E, 0xB8, 0xEC, 0xBA, 0x24, 0x36,
        0xDA, 0xF0, 0x8A, 0x91, 0x97, 0x8D, 0xD0, 0x93,
        0xF2, 0x0F, 0x1E, 0xFB, 0x6B, 0x0B, 0xCB, 0x90,
        0xDA, 0x99, 0xCC, 0xA0, 0x5E, 0x8F, 0x6F, 0x82,
        0xB8, 0x6D, 0x3C, 0x6E, 0xE2, 0x4B, 0xA5, 0xD5,
        0x0A, 0xEA, 0x10, 0xB2, 0x30, 0x7F, 0x57, 0xF8,
        0x9E, 0xD7, 0x8D, 0xB4, 0xA7, 0x4F, 0xBB, 0xF6,
        0xEB, 0x33, 0x2A, 0xFB, 0x08, 0xD0, 0x74, 0xAC,
        0xF0, 0xDE, 0x5C, 0xD7, 0xFE, 0xC1, 0x2F, 0x76,
        0xF3, 0xAB, 0x61, 0x9C, 0x81, 0x5B, 0x9E, 0xDD,
        0x28, 0x7E, 0xAD, 0x67, 0xF0, 0x4F, 0x14, 0x79,
        0x7F, 0x8D, 0xCF, 0x2C, 0xDE, 0x9A, 0x87, 0x53,
        0xB5, 0xAD, 0x0A, 0xFA, 0x12, 0x87, 0x41, 0x97,
        0xD1, 0x74, 0x40, 0x92, 0x87, 0x25, 0x21, 0xE8,
        0x68, 0xAF, 0x9E, 0x64, 0x45, 0x23, 0x73, 0xFE,
        0xB6, 0xFE, 0x25, 0xD5, 0x27, 0x3D, 0x63, 0xC0,
        0xEB, 0xD6, 0xD3, 0xB1, 0x02, 0x8C, 0x1C, 0xD0,
        0x6A, 0xF3, 0x2C, 0xEC, 0xA2, 0x62, 0x13, 0x10,
        0x83, 0x7C, 0x72, 0x78, 0x8C, 0x8A, 0xDA, 0xB5,
        0xA0, 0xF0, 0x38, 0x17, 0x12, 0x8E, 0xB7, 0xB7,
        0x66, 0xFA, 0x81, 0x2C, 0x69, 0x6C, 0xF8, 0x86,
        0xF0, 0x0A, 0x10, 0x44, 0xCD, 0xD0, 0x6B, 0xB2,
        0x8C, 0xB2, 0xE5, 0x78, 0x0C, 0x8D, 0x8C, 0xC7,
        0xE6, 0x0A, 0xB6, 0x99, 0xDD, 0x78, 0x66, 0x8B,
        0xE4, 0xFF, 0x9F, 0x46, 0x90, 0xC6, 0xFC, 0x98,
        0xAA, 0xC9, 0xC0, 0x2B, 0x66, 0xB9, 0xB9, 0x82,
        0x6A, 0x30, 0x61, 0xFD, 0x32, 0x22, 0xDA, 0x84,
        0x82, 0x66, 0x79, 0x60, 0xA3, 0x16, 0x52, 0xEE,
        0x88, 0xEB, 0x32, 0xB0, 0x46, 0x9A, 0xB7, 0x1C,
        0xAA, 0x25, 0x19, 0xF2, 0x3D, 0x1A, 0x24, 0x42,
        0xD5, 0xB1, 0x31, 0x62, 0x62, 0x13, 0x1D, 0xCE,
        0xC5, 0xF2, 0x87, 0xE3, 0x2F, 0xD3, 0x43, 0xFE,
        0xB4, 0x42, 0x9E, 0x54, 0x25, 0x8D, 0x69, 0x0D,
        0x9D, 0x20, 0xA1, 0x0A, 0xBD, 0x75, 0xA5, 0x36,
        0xDF, 0xF8, 0xCF, 0x1D, 0x6D, 0xDF, 0x19, 0x29,
        0x1E, 0x27, 0x49, 0xA7, 0xD1, 0x6E, 0xB9, 0x0A,
        0xB5, 0x09, 0x3B, 0xAD, 0x38, 0xE1, 0x16, 0xA8,
        0x6B, 0x73, 0x0E, 0x65, 0x57, 0x4C, 0x06, 0x8C,
        0x38, 0xBA, 0x94, 0x57, 0xC9, 0xD6, 0xD9, 0x13,
        0xEA, 0xFF, 0x57, 0xFE, 0x23, 0xBF, 0x3D, 0xD2,
        0x4D, 0x8C, 0xA5, 0x11, 0xEF, 0xA3, 0x76, 0xA5,
        0xDF, 0x08, 0x46, 0x70, 0x25, 0xFF, 0x51, 0xBE,
        0xAD, 0x3E, 0xDE, 0x0A, 0x84, 0xED, 0xC5, 0x32,
        0x16, 0x20, 0x99, 0x80, 0x61, 0xE8, 0xA1, 0xA7,
        0x3D, 0x67, 0xB7, 0x02, 0x1B, 0x81, 0x0C, 0x78,
        0x67, 0xFF, 0x39, 0x18, 0x7B, 0x59, 0xD4, 0x03,
        0xBF, 0x7C, 0x75, 0x06, 0x30, 0x0C, 0x73, 0x45,
        0xB1, 0xFE, 0x07, 0xC1, 0x12, 0x78, 0xB0, 0xAB,
        0xA6, 0x1D, 0xBB, 0x4F, 0x2B, 0x8C, 0x43, 0xE7,
        0x4F, 0xEF, 0xA5, 0x5E, 0xD5, 0x2C, 0x10, 0xA8,
        0xC4, 0x90, 0x88, 0x2B, 0xBF, 0xE3, 0xE3, 0xB3,
        0xCE, 0x57, 0x9E, 0x81, 0x16, 0xA9, 0xB6, 0x68,
        0x6C, 0x1A, 0x10, 0x0A, 0xA1, 0xF6, 0x59, 0x1F,
        0x19, 0x1F, 0x77, 0x2B, 0x5A, 0x5A, 0x50, 0xDD,
        0x6C, 0xC1, 0x55, 0xCB, 0x5A, 0x1B, 0xE5, 0xBA,
        0x12, 0x2E, 0x91, 0xF0, 0x44, 0x42, 0x01, 0x56,
        0xCD, 0x63, 0x08, 0x0F, 0x0A, 0x45, 0xD6, 0x62,
        0xE7, 0x6D, 0xD5, 0x7B, 0xD0, 0xF6, 0x89, 0xD0,
        0xB2, 0x99, 0x04, 0x2B, 0xFF, 0x48, 0x5E, 0x8A,
        0x38, 0x2D, 0x86, 0x5C, 0x26, 0xCD, 0x46, 0xB4,
        0xA5, 0x47, 0x28, 0xBD, 0x48, 0x45, 0x83, 0x62,
        0xD7, 0x9A, 0xC3, 0xEB, 0x75, 0x6F, 0xC6, 0xC5,
        0x18, 0xC9, 0xE2, 0xF0, 0xE7, 0xD5, 0xA3, 0x03,
        0xAF, 0x11, 0x59, 0xEE, 0x6D, 0xBE, 0x7D, 0xD5,
        0x6B, 0xA0, 0x71, 0x28, 0x57, 0xA6, 0x88, 0x36,
        0xC3, 0xC7, 0x8C, 0x6C, 0x9F, 0x74, 0x88, 0x57,
        0x28, 0x13, 0xC0, 0xF6, 0xA8, 0x14, 0x70, 0x9D,
        0x2B, 0xC1, 0x42, 0xFE, 0xF0, 0x25, 0x27, 0xCA,
        0xE7, 0x71, 0x23, 0x58, 0x37, 0x1C, 0x54, 0x26,
        0x52, 0x2C, 0xCC, 0x64, 0x30, 0x0C, 0x2C, 0xD9,
        0xFB, 0xE2, 0x0C, 0x65, 0x62, 0xE3, 0x48, 0x35,
        0x20, 0x5F, 0xCD, 0xD5, 0xA8, 0x98, 0x2C, 0x92,
        0x0B, 0xB4, 0x77, 0xFB, 0x88, 0x17, 0x02, 0x82,
        0x7B, 0x49, 0x11, 0x87, 0x13, 0x94, 0xC0, 0x6B,
        0x5F, 0xEC, 0xD0, 0xC7, 0x40, 0xAF, 0x7B, 0x27,
        0x63, 0x7B, 0xAC, 0x1A, 0x0C, 0xBC, 0xA5, 0x37,
        0xE4, 0x43, 0x3E, 0xA8, 0x47, 0x45, 0x4C, 0x69,
        0x38, 0x97, 0xA3, 0x2E, 0x4D, 0x18, 0x44, 0x19,
        0x54, 0x26, 0xA0, 0xC6, 0xAE, 0xD6, 0x74, 0x72,
        0xBD, 0x2C, 0x4E, 0xEE, 0x17, 0x9F, 0x3F, 0x60,
        0x84, 0xA3, 0x6A, 0x76, 0x89, 0xF4, 0xCB, 0x1F,
        0x8E, 0x5D, 0xB2, 0xDD, 0xE5, 0x4A, 0xCC, 0x06,
        0x66, 0xBA, 0x98, 0x41, 0x54, 0x31, 0xA4, 0xB2,
        0x02, 0xF4, 0x02, 0xFB, 0x1F, 0x1B, 0xCC, 0xDC,
        0x23, 0xBF, 0xF1, 0x31, 0x48, 0xC7, 0xB8, 0xF6,
        0x1F, 0xBF, 0x62, 0x43, 0xB2, 0x96, 0xA7, 0x8E,
        0xB6, 0x98, 0x18, 0x9D, 0xA9, 0x5B, 0xDA, 0x85,
        0xDB, 0xC1, 0x1D, 0x15, 0xFF, 0xDC, 0x6B, 0xF4,
        0x6C, 0x53, 0xF6, 0xE4, 0x72, 0xA8, 0x71, 0x40,
        0x1E, 0x9A, 0x9A, 0xB7, 0xF9, 0xFB, 0x46, 0x7E,
        0xB4, 0xEC, 0xB1, 0xF0, 0xDA, 0x7E, 0x63, 0xEE,
        0x86, 0x19, 0xCB, 0xC4, 0x86, 0xEB, 0xB0, 0xF2,
        0x12, 0x0A, 0x78, 0x11, 0xBF, 0xB0, 0x55, 0x7D,
        0x13, 0x93, 0x05, 0x74, 0x29, 0x7C, 0x94, 0x64,
        0xFC, 0x59, 0x5B, 0x27, 0x56, 0x9A, 0xDF, 0x5F,
        0x4A, 0x8D, 0xF6, 0x69, 0xC9, 0xEE, 0xA0, 0xA2,
        0x50, 0xF4, 0xD2, 0x2C, 0x2E, 0x8C, 0x64, 0x1B,
        0xA3, 0x90, 0x2B, 0xA8, 0x08, 0x00, 0x48, 0x99,
        0x65, 0xF1, 0x1A, 0xF1, 0xE1, 0xA8, 0x57, 0x17,
        0xC6, 0x24, 0xE7, 0x42, 0xF1, 0x61, 0x55, 0x08,
        0x19, 0xD1, 0xF0, 0x37, 0x2C, 0x5C, 0xAE, 0x8B,
        0xC6, 0x2B, 0x54, 0x9E, 0xFE, 0x87, 0x44, 0x61,
        0x08, 0x0D, 0x06, 0x34, 0x6E, 0x1F, 0xA6, 0xF0,
        0x15, 0x14, 0xFB, 0xEC, 0xCB, 0x06, 0xE3, 0x4E,
        0xE2, 0x71, 0xA0, 0xF0, 0x03, 0x17, 0x90, 0xBD,
        0xAB, 0xE0, 0xF0, 0x2B, 0xBA, 0x4A, 0xEA, 0x4B,
        0x73, 0x97, 0xFE, 0x33, 0x33, 0xEB, 0x81, 0x21,
        0x82, 0x07, 0x57, 0x28, 0x1F, 0x96, 0xA5, 0x83,
        0x1F, 0x9E, 0x49, 0x03, 0x66, 0x54, 0x9D, 0x16,
        0x76, 0x3F, 0xF1, 0x9F, 0xF7, 0x73, 0x58, 0x0E,
        0xD5, 0xE3, 0xE1, 0xE2, 0xAA, 0x3E, 0x38, 0xF8,
        0x84, 0x74, 0xDE, 0x6D, 0x9B, 0xA6, 0x99, 0x4F,
        0x8E, 0x62, 0x91, 0x60, 0x48, 0x8C, 0xB4, 0xCD,
        0x5B, 0x87, 0x8C, 0xDA, 0x37, 0xAA, 0xEC, 0x9B,
        0x56, 0x36, 0x9A, 0x7E, 0x73, 0xF7, 0x3B, 0x42,
        0x86, 0x39, 0xA0, 0x5C, 0x13, 0x78, 0x44, 0x8A,
        0xDB, 0x7F, 0x07, 0x4D, 0xC8, 0x15, 0x4D, 0x92,
        0xE1, 0x3C, 0x63, 0x56, 0xB5, 0xF4, 0x66, 0xD6,
        0x64, 0x77, 0x15, 0x9B, 0x2A, 0x94, 0x37, 0x99,
        0xAD, 0x61, 0x9A, 0x02, 0x9F, 0x30, 0x10, 0xD0,
        0x37, 0x67, 0x2D, 0xBB, 0x68, 0x20, 0xE5, 0x13,
        0x23, 0xAD, 0xA9, 0x88, 0x81, 0xC6, 0xDE, 0x85,
        0x9D, 0xF8, 0x75, 0xAB, 0xAF, 0x11, 0xDA, 0x5D,
        0xDC, 0xA5, 0xA7, 0x77, 0x62, 0x2B, 0xDA, 0xE8,
        0xFA, 0xCE, 0x2E, 0x0C, 0xED, 0x3B, 0x6A, 0x77,
        0xB8, 0x8A, 0x87, 0x29, 0xFB, 0x7C, 0x50, 0x93,
        0x3D, 0xA6, 0xC5, 0x2E, 0x3F, 0x4D, 0x94, 0x8F,
        0x9D, 0xC1, 0x53, 0xB5, 0xB1, 0x29, 0x9C, 0xD8,
        0x62, 0x1D, 0xDF, 0xBA, 0x48, 0xAF, 0x44, 0xE4,
        0xB6, 0xF6, 0x10, 0x6E, 0xE7, 0x77, 0x95, 0x01,
        0xDD, 0x5F, 0xB3, 0xC5, 0x78, 0xEA, 0x4D, 0x32,
        0xC5, 0xC2, 0xF0, 0x36, 0xA7, 0x35, 0x27, 0x03,
        0xAD, 0xD1, 0x35, 0xAB, 0x84, 0x46, 0x01, 0x62,
        0x41, 0x7E, 0x50, 0xBF, 0x91, 0xE6, 0x07, 0x97,
        0xD5, 0x9B, 0x9E, 0x18, 0xD3, 0x24, 0xDA, 0x97,
        0x1F, 0x4F, 0xF4, 0x28, 0xAE, 0xAF, 0x23, 0xAC,
        0x0B, 0xA4, 0xE2, 0xE2, 0xFC, 0x7A, 0xBA, 0xA6,
        0xC8, 0x98, 0x4F, 0xE9, 0xE2, 0xD8, 0x5B, 0x8A,
        0xDA, 0x40, 0x86, 0xB3, 0xC1, 0x3A, 0xBD, 0x43,
        0xCF, 0xD1, 0xC7, 0x11, 0xD8, 0x32, 0x6B, 0x18,
        0xAD, 0xC3, 0x4C, 0xC1, 0x4C, 0xF8, 0x95, 0x7E,
        0xC3, 0x95, 0x94, 0x98, 0xFC, 0x2A, 0x7B, 0xE0,
        0x6B, 0xD1, 0x84, 0x0D, 0xE1, 0x70, 0x36, 0x65,
        0x66, 0xE5, 0x07, 0x41, 0x95, 0x77, 0x63, 0xC2,
        0xDD, 0x27, 0xAC, 0xF8, 0xC3, 0xF1, 0x02, 0x6F,
        0xAE, 0xE1, 0xD2, 0x56, 0x2F, 0xA1, 0x05, 0x2E,
        0x69, 0xAF, 0xDD, 0x42, 0xF4, 0x46, 0xF0, 0x59,
        0x88, 0x66, 0xD5, 0xD3, 0x06, 0xBF, 0x1B, 0x77,
        0x50, 0x42, 0xB0, 0x35, 0x92, 0x73, 0x72, 0x82,
        0x7F, 0x43, 0x86, 0x31, 0x65, 0x34, 0xFA, 0x1B,
        0x7E, 0xE6, 0x33, 0xBA, 0x95, 0x8C, 0xED, 0x8F,
        0x0D, 0x24, 0x1D, 0x46, 0x88, 0xE3, 0xC7, 0x91,
        0x8E, 0x2A, 0x75, 0x62, 0x63, 0x77, 0xC3, 0x42,
        0xA5, 0x90, 0x69, 0x2B, 0xBF, 0xB8, 0x27, 0xBF,
        0x90, 0x51, 0x41, 0x82, 0xD4, 0x09, 0x0D, 0xF8,
        0xD7, 0x32, 0x35, 0x19, 0xA1, 0xAB, 0x6C, 0xD0,
        0x22, 0x73, 0x67, 0x41, 0x0D, 0xD1, 0x4D, 0x37,
        0x86, 0xA2, 0x6D, 0xDF, 0x91, 0x72, 0x4F, 0xC8,
        0x2D, 0x06, 0xA2, 0x5D, 0x5F, 0x56, 0x68, 0x39,
        0x53, 0xE8, 0xE0, 0xF2, 0x0E, 0x3C, 0x17, 0x71,
        0xDA, 0xF4, 0x2E, 0x52, 0x02, 0x4C, 0x11, 0x6E,
        0xD8, 0xA4, 0xC0, 0xA6, 0x11, 0x68, 0x0F, 0x5F,
        0xE0, 0x0E, 0xD9, 0xB1, 0x48, 0xD1, 0x5F, 0x12,
        0xAA, 0x95, 0xB9, 0xBD, 0x5A, 0x9F, 0xD8, 0x10,
        0x16, 0x42, 0xB3, 0x69, 0x11, 0xF3, 0x10, 0xB0,
        0xDE, 0x18, 0x17, 0x1D, 0x62, 0x37, 0xD9, 0xBE,
        0x17, 0x25, 0xDC, 0x29, 0x9A, 0x1A, 0x3A, 0xAA,
        0xE9, 0x85, 0x40, 0xCE, 0xED, 0x26, 0x95, 0x3D,
        0x10, 0xCE, 0x85, 0x47, 0xF1, 0xC3, 0xE4, 0x6A,
        0x86, 0x2B, 0xED, 0x42, 0x8D, 0x1E, 0x10, 0x60,
        0x1B, 0xF3, 0x28, 0xC7, 0x27, 0xFD, 0x95, 0x34,
        0x3E, 0x2D, 0xB4, 0xD9, 0xAC, 0xD5, 0xD1, 0xCB,
        0x47, 0x15, 0xF6, 0x00, 0x40, 0x96, 0xED, 0xA0,
        0x93, 0xD1, 0xB0, 0xA3, 0x3B, 0x1E, 0x56, 0xF1,
        0x6D, 0x73, 0xAD, 0xB8, 0x73, 0x2C, 0xB4, 0xA3,
        0x11, 0x60, 0xA4, 0x49, 0x1F, 0xAA, 0x0C, 0x86,
        0xE6, 0x80, 0xE3, 0xD7, 0xC0, 0x2C, 0xCE, 0xA8,
        0xFE, 0x92, 0xF1, 0xE0, 0x01, 0x01, 0x6D, 0x22,
        0x02, 0x21, 0xDD, 0x10, 0xED, 0x62, 0x60, 0x17,
        0x96, 0x6C, 0x34, 0x50, 0xAD, 0x12, 0x13, 0x65,
        0x91, 0x8C, 0x93, 0x09, 0x1F, 0x14, 0x71, 0x2B,
        0xA4, 0x77, 0xCF, 0x2E, 0x26, 0x32, 0x96, 0xC7,
        0x78, 0xA2, 0xBA, 0xEE, 0xF5, 0x84, 0x94, 0x55,
        0xFA, 0x35, 0xCB, 0x61, 0x72, 0x51, 0xE0, 0x2A,
        0x22, 0xDA, 0xF5, 0xC3, 0x3E, 0x5A, 0xAA, 0x9F,
        0x00, 0xE8, 0xAC, 0xDC, 0x50, 0xEC, 0xF4, 0x7C,
        0x52, 0x15, 0x03, 0xC5, 0x2F, 0x27, 0xD6, 0xB5,
        0x7C, 0x8F, 0x2B, 0x3D, 0x8F, 0x12, 0x22, 0x41,
        0x3E, 0x7F, 0xA4, 0xEC, 0x59, 0x29, 0x63, 0x38,
        0x09, 0x8C, 0x9A, 0xB5, 0xA1, 0xD8, 0xA5, 0x78,
        0x84, 0xBD, 0x86, 0x00, 0x41, 0x40, 0x6D, 0x96,
        0x55, 0xD1, 0x73, 0x82, 0x94, 0x9A, 0x03, 0xD5,
        0x0F, 0x11, 0x08, 0xD0, 0x5B, 0xDB, 0x31, 0xCA,
        0x08, 0xE6, 0x6F, 0x2D, 0x8D, 0xE4, 0x80, 0xC6,
        0x79, 0x35, 0x18, 0xD4, 0x9A, 0x60, 0xD4, 0x76,
        0x2A, 0x9E, 0xDD, 0xC0, 0x24, 0x9B, 0x42, 0x2E,
        0x84, 0x02, 0x0E, 0xD5, 0x39, 0xA1, 0x4E, 0x24,
        0x78, 0xF6, 0x8B, 0xAB, 0x1F, 0x2B, 0x00, 0xE2,
        0x2A, 0x5C, 0xBB, 0x62, 0x97, 0x9A, 0xC7, 0x44,
        0xE0, 0x8B, 0x57, 0xD5, 0xB5, 0x78, 0xC4, 0x01,
        0xA8, 0xD2, 0x6D, 0x9A, 0xDD, 0x15, 0x05, 0x23,
        0x60, 0x82, 0x86, 0x36, 0x72, 0xD9, 0x11, 0xCF,
        0x3A, 0x09, 0x66, 0xD3, 0x03, 0xF8, 0x91, 0x70,
        0x93, 0xBF, 0x97, 0xAF, 0x90, 0xA7, 0xE1, 0xF9,
        0xD5, 0x9B, 0x09, 0x20, 0x6B, 0x9C, 0xAC, 0x35,
        0x11, 0x0F, 0xA3, 0x8D, 0x58, 0x90, 0xED, 0x21,
        0x16, 0x83, 0x5C, 0xE3, 0x73, 0x84, 0xF5, 0x63,
        0x0F, 0x1C, 0x42, 0x8E, 0x21, 0x36, 0x05, 0x87,
        0x2E, 0xCF, 0x91, 0x1B, 0x01, 0x4B, 0x91, 0xC2,
        0xC6, 0x00, 0xE8, 0xA4, 0x07, 0x29, 0xD0, 0x7B,
        0xF9, 0x18, 0x79, 0x07, 0x42, 0xC9, 0x27, 0x9F,
        0x31, 0x14, 0xF6, 0x8C, 0xDF, 0x65, 0x94, 0xCD,
        0xA3, 0xCA, 0x66, 0x94, 0x22, 0x3A, 0x82, 0xF6,
        0x6C, 0x2B, 0x4B, 0xDF, 0x3E, 0x51, 0xC6, 0xFF,
        0xDC, 0x55, 0xE0, 0xFF, 0x51, 0xEF, 0xD6, 0xC9,
        0x34, 0x36, 0x2B, 0xE7, 0xD6, 0xFA, 0xBC, 0x11,
        0xB8, 0xB0, 0xDA, 0xDD, 0xD5, 0x21, 0x08, 0xFA,
        0x5F, 0xB5, 0xCA, 0x75, 0x8A, 0x64, 0x37, 0x7D,
        0x38, 0x6D, 0x45, 0xCE, 0x70, 0x60, 0x5B, 0x46,
        0x0E, 0x81, 0x57, 0x03, 0x7B, 0x5B, 0x1B, 0x2E,
        0x0A, 0xED, 0xD1, 0x2A, 0x63, 0x31, 0x15, 0xD6,
        0xC4, 0x3B, 0xC6, 0xC7, 0xC8, 0x36, 0xFF, 0xF3,
        0x3E, 0x7D, 0x03, 0x3F, 0x2E, 0x58, 0x00, 0x52,
        0x71, 0x64, 0xC0, 0xC4, 0x78, 0x1C, 0x37, 0xDF,
        0x50, 0xB6, 0x6B, 0xBA, 0x5C, 0x81, 0x94, 0x73,
        0xA1, 0xC5, 0x30, 0x20, 0x83, 0xA1, 0x6F, 0x01,
        0x43, 0x72, 0x79, 0xD2, 0xF2, 0xDF, 0x14, 0xC8,
        0x78, 0x26, 0x9A, 0x2F, 0x3F, 0xA4, 0x0C, 0x1C,
        0x76, 0x1E, 0xD6, 0x15, 0x01, 0xAC, 0x9E, 0xF1,
        0x41, 0x02, 0x90, 0x38, 0xC8, 0x19, 0x95, 0x40,
        0x89, 0xB7, 0x38, 0x09, 0x87, 0x08, 0x17, 0x43,
        0x93, 0xFE, 0xAE, 0xA7, 0xB0, 0x2A, 0xE5, 0xCE,
        0xF6, 0x7B, 0x3C, 0x8C, 0xE6, 0xA9, 0x70, 0x67,
        0x5C, 0xA1, 0xB8, 0xC8, 0x56, 0xDC, 0xF5, 0x97,
        0x25, 0x08, 0xC7, 0xC6, 0xB2, 0x5E, 0xE4, 0xD1,
        0x2D, 0x82, 0x12, 0xB9, 0x89, 0x40, 0xB4, 0x88,
        0xEC, 0x40, 0x2A, 0xC7, 0xAE, 0x3C, 0x70, 0xDF,
        0x93, 0x8D, 0x12, 0x88, 0xCD, 0xA7, 0xA3, 0x19,
        0xE0, 0x85, 0xBC, 0x73, 0xA4, 0x69, 0xB2, 0xD2,
        0xA3, 0x30, 0x3B, 0x11, 0xA6, 0x83, 0x10, 0x0A,
        0xF6, 0xDB, 0x86, 0x93, 0x7B, 0xA1, 0x18, 0x29,
        0x03, 0x61, 0x6E, 0x3F, 0x03, 0x47, 0xBD, 0x68,
        0x59, 0x1B, 0x47, 0xBA, 0x65, 0x15, 0x6B, 0x93,
        0xF2, 0x60, 0xDE, 0x59, 0xB3, 0xAE, 0xB2, 0x89,
        0xE2, 0xA7, 0x3A, 0x3B, 0xFF, 0x38, 0xC2, 0xF3,
        0xAD, 0xED, 0xA2, 0x9C, 0x7E, 0x90, 0x28, 0x3A,
        0xC7, 0xB8, 0x6D, 0x03, 0x6B, 0x47, 0xD5, 0xBA,
        0x1A, 0x03, 0xEC, 0x78, 0x3D, 0x25, 0x0B, 0xAC,
        0xAE, 0x58, 0x47, 0xE4, 0x1F, 0x82, 0x9C, 0xB3,
        0x3D, 0xE0, 0x8D, 0xF8, 0xF7, 0xD6, 0x9C, 0x9A,
        0xA4, 0xED, 0xE8, 0xD7, 0xAB, 0x96, 0x84, 0x07,
        0xEE, 0xD3, 0x1A, 0x05, 0x6B, 0xA0, 0xEF, 0x88,
        0x16, 0xE1, 0x27, 0xAA, 0x90, 0x06, 0x5A, 0x67,
        0x9E, 0x1C, 0xA9, 0x55, 0x0D, 0xEE, 0xF2, 0x5A,
        0xC5, 0xB7, 0xA3, 0x4F, 0x70, 0xDC, 0xF2, 0xB1,
        0x16, 0xCF, 0x35, 0x1F, 0x3B, 0xAD, 0xA9, 0x9F,
        0x83, 0x6C, 0x73, 0x0D, 0xCC, 0x1A, 0xE0, 0x3F,
        0x49, 0x6C, 0xF3, 0xF0, 0x38, 0x7A, 0x0C, 0x2C,
        0x70, 0x2E, 0x2C, 0x13, 0xBD, 0xD9, 0xCF, 0x45,
        0xA1, 0xCD, 0x53, 0xAB, 0x58, 0x73, 0x11, 0x88,
        0xB1, 0x8E, 0xA8, 0xBE, 0x48, 0xD5, 0x10, 0xC5,
        0x81, 0x2E, 0x90, 0xBC, 0xEC, 0xBC, 0x6E, 0x19,
        0x8E, 0x70, 0x8B, 0x1C, 0x08, 0xC8, 0xF8, 0x64,
        0xB1, 0x24, 0xBB, 0x4C, 0xC0, 0xBD, 0xBB, 0xDF,
        0x2C, 0x2F, 0x4E, 0x38, 0x8F, 0xC1, 0x96, 0x60,
        0xD6, 0x9C, 0xC2, 0xC0, 0xEB, 0xF9, 0x10, 0x08,
        0xC8, 0x24, 0x3D, 0xB4, 0x2D, 0xDA, 0xF5, 0x7C,
        0x02, 0x42, 0x51, 0xC4, 0x23, 0x1D, 0xF5, 0x37,
        0x90, 0xCE, 0x57, 0x56, 0x13, 0xEE, 0x8E, 0x1C,
        0x7A, 0x33, 0xC1, 0x56, 0x1F, 0x35, 0x04, 0xDE,
        0xAA, 0xED, 0x1E, 0x84, 0x08, 0x50, 0x06, 0x23,
        0xEC, 0xA5, 0xAE, 0x5A, 0x28, 0x45, 0x41, 0x17,
        0x49, 0x93, 0x0D, 0x8E, 0x42, 0x07, 0x8C, 0x03,
        0x23, 0x49, 0x95, 0x7F, 0xC3, 0x9A, 0x1D, 0xA0,
        0xEA, 0xF9, 0xE8, 0x7C, 0x31, 0xFF, 0xBF, 0x6A,
        0xC0, 0xC1, 0x81, 0x1E, 0xB2, 0x8A, 0x41, 0xB1,
        0xD8, 0x6B, 0xD7, 0xD4, 0x9A, 0xD1, 0xC4, 0x68,
        0xA4, 0x95, 0x94, 0x95, 0x65, 0x25, 0xA2, 0x0A,
        0x31, 0x70, 0x0F, 0x12, 0x2F, 0x4C, 0x4B, 0xB2,
        0x25, 0x2A, 0x2F, 0x3D, 0x5C, 0x5D, 0x68, 0x73,
        0x83, 0x8C, 0x90, 0x95, 0x97, 0xBB, 0xCA, 0xD8,
        0xE1, 0x33, 0x3D, 0x5D, 0x61, 0x7C, 0x87, 0xC8,
        0xEE, 0x0F, 0x1B, 0x22, 0x38, 0x3B, 0x42, 0x4B,
        0x4C, 0x5C, 0x62, 0x72, 0x98, 0xA3, 0xBE, 0xCC,
        0x1B, 0x32, 0x47, 0x5C, 0x9D, 0xB6, 0xB9, 0xBD,
        0xC6, 0xD6, 0xDC, 0xF5, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x11, 0x19, 0x28, 0x34
    };
#endif
#ifndef WOLFSSL_NO_ML_DSA_65
    static const byte pk_65[] = {
        0x6C, 0x9E, 0x7A, 0x1E, 0xE3, 0x66, 0x25, 0x76,
        0x0E, 0x5D, 0x2F, 0x33, 0xDF, 0x29, 0x29, 0xDA,
        0x56, 0x20, 0x32, 0x34, 0x06, 0x91, 0x60, 0xE5,
        0xF2, 0xBF, 0x03, 0x9C, 0x11, 0x06, 0x22, 0x73,
        0x07, 0x3C, 0x23, 0x75, 0x66, 0xCE, 0x05, 0x5D,
        0x87, 0x1F, 0x38, 0xAC, 0xD1, 0xA9, 0x85, 0x9A,
        0x82, 0x44, 0x67, 0xF1, 0x9B, 0xE6, 0x8E, 0x4F,
        0x00, 0x64, 0x5D, 0x22, 0x5C, 0x42, 0xC8, 0x5A,
        0x55, 0x7D, 0x2C, 0x5E, 0xCB, 0x44, 0x2B, 0x0F,
        0x02, 0x8A, 0x65, 0x28, 0x89, 0x8E, 0xE2, 0xB6,
        0x73, 0xD8, 0x63, 0xF3, 0x2E, 0xB9, 0xEC, 0x81,
        0x64, 0x12, 0x75, 0x41, 0xF3, 0x25, 0x19, 0xBB,
        0x88, 0xE0, 0x34, 0xA0, 0x3F, 0x46, 0xF7, 0xD1,
        0x93, 0xCD, 0x3D, 0xFB, 0xAD, 0xF6, 0x35, 0x57,
        0x92, 0x6C, 0x5C, 0x8F, 0x5B, 0x76, 0x6A, 0x7F,
        0xC5, 0xEC, 0x8B, 0x3F, 0x94, 0x8B, 0xF7, 0xA8,
        0x21, 0xB5, 0x4C, 0x94, 0x41, 0xAB, 0x0B, 0xD8,
        0x33, 0xFD, 0x63, 0x54, 0xCE, 0xC7, 0x06, 0xFA,
        0xA5, 0x00, 0xAB, 0xB5, 0x28, 0x9B, 0x90, 0xB1,
        0xBF, 0x91, 0x76, 0x77, 0xA2, 0x9D, 0x11, 0x5F,
        0x00, 0x94, 0xBD, 0xB4, 0x8D, 0xC7, 0x2E, 0x26,
        0x1D, 0xBA, 0x12, 0x0B, 0xA6, 0xFF, 0x5E, 0x52,
        0xA0, 0x1B, 0x17, 0x89, 0x81, 0xDD, 0x82, 0x96,
        0x44, 0x46, 0x56, 0xD9, 0x44, 0x2D, 0xF9, 0xCB,
        0xB6, 0xBF, 0xDA, 0xE5, 0x6A, 0x23, 0x0F, 0x6F,
        0x29, 0xF9, 0x4C, 0xDC, 0xC2, 0x65, 0x57, 0x6A,
        0xA8, 0x75, 0x2A, 0xCE, 0xD0, 0x7E, 0x99, 0x89,
        0x5C, 0xAE, 0xF0, 0x16, 0x8B, 0xF8, 0x3D, 0x23,
        0xFD, 0xAD, 0xFB, 0xB9, 0x28, 0xCB, 0xCD, 0xAB,
        0xA2, 0x5F, 0xE2, 0xCD, 0x26, 0xAD, 0xDF, 0xB0,
        0xDA, 0xCD, 0x74, 0x94, 0x0F, 0x35, 0x14, 0x26,
        0x94, 0x2F, 0x17, 0x6F, 0xFB, 0xC5, 0xF3, 0x45,
        0x6D, 0xB7, 0xC9, 0x12, 0xAA, 0x16, 0xB8, 0x6D,
        0x07, 0x45, 0xF8, 0x7C, 0x9F, 0x45, 0x37, 0x0A,
        0x84, 0x56, 0xA1, 0xAD, 0xB5, 0x1D, 0xB4, 0x05,
        0x2B, 0x5C, 0x9E, 0xAF, 0x60, 0xAD, 0x7B, 0x80,
        0xA4, 0x2E, 0xA4, 0xBF, 0x92, 0xC8, 0x41, 0x27,
        0x3A, 0xD7, 0x61, 0xDE, 0xDB, 0x0D, 0x34, 0xBF,
        0x57, 0x96, 0x00, 0xB1, 0x49, 0xFC, 0xCD, 0x42,
        0xAB, 0x15, 0x49, 0xBA, 0x0A, 0xBE, 0xDA, 0x57,
        0xEF, 0x71, 0xD1, 0xFC, 0xA5, 0x70, 0x2A, 0xAD,
        0x08, 0x32, 0x99, 0xBB, 0x98, 0x30, 0x01, 0x89,
        0xC2, 0x5F, 0x3B, 0x27, 0x0A, 0x87, 0x65, 0x8D,
        0x0B, 0x2E, 0xA5, 0x65, 0x24, 0x14, 0x7F, 0x73,
        0x9E, 0xB6, 0xC6, 0x76, 0xD7, 0xBE, 0x73, 0xDD,
        0x3B, 0x95, 0xB1, 0x0C, 0x55, 0xAB, 0x46, 0xFD,
        0x01, 0x54, 0x9C, 0x51, 0x68, 0xBF, 0x7D, 0xA1,
        0x3A, 0x49, 0x97, 0x85, 0xF3, 0x5A, 0x1E, 0x3B,
        0x56, 0xF4, 0xC5, 0x67, 0xF5, 0x4E, 0xA9, 0xAA,
        0x28, 0x17, 0xA3, 0x36, 0x38, 0x36, 0x43, 0xFA,
        0x2E, 0xA3, 0x1F, 0xB1, 0xB7, 0x3E, 0x10, 0x24,
        0x8D, 0xFC, 0xA0, 0x5C, 0x04, 0x13, 0x12, 0x66,
        0x49, 0x8E, 0x1C, 0x94, 0x91, 0x13, 0x5A, 0x50,
        0xE6, 0x3D, 0x02, 0xFA, 0xDF, 0x41, 0x65, 0xFC,
        0x9E, 0x15, 0xE3, 0xE1, 0xB3, 0x2F, 0xAB, 0x83,
        0x37, 0x68, 0x4C, 0x49, 0x19, 0x3E, 0x1B, 0xC4,
        0xED, 0xEA, 0xE3, 0x73, 0xA2, 0x67, 0xA7, 0x14,
        0xAC, 0x1F, 0x90, 0x9C, 0xC6, 0x57, 0xCD, 0x80,
        0x66, 0x64, 0x63, 0x27, 0xE0, 0xEE, 0xA0, 0x41,
        0xAC, 0x9F, 0x2A, 0xEF, 0xFC, 0x80, 0x69, 0x1B,
        0xF6, 0x0D, 0x3C, 0x94, 0xC6, 0x42, 0x55, 0x7E,
        0x42, 0x99, 0xD3, 0x95, 0x92, 0x22, 0x16, 0xC6,
        0x5E, 0x75, 0xB7, 0xE1, 0xA5, 0x02, 0x89, 0x60,
        0x38, 0x4B, 0xF8, 0x16, 0xC9, 0xF7, 0x05, 0x48,
        0x29, 0xE7, 0x98, 0x5B, 0x58, 0x41, 0xA7, 0x33,
        0xF3, 0x3F, 0xCE, 0x24, 0x55, 0xEF, 0xC8, 0x9B,
        0xAE, 0x84, 0xB4, 0x79, 0x90, 0xE8, 0xD0, 0xAF,
        0xC6, 0x19, 0x3E, 0x4A, 0xF9, 0xBC, 0x68, 0x0A,
        0xE2, 0x4F, 0xE5, 0x91, 0xE8, 0x8B, 0xA6, 0xA2,
        0xAE, 0x12, 0xDA, 0x38, 0x58, 0xD2, 0x1F, 0x49,
        0x2D, 0x24, 0xAB, 0xC4, 0xFE, 0x4F, 0xD5, 0x2D,
        0x5A, 0xBF, 0x24, 0xBD, 0x25, 0x46, 0x87, 0xB9,
        0x18, 0x79, 0x2F, 0x0A, 0x00, 0x3A, 0x52, 0x22,
        0xDF, 0x45, 0x03, 0x86, 0x85, 0xC7, 0x25, 0xCE,
        0x75, 0x79, 0xE0, 0x2C, 0xB1, 0x68, 0xBB, 0xC6,
        0x66, 0xAB, 0xF6, 0x69, 0x85, 0x6E, 0x10, 0x53,
        0x7C, 0x92, 0x91, 0x69, 0x2C, 0x0C, 0xB0, 0xCF,
        0xA9, 0x06, 0x27, 0x0A, 0xC2, 0xC7, 0xB7, 0xDC,
        0x31, 0xD4, 0xF9, 0x28, 0x3C, 0xB2, 0xDB, 0x8A,
        0x46, 0x2A, 0xEC, 0x0B, 0x98, 0x07, 0xBB, 0xF4,
        0xAB, 0x45, 0x76, 0xFE, 0xC6, 0x22, 0x6B, 0x41,
        0x79, 0x32, 0x2B, 0x67, 0xAE, 0xA5, 0x3B, 0xDD,
        0xF9, 0xC9, 0xBE, 0x5E, 0x0D, 0xBC, 0x43, 0xF7,
        0x87, 0x43, 0x06, 0x8A, 0xB5, 0xBE, 0x49, 0xF0,
        0xE6, 0x2F, 0x8E, 0x2E, 0xB1, 0xB6, 0xC6, 0x73,
        0x6C, 0x05, 0xC9, 0x41, 0x3D, 0x06, 0x5C, 0xE0,
        0xCC, 0xB7, 0x90, 0x54, 0x80, 0x41, 0xD7, 0xE8,
        0x32, 0x88, 0x1A, 0x83, 0x9B, 0x57, 0x29, 0xAF,
        0x94, 0xAB, 0x79, 0xFD, 0x8A, 0x16, 0xDF, 0xFF,
        0x78, 0xCA, 0xAA, 0x14, 0x1D, 0x97, 0xCC, 0x06,
        0x50, 0xF8, 0x62, 0x62, 0xF2, 0x61, 0x59, 0xBE,
        0x8B, 0x36, 0x1A, 0x4A, 0x04, 0x1E, 0x9A, 0x0B,
        0x65, 0x11, 0xBB, 0xE3, 0x35, 0x5A, 0x4B, 0xF5,
        0x7A, 0xC0, 0x98, 0x48, 0x84, 0x7E, 0xE0, 0x24,
        0x3C, 0x3B, 0xA7, 0x74, 0x77, 0x6F, 0x7E, 0x9A,
        0x22, 0x72, 0x75, 0xD7, 0x4E, 0x6E, 0x31, 0x01,
        0xD3, 0x82, 0x81, 0x87, 0x63, 0xED, 0x1E, 0x13,
        0x53, 0xAB, 0x9E, 0xEC, 0xCD, 0x92, 0x0C, 0xD2,
        0x89, 0x22, 0xD5, 0x59, 0xA4, 0x04, 0x8F, 0x40,
        0xF0, 0x62, 0x16, 0x4C, 0xB6, 0x61, 0xC4, 0xF4,
        0xAF, 0xA8, 0x1A, 0x3D, 0x55, 0x93, 0x3C, 0x47,
        0x91, 0xED, 0xDA, 0xA3, 0x93, 0x9E, 0x5A, 0xC3,
        0x42, 0xB0, 0xAD, 0x1F, 0x43, 0x8A, 0x53, 0x2C,
        0x6C, 0xE7, 0x86, 0x68, 0x1A, 0x87, 0x0D, 0x94,
        0xEC, 0x88, 0xA3, 0x34, 0xCC, 0xEF, 0xC6, 0xAC,
        0xE7, 0xD9, 0x88, 0xA1, 0xA8, 0x2B, 0xC0, 0xAC,
        0xCE, 0x78, 0x5F, 0x12, 0x3B, 0xE2, 0x3A, 0x7C,
        0x92, 0xAF, 0x10, 0x8E, 0x5E, 0xD4, 0xF0, 0x86,
        0x9E, 0x22, 0xDA, 0xE2, 0x73, 0x55, 0x6D, 0x1D,
        0xE3, 0x86, 0x62, 0x3A, 0x6C, 0x3F, 0x11, 0x5B,
        0xBD, 0x11, 0x92, 0x71, 0xD3, 0xFB, 0xA7, 0x96,
        0xF6, 0x18, 0xB5, 0x39, 0x59, 0xFB, 0x98, 0x01,
        0x2E, 0x7D, 0x5B, 0x9A, 0xC6, 0x88, 0x94, 0x0B,
        0x87, 0xE2, 0xC9, 0xC0, 0x65, 0x52, 0x4A, 0x00,
        0xD3, 0xA4, 0xF4, 0xDB, 0xF5, 0x2F, 0x4B, 0x1A,
        0x63, 0xEF, 0x5C, 0x46, 0x19, 0x3B, 0xAD, 0xF7,
        0xAD, 0x7F, 0x98, 0x8D, 0x44, 0x64, 0x34, 0x5B,
        0x2C, 0x3E, 0x54, 0x96, 0x84, 0xF2, 0xF9, 0x05,
        0xF6, 0xF8, 0x9D, 0xD6, 0x41, 0x47, 0x3E, 0xC0,
        0x51, 0x08, 0xA5, 0x2D, 0x8D, 0xBB, 0x91, 0x76,
        0x8C, 0x54, 0x1D, 0xE5, 0x20, 0xB1, 0x76, 0x66,
        0x97, 0x0A, 0xAE, 0xB5, 0x06, 0xE7, 0x5D, 0x8E,
        0xE9, 0xF4, 0xB4, 0x45, 0x5B, 0x71, 0xE0, 0x08,
        0x8A, 0xB2, 0x56, 0x55, 0x21, 0x3B, 0x75, 0x85,
        0x9D, 0x25, 0xF5, 0x59, 0xD3, 0xC3, 0x24, 0xD2,
        0x83, 0xD3, 0x97, 0xAB, 0xE6, 0xF0, 0xAA, 0xA3,
        0x86, 0x81, 0x57, 0x68, 0xD0, 0x33, 0x57, 0xD7,
        0x75, 0x96, 0x49, 0x02, 0x41, 0x31, 0x53, 0xE3,
        0x56, 0x0C, 0xCE, 0xF1, 0xFD, 0x44, 0xB6, 0x5F,
        0xF1, 0xB2, 0x87, 0xA9, 0x2A, 0x96, 0x93, 0xF0,
        0x34, 0xB7, 0xEE, 0x66, 0x89, 0x34, 0x70, 0x2D,
        0x75, 0x01, 0xCA, 0xF6, 0xDA, 0x4E, 0xE9, 0x8A,
        0xF4, 0xE8, 0xE6, 0x4B, 0x03, 0x40, 0xE0, 0xBB,
        0x8B, 0xDC, 0x53, 0x3B, 0x0E, 0xFE, 0xE1, 0x91,
        0x5A, 0x4B, 0x68, 0xB9, 0x3C, 0x5E, 0x95, 0x32,
        0x1E, 0xED, 0xC2, 0x34, 0xAE, 0xFE, 0x71, 0xAE,
        0x2E, 0x5D, 0xAC, 0xEC, 0x2F, 0x52, 0xF8, 0x37,
        0x23, 0xA2, 0x39, 0x2A, 0x7F, 0x8E, 0x13, 0xBC,
        0x03, 0x01, 0xCD, 0x10, 0x4D, 0x85, 0x2E, 0x62,
        0xA7, 0xF8, 0x28, 0xAD, 0x32, 0x9B, 0x3D, 0x95,
        0x96, 0xC5, 0x8E, 0x13, 0xFC, 0xC0, 0xED, 0x96,
        0xC1, 0xC4, 0x8D, 0x82, 0xA2, 0xC0, 0xF4, 0xD9,
        0xD2, 0x4D, 0xD8, 0x42, 0x1F, 0xDC, 0xCE, 0xFD,
        0x49, 0x7A, 0x9B, 0x05, 0xFF, 0xC5, 0x09, 0x04,
        0x77, 0x04, 0x01, 0x37, 0x3F, 0xEE, 0x7D, 0xC7,
        0x37, 0x73, 0x41, 0x8A, 0xEB, 0x4A, 0x1F, 0x59,
        0x9A, 0x4B, 0xB3, 0x8E, 0xDE, 0x8D, 0x10, 0xA3,
        0xCC, 0x83, 0xA1, 0xC7, 0x2D, 0xE9, 0x21, 0x96,
        0x9E, 0x3C, 0xE3, 0xE8, 0xEF, 0x2F, 0x7D, 0xA8,
        0x9D, 0x34, 0x4C, 0x80, 0xD6, 0x1C, 0xF9, 0xC5,
        0xA4, 0x23, 0xB1, 0xA4, 0xF3, 0x56, 0x7D, 0x96,
        0xDB, 0x2D, 0xA3, 0xDB, 0x9B, 0x5B, 0x5F, 0xA6,
        0x81, 0x56, 0xBE, 0x74, 0x52, 0xC8, 0xA0, 0x18,
        0x1B, 0xB9, 0xF0, 0xDC, 0x75, 0xCD, 0x97, 0x50,
        0x88, 0x3D, 0x0D, 0xDA, 0xE5, 0x3F, 0xC1, 0x56,
        0xD6, 0x7A, 0x74, 0x20, 0x08, 0x69, 0x04, 0x6B,
        0x41, 0xDF, 0x4B, 0xC4, 0x39, 0x69, 0x93, 0xC0,
        0x8A, 0xA4, 0x89, 0x7A, 0x0B, 0xDD, 0xEF, 0xB5,
        0x5F, 0x69, 0xCC, 0x1C, 0x4D, 0x7B, 0x5F, 0xB1,
        0x50, 0x40, 0x84, 0x27, 0xB4, 0x16, 0xF7, 0x31,
        0x83, 0xF2, 0xB3, 0xCC, 0x16, 0xE3, 0xB7, 0xDA,
        0x63, 0xCE, 0xE1, 0x14, 0x3A, 0xDA, 0x1A, 0x05,
        0x66, 0x26, 0xA0, 0x77, 0xB6, 0xD2, 0x1C, 0x3D,
        0xD9, 0x74, 0xED, 0x90, 0x7C, 0x5A, 0x09, 0x40,
        0x19, 0x22, 0x57, 0x37, 0xEF, 0xB9, 0x33, 0x19,
        0xAD, 0x3B, 0x40, 0xA4, 0xF4, 0x34, 0xAE, 0x49,
        0xD2, 0x83, 0x91, 0xC1, 0x7A, 0x99, 0x9C, 0x74,
        0x4A, 0x68, 0xC5, 0x5A, 0x91, 0xB8, 0x62, 0x72,
        0x95, 0x83, 0xD3, 0xDA, 0x46, 0xEE, 0x70, 0xC5,
        0xCC, 0x46, 0x16, 0x94, 0x16, 0x7D, 0x32, 0xD2,
        0x1D, 0xE7, 0x53, 0x27, 0x73, 0x2C, 0x63, 0xBB,
        0xFB, 0xD7, 0xB3, 0x0D, 0xBF, 0x20, 0x57, 0xA0,
        0xD6, 0x81, 0x51, 0x9F, 0x6E, 0x4A, 0xF6, 0x08,
        0xD4, 0xBC, 0xD0, 0xB4, 0x75, 0x07, 0x26, 0x77,
        0x0E, 0x15, 0x6A, 0xED, 0xE8, 0x54, 0x17, 0xBD,
        0x75, 0x9D, 0x5F, 0xFE, 0x40, 0x1C, 0xB2, 0x99,
        0x6F, 0x34, 0x43, 0x4D, 0xB4, 0x28, 0xD9, 0xA4,
        0x17, 0x03, 0x72, 0x01, 0xFC, 0xD2, 0x60, 0xFA,
        0xA9, 0x80, 0x84, 0x50, 0x2E, 0xED, 0x5C, 0x27,
        0xA8, 0x91, 0x6E, 0x44, 0xF5, 0x92, 0x98, 0x19,
        0xD2, 0x1A, 0x69, 0xCE, 0x16, 0xBC, 0xDC, 0x3C,
        0xC8, 0x14, 0x1E, 0x28, 0x5E, 0xF8, 0x97, 0xB1,
        0x40, 0x2C, 0x15, 0xC9, 0x52, 0x59, 0x01, 0x19,
        0x05, 0x1E, 0x36, 0x9A, 0x1B, 0x7B, 0xE4, 0x43,
        0xFE, 0xAE, 0x6E, 0x32, 0xBC, 0x8F, 0x3D, 0x64,
        0x7F, 0xC5, 0x31, 0x5A, 0x52, 0x00, 0xCD, 0x52,
        0x38, 0xDC, 0x66, 0x77, 0x46, 0x6E, 0xA8, 0x6E,
        0xF8, 0xD1, 0x8E, 0x5A, 0x79, 0xF2, 0x62, 0x48,
        0x3E, 0x89, 0x6B, 0x82, 0x77, 0xC7, 0x41, 0xF5,
        0x16, 0xFC, 0x04, 0x0C, 0x10, 0x90, 0xF2, 0x49,
        0x5B, 0xF1, 0x65, 0x0B, 0x02, 0xAF, 0x30, 0x45,
        0x67, 0x33, 0xA0, 0x71, 0xAF, 0x47, 0xD7, 0xA1,
        0x5B, 0xD8, 0xE3, 0x2A, 0x49, 0x80, 0x64, 0x55,
        0xD3, 0xBE, 0xA7, 0x4A, 0xEF, 0x5D, 0x00, 0x90,
        0x6A, 0xD2, 0xF0, 0xC0, 0x45, 0x35, 0x4E, 0xFD,
        0xE7, 0xC9, 0xA2, 0x76, 0xE7, 0x3D, 0x9E, 0xDD,
        0x11, 0xD1, 0xCA, 0x5C, 0x29, 0x7B, 0x9A, 0x68,
        0x51, 0xE7, 0xF6, 0x7E, 0x21, 0xEB, 0x06, 0x1B,
        0xB5, 0x5D, 0x9E, 0x67, 0x3C, 0x4A, 0x75, 0xFE,
        0xB8, 0x4D, 0x52, 0x62, 0x9E, 0xEC, 0xC5, 0x3C,
        0x24, 0xBE, 0xA9, 0x51, 0x53, 0x05, 0x1A, 0xC2,
        0x06, 0xC8, 0x7D, 0xF5, 0x54, 0x10, 0xCA, 0x1F,
        0xE6, 0xCF, 0xC3, 0xF4, 0x03, 0xA6, 0xD9, 0xD4,
        0x3E, 0xA8, 0x4C, 0x60, 0xC9, 0x45, 0xE6, 0x42,
        0xB2, 0x83, 0x63, 0x38, 0xB5, 0xAF, 0x9F, 0x69,
        0xE5, 0x27, 0x08, 0xB2, 0xE2, 0x25, 0x93, 0x3D,
        0xB3, 0x20, 0xBB, 0x3F, 0x79, 0x0D, 0x39, 0x7F,
        0x22, 0xD7, 0xB6, 0xF8, 0xA4, 0x33, 0xCD, 0xAC,
        0xE9, 0x81, 0x0A, 0xA0, 0xE2, 0x7C, 0x69, 0x95,
        0x55, 0x53, 0x0C, 0x56, 0x2D, 0xBF, 0x75, 0x17,
        0xA4, 0x16, 0x26, 0x28, 0xBF, 0x10, 0xD1, 0xB6,
        0xDB, 0xAC, 0xEF, 0x5C, 0x9E, 0xD5, 0x1E, 0x55,
        0xD9, 0xA8, 0x9D, 0x60, 0xE0, 0xFC, 0x37, 0x8C,
        0x47, 0xA2, 0x1D, 0x5E, 0x0F, 0x2D, 0xC3, 0xBC,
        0xEF, 0x5E, 0x05, 0xC6, 0xE0, 0x26, 0x15, 0x30,
        0xFB, 0x02, 0x7E, 0x50, 0x32, 0x55, 0x8C, 0xA2,
        0xB4, 0x70, 0x05, 0xBD, 0xDE, 0x99, 0x90, 0x99,
        0x30, 0x39, 0x1E, 0xAD, 0x7F, 0x3F, 0x0A, 0x96,
        0xB3, 0xDE, 0xDA, 0x54, 0xA1, 0x11, 0x45, 0xF5,
        0x30, 0xE5, 0x1D, 0xEF, 0x89, 0x2E, 0x5A, 0xB0,
        0x20, 0x4D, 0x61, 0x4E, 0x6E, 0x38, 0xAF, 0xE7,
        0x9C, 0xA9, 0x2C, 0x28, 0x15, 0x8D, 0x57, 0x01,
        0x20, 0x35, 0x3B, 0x7A, 0x4D, 0xE0, 0x88, 0x98,
        0x46, 0xD8, 0x35, 0x29, 0x49, 0x39, 0x55, 0x7E,
        0xD0, 0xAE, 0xDA, 0x27, 0x0D, 0x4D, 0x73, 0xED,
        0x84, 0xD3, 0xD4, 0x9F, 0x9F, 0x03, 0x2D, 0x43,
        0x45, 0x7B, 0xF5, 0x9B, 0xB7, 0xD6, 0x63, 0x59,
        0xDC, 0x53, 0xF9, 0xB4, 0x69, 0x63, 0xB2, 0x17,
        0x84, 0xB0, 0x6C, 0xBC, 0xF0, 0x4B, 0xEC, 0x1E,
        0x33, 0xA3, 0x33, 0x71, 0x53, 0x27, 0x16, 0xC9,
        0xED, 0xB3, 0xFB, 0xED, 0xB8, 0x19, 0x99, 0xB4,
        0x37, 0x2D, 0x09, 0x45, 0xC1, 0x0A, 0xE8, 0x26,
        0xC6, 0x0F, 0xFE, 0x93, 0x17, 0x0B, 0x6D, 0x29,
        0x4B, 0x38, 0x91, 0xB0, 0xD2, 0xA7, 0xB3, 0x5B,
        0x28, 0xA8, 0x97, 0x18, 0x45, 0xDC, 0x2F, 0xEC,
        0xE2, 0x37, 0xB8, 0x0F, 0x20, 0xB3, 0x79, 0xCC,
        0x4D, 0x13, 0x6D, 0xAB, 0x3F, 0xBB, 0x37, 0x92,
        0xC6, 0x3E, 0xC6, 0x1F, 0x5C, 0x75, 0x5B, 0xC9,
        0xDB, 0x35, 0x08, 0x6F, 0xBF, 0x46, 0xD2, 0xB7,
        0x97, 0x0D, 0xCA, 0x2A, 0x85, 0x23, 0xFD, 0xB4,
        0xC7, 0xA0, 0xB8, 0xE4, 0x2F, 0x8A, 0xF9, 0xAC,
        0xAD, 0x2A, 0x0E, 0xFC, 0x11, 0x36, 0x02, 0xA4,
        0xEA, 0x62, 0xE4, 0xEB, 0xB7, 0xD2, 0x69, 0xC3,
        0xA4, 0x0B, 0xA2, 0xC4, 0x4E, 0xDD, 0x29, 0x56
    };
    static const byte msg_65[] = {
       0xC4, 0xF5, 0x9F, 0xA2, 0xDE, 0x30, 0xC8, 0x42,
        0x0A, 0x7E, 0x7F, 0x09, 0x6B, 0xAF, 0x6A, 0xD6,
        0x9B, 0x1C, 0x15, 0xA5, 0xC6, 0xE6, 0x1C, 0x9D,
        0x82, 0xAF, 0xCF, 0xDB, 0x6E, 0xB8, 0xF2, 0x75,
        0xBF, 0x57, 0x87, 0x18, 0x6A, 0xAE, 0x78, 0x1F,
        0x48, 0x7F, 0x9F, 0x88, 0x75, 0x8C, 0x9C, 0x61,
        0xF3, 0x5D, 0x50, 0x83, 0xEE, 0x70, 0x42, 0x4B,
        0x0D, 0x0A, 0x51, 0x57, 0x50, 0x10, 0xC2, 0xA9,
        0x07, 0xF4, 0x96, 0x08, 0x11, 0x5D, 0x33, 0xEB,
        0xA0, 0x03, 0x15, 0x09, 0x32, 0x2A, 0xA7, 0xD3,
        0x06, 0x1F, 0xEC, 0x31, 0x62, 0xF9, 0x6A, 0x56,
        0x5F, 0x98, 0x76, 0x9E, 0x9A, 0x19, 0x23, 0x5D,
        0x89, 0xD1, 0xB2, 0x1D, 0x60, 0xA3, 0x81, 0xDF,
        0x8E, 0xB3, 0x7D, 0x58, 0xC6, 0xA2, 0xE4, 0x83,
        0xA8, 0xEB, 0x70, 0x73, 0x6E, 0x4B, 0x7B, 0xB9,
        0x11, 0xF7, 0xAB, 0x92, 0x3D, 0xC2, 0x9F, 0x1E
    };
    static const byte sig_65[] = {
        0xE8, 0x95, 0xDB, 0x64, 0xC5, 0x7B, 0xC3, 0xC2,
        0xA9, 0x7F, 0x0E, 0xC9, 0x33, 0x41, 0x0E, 0x98,
        0xF6, 0x21, 0x61, 0x03, 0xE3, 0x42, 0x3C, 0xAF,
        0x06, 0xA6, 0x71, 0x96, 0x4C, 0x51, 0x4A, 0x69,
        0x4E, 0xB6, 0xF6, 0x5C, 0xBD, 0x11, 0x37, 0xCC,
        0xCF, 0x88, 0x81, 0xFA, 0x40, 0x3C, 0x5F, 0xA0,
        0xE0, 0xB2, 0xF3, 0x6B, 0x9F, 0x40, 0x09, 0xC3,
        0x78, 0x21, 0x0D, 0x29, 0xE5, 0x4A, 0x7A, 0x5A,
        0x9B, 0x79, 0x31, 0x97, 0xCD, 0x6D, 0x2F, 0x38,
        0xD7, 0xE1, 0xF3, 0xAC, 0xA6, 0x9D, 0x48, 0x88,
        0x13, 0x89, 0x38, 0x1C, 0x89, 0xFA, 0x67, 0x6D,
        0xE4, 0x26, 0xD6, 0x34, 0xF9, 0xA1, 0x57, 0x05,
        0x5F, 0x17, 0x28, 0x3E, 0xCE, 0x82, 0x48, 0xCA,
        0xF1, 0x4D, 0xCF, 0x11, 0xE2, 0xD5, 0x63, 0x55,
        0xB0, 0x47, 0xDF, 0x63, 0x2A, 0x18, 0x48, 0x2E,
        0x79, 0xCB, 0x2D, 0x5A, 0x74, 0x39, 0x66, 0xBA,
        0xA8, 0xA7, 0x61, 0x21, 0xBB, 0x69, 0xC2, 0xE6,
        0x81, 0x55, 0xAC, 0xCB, 0x0A, 0x31, 0xDA, 0x6E,
        0xDC, 0x73, 0xCB, 0x09, 0xA9, 0xE6, 0x60, 0xFE,
        0xB2, 0x0F, 0x66, 0xC7, 0xBD, 0x96, 0x7A, 0xDE,
        0x32, 0x14, 0x9C, 0x55, 0x52, 0xEA, 0xEB, 0x2E,
        0xA1, 0x75, 0xB5, 0x62, 0x33, 0xF3, 0xB3, 0x70,
        0xED, 0xD8, 0x67, 0x92, 0x69, 0xCE, 0x0D, 0x2B,
        0x43, 0xF6, 0xB2, 0xF6, 0x5F, 0xE9, 0x57, 0xE7,
        0xAB, 0x37, 0xB9, 0x82, 0x04, 0x37, 0x54, 0xEA,
        0xC8, 0xA3, 0x0B, 0x36, 0xC1, 0x00, 0x04, 0xEF,
        0x13, 0xC6, 0x92, 0xE2, 0x19, 0xAA, 0x7A, 0xF0,
        0xA4, 0xC5, 0x28, 0x69, 0x10, 0xC7, 0x10, 0x0D,
        0xA4, 0x1E, 0x17, 0xBB, 0xEF, 0x2D, 0xA2, 0xAB,
        0x03, 0xAD, 0xF3, 0x07, 0x4B, 0xA1, 0xDA, 0x15,
        0xBC, 0xC8, 0x48, 0x05, 0xB8, 0x9B, 0x9D, 0xA8,
        0x8E, 0x9B, 0x40, 0x0A, 0xFB, 0x7E, 0x3B, 0xC8,
        0x33, 0x8D, 0x35, 0x4D, 0xA9, 0x53, 0xAC, 0x0B,
        0xAD, 0x82, 0x27, 0x56, 0xCA, 0x92, 0xE5, 0xDD,
        0x95, 0x07, 0xF4, 0x2B, 0xFE, 0xFC, 0xCB, 0x32,
        0xB4, 0xB9, 0x1A, 0x2B, 0xE5, 0xEF, 0x34, 0xC2,
        0xCF, 0x11, 0x77, 0xEA, 0xAF, 0xB2, 0x50, 0xAC,
        0x9A, 0xDE, 0xC4, 0xBE, 0x71, 0x80, 0x75, 0x89,
        0xF1, 0x00, 0x32, 0x27, 0xF9, 0xB7, 0x6B, 0x74,
        0xE0, 0x7B, 0xA6, 0x7A, 0xC6, 0x08, 0x19, 0xB2,
        0xAF, 0x76, 0x6A, 0x47, 0xFF, 0xFC, 0x7B, 0x76,
        0xD3, 0xA7, 0xC0, 0x77, 0xF5, 0xEC, 0x69, 0xAE,
        0xEA, 0x3E, 0x96, 0x38, 0x59, 0xB8, 0x2C, 0x2A,
        0xDE, 0x58, 0xBE, 0xC2, 0x15, 0x2E, 0xC8, 0x20,
        0x51, 0x10, 0x97, 0x5D, 0x37, 0xC6, 0x50, 0x5E,
        0x0D, 0xC7, 0x76, 0xFD, 0xE0, 0x71, 0x09, 0x7E,
        0x93, 0x01, 0x3D, 0x10, 0x04, 0xF4, 0xE1, 0xA2,
        0xFD, 0x79, 0xB8, 0x77, 0xED, 0x50, 0x25, 0xF5,
        0x27, 0xF3, 0xBF, 0xF1, 0x37, 0xF0, 0x41, 0xBB,
        0x9B, 0xD0, 0x01, 0xE9, 0x49, 0xF0, 0x8B, 0x4C,
        0xF8, 0x8D, 0xFD, 0x32, 0xFC, 0x7C, 0xDB, 0xCE,
        0xCC, 0xFD, 0xB0, 0xFA, 0x2D, 0xE7, 0x82, 0x3E,
        0x11, 0x0B, 0xCF, 0xF5, 0x8A, 0x41, 0x2C, 0xEA,
        0x27, 0x95, 0x75, 0x3E, 0x9C, 0x89, 0x67, 0x8C,
        0x3A, 0xE2, 0x42, 0x68, 0xF7, 0x48, 0x9F, 0x72,
        0x97, 0x4B, 0x69, 0x55, 0xED, 0xD0, 0x4E, 0x19,
        0x0D, 0x99, 0xBB, 0x0D, 0x7A, 0x25, 0x2F, 0xAD,
        0x5B, 0xBA, 0x60, 0x6C, 0x1A, 0x1F, 0x3A, 0xCA,
        0x73, 0x3B, 0xFA, 0xE3, 0x30, 0x9E, 0xA0, 0xA6,
        0xEB, 0x7D, 0x07, 0xE3, 0x6D, 0x8C, 0xA3, 0x36,
        0xD2, 0x64, 0x4F, 0xCE, 0x1A, 0x41, 0x89, 0x5D,
        0x01, 0x4D, 0x1A, 0x60, 0xCB, 0x10, 0x6F, 0x3F,
        0x80, 0x75, 0xF9, 0x37, 0x84, 0x61, 0x73, 0x8D,
        0x63, 0xD1, 0x15, 0xD0, 0x0B, 0x02, 0x4C, 0x67,
        0x78, 0x01, 0x05, 0x0A, 0x1B, 0x0B, 0x50, 0xDE,
        0x05, 0x7F, 0x85, 0xDB, 0x6A, 0xEB, 0x2C, 0x9D,
        0x6B, 0xB7, 0x40, 0x2A, 0x66, 0xE3, 0xAB, 0x4D,
        0xB0, 0x5C, 0x58, 0xBB, 0xDA, 0x12, 0xF6, 0x95,
        0x95, 0x8B, 0x8A, 0xC7, 0xB4, 0xE4, 0x5E, 0xC6,
        0xC9, 0x52, 0xF6, 0x79, 0xC1, 0xEE, 0xBD, 0xF8,
        0x60, 0xE3, 0x48, 0x98, 0x27, 0x79, 0xAA, 0x69,
        0x88, 0xEF, 0xC2, 0xAD, 0x1D, 0xC1, 0xEA, 0xE2,
        0x2A, 0x27, 0xA5, 0xB2, 0xC6, 0x1C, 0x97, 0xB3,
        0xB2, 0x49, 0x3C, 0xB6, 0xC1, 0x3C, 0x5F, 0x6E,
        0x20, 0xA6, 0x7B, 0x88, 0xD3, 0xC3, 0xAC, 0xCF,
        0xAF, 0x0A, 0x42, 0x57, 0x42, 0xDF, 0x24, 0x06,
        0x34, 0xD1, 0xEE, 0x59, 0x38, 0x28, 0xFE, 0x62,
        0x97, 0x44, 0x6C, 0x07, 0x6F, 0x97, 0x90, 0x55,
        0x98, 0x8A, 0xB8, 0x34, 0xB2, 0xBD, 0x82, 0xE1,
        0x4D, 0xC0, 0x86, 0x40, 0x0E, 0x1C, 0x95, 0x6C,
        0xC0, 0xC3, 0x0C, 0xE7, 0xBF, 0xD9, 0x62, 0x22,
        0x3D, 0x23, 0xFE, 0x94, 0x94, 0x96, 0x4A, 0x81,
        0x1B, 0x93, 0xE8, 0xD7, 0xB8, 0xF3, 0x4C, 0x89,
        0xAA, 0xD4, 0x5D, 0xD4, 0x11, 0x3F, 0x2A, 0xE7,
        0xBD, 0x94, 0xB5, 0x3F, 0xC8, 0x6E, 0x8B, 0x2A,
        0xE8, 0x2E, 0x51, 0xEC, 0x6F, 0x3E, 0xA4, 0xC3,
        0x0D, 0x60, 0xB8, 0x60, 0x72, 0x74, 0x86, 0x12,
        0xD1, 0x60, 0x70, 0x56, 0xB5, 0xFF, 0x6A, 0x45,
        0x00, 0xEE, 0xE7, 0x8A, 0x5A, 0x63, 0x9C, 0x7B,
        0x74, 0x16, 0x97, 0x77, 0x62, 0x68, 0x64, 0xDD,
        0x9E, 0xAE, 0xF0, 0xE3, 0xAD, 0x84, 0x93, 0xD8,
        0x31, 0xF7, 0x1D, 0xEA, 0x95, 0xBB, 0xFC, 0xF8,
        0x14, 0x23, 0xA2, 0x66, 0xDE, 0x56, 0xF3, 0xA8,
        0xFE, 0x8E, 0x6C, 0x3C, 0x0D, 0x61, 0x2F, 0xB6,
        0x2B, 0xD6, 0x42, 0x18, 0x8C, 0xA7, 0x1C, 0xB8,
        0x98, 0x34, 0xF3, 0x0B, 0xCC, 0x28, 0xBD, 0x17,
        0x88, 0x45, 0xF1, 0xF6, 0xF4, 0x6C, 0x03, 0xD3,
        0x06, 0xF7, 0xED, 0x4E, 0x68, 0x75, 0x94, 0x27,
        0xAE, 0xC2, 0x70, 0x11, 0x98, 0xC3, 0xC0, 0x5D,
        0x38, 0x5D, 0xFA, 0xFD, 0x52, 0x8C, 0xCE, 0x84,
        0x25, 0xBC, 0x55, 0x14, 0x69, 0xA0, 0xED, 0x68,
        0x1B, 0xEE, 0x4D, 0x12, 0xA8, 0x43, 0xE3, 0x33,
        0xB5, 0xA8, 0xE0, 0x51, 0x7F, 0xC6, 0x19, 0x06,
        0xF9, 0xC4, 0xE7, 0x80, 0x9B, 0xAE, 0xD4, 0xD3,
        0xD1, 0x6E, 0xB2, 0x2F, 0x1F, 0xA9, 0xAB, 0x40,
        0x2D, 0x98, 0x8E, 0xD5, 0x9F, 0x9F, 0xED, 0x04,
        0x55, 0xE9, 0x26, 0x0F, 0xD6, 0x27, 0xA2, 0x4A,
        0x17, 0xFE, 0x7C, 0xB6, 0x3E, 0x53, 0x0B, 0x48,
        0xF5, 0xFB, 0x66, 0x87, 0xA2, 0xE8, 0xC4, 0x9D,
        0xA7, 0x9F, 0xBD, 0x69, 0xA3, 0x40, 0x00, 0x56,
        0x66, 0x5D, 0xD1, 0x1D, 0x19, 0xA2, 0xBC, 0x4D,
        0xB1, 0xD3, 0x74, 0xAB, 0x6A, 0x6E, 0x42, 0x47,
        0x2A, 0x27, 0xAC, 0x6B, 0x98, 0xF6, 0x76, 0xE8,
        0xED, 0xAA, 0xDD, 0x51, 0x4F, 0x6D, 0x44, 0xDE,
        0xEC, 0xDA, 0xB5, 0xA6, 0xDF, 0xA0, 0xF8, 0x4F,
        0x13, 0x9A, 0x80, 0x3A, 0x25, 0x24, 0xBF, 0x33,
        0x5D, 0xC5, 0x2E, 0xA5, 0x8F, 0xA5, 0x0D, 0x98,
        0xFB, 0x5C, 0xD5, 0x5D, 0x5D, 0x50, 0xA6, 0x63,
        0xCF, 0x64, 0x7E, 0xEE, 0x56, 0xFE, 0x8E, 0x66,
        0x4B, 0x3B, 0xCA, 0xF9, 0xE3, 0x33, 0x97, 0x8A,
        0x79, 0x46, 0x97, 0x3F, 0xD1, 0x13, 0xE4, 0xFD,
        0x39, 0x24, 0xE6, 0xC0, 0x9E, 0x60, 0x38, 0x64,
        0x44, 0x21, 0x4D, 0xFA, 0x7A, 0x4D, 0x67, 0x1F,
        0xC2, 0x38, 0x90, 0x63, 0x7E, 0xB8, 0x59, 0x13,
        0x4D, 0x79, 0xE2, 0x65, 0xC5, 0x9C, 0xA3, 0xEC,
        0xCD, 0xDF, 0xA0, 0x18, 0x22, 0x3C, 0x9B, 0xAE,
        0x1C, 0xCA, 0x10, 0x39, 0x62, 0x07, 0x8B, 0xC5,
        0xF0, 0xDD, 0x02, 0x24, 0x6F, 0xA2, 0x83, 0x24,
        0xF7, 0xCB, 0x2F, 0xCF, 0xAD, 0x07, 0xC2, 0x5B,
        0x4B, 0xC2, 0xD8, 0x88, 0x06, 0x9B, 0x0C, 0xF5,
        0xF2, 0x3C, 0x76, 0x1C, 0x0E, 0x47, 0x10, 0x98,
        0x81, 0xCD, 0x31, 0x45, 0x6A, 0x64, 0xB9, 0x40,
        0xB4, 0xBB, 0x9B, 0x4C, 0x2C, 0x3B, 0x8E, 0x6B,
        0xA8, 0x34, 0xAA, 0xAE, 0x69, 0xFD, 0xFC, 0x47,
        0xD4, 0x4B, 0x3C, 0x96, 0x88, 0x7A, 0xBE, 0xD3,
        0x60, 0x15, 0xE7, 0xB6, 0x4E, 0x85, 0x42, 0x92,
        0x8F, 0x27, 0x7C, 0xBD, 0x2D, 0x3C, 0x51, 0x2C,
        0x24, 0xDE, 0xEF, 0xE5, 0x90, 0xE8, 0x1C, 0x68,
        0x4E, 0x06, 0x3E, 0x7A, 0xAD, 0xCF, 0x11, 0x7B,
        0x48, 0x94, 0x3D, 0xB7, 0x71, 0xFC, 0x22, 0x07,
        0xF5, 0x7A, 0x74, 0x53, 0x57, 0x55, 0x5D, 0x41,
        0x9C, 0x9C, 0xDC, 0xA3, 0x5C, 0xC1, 0xA7, 0x10,
        0x0A, 0x69, 0x13, 0xA3, 0xB6, 0xAA, 0xCF, 0x79,
        0x6F, 0xE3, 0xF9, 0x4D, 0xD2, 0xF8, 0x18, 0x98,
        0x27, 0x16, 0xCE, 0x03, 0x16, 0x54, 0x2A, 0x1B,
        0x95, 0x7E, 0x12, 0xDA, 0x43, 0xE2, 0x31, 0x54,
        0x2C, 0xC1, 0x4F, 0xCC, 0x66, 0xD7, 0x28, 0xA6,
        0x83, 0x26, 0xB2, 0xBC, 0x31, 0x12, 0x48, 0x33,
        0x0F, 0x3E, 0x98, 0xF8, 0x1E, 0xA3, 0x8C, 0xA9,
        0x24, 0xA8, 0xE4, 0xDA, 0x97, 0xCF, 0x67, 0x38,
        0x42, 0xC7, 0x59, 0xF9, 0x35, 0xBE, 0x88, 0x16,
        0x3C, 0xE9, 0x7F, 0xE4, 0xD9, 0x45, 0x71, 0x76,
        0xF5, 0xB8, 0x90, 0x8A, 0xF9, 0x48, 0xF7, 0x4D,
        0x5D, 0x1D, 0xDB, 0xC5, 0x21, 0x82, 0x5D, 0x93,
        0x1C, 0x63, 0xCA, 0x8A, 0x8E, 0x12, 0x24, 0x26,
        0x26, 0x30, 0x5A, 0xB6, 0xA2, 0xE0, 0x62, 0x45,
        0x64, 0xEE, 0x04, 0x19, 0x83, 0xC1, 0x8C, 0x29,
        0x52, 0xEC, 0x3D, 0x9D, 0x15, 0x9B, 0xDE, 0x39,
        0x85, 0xCF, 0x77, 0x89, 0x7E, 0xE2, 0xDC, 0x88,
        0x81, 0x12, 0x72, 0x1D, 0x48, 0x54, 0xE9, 0x14,
        0xA5, 0x39, 0x7E, 0x08, 0xB5, 0x4F, 0x4A, 0x54,
        0x32, 0x3F, 0xF8, 0x20, 0x82, 0x1B, 0xE0, 0x26,
        0xEA, 0x09, 0x1E, 0xCA, 0x6B, 0x7D, 0x80, 0xD9,
        0x1E, 0x3D, 0xCA, 0x2E, 0xF7, 0x84, 0x8B, 0x86,
        0xFC, 0xA6, 0xBB, 0x40, 0xCE, 0x48, 0x27, 0x1E,
        0x10, 0x08, 0x36, 0x8E, 0x3E, 0xBB, 0x5E, 0x39,
        0x5E, 0x1C, 0xCD, 0x0D, 0x17, 0x8F, 0x1A, 0x62,
        0x57, 0xD2, 0x6B, 0x6B, 0xA4, 0xB7, 0xCE, 0x53,
        0x2C, 0xAA, 0x1E, 0x76, 0xCE, 0x28, 0xFA, 0x4C,
        0xF9, 0xE0, 0x29, 0xE2, 0x48, 0x2B, 0x94, 0xD3,
        0xAC, 0xF9, 0x7A, 0x32, 0x6D, 0x23, 0x5D, 0x1B,
        0xDC, 0x89, 0xF7, 0x00, 0x02, 0x19, 0x84, 0x51,
        0xD9, 0xF1, 0xF1, 0x2C, 0xCD, 0x5B, 0xCA, 0xEC,
        0xDD, 0xE9, 0xE1, 0x4A, 0xC8, 0x07, 0x42, 0xEB,
        0x31, 0xE6, 0x46, 0x4C, 0x83, 0x21, 0x0A, 0x39,
        0xF3, 0x50, 0x98, 0xBE, 0x03, 0x78, 0xD0, 0x74,
        0xCE, 0x1C, 0xCD, 0x1E, 0xBC, 0x1C, 0x77, 0x70,
        0xF7, 0x78, 0xD6, 0x05, 0xF2, 0xBE, 0x59, 0xDB,
        0x7E, 0xA0, 0x7D, 0x80, 0xCC, 0xDF, 0x55, 0xF1,
        0x6E, 0x98, 0x5B, 0x14, 0x2F, 0xB7, 0xBD, 0xA0,
        0x7A, 0xA7, 0xDC, 0xA5, 0xB2, 0x01, 0xE1, 0x95,
        0x0C, 0xF9, 0xA7, 0x28, 0xF2, 0x1E, 0x9A, 0x9D,
        0x8A, 0xC4, 0xD1, 0x32, 0x7E, 0x3B, 0xC0, 0xFF,
        0x33, 0x9A, 0x25, 0x05, 0x22, 0xF6, 0x31, 0xDF,
        0x2E, 0x75, 0x95, 0x51, 0x54, 0x89, 0x3E, 0x4A,
        0x1A, 0xAF, 0x98, 0x66, 0xFE, 0xE1, 0x63, 0x7E,
        0xE1, 0xAA, 0x51, 0x06, 0xD2, 0x44, 0xE9, 0x9E,
        0x6F, 0x31, 0xFC, 0x56, 0x01, 0xBB, 0x7B, 0x79,
        0xBA, 0xD8, 0x28, 0x60, 0xB1, 0xD6, 0x05, 0x9D,
        0x9B, 0x13, 0x2E, 0x02, 0x64, 0x18, 0x02, 0x0D,
        0xB0, 0x6E, 0xB8, 0x39, 0x1F, 0xA1, 0x5B, 0x7A,
        0x0F, 0x29, 0xE3, 0x6D, 0x96, 0x6A, 0xBD, 0x3D,
        0x2A, 0x2F, 0xF3, 0xF2, 0xAA, 0xC3, 0x4C, 0x8B,
        0x45, 0xC7, 0xD2, 0x35, 0x5E, 0xDB, 0xB8, 0x0B,
        0x22, 0x4B, 0xC1, 0x06, 0xEB, 0xC6, 0x75, 0x0E,
        0x55, 0x07, 0x0F, 0x85, 0xA7, 0xCB, 0x60, 0x03,
        0x39, 0x4E, 0x51, 0x61, 0xAE, 0x26, 0xF5, 0xAB,
        0xF8, 0x3F, 0x0D, 0xCC, 0xCF, 0x69, 0xB8, 0x61,
        0x39, 0xAF, 0x86, 0x94, 0xFE, 0x1D, 0xC0, 0x07,
        0x81, 0xEA, 0xE0, 0x9C, 0xDB, 0x42, 0x18, 0x14,
        0x87, 0x80, 0x43, 0xDC, 0x9B, 0x05, 0x30, 0xE5,
        0x54, 0x5A, 0x16, 0x5E, 0x39, 0xA9, 0xB7, 0xDE,
        0x88, 0xB4, 0xAD, 0x2A, 0xEB, 0x90, 0xD3, 0xC3,
        0x29, 0x41, 0x2E, 0xD2, 0xFE, 0x1D, 0x97, 0xB7,
        0x32, 0xC8, 0x43, 0x9D, 0xF4, 0xF8, 0x3D, 0x22,
        0x88, 0x35, 0xB5, 0x38, 0xDC, 0x27, 0x8F, 0xF0,
        0xA2, 0xDC, 0x42, 0xF4, 0x1B, 0x00, 0xCE, 0x3A,
        0xCA, 0x06, 0xB0, 0x5C, 0x48, 0x39, 0xB8, 0x96,
        0x93, 0x15, 0x15, 0xD7, 0x8E, 0xA3, 0x67, 0x3A,
        0x37, 0x82, 0x79, 0xF4, 0xE8, 0x9C, 0xE0, 0x8E,
        0x34, 0x53, 0xFF, 0x2F, 0xB4, 0x53, 0xBE, 0x03,
        0x1C, 0x63, 0x18, 0x62, 0x8A, 0x73, 0x1D, 0x02,
        0x9F, 0xC7, 0xBE, 0xA2, 0xBA, 0x5E, 0xAC, 0x49,
        0x16, 0x27, 0x8B, 0x93, 0x8A, 0x6A, 0x6A, 0xCE,
        0xF5, 0xBF, 0xE2, 0x15, 0x8F, 0x2A, 0xF4, 0x3D,
        0x8E, 0x56, 0xA0, 0x64, 0x9D, 0xF2, 0x8A, 0x25,
        0x0D, 0x2F, 0x25, 0x36, 0xAB, 0xDE, 0x1E, 0x00,
        0x8E, 0xB6, 0x31, 0xF4, 0xBD, 0x0E, 0xB5, 0x55,
        0x73, 0xA4, 0x05, 0x39, 0xA6, 0x00, 0x41, 0x81,
        0xA9, 0xD2, 0xBF, 0x7A, 0x1E, 0x53, 0x50, 0x4F,
        0x11, 0xE0, 0x14, 0x84, 0x07, 0x33, 0x84, 0x41,
        0x31, 0xAC, 0x66, 0x89, 0x46, 0xE5, 0xB8, 0x27,
        0x28, 0x9A, 0xB6, 0xB2, 0x13, 0x66, 0xC5, 0xD0,
        0xE2, 0x64, 0x92, 0x19, 0xB9, 0x2C, 0x47, 0x60,
        0xDF, 0xB7, 0x05, 0xF7, 0xF6, 0x1A, 0x96, 0x56,
        0x4C, 0x9E, 0x84, 0x0D, 0x14, 0xB0, 0xBB, 0x0D,
        0xA8, 0x2D, 0xA5, 0x0F, 0x8B, 0x8E, 0x75, 0x2B,
        0xBF, 0xEA, 0x3B, 0x0A, 0x33, 0x7B, 0xE1, 0x24,
        0xF7, 0x2D, 0x8F, 0x82, 0x49, 0x19, 0x5B, 0xC1,
        0x9C, 0x3E, 0x0B, 0x62, 0xEA, 0xE4, 0x96, 0xD3,
        0x8C, 0xF7, 0x50, 0x0B, 0x4F, 0x10, 0x66, 0x5F,
        0xC2, 0xD2, 0x8B, 0x9E, 0xA9, 0x35, 0xF7, 0xE3,
        0x16, 0x47, 0x2F, 0x4F, 0xF4, 0x01, 0x26, 0x75,
        0x41, 0xBD, 0xB6, 0x23, 0x01, 0x55, 0x4B, 0x20,
        0x09, 0x92, 0x8C, 0x64, 0x45, 0xBB, 0xD0, 0xEF,
        0x21, 0xD0, 0x99, 0x72, 0xF3, 0x50, 0x81, 0xAB,
        0xA9, 0x09, 0x1A, 0x6C, 0x23, 0xFE, 0xD2, 0x9F,
        0x5C, 0xF9, 0xE0, 0x77, 0x9F, 0x7E, 0xFB, 0xAD,
        0x88, 0xE6, 0x2A, 0x45, 0x44, 0x42, 0xB3, 0x00,
        0x79, 0xBE, 0x0A, 0xC9, 0xC6, 0x48, 0x26, 0xB9,
        0x8C, 0x1E, 0x10, 0x01, 0xCB, 0x0F, 0xB0, 0xF0,
        0xA9, 0x5F, 0x79, 0x65, 0xFE, 0x93, 0x12, 0xBF,
        0xDA, 0xEC, 0x33, 0xF9, 0x50, 0x65, 0xC8, 0xE5,
        0x9D, 0x39, 0x50, 0xF8, 0x0A, 0xDC, 0x7F, 0xB3,
        0x34, 0xF2, 0x02, 0xD3, 0xE5, 0xF8, 0xDA, 0x48,
        0x1C, 0x9B, 0x54, 0xA7, 0x59, 0x83, 0x93, 0x0F,
        0xD1, 0xE5, 0xAC, 0xD1, 0x62, 0x84, 0xF0, 0x71,
        0x93, 0xFB, 0xCB, 0x50, 0xD0, 0xDC, 0x00, 0xEF,
        0xF8, 0x20, 0x31, 0x44, 0xC1, 0x1E, 0xC6, 0x14,
        0x20, 0xFC, 0x32, 0xD7, 0x98, 0x2C, 0xE8, 0x96,
        0x40, 0x6B, 0xE7, 0x69, 0xA7, 0x5D, 0xD8, 0xD3,
        0xCA, 0xC7, 0x53, 0xAB, 0xE5, 0xA2, 0x78, 0x65,
        0x5B, 0xF5, 0x4B, 0xE3, 0x3A, 0x1B, 0x83, 0x74,
        0xEB, 0xEE, 0xFF, 0x21, 0x2C, 0x39, 0xCE, 0x51,
        0x46, 0x68, 0xF1, 0xC4, 0x56, 0xEA, 0xA2, 0x53,
        0x28, 0x28, 0xC8, 0x42, 0x93, 0xF1, 0xA5, 0xBC,
        0x9E, 0xB5, 0xDE, 0xDF, 0x55, 0x8A, 0x9B, 0x4C,
        0x12, 0x39, 0xF7, 0x72, 0x72, 0xC6, 0x7E, 0x1A,
        0xB2, 0x8E, 0x1E, 0xFE, 0xC5, 0x89, 0x3E, 0x09,
        0xC1, 0x06, 0x62, 0xB5, 0x3C, 0x8B, 0x82, 0x55,
        0xB1, 0xC8, 0xDC, 0x8F, 0x8E, 0x51, 0x20, 0xA2,
        0x5C, 0x75, 0xEE, 0xFE, 0x79, 0xC4, 0x3F, 0x7A,
        0x8B, 0x37, 0xDF, 0x9D, 0x1E, 0x4F, 0x32, 0x48,
        0x69, 0x33, 0xDA, 0x1C, 0xB0, 0x66, 0x4C, 0x5D,
        0xB3, 0x9E, 0x21, 0xBC, 0x22, 0x7B, 0x0C, 0xDF,
        0xE7, 0xA5, 0x50, 0x7F, 0x07, 0xF2, 0x18, 0xA7,
        0xA4, 0x7D, 0xEB, 0xCD, 0x9D, 0xAD, 0x72, 0x47,
        0xB4, 0xD0, 0x45, 0xA1, 0x3A, 0xD4, 0xF7, 0x5E,
        0xAD, 0x2D, 0x45, 0xC3, 0x39, 0xD0, 0xDF, 0x04,
        0x57, 0x7F, 0x2E, 0x0F, 0xDC, 0x78, 0x03, 0x92,
        0x55, 0x30, 0x33, 0xC7, 0x38, 0x85, 0x2B, 0x1B,
        0xE4, 0xE6, 0x3E, 0xA3, 0x89, 0x7D, 0x6C, 0x9C,
        0x4B, 0x11, 0xAD, 0x6B, 0x58, 0xD3, 0xE2, 0xD3,
        0x42, 0xD3, 0x28, 0x40, 0xF6, 0x49, 0xDD, 0x83,
        0xE7, 0x59, 0x86, 0x6B, 0x73, 0x81, 0xA8, 0x4C,
        0x8A, 0xDD, 0xDF, 0x41, 0x3F, 0xAE, 0x18, 0xE6,
        0x43, 0x1B, 0x1E, 0xEA, 0x73, 0xA5, 0x6C, 0xD8,
        0x89, 0xB7, 0x6B, 0xC9, 0x78, 0x6B, 0xED, 0xED,
        0xCA, 0x25, 0x41, 0xE4, 0xC9, 0xB2, 0x4E, 0x28,
        0xF5, 0x8A, 0xD3, 0x74, 0xC1, 0xD9, 0x3D, 0xF2,
        0xD3, 0xF2, 0xC3, 0x7E, 0xC5, 0x94, 0xA0, 0x49,
        0x8C, 0x57, 0x45, 0x79, 0xA7, 0x33, 0x2F, 0x72,
        0xC0, 0xF9, 0x75, 0x08, 0x77, 0xFA, 0xD5, 0xB9,
        0x0B, 0x96, 0x8D, 0x88, 0xF1, 0x16, 0x82, 0xC4,
        0x07, 0x1E, 0x4E, 0xA3, 0x8B, 0x81, 0x6A, 0xEA,
        0xD6, 0xBE, 0x54, 0xD2, 0xF3, 0x71, 0x32, 0x4F,
        0x24, 0x75, 0xB8, 0x62, 0xC7, 0x54, 0x24, 0xEC,
        0xF9, 0x85, 0x8A, 0xA4, 0xE2, 0x00, 0xCF, 0xBA,
        0x41, 0x2D, 0x7E, 0x3E, 0x6C, 0x30, 0x8D, 0x8D,
        0xE1, 0x1D, 0xD1, 0x85, 0x33, 0x1A, 0xF9, 0xD4,
        0x1A, 0xFE, 0x88, 0x79, 0x96, 0x5D, 0x67, 0x46,
        0xEF, 0x21, 0xFD, 0x98, 0xD3, 0xED, 0x38, 0x06,
        0xFB, 0x5C, 0x46, 0x19, 0xC9, 0x8E, 0x34, 0x7D,
        0x76, 0xB8, 0xB8, 0x98, 0x49, 0x39, 0x55, 0x61,
        0xEE, 0x28, 0x6D, 0xFD, 0xFC, 0x6A, 0x04, 0xE1,
        0xD4, 0x7E, 0x9F, 0x5B, 0x5B, 0x49, 0x25, 0x77,
        0x84, 0xC3, 0x93, 0x64, 0xDF, 0xA8, 0x8A, 0xD6,
        0x30, 0xDF, 0xA5, 0x9C, 0xCA, 0x32, 0x37, 0xF4,
        0xA2, 0xB1, 0x41, 0xA8, 0x13, 0xD2, 0x2C, 0x6F,
        0xFE, 0x73, 0xC2, 0xD9, 0x9A, 0xDC, 0x82, 0x4D,
        0x93, 0xE0, 0x6A, 0x54, 0xB6, 0xDE, 0x62, 0xC3,
        0x12, 0x5D, 0x94, 0xB4, 0x9E, 0x95, 0x0D, 0xEC,
        0x36, 0x1F, 0x96, 0x1F, 0x56, 0xD3, 0x67, 0x1C,
        0x99, 0x25, 0x37, 0x7F, 0x6E, 0x67, 0x06, 0x65,
        0x32, 0x2B, 0x84, 0x89, 0xE8, 0x33, 0xD3, 0x83,
        0x0E, 0xCC, 0xDD, 0x0F, 0x53, 0xF4, 0xA4, 0xF9,
        0xD6, 0x8F, 0x14, 0x45, 0xF3, 0xAE, 0xD5, 0xC9,
        0xD7, 0x66, 0x40, 0x9B, 0x59, 0xBA, 0xE7, 0xA7,
        0x29, 0x12, 0xE9, 0x8B, 0x3B, 0xB5, 0x73, 0x42,
        0xD2, 0x9B, 0x6A, 0xCF, 0xD1, 0x43, 0x36, 0xB7,
        0xB8, 0xB6, 0xB7, 0x54, 0x9A, 0xF8, 0xCC, 0x88,
        0x45, 0xE1, 0x0C, 0x28, 0x11, 0x28, 0x72, 0x81,
        0x98, 0x5D, 0x5D, 0x47, 0x68, 0x5F, 0xC5, 0x89,
        0xF2, 0x67, 0x8E, 0xD8, 0x93, 0xF5, 0x7B, 0x85,
        0xAC, 0xED, 0x75, 0x63, 0x2E, 0x50, 0xDE, 0x5E,
        0x07, 0x4E, 0x6C, 0xED, 0xCF, 0x1A, 0xD4, 0x99,
        0xBC, 0xE6, 0x7A, 0x7F, 0x49, 0x85, 0x64, 0xDE,
        0xEC, 0x67, 0x7C, 0x70, 0x83, 0x88, 0xDE, 0x8F,
        0xD7, 0xB0, 0x99, 0xCF, 0xC1, 0x16, 0x09, 0x6C,
        0x45, 0xFE, 0x28, 0x89, 0x0B, 0x5E, 0xAF, 0x06,
        0x16, 0x99, 0x39, 0xFD, 0xA3, 0x5E, 0x12, 0x15,
        0xF2, 0x38, 0xE8, 0xCD, 0xED, 0xFE, 0x67, 0x00,
        0x65, 0xF5, 0xDE, 0x32, 0x72, 0xA2, 0x32, 0xFD,
        0x53, 0xC2, 0x50, 0xF5, 0xD7, 0x79, 0xB3, 0x16,
        0x94, 0xFB, 0xA9, 0x1B, 0x55, 0x48, 0x03, 0x67,
        0x6E, 0x4D, 0xEA, 0x28, 0x84, 0x63, 0xFE, 0x10,
        0x63, 0x00, 0x9E, 0x9C, 0xB7, 0x6C, 0x31, 0x7D,
        0xB4, 0x00, 0xAC, 0xF4, 0xD2, 0xD2, 0xB6, 0xD1,
        0x6E, 0xDE, 0xBA, 0x41, 0x08, 0x91, 0x3F, 0x60,
        0xAE, 0xB2, 0x52, 0xCD, 0xE4, 0x13, 0x69, 0x0C,
        0xEE, 0xFD, 0xCF, 0xA6, 0x38, 0x96, 0x3D, 0xBD,
        0x04, 0xF4, 0xCF, 0x21, 0xAD, 0x74, 0xDD, 0xE6,
        0x5F, 0x0F, 0x1E, 0x7C, 0xE7, 0x0A, 0xF1, 0x01,
        0xA6, 0xDE, 0x9A, 0x59, 0xDB, 0x21, 0xD3, 0x80,
        0x27, 0xDB, 0xBF, 0x76, 0x16, 0x78, 0x27, 0x95,
        0x0B, 0x69, 0x41, 0x82, 0x66, 0xAF, 0xA4, 0x44,
        0xC7, 0x28, 0xDE, 0x36, 0x24, 0xA1, 0xC8, 0x1E,
        0x5B, 0x16, 0x41, 0xDB, 0xE8, 0x79, 0xCD, 0x82,
        0x2F, 0xB2, 0x30, 0x3C, 0xC3, 0xA9, 0xFC, 0xEE,
        0xFE, 0x3D, 0xDF, 0x7D, 0xBD, 0x0B, 0x70, 0x57,
        0x24, 0x8A, 0x28, 0xD6, 0x06, 0x2D, 0x76, 0xEB,
        0x13, 0xB9, 0x2C, 0x9C, 0x9D, 0x00, 0x3B, 0x69,
        0xE1, 0x84, 0x2A, 0x54, 0xC0, 0x9C, 0xF6, 0xB4,
        0x84, 0x52, 0x08, 0x15, 0xE2, 0xBB, 0x23, 0x72,
        0x88, 0xC6, 0x4F, 0xC6, 0x96, 0xFD, 0x3B, 0xC4,
        0x5D, 0xB3, 0x0C, 0xB8, 0x64, 0x65, 0xDF, 0x11,
        0x88, 0xBF, 0x47, 0x95, 0x6E, 0x5B, 0x91, 0x6A,
        0x80, 0x09, 0x71, 0x5C, 0xC9, 0xA9, 0xA6, 0xDC,
        0xE4, 0x4C, 0x54, 0xF9, 0x28, 0x81, 0x6B, 0x41,
        0xD0, 0x18, 0xC5, 0xFE, 0x65, 0x2F, 0xFE, 0x4E,
        0x33, 0xF3, 0x52, 0xD3, 0x83, 0xA9, 0xC1, 0x36,
        0x5F, 0x02, 0xAB, 0xFD, 0x64, 0x7B, 0xD6, 0xB4,
        0x2A, 0xD1, 0x63, 0x73, 0x0F, 0x8B, 0xFD, 0xA1,
        0xE2, 0xBE, 0x5F, 0x61, 0x4D, 0x79, 0x59, 0x78,
        0x25, 0xBA, 0x09, 0xF4, 0x57, 0xD3, 0xCB, 0xE7,
        0x56, 0x1E, 0x7E, 0x89, 0xEA, 0xF0, 0x59, 0xE9,
        0x77, 0xD1, 0xEE, 0x88, 0x84, 0x8B, 0x78, 0x1F,
        0x21, 0xF7, 0x23, 0x89, 0x0F, 0xF1, 0xF9, 0x87,
        0x39, 0x28, 0x41, 0x2C, 0x8F, 0x11, 0xEE, 0xDD,
        0x2C, 0x0C, 0x39, 0xC9, 0x51, 0x27, 0x90, 0x98,
        0x6A, 0x19, 0xE1, 0x7B, 0x2B, 0x70, 0xA4, 0xD7,
        0xCF, 0x49, 0xD9, 0xD1, 0x8C, 0xAA, 0x0C, 0x20,
        0x23, 0x13, 0x4C, 0xAC, 0xD1, 0x69, 0x20, 0x0D,
        0x88, 0x17, 0xFA, 0x32, 0x1F, 0x04, 0xAC, 0xC9,
        0x10, 0x61, 0x3D, 0xFF, 0x25, 0x0E, 0xB3, 0x25,
        0xDB, 0xEF, 0x29, 0xEB, 0x56, 0x11, 0xB2, 0xAD,
        0x2A, 0x23, 0xED, 0xD5, 0x38, 0x04, 0x9B, 0x3F,
        0x43, 0xEF, 0xEB, 0x4D, 0x60, 0x98, 0x37, 0x92,
        0xB4, 0xBF, 0x05, 0x56, 0x79, 0x44, 0xAA, 0xDB,
        0x7A, 0xC4, 0xD3, 0xA5, 0xD8, 0x0A, 0x1B, 0x9D,
        0x84, 0x48, 0xB4, 0xC0, 0xC1, 0x15, 0xC3, 0xB5,
        0xAD, 0x38, 0x85, 0x35, 0x3F, 0x47, 0xD5, 0xFC,
        0xB9, 0xB7, 0xD6, 0x44, 0x6F, 0x1A, 0x72, 0x10,
        0xBB, 0xC6, 0x67, 0xFC, 0x41, 0x14, 0x15, 0xF2,
        0x3C, 0xD4, 0x0A, 0x2A, 0x3D, 0x64, 0x06, 0x1D,
        0x71, 0xC6, 0x71, 0x91, 0x57, 0x1A, 0x97, 0xD0,
        0x10, 0x88, 0xA2, 0x4B, 0x67, 0x11, 0x56, 0x7F,
        0xC8, 0x91, 0x06, 0x73, 0x2D, 0x88, 0x92, 0xFF,
        0x98, 0x5B, 0x8E, 0x6C, 0xF7, 0x01, 0x63, 0x82,
        0x9C, 0xC0, 0x85, 0xBE, 0x4E, 0x40, 0x83, 0x15,
        0x36, 0x1B, 0xB1, 0xB2, 0x00, 0x3D, 0x64, 0x13,
        0x22, 0x0B, 0x13, 0x45, 0x06, 0xD3, 0xC3, 0x04,
        0xC0, 0xBB, 0xBA, 0x9C, 0x9C, 0x45, 0xD3, 0x65,
        0x1E, 0x05, 0x71, 0xB6, 0xB1, 0x15, 0x17, 0x72,
        0x13, 0xD8, 0x59, 0x5E, 0x14, 0x3D, 0xB9, 0x0B,
        0xD7, 0x2F, 0x7E, 0xB9, 0x74, 0xD8, 0xD0, 0xA0,
        0x31, 0x74, 0x09, 0xD6, 0x4D, 0x58, 0x37, 0xEA,
        0xEC, 0x9B, 0x8D, 0x44, 0xDD, 0x7E, 0xCF, 0xF6,
        0xCD, 0xA9, 0xF7, 0x29, 0x38, 0x2A, 0x43, 0xB3,
        0x79, 0xCB, 0xDD, 0x43, 0xFF, 0xB1, 0x8A, 0xEA,
        0x35, 0xC1, 0xA9, 0x96, 0xCE, 0xF1, 0x48, 0x8D,
        0x3B, 0x7A, 0x81, 0xEE, 0x7C, 0xFC, 0x0B, 0x96,
        0x23, 0x41, 0x8A, 0xB3, 0x91, 0x9A, 0x6E, 0xDD,
        0xB9, 0x9F, 0x22, 0x2F, 0x0D, 0xDD, 0xB2, 0xF3,
        0x2A, 0x20, 0xC8, 0xF8, 0x4F, 0xBF, 0x4C, 0x49,
        0xB4, 0xCB, 0x3E, 0xB5, 0x0D, 0x9C, 0x4C, 0xD2,
        0x5A, 0x6F, 0x71, 0x75, 0x46, 0x70, 0x66, 0xD2,
        0x5E, 0x64, 0x37, 0xB6, 0x7F, 0x2D, 0xBC, 0x70,
        0xC2, 0xE6, 0xEB, 0x0B, 0xDE, 0x23, 0x86, 0xD0,
        0x30, 0x14, 0xA7, 0x89, 0xFB, 0x6D, 0xC0, 0x8E,
        0xE3, 0x3C, 0x0C, 0x67, 0x95, 0x1D, 0xA9, 0xD7,
        0x4B, 0x9C, 0x94, 0x84, 0x5D, 0x2A, 0x99, 0x03,
        0x7E, 0x09, 0x5F, 0xEF, 0x79, 0x19, 0x92, 0x0F,
        0xE5, 0x26, 0xEB, 0x5D, 0xD0, 0xBA, 0x1F, 0x97,
        0xDF, 0xBD, 0x2D, 0xDC, 0x31, 0x60, 0x9C, 0x1B,
        0x7B, 0x45, 0xEC, 0x3A, 0xDB, 0x58, 0x6F, 0xE3,
        0x03, 0x0A, 0x0C, 0x7A, 0x9D, 0xD0, 0x34, 0xA3,
        0xC2, 0xE6, 0xF9, 0x84, 0x90, 0x93, 0xCE, 0xE1,
        0x0A, 0x18, 0x19, 0x53, 0x54, 0x7F, 0x8B, 0xE3,
        0x28, 0x72, 0x0A, 0x4A, 0x5A, 0x82, 0x90, 0xB5,
        0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
        0x0B, 0x10, 0x18, 0x1A, 0x21
    };
#endif
#ifndef WOLFSSL_NO_ML_DSA_87
    static const byte pk_87[] = {
        0x59, 0xB2, 0x37, 0x1F, 0xE7, 0xBA, 0xCC, 0x20,
        0x7F, 0xE1, 0xFE, 0xE8, 0x8A, 0x8B, 0x38, 0x05,
        0xA7, 0x05, 0x28, 0x65, 0x69, 0x17, 0x89, 0xBB,
        0x90, 0x54, 0x2F, 0xA4, 0x7F, 0x7E, 0xF2, 0xB7,
        0x5F, 0xCA, 0x13, 0xDB, 0xA5, 0x88, 0x8B, 0xEC,
        0x32, 0x05, 0x14, 0xDC, 0xB0, 0x5F, 0xD2, 0x6E,
        0xB5, 0x54, 0x1F, 0x6E, 0x57, 0x2E, 0xCE, 0xA6,
        0xC4, 0xF1, 0xD3, 0x8A, 0xA7, 0x02, 0x59, 0x09,
        0x4A, 0xA9, 0x45, 0xF1, 0x9F, 0xED, 0x0D, 0x98,
        0x0E, 0x65, 0xDB, 0xF6, 0x5D, 0xB8, 0x0F, 0x56,
        0x4F, 0xE2, 0x9D, 0x83, 0x6C, 0x54, 0x79, 0x28,
        0x8B, 0x55, 0xCF, 0x07, 0xF4, 0xE0, 0x01, 0x59,
        0xB6, 0x95, 0x5D, 0xAB, 0xDE, 0xCC, 0x8C, 0x4D,
        0x66, 0xAE, 0x68, 0x87, 0x28, 0xBA, 0x6D, 0x5C,
        0x04, 0x42, 0xF3, 0xC1, 0x23, 0x2C, 0x78, 0x2C,
        0x46, 0x5B, 0x9B, 0x7C, 0x50, 0x14, 0xB1, 0x46,
        0x40, 0x65, 0xCC, 0xD8, 0xA5, 0x6D, 0x6B, 0x1C,
        0x16, 0x51, 0x08, 0x69, 0xE0, 0x14, 0xE6, 0x93,
        0x39, 0x98, 0xEF, 0x72, 0x55, 0x20, 0xB4, 0x00,
        0x91, 0x3D, 0x93, 0xB0, 0xEC, 0x75, 0xE2, 0xFB,
        0x72, 0x5D, 0xC1, 0xAE, 0xC0, 0xC0, 0xCC, 0x73,
        0x43, 0xB9, 0xE5, 0x44, 0xBA, 0xA4, 0xD6, 0x79,
        0x86, 0x0E, 0x34, 0x7B, 0x2E, 0x94, 0x7D, 0x8D,
        0x24, 0x36, 0xF0, 0x92, 0x98, 0xA7, 0xBB, 0x83,
        0x36, 0xB9, 0xDE, 0x9C, 0xFD, 0x5C, 0xDB, 0xCD,
        0x91, 0xC7, 0x24, 0x92, 0x68, 0xCA, 0x03, 0xEF,
        0xAC, 0x27, 0x3A, 0xF5, 0x29, 0x68, 0xD5, 0x01,
        0x40, 0x6C, 0xD9, 0xC9, 0x61, 0x59, 0xD7, 0xC1,
        0x5A, 0xA2, 0x90, 0x03, 0x30, 0xC1, 0x18, 0x9C,
        0xFC, 0x2C, 0xD8, 0xB9, 0x12, 0xC4, 0x80, 0xE4,
        0x58, 0x29, 0x7E, 0xF1, 0x4D, 0xB6, 0x94, 0xA3,
        0xF1, 0xE7, 0x2C, 0x1D, 0xFA, 0x3A, 0x3D, 0x2A,
        0x8A, 0x69, 0xE0, 0x11, 0x60, 0x2B, 0x93, 0x02,
        0x0B, 0xAC, 0xD1, 0xC2, 0xF3, 0xAD, 0x06, 0xC9,
        0x5A, 0x7F, 0x36, 0xEB, 0xF5, 0x26, 0x1F, 0x6E,
        0xC1, 0x06, 0x81, 0x6B, 0xB3, 0x30, 0x3C, 0xC0,
        0x0B, 0xF4, 0xE8, 0x68, 0x8D, 0x2E, 0x85, 0x48,
        0xF1, 0x04, 0x90, 0xD9, 0xEB, 0x23, 0xC5, 0x67,
        0x93, 0xB3, 0x4B, 0x84, 0x06, 0xCB, 0xE4, 0x43,
        0xD8, 0x35, 0x6B, 0xCD, 0x0F, 0x4F, 0x61, 0xD0,
        0xD0, 0x17, 0xD5, 0x48, 0x31, 0xB9, 0xBA, 0x32,
        0x9F, 0x89, 0x48, 0xF2, 0x5C, 0x31, 0x22, 0xF9,
        0xDE, 0xDE, 0x8C, 0xEC, 0xBA, 0x51, 0x56, 0x9E,
        0xDF, 0xFF, 0x89, 0x5F, 0xA0, 0x20, 0x86, 0x2C,
        0x5D, 0xF7, 0x9F, 0x86, 0x40, 0x78, 0x48, 0x6B,
        0x5F, 0xB2, 0x28, 0xFD, 0x78, 0x9C, 0x35, 0xFD,
        0xE1, 0xC5, 0x4B, 0xFF, 0xBF, 0x4A, 0x02, 0x5A,
        0x7F, 0xE7, 0xD8, 0xC3, 0x49, 0x0A, 0x5D, 0x4E,
        0x62, 0xD0, 0x4F, 0x79, 0xF4, 0x18, 0x3C, 0xA6,
        0x83, 0x79, 0xF4, 0x64, 0x8B, 0xD5, 0xB2, 0x41,
        0x6D, 0xBE, 0x5B, 0x84, 0x5C, 0x9F, 0x4B, 0x7A,
        0x7E, 0x23, 0x39, 0xC0, 0x50, 0x6D, 0x58, 0x53,
        0x9E, 0xAE, 0xA9, 0x45, 0x1C, 0x9B, 0x2F, 0xE2,
        0xA1, 0x8C, 0x84, 0x9D, 0xCA, 0x7E, 0xED, 0x9D,
        0xAC, 0xC0, 0x58, 0xD0, 0x05, 0xFB, 0x73, 0x75,
        0xC4, 0xEF, 0x45, 0xB0, 0x01, 0x54, 0x3F, 0xC6,
        0x8E, 0x47, 0xDD, 0xB6, 0xD1, 0x4F, 0xF9, 0x37,
        0xD1, 0xAA, 0x0D, 0x4D, 0x74, 0x89, 0xDF, 0xFA,
        0x62, 0x10, 0x67, 0x9C, 0xCC, 0xEC, 0xF9, 0xB8,
        0x55, 0x1D, 0xCF, 0x68, 0x2D, 0x2A, 0xF1, 0xE5,
        0xBD, 0x86, 0x9F, 0x3E, 0x8D, 0x40, 0x0D, 0x5C,
        0x86, 0x1A, 0xE5, 0x1F, 0xE7, 0xEB, 0xBB, 0x54,
        0x57, 0xF2, 0xEA, 0xAF, 0xD0, 0x93, 0xA9, 0x59,
        0x8E, 0xC7, 0x21, 0xC6, 0x93, 0x27, 0xC5, 0x19,
        0x30, 0xF4, 0xB9, 0xFF, 0xB2, 0xAA, 0x7F, 0x1A,
        0x28, 0x43, 0x6B, 0x6D, 0x80, 0x8D, 0x75, 0x39,
        0x2B, 0xC4, 0x3C, 0x1B, 0x5B, 0x85, 0x9C, 0x66,
        0xC5, 0x4F, 0xA5, 0x15, 0xC7, 0xA6, 0x15, 0xA6,
        0x9E, 0x60, 0x92, 0x14, 0x34, 0xAA, 0x9C, 0xF9,
        0xF9, 0xE0, 0x3C, 0x3C, 0xA3, 0x5B, 0x5E, 0xBC,
        0x6A, 0x40, 0x9E, 0x82, 0x2F, 0xE7, 0x6E, 0x09,
        0x24, 0xC6, 0xC0, 0x62, 0xF1, 0x72, 0x4C, 0x38,
        0x2F, 0xF3, 0xC8, 0xAC, 0xB5, 0xC1, 0x66, 0x6C,
        0x2E, 0xC2, 0x6B, 0x76, 0x28, 0xE3, 0xD7, 0xC1,
        0x3D, 0xA8, 0xD7, 0x58, 0x89, 0x0E, 0x6C, 0xC0,
        0x17, 0xB7, 0x89, 0x25, 0x82, 0xE9, 0x5E, 0xDD,
        0x04, 0xBA, 0x93, 0x45, 0xDF, 0x70, 0xFA, 0xD5,
        0x6E, 0xA6, 0x8B, 0xF8, 0x87, 0x5B, 0x93, 0x2C,
        0x28, 0xB3, 0x28, 0x07, 0xC8, 0x63, 0x71, 0xE1,
        0x7D, 0xCC, 0x04, 0x72, 0x5C, 0xB5, 0x97, 0xB5,
        0x24, 0x46, 0x79, 0x63, 0xE1, 0xD4, 0xA6, 0x1B,
        0x5F, 0xBF, 0x9E, 0xC5, 0x04, 0xD5, 0xDD, 0xB6,
        0x17, 0x93, 0xDD, 0x4E, 0x34, 0xAE, 0x08, 0x2A,
        0x59, 0x90, 0xEF, 0xCE, 0x80, 0x1E, 0x93, 0x8C,
        0xCA, 0xE7, 0x38, 0xE0, 0x2E, 0x90, 0x59, 0x9D,
        0x97, 0x1C, 0x2D, 0x7C, 0x64, 0xE5, 0xB6, 0xF8,
        0x63, 0x9F, 0x75, 0x8E, 0xD6, 0x21, 0xC1, 0xF2,
        0x10, 0x73, 0xC0, 0x3E, 0xDB, 0x78, 0x2C, 0x7A,
        0x0F, 0x5D, 0x7C, 0x66, 0xF5, 0xCE, 0x16, 0x1D,
        0xED, 0x55, 0xB3, 0xE9, 0x2D, 0xC2, 0x71, 0x83,
        0xAB, 0x08, 0x3D, 0xBC, 0x1F, 0x39, 0x30, 0xAE,
        0x56, 0xED, 0xB8, 0xC5, 0x3E, 0x9A, 0x7E, 0x02,
        0x0F, 0xFF, 0x0C, 0x40, 0x42, 0xF5, 0x18, 0xB2,
        0x6F, 0x39, 0x0C, 0x96, 0xC8, 0x18, 0x3B, 0x79,
        0xB5, 0x3C, 0x7C, 0x7B, 0xC5, 0x15, 0x18, 0x7B,
        0x3D, 0xE8, 0xCA, 0xB0, 0x87, 0x69, 0xC5, 0xDD,
        0x6F, 0xF5, 0x49, 0x21, 0x12, 0xE8, 0xB0, 0xF2,
        0x8D, 0x09, 0xF4, 0x06, 0x7A, 0xDB, 0x04, 0x19,
        0x4F, 0x60, 0x25, 0x0E, 0x75, 0xAD, 0xE3, 0x31,
        0xA5, 0xC2, 0x55, 0x93, 0xBC, 0xD9, 0x2A, 0x6D,
        0x13, 0x50, 0x43, 0x95, 0x85, 0x86, 0x0B, 0xB6,
        0xFE, 0xED, 0xBD, 0x2F, 0x83, 0x9F, 0x31, 0x7A,
        0x01, 0x35, 0x88, 0x76, 0xC8, 0x8E, 0x89, 0x8A,
        0xC0, 0xC8, 0x53, 0x78, 0xF5, 0x72, 0xF2, 0x3C,
        0xDE, 0x93, 0x1D, 0x47, 0xDE, 0x71, 0xD3, 0x35,
        0x3D, 0xAB, 0x1F, 0x81, 0x0A, 0x61, 0xB1, 0x8D,
        0x24, 0xCD, 0x83, 0xDD, 0xAB, 0x8D, 0x53, 0xBA,
        0x9C, 0x7B, 0x82, 0x74, 0xB0, 0xFE, 0x82, 0xAF,
        0xF3, 0x0C, 0x57, 0x07, 0x2F, 0x64, 0x37, 0x87,
        0xCA, 0x1D, 0xF0, 0x3B, 0x99, 0xEB, 0x57, 0xDB,
        0xDA, 0x8C, 0x8E, 0xE8, 0xEB, 0x20, 0x1F, 0x28,
        0x47, 0xCB, 0xC9, 0xD3, 0x4F, 0xD8, 0x0C, 0xE6,
        0xBC, 0x5E, 0x1E, 0x32, 0x8E, 0xB6, 0xEF, 0xC8,
        0x3C, 0x4B, 0xD9, 0xD5, 0x2F, 0x32, 0x4E, 0x30,
        0xEE, 0x4B, 0x5E, 0x86, 0x35, 0x1E, 0x5C, 0x8C,
        0x4C, 0x54, 0x56, 0x83, 0x6D, 0x5A, 0x45, 0x22,
        0x03, 0xB3, 0xC3, 0x72, 0xC7, 0x87, 0xAE, 0x33,
        0x32, 0xC8, 0xA5, 0xE9, 0xDC, 0x21, 0x97, 0xD9,
        0xC3, 0x41, 0xB9, 0x75, 0x6B, 0xB1, 0xE6, 0x3C,
        0x75, 0xBB, 0xD5, 0xCF, 0x3E, 0x5C, 0xD4, 0xBF,
        0x47, 0xBD, 0x1F, 0xEB, 0xC3, 0xE3, 0x71, 0x09,
        0x12, 0xD6, 0x30, 0x32, 0xF6, 0xB9, 0x7D, 0xC1,
        0x9C, 0x4D, 0xE1, 0x96, 0xAC, 0xD9, 0x15, 0x77,
        0x15, 0xE2, 0xC1, 0x4E, 0x05, 0x4A, 0x93, 0x17,
        0xBF, 0x96, 0xA6, 0x84, 0xBB, 0x96, 0xCE, 0xFB,
        0x7D, 0x8F, 0xDC, 0xA8, 0xAA, 0x47, 0x7A, 0x2A,
        0xF6, 0xF7, 0x26, 0xD2, 0xCA, 0xC1, 0xA6, 0x03,
        0xCF, 0x13, 0x60, 0xEC, 0x11, 0xCA, 0x89, 0x7E,
        0x5B, 0xC7, 0x35, 0xAB, 0x69, 0xB8, 0x64, 0x7F,
        0x30, 0xCE, 0xD4, 0x94, 0x7B, 0xA9, 0xF6, 0x35,
        0xD9, 0xCB, 0x2D, 0x82, 0xA6, 0x62, 0xFF, 0x17,
        0xA0, 0xE1, 0x2D, 0x4D, 0x06, 0xD6, 0x41, 0xEE,
        0x76, 0xEB, 0x8B, 0x45, 0xC7, 0x1E, 0xDE, 0x38,
        0xC9, 0x05, 0xC5, 0x2B, 0xE7, 0x6C, 0x61, 0x09,
        0xF2, 0x61, 0x2F, 0xEE, 0x6C, 0x31, 0x94, 0x46,
        0x5C, 0x19, 0xBA, 0x5D, 0x3E, 0xBC, 0xF1, 0xF0,
        0xB5, 0xE5, 0x34, 0xE0, 0xF0, 0xF1, 0xD3, 0x1C,
        0xB1, 0xE7, 0xA3, 0x6C, 0x43, 0x03, 0xF2, 0x83,
        0xDB, 0xA8, 0x59, 0x1C, 0xC6, 0x09, 0x31, 0x1A,
        0x80, 0x9E, 0x44, 0x4E, 0x33, 0xA8, 0x93, 0x88,
        0x0C, 0xDB, 0xAE, 0x29, 0x11, 0x91, 0x46, 0xA3,
        0x68, 0xE4, 0xD2, 0xED, 0xD9, 0x1F, 0xE4, 0x71,
        0x64, 0x7F, 0xFE, 0x82, 0x1A, 0xA6, 0xD3, 0x1C,
        0x9F, 0xA4, 0x96, 0x95, 0xEB, 0x99, 0x41, 0xB0,
        0x8F, 0x7B, 0xE3, 0xF0, 0x6C, 0xDD, 0xF2, 0x73,
        0x9B, 0x8C, 0xAD, 0x2A, 0xB0, 0xDA, 0x4F, 0x5A,
        0x3C, 0x0A, 0x26, 0xDF, 0x6A, 0x17, 0xB1, 0x37,
        0xCA, 0xAB, 0x3B, 0x91, 0x9A, 0xB6, 0x36, 0xD6,
        0xC8, 0x9B, 0xED, 0xA3, 0x05, 0x88, 0x98, 0x62,
        0x87, 0x21, 0xF2, 0x77, 0x03, 0x15, 0xFE, 0xEE,
        0x88, 0x15, 0x95, 0xE2, 0x4C, 0xF4, 0x8B, 0x44,
        0x16, 0x60, 0xD0, 0xB2, 0xE9, 0xD5, 0xB9, 0x09,
        0x28, 0xC3, 0x81, 0xF2, 0xB0, 0xFA, 0x26, 0x34,
        0x2E, 0x4C, 0x9B, 0x88, 0xC0, 0x88, 0x7A, 0x46,
        0x87, 0x12, 0x4C, 0x01, 0x2D, 0x96, 0x9E, 0x1A,
        0xFD, 0x85, 0x32, 0x75, 0x4B, 0xA1, 0x21, 0x25,
        0xE9, 0x43, 0x3D, 0xCF, 0x6D, 0x7B, 0xC1, 0xA3,
        0x6A, 0x83, 0xE6, 0xA1, 0x0B, 0xA1, 0xCB, 0x76,
        0x52, 0xA8, 0x13, 0x50, 0x89, 0x9C, 0x2D, 0xFC,
        0x6E, 0x4F, 0xED, 0x38, 0xD0, 0x09, 0xE6, 0xD0,
        0xF1, 0xD4, 0x4C, 0xCC, 0xB9, 0x5E, 0x55, 0x1B,
        0x3A, 0xD5, 0x4B, 0x3A, 0xC8, 0x1E, 0x8B, 0xA4,
        0x66, 0x5E, 0xA4, 0x28, 0xB3, 0xC8, 0x61, 0xE8,
        0x67, 0x78, 0x90, 0xCF, 0x5F, 0x62, 0x5C, 0x19,
        0xA7, 0xC5, 0x94, 0x3A, 0x94, 0x01, 0xCB, 0x78,
        0xE7, 0x02, 0x6B, 0xAE, 0x92, 0xB6, 0x0A, 0x8B,
        0x68, 0x07, 0xC1, 0x77, 0x45, 0x41, 0x5C, 0xD8,
        0xE0, 0x30, 0xC6, 0x4C, 0x56, 0xE8, 0x22, 0x13,
        0x9A, 0x35, 0xDA, 0x42, 0x3F, 0x26, 0x43, 0x36,
        0xE0, 0xAF, 0xDF, 0x16, 0x74, 0x30, 0xDD, 0x36,
        0xE0, 0x06, 0x4B, 0x2F, 0x6E, 0x8D, 0x8B, 0xB6,
        0xBE, 0x99, 0xC5, 0xA9, 0xFB, 0x55, 0x1C, 0xC6,
        0x3E, 0x50, 0x8D, 0xB6, 0x36, 0x66, 0x7D, 0xDA,
        0x53, 0xF6, 0x11, 0xF0, 0x2F, 0xCD, 0x1F, 0x99,
        0x41, 0x0F, 0x1A, 0x7A, 0x82, 0x88, 0x2F, 0x96,
        0x23, 0xAD, 0xDC, 0x50, 0xEB, 0x01, 0xE1, 0xF3,
        0x99, 0x78, 0xBF, 0x68, 0x50, 0x6C, 0x71, 0xDB,
        0xBE, 0xE4, 0x2E, 0x4A, 0x80, 0x06, 0x9B, 0x0E,
        0x4C, 0x7F, 0xC4, 0xCC, 0x14, 0x71, 0xF4, 0xF1,
        0x02, 0x8D, 0xB2, 0x5C, 0x46, 0x87, 0xB6, 0x0D,
        0xF4, 0x25, 0x5D, 0xEC, 0x91, 0x48, 0x19, 0x7A,
        0x74, 0x79, 0x6E, 0xC7, 0x60, 0xA6, 0x6A, 0xFC,
        0x78, 0x84, 0x03, 0x86, 0x51, 0x92, 0x09, 0x73,
        0xA6, 0x9C, 0x20, 0x35, 0x16, 0x22, 0x26, 0x32,
        0xEC, 0x58, 0x75, 0xEA, 0x6D, 0x83, 0x80, 0x96,
        0xE7, 0xFE, 0x9B, 0x5B, 0x4F, 0xB6, 0x9C, 0x5E,
        0x94, 0x07, 0xE7, 0x0D, 0x27, 0xFA, 0x34, 0xB0,
        0xCD, 0xBD, 0x6E, 0x11, 0x9D, 0x87, 0xCE, 0x38,
        0x58, 0x1D, 0xF1, 0xD3, 0xE0, 0xDF, 0x3A, 0xE0,
        0x29, 0x04, 0x2A, 0x3B, 0x20, 0xE9, 0x23, 0xEB,
        0xCE, 0x19, 0xA4, 0x95, 0x87, 0x55, 0xEE, 0x2F,
        0x98, 0xFD, 0x23, 0x4C, 0x44, 0x13, 0xE2, 0xDB,
        0xC9, 0x35, 0x59, 0xA4, 0x28, 0xDC, 0x37, 0xF2,
        0xD1, 0x23, 0x5B, 0xD4, 0x41, 0x9B, 0x09, 0x9E,
        0x0F, 0x0D, 0xE5, 0x42, 0xC4, 0x69, 0x35, 0x99,
        0x1B, 0xE0, 0x69, 0x2A, 0x6D, 0x80, 0xB8, 0xFD,
        0x98, 0x86, 0xE0, 0xFA, 0x17, 0x69, 0xB4, 0x9E,
        0x8A, 0xE6, 0x30, 0x7C, 0xB0, 0xBC, 0x1B, 0x49,
        0x73, 0x2D, 0x26, 0xE2, 0x5C, 0xA1, 0xCD, 0x9D,
        0x40, 0x7E, 0x0D, 0x88, 0x64, 0x04, 0x09, 0x41,
        0x61, 0x1F, 0x93, 0x33, 0xB6, 0x36, 0x7E, 0x83,
        0x00, 0xFD, 0x64, 0x6A, 0xC5, 0xA7, 0x1A, 0xD9,
        0x13, 0xEE, 0xFD, 0x80, 0x8D, 0x5C, 0xAF, 0xBF,
        0x15, 0x21, 0xA3, 0x06, 0x2E, 0xC1, 0x84, 0xE5,
        0x21, 0x65, 0x50, 0x1E, 0x00, 0x55, 0x56, 0xDE,
        0x4D, 0xEE, 0x46, 0xF9, 0xE5, 0x3D, 0x7D, 0xEF,
        0x99, 0x09, 0xF3, 0xD5, 0xD9, 0x8C, 0xA8, 0x0D,
        0x87, 0x70, 0x7F, 0x7B, 0xC0, 0xFF, 0x8D, 0x87,
        0x9D, 0x65, 0xD4, 0xD7, 0x83, 0xD1, 0x96, 0xF2,
        0x46, 0x06, 0x93, 0x81, 0x1C, 0xDF, 0x33, 0x35,
        0x8E, 0x08, 0x2D, 0x81, 0xF4, 0xDB, 0x8F, 0x6C,
        0x20, 0x48, 0x61, 0x83, 0xA3, 0x6D, 0x4F, 0xBC,
        0xC8, 0xA1, 0xC6, 0xDA, 0x21, 0xAA, 0x4D, 0xD1,
        0x36, 0xE1, 0x9F, 0xEF, 0x2E, 0xA9, 0x93, 0x97,
        0x2B, 0xB9, 0x98, 0x9A, 0xC1, 0xC3, 0x8A, 0x79,
        0xF3, 0x18, 0x52, 0x17, 0x80, 0x04, 0x12, 0x3C,
        0x46, 0x27, 0x7D, 0x38, 0xA8, 0x8F, 0xC1, 0x58,
        0x9F, 0x25, 0x73, 0x32, 0x28, 0x4C, 0xD8, 0xA8,
        0x73, 0xC2, 0x5A, 0x1A, 0x6D, 0x40, 0x26, 0x5B,
        0x28, 0x5D, 0xF0, 0x93, 0x70, 0xE8, 0x8F, 0x72,
        0xFF, 0x70, 0xE4, 0x34, 0xE8, 0xF6, 0x60, 0x84,
        0xCC, 0xFE, 0xBD, 0xBB, 0xC4, 0xB9, 0x9E, 0xDF,
        0xBC, 0x75, 0x0C, 0xC5, 0xDE, 0xA6, 0x36, 0x17,
        0xF6, 0x47, 0xF5, 0xF0, 0x21, 0xD5, 0x7D, 0x64,
        0xD5, 0xEF, 0xF0, 0x48, 0x63, 0x4D, 0xB2, 0x20,
        0x9D, 0x7C, 0x8B, 0x82, 0xFB, 0x63, 0xB8, 0x82,
        0x3E, 0x4C, 0xA0, 0x57, 0x16, 0x8B, 0xAE, 0x88,
        0xD9, 0x71, 0x52, 0x91, 0x24, 0x0B, 0x37, 0x58,
        0xD7, 0x68, 0x45, 0x01, 0xF8, 0x61, 0x86, 0x7B,
        0x7A, 0x24, 0x1C, 0x06, 0x3B, 0x05, 0xD5, 0xE8,
        0xCA, 0x6B, 0x4C, 0x79, 0xCB, 0x24, 0x35, 0xD7,
        0xF9, 0x94, 0xCB, 0x76, 0x91, 0x5B, 0x4A, 0x54,
        0x87, 0x08, 0xB1, 0x1B, 0x29, 0x44, 0x96, 0x85,
        0x94, 0x1D, 0x43, 0xE6, 0x0A, 0x89, 0x76, 0xF9,
        0xA9, 0x60, 0x72, 0xF9, 0x10, 0x41, 0xF4, 0xC3,
        0xDF, 0x7C, 0x73, 0x96, 0x90, 0x12, 0xAE, 0x1B,
        0x30, 0xE4, 0xB9, 0xC4, 0xE1, 0x33, 0x55, 0x8D,
        0xAB, 0xC4, 0x6C, 0x10, 0x3C, 0x0C, 0xB1, 0xDF,
        0xB9, 0x9B, 0x58, 0x53, 0x74, 0xA5, 0x4F, 0x9B,
        0xA5, 0x6B, 0x72, 0x48, 0xB8, 0xC3, 0xF6, 0x6F,
        0x1D, 0x55, 0x76, 0x0D, 0x6A, 0xBB, 0x43, 0x03,
        0x75, 0x77, 0x4D, 0xFB, 0xA2, 0x05, 0x9C, 0x5D,
        0xDD, 0xB6, 0x59, 0xFD, 0x2E, 0x1D, 0xA9, 0xC3,
        0xF0, 0xB8, 0x08, 0x68, 0xC9, 0x2B, 0xCA, 0xC1,
        0x04, 0x03, 0xDC, 0xD1, 0x40, 0xD6, 0xA3, 0xD3,
        0xF3, 0x5F, 0x8E, 0xF1, 0xA2, 0xDD, 0x98, 0xDE,
        0x1A, 0x43, 0x34, 0x23, 0x85, 0x99, 0xED, 0xAD,
        0x92, 0x0D, 0xC0, 0xAA, 0x69, 0x8E, 0x9F, 0xE6,
        0x10, 0x6A, 0x07, 0x80, 0xC9, 0xC2, 0x45, 0xF2,
        0xC6, 0x5A, 0x0C, 0x3E, 0x5C, 0xD5, 0x36, 0x61,
        0x10, 0xB1, 0x76, 0x0F, 0xCD, 0x41, 0x4D, 0x45,
        0x0D, 0xB9, 0xD7, 0x6A, 0x22, 0xA9, 0xEA, 0xEA,
        0x0C, 0x9F, 0xB7, 0x2E, 0xD5, 0x43, 0xCE, 0x9F,
        0xA3, 0x31, 0x4B, 0xAB, 0x17, 0x68, 0x7E, 0x9D,
        0xE5, 0xAD, 0xAD, 0x75, 0x61, 0xF1, 0xA5, 0xBE,
        0xC1, 0x63, 0x39, 0x26, 0x9A, 0x87, 0xE0, 0x9A,
        0xCB, 0x29, 0xE4, 0xC4, 0x39, 0x60, 0x5E, 0x95,
        0x72, 0xAA, 0x9B, 0x7D, 0x0E, 0x83, 0x71, 0xA3,
        0x0E, 0x41, 0xA0, 0xA7, 0xBD, 0xC0, 0x2D, 0xA3,
        0xA6, 0x12, 0x1B, 0xF2, 0x61, 0xEA, 0xA0, 0x16,
        0xA2, 0x07, 0x4E, 0x44, 0x32, 0xCF, 0x63, 0xAF,
        0x96, 0xBE, 0x81, 0xCE, 0xB6, 0xE0, 0xC2, 0x67,
        0x6A, 0x85, 0x45, 0xC6, 0x6D, 0x2F, 0x30, 0xC9,
        0x8B, 0x54, 0x24, 0xF0, 0xFE, 0xF0, 0x4B, 0x3C,
        0x6C, 0x70, 0x64, 0xE2, 0xD2, 0xE1, 0x1C, 0xBE,
        0x60, 0xF8, 0x57, 0x23, 0xFF, 0xC0, 0xB7, 0x70,
        0xD6, 0x86, 0x6F, 0xFA, 0x58, 0x9E, 0x3F, 0x9B,
        0x2A, 0xBF, 0x75, 0x10, 0x40, 0x19, 0xAA, 0x69,
        0xCB, 0x58, 0x89, 0x5B, 0x47, 0x4A, 0x0A, 0xDE,
        0x2B, 0x60, 0xA4, 0xAB, 0x07, 0x7C, 0x3A, 0x6D,
        0xF6, 0x15, 0x33, 0x4E, 0xBB, 0xE7, 0x32, 0xE9,
        0x52, 0x20, 0x21, 0x39, 0x94, 0xD3, 0xBD, 0xC4,
        0x43, 0xC8, 0xEF, 0x94, 0xAD, 0x51, 0x5F, 0x45,
        0x41, 0x83, 0x55, 0x18, 0x33, 0x14, 0x48, 0x58,
        0x57, 0xAC, 0x12, 0xBA, 0x1D, 0x62, 0xCF, 0x4F,
        0xD4, 0xF4, 0xDE, 0x2A, 0x7F, 0xFF, 0x1E, 0xCF,
        0x0D, 0x29, 0x0C, 0x4C, 0xDF, 0xFA, 0x88, 0xD8,
        0xF4, 0x8C, 0x5B, 0x83, 0x7D, 0x3A, 0x94, 0xCD,
        0x17, 0xB3, 0xD1, 0x69, 0x96, 0x6E, 0xB0, 0x38,
        0xFE, 0x5A, 0x6E, 0x85, 0xDF, 0xC6, 0x0A, 0x00,
        0x23, 0x3F, 0x10, 0x73, 0x19, 0x73, 0xDC, 0x47,
        0x5D, 0x53, 0xBC, 0x7B, 0x9E, 0x60, 0x32, 0x0B,
        0xA7, 0x90, 0x5D, 0x88, 0x51, 0x9F, 0xA3, 0x25,
        0xDF, 0x5A, 0xB0, 0x2B, 0x40, 0xF2, 0xAB, 0xBD,
        0xB3, 0x7D, 0x22, 0x61, 0xCB, 0x81, 0x48, 0x27,
        0x7B, 0x87, 0xAE, 0x32, 0x97, 0x97, 0x6C, 0x80,
        0xC3, 0x51, 0x34, 0xE5, 0xF7, 0x86, 0x90, 0x45,
        0x64, 0xC1, 0x46, 0x99, 0x47, 0xF6, 0x20, 0xFE,
        0x09, 0xFD, 0xF3, 0x86, 0x2C, 0x40, 0x57, 0xA3,
        0xBC, 0xEF, 0x70, 0x75, 0x0C, 0xB7, 0x27, 0xF0,
        0x31, 0x28, 0x3A, 0x18, 0x26, 0xF1, 0x38, 0x1B,
        0x33, 0x48, 0xE3, 0xEA, 0x46, 0x88, 0x60, 0x9E,
        0xCB, 0x19, 0x3A, 0xFA, 0xAE, 0xE1, 0xCD, 0x97,
        0xE4, 0xDD, 0xAA, 0x02, 0xC0, 0xC3, 0x0E, 0x49,
        0xF1, 0x37, 0xD0, 0x82, 0x85, 0x94, 0x15, 0x28,
        0x10, 0x17, 0x59, 0xA7, 0x42, 0x2A, 0xA4, 0x99,
        0xC9, 0x00, 0xA3, 0x79, 0xDD, 0x73, 0xB3, 0x07,
        0x28, 0x4C, 0xCD, 0xDA, 0xF1, 0xFA, 0x1B, 0x0C,
        0x4B, 0x28, 0x0E, 0x3F, 0x9F, 0x1D, 0xB6, 0xD3,
        0x8E, 0xCF, 0x8A, 0x84, 0x1F, 0x9D, 0x4E, 0x40,
        0xEC, 0xA8, 0x62, 0x47, 0xD6, 0xCD, 0x9B, 0x31,
        0xEA, 0xCD, 0x6A, 0x46, 0xF0, 0xE3, 0x33, 0xB9,
        0xE8, 0x3D, 0x69, 0x0D, 0x7E, 0x13, 0x46, 0x76,
        0x19, 0xB4, 0x6A, 0xF9, 0xAF, 0xCF, 0xDC, 0x4A,
        0xA9, 0xA0, 0x49, 0xB1, 0x80, 0x26, 0x0D, 0x70,
        0xD9, 0xEE, 0xDB, 0x8A, 0x53, 0x30, 0x51, 0xAB,
        0x83, 0x51, 0x7A, 0xAD, 0xC2, 0xCD, 0x90, 0x0B,
        0x3E, 0xA5, 0x12, 0x60, 0xF4, 0x64, 0xAF, 0xC5,
        0xD2, 0xDC, 0x41, 0x10, 0x29, 0x77, 0x9B, 0x21,
        0xCE, 0x2C, 0xBD, 0x16, 0x02, 0x18, 0xDF, 0x41,
        0xF6, 0x61, 0xDA, 0x1A, 0xD9, 0x5A, 0xD4, 0x0B,
        0x8C, 0x35, 0x3C, 0x7F, 0x10, 0xFC, 0x23, 0xF8,
        0x30, 0xD1, 0x17, 0xBC, 0xAE, 0xF8, 0xCE, 0xCE,
        0xBC, 0xBF, 0xA4, 0x9D, 0x79, 0xD8, 0xD9, 0x39,
        0x1E, 0x8D, 0x08, 0x28, 0x1F, 0x00, 0x0A, 0x55,
        0xE9, 0x2D, 0xB3, 0x31, 0xBD, 0xEC, 0xD7, 0x31,
        0x83, 0xE0, 0x58, 0xFF, 0x3F, 0xE5, 0x83, 0x9A,
        0xF5, 0x0D, 0x8C, 0x55, 0xF2, 0x2F, 0x6A, 0xFF,
        0x5A, 0x33, 0xDA, 0x77, 0x4B, 0xA1, 0xB3, 0xE6,
        0x43, 0xF5, 0x87, 0x7C, 0xF5, 0x49, 0xC4, 0xF9,
        0x08, 0xEA, 0x64, 0xA3, 0x7D, 0xF3, 0xBF, 0xA4,
        0xCD, 0x5F, 0x70, 0xF8, 0xCD, 0x15, 0x44, 0x76,
        0xD3, 0x4B, 0xC8, 0x53, 0xC9, 0xE8, 0xF7, 0x97,
        0x9E, 0x5F, 0x4E, 0xBB, 0x88, 0x8A, 0xF7, 0x61
    };
    static const byte msg_87[] = {
        0x4A, 0xC4, 0x67, 0x5C, 0x96, 0xD9, 0x11, 0x7D,
        0x1E, 0xDE, 0xB8, 0x0D, 0x7C, 0xD2, 0x84, 0xA3,
        0xE1, 0xE1, 0xFE, 0x03, 0x8E, 0x30, 0x12, 0x05,
        0xB4, 0xC4, 0x08, 0xEB, 0x96, 0x52, 0x35, 0xAD,
        0x1C, 0x85, 0xF8, 0xBE, 0x3F, 0x77, 0xCA, 0x48,
        0x6F, 0xD2, 0x07, 0xF7, 0xC7, 0x5F, 0x41, 0x21,
        0xCD, 0x3C, 0xA2, 0xB2, 0x3D, 0x6B, 0xCE, 0x43,
        0x82, 0xA6, 0xD3, 0x61, 0x21, 0x81, 0x50, 0x25,
        0xD5, 0x80, 0x6C, 0xBE, 0xF4, 0x52, 0xE0, 0x83,
        0x93, 0x3C, 0x6E, 0x5C, 0x73, 0x94, 0xAC, 0x88,
        0x26, 0x2A, 0x6D, 0xE7, 0x77, 0x0B, 0x2D, 0x88,
        0x43, 0xEC, 0x10, 0x1F, 0xFB, 0x5E, 0x84, 0xDE,
        0x2F, 0x7A, 0x8B, 0x74, 0xE7, 0x67, 0x4B, 0x3B,
        0x23, 0x19, 0xBD, 0x6B, 0xF4, 0x11, 0x2F, 0x92,
        0xC5, 0xCF, 0xC0, 0xA5, 0x5F, 0x7F, 0xA0, 0x61,
        0xF4, 0x53, 0x25, 0x40, 0x8D, 0x03, 0x9D, 0x51
    };
    static const byte sig_87[] = {
        0x4B, 0x3F, 0x52, 0xF0, 0x81, 0xB3, 0xD9, 0x14,
        0xBC, 0x7C, 0x6C, 0x07, 0x3B, 0x18, 0x2B, 0x26,
        0x8A, 0xDF, 0x51, 0x89, 0xE2, 0x98, 0xA8, 0x69,
        0xBF, 0xB9, 0x91, 0xB1, 0x99, 0x99, 0x3C, 0x10,
        0x42, 0xDE, 0xF5, 0xB5, 0x92, 0x70, 0xB6, 0xCD,
        0x3F, 0xF8, 0xF9, 0x07, 0xA1, 0xCB, 0x0D, 0x3B,
        0x6F, 0xED, 0xCA, 0x14, 0x38, 0x38, 0xF8, 0xF8,
        0x1E, 0x0C, 0x37, 0x0F, 0xFE, 0xEE, 0x6B, 0x25,
        0xCD, 0x07, 0x03, 0x56, 0x41, 0xA0, 0x51, 0x94,
        0x4E, 0xAB, 0x51, 0x6C, 0xFB, 0xB8, 0x01, 0x53,
        0x6B, 0x4F, 0x26, 0x2B, 0x16, 0x19, 0x8E, 0x7D,
        0xDB, 0x1D, 0x61, 0xC3, 0x5A, 0x64, 0xD9, 0x0D,
        0x39, 0x48, 0xCE, 0xAA, 0xC8, 0xEE, 0x58, 0x0D,
        0xCE, 0xF5, 0x40, 0xED, 0x99, 0xD9, 0x12, 0xBB,
        0xA2, 0xBC, 0x4F, 0x51, 0x45, 0xBB, 0x94, 0x9C,
        0x73, 0xCC, 0xBD, 0x58, 0x26, 0x13, 0xB1, 0x0E,
        0xAA, 0xE8, 0x63, 0xAC, 0xA3, 0x46, 0x83, 0xEB,
        0x92, 0x2B, 0x3D, 0xAD, 0xFC, 0x74, 0xF7, 0x6F,
        0x47, 0xE4, 0x97, 0x86, 0x02, 0x59, 0x24, 0x02,
        0xD9, 0x15, 0x43, 0x94, 0xEB, 0x09, 0xFB, 0xC2,
        0xEB, 0xCC, 0xC5, 0x94, 0x73, 0x2F, 0x2D, 0x8B,
        0xC3, 0x83, 0x50, 0xE5, 0x53, 0x5A, 0x44, 0x12,
        0xA7, 0x7A, 0xDD, 0x79, 0x16, 0x60, 0x45, 0x76,
        0xFD, 0x6A, 0x36, 0x31, 0xE5, 0x15, 0xBA, 0xF2,
        0x6A, 0x6F, 0x9C, 0xA4, 0x06, 0x1E, 0xBB, 0xDD,
        0x3B, 0xEC, 0x71, 0x79, 0xAD, 0x58, 0x55, 0x2A,
        0x5B, 0x50, 0x8F, 0x31, 0x34, 0x8A, 0x56, 0xAD,
        0x1A, 0xDA, 0x7A, 0x05, 0x35, 0x2C, 0x72, 0xC0,
        0x04, 0xB9, 0x4C, 0x47, 0xE7, 0x04, 0x9A, 0x10,
        0xB3, 0xA5, 0x9B, 0xF2, 0x38, 0xA8, 0xDF, 0xC6,
        0xC7, 0x01, 0x9A, 0x17, 0xF0, 0x5D, 0x5B, 0xFC,
        0xB9, 0xD9, 0x3D, 0x9D, 0x1C, 0xCB, 0xCB, 0x47,
        0xF8, 0xC4, 0x38, 0x09, 0x8F, 0xDB, 0xDF, 0xE2,
        0x3F, 0x9F, 0x78, 0xBC, 0x28, 0x06, 0x99, 0x08,
        0xC6, 0xB9, 0x89, 0x8B, 0x43, 0x4C, 0xBF, 0x37,
        0x78, 0x7E, 0x1A, 0xF6, 0xA6, 0xB8, 0x27, 0xE8,
        0x30, 0xE9, 0xF7, 0x62, 0x9C, 0xD8, 0xF5, 0x10,
        0x70, 0xC4, 0xC8, 0xA8, 0xDE, 0xB2, 0x60, 0xD0,
        0x7C, 0x3E, 0x41, 0xD8, 0x49, 0x04, 0x84, 0x87,
        0x74, 0x91, 0xB3, 0x9A, 0xA6, 0xD9, 0xE1, 0x0D,
        0x91, 0x74, 0x8B, 0x64, 0xE3, 0x31, 0x60, 0x62,
        0x9D, 0x8A, 0xE4, 0x3E, 0xFD, 0x5F, 0x85, 0x78,
        0x1E, 0x69, 0xF7, 0x6B, 0x68, 0x95, 0xC1, 0x41,
        0xEB, 0xCD, 0xDF, 0xEE, 0xB4, 0x85, 0xA0, 0x0B,
        0xDB, 0xA4, 0xF7, 0xC9, 0x91, 0xF5, 0x3F, 0x2F,
        0x84, 0x93, 0x39, 0x26, 0xAF, 0x39, 0xE6, 0x96,
        0x4A, 0xBF, 0x2D, 0xFE, 0xBB, 0xC1, 0x9A, 0x7E,
        0x31, 0xC5, 0x07, 0x97, 0xB8, 0xDA, 0x29, 0x31,
        0xE1, 0x0F, 0x3D, 0xAC, 0x49, 0x3F, 0x19, 0x8D,
        0xFD, 0x78, 0x5D, 0x21, 0xAD, 0xB2, 0xC0, 0x62,
        0xB0, 0x97, 0xE8, 0x89, 0xA2, 0x07, 0x37, 0xF1,
        0x86, 0x00, 0x8F, 0x29, 0x28, 0xF6, 0xB8, 0x4D,
        0x6E, 0x09, 0xE9, 0x75, 0xA8, 0xF2, 0xAA, 0xAD,
        0xC7, 0x85, 0x23, 0x42, 0x34, 0xFD, 0xA0, 0x37,
        0x03, 0xA7, 0xC2, 0x1F, 0x81, 0x2D, 0x65, 0x0B,
        0xD2, 0x51, 0x0B, 0x30, 0xF0, 0x55, 0x00, 0x81,
        0x04, 0x7A, 0x15, 0x5C, 0x84, 0x85, 0x86, 0xA9,
        0x6F, 0x10, 0x0D, 0x77, 0x4F, 0x3E, 0x39, 0xE0,
        0x29, 0xB0, 0x77, 0x7C, 0xD3, 0x3E, 0x68, 0x31,
        0x8A, 0x11, 0xC1, 0x98, 0x02, 0x93, 0xFA, 0xD3,
        0xE7, 0x87, 0xD2, 0x0D, 0xFE, 0x7E, 0xEE, 0x70,
        0x53, 0xC0, 0x5E, 0xEB, 0x6A, 0x15, 0x9B, 0xAA,
        0xD4, 0x02, 0x0B, 0x9E, 0xC3, 0xF5, 0x37, 0xDA,
        0x4D, 0xAD, 0xAF, 0xB3, 0xB1, 0xBB, 0x1D, 0xBE,
        0xB2, 0xD5, 0xB8, 0xF9, 0xD0, 0x5A, 0x01, 0x97,
        0x98, 0xEA, 0xE0, 0xED, 0x09, 0x9D, 0xB0, 0x66,
        0xD7, 0x3E, 0xE8, 0xE9, 0xA5, 0x6D, 0xE3, 0x68,
        0xE8, 0x78, 0xA7, 0xFF, 0x39, 0x14, 0x0D, 0x80,
        0x21, 0xD5, 0x00, 0x85, 0xE6, 0x25, 0x29, 0x41,
        0xAB, 0x31, 0x53, 0x09, 0xCB, 0x53, 0xAA, 0xA4,
        0x9E, 0x86, 0x34, 0x7F, 0xBA, 0xD5, 0x4A, 0x1F,
        0x87, 0x3E, 0x0C, 0xB4, 0xB8, 0x6A, 0x8D, 0x5B,
        0x1B, 0x2A, 0x95, 0xD4, 0x85, 0xF3, 0x7A, 0x9F,
        0xB6, 0x10, 0x5D, 0xF8, 0x44, 0x0F, 0xDB, 0x85,
        0x78, 0xF2, 0x62, 0x4C, 0x07, 0x93, 0x29, 0x56,
        0x9A, 0x75, 0xF3, 0x6F, 0x2C, 0x55, 0xD8, 0xD0,
        0x30, 0xFB, 0xFE, 0xAA, 0x88, 0x89, 0xAD, 0x74,
        0x6C, 0x32, 0x3B, 0x1A, 0xC4, 0xEC, 0x8C, 0x40,
        0x3E, 0x77, 0x5A, 0x6F, 0xBE, 0x59, 0x6E, 0x7E,
        0x6A, 0x5A, 0x28, 0x63, 0x57, 0x66, 0x25, 0x14,
        0x99, 0x40, 0x97, 0x6F, 0x7C, 0xC9, 0x36, 0x17,
        0xB4, 0x3F, 0xB1, 0x34, 0x89, 0x07, 0x4E, 0xCA,
        0xC5, 0xBE, 0xB1, 0xA4, 0xDF, 0xE5, 0x8B, 0x9A,
        0xD2, 0xE0, 0xC6, 0xA1, 0x5B, 0x76, 0xA7, 0xC2,
        0xD2, 0x08, 0x72, 0x5A, 0x31, 0x23, 0xCA, 0x4E,
        0x6F, 0x2C, 0x58, 0x47, 0xEE, 0x5F, 0xA8, 0x38,
        0x49, 0x19, 0xEF, 0x89, 0x01, 0x1D, 0x21, 0x9B,
        0x25, 0x7B, 0x3E, 0x4D, 0xC4, 0xF2, 0x09, 0x51,
        0x60, 0x84, 0x4C, 0xAE, 0xEA, 0xFC, 0xF8, 0x57,
        0x26, 0x0F, 0x1C, 0x63, 0xD3, 0xB0, 0x5A, 0x67,
        0xD3, 0xD0, 0xF2, 0xB0, 0xEC, 0x9D, 0xCC, 0x27,
        0x23, 0xF1, 0x37, 0x55, 0x75, 0x0B, 0xAE, 0x62,
        0xFC, 0xC3, 0x61, 0xCF, 0xB5, 0x84, 0xF7, 0x74,
        0xC0, 0x9A, 0xDF, 0x9A, 0x04, 0x31, 0xB2, 0x3E,
        0x48, 0x8C, 0x35, 0x9C, 0x0A, 0xEF, 0x5B, 0x1C,
        0x97, 0x87, 0xBD, 0x8F, 0x52, 0xB0, 0x83, 0xBC,
        0x9D, 0xBC, 0xC9, 0xB3, 0x03, 0x9F, 0x77, 0x7C,
        0x7E, 0x8E, 0xAB, 0xC8, 0x00, 0x78, 0x05, 0x0C,
        0xE6, 0xD4, 0x9C, 0x3B, 0xB7, 0x01, 0x68, 0xFA,
        0x21, 0x77, 0x29, 0x8F, 0xB0, 0xA8, 0xF7, 0x2C,
        0x1C, 0xD2, 0x8D, 0x66, 0x2A, 0x07, 0xDA, 0xE6,
        0xC7, 0xAC, 0xB7, 0xFB, 0x8E, 0x7F, 0xDD, 0x01,
        0xDF, 0xB2, 0x7C, 0x62, 0xEE, 0x68, 0x3F, 0x4E,
        0x5F, 0x88, 0xC7, 0xC1, 0xDD, 0xDD, 0x5E, 0xEC,
        0xC1, 0xC3, 0xAF, 0x85, 0x3F, 0x1F, 0xF6, 0xB1,
        0xD9, 0xDE, 0x67, 0x2F, 0x1B, 0xF6, 0x47, 0x3A,
        0xF0, 0x02, 0x1D, 0x8A, 0x3D, 0x4D, 0xD0, 0x4A,
        0x2F, 0xCA, 0x23, 0x25, 0xC7, 0x21, 0xCF, 0x1C,
        0x82, 0x16, 0x76, 0xD0, 0xA0, 0xD5, 0x74, 0x18,
        0x66, 0x25, 0xDE, 0x83, 0x1C, 0x84, 0x11, 0xF6,
        0x41, 0x79, 0xF9, 0x16, 0x7F, 0x78, 0xBC, 0xB2,
        0x2F, 0xB4, 0x1C, 0x2C, 0xDB, 0x63, 0xC4, 0xDB,
        0x5E, 0x13, 0x87, 0x66, 0xD3, 0x80, 0x35, 0x89,
        0x59, 0x8F, 0x11, 0x4F, 0x41, 0xBA, 0x42, 0xCD,
        0xB1, 0x34, 0x10, 0x20, 0x44, 0x9B, 0xA9, 0x96,
        0x56, 0x11, 0x39, 0x90, 0xB4, 0xE0, 0x22, 0xD8,
        0xDA, 0x20, 0xD7, 0x44, 0x49, 0x1C, 0x6E, 0xEA,
        0xB6, 0x7B, 0x91, 0x8E, 0x80, 0xFF, 0xF3, 0x43,
        0xCC, 0x5B, 0x4C, 0x8E, 0x58, 0xC3, 0x48, 0x4B,
        0x01, 0x25, 0xA6, 0x0C, 0x36, 0xAE, 0xF7, 0x63,
        0x89, 0x4D, 0x35, 0x14, 0x8B, 0x57, 0x8F, 0x41,
        0x7C, 0x3A, 0x98, 0xA1, 0x43, 0xED, 0xFE, 0x9F,
        0x8C, 0x95, 0xBC, 0xC3, 0x46, 0xC6, 0xF5, 0xEA,
        0xF9, 0x7A, 0xAD, 0x11, 0xDA, 0xE0, 0x1C, 0x47,
        0x7C, 0x22, 0x7A, 0x88, 0xD1, 0x0E, 0xCF, 0xDC,
        0xF4, 0x50, 0xB3, 0x7F, 0x88, 0x19, 0x68, 0x02,
        0x78, 0x49, 0xD9, 0xB4, 0x3E, 0x2B, 0xFF, 0x90,
        0xC6, 0xA3, 0x4A, 0xE4, 0x1B, 0x8B, 0xBD, 0x74,
        0x30, 0x83, 0xD3, 0xC5, 0x87, 0x86, 0xB0, 0x36,
        0x67, 0x1C, 0xD6, 0xEE, 0xD9, 0x4D, 0xAE, 0x51,
        0xF7, 0x61, 0x32, 0x47, 0xEF, 0x86, 0x07, 0xAC,
        0xF7, 0x4A, 0x3C, 0xCE, 0x93, 0x2F, 0x1C, 0x38,
        0x69, 0xBD, 0xB3, 0x5C, 0xA1, 0x7F, 0xC6, 0xBA,
        0x9F, 0x9C, 0x95, 0x6F, 0xF1, 0xD4, 0xD8, 0x80,
        0x94, 0x32, 0x5C, 0xAB, 0xCE, 0x41, 0x23, 0x3F,
        0xB1, 0xD8, 0x08, 0xEF, 0x41, 0x01, 0x03, 0x96,
        0xDE, 0xB0, 0xEC, 0xF5, 0x07, 0x34, 0xD8, 0x18,
        0xDD, 0xAB, 0x70, 0x01, 0x5A, 0x0A, 0xBD, 0xD1,
        0x92, 0x6D, 0xFA, 0x49, 0x1F, 0x71, 0x1A, 0xA8,
        0x5D, 0xA2, 0xA8, 0xEC, 0x60, 0xE3, 0x25, 0x5C,
        0xCF, 0x97, 0x5C, 0x23, 0xCC, 0x4E, 0x8D, 0xAF,
        0xDD, 0xED, 0x9F, 0xEC, 0x60, 0xA6, 0x46, 0x7C,
        0x45, 0xB0, 0x3C, 0xA4, 0x76, 0x49, 0x9A, 0xA3,
        0x31, 0xB0, 0xE3, 0x99, 0x95, 0x76, 0xCE, 0xC3,
        0x19, 0x1A, 0x9A, 0x62, 0xBC, 0x1B, 0xEA, 0xC1,
        0xEA, 0xF2, 0x0E, 0x18, 0xCF, 0xC3, 0x21, 0x61,
        0x27, 0xDE, 0x4A, 0xAE, 0x2E, 0x75, 0x20, 0x1F,
        0x9E, 0x42, 0x7E, 0x39, 0xBF, 0x92, 0x11, 0x50,
        0xEA, 0xB9, 0x49, 0x55, 0x9C, 0x02, 0x2D, 0x87,
        0x6F, 0xA2, 0x42, 0xC2, 0xA8, 0x45, 0xBC, 0xA7,
        0x23, 0x5F, 0x72, 0x1B, 0x00, 0x56, 0x78, 0x8A,
        0x44, 0xEC, 0xC3, 0xEB, 0x98, 0xF0, 0xF5, 0x02,
        0xB8, 0x9F, 0x8E, 0x74, 0x10, 0xEA, 0x56, 0x79,
        0xAE, 0x7C, 0x04, 0x34, 0xF1, 0x3A, 0xD8, 0x16,
        0x42, 0x1D, 0x2F, 0xEE, 0x30, 0xCB, 0xCB, 0x2D,
        0xAA, 0x6B, 0x85, 0x1C, 0xD1, 0xB6, 0xE9, 0x96,
        0xDA, 0x7A, 0x75, 0x7E, 0x4C, 0x4D, 0x85, 0x72,
        0xC8, 0xB6, 0x00, 0xDE, 0x85, 0xDD, 0xB6, 0x53,
        0x20, 0xD1, 0xCB, 0x71, 0xD9, 0x37, 0x83, 0x49,
        0xC0, 0xC4, 0x01, 0xAD, 0x4F, 0x9E, 0x91, 0x27,
        0x21, 0x39, 0x22, 0x8A, 0x8D, 0xA2, 0xF4, 0xFD,
        0x2F, 0x48, 0x89, 0x1A, 0x4D, 0xCB, 0x06, 0x6D,
        0x50, 0x1D, 0x44, 0x74, 0x83, 0xB6, 0x11, 0xBB,
        0x3C, 0x80, 0x55, 0x0A, 0x90, 0xEA, 0x0B, 0x73,
        0x2D, 0x63, 0x9D, 0x8B, 0x39, 0x26, 0xB6, 0xE7,
        0xC3, 0x54, 0x53, 0xED, 0x3C, 0xC1, 0x10, 0xBA,
        0xF5, 0x56, 0xCF, 0x46, 0xD8, 0xFC, 0x21, 0x77,
        0xE7, 0x6F, 0xB2, 0x66, 0x3B, 0x8B, 0xDD, 0x17,
        0x1E, 0x94, 0xC0, 0xAC, 0xAF, 0x25, 0xB9, 0x15,
        0x3B, 0x22, 0xBC, 0xA7, 0x49, 0x91, 0x67, 0x56,
        0xFB, 0x3E, 0xD3, 0x01, 0x8E, 0x09, 0x44, 0xB6,
        0xC3, 0xB9, 0xB6, 0xBF, 0xA1, 0x5B, 0x9B, 0xE8,
        0x03, 0xAC, 0x79, 0x33, 0x3C, 0xD2, 0xC3, 0xA2,
        0x7A, 0x26, 0xBC, 0x17, 0xCD, 0xA2, 0x57, 0x79,
        0x8A, 0xE1, 0x6B, 0x28, 0xB4, 0x63, 0xB6, 0xDF,
        0x3F, 0xA8, 0x7C, 0x2D, 0x74, 0x2D, 0x0F, 0x68,
        0x85, 0xBE, 0xE0, 0xBE, 0xC6, 0xE2, 0x0D, 0x01,
        0xE5, 0xDA, 0xDC, 0x86, 0x82, 0x3E, 0x92, 0xD6,
        0x0F, 0xEC, 0x79, 0xB0, 0xD2, 0x40, 0x24, 0x87,
        0x53, 0xE4, 0x20, 0x48, 0x38, 0x4C, 0x80, 0x42,
        0x89, 0x60, 0x48, 0x21, 0xA5, 0x7F, 0x4F, 0x9F,
        0x50, 0xAE, 0x0C, 0x38, 0x52, 0x7F, 0xE5, 0xA3,
        0x49, 0x38, 0xDD, 0xBC, 0xDC, 0xD9, 0xA1, 0xD0,
        0x20, 0x83, 0x9B, 0xEB, 0xB6, 0x2F, 0x9F, 0x41,
        0xFB, 0xA0, 0x80, 0x52, 0xAB, 0xB8, 0x2F, 0xAD,
        0xA8, 0x84, 0xCB, 0xE5, 0x63, 0x79, 0x11, 0x03,
        0xAA, 0x58, 0x55, 0x46, 0xEB, 0xFE, 0xB1, 0x12,
        0x72, 0xCC, 0x2E, 0x87, 0xA3, 0xB7, 0x5B, 0x3C,
        0x6B, 0xB1, 0x85, 0x3A, 0xE7, 0xF9, 0xCF, 0x55,
        0x85, 0xB2, 0x65, 0x3C, 0xF5, 0xEE, 0xA2, 0x44,
        0xD2, 0x04, 0xEB, 0x26, 0x9C, 0x56, 0xA2, 0x09,
        0x85, 0x16, 0x06, 0x59, 0xCB, 0x07, 0x25, 0xEE,
        0x13, 0xCE, 0x35, 0xD5, 0x5E, 0xB0, 0x95, 0xA5,
        0x34, 0x14, 0xF2, 0x32, 0xDF, 0x81, 0x08, 0xB1,
        0x80, 0x24, 0xEB, 0x0D, 0xBF, 0x34, 0x5E, 0xB5,
        0xCD, 0xAD, 0x0B, 0xCE, 0x72, 0x63, 0x50, 0x9A,
        0x34, 0x1D, 0x54, 0xA7, 0xD5, 0x34, 0xE5, 0x53,
        0xEA, 0xEF, 0xFE, 0x4E, 0x24, 0x2E, 0xA2, 0x3B,
        0xCF, 0xE5, 0x9A, 0x58, 0xA6, 0x04, 0x25, 0x88,
        0x2C, 0xB7, 0xE3, 0xB0, 0xC9, 0xE4, 0xAF, 0xE8,
        0x69, 0x8E, 0x3D, 0xF5, 0x6A, 0xFD, 0x6D, 0x61,
        0x1E, 0x91, 0x68, 0x74, 0x7D, 0x87, 0x35, 0xCF,
        0x92, 0x46, 0xD9, 0x4F, 0x21, 0x26, 0xBE, 0x72,
        0x7F, 0xB4, 0x2B, 0x22, 0x41, 0xA8, 0x3B, 0x34,
        0xF0, 0xB9, 0xEB, 0x47, 0x93, 0x8D, 0x72, 0x65,
        0x02, 0xC5, 0x4E, 0x45, 0x72, 0x76, 0x63, 0x31,
        0x62, 0x8F, 0xA5, 0xCD, 0xA8, 0x93, 0xC3, 0x53,
        0x76, 0xAB, 0x45, 0x38, 0xFF, 0x87, 0x17, 0xC2,
        0x79, 0x5B, 0x0F, 0x51, 0xF0, 0x8E, 0x11, 0x37,
        0x61, 0x2B, 0x89, 0xB0, 0xC1, 0xE2, 0xCD, 0x1F,
        0x09, 0x9E, 0x88, 0x55, 0x69, 0x23, 0xAE, 0x57,
        0xA1, 0xDA, 0xD2, 0xAF, 0xB1, 0x23, 0x0B, 0x50,
        0x94, 0xA1, 0xB2, 0x1B, 0xAD, 0x7D, 0xBB, 0xC3,
        0x33, 0xA9, 0x7F, 0x17, 0x93, 0x04, 0x71, 0x8F,
        0x32, 0x89, 0xB6, 0xDE, 0x31, 0x31, 0x5B, 0x74,
        0xC1, 0xA7, 0x3A, 0xC7, 0x75, 0x6F, 0xAA, 0x4D,
        0x7E, 0xB5, 0x68, 0xBB, 0xC6, 0xF7, 0xE7, 0x88,
        0xCD, 0x08, 0x9B, 0x39, 0x55, 0x64, 0xD2, 0x17,
        0x6B, 0x00, 0x56, 0xDF, 0xFE, 0x95, 0x2C, 0x77,
        0x48, 0xB0, 0x48, 0x30, 0x67, 0x20, 0xF6, 0x02,
        0xB6, 0x7E, 0x8F, 0x6A, 0xDC, 0xC9, 0x1F, 0x8E,
        0x3A, 0xA4, 0xB8, 0xC4, 0xD7, 0xFA, 0xC2, 0x33,
        0xAA, 0xF9, 0x36, 0x53, 0xAD, 0x22, 0x09, 0xE2,
        0xFF, 0x92, 0xDA, 0x30, 0xC2, 0xD5, 0x3F, 0xDE,
        0xF6, 0xF4, 0xC9, 0x0E, 0xAA, 0x0D, 0xE6, 0x0D,
        0x59, 0x4A, 0xDA, 0x39, 0x15, 0xDB, 0x24, 0x27,
        0x9D, 0x86, 0x74, 0x76, 0xEA, 0xD7, 0x57, 0xB4,
        0xC0, 0x26, 0x4A, 0x1D, 0xB8, 0xA1, 0xF5, 0x7A,
        0x1B, 0x5D, 0x71, 0x73, 0xBB, 0x1A, 0x96, 0x0C,
        0xE0, 0x2F, 0xDE, 0xFE, 0xF1, 0x60, 0xD5, 0x12,
        0x66, 0x7D, 0x65, 0x52, 0x68, 0xFC, 0xC3, 0xA1,
        0x53, 0xA4, 0x31, 0x47, 0x82, 0xA0, 0xEB, 0xFF,
        0x84, 0xF6, 0x5F, 0x14, 0xA0, 0xE3, 0xE1, 0x2A,
        0x13, 0x25, 0x0C, 0x07, 0xD0, 0x8C, 0x22, 0x5B,
        0x11, 0xA6, 0x83, 0x1B, 0xC2, 0x5C, 0x40, 0x46,
        0x7B, 0x76, 0x80, 0x04, 0xDD, 0xE0, 0xE8, 0x74,
        0xA5, 0x11, 0x44, 0xC1, 0x89, 0x20, 0xBD, 0xF2,
        0x86, 0x09, 0x0B, 0x59, 0xF5, 0x15, 0x64, 0xEA,
        0x40, 0x70, 0xFB, 0xBF, 0x61, 0xE3, 0x69, 0x64,
        0x35, 0xF2, 0x8F, 0x63, 0x33, 0x2B, 0x64, 0x49,
        0x6D, 0xF3, 0xEC, 0x8B, 0x65, 0xD5, 0x4E, 0x1C,
        0xF4, 0x78, 0x9D, 0xDA, 0xB1, 0x22, 0xDA, 0x6B,
        0x26, 0x4D, 0x31, 0x2A, 0x71, 0x1C, 0x12, 0x9E,
        0x3B, 0x07, 0xF4, 0xC6, 0xDA, 0x25, 0xA5, 0x61,
        0x73, 0xAF, 0x58, 0xB9, 0x0A, 0x71, 0xB7, 0xAC,
        0xFA, 0x31, 0x61, 0xA8, 0x1F, 0x59, 0xD1, 0x79,
        0x14, 0xC9, 0x9B, 0xBA, 0xC4, 0xF9, 0xA3, 0x14,
        0x97, 0x7A, 0x89, 0xCE, 0xF7, 0x69, 0x69, 0x43,
        0x60, 0x9B, 0xB4, 0x82, 0x79, 0x64, 0xFB, 0x29,
        0x76, 0x40, 0x3B, 0xD4, 0x99, 0x6F, 0x1E, 0x84,
        0x2B, 0xF5, 0xAA, 0xAE, 0x1E, 0xCC, 0xA1, 0x12,
        0x55, 0xB9, 0xE6, 0x00, 0x1C, 0x20, 0xF7, 0x2F,
        0x1F, 0xD5, 0xE3, 0x2C, 0xDA, 0x32, 0xD8, 0xA7,
        0xAC, 0x5F, 0x62, 0xB0, 0x9A, 0x0E, 0x61, 0x58,
        0x47, 0xCA, 0x74, 0x6F, 0x48, 0x95, 0x15, 0xCF,
        0x8F, 0x18, 0x31, 0x62, 0x85, 0x9F, 0x53, 0xB9,
        0x7E, 0x9E, 0x5C, 0xA8, 0x00, 0xEE, 0x62, 0x4F,
        0x72, 0x98, 0x43, 0xA0, 0x00, 0x91, 0x64, 0xA4,
        0xA9, 0xFF, 0x76, 0xEB, 0x34, 0xE4, 0x70, 0x41,
        0x84, 0x84, 0x8A, 0x13, 0x9A, 0xD9, 0x7D, 0x90,
        0x9F, 0x7A, 0x7E, 0xD1, 0x14, 0xF0, 0x87, 0xA4,
        0xB2, 0xE1, 0xB4, 0xA3, 0x03, 0x23, 0x91, 0x16,
        0x0B, 0x6F, 0x3A, 0x36, 0x49, 0xFF, 0x15, 0xAE,
        0xA2, 0xB7, 0x10, 0x7A, 0xF8, 0xA3, 0xB5, 0xFC,
        0xAD, 0x61, 0xD4, 0x3D, 0x60, 0x2E, 0x62, 0x86,
        0xA9, 0x00, 0x87, 0x0C, 0xC8, 0xCE, 0x24, 0xE3,
        0x9E, 0x78, 0xF0, 0x39, 0x7A, 0x0D, 0x7E, 0x27,
        0xE8, 0xE2, 0xD4, 0x77, 0x6A, 0x44, 0xCB, 0xA2,
        0x18, 0xEB, 0xCD, 0x88, 0xB3, 0xC2, 0x8C, 0x18,
        0x2A, 0x7C, 0x9F, 0x4D, 0xBB, 0x2D, 0xBB, 0x5E,
        0x98, 0x15, 0x63, 0xD6, 0x6C, 0xEE, 0xB7, 0x7E,
        0x7F, 0x90, 0x34, 0xBD, 0x42, 0x9D, 0x27, 0x63,
        0x7C, 0xF7, 0x97, 0xDE, 0x82, 0xE0, 0x1F, 0xEB,
        0xBC, 0xE2, 0x17, 0x1E, 0xFD, 0x01, 0x6E, 0x40,
        0x2A, 0x42, 0xD7, 0x8E, 0xA1, 0xAC, 0xE2, 0xCB,
        0x37, 0x0E, 0x75, 0xC9, 0x0A, 0xDF, 0xA1, 0xA7,
        0x93, 0xB2, 0x16, 0x9C, 0xC2, 0x65, 0x22, 0xDB,
        0x2F, 0x54, 0x6A, 0xC1, 0xDE, 0x34, 0xC9, 0x08,
        0x71, 0x20, 0xC4, 0x2A, 0x9F, 0x10, 0xC0, 0x0D,
        0x49, 0x3C, 0x25, 0x73, 0x01, 0x66, 0xF9, 0xD2,
        0x19, 0xFB, 0xDA, 0xD2, 0x22, 0xC8, 0xB2, 0x81,
        0x15, 0x54, 0x33, 0x13, 0x21, 0x08, 0x48, 0xFB,
        0x2F, 0x04, 0xBF, 0xDC, 0xE1, 0x5D, 0x32, 0x0C,
        0x36, 0x34, 0xA8, 0xE4, 0xD6, 0x37, 0x55, 0x51,
        0x59, 0x00, 0xC7, 0x5B, 0xFD, 0x09, 0x0A, 0xD7,
        0x8D, 0xD5, 0x88, 0x65, 0x9F, 0xBF, 0x97, 0xC9,
        0x6E, 0x0D, 0x0A, 0xCC, 0x8E, 0x81, 0x5E, 0x60,
        0x8F, 0x9E, 0x86, 0x1D, 0x79, 0xAF, 0x30, 0x51,
        0xB9, 0x42, 0xB5, 0x25, 0x70, 0xB6, 0x29, 0x2B,
        0xF4, 0x8C, 0x2B, 0xFA, 0xA9, 0x07, 0x7D, 0xC7,
        0x6F, 0xE9, 0x02, 0x68, 0x32, 0x17, 0xB8, 0xBF,
        0x80, 0x9E, 0xD7, 0xA0, 0x05, 0x0A, 0xDD, 0xBB,
        0x65, 0xFD, 0xDF, 0xBD, 0x24, 0x01, 0x9C, 0x91,
        0x81, 0xB5, 0xAC, 0x81, 0x56, 0x61, 0x13, 0xD6,
        0x69, 0x4E, 0xA6, 0x29, 0x1D, 0x7F, 0x4A, 0x7F,
        0x56, 0xA4, 0x1E, 0xB9, 0x1F, 0x76, 0x36, 0x8D,
        0xF8, 0x2B, 0x16, 0x4B, 0x48, 0x59, 0x25, 0x9D,
        0x71, 0x89, 0x24, 0x0F, 0x1D, 0x88, 0x03, 0xF8,
        0x10, 0x72, 0x96, 0xD3, 0x78, 0xBA, 0xB4, 0xD2,
        0x4F, 0xE6, 0xD1, 0x0E, 0xF7, 0x88, 0x36, 0x7B,
        0xCE, 0x16, 0xC5, 0xAB, 0x77, 0xFB, 0xC1, 0x68,
        0xB8, 0x57, 0xF7, 0xBA, 0x5C, 0xDC, 0xBE, 0x50,
        0x67, 0xC8, 0x64, 0xF8, 0x79, 0x80, 0x9F, 0xE5,
        0x21, 0x7D, 0xEF, 0x02, 0x94, 0xBF, 0xAF, 0xDF,
        0x80, 0x9A, 0xBC, 0xE9, 0x53, 0x2D, 0xD9, 0xDA,
        0xB3, 0x44, 0x8F, 0x4D, 0xA6, 0x8E, 0xCA, 0x51,
        0x60, 0x94, 0x76, 0x27, 0x8E, 0xB8, 0xC4, 0xF6,
        0x9E, 0xA2, 0x96, 0x73, 0xF6, 0x94, 0x18, 0x04,
        0x1D, 0x26, 0x85, 0x7E, 0xBC, 0x24, 0xA4, 0x87,
        0xBB, 0x4B, 0x0B, 0xA6, 0x3A, 0xF8, 0x48, 0x54,
        0x5E, 0xE9, 0xBE, 0x89, 0xF1, 0x39, 0xD5, 0x02,
        0x09, 0x9B, 0x9D, 0x35, 0xDB, 0x38, 0x07, 0xB9,
        0x25, 0xCB, 0xA5, 0x76, 0xE2, 0x71, 0x70, 0xEA,
        0xEC, 0x48, 0xCC, 0x2C, 0xC1, 0x5B, 0x04, 0x36,
        0x77, 0x82, 0x5D, 0x0E, 0xE8, 0x1E, 0xB2, 0xCE,
        0xE3, 0xA8, 0xED, 0x14, 0xA7, 0x98, 0xB8, 0x79,
        0x53, 0x02, 0x20, 0xE5, 0x0C, 0xE8, 0xC0, 0x03,
        0xA3, 0x05, 0x38, 0x2A, 0x24, 0xD2, 0x3C, 0x27,
        0x7B, 0x99, 0xD1, 0xF4, 0xC5, 0x4F, 0x9A, 0x8D,
        0x33, 0xFA, 0x3D, 0x1E, 0x33, 0x7E, 0x18, 0xD7,
        0xCB, 0xBA, 0x5E, 0x5A, 0x47, 0xF2, 0xD5, 0xE0,
        0x96, 0xCF, 0x45, 0x51, 0xB2, 0x3B, 0x1B, 0x86,
        0x43, 0x6E, 0x81, 0xB4, 0xA0, 0x9D, 0x1E, 0x3D,
        0x38, 0x49, 0x2E, 0xC8, 0xB2, 0xA0, 0x09, 0x67,
        0x01, 0x6A, 0xB7, 0x6B, 0x9A, 0x9B, 0x18, 0x64,
        0x67, 0x14, 0x21, 0xDA, 0x56, 0xF5, 0x7D, 0x00,
        0x8D, 0x5C, 0xE1, 0xB8, 0x92, 0xA7, 0xE9, 0xC1,
        0xF6, 0x9F, 0x6C, 0x72, 0x2C, 0xF1, 0x09, 0xDB,
        0x50, 0x0E, 0x53, 0xF6, 0xBC, 0x07, 0x83, 0x7A,
        0xD1, 0xCD, 0x4C, 0xF4, 0xA6, 0x4D, 0xA7, 0x63,
        0xB4, 0xA9, 0xC4, 0x92, 0x9B, 0x0D, 0xCD, 0xDF,
        0x7C, 0x7E, 0x11, 0x86, 0xBE, 0x3F, 0xF0, 0xC3,
        0x21, 0x15, 0x84, 0x37, 0x82, 0x0C, 0x81, 0xE7,
        0x4F, 0xF3, 0x16, 0xAE, 0x32, 0x54, 0xE9, 0x72,
        0xFC, 0x19, 0x7A, 0x7F, 0x0E, 0x62, 0x02, 0x42,
        0xAC, 0x05, 0xA4, 0xE4, 0x3E, 0x98, 0x7C, 0x2A,
        0x83, 0x55, 0xB0, 0x35, 0x77, 0x45, 0xCA, 0x79,
        0xE6, 0xAE, 0x48, 0xAB, 0x29, 0xED, 0x4F, 0xA6,
        0x3D, 0x3A, 0x1F, 0x19, 0xB9, 0x99, 0xDE, 0x25,
        0x1F, 0xDE, 0x06, 0x40, 0xDD, 0x87, 0x87, 0x6D,
        0x55, 0x76, 0x28, 0x78, 0xAD, 0x1D, 0xB1, 0x2D,
        0x65, 0xBA, 0xFD, 0x14, 0xB6, 0xA9, 0xA7, 0x08,
        0x1B, 0xF2, 0x3F, 0x9F, 0x06, 0xD9, 0x0C, 0xE2,
        0x73, 0xC5, 0xA2, 0x6E, 0x01, 0x2C, 0xA9, 0x4D,
        0xD4, 0x81, 0xD3, 0x2E, 0x10, 0x93, 0x8C, 0x16,
        0x51, 0x63, 0xE8, 0x9B, 0xE8, 0xA9, 0x3A, 0x63,
        0x03, 0x4D, 0x34, 0x5B, 0x74, 0xE2, 0xA9, 0x4E,
        0xF6, 0x43, 0xD0, 0x6A, 0xF9, 0xE1, 0xF5, 0xC9,
        0xF1, 0x04, 0x93, 0x0D, 0xA0, 0x0E, 0x61, 0xE0,
        0x61, 0xEE, 0x8C, 0x3B, 0xB1, 0x7C, 0x11, 0xE0,
        0x5D, 0x45, 0xC1, 0x68, 0x2E, 0x4D, 0x59, 0x3C,
        0x91, 0x98, 0x23, 0x8D, 0x2B, 0xA2, 0x89, 0x77,
        0x9E, 0x7D, 0x0F, 0x22, 0x7B, 0xCB, 0x0B, 0x09,
        0x97, 0x2B, 0x19, 0x77, 0x0F, 0xF0, 0x11, 0xBF,
        0x6C, 0x60, 0xD9, 0xD1, 0x93, 0xCF, 0xAB, 0x32,
        0x74, 0x7A, 0x00, 0x95, 0xE1, 0xA4, 0xAD, 0x32,
        0x51, 0x4C, 0x78, 0x2E, 0xF3, 0xDE, 0x7A, 0x26,
        0xEA, 0x77, 0x1F, 0x55, 0x30, 0xD9, 0xDE, 0x97,
        0x36, 0xD0, 0xF6, 0xAE, 0x1A, 0xFB, 0x78, 0xEC,
        0x7C, 0xE4, 0x88, 0x4A, 0x1B, 0xB4, 0x36, 0xCF,
        0xCE, 0x45, 0x9C, 0xD9, 0x93, 0x58, 0x26, 0x09,
        0x06, 0xAA, 0xC9, 0x97, 0x16, 0xA5, 0x36, 0xCC,
        0x76, 0x87, 0xA0, 0x37, 0x5F, 0xDA, 0x11, 0x00,
        0x76, 0x18, 0xE5, 0x53, 0x53, 0x4E, 0x54, 0xD5,
        0xB2, 0x14, 0xF7, 0xAA, 0x6F, 0xC7, 0xDB, 0xE3,
        0x7C, 0x2B, 0xD2, 0xB6, 0x48, 0x50, 0xAE, 0x46,
        0x9A, 0x98, 0x58, 0x98, 0x7F, 0x3F, 0xA4, 0xB1,
        0xFD, 0x26, 0xD9, 0x54, 0xBF, 0xEC, 0x36, 0x5D,
        0xBE, 0x06, 0xDD, 0xCD, 0x61, 0x5E, 0x1F, 0xED,
        0x58, 0xA8, 0x86, 0x76, 0x40, 0x2D, 0x1D, 0x6B,
        0x58, 0x14, 0x85, 0x49, 0x8B, 0x5A, 0xDF, 0xFF,
        0xC4, 0x2D, 0x47, 0xD6, 0x1D, 0xF9, 0x93, 0x84,
        0xE2, 0x2C, 0x51, 0x57, 0xF0, 0x17, 0x8A, 0x6F,
        0xDA, 0xF8, 0xF4, 0xA9, 0x49, 0x1D, 0xAF, 0x29,
        0x8B, 0x2C, 0x3E, 0xC8, 0x80, 0x85, 0x02, 0x2C,
        0x0A, 0x7C, 0xF2, 0x45, 0xED, 0x0F, 0xB5, 0xA3,
        0x8C, 0xD1, 0x6F, 0x30, 0xD3, 0x7D, 0xA5, 0xC4,
        0x95, 0x9A, 0x55, 0x50, 0x1D, 0xAD, 0x50, 0xF1,
        0xB4, 0x8B, 0xBB, 0xDD, 0x86, 0xAB, 0x8B, 0xB5,
        0x22, 0xA9, 0x36, 0xDD, 0xF0, 0x00, 0x3B, 0x81,
        0xBE, 0x16, 0x23, 0x1A, 0x04, 0xE7, 0xA5, 0x89,
        0xC5, 0x6F, 0xFF, 0xB5, 0x1B, 0x07, 0x92, 0x7B,
        0x4A, 0xFA, 0x1D, 0xB7, 0xD4, 0x8B, 0xC6, 0xFB,
        0xC3, 0xF3, 0x67, 0x56, 0x37, 0x18, 0x4B, 0x7A,
        0xDB, 0x9B, 0xAD, 0xF4, 0xDE, 0x7C, 0x08, 0x5B,
        0xCA, 0x1D, 0x42, 0x8D, 0xC9, 0xFC, 0x82, 0x77,
        0xCB, 0xD8, 0x58, 0x84, 0xA5, 0x92, 0x1B, 0x52,
        0xBB, 0x05, 0xB7, 0x10, 0x61, 0x55, 0x08, 0x26,
        0x1B, 0xB4, 0x54, 0x6B, 0xD6, 0xE1, 0xFC, 0x73,
        0x0D, 0x16, 0xB0, 0x49, 0xEA, 0x12, 0x79, 0x8C,
        0xE2, 0xE6, 0xDF, 0x43, 0xF5, 0xB8, 0xF3, 0xEF,
        0x9A, 0xC8, 0xFB, 0xAE, 0x31, 0xB0, 0x11, 0xE1,
        0x0C, 0x4F, 0xC6, 0x2F, 0xFD, 0x7F, 0x39, 0xD1,
        0x6E, 0xC3, 0x2C, 0xA8, 0x21, 0x0E, 0xD1, 0x6E,
        0x04, 0x1D, 0xA4, 0x3D, 0x92, 0x74, 0x22, 0x95,
        0x14, 0x05, 0x4A, 0x0F, 0x82, 0xD4, 0x62, 0xFE,
        0x08, 0x0C, 0x6F, 0xFD, 0x7B, 0xBD, 0xBF, 0xBF,
        0x0B, 0xFF, 0xC6, 0xD5, 0xEC, 0xC4, 0x32, 0xA3,
        0x25, 0x6C, 0x0B, 0xE0, 0xDD, 0xFD, 0x5D, 0x90,
        0x80, 0xC6, 0x76, 0xC7, 0x95, 0x5D, 0x66, 0xE4,
        0x4D, 0x1C, 0xE5, 0x1F, 0xCC, 0x23, 0x82, 0xF8,
        0x68, 0xD7, 0x32, 0xE8, 0x58, 0x51, 0x72, 0x1B,
        0x48, 0xA0, 0x1D, 0x08, 0xC6, 0x39, 0x62, 0x6E,
        0xE0, 0x50, 0x9C, 0xB5, 0x81, 0xEF, 0xF5, 0x62,
        0x8F, 0xA6, 0xCC, 0xD1, 0x08, 0x9A, 0xC0, 0xE1,
        0x2D, 0xEB, 0xE0, 0x85, 0x17, 0x82, 0xE6, 0x4C,
        0x50, 0x49, 0xCB, 0xD6, 0x50, 0x10, 0x13, 0x96,
        0x5C, 0xC0, 0xCA, 0x25, 0xAC, 0xAB, 0x17, 0x6E,
        0xF7, 0xCA, 0xB9, 0x29, 0x40, 0x98, 0x5D, 0xDB,
        0x49, 0x02, 0x1D, 0xF6, 0xC6, 0x0D, 0x6C, 0x4A,
        0x48, 0x91, 0x16, 0x31, 0x1E, 0x86, 0xBA, 0x19,
        0xED, 0xF0, 0x0D, 0x74, 0x79, 0x73, 0x58, 0x20,
        0x7C, 0xDE, 0x50, 0x50, 0x6D, 0x00, 0x7F, 0xE0,
        0x3C, 0x88, 0x04, 0xC6, 0x64, 0x51, 0xF0, 0x2A,
        0x01, 0x82, 0xD3, 0x87, 0xB7, 0x59, 0x89, 0x40,
        0x96, 0xF6, 0x52, 0x32, 0x95, 0x2D, 0x18, 0x3D,
        0xBA, 0xAA, 0xBB, 0x6B, 0xC0, 0xE1, 0x91, 0xDC,
        0x2C, 0x3F, 0x75, 0xFC, 0x72, 0xBD, 0x61, 0xBA,
        0xB2, 0xEF, 0x19, 0xB6, 0x53, 0x2B, 0x23, 0x1C,
        0x4A, 0xFB, 0x1A, 0x9C, 0x2C, 0xB2, 0xF3, 0xD6,
        0xC4, 0x51, 0xE8, 0x44, 0x0D, 0x6A, 0x92, 0x3C,
        0xF7, 0x2A, 0x63, 0xE2, 0xED, 0x85, 0x54, 0x77,
        0x38, 0x87, 0x91, 0x0C, 0xA5, 0xC6, 0x71, 0xAD,
        0x4F, 0xD5, 0x92, 0x3C, 0xB9, 0x5E, 0xC7, 0x3F,
        0xFD, 0xFB, 0xDA, 0x4B, 0x66, 0x55, 0xF5, 0x5D,
        0xBF, 0xD1, 0x31, 0x7D, 0x02, 0x44, 0x22, 0x30,
        0x1E, 0xD6, 0x6A, 0x6E, 0x4C, 0x67, 0x20, 0x85,
        0xCE, 0xD1, 0xF4, 0xC7, 0xB0, 0x50, 0x30, 0xA1,
        0x00, 0xC4, 0x78, 0x8F, 0xEF, 0x4C, 0xD3, 0xE4,
        0x94, 0xA8, 0x53, 0xBD, 0xE6, 0x3E, 0x9D, 0x44,
        0x9A, 0xE3, 0xBB, 0x6B, 0xA1, 0x08, 0x32, 0x38,
        0xDA, 0x3F, 0x40, 0x90, 0x51, 0x5D, 0x14, 0x3C,
        0x67, 0xDB, 0xE5, 0x3D, 0x8D, 0x50, 0x7A, 0x52,
        0x29, 0xFF, 0xEB, 0x20, 0x72, 0xD0, 0xBD, 0x09,
        0x2F, 0xC9, 0xAE, 0x52, 0xDE, 0xAA, 0xAC, 0xD1,
        0xF0, 0xF1, 0x4B, 0x5A, 0xC8, 0x47, 0x52, 0xBF,
        0xD0, 0x02, 0x5E, 0x5F, 0x55, 0xB8, 0x69, 0x35,
        0x0F, 0x4B, 0x27, 0x19, 0xC5, 0xC0, 0x5A, 0xC1,
        0x66, 0x9B, 0xB0, 0xFD, 0x3C, 0x61, 0x4A, 0xCE,
        0x02, 0xA2, 0x70, 0x61, 0x3F, 0xD3, 0x30, 0x97,
        0x06, 0xDD, 0xCD, 0x5B, 0x1A, 0x6A, 0xD2, 0x6F,
        0x35, 0x9A, 0xDA, 0x80, 0xB3, 0x0E, 0x50, 0xA7,
        0xE5, 0x0B, 0xBD, 0x3A, 0xA4, 0x5D, 0x06, 0x54,
        0xDD, 0x7D, 0x05, 0x8B, 0x0B, 0xBF, 0x4D, 0x0D,
        0x92, 0x13, 0x51, 0x42, 0x21, 0x4E, 0xE7, 0x05,
        0x11, 0xF3, 0x67, 0x6A, 0xE6, 0x43, 0xB5, 0xF2,
        0x45, 0x06, 0x3B, 0x94, 0x19, 0xCF, 0x6B, 0x49,
        0xFD, 0x64, 0x7F, 0x27, 0xD7, 0xC4, 0x1C, 0x86,
        0x6E, 0x6C, 0xAD, 0x9D, 0x5E, 0x2E, 0x3E, 0x33,
        0x1B, 0xF6, 0xB9, 0xF7, 0x2A, 0xCA, 0x32, 0x9B,
        0xB6, 0x42, 0x59, 0xC3, 0xE7, 0x97, 0x83, 0xA2,
        0x66, 0x74, 0xB7, 0xD3, 0x8E, 0xBD, 0xE8, 0x31,
        0x84, 0x11, 0xF4, 0x76, 0x4E, 0xBD, 0xC4, 0xC7,
        0xE4, 0x1A, 0xCF, 0xF8, 0x5B, 0xBB, 0x30, 0x31,
        0x8D, 0x59, 0xC4, 0x2C, 0x92, 0x03, 0xAB, 0xD6,
        0x63, 0x6B, 0xA3, 0xF7, 0x72, 0xB6, 0x72, 0x51,
        0x21, 0xC0, 0x52, 0xDE, 0x99, 0x91, 0x0D, 0x55,
        0x15, 0x8C, 0x6F, 0x3E, 0xF8, 0xBB, 0x7F, 0xED,
        0xE2, 0xF8, 0x1E, 0x58, 0xA7, 0xAE, 0xB2, 0x5E,
        0x2E, 0x46, 0xFD, 0x72, 0x32, 0x30, 0x2F, 0xAF,
        0xA8, 0xFC, 0x37, 0xFC, 0x8B, 0x55, 0xD5, 0x94,
        0xB7, 0x6E, 0xC4, 0xA5, 0x3E, 0xB1, 0x1E, 0xB3,
        0xFD, 0x63, 0x44, 0x28, 0xAA, 0xA5, 0xD8, 0x6F,
        0x83, 0x9D, 0x08, 0x9A, 0xBE, 0x2F, 0xEF, 0xE2,
        0xAE, 0x52, 0x62, 0xFE, 0xFC, 0x73, 0x48, 0xD8,
        0x36, 0x69, 0x2E, 0xDB, 0x21, 0x5D, 0x6F, 0x8F,
        0x54, 0x8B, 0x88, 0x52, 0x90, 0xC2, 0x40, 0x3C,
        0x51, 0xC3, 0xE2, 0x69, 0xD4, 0x93, 0xFB, 0xD3,
        0x39, 0xB5, 0xDF, 0xB0, 0xA3, 0x8E, 0xED, 0xA7,
        0x75, 0x4D, 0xAF, 0xFA, 0x16, 0xE5, 0xBC, 0xA5,
        0xA9, 0xBB, 0xDE, 0x04, 0xB0, 0x14, 0xB7, 0xAE,
        0xA8, 0x98, 0x8F, 0x37, 0x49, 0xD5, 0x2D, 0x2F,
        0xC1, 0xC9, 0xF7, 0xC7, 0xB2, 0xC2, 0xD6, 0x92,
        0xE7, 0x89, 0x6E, 0x4C, 0x34, 0xF5, 0x7C, 0x55,
        0x8C, 0xFE, 0x83, 0x17, 0xA8, 0x37, 0x44, 0x09,
        0xD5, 0x66, 0x87, 0x9A, 0x08, 0x62, 0x8F, 0x64,
        0x4F, 0xB4, 0x5B, 0x81, 0x84, 0x55, 0xBC, 0xA6,
        0x04, 0x2B, 0x4E, 0x61, 0x87, 0xC1, 0xDD, 0x17,
        0x7E, 0x9E, 0x51, 0x46, 0x31, 0x99, 0x04, 0xB1,
        0x50, 0x5F, 0x3E, 0xE0, 0x0C, 0xD7, 0xFE, 0xAF,
        0x0E, 0x83, 0xC3, 0x02, 0x49, 0x56, 0xF7, 0x76,
        0x59, 0xAC, 0xC5, 0x6D, 0x8D, 0x91, 0x7A, 0x37,
        0xE8, 0xFF, 0x7E, 0xB8, 0x87, 0x13, 0xCC, 0xA3,
        0x34, 0xEA, 0x04, 0xB8, 0xE2, 0x58, 0xC9, 0x34,
        0x5D, 0xA9, 0xDE, 0x26, 0xA0, 0xA3, 0x66, 0x51,
        0x94, 0x51, 0xE1, 0x01, 0x2D, 0xE6, 0xAA, 0xBF,
        0x46, 0x97, 0xC9, 0xDE, 0x82, 0x1D, 0x70, 0x02,
        0x1C, 0x32, 0x50, 0xA1, 0x06, 0xCF, 0x4C, 0x23,
        0xA1, 0xB1, 0x78, 0x5F, 0x54, 0x9D, 0x3C, 0x8C,
        0xD7, 0x1B, 0x05, 0xFE, 0xA7, 0x53, 0xE0, 0x04,
        0x6A, 0x3A, 0xE0, 0xA9, 0xB1, 0xF4, 0x02, 0x77,
        0xCF, 0x45, 0x3A, 0x2B, 0xA1, 0x4C, 0xBA, 0x92,
        0x3C, 0xC6, 0x26, 0x97, 0x06, 0xDF, 0xFF, 0xD5,
        0x17, 0xC1, 0xE5, 0x93, 0x00, 0x79, 0x91, 0x2E,
        0x05, 0xA5, 0x57, 0x18, 0x97, 0xA0, 0x68, 0x65,
        0x51, 0x6C, 0x86, 0x69, 0x9F, 0x70, 0x7E, 0x00,
        0xCB, 0x38, 0xCE, 0x19, 0x34, 0x90, 0xAE, 0xE3,
        0x0B, 0xA4, 0x7D, 0xDD, 0xF3, 0xA5, 0xB4, 0xFB,
        0xCE, 0xBA, 0x73, 0xDC, 0x13, 0xD0, 0xA1, 0x60,
        0xEA, 0x64, 0x2D, 0x30, 0xD6, 0x3A, 0x02, 0x96,
        0x4E, 0xDF, 0xDB, 0x2F, 0x29, 0xDC, 0xD3, 0x2C,
        0xA9, 0x97, 0x4F, 0x89, 0xC3, 0x2D, 0x1F, 0xA9,
        0xA8, 0x3C, 0x94, 0xA2, 0x77, 0x0F, 0xCF, 0xCF,
        0x86, 0xE6, 0x46, 0x46, 0x88, 0x2B, 0xD5, 0x50,
        0xDD, 0xD6, 0x5B, 0x4E, 0x2D, 0x28, 0x7A, 0xF6,
        0xC1, 0x96, 0xF4, 0x2D, 0xBD, 0x39, 0xB0, 0x20,
        0xD7, 0xCD, 0xFB, 0xB6, 0xE6, 0xE7, 0x5F, 0xFA,
        0xAB, 0x26, 0x09, 0x9E, 0xC1, 0xD2, 0x5E, 0x32,
        0x34, 0xF7, 0x0D, 0xD9, 0x72, 0x28, 0x6A, 0xEA,
        0x0C, 0x34, 0x36, 0x59, 0x5F, 0xE4, 0x9F, 0xCA,
        0x89, 0x8B, 0xFA, 0x42, 0x16, 0x04, 0xC8, 0x2D,
        0x3E, 0x94, 0x85, 0x6D, 0x18, 0x69, 0x05, 0x07,
        0x6D, 0x18, 0x6C, 0x68, 0x41, 0x74, 0xBF, 0x42,
        0x90, 0xDF, 0x31, 0x76, 0x9E, 0xDC, 0x97, 0xA1,
        0xDF, 0x2D, 0xFE, 0xD0, 0x3C, 0xF4, 0x5C, 0xE6,
        0x78, 0xC8, 0xA1, 0x42, 0x9E, 0xB9, 0x78, 0xD0,
        0x2A, 0x79, 0xD4, 0xF8, 0xCF, 0x01, 0x68, 0xDA,
        0xAB, 0x48, 0x2C, 0x6C, 0x61, 0x2F, 0x04, 0xB1,
        0xC9, 0x36, 0x37, 0xFE, 0x77, 0xB3, 0x02, 0xCE,
        0xFA, 0x78, 0x8C, 0x11, 0x35, 0x6C, 0x52, 0xC5,
        0x4F, 0x37, 0xA9, 0xDC, 0xFD, 0xA5, 0x59, 0x27,
        0xA8, 0xEF, 0x0A, 0x0C, 0xEA, 0x7C, 0xC4, 0xAD,
        0xCE, 0xE4, 0x59, 0xEB, 0x64, 0xDF, 0x08, 0xED,
        0x0F, 0xC2, 0x9F, 0xDC, 0x3C, 0x7B, 0x76, 0x2B,
        0x39, 0x93, 0x32, 0x06, 0x33, 0x40, 0xD4, 0x73,
        0x96, 0x62, 0x19, 0xBF, 0xC8, 0x7B, 0x4A, 0x3C,
        0x91, 0xC8, 0x0F, 0x0E, 0x4B, 0xA8, 0x6A, 0xA1,
        0x87, 0x9C, 0x76, 0x62, 0x5C, 0x86, 0x80, 0xA2,
        0x27, 0xAB, 0x22, 0x78, 0x06, 0x59, 0xD4, 0xB5,
        0xD3, 0x0E, 0x0E, 0x9A, 0x0D, 0xCE, 0x09, 0x4D,
        0xAF, 0x53, 0x76, 0x79, 0x27, 0x3A, 0x9B, 0x27,
        0x7E, 0xD2, 0xA2, 0xE2, 0x50, 0xEE, 0xA0, 0x93,
        0x82, 0x04, 0xC9, 0xE9, 0x63, 0xD3, 0x38, 0x52,
        0x2A, 0x3D, 0x1A, 0x44, 0x40, 0xE2, 0xA1, 0x23,
        0x97, 0xA5, 0xB9, 0x7D, 0x35, 0x65, 0x73, 0x07,
        0xBE, 0xC9, 0x4C, 0xC0, 0xC7, 0x2C, 0x5C, 0x6B,
        0x09, 0xDA, 0xF2, 0xBA, 0xF0, 0x02, 0x0B, 0x7D,
        0x8C, 0xA5, 0x60, 0xBF, 0x65, 0x96, 0x92, 0x9A,
        0xC8, 0xD4, 0xE5, 0x46, 0x0F, 0x78, 0x37, 0xB4,
        0x1B, 0x4A, 0xE6, 0xFF, 0x12, 0x33, 0x9D, 0xB8,
        0xEB, 0xD7, 0x02, 0x8A, 0xAC, 0xFE, 0x0B, 0x42,
        0xE0, 0x2C, 0xDE, 0x90, 0x67, 0x83, 0xAB, 0xFF,
        0x69, 0x4E, 0x7C, 0xBE, 0x08, 0x97, 0xED, 0x6E,
        0xD4, 0x38, 0xAC, 0xDB, 0x00, 0xA4, 0x70, 0x9C,
        0xFE, 0xF7, 0x15, 0x0E, 0xBE, 0xB0, 0x8C, 0x8F,
        0xF6, 0xC1, 0x54, 0x38, 0x15, 0xF4, 0xB8, 0x95,
        0x1C, 0x3C, 0xAC, 0xE4, 0x99, 0x58, 0x64, 0x58,
        0xA7, 0x3C, 0x85, 0x72, 0x38, 0x9A, 0xFC, 0x97,
        0x03, 0xA7, 0xFE, 0xAF, 0x67, 0x34, 0x45, 0xFB,
        0x4B, 0x0C, 0xCA, 0xA5, 0x11, 0xD4, 0xA2, 0xCF,
        0x46, 0x3F, 0x57, 0xE3, 0xA6, 0xD7, 0x2D, 0xA0,
        0x4B, 0x25, 0x66, 0x99, 0xA3, 0x02, 0x12, 0xE7,
        0xC5, 0x76, 0x8E, 0xFC, 0x15, 0x1B, 0x71, 0x74,
        0x41, 0x56, 0x57, 0x5A, 0x2E, 0x94, 0x43, 0x31,
        0x92, 0x32, 0xD1, 0x59, 0xC6, 0xCC, 0x00, 0x6F,
        0xDB, 0x57, 0xC5, 0x81, 0x73, 0xAD, 0x8D, 0x2C,
        0x86, 0x6C, 0x88, 0x87, 0x43, 0x7C, 0x22, 0x38,
        0x88, 0xE2, 0x1E, 0xF6, 0x7E, 0x1A, 0x33, 0x2C,
        0x1F, 0xDF, 0xCC, 0x15, 0xEF, 0x17, 0x47, 0x6F,
        0xE0, 0xFB, 0x57, 0xD4, 0x22, 0x98, 0x94, 0x72,
        0x5E, 0x14, 0x74, 0xC1, 0xBA, 0x12, 0x16, 0x56,
        0x28, 0x17, 0xF1, 0x6C, 0x53, 0xEC, 0xE0, 0x1C,
        0x7F, 0x9E, 0x36, 0x64, 0xEE, 0xDB, 0xBA, 0x94,
        0x95, 0x29, 0x87, 0x43, 0x1A, 0xA2, 0xA5, 0x7D,
        0x33, 0x0E, 0xB1, 0x1B, 0x28, 0xE6, 0xBF, 0x77,
        0x0E, 0x34, 0x9E, 0xCE, 0x35, 0x0C, 0x83, 0xE9,
        0x0D, 0xA6, 0xFE, 0x0D, 0x0A, 0x4A, 0xB9, 0x71,
        0x5D, 0xB2, 0x8B, 0xDD, 0x39, 0x7F, 0xAF, 0xA1,
        0x42, 0x83, 0x02, 0x15, 0x1E, 0x1F, 0x22, 0x2B,
        0x44, 0x69, 0x87, 0x9E, 0xB5, 0xD0, 0xF0, 0x18,
        0x60, 0x6A, 0x75, 0x94, 0xBF, 0xC8, 0x2C, 0x39,
        0x4E, 0x91, 0xB9, 0x26, 0x44, 0x95, 0xC9, 0x06,
        0x3D, 0x50, 0x52, 0x62, 0x79, 0x9B, 0x9F, 0xCB,
        0xE6, 0x31, 0x6B, 0xBC, 0xC8, 0xD8, 0x09, 0x30,
        0x53, 0x63, 0x6A, 0x74, 0xD4, 0xFA, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x02, 0x0F, 0x16, 0x1B, 0x1F,
        0x29, 0x2E, 0x36
    };
#endif
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
#ifndef WOLFSSL_NO_ML_DSA_44
    static const byte pk_44_draft[] = {
        0x35, 0x07, 0x31, 0x3A, 0xE3, 0x7A, 0xF6, 0x96,
        0x6C, 0x11, 0xA9, 0xE4, 0x0B, 0xEB, 0xEC, 0xE9,
        0x2B, 0x67, 0x3F, 0xD2, 0x67, 0x3C, 0x1C, 0x4C,
        0x08, 0xF0, 0x45, 0xA9, 0xDD, 0x5A, 0xB8, 0x8C,
        0x0A, 0x51, 0xA9, 0xBA, 0x89, 0x0F, 0x4C, 0xCB,
        0x9D, 0x0A, 0x41, 0x3F, 0x9C, 0xF4, 0x13, 0x36,
        0x79, 0x49, 0x00, 0x90, 0xBB, 0x57, 0x3B, 0xBD,
        0x2E, 0x18, 0xB3, 0xD0, 0xA5, 0x0E, 0x6B, 0x67,
        0xFF, 0x98, 0x8C, 0xDD, 0x07, 0xE8, 0xA7, 0xA1,
        0x3F, 0xAE, 0xFB, 0xD6, 0xC0, 0xF8, 0xF3, 0x34,
        0xA5, 0x17, 0xC2, 0x34, 0x88, 0x92, 0x65, 0xA6,
        0xE8, 0x66, 0x57, 0xFE, 0x86, 0x08, 0xF7, 0xDF,
        0xA0, 0x5B, 0x70, 0x3E, 0x91, 0x6C, 0x63, 0xA0,
        0xA3, 0x75, 0x55, 0xF8, 0xB6, 0xAA, 0xD4, 0x1B,
        0x78, 0x5E, 0x42, 0x9F, 0x96, 0xE4, 0xA0, 0x50,
        0xB6, 0x94, 0x2D, 0xC3, 0xE3, 0x36, 0x2B, 0x9D,
        0x6B, 0x7A, 0xEF, 0xF5, 0x68, 0xF2, 0x11, 0xDF,
        0x87, 0xA0, 0x9A, 0xC4, 0x61, 0xFB, 0xA4, 0x1C,
        0x98, 0x3F, 0xC9, 0x52, 0x59, 0x3B, 0x47, 0x4D,
        0xF5, 0x24, 0xA3, 0xD8, 0x63, 0xE1, 0xED, 0xDC,
        0xFD, 0xEB, 0x96, 0xFB, 0xF3, 0xE7, 0x50, 0x9C,
        0x72, 0x61, 0xC7, 0x3C, 0xCE, 0xF2, 0xEB, 0x22,
        0x55, 0x6B, 0x9F, 0x25, 0xE4, 0x45, 0xE1, 0xFB,
        0x3E, 0x2E, 0x4E, 0x92, 0x4F, 0x8A, 0x85, 0xEB,
        0x63, 0x2C, 0x05, 0x0F, 0x9A, 0xEC, 0x0E, 0x9D,
        0x05, 0x81, 0x46, 0x82, 0xEA, 0x74, 0x91, 0xD5,
        0x2A, 0xBC, 0xCC, 0xBB, 0xD6, 0x7F, 0x5F, 0x9A,
        0xD3, 0xBD, 0xEB, 0x14, 0xBA, 0x84, 0x27, 0x13,
        0x32, 0xB5, 0xF3, 0x71, 0xAC, 0x47, 0x19, 0x6B,
        0x5E, 0x43, 0x50, 0xC2, 0xA8, 0x82, 0xF5, 0x97,
        0x9B, 0x27, 0x62, 0xFB, 0xB7, 0xFF, 0x6B, 0xC8,
        0x52, 0x1E, 0xFB, 0x97, 0x39, 0x1E, 0x7F, 0x01,
        0xF8, 0x34, 0x47, 0xAA, 0xB2, 0x64, 0xB5, 0x9E,
        0x28, 0x18, 0xCB, 0x4A, 0x94, 0xBE, 0x6A, 0x43,
        0x5B, 0xAE, 0x21, 0xA4, 0x63, 0x64, 0x46, 0x0C,
        0x6B, 0x36, 0x1C, 0x2A, 0x3B, 0x64, 0xFA, 0xA0,
        0xAB, 0xE3, 0x3B, 0x7D, 0xB0, 0x23, 0x99, 0x21,
        0x55, 0x59, 0xBF, 0xD6, 0xDB, 0xB8, 0xDB, 0x09,
        0x5E, 0xBC, 0x32, 0x3C, 0xAC, 0xAB, 0x1A, 0x63,
        0x32, 0x21, 0x10, 0xD5, 0x8D, 0x7A, 0x5F, 0xCE,
        0x72, 0x8D, 0x2A, 0xED, 0x1D, 0x30, 0x38, 0x5D,
        0x3E, 0x62, 0xC2, 0x8E, 0xC9, 0x9F, 0x8C, 0x50,
        0x3F, 0xC6, 0xCE, 0x86, 0x4D, 0x67, 0x3D, 0x09,
        0xB6, 0x27, 0x14, 0x57, 0x14, 0xED, 0xC9, 0x8F,
        0xAC, 0x9E, 0xAC, 0x6F, 0xB5, 0xB2, 0xE6, 0x8D,
        0x9D, 0x5E, 0xE6, 0x78, 0x77, 0x09, 0x94, 0x35,
        0x5E, 0x3B, 0x64, 0x04, 0x38, 0xD4, 0x5B, 0x04,
        0xB8, 0x6C, 0x33, 0x97, 0xE1, 0x58, 0x54, 0x32,
        0xB3, 0x0F, 0x37, 0x69, 0x39, 0xCE, 0x57, 0x31,
        0x5C, 0x75, 0xA8, 0x94, 0xD0, 0x39, 0x2D, 0xB4,
        0x73, 0xA7, 0xA4, 0x7C, 0xBE, 0x34, 0x03, 0x2D,
        0x99, 0x1D, 0xDF, 0x32, 0x26, 0xB7, 0x45, 0x1B,
        0x03, 0xCD, 0xEE, 0x9D, 0x58, 0xA8, 0xA7, 0x76,
        0x1B, 0x17, 0x42, 0xD9, 0x69, 0x0F, 0x26, 0x3A,
        0x9D, 0x70, 0x9B, 0x4E, 0x81, 0xEB, 0x96, 0x02,
        0xB5, 0xB3, 0x92, 0x31, 0xFE, 0xBC, 0x38, 0x11,
        0x5A, 0x47, 0xED, 0x0A, 0x2A, 0xE2, 0xB8, 0x47,
        0x13, 0x5E, 0x43, 0x97, 0xD5, 0xFA, 0x31, 0x02,
        0x58, 0xE9, 0x9E, 0xB5, 0x3F, 0x85, 0x92, 0x0E,
        0xB9, 0xDB, 0xE0, 0xEE, 0x56, 0x76, 0x64, 0x8F,
        0xF2, 0xE2, 0x47, 0x81, 0xD4, 0xA4, 0x82, 0x43,
        0x69, 0xAE, 0x8E, 0x48, 0x50, 0x84, 0x93, 0x3B,
        0x9C, 0x65, 0xD3, 0x6F, 0xCD, 0x90, 0xA0, 0xD8,
        0xA0, 0xE1, 0x79, 0xCC, 0xD5, 0x1F, 0x71, 0x73,
        0x93, 0xE7, 0xB2, 0xB0, 0x78, 0x17, 0xD7, 0x79,
        0xDE, 0xCC, 0x83, 0x7D, 0x5A, 0xF2, 0x0E, 0xA6,
        0xB1, 0x76, 0x61, 0x15, 0x88, 0x8E, 0xD7, 0xA6,
        0x51, 0xBF, 0x9C, 0xD1, 0x0A, 0xFC, 0xDA, 0x65,
        0xA5, 0x65, 0xFE, 0xB2, 0xED, 0x07, 0x74, 0x42,
        0x4C, 0xF5, 0x42, 0x3D, 0xAF, 0x5F, 0x4D, 0x72,
        0x51, 0xE6, 0x3F, 0x68, 0xCC, 0xC5, 0x2D, 0x89,
        0x01, 0xD8, 0x80, 0xB4, 0xFC, 0xEB, 0x3B, 0xBE,
        0x7C, 0xFA, 0x24, 0x27, 0xE1, 0x05, 0x94, 0x67,
        0xAD, 0xB3, 0x47, 0x7D, 0x28, 0x18, 0xC1, 0xC9,
        0xB8, 0xA1, 0x2A, 0x95, 0xBB, 0x5D, 0xC9, 0x42,
        0x4F, 0x64, 0x94, 0x07, 0x5F, 0x65, 0xD3, 0xA5,
        0x65, 0xEE, 0x67, 0x2C, 0x10, 0x65, 0x81, 0x4D,
        0x7F, 0xAF, 0x2E, 0x97, 0x9E, 0x11, 0xA3, 0xF5,
        0x3E, 0xDE, 0xB1, 0x1D, 0x44, 0x72, 0x90, 0x74,
        0xFD, 0x47, 0x82, 0xA6, 0x04, 0x3E, 0x28, 0x3C,
        0x15, 0xDF, 0xC4, 0x7A, 0x7C, 0xF5, 0x5A, 0xC6,
        0xFB, 0xE4, 0xC2, 0xE0, 0x6E, 0x4C, 0x09, 0x2E,
        0xE3, 0xE6, 0x3A, 0xEF, 0xF6, 0x54, 0xDC, 0x92,
        0xBE, 0x8F, 0x24, 0x8E, 0x70, 0x53, 0x90, 0x3D,
        0x06, 0xA5, 0x0A, 0x72, 0xA0, 0x7B, 0x22, 0x14,
        0x80, 0x43, 0xAD, 0xDC, 0x11, 0xFC, 0xFF, 0xCF,
        0x5E, 0xA4, 0x69, 0x1C, 0x09, 0x09, 0xC3, 0x3D,
        0xF5, 0xE7, 0x05, 0x6F, 0x16, 0x33, 0x75, 0xB4,
        0x9B, 0x7B, 0x26, 0xDB, 0xE7, 0x27, 0x56, 0xD3,
        0x91, 0x82, 0x9D, 0xEB, 0x96, 0x3E, 0xE8, 0x40,
        0xAB, 0x5D, 0x6C, 0xB7, 0xA6, 0x36, 0x07, 0xD4,
        0xE7, 0x7C, 0xD4, 0x5C, 0x36, 0xE4, 0xFC, 0x7C,
        0x8A, 0x36, 0x8D, 0x53, 0x43, 0xD4, 0xAC, 0x0B,
        0x1B, 0xBA, 0x32, 0x88, 0xFA, 0xCE, 0xC1, 0xB9,
        0x34, 0x3C, 0xAC, 0xA0, 0xF4, 0xF2, 0x83, 0xA8,
        0xBB, 0x6F, 0x12, 0xC6, 0xB5, 0x3C, 0xDE, 0xA8,
        0x49, 0x66, 0x97, 0xD7, 0x7E, 0x37, 0xF7, 0xCE,
        0x7C, 0xF8, 0xC8, 0xBB, 0x8C, 0xB5, 0x3B, 0x3F,
        0xB9, 0x51, 0x68, 0x00, 0xD7, 0x2E, 0x1C, 0x10,
        0xAF, 0x9F, 0x3C, 0xD2, 0xAC, 0xE5, 0xBE, 0x94,
        0xB9, 0x60, 0xF5, 0xB2, 0x70, 0x24, 0xE8, 0x8A,
        0x2C, 0xD8, 0x95, 0xAF, 0xAA, 0xA9, 0xA5, 0x2B,
        0xCA, 0xE0, 0x58, 0x44, 0x02, 0x3F, 0xF8, 0x21,
        0x0C, 0x29, 0xB7, 0xD5, 0x08, 0x9E, 0x69, 0x81,
        0xD4, 0x6C, 0xC5, 0x0B, 0xF6, 0xEF, 0xAB, 0x01,
        0xEA, 0xDF, 0x36, 0x2C, 0x5C, 0xFB, 0xEB, 0xC8,
        0x4F, 0x71, 0x80, 0xD7, 0x00, 0xC9, 0x32, 0x5D,
        0x02, 0x4F, 0x96, 0x94, 0x71, 0xCD, 0x98, 0xC4,
        0x25, 0x7A, 0x92, 0xF1, 0x9B, 0xA0, 0x34, 0x30,
        0x6C, 0x41, 0x59, 0xD5, 0x01, 0x5D, 0xD6, 0x56,
        0xEA, 0x05, 0xF2, 0xFC, 0xF8, 0x58, 0xFA, 0x12,
        0x9C, 0x5A, 0x5C, 0xD5, 0x3D, 0xC7, 0x5D, 0x1B,
        0x99, 0x2A, 0x6A, 0x4C, 0xF9, 0xEA, 0x9D, 0x70,
        0x53, 0xBC, 0xBE, 0xAD, 0x61, 0xC7, 0x2D, 0x77,
        0xEF, 0x61, 0xC7, 0xBE, 0x9C, 0x73, 0xC1, 0xD5,
        0xD4, 0x5C, 0x5F, 0x21, 0x6A, 0x5C, 0xEE, 0x78,
        0xAA, 0xC6, 0x6C, 0x56, 0xDB, 0x38, 0x5A, 0x94,
        0x12, 0xB8, 0x73, 0x7C, 0xDF, 0x9A, 0x27, 0xCD,
        0xC5, 0xD1, 0xD3, 0xCA, 0x0E, 0x37, 0x0A, 0xC1,
        0x6F, 0xAD, 0xE3, 0x32, 0x94, 0x6C, 0x20, 0xB5,
        0xED, 0xE6, 0x2D, 0x34, 0x39, 0x58, 0xD2, 0x1E,
        0x63, 0x8D, 0xFA, 0xFF, 0xB5, 0xE8, 0x40, 0xC8,
        0x42, 0x38, 0x7A, 0x01, 0x80, 0xFF, 0x52, 0x3F,
        0xE9, 0x89, 0x63, 0xAD, 0x91, 0x5F, 0xCE, 0x0A,
        0x47, 0x87, 0xF9, 0x6D, 0xD7, 0x79, 0xEF, 0xCE,
        0x10, 0x7B, 0x73, 0x43, 0xBE, 0x51, 0xA0, 0xDF,
        0xE5, 0xEC, 0xA9, 0x63, 0xF6, 0x5E, 0x72, 0x36,
        0x22, 0x86, 0xEE, 0x4E, 0x4A, 0x76, 0xFD, 0x86,
        0xBA, 0xE6, 0xD6, 0xC4, 0xD2, 0xE6, 0xFF, 0xB2,
        0x5B, 0x39, 0xF9, 0xC3, 0x29, 0xA8, 0x61, 0x3A,
        0x33, 0x34, 0x89, 0xC9, 0x83, 0xF9, 0xB2, 0x70,
        0x21, 0x54, 0x44, 0x94, 0x70, 0xAD, 0x70, 0x18,
        0x84, 0x38, 0x91, 0xFB, 0xDE, 0x5E, 0x3D, 0xE3,
        0xB2, 0xA7, 0x3C, 0x1D, 0x49, 0xA6, 0x66, 0x7C,
        0x4B, 0xEB, 0xB0, 0xA7, 0x7C, 0xC5, 0xAE, 0x45,
        0x1F, 0xBE, 0x0E, 0x2F, 0x11, 0xDC, 0x92, 0x08,
        0xAA, 0x18, 0x38, 0xFE, 0x61, 0xBE, 0x9D, 0xC3,
        0x3A, 0x1F, 0x2F, 0xB6, 0x6E, 0xB6, 0x54, 0x97,
        0x74, 0x06, 0xBC, 0x12, 0x2D, 0x64, 0x18, 0x14,
        0x25, 0x5A, 0xCB, 0x7B, 0xD7, 0x9D, 0xC3, 0x2C,
        0xC2, 0x0B, 0x19, 0x10, 0xD2, 0x57, 0xF0, 0xDF,
        0xA4, 0x95, 0xA4, 0x5A, 0xA0, 0x2D, 0x0F, 0xA0,
        0xBC, 0xF7, 0x60, 0x7F, 0x38, 0xE1, 0x17, 0x0D,
        0x36, 0x08, 0xF5, 0xF9, 0x75, 0x28, 0x75, 0xAC,
        0xA9, 0x2B, 0x75, 0xC4, 0x41, 0xE0, 0x0D, 0x5C,
        0xBC, 0x5F, 0x49, 0x16, 0x25, 0x38, 0x16, 0xE1,
        0x0C, 0x2C, 0x9C, 0x63, 0xA8, 0x5F, 0x70, 0xF4,
        0x64, 0xC7, 0x10, 0x19, 0x52, 0x19, 0x6E, 0x9B,
        0x5C, 0x09, 0x4F, 0xEE, 0xB6, 0x7C, 0x85, 0xC9,
        0x6E, 0xCB, 0x33, 0x32, 0x42, 0x9D, 0x57, 0x18,
        0xE6, 0x55, 0x94, 0x74, 0x02, 0xEE, 0xEB, 0xAA,
        0xF7, 0xD3, 0x45, 0x7A, 0x49, 0x6F, 0x83, 0x89,
        0x00, 0xE4, 0xAA, 0x20, 0x87, 0x10, 0xAD, 0xC0,
        0x0E, 0xF5, 0x93, 0x57, 0xE5, 0x45, 0x7A, 0xBD,
        0x82, 0x87, 0x50, 0x0F, 0xE1, 0x2C, 0x0C, 0x6D,
        0xEE, 0xC8, 0x94, 0xB8, 0x39, 0xF3, 0x3C, 0xFE,
        0x7E, 0xC1, 0x0F, 0xB4, 0x67, 0xA2, 0xDF, 0xC6,
        0x9D, 0xB5, 0x9D, 0xB8, 0x72, 0x50, 0xBD, 0xB3,
        0xDB, 0xF6, 0x87, 0x5E, 0x26, 0x93, 0xF0, 0xD4,
        0x0D, 0x68, 0xA4, 0x8B, 0xBD, 0x2C, 0x6E, 0xD8,
        0x4F, 0x81, 0x5D, 0x0D, 0xAC, 0x72, 0x65, 0xEC,
        0x4E, 0xF2, 0x4E, 0x5F, 0x67, 0x04, 0xF3, 0x08,
        0x29, 0x4D, 0xB2, 0xE2, 0xD5, 0x9F, 0xD4, 0xB9,
        0x13, 0xB4, 0x33, 0x80, 0x27, 0x84, 0x7E, 0xF4
    };
    static const byte msg_44_draft[] = {
        0x5C, 0x70, 0x7F, 0xBF, 0xF4, 0xFF, 0xE5, 0x9B,
        0x09, 0xAA, 0xF8, 0xDB, 0x21, 0xAD, 0xBE, 0xBA,
        0xC6, 0xB2, 0x65, 0x37, 0x9A, 0x9A, 0x43, 0x3A,
        0xA8, 0x23, 0x2B, 0x13, 0x9B, 0xBD, 0x46, 0x37,
        0x30, 0x60, 0xA7, 0x5B, 0xC4, 0x48, 0x63, 0x5F,
        0x41, 0x35, 0x38, 0x69, 0xF9, 0x6F, 0xB5, 0x65,
        0x26, 0xDB, 0xAE, 0xB7, 0x5C, 0xFE, 0x2C, 0x03,
        0xCB, 0x43, 0x08, 0x58, 0x5E, 0x27, 0xD1, 0x42,
        0x14, 0xF2, 0x4B, 0xD7, 0x13, 0xE4, 0x96, 0x74,
        0x6A, 0xC1, 0x36, 0xC7, 0x9D, 0x0F, 0x7D, 0xB0,
        0x7B, 0x8A, 0x3A, 0x6D, 0x00, 0x5B, 0x29, 0x7B,
        0x37, 0xBA, 0x3F, 0x5B, 0xBD, 0xCE, 0x21, 0x77,
        0xFD, 0xD6, 0x78, 0x77, 0x20, 0x31, 0xF0, 0x60,
        0x49, 0xAE, 0x12, 0x86, 0x7A, 0x64, 0xBD, 0x0B,
        0x9E, 0xC6, 0x26, 0x80, 0x9E, 0xCE, 0x19, 0x8D,
        0x6A, 0x6B, 0x09, 0x03, 0x45, 0xDF, 0x22, 0x7D
    };
    static const byte sig_44_draft[] = {
        0x08, 0xF0, 0x10, 0xFA, 0x63, 0x3F, 0x2B, 0xA1,
        0x46, 0x81, 0x34, 0xC4, 0xBC, 0xAB, 0x62, 0x17,
        0x0B, 0x64, 0xEA, 0x00, 0x2D, 0xD6, 0x8A, 0xE5,
        0xC2, 0x45, 0x29, 0xB9, 0xEC, 0x6F, 0x3B, 0xF2,
        0xDC, 0x2F, 0xC7, 0x34, 0x5A, 0x1E, 0xFE, 0x0C,
        0xCA, 0xB9, 0x6A, 0xD8, 0xDA, 0xBA, 0xAA, 0x80,
        0x90, 0xDC, 0x8C, 0x6C, 0x22, 0xFF, 0xC4, 0x90,
        0x9E, 0xE9, 0xA5, 0x45, 0xFC, 0xE8, 0x64, 0x53,
        0x9E, 0xC4, 0x17, 0xE1, 0xB2, 0x1A, 0x31, 0x40,
        0x26, 0x9D, 0x5E, 0x03, 0x6A, 0xC6, 0x09, 0x19,
        0xDD, 0xB3, 0x63, 0xE0, 0x35, 0xCD, 0xB4, 0x2E,
        0x25, 0x38, 0x6E, 0x6C, 0x76, 0xA9, 0x19, 0x75,
        0x68, 0x6E, 0xB7, 0xAB, 0xAD, 0x8F, 0x63, 0x64,
        0x97, 0x4E, 0x56, 0x82, 0x30, 0x45, 0x86, 0x22,
        0x64, 0xDA, 0xD2, 0xAE, 0x54, 0x70, 0x5C, 0xF1,
        0xEB, 0xD1, 0x84, 0x8D, 0xFF, 0x86, 0x15, 0xE6,
        0x20, 0xCE, 0x14, 0x89, 0xEF, 0xFA, 0x2E, 0xF8,
        0x60, 0xCA, 0x53, 0x52, 0xE4, 0xD5, 0xC8, 0x2E,
        0x50, 0xD5, 0x9D, 0x90, 0xA6, 0x12, 0xC7, 0xF1,
        0x70, 0x0D, 0xE2, 0x89, 0x5B, 0x31, 0x6A, 0x21,
        0x79, 0x9C, 0xBE, 0x77, 0x6E, 0xA6, 0xBF, 0x51,
        0x05, 0x2A, 0x83, 0x50, 0x7E, 0x86, 0x14, 0xD1,
        0x50, 0x53, 0x1F, 0x1C, 0x5E, 0x50, 0x24, 0x69,
        0x6C, 0x91, 0x55, 0x35, 0x19, 0x6F, 0xE0, 0xDC,
        0xB5, 0xD6, 0x48, 0x7E, 0x78, 0x61, 0x59, 0x2C,
        0xD0, 0x1B, 0x42, 0x58, 0xAF, 0x7A, 0x39, 0xCA,
        0x02, 0x1C, 0x50, 0xEF, 0xE9, 0xE1, 0xDE, 0x31,
        0x8D, 0x09, 0x51, 0xC9, 0xDB, 0x16, 0xF9, 0xB9,
        0x45, 0x54, 0x81, 0x16, 0xD7, 0x14, 0xD8, 0xBE,
        0x9C, 0xCA, 0x53, 0xFE, 0x8F, 0x24, 0x99, 0x0D,
        0xBA, 0x7F, 0x99, 0x42, 0x11, 0x9B, 0x32, 0xDD,
        0x93, 0x5C, 0xBA, 0x2D, 0xD3, 0xB3, 0xF2, 0x48,
        0x13, 0x9C, 0x80, 0xBB, 0x8D, 0xF4, 0xC7, 0xAA,
        0xEB, 0xC6, 0xFD, 0xB8, 0x35, 0x95, 0x87, 0x2B,
        0x9E, 0xCF, 0x48, 0xF3, 0x2D, 0xFF, 0x70, 0xF4,
        0xCE, 0x35, 0x68, 0x7E, 0x9D, 0xDF, 0xD5, 0x0C,
        0xCD, 0xE3, 0x51, 0xB0, 0x90, 0x86, 0xE5, 0xD1,
        0xF1, 0x3B, 0x72, 0x42, 0x73, 0x07, 0x03, 0xE2,
        0xFB, 0x40, 0x3F, 0xD4, 0xC8, 0x30, 0xB6, 0x86,
        0x49, 0x8A, 0x17, 0xDB, 0x8F, 0x46, 0x6C, 0x3A,
        0xC3, 0x49, 0xCD, 0x59, 0x68, 0x81, 0x66, 0x03,
        0xD7, 0x24, 0xAF, 0x1F, 0x77, 0xC7, 0xFB, 0xF7,
        0x83, 0xCD, 0xA2, 0x6D, 0x35, 0x0C, 0x8B, 0xBC,
        0x29, 0x3A, 0x7F, 0xAC, 0xB9, 0xF9, 0x78, 0x50,
        0x6A, 0x67, 0xFC, 0xDC, 0x6F, 0x01, 0x65, 0x06,
        0x82, 0x81, 0xB0, 0x7D, 0x25, 0x5D, 0x74, 0x0B,
        0x68, 0x5F, 0x51, 0x2C, 0x82, 0xF3, 0x1D, 0x92,
        0xF6, 0xA9, 0xA9, 0x6A, 0x77, 0x57, 0x58, 0xAA,
        0x7C, 0xBE, 0x35, 0xF4, 0x56, 0xDE, 0x42, 0x01,
        0x2D, 0xB8, 0x28, 0x83, 0x7B, 0xA0, 0xA9, 0x7D,
        0xC3, 0x30, 0x13, 0x52, 0xD0, 0xA1, 0xC8, 0xA1,
        0x2C, 0x51, 0x49, 0xAE, 0xA8, 0x04, 0xCB, 0xA8,
        0x66, 0x01, 0x26, 0xDF, 0x2D, 0x1C, 0x21, 0xA2,
        0x4E, 0xBD, 0xA5, 0x48, 0x2A, 0x2D, 0x56, 0x60,
        0x20, 0x98, 0x4D, 0x15, 0x7D, 0x02, 0xB6, 0x3A,
        0xE4, 0x11, 0xAE, 0xF7, 0x3E, 0x5D, 0x56, 0x4F,
        0x6A, 0xA3, 0x0A, 0xEA, 0xCC, 0x35, 0x8A, 0xB7,
        0xC4, 0x8F, 0x25, 0x3E, 0x42, 0x41, 0x2B, 0xA5,
        0x1F, 0xA7, 0x3B, 0x87, 0x22, 0x86, 0x79, 0xD5,
        0xE5, 0x2A, 0xA2, 0xCD, 0x68, 0xCE, 0xB8, 0x18,
        0x6D, 0xEF, 0x1C, 0x36, 0x7F, 0x75, 0x50, 0x36,
        0x1B, 0x58, 0xEB, 0x32, 0xA1, 0xC8, 0xAF, 0x47,
        0xE1, 0x26, 0x73, 0x1F, 0x5D, 0x73, 0x30, 0x13,
        0x2F, 0xC7, 0x8B, 0xA3, 0x03, 0xB4, 0xA8, 0x86,
        0x25, 0x29, 0xD1, 0x75, 0x10, 0xEE, 0x7F, 0x56,
        0xBC, 0x0D, 0x59, 0xB4, 0xAE, 0xC9, 0x44, 0x0A,
        0xF7, 0x0D, 0xBF, 0x17, 0x6A, 0x22, 0x9C, 0x75,
        0x2B, 0x3E, 0x22, 0xB8, 0x2F, 0x4B, 0x68, 0xF1,
        0x07, 0xE3, 0x47, 0x47, 0x21, 0x9C, 0xA3, 0x5B,
        0x31, 0x0A, 0x14, 0xD9, 0x7C, 0xA8, 0xC0, 0xC6,
        0x5C, 0xAD, 0x05, 0xD6, 0x15, 0xD3, 0xEC, 0xEC,
        0x32, 0xC2, 0xFF, 0xF4, 0x96, 0x9C, 0xC8, 0x65,
        0xA0, 0xB2, 0xD6, 0xF4, 0x98, 0xBB, 0xB1, 0x4E,
        0xA5, 0x11, 0x3B, 0x4E, 0xA8, 0xEB, 0x90, 0xAB,
        0xD8, 0x25, 0x10, 0xE3, 0x66, 0xB5, 0xA5, 0x11,
        0x60, 0xA0, 0xCB, 0xDF, 0x77, 0x8A, 0x80, 0x4C,
        0x07, 0x9B, 0x1B, 0x45, 0x95, 0x29, 0x1D, 0x88,
        0x85, 0xAC, 0x32, 0x94, 0x26, 0x87, 0x12, 0x0A,
        0x2F, 0x9E, 0xAE, 0x69, 0x79, 0x25, 0x5A, 0x50,
        0xF4, 0xDB, 0x15, 0x20, 0x9F, 0x7A, 0x7A, 0xF2,
        0xE5, 0x8A, 0x63, 0x6A, 0xDD, 0xBD, 0x06, 0xCB,
        0x42, 0xF0, 0x20, 0xA9, 0x3B, 0x52, 0xD8, 0x68,
        0x37, 0x71, 0x07, 0xB8, 0x5B, 0xFE, 0xA0, 0xEC,
        0xBD, 0x75, 0xFF, 0x9C, 0x89, 0xDF, 0x01, 0xE7,
        0x17, 0x7D, 0xA7, 0xE8, 0x27, 0x9E, 0xA2, 0x41,
        0x66, 0xE6, 0xDB, 0x8B, 0x5A, 0x3F, 0x6C, 0xC9,
        0xE3, 0x4F, 0x0D, 0xD0, 0x92, 0x1E, 0x27, 0x41,
        0xF2, 0xB3, 0x08, 0x32, 0x03, 0x6D, 0x2C, 0x4F,
        0x78, 0xEC, 0x99, 0xB3, 0x94, 0x6C, 0xC1, 0x89,
        0xD9, 0x34, 0x0F, 0xEF, 0x10, 0xF0, 0xDA, 0xCE,
        0x09, 0x69, 0x7A, 0x93, 0xC6, 0xFF, 0x19, 0x4F,
        0xBD, 0xDE, 0xA6, 0x54, 0x8A, 0xE5, 0x81, 0x3F,
        0x96, 0xD3, 0xA0, 0x77, 0x7C, 0xF2, 0x4B, 0xF1,
        0x68, 0xA2, 0x23, 0x3D, 0xD4, 0x16, 0xC1, 0x66,
        0xDA, 0x13, 0x53, 0xE1, 0x9F, 0x9A, 0x36, 0x09,
        0x4D, 0x72, 0x08, 0x09, 0xEB, 0x87, 0x74, 0x9A,
        0xB2, 0x8C, 0x60, 0x7F, 0xFB, 0x70, 0x17, 0x51,
        0xB1, 0xAC, 0x18, 0xDF, 0xCB, 0x43, 0x2A, 0xD3,
        0x89, 0xDA, 0x78, 0xAE, 0xDC, 0xEA, 0xB2, 0x22,
        0xCA, 0x2F, 0xF1, 0xE4, 0xA7, 0xCC, 0xAF, 0xB1,
        0x63, 0x1B, 0x5D, 0xDD, 0xD1, 0x49, 0xB8, 0x90,
        0x2E, 0xC9, 0xC0, 0x83, 0x0D, 0xAB, 0x88, 0x88,
        0x4C, 0x74, 0x72, 0x00, 0x7D, 0xFE, 0xF2, 0x46,
        0x73, 0xFD, 0x99, 0xEC, 0x89, 0x8B, 0x3B, 0x0F,
        0xCE, 0x35, 0x5A, 0xEA, 0x13, 0x4F, 0x67, 0x67,
        0xFD, 0x0D, 0x87, 0xFC, 0xB1, 0x36, 0x48, 0x07,
        0x33, 0x0B, 0xCA, 0xD4, 0xD7, 0xD0, 0xCC, 0xA1,
        0x8F, 0xF0, 0x3F, 0x01, 0x8B, 0x6B, 0x74, 0x44,
        0x2F, 0x1B, 0xE0, 0x65, 0x31, 0x1B, 0x4E, 0xDB,
        0x67, 0x65, 0xA9, 0x34, 0xE8, 0x4D, 0x0C, 0xF3,
        0x29, 0xED, 0x53, 0xAB, 0x8A, 0x98, 0x07, 0x2B,
        0xE0, 0xCD, 0xC0, 0x08, 0x82, 0x4A, 0x72, 0x28,
        0x72, 0xA2, 0xAC, 0xFE, 0xF7, 0xBF, 0x6E, 0x8E,
        0xF8, 0x3E, 0x04, 0x58, 0xA4, 0x36, 0x46, 0x33,
        0xAB, 0xDD, 0x0E, 0xBF, 0x01, 0xD2, 0xEF, 0x19,
        0x5B, 0x78, 0x2B, 0x30, 0x51, 0x25, 0x50, 0xD0,
        0xB5, 0x82, 0xC7, 0x20, 0x0D, 0xA1, 0x2C, 0x38,
        0xAF, 0x44, 0xFC, 0xBD, 0x49, 0xB8, 0x7F, 0x89,
        0xEF, 0xBE, 0x37, 0x5C, 0xCB, 0xA2, 0x11, 0x75,
        0x7D, 0xDA, 0xA8, 0x7B, 0x3A, 0x3C, 0x10, 0x11,
        0x4D, 0x9F, 0x99, 0xAB, 0x4B, 0xA2, 0x20, 0x7A,
        0x5F, 0x96, 0xEF, 0x1C, 0x00, 0xD7, 0x27, 0x17,
        0x77, 0x7C, 0x51, 0x58, 0x4B, 0x13, 0x97, 0x53,
        0x2A, 0xC6, 0x86, 0x4D, 0x3B, 0x8E, 0xBB, 0x4F,
        0xB8, 0xA0, 0x84, 0x87, 0xF6, 0xEF, 0x55, 0x12,
        0x2B, 0xCF, 0x9E, 0x5C, 0xD0, 0x0E, 0xBC, 0x1E,
        0x79, 0x53, 0xE7, 0x8C, 0x4D, 0x8B, 0xCB, 0x20,
        0xF6, 0xEA, 0x72, 0x0A, 0x63, 0x2F, 0x0C, 0xCF,
        0x57, 0x27, 0x26, 0xF4, 0x3A, 0x95, 0xCA, 0xBE,
        0xB5, 0x7C, 0x47, 0x60, 0x10, 0xCD, 0x28, 0x9E,
        0x02, 0x64, 0xC9, 0x8D, 0x82, 0x49, 0xD0, 0xD6,
        0x60, 0xF8, 0xDC, 0xC8, 0x4B, 0x7D, 0xB5, 0xEF,
        0x11, 0x17, 0xC7, 0x94, 0x5F, 0x0D, 0x99, 0xBE,
        0x75, 0x48, 0x49, 0xC6, 0x58, 0x43, 0x64, 0x99,
        0x1A, 0x5A, 0x41, 0xBA, 0xC2, 0x31, 0xB3, 0xE0,
        0x45, 0x1B, 0x81, 0xD2, 0x12, 0xBE, 0x90, 0xDB,
        0xFF, 0xBC, 0xCB, 0x99, 0xA3, 0xF0, 0x74, 0xE8,
        0x2C, 0x48, 0x58, 0xB3, 0x17, 0xA4, 0x9A, 0xD2,
        0x22, 0x46, 0xFB, 0xF5, 0x85, 0x8D, 0x07, 0xDF,
        0xDB, 0x78, 0x07, 0xF4, 0x99, 0xA8, 0x6C, 0xEE,
        0x6E, 0x96, 0x20, 0xB8, 0xC2, 0xA9, 0xFA, 0x8B,
        0x6E, 0xA6, 0x79, 0x6D, 0xF9, 0xC3, 0x0C, 0x77,
        0x74, 0xAE, 0xB0, 0x40, 0xA9, 0xE5, 0xA7, 0x0B,
        0x30, 0x40, 0x4B, 0x4F, 0xB1, 0x0A, 0x0B, 0x7B,
        0xEE, 0x1F, 0x69, 0xFA, 0xD0, 0xF0, 0x2D, 0x5D,
        0x00, 0xB5, 0x4D, 0xEB, 0x32, 0x84, 0xB2, 0xB7,
        0x60, 0xAA, 0x6C, 0xF9, 0x98, 0x18, 0xB3, 0xD9,
        0xC1, 0x54, 0x8D, 0xAC, 0x12, 0xB0, 0x3A, 0x26,
        0xB2, 0x23, 0x2D, 0x9B, 0xF8, 0x20, 0xEE, 0x90,
        0xE0, 0x6D, 0x31, 0xDE, 0xF5, 0xCA, 0xBA, 0x6A,
        0x53, 0x40, 0x29, 0x6C, 0x18, 0x62, 0xA5, 0x8A,
        0xB8, 0x17, 0xA0, 0xAB, 0xCB, 0xDC, 0xE1, 0x3B,
        0xD6, 0xC6, 0x29, 0xA3, 0x1C, 0x5F, 0x8D, 0x6E,
        0x73, 0xF6, 0x98, 0x10, 0x0F, 0x9F, 0x7E, 0xCA,
        0x4C, 0xD8, 0xEB, 0xE4, 0xB8, 0xDF, 0x72, 0x78,
        0x65, 0xAF, 0x4A, 0x20, 0xFE, 0x7C, 0xB4, 0xCA,
        0x07, 0x81, 0xFD, 0xC5, 0xC5, 0xFD, 0x33, 0x4D,
        0xB8, 0x37, 0x37, 0xC4, 0x21, 0x81, 0x66, 0x45,
        0xAE, 0x81, 0x34, 0x13, 0xA6, 0x40, 0x81, 0x39,
        0x55, 0x90, 0xE6, 0xF1, 0x42, 0x56, 0x74, 0xFF,
        0x06, 0x9B, 0x50, 0x1F, 0x0F, 0xDA, 0x6B, 0x31,
        0xC6, 0x4B, 0xC5, 0xC2, 0x14, 0xE7, 0x01, 0x5E,
        0xA9, 0xDA, 0x12, 0x2D, 0x6C, 0xE0, 0x8C, 0xEB,
        0x2D, 0xF6, 0x2C, 0x45, 0xBC, 0x01, 0x73, 0x34,
        0x6D, 0xAB, 0xBC, 0x15, 0x4C, 0x16, 0x03, 0x35,
        0x9D, 0xD4, 0xF0, 0xAC, 0x49, 0x84, 0x4A, 0xEE,
        0x46, 0x47, 0x64, 0x93, 0xF2, 0x49, 0x59, 0x86,
        0x26, 0xFB, 0x24, 0x6B, 0x99, 0xB3, 0x9A, 0xCB,
        0xB4, 0x2B, 0x28, 0x4E, 0x0C, 0x2D, 0x3F, 0x9E,
        0xCE, 0x32, 0x71, 0xC4, 0xD5, 0xE0, 0x6C, 0x48,
        0x25, 0xEA, 0x1A, 0x8F, 0x08, 0x57, 0x23, 0x85,
        0x89, 0xCD, 0xC5, 0x48, 0x37, 0x19, 0x8E, 0xD4,
        0x23, 0x4D, 0xD0, 0x31, 0x73, 0xA8, 0x8E, 0x43,
        0xEE, 0x95, 0x67, 0xF5, 0x7A, 0x93, 0x27, 0xD3,
        0x90, 0x36, 0x30, 0x4C, 0xA1, 0xCD, 0xB5, 0xF8,
        0x65, 0xC5, 0x89, 0x54, 0x57, 0x2C, 0xAE, 0xF8,
        0x75, 0xF1, 0x2E, 0x14, 0x14, 0x14, 0x0D, 0x97,
        0x5B, 0x24, 0x52, 0x46, 0x7A, 0x57, 0x6D, 0x9C,
        0x4C, 0x79, 0xDB, 0x0A, 0xE0, 0x23, 0x69, 0x52,
        0x9B, 0xF8, 0x1B, 0x54, 0x40, 0x18, 0xDF, 0xE0,
        0x1E, 0xF0, 0x61, 0xE4, 0x79, 0x81, 0xF9, 0x98,
        0x9A, 0x8C, 0x48, 0xFF, 0x86, 0x93, 0x0B, 0x68,
        0x96, 0x78, 0x2F, 0xF1, 0x2D, 0xDC, 0x60, 0x1F,
        0x8B, 0x1C, 0x04, 0x43, 0x4E, 0x60, 0x96, 0x5B,
        0x8A, 0xF6, 0x89, 0xCC, 0xC8, 0xB2, 0x9B, 0xBF,
        0x87, 0x16, 0x2E, 0xA8, 0x6F, 0x9B, 0x4B, 0xFD,
        0x74, 0x4E, 0x8F, 0x36, 0x33, 0x23, 0xDE, 0x94,
        0xD2, 0xA1, 0x72, 0x4F, 0xB2, 0xE6, 0x75, 0x3D,
        0x6E, 0x47, 0x9B, 0xDB, 0x58, 0xE5, 0x4A, 0x0C,
        0x09, 0x8F, 0x9C, 0x83, 0x63, 0x98, 0x8B, 0xA4,
        0xF7, 0x3D, 0x01, 0xA6, 0x8B, 0x93, 0x97, 0x48,
        0x84, 0x75, 0x32, 0xC7, 0xD7, 0x03, 0xDF, 0x7E,
        0x94, 0x8C, 0x8A, 0xA6, 0x78, 0x1A, 0xAE, 0xDE,
        0x36, 0x8A, 0xAD, 0x13, 0x7E, 0xF0, 0x16, 0xC2,
        0x3B, 0xAF, 0xF9, 0xD8, 0x66, 0x12, 0x30, 0x72,
        0x76, 0x6D, 0x21, 0x4C, 0xF3, 0xEF, 0x0D, 0x8C,
        0x11, 0xA4, 0x12, 0xBE, 0xF5, 0x7E, 0x8E, 0x6A,
        0x11, 0x13, 0x48, 0x8D, 0xC2, 0x62, 0xCF, 0x45,
        0x7C, 0xE3, 0x91, 0x88, 0x59, 0xFF, 0xB0, 0xF1,
        0xC3, 0xBC, 0x1D, 0x2A, 0x3E, 0x9B, 0x78, 0xF3,
        0xB1, 0x2E, 0xB0, 0x27, 0xD8, 0x16, 0xF8, 0x9B,
        0x2A, 0xAF, 0xF1, 0xAB, 0xB0, 0xF1, 0x8C, 0x7F,
        0x94, 0x31, 0x97, 0x85, 0xDA, 0xF0, 0xF4, 0x27,
        0x51, 0x3E, 0x5A, 0xE1, 0xDD, 0x6D, 0x9E, 0x98,
        0x39, 0xBB, 0xDF, 0xA2, 0xBA, 0x2C, 0x08, 0xAD,
        0x1D, 0x3F, 0x86, 0xF6, 0xC2, 0x1A, 0x8C, 0xAD,
        0xE0, 0xDC, 0xDD, 0x02, 0x47, 0x4C, 0x7E, 0x2D,
        0xDA, 0x1D, 0x70, 0x92, 0x39, 0xAA, 0x4E, 0xBA,
        0x14, 0xC7, 0xEC, 0x26, 0xBD, 0x9D, 0x1F, 0x6D,
        0x91, 0x58, 0x3C, 0xB5, 0xEF, 0x37, 0xB9, 0x66,
        0x4E, 0x04, 0x7C, 0x29, 0xCF, 0xD7, 0x8E, 0x47,
        0x84, 0xF3, 0xD2, 0x21, 0x84, 0xC5, 0xF8, 0xDC,
        0xC9, 0xF2, 0x52, 0xD5, 0x6A, 0xBF, 0xF1, 0xF1,
        0xDE, 0x9E, 0x7A, 0xF1, 0xD5, 0x5A, 0xF6, 0xEF,
        0x94, 0x66, 0xF9, 0x25, 0x44, 0x7F, 0x8D, 0x92,
        0xA2, 0x25, 0x1C, 0x72, 0x92, 0x30, 0x2A, 0xB7,
        0xEF, 0x18, 0xF3, 0x8C, 0xEF, 0x69, 0xA5, 0x5C,
        0x19, 0x3E, 0xC5, 0xBD, 0xEE, 0x2C, 0x2D, 0x71,
        0xDB, 0x89, 0xD4, 0x11, 0xA6, 0x27, 0x80, 0x8F,
        0x5A, 0x39, 0x9A, 0x04, 0x28, 0x4F, 0x9F, 0x00,
        0xBE, 0xF9, 0xF7, 0x9B, 0x46, 0x69, 0xD6, 0xAC,
        0x12, 0xE9, 0xA7, 0xC2, 0xD1, 0xC8, 0xAD, 0x5D,
        0xF7, 0xCB, 0x0C, 0x98, 0x78, 0x2D, 0x04, 0x4D,
        0x2D, 0x41, 0xAB, 0xC6, 0x3F, 0x81, 0x1D, 0xB9,
        0x2C, 0x1F, 0x3F, 0x59, 0x11, 0xF4, 0x80, 0x4F,
        0x0B, 0xCA, 0x9F, 0x81, 0x6E, 0x9C, 0xD1, 0xB4,
        0x74, 0x06, 0x48, 0x0A, 0x87, 0x2C, 0xFD, 0x4D,
        0x85, 0xD4, 0x21, 0x65, 0x7C, 0x96, 0x69, 0x53,
        0x51, 0xC0, 0xC4, 0xB0, 0xEB, 0x20, 0xDB, 0xE0,
        0x41, 0x09, 0xA7, 0x62, 0xB2, 0xF3, 0xC7, 0x6A,
        0x1D, 0x53, 0xA0, 0x39, 0xBA, 0xCF, 0x78, 0x9E,
        0xBF, 0x1D, 0xA5, 0x98, 0x09, 0x8E, 0xA7, 0x1A,
        0xE7, 0x95, 0xFF, 0x10, 0x38, 0xCC, 0x8F, 0x44,
        0xCB, 0xE7, 0xF6, 0xD6, 0x2C, 0xFF, 0xA8, 0x1C,
        0xFF, 0xA3, 0x65, 0xE8, 0x4E, 0xAE, 0xC7, 0xEF,
        0x61, 0xE1, 0x16, 0x4B, 0x8C, 0xA8, 0xC8, 0xFB,
        0xA5, 0x2C, 0xD1, 0x0A, 0x39, 0xAB, 0x4A, 0xF9,
        0xEE, 0x0B, 0x9B, 0xB4, 0x33, 0x5E, 0x25, 0x15,
        0xD0, 0xAA, 0x93, 0xC4, 0x53, 0x42, 0x91, 0xC5,
        0x98, 0x15, 0x34, 0x9A, 0x22, 0x1D, 0x9A, 0xE7,
        0x0E, 0x81, 0xF6, 0x99, 0x55, 0xB3, 0xD6, 0x49,
        0x1B, 0xB8, 0xA8, 0xBE, 0xDF, 0x54, 0xF0, 0x78,
        0xF7, 0x02, 0x97, 0x74, 0x84, 0x67, 0x6B, 0xAE,
        0x2F, 0xEC, 0x6E, 0x59, 0x20, 0x68, 0xD8, 0xE3,
        0x5A, 0x07, 0x48, 0xE1, 0x99, 0x90, 0xEE, 0xCD,
        0x17, 0x2B, 0xB6, 0xD6, 0xAA, 0x1A, 0xF8, 0x97,
        0x4E, 0xE0, 0x67, 0x9E, 0x4C, 0x35, 0xFE, 0x68,
        0x71, 0x54, 0x43, 0x5D, 0x43, 0x59, 0x19, 0xEB,
        0x58, 0x8E, 0x9A, 0xF6, 0xBD, 0x88, 0x71, 0xEE,
        0x89, 0xC6, 0xF2, 0x10, 0x04, 0x33, 0x13, 0x88,
        0xCD, 0x08, 0xB5, 0xE3, 0x5D, 0xA8, 0xBC, 0x43,
        0xB3, 0x84, 0x5F, 0x70, 0x94, 0xD9, 0xAC, 0xAE,
        0x74, 0x70, 0x13, 0x1E, 0x21, 0xFB, 0xD5, 0x7F,
        0xEC, 0x66, 0x2F, 0xA0, 0xB1, 0x1D, 0xE3, 0xF8,
        0xB9, 0x36, 0x48, 0x25, 0x3D, 0xBA, 0x7D, 0x44,
        0x08, 0xC5, 0x71, 0x74, 0xDA, 0xD3, 0x4F, 0x97,
        0x86, 0xF1, 0x16, 0x38, 0xD8, 0xC9, 0xE3, 0x3A,
        0xA7, 0x2E, 0x06, 0x4D, 0x9D, 0xE8, 0xFC, 0x38,
        0x58, 0x2A, 0x8D, 0x2D, 0x07, 0x99, 0xEA, 0xDF,
        0xF3, 0x00, 0x3B, 0xBC, 0x5F, 0x67, 0x1E, 0x4B,
        0x6C, 0xF1, 0x4A, 0x47, 0xB0, 0x71, 0x90, 0x5A,
        0x3B, 0x75, 0x93, 0x75, 0x56, 0x50, 0x4C, 0x70,
        0xF3, 0xC7, 0x95, 0xD5, 0xEA, 0xCB, 0x4C, 0x92,
        0x4F, 0x22, 0x4F, 0xD9, 0x34, 0x46, 0x76, 0xFB,
        0x79, 0xD6, 0xBD, 0x4E, 0x84, 0xEE, 0xE7, 0x78,
        0x7C, 0xB8, 0x92, 0x9F, 0xAD, 0xF2, 0x17, 0x5D,
        0x38, 0xB1, 0x88, 0x2E, 0xE9, 0x65, 0xAC, 0x4C,
        0x24, 0x27, 0x1D, 0x7B, 0xA3, 0x69, 0x96, 0x55,
        0x5C, 0x26, 0x40, 0xAF, 0x04, 0xB1, 0xCE, 0xA8,
        0x5D, 0x1E, 0x1F, 0xE5, 0x5A, 0xC3, 0xAE, 0xF9,
        0x14, 0x03, 0x58, 0x10, 0x1C, 0x8B, 0x1F, 0xDB,
        0x6C, 0x71, 0x68, 0x60, 0x13, 0x32, 0xF1, 0xA9,
        0x69, 0x45, 0x28, 0x69, 0x7C, 0xE3, 0xC9, 0x56,
        0xAF, 0xF3, 0xBD, 0x4B, 0x9E, 0x0A, 0x06, 0x6A,
        0x62, 0x20, 0x40, 0x65, 0xBD, 0xBC, 0xBF, 0xC7,
        0x0A, 0x2A, 0xCF, 0x56, 0x7C, 0x0E, 0x64, 0xBB,
        0x64, 0x71, 0x2D, 0x90, 0xBB, 0x32, 0x00, 0x0A,
        0x4A, 0x45, 0x44, 0x08, 0x75, 0x2C, 0x86, 0x13,
        0x86, 0x52, 0x8D, 0x3D, 0xFC, 0xF3, 0x5E, 0x5B,
        0x3F, 0x7A, 0xAA, 0x98, 0x84, 0xCF, 0x92, 0xF9,
        0x0B, 0x40, 0x8F, 0xC0, 0xA3, 0x71, 0x84, 0xAD,
        0xEE, 0xDF, 0xC4, 0x91, 0x7E, 0x87, 0x7D, 0x06,
        0xCA, 0x65, 0x8C, 0xE4, 0x8E, 0x03, 0xF0, 0x59,
        0x3E, 0xB4, 0x90, 0x4C, 0xEE, 0x88, 0x29, 0xE4,
        0x26, 0x7D, 0xA6, 0x54, 0x82, 0x49, 0xC1, 0x9D,
        0x80, 0xAB, 0x6B, 0xD7, 0xBE, 0x7D, 0x09, 0x80,
        0x5E, 0xB6, 0xD1, 0x1E, 0xD1, 0x1B, 0xE9, 0x8D,
        0xFC, 0x6E, 0x9C, 0x14, 0x0C, 0x15, 0x02, 0x87,
        0xF3, 0x9D, 0x21, 0xF8, 0xCB, 0xC8, 0xB9, 0xBD,
        0xE1, 0x70, 0xEA, 0xE4, 0x86, 0x4C, 0x97, 0xC1,
        0xEE, 0x4C, 0x18, 0x95, 0xEC, 0xD2, 0x4D, 0x35,
        0x9F, 0xC6, 0x56, 0x10, 0x3E, 0xC0, 0xB9, 0x7B,
        0x13, 0x1A, 0x37, 0x3D, 0x40, 0x4C, 0x88, 0x8B,
        0x9A, 0xA5, 0xB2, 0xB8, 0xB9, 0xC3, 0xEC, 0xF1,
        0x14, 0x33, 0x63, 0x67, 0x84, 0x98, 0xC8, 0xF4,
        0x06, 0x0C, 0x0E, 0x0F, 0x10, 0x12, 0x15, 0x16,
        0x45, 0x4E, 0x55, 0x5A, 0x5F, 0x8A, 0x94, 0x97,
        0xA8, 0xAF, 0xB2, 0xCC, 0xD4, 0xDC, 0xE7, 0xF1,
        0xFE, 0xFF, 0x11, 0x24, 0x53, 0x62, 0x94, 0xB7,
        0xB9, 0xD3, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x10, 0x18, 0x32, 0x3B
    };
#endif
#ifndef WOLFSSL_NO_ML_DSA_65
    static const byte pk_65_draft[] = {
        0x6C, 0x84, 0x14, 0x38, 0x08, 0x56, 0xCB, 0x52,
        0xD7, 0x9C, 0x4B, 0x29, 0x13, 0x9F, 0xB1, 0x83,
        0x9B, 0x86, 0x06, 0xF5, 0x94, 0x8B, 0x9D, 0x72,
        0xA9, 0x56, 0xDC, 0xF1, 0x01, 0x16, 0xDA, 0x9E,
        0x2D, 0x79, 0x77, 0x01, 0x86, 0xFC, 0x74, 0xD9,
        0x42, 0xC0, 0xF4, 0xA3, 0xB5, 0x95, 0xFF, 0x6C,
        0x19, 0x80, 0x4B, 0x49, 0x90, 0x1C, 0x6A, 0xD5,
        0xFA, 0xF7, 0x16, 0x01, 0xC2, 0xB6, 0x00, 0x31,
        0x5E, 0x1F, 0x40, 0xC2, 0x05, 0x47, 0x67, 0xB0,
        0x09, 0x25, 0xDF, 0x3A, 0xA4, 0x90, 0xE8, 0xC7,
        0x6F, 0x05, 0xFB, 0xFB, 0x74, 0x91, 0x10, 0x75,
        0xE6, 0x51, 0x8C, 0x5F, 0x1D, 0x91, 0xB8, 0xA0,
        0xE5, 0xB5, 0x98, 0x30, 0xD3, 0xDF, 0x39, 0x94,
        0x76, 0x04, 0x11, 0xEB, 0xB9, 0x11, 0xED, 0x4C,
        0xC2, 0xC1, 0x60, 0xE3, 0x84, 0x9A, 0x93, 0x76,
        0x2D, 0xFC, 0xA7, 0xB9, 0x81, 0x2B, 0xC7, 0xAE,
        0xB2, 0xDD, 0xB2, 0x76, 0x7B, 0xEF, 0x36, 0x50,
        0x56, 0x05, 0xAE, 0x06, 0x92, 0x60, 0xBC, 0xC8,
        0xDC, 0x47, 0x87, 0xC4, 0x28, 0xCB, 0x3C, 0x07,
        0x6E, 0xF2, 0xA6, 0xB9, 0x35, 0x61, 0xD8, 0x94,
        0x3F, 0x45, 0xCA, 0xBE, 0x8F, 0x05, 0x53, 0xFF,
        0x2E, 0xA1, 0xAC, 0x95, 0xC1, 0xCE, 0x21, 0x59,
        0x3A, 0x17, 0x54, 0x59, 0xD7, 0xDF, 0x12, 0xC4,
        0x07, 0x0A, 0xDB, 0x0E, 0xEE, 0x55, 0xB4, 0xAB,
        0xAE, 0x59, 0xBE, 0x69, 0xC3, 0xFF, 0x0D, 0xE5,
        0xA9, 0xB0, 0x27, 0xFC, 0x7D, 0x8E, 0x6E, 0x05,
        0x7B, 0x71, 0x52, 0xEE, 0x6A, 0xB4, 0x80, 0xD1,
        0x05, 0xD3, 0x0B, 0x0F, 0x50, 0x51, 0xB6, 0x0C,
        0x79, 0x01, 0xC5, 0x25, 0xC4, 0x63, 0x5F, 0xE6,
        0x68, 0xCC, 0x00, 0xE9, 0xD3, 0x09, 0x7D, 0xB9,
        0x9D, 0x66, 0x32, 0x37, 0x15, 0xCE, 0x4F, 0x0B,
        0x79, 0xB4, 0x26, 0xB4, 0x54, 0x5E, 0x09, 0xF4,
        0xDE, 0x39, 0x32, 0x3D, 0xD1, 0x4C, 0xCB, 0x0D,
        0x17, 0x10, 0x8C, 0xD4, 0x6D, 0xEC, 0x61, 0x38,
        0xCD, 0xFA, 0x28, 0x72, 0xC1, 0xC4, 0xC8, 0xAE,
        0xAD, 0x5C, 0x8C, 0xE0, 0x41, 0x57, 0xE5, 0x53,
        0xA3, 0x75, 0x58, 0xC2, 0x34, 0x6A, 0x06, 0x19,
        0x4C, 0xB5, 0x0B, 0x49, 0x81, 0xBF, 0x4D, 0x09,
        0x0C, 0xE4, 0xE8, 0x60, 0x12, 0x6A, 0x82, 0x54,
        0xA4, 0xD4, 0xC0, 0x84, 0xC3, 0xE2, 0x02, 0x0B,
        0xC0, 0x75, 0x35, 0x21, 0x04, 0x9B, 0x0F, 0xD8,
        0x89, 0x97, 0xE0, 0x27, 0xAC, 0x51, 0xE7, 0x5C,
        0xF1, 0x35, 0x0C, 0x3F, 0x30, 0x3A, 0x0E, 0xCE,
        0x42, 0x64, 0x87, 0x15, 0x3D, 0xAF, 0x1F, 0xAA,
        0xD6, 0x80, 0x8B, 0x9D, 0x99, 0x07, 0xDA, 0x9F,
        0x35, 0x18, 0x5B, 0xD3, 0xBE, 0x8D, 0x9C, 0xEB,
        0xE9, 0x16, 0xCE, 0xD1, 0xFA, 0x29, 0x28, 0xD8,
        0x85, 0xA9, 0xCB, 0xA8, 0x81, 0x49, 0x70, 0x3F,
        0x5E, 0x47, 0x72, 0xE4, 0x85, 0x23, 0x12, 0x5D,
        0xDD, 0x02, 0x6E, 0x71, 0x4C, 0x49, 0xF4, 0xFB,
        0x4E, 0x54, 0x4B, 0xBF, 0x61, 0x7A, 0x40, 0xB0,
        0x0B, 0x68, 0xDF, 0x8F, 0x15, 0x5F, 0x58, 0x80,
        0xD4, 0x11, 0x87, 0x7E, 0x25, 0xB4, 0x2B, 0x24,
        0x48, 0xB3, 0x6B, 0xEC, 0x2F, 0x1F, 0x8F, 0x9A,
        0x77, 0x0C, 0x54, 0x51, 0x50, 0xA0, 0x27, 0x8E,
        0x9B, 0x72, 0x45, 0x00, 0xAE, 0xAA, 0xEA, 0x47,
        0x1C, 0x11, 0xCF, 0xF0, 0x4E, 0x30, 0xEA, 0xB2,
        0xF4, 0x73, 0xBC, 0x04, 0x8E, 0x32, 0xCD, 0x31,
        0xAE, 0xF2, 0x15, 0x79, 0xB6, 0x99, 0x22, 0x5B,
        0xF9, 0xE1, 0xB6, 0x70, 0x0C, 0x57, 0xE5, 0x09,
        0xFC, 0xA1, 0xF2, 0x36, 0x29, 0x4A, 0x59, 0x74,
        0xDA, 0xA1, 0x5F, 0xBC, 0xAD, 0x62, 0xD4, 0xBD,
        0xDC, 0x45, 0x32, 0xB2, 0x61, 0x41, 0x44, 0xDB,
        0xE2, 0x88, 0x07, 0x36, 0x8C, 0x28, 0x1A, 0x77,
        0x0E, 0xA2, 0x2B, 0x1E, 0x5A, 0x3F, 0xA5, 0xBA,
        0x14, 0x92, 0x6D, 0xC5, 0x5A, 0x54, 0xF8, 0x4A,
        0x2A, 0x77, 0xC5, 0xA7, 0x08, 0x41, 0xF0, 0x7B,
        0xC1, 0xDE, 0xEF, 0x74, 0x03, 0xB2, 0x47, 0xAB,
        0x42, 0xB8, 0x4A, 0xDF, 0x14, 0x1E, 0x03, 0x0C,
        0x98, 0x46, 0x84, 0x24, 0xDA, 0xAE, 0xB9, 0x9D,
        0x25, 0x77, 0xF9, 0x50, 0xC2, 0x37, 0x3C, 0xCA,
        0x1E, 0x2D, 0xC2, 0x76, 0x1B, 0x8E, 0xDD, 0x6D,
        0x08, 0xFF, 0x79, 0xE5, 0x28, 0x88, 0x0F, 0xFB,
        0x51, 0xC3, 0x6E, 0xD4, 0x20, 0xAC, 0x5D, 0x50,
        0xF2, 0x58, 0x2A, 0xA6, 0x64, 0xE5, 0x4E, 0xA5,
        0xF4, 0x18, 0x9E, 0xA0, 0x17, 0x6D, 0xAA, 0x61,
        0x22, 0xF6, 0x23, 0x5A, 0x70, 0xB1, 0x5C, 0xEB,
        0x4D, 0xDD, 0x65, 0xD3, 0xBE, 0x6E, 0xBF, 0x3D,
        0xC4, 0x31, 0x89, 0xEE, 0x0A, 0x2E, 0x31, 0x05,
        0x63, 0x8F, 0x23, 0x87, 0x36, 0x95, 0x28, 0x0F,
        0x1B, 0x74, 0x27, 0x43, 0x52, 0xD6, 0x0A, 0x48,
        0xE5, 0xD3, 0xDD, 0x02, 0xFB, 0x7A, 0x5E, 0xD8,
        0x3F, 0xE2, 0x7A, 0x69, 0x82, 0x51, 0x42, 0x1C,
        0x8E, 0x9C, 0x98, 0x80, 0x61, 0x02, 0x39, 0x6E,
        0x53, 0x73, 0x90, 0xAC, 0xFD, 0x8C, 0x1D, 0x0B,
        0x4F, 0x99, 0xB7, 0x02, 0xA9, 0xEA, 0x65, 0x98,
        0x78, 0x58, 0x3D, 0x92, 0x75, 0x89, 0x41, 0xB3,
        0x0E, 0xCE, 0x50, 0x7C, 0x10, 0x4B, 0x2C, 0xE4,
        0x87, 0x67, 0x9E, 0xCF, 0x68, 0xB4, 0xD8, 0xB9,
        0x80, 0x69, 0x8A, 0xCF, 0x6A, 0xA6, 0xA5, 0x7E,
        0x8E, 0xD6, 0xAF, 0x3F, 0xF1, 0x8D, 0x26, 0x68,
        0x95, 0x04, 0x28, 0xB5, 0x7D, 0x18, 0x2F, 0x73,
        0xBB, 0x49, 0xB9, 0xB0, 0x38, 0xCC, 0xC8, 0x2D,
        0x56, 0x12, 0x78, 0xA3, 0x86, 0xD5, 0x66, 0x45,
        0xEC, 0x3F, 0xAF, 0xFB, 0x41, 0x25, 0xE0, 0xE7,
        0xF3, 0x6B, 0x48, 0xB1, 0x4B, 0x45, 0x25, 0x47,
        0xA0, 0xB4, 0x81, 0xAA, 0x6B, 0x33, 0x42, 0x29,
        0x24, 0x91, 0x53, 0xE4, 0x2E, 0xDF, 0x7E, 0x49,
        0xDD, 0x6E, 0x76, 0x36, 0xBF, 0xC6, 0x15, 0xA2,
        0x3A, 0x40, 0x1E, 0xFD, 0x40, 0x34, 0xC8, 0x1B,
        0x4D, 0xCE, 0xF0, 0x27, 0xD3, 0x44, 0xDD, 0xCC,
        0xE0, 0xA7, 0x16, 0x18, 0xEB, 0x59, 0x10, 0xCE,
        0xC6, 0x22, 0x28, 0x81, 0x93, 0x85, 0x03, 0x3E,
        0x8D, 0x0A, 0xBD, 0x49, 0x3D, 0x98, 0x3E, 0x4F,
        0xC0, 0x87, 0xD7, 0x2B, 0x45, 0x5E, 0x4D, 0xB6,
        0x3A, 0x2F, 0x82, 0xCE, 0xFF, 0x65, 0xC1, 0xE6,
        0x28, 0xEA, 0xE6, 0x30, 0x59, 0x6D, 0xEC, 0x27,
        0xFB, 0x98, 0xB8, 0x4D, 0xBF, 0xDC, 0xDF, 0xAB,
        0x40, 0xE4, 0x72, 0x24, 0x49, 0x14, 0xAF, 0xF1,
        0x79, 0x32, 0x6D, 0x54, 0x2D, 0x40, 0x1A, 0x3C,
        0xBB, 0x86, 0xE5, 0xFF, 0x83, 0x51, 0xEF, 0xE5,
        0x3A, 0x73, 0xC5, 0x1A, 0xBB, 0x63, 0xFF, 0x55,
        0x3E, 0x7D, 0x79, 0x57, 0xEF, 0x89, 0x13, 0x5E,
        0x0F, 0x5B, 0xB1, 0xBD, 0x0C, 0x24, 0xF9, 0xE4,
        0x5E, 0x32, 0x36, 0x41, 0x3C, 0x60, 0xE1, 0x39,
        0x6A, 0x47, 0x56, 0x7C, 0x94, 0x39, 0x51, 0x0F,
        0x00, 0xD4, 0xA4, 0x3C, 0x14, 0x9A, 0x5C, 0xCC,
        0x04, 0xF3, 0xD4, 0x7E, 0x67, 0xA8, 0xE2, 0x94,
        0xA4, 0x61, 0xA5, 0xF6, 0x93, 0xDB, 0x0C, 0xAE,
        0x22, 0xCF, 0xAC, 0x61, 0xE8, 0x53, 0x47, 0x7D,
        0x33, 0x9A, 0x4E, 0x45, 0xF7, 0xB1, 0x7C, 0x3C,
        0x11, 0x6D, 0x56, 0xF3, 0xA0, 0x68, 0xFC, 0x5A,
        0xDF, 0xEF, 0x38, 0xFF, 0x85, 0x33, 0x2B, 0xD5,
        0x15, 0x3C, 0x4D, 0x8F, 0xB8, 0xF1, 0x48, 0xF1,
        0x17, 0x65, 0x9C, 0x2E, 0xA9, 0x4D, 0xB4, 0x2A,
        0xA0, 0xB0, 0xBE, 0xBB, 0x47, 0x5A, 0x11, 0x04,
        0x12, 0xF3, 0xCD, 0x33, 0x49, 0xFC, 0x1A, 0xD0,
        0x41, 0xB7, 0xD5, 0x30, 0x4A, 0x85, 0x93, 0x14,
        0x4E, 0xFA, 0x3A, 0x36, 0x1D, 0x1B, 0x0C, 0x76,
        0x13, 0xB8, 0x2C, 0x08, 0x6E, 0xA7, 0x12, 0x6E,
        0x43, 0xC6, 0x16, 0xCE, 0xE8, 0xF1, 0x44, 0x4E,
        0x99, 0x56, 0xE8, 0x7F, 0x5C, 0xAB, 0x95, 0xC7,
        0xC7, 0xFB, 0x17, 0x58, 0xEC, 0x7D, 0x97, 0x01,
        0x9E, 0x5B, 0xA9, 0x35, 0x43, 0xEF, 0x3B, 0xAC,
        0x1A, 0x17, 0x42, 0x99, 0xCA, 0x48, 0xBF, 0x78,
        0x59, 0xDB, 0xFB, 0xDF, 0xF2, 0x43, 0xB1, 0x14,
        0xF6, 0xBF, 0x42, 0x3C, 0xE9, 0x8B, 0x4D, 0x4D,
        0x09, 0x1D, 0xA4, 0x4F, 0x32, 0x74, 0xD5, 0x73,
        0xFD, 0xC9, 0x04, 0xBD, 0x88, 0x5E, 0x35, 0xC9,
        0x15, 0x2A, 0x65, 0x35, 0x48, 0x88, 0xF1, 0x1E,
        0xD4, 0xF3, 0xD6, 0x3F, 0x26, 0xA7, 0xBE, 0x2F,
        0x57, 0x26, 0xEA, 0xDA, 0xF4, 0x85, 0x86, 0x59,
        0x2B, 0xBD, 0xF6, 0xCE, 0xE2, 0x46, 0x76, 0x9E,
        0x0E, 0xDA, 0x2A, 0x80, 0x77, 0x1F, 0xED, 0x34,
        0x7D, 0x67, 0xAF, 0xEE, 0xC6, 0x8B, 0x89, 0x46,
        0x3F, 0xA0, 0x49, 0x6D, 0xBC, 0x15, 0xC8, 0x9E,
        0x8D, 0x56, 0x99, 0x83, 0xD1, 0xD6, 0x74, 0x73,
        0x3F, 0x2B, 0xF9, 0xDF, 0x4A, 0x98, 0x0E, 0xA8,
        0xC5, 0xE3, 0xAF, 0x15, 0x56, 0x0A, 0x0E, 0x28,
        0xD6, 0x72, 0xB5, 0x80, 0xAB, 0x65, 0x52, 0xED,
        0x76, 0xAA, 0xCB, 0x5F, 0x80, 0x26, 0x0B, 0x97,
        0x03, 0x76, 0x9D, 0x33, 0xF4, 0x13, 0x8A, 0xBC,
        0x10, 0xBF, 0x5B, 0x05, 0x82, 0xDC, 0xC6, 0x2D,
        0xBE, 0x58, 0xC8, 0x90, 0xF5, 0x1B, 0x41, 0x00,
        0x12, 0x77, 0x34, 0xFB, 0x7D, 0xB7, 0x44, 0x7A,
        0x72, 0x0A, 0xAE, 0x00, 0x9D, 0x00, 0xBE, 0x8C,
        0x61, 0x07, 0x92, 0xC6, 0x4F, 0x13, 0x1F, 0x2D,
        0x72, 0x11, 0x5C, 0x7E, 0x05, 0x8E, 0x48, 0xB9,
        0xDE, 0x64, 0xF5, 0x5B, 0x4D, 0x61, 0x0C, 0x36,
        0xD1, 0x12, 0x71, 0x6A, 0x31, 0xA3, 0xDF, 0xE2,
        0x66, 0x99, 0xE9, 0xC2, 0xAB, 0xA0, 0x56, 0x58,
        0xCE, 0xF1, 0xB2, 0xB0, 0x86, 0x7C, 0xF8, 0xD5,
        0x23, 0x3D, 0xB7, 0x4F, 0xA8, 0xDC, 0x3A, 0xD1,
        0x45, 0xF5, 0xD2, 0x85, 0x74, 0x36, 0x0A, 0x85,
        0xE3, 0xB0, 0xB1, 0x0A, 0xC0, 0xA6, 0x46, 0x7A,
        0x7B, 0x05, 0x98, 0x46, 0x28, 0xEC, 0xA1, 0x04,
        0x63, 0xF3, 0x48, 0xA3, 0x11, 0x1E, 0x00, 0x57,
        0x8D, 0x3C, 0xE5, 0x48, 0x0F, 0x53, 0x75, 0xA1,
        0xEE, 0x23, 0xEE, 0x82, 0x08, 0x7B, 0xAC, 0x41,
        0x23, 0x3A, 0x14, 0xAA, 0xA7, 0x24, 0x73, 0x4B,
        0x18, 0x74, 0xA4, 0xAC, 0xE1, 0x13, 0x37, 0x06,
        0x25, 0x8F, 0x5F, 0xEA, 0x3A, 0x0C, 0x16, 0x09,
        0xE3, 0x0C, 0x7F, 0xD2, 0x10, 0xDA, 0x0C, 0x4F,
        0xDE, 0x91, 0x62, 0xDF, 0x66, 0xFB, 0xAF, 0x79,
        0x2F, 0xA2, 0xAE, 0xAA, 0x51, 0x2F, 0x0F, 0xF7,
        0x83, 0x7B, 0x9C, 0xC0, 0x2E, 0xE9, 0xBD, 0x95,
        0x53, 0x9F, 0x00, 0x1B, 0xBD, 0x60, 0xDD, 0x8B,
        0x42, 0xD6, 0x16, 0xB2, 0xCA, 0x95, 0xF3, 0x83,
        0x5F, 0x5E, 0x47, 0xD4, 0x3B, 0x14, 0x34, 0xC4,
        0x56, 0x3F, 0xD8, 0x1C, 0x15, 0xBE, 0xFA, 0x20,
        0x2C, 0xF3, 0xD9, 0x54, 0x08, 0x73, 0xF6, 0x84,
        0xAF, 0xE1, 0x9A, 0xB5, 0xC0, 0x1F, 0xA9, 0x2E,
        0x95, 0xA8, 0xCD, 0x6F, 0x36, 0x07, 0x30, 0x85,
        0x6E, 0x59, 0xC9, 0xC6, 0xAB, 0x77, 0x0D, 0x65,
        0x75, 0x96, 0x2A, 0xF7, 0x58, 0x78, 0x57, 0x2A,
        0x2A, 0x26, 0x41, 0x3D, 0x01, 0xAB, 0x31, 0x8C,
        0x10, 0x0D, 0xFC, 0x34, 0xDC, 0x1D, 0xEF, 0xA5,
        0x92, 0x7C, 0x4B, 0x45, 0x99, 0x25, 0xD7, 0x3E,
        0x1E, 0xB9, 0x14, 0x70, 0xE3, 0x7A, 0x58, 0x45,
        0x5C, 0x22, 0xA9, 0x61, 0xFD, 0x53, 0xF7, 0xD9,
        0x90, 0x26, 0xFF, 0x88, 0x4B, 0xF4, 0xA2, 0x57,
        0x9F, 0x70, 0x63, 0x35, 0xEF, 0xB6, 0xFB, 0x22,
        0x50, 0xD5, 0x2A, 0xE5, 0x61, 0x89, 0x8B, 0xA1,
        0x60, 0x6E, 0x51, 0xE9, 0x6D, 0x37, 0xC9, 0xED,
        0x3E, 0xC6, 0xCF, 0xCB, 0x33, 0xBF, 0xBE, 0x9C,
        0x31, 0x43, 0xFD, 0x3B, 0x6B, 0x33, 0x4D, 0x5F,
        0x61, 0x92, 0x2B, 0x36, 0x9A, 0xFB, 0xB3, 0x1C,
        0x3E, 0x6E, 0x9B, 0x5F, 0x3A, 0xEB, 0xF9, 0x5C,
        0xB7, 0x08, 0x34, 0x6F, 0xEC, 0xF7, 0x15, 0x9C,
        0xAD, 0x94, 0xA9, 0x3D, 0x8C, 0xD4, 0xB8, 0xC4,
        0x89, 0x41, 0x92, 0xDF, 0xE5, 0x3E, 0xA4, 0x36,
        0xFB, 0xF3, 0xAF, 0x4E, 0x86, 0x4E, 0x8C, 0x39,
        0x91, 0xEA, 0x02, 0x0A, 0x81, 0x1F, 0x0A, 0xF5,
        0x0B, 0x42, 0x57, 0x43, 0x6A, 0x3F, 0xF5, 0x22,
        0xBE, 0x73, 0x67, 0x39, 0x1D, 0x0F, 0x95, 0x0B,
        0xA6, 0x45, 0x2F, 0xBF, 0xD8, 0xFD, 0x87, 0x28,
        0xF4, 0x0B, 0xD2, 0xFC, 0xB8, 0x94, 0x52, 0x99,
        0x85, 0xB4, 0x32, 0xDF, 0xEF, 0x62, 0x30, 0xEB,
        0x4D, 0xEE, 0x73, 0x7A, 0x8D, 0x10, 0xA3, 0xBC,
        0xDF, 0xB7, 0x63, 0xE0, 0x86, 0x9B, 0x22, 0x5C,
        0x1A, 0x8D, 0x0E, 0x1F, 0xBF, 0x2D, 0x16, 0x1C,
        0x2C, 0x65, 0xD6, 0xDF, 0xB9, 0x58, 0xE9, 0x82,
        0xD1, 0x17, 0x77, 0xAC, 0xBE, 0xAD, 0x8D, 0xFB,
        0x6B, 0x1F, 0x5E, 0xB2, 0x1E, 0xA9, 0x42, 0xF7,
        0xC4, 0x0D, 0xC2, 0x0D, 0x2E, 0x4E, 0xB3, 0xE7,
        0x29, 0xB4, 0xE2, 0x9F, 0x75, 0x01, 0xDA, 0x34,
        0x23, 0x45, 0x61, 0xF6, 0x28, 0x88, 0x12, 0xD6,
        0x12, 0xD4, 0x1D, 0xFA, 0x83, 0xC5, 0xB8, 0xD9,
        0x0F, 0xF3, 0x8B, 0xA5, 0x48, 0x20, 0x1B, 0x57,
        0x5B, 0x52, 0x93, 0xAD, 0x78, 0x12, 0x0D, 0x91,
        0xCE, 0xC0, 0x59, 0xCA, 0xE2, 0xE7, 0x6A, 0x9A,
        0xB4, 0x3E, 0xF1, 0x28, 0x1E, 0x2B, 0xEF, 0x3E,
        0x34, 0x8D, 0x28, 0xF2, 0x19, 0x47, 0xC8, 0x88,
        0x48, 0x96, 0x04, 0x59, 0x48, 0x97, 0x75, 0x17,
        0x6F, 0x8E, 0x40, 0xEE, 0x06, 0x42, 0x79, 0x53,
        0x68, 0x7F, 0xB6, 0x3E, 0x47, 0x0F, 0x7D, 0x59,
        0xFB, 0x60, 0xDF, 0x56, 0x9F, 0x8A, 0x11, 0xE2,
        0x8E, 0x09, 0x37, 0x16, 0x2C, 0x46, 0xAF, 0xC7,
        0xD2, 0x21, 0x0A, 0x88, 0x5F, 0xFA, 0x21, 0xB3,
        0xDB, 0xF5, 0x35, 0x4B, 0x29, 0x41, 0xF4, 0xED,
        0x5D, 0x50, 0x79, 0x08, 0x90, 0x84, 0x0C, 0xC3,
        0xB9, 0x73, 0xD2, 0xC3, 0xD0, 0x26, 0x02, 0xB2,
        0x9B, 0xAC, 0xCB, 0x6C, 0xE1, 0x7C, 0xED, 0xB9,
        0x7B, 0x08, 0x5A, 0x2A, 0xB3, 0x10, 0x57, 0x2B,
        0xA7, 0x37, 0x1D, 0x1F, 0x81, 0x20, 0xFF, 0xE3,
        0x7D, 0x0B, 0x0F, 0xCA, 0x35, 0xAF, 0xC5, 0xB5,
        0x62, 0xAA, 0x84, 0x99, 0x71, 0x5A, 0x29, 0x9C,
        0xE0, 0x59, 0xCC, 0xE3, 0xB0, 0xD1, 0x1C, 0xEF,
        0x0D, 0x92, 0x38, 0x96, 0x1A, 0xD4, 0xBE, 0x11,
        0xE9, 0xA6, 0xD1, 0xA4, 0x69, 0x21, 0x77, 0xC8,
        0xB0, 0xC5, 0x3F, 0x11, 0xA8, 0xED, 0x26, 0x50,
        0x21, 0x2E, 0x7A, 0x2F, 0x80, 0xEB, 0xFF, 0x6D,
        0xCF, 0xE4, 0x67, 0x21, 0x03, 0x65, 0x84, 0x34,
        0xD0, 0x32, 0x7A, 0xDD, 0xCD, 0x66, 0xBC, 0xB6
    };
    static const byte msg_65_draft[] = {
        0xDB, 0x84, 0x94, 0xBA, 0x19, 0xC4, 0x11, 0x8F,
        0xB1, 0x5D, 0x0A, 0xCF, 0x42, 0x54, 0xFD, 0x37,
        0x48, 0x3F, 0xCF, 0x47, 0x48, 0xFD, 0x18, 0x44,
        0xF7, 0x17, 0xCE, 0x6F, 0x69, 0x58, 0x9E, 0x61,
        0x77, 0x2C, 0xFE, 0xFA, 0x7F, 0x97, 0x58, 0x65,
        0x34, 0x09, 0xD4, 0xEE, 0x5A, 0x26, 0x4B, 0x83,
        0x4E, 0x60, 0xD6, 0xBB, 0x96, 0x49, 0x9E, 0xBE,
        0xB2, 0xB0, 0x6B, 0x0B, 0xA8, 0x74, 0xBF, 0x31,
        0xE6, 0x41, 0x39, 0x4C, 0xFA, 0xA6, 0xA2, 0xD3,
        0x0D, 0xDB, 0x8F, 0x04, 0x58, 0x76, 0x20, 0x8D,
        0x2F, 0x51, 0xDE, 0x15, 0xE2, 0x05, 0xE8, 0xC9,
        0x1B, 0x87, 0xEC, 0xEB, 0x05, 0xFF, 0x31, 0x83,
        0x27, 0x1B, 0x26, 0x49, 0x66, 0x5D, 0xD3, 0xCC,
        0x49, 0xBF, 0xDB, 0x99, 0x8D, 0x53, 0x9D, 0xA8,
        0x09, 0x30, 0x55, 0x16, 0xBB, 0xBE, 0x9C, 0x90,
        0x60, 0x21, 0x19, 0x1C, 0x52, 0x23, 0xE5, 0x25,
        0xA8, 0xFC, 0x36, 0x16, 0xA1, 0x76, 0x5E, 0xC3,
        0xF9, 0xC5, 0xDB, 0x53, 0xCC, 0x33, 0x7E, 0x03,
        0x9F, 0x18, 0x6A, 0xCF, 0xEA, 0x91, 0x14, 0x8E,
        0xE2, 0xA7, 0x9C, 0xCA, 0x36, 0x89, 0xED, 0xB6,
        0x2A, 0xAF, 0x28, 0xB5, 0xD7, 0x52, 0xFD, 0xE2,
        0x65, 0xEE, 0x52, 0x80, 0xB5, 0x19, 0x72, 0x6C,
        0x1C, 0xA9, 0x80, 0x32, 0x95, 0xC6, 0x74, 0xB7,
        0xEF, 0xAF, 0xA4, 0xD6, 0x1B, 0x30, 0x6A, 0x79,
        0xE3, 0xF6, 0xE7, 0xA8, 0x87, 0xC2, 0xFB, 0x53,
        0x5B, 0x3B, 0x0F, 0xB3, 0xD9, 0xEB, 0xC8, 0x76,
        0x03, 0xEA, 0xFE, 0xF1, 0x70, 0xC1, 0xF1, 0xD2,
        0x8E, 0x99, 0xBB
    };
    static const byte sig_65_draft[] = {
        0xF7, 0x78, 0x9A, 0x45, 0xA3, 0x58, 0x73, 0x30,
        0xE7, 0xFC, 0xF7, 0x06, 0x95, 0xF7, 0xF6, 0x96,
        0x88, 0xA2, 0xB8, 0xD0, 0xCE, 0x54, 0xF0, 0x90,
        0x21, 0x4F, 0x10, 0x9F, 0x56, 0x48, 0x4F, 0x98,
        0xC3, 0xAD, 0x1A, 0x53, 0xA5, 0x44, 0x1C, 0x2C,
        0xA7, 0x2A, 0x3B, 0x31, 0x91, 0xBC, 0x04, 0x6F,
        0x46, 0x37, 0x30, 0x45, 0xB9, 0xE5, 0x40, 0xC7,
        0x3D, 0xFE, 0x91, 0xB6, 0x1F, 0x05, 0x88, 0xD6,
        0x13, 0x59, 0x3F, 0xCE, 0x1B, 0x00, 0xEE, 0xF1,
        0xB2, 0x27, 0x03, 0x4C, 0x6F, 0xD3, 0xB1, 0x8B,
        0x3F, 0x22, 0x11, 0x10, 0xFB, 0x34, 0x5A, 0xA7,
        0x86, 0x31, 0xB8, 0xB5, 0x9F, 0xBD, 0xFD, 0xCC,
        0xDA, 0xE6, 0xA2, 0x4D, 0x25, 0x9D, 0x34, 0xAA,
        0xBA, 0xD2, 0x18, 0xB3, 0xAE, 0x4E, 0x77, 0x18,
        0x66, 0x53, 0xB8, 0x56, 0x3A, 0xA6, 0x12, 0x0A,
        0x0A, 0x53, 0x1A, 0x4E, 0x91, 0x37, 0x30, 0xDC,
        0x91, 0x4F, 0xE5, 0xE0, 0x08, 0xBE, 0xCE, 0x68,
        0x69, 0xB0, 0x2B, 0x07, 0xFD, 0xC1, 0x62, 0x14,
        0x54, 0x0D, 0x31, 0x6C, 0x43, 0xFA, 0x0C, 0x21,
        0x1B, 0x41, 0xAC, 0x7E, 0x52, 0x65, 0x67, 0x29,
        0xC7, 0x73, 0xE4, 0xC4, 0xB8, 0x8E, 0xD3, 0x11,
        0x88, 0x6D, 0xD4, 0xD2, 0x75, 0x41, 0x7D, 0x70,
        0x19, 0x66, 0x44, 0xEE, 0xD1, 0x5F, 0xA3, 0x15,
        0x06, 0x60, 0x03, 0xE3, 0x09, 0xF8, 0x32, 0xAF,
        0x91, 0x26, 0x2C, 0x94, 0x90, 0x11, 0xFC, 0xB0,
        0xAD, 0x2C, 0xCE, 0x65, 0xDD, 0x9E, 0xFF, 0x56,
        0x7E, 0xE2, 0x9C, 0xC4, 0x0A, 0x6F, 0xE0, 0x66,
        0x4E, 0x7D, 0x9F, 0x23, 0x65, 0x68, 0xFC, 0x94,
        0x29, 0x5D, 0xBB, 0x34, 0x28, 0x82, 0x33, 0xE8,
        0xC5, 0x11, 0xD2, 0x88, 0x15, 0xEC, 0x72, 0x10,
        0x32, 0x29, 0x6E, 0x1E, 0xDE, 0xCA, 0x7F, 0x72,
        0x6A, 0x6E, 0xB0, 0xF7, 0x6C, 0xC5, 0x82, 0x80,
        0x11, 0xC0, 0xE4, 0x01, 0x3C, 0xC7, 0xEE, 0x43,
        0x29, 0xB8, 0x1E, 0xCC, 0x0D, 0x52, 0xED, 0x1E,
        0x49, 0x1D, 0xD6, 0xD5, 0x5C, 0x52, 0x65, 0x66,
        0x5E, 0xD8, 0xAD, 0x21, 0x9B, 0x89, 0x4F, 0x31,
        0xC6, 0x8C, 0x61, 0x9A, 0xFC, 0xDB, 0x73, 0x58,
        0xE5, 0x55, 0x4C, 0x49, 0x5B, 0x8B, 0x6E, 0x33,
        0x25, 0x68, 0x8F, 0xB8, 0xC1, 0xA2, 0x53, 0x31,
        0xD5, 0x7B, 0xD3, 0x48, 0xA2, 0x7D, 0x39, 0x09,
        0x29, 0xBC, 0x46, 0xA1, 0x49, 0x6A, 0xB3, 0x5B,
        0x46, 0xBA, 0x61, 0xB6, 0xB9, 0xD2, 0x3C, 0xD0,
        0x63, 0x15, 0xFB, 0x72, 0xC2, 0x47, 0x76, 0x01,
        0x61, 0x30, 0xAD, 0xB1, 0xCF, 0x2D, 0xC7, 0x29,
        0x59, 0xEA, 0x9C, 0xAD, 0x96, 0xAF, 0x5D, 0xA9,
        0x96, 0x12, 0x6C, 0xDD, 0x85, 0xB1, 0x34, 0xCC,
        0x92, 0x7A, 0x51, 0xFD, 0x23, 0xF8, 0x47, 0x91,
        0xA3, 0xFC, 0xDA, 0x07, 0x7E, 0x15, 0x99, 0x17,
        0x48, 0xA0, 0x39, 0x4F, 0x33, 0x4E, 0xB8, 0xBC,
        0x48, 0xA9, 0x9A, 0xB9, 0xDF, 0xBB, 0x0F, 0x2A,
        0xAD, 0x6F, 0xBE, 0x48, 0x49, 0x61, 0xD3, 0xA4,
        0xE8, 0xF8, 0xB2, 0x1A, 0x6A, 0xC0, 0x92, 0xB2,
        0x26, 0xD6, 0xE1, 0x19, 0xFA, 0xD4, 0x4D, 0x8E,
        0x57, 0x6F, 0xE9, 0x6C, 0x6C, 0xDB, 0x68, 0x40,
        0xEA, 0x61, 0x4B, 0xAF, 0xC7, 0x07, 0x86, 0xC5,
        0x19, 0xE1, 0xD5, 0xDC, 0x0F, 0x98, 0x44, 0x43,
        0xC8, 0xB1, 0xE5, 0x4F, 0x8E, 0xE1, 0x76, 0xD9,
        0x8B, 0x2C, 0x70, 0x27, 0xF5, 0x7D, 0x7E, 0x3D,
        0xE9, 0xB2, 0xA0, 0xA3, 0x69, 0x11, 0xB8, 0xE4,
        0x71, 0x21, 0xDE, 0x0C, 0x07, 0xEB, 0xBA, 0x5D,
        0x7B, 0x59, 0x4E, 0xF2, 0x44, 0xC6, 0x83, 0x27,
        0xEC, 0x6C, 0x6D, 0x1D, 0xD5, 0x01, 0xF4, 0x83,
        0xFE, 0x9B, 0x95, 0x70, 0x59, 0x7E, 0x70, 0xDF,
        0x41, 0x3E, 0x7A, 0xF0, 0x38, 0x47, 0xF4, 0x09,
        0xED, 0x61, 0xE2, 0x84, 0x6E, 0x6C, 0x64, 0x1E,
        0x6A, 0x7F, 0xFA, 0x79, 0xDE, 0x6B, 0xFA, 0x37,
        0x3A, 0x06, 0x44, 0xB0, 0x0B, 0xF4, 0x1A, 0x03,
        0x49, 0x92, 0xA7, 0x94, 0xDA, 0x17, 0xC8, 0x88,
        0x85, 0x23, 0x90, 0x32, 0xC8, 0x51, 0x76, 0x4E,
        0x3E, 0x4D, 0xBD, 0xE7, 0xF1, 0x2A, 0x16, 0xC5,
        0xA2, 0x63, 0xE9, 0x64, 0xC1, 0xE7, 0xFD, 0xD3,
        0xCC, 0xE5, 0x76, 0xDD, 0x6D, 0x56, 0xB1, 0x81,
        0x82, 0x84, 0x8B, 0x75, 0x63, 0x64, 0x5D, 0x4E,
        0x42, 0xFF, 0x22, 0x74, 0x2A, 0x99, 0x67, 0x85,
        0x16, 0x9D, 0x7F, 0x50, 0x3B, 0x48, 0xA7, 0x15,
        0x8B, 0x3C, 0xBD, 0x29, 0x93, 0x5E, 0xD3, 0x20,
        0x49, 0xBE, 0xA1, 0xAD, 0x95, 0x3E, 0xF7, 0x07,
        0x32, 0x7B, 0x77, 0x8B, 0xFD, 0xDD, 0xFC, 0x60,
        0x51, 0x1D, 0xA1, 0x13, 0xA3, 0x4F, 0x65, 0x57,
        0x12, 0xE4, 0xE5, 0x9D, 0x6C, 0xCE, 0x40, 0x4E,
        0x94, 0xAB, 0xA6, 0x1E, 0x81, 0x35, 0x38, 0x8F,
        0xC2, 0x1C, 0x8E, 0x41, 0x34, 0x4F, 0x32, 0x4B,
        0x01, 0xAC, 0x8C, 0x06, 0x9F, 0x92, 0x57, 0x5D,
        0x34, 0xF8, 0x8B, 0xCA, 0x22, 0xCB, 0x30, 0x7E,
        0x37, 0x07, 0x00, 0x63, 0x32, 0x02, 0x56, 0xB8,
        0xBA, 0xD6, 0xEB, 0x7A, 0x81, 0xAF, 0xE9, 0xA2,
        0x54, 0x01, 0x6E, 0x1C, 0x8A, 0x12, 0x50, 0x89,
        0xAA, 0xA3, 0xED, 0xE8, 0x4E, 0x5B, 0x6C, 0x2E,
        0xCF, 0xAE, 0xFA, 0xA5, 0x2B, 0x9F, 0x57, 0x09,
        0x60, 0x2C, 0x06, 0xAE, 0xA4, 0xA0, 0x38, 0x4E,
        0x9B, 0x09, 0xE5, 0xB8, 0x81, 0x64, 0xB2, 0x74,
        0xEA, 0x32, 0x65, 0xFB, 0x51, 0x52, 0x39, 0x7D,
        0xFF, 0x5A, 0x3A, 0x08, 0x61, 0xE2, 0xBC, 0x12,
        0xD2, 0x10, 0x92, 0x89, 0x72, 0x97, 0x47, 0xE8,
        0x3F, 0xDF, 0x24, 0x3A, 0x1D, 0x17, 0xB9, 0x83,
        0x48, 0x37, 0x98, 0x45, 0xA9, 0xE9, 0x55, 0xE2,
        0xD6, 0xF9, 0x38, 0xDA, 0xA5, 0x91, 0x8E, 0x2A,
        0x14, 0xF9, 0x7B, 0xA2, 0xBE, 0x50, 0x1C, 0xCC,
        0xAF, 0xD6, 0x81, 0x91, 0x0F, 0x4A, 0x4F, 0x06,
        0x71, 0x5C, 0xE8, 0x40, 0x96, 0xF3, 0x7A, 0x91,
        0xDC, 0xCA, 0x2A, 0x8A, 0x4B, 0xE8, 0xDA, 0x79,
        0x21, 0xDB, 0xF8, 0xD3, 0xF4, 0xEF, 0xB9, 0x8C,
        0x6B, 0x4F, 0x94, 0x0E, 0xCE, 0xF8, 0x32, 0xB5,
        0x49, 0xD0, 0x68, 0x94, 0x7C, 0x3D, 0xFB, 0x58,
        0x09, 0xCB, 0x7B, 0x06, 0x0A, 0x3A, 0x0E, 0xF3,
        0xB2, 0x1C, 0x01, 0x64, 0x50, 0x1D, 0xDE, 0xA7,
        0xC9, 0xE5, 0xE7, 0x89, 0x7C, 0x6B, 0x1C, 0x46,
        0x34, 0x8B, 0x2C, 0x3E, 0x80, 0x5F, 0x6F, 0x22,
        0x87, 0xBA, 0x15, 0x8C, 0xF9, 0x25, 0xA7, 0xBA,
        0x7F, 0x08, 0x25, 0x49, 0x89, 0xC8, 0x7D, 0x24,
        0x97, 0x9A, 0xD9, 0x86, 0xAA, 0x97, 0xC5, 0x1B,
        0x01, 0xF4, 0x5D, 0x4A, 0x1F, 0x24, 0x75, 0x29,
        0x91, 0xF0, 0x42, 0x05, 0xEB, 0x55, 0x1F, 0xD0,
        0x2D, 0x41, 0x5F, 0x2D, 0xD1, 0xEF, 0xF1, 0x42,
        0xB0, 0xD7, 0x04, 0x16, 0xC6, 0xD8, 0x15, 0xEB,
        0x91, 0x73, 0x2B, 0x26, 0x8F, 0xB2, 0x0D, 0x08,
        0x67, 0x44, 0x2D, 0x71, 0xDE, 0xC0, 0x57, 0xB2,
        0x86, 0xCD, 0x93, 0x81, 0x1F, 0xF3, 0xF6, 0x46,
        0xEB, 0xD5, 0x65, 0xD5, 0x1D, 0x09, 0xA4, 0x2D,
        0x3A, 0xBA, 0xAC, 0x0F, 0x34, 0xCC, 0x81, 0x7B,
        0x18, 0x93, 0x8E, 0xCC, 0xBB, 0x1F, 0xEF, 0x05,
        0xBD, 0x3C, 0x2B, 0x49, 0x4F, 0xA5, 0x29, 0xED,
        0x4C, 0x63, 0x4C, 0x93, 0x25, 0xA4, 0x81, 0x73,
        0xF2, 0x0F, 0xFA, 0xC3, 0x2D, 0xC1, 0x01, 0xE6,
        0xEE, 0x03, 0xB2, 0xFC, 0xBE, 0xC2, 0x46, 0x8D,
        0xBC, 0x8F, 0x76, 0x75, 0x8C, 0x32, 0x15, 0x47,
        0x4F, 0x7E, 0xF2, 0x40, 0x65, 0xF7, 0x90, 0x60,
        0xAC, 0xA3, 0xC8, 0xD5, 0xD7, 0x4A, 0xF7, 0x0F,
        0x48, 0x30, 0x1D, 0xDB, 0x30, 0xC0, 0x5D, 0xB3,
        0xEF, 0xA7, 0x26, 0xCF, 0x88, 0x55, 0x59, 0x01,
        0x84, 0x12, 0x82, 0xAA, 0x08, 0xF6, 0x66, 0xA6,
        0x53, 0x51, 0xA6, 0xA2, 0x4E, 0xED, 0x6B, 0xE2,
        0x11, 0x77, 0x31, 0x07, 0xE1, 0x85, 0xE1, 0xB4,
        0x88, 0xA2, 0xE4, 0x91, 0xB6, 0xC1, 0x41, 0x52,
        0x84, 0x62, 0xA8, 0x64, 0x94, 0xB5, 0x4F, 0xDC,
        0xCE, 0xCC, 0xB6, 0xAA, 0x21, 0x25, 0x36, 0x86,
        0x69, 0x3A, 0xE7, 0x98, 0xC9, 0xCE, 0x9E, 0x0B,
        0xDD, 0xC6, 0xAE, 0x53, 0xD9, 0xB7, 0x06, 0xDC,
        0x4F, 0x4D, 0x81, 0xB9, 0xC7, 0x3C, 0x46, 0x1E,
        0xCD, 0x70, 0x35, 0xC5, 0x17, 0x2E, 0xFA, 0xE5,
        0x60, 0x2C, 0xAF, 0x88, 0xC6, 0x4E, 0x79, 0xE5,
        0x32, 0x40, 0x30, 0x55, 0x5D, 0xE2, 0x11, 0xF8,
        0x9F, 0xD4, 0x24, 0xC3, 0x38, 0xC3, 0x88, 0x3C,
        0x83, 0xCA, 0x94, 0x05, 0xC2, 0xB5, 0xD1, 0x44,
        0x5F, 0x7C, 0x98, 0xC4, 0x3E, 0xD3, 0xD2, 0xBE,
        0xCB, 0xE2, 0x5F, 0x5F, 0x3F, 0x54, 0x4C, 0xCC,
        0x5B, 0x5A, 0xEA, 0xE4, 0x7D, 0xDF, 0x3F, 0xB5,
        0x64, 0x9F, 0xF5, 0xD6, 0x1E, 0xAA, 0x02, 0xED,
        0xEB, 0xC7, 0x5C, 0xE4, 0x78, 0xBA, 0x00, 0x42,
        0x6C, 0xAF, 0x47, 0x4F, 0xA7, 0x9E, 0x5B, 0x08,
        0x9E, 0xB1, 0xA8, 0x82, 0xF1, 0x53, 0x54, 0x59,
        0x26, 0x95, 0x95, 0x2B, 0xA0, 0xA8, 0xEE, 0x91,
        0xE6, 0x49, 0xE3, 0xF2, 0xC3, 0x82, 0x26, 0x4D,
        0xAA, 0x30, 0xF6, 0xA6, 0xD2, 0x17, 0xF6, 0x12,
        0x9C, 0x19, 0x39, 0xB6, 0xDC, 0xAC, 0xCD, 0xA5,
        0xB6, 0x37, 0x32, 0x6E, 0x8A, 0x83, 0x61, 0xC3,
        0xB5, 0x6F, 0xCF, 0xFC, 0x48, 0x50, 0x36, 0x86,
        0x58, 0x22, 0xB9, 0xBB, 0x87, 0xB4, 0x35, 0x10,
        0xBC, 0xDD, 0x55, 0xBC, 0x35, 0x0D, 0xE7, 0xB2,
        0xAE, 0x90, 0xA2, 0x1E, 0x9E, 0x19, 0x97, 0x8E,
        0xDA, 0x10, 0xDF, 0x66, 0x76, 0x14, 0xA4, 0x4F,
        0xE2, 0xA8, 0x4D, 0x16, 0xBE, 0x04, 0x3E, 0xA8,
        0x77, 0x36, 0x33, 0xEA, 0x6B, 0xAD, 0xF6, 0x57,
        0x10, 0x05, 0x2F, 0x34, 0x1F, 0x65, 0xCB, 0xE9,
        0x28, 0xD3, 0x96, 0x2A, 0x5A, 0x2F, 0xE6, 0x4E,
        0x46, 0xD6, 0xBF, 0xB8, 0xFD, 0x0D, 0x99, 0x78,
        0xF0, 0x42, 0x3C, 0xBD, 0x19, 0x5F, 0x72, 0xF3,
        0xCB, 0x19, 0xD7, 0xEF, 0xD9, 0xEB, 0xE3, 0x3C,
        0xD2, 0xF5, 0x70, 0x9A, 0x57, 0x80, 0x7D, 0xF9,
        0x44, 0xEC, 0xE5, 0x68, 0xAA, 0xCA, 0x43, 0x36,
        0x42, 0x20, 0x83, 0xB0, 0x69, 0x7B, 0x6A, 0xA0,
        0x05, 0x86, 0xE4, 0xBF, 0x7D, 0xD6, 0x73, 0xA3,
        0xD5, 0x96, 0xB8, 0x61, 0x8A, 0xC3, 0xB4, 0x06,
        0x17, 0x50, 0xC6, 0xBE, 0x97, 0xCB, 0x53, 0x75,
        0x3D, 0x02, 0x39, 0x55, 0x56, 0x07, 0x5A, 0x26,
        0xF1, 0x40, 0xB9, 0x3F, 0x57, 0x7D, 0xAD, 0x50,
        0x5E, 0x1C, 0xF2, 0xB5, 0x51, 0xA0, 0x4C, 0x98,
        0xC7, 0xF0, 0x90, 0x18, 0x31, 0xB3, 0xCA, 0x61,
        0xD7, 0x5D, 0xA7, 0x93, 0xAC, 0x72, 0xA4, 0x4C,
        0x7A, 0x07, 0xF7, 0xDB, 0xBA, 0xD6, 0x0A, 0x55,
        0xF4, 0x9C, 0xBD, 0x79, 0xDE, 0xE4, 0x73, 0x9F,
        0xFD, 0x36, 0x77, 0x8E, 0xBD, 0x08, 0xEB, 0xDB,
        0x79, 0xEC, 0x07, 0xA1, 0x62, 0x39, 0xC5, 0xB9,
        0x21, 0x59, 0x9F, 0xEB, 0xFE, 0xA4, 0x6D, 0xDF,
        0x96, 0x6A, 0xA4, 0xA0, 0x15, 0x12, 0xE6, 0x10,
        0x94, 0x3F, 0x5D, 0xC5, 0x4B, 0x4C, 0x76, 0xB7,
        0x64, 0xB3, 0x80, 0xBF, 0x2F, 0x84, 0xED, 0xE3,
        0x21, 0x24, 0x91, 0x2F, 0x54, 0xF7, 0xB6, 0xE2,
        0x07, 0xB7, 0x38, 0x1F, 0x67, 0x0F, 0x7A, 0xA0,
        0xF3, 0xC3, 0xED, 0x10, 0x15, 0x74, 0x03, 0x84,
        0xDD, 0x61, 0xA9, 0x76, 0x5E, 0xE4, 0x69, 0x6E,
        0xAC, 0xF8, 0x2E, 0xA4, 0x10, 0x69, 0x18, 0x05,
        0xCB, 0x68, 0x89, 0x03, 0x53, 0x5D, 0x70, 0x46,
        0x10, 0x0D, 0xCC, 0x2B, 0xA7, 0xD8, 0x30, 0x2A,
        0xCB, 0x04, 0x30, 0xD5, 0x06, 0xCC, 0xC1, 0xC0,
        0xDD, 0xEA, 0x71, 0x11, 0xA7, 0x6F, 0x45, 0xB4,
        0x54, 0xE2, 0x5C, 0xDD, 0xFB, 0x63, 0x9B, 0x3D,
        0x66, 0x4C, 0x36, 0xD8, 0x84, 0x35, 0x13, 0xA3,
        0xFC, 0xAF, 0x9E, 0x60, 0x57, 0xE9, 0xBC, 0x06,
        0x82, 0x37, 0xFE, 0x24, 0x19, 0xA2, 0xD2, 0xD9,
        0x0B, 0x4A, 0x1F, 0xC2, 0xA7, 0x1A, 0x14, 0x6D,
        0x2B, 0xD0, 0x43, 0x64, 0xC7, 0x9B, 0x8E, 0xBA,
        0x8E, 0x3E, 0x88, 0xCE, 0x11, 0xE9, 0x16, 0xE4,
        0xA7, 0x52, 0x84, 0x21, 0x32, 0x8C, 0xF5, 0x4F,
        0xAA, 0xB2, 0xB1, 0x9F, 0x44, 0x46, 0x87, 0x81,
        0xF8, 0xAB, 0x84, 0xB7, 0xDD, 0x97, 0x2F, 0xF5,
        0x61, 0x50, 0x71, 0x43, 0x0A, 0x43, 0x74, 0xDA,
        0xFC, 0xAE, 0x1E, 0x60, 0x44, 0xAA, 0x98, 0xE9,
        0x85, 0x94, 0x1B, 0xA6, 0xB9, 0xDB, 0x8C, 0x02,
        0xF5, 0x89, 0x60, 0x3E, 0xEB, 0x8B, 0xE9, 0x0A,
        0x70, 0xEF, 0xC0, 0x88, 0xD7, 0x95, 0xE6, 0xDA,
        0x1F, 0x1F, 0x2E, 0x6E, 0xCE, 0xDD, 0x03, 0x1D,
        0x81, 0x99, 0xE6, 0x59, 0x12, 0xD4, 0x34, 0xD0,
        0x9B, 0xFB, 0xE5, 0x94, 0x40, 0x6D, 0xC1, 0x15,
        0x0E, 0x99, 0x35, 0x8C, 0xEA, 0x7F, 0xAD, 0x2E,
        0x7C, 0x44, 0xC3, 0x8B, 0x6E, 0x0C, 0xEE, 0xAB,
        0x9B, 0xDE, 0x0D, 0xB9, 0x7B, 0xCF, 0x5A, 0xC9,
        0x94, 0x10, 0xC9, 0x47, 0x0E, 0x26, 0x6B, 0x8B,
        0xE4, 0x5F, 0x66, 0x90, 0x83, 0x1F, 0x41, 0x45,
        0xE2, 0x63, 0x79, 0xDB, 0x80, 0x7C, 0x26, 0xDD,
        0xF9, 0x1E, 0x30, 0x9D, 0x4F, 0x4A, 0x3E, 0x7E,
        0xCA, 0xB7, 0x36, 0x2F, 0x15, 0xD2, 0x0E, 0xA4,
        0x33, 0xB7, 0xE7, 0x0A, 0x7D, 0xDE, 0x74, 0x16,
        0xCE, 0xA8, 0x71, 0x49, 0x8B, 0x2C, 0xE3, 0xF5,
        0x8D, 0x29, 0xD8, 0x62, 0x8C, 0x53, 0x18, 0x40,
        0xF0, 0x22, 0xDD, 0x3B, 0xD2, 0xF3, 0x80, 0x9B,
        0x11, 0x68, 0xD3, 0x8E, 0x63, 0xC7, 0xF6, 0x93,
        0x08, 0xA3, 0x1A, 0x2D, 0x4D, 0x5E, 0xEB, 0x97,
        0x42, 0x39, 0xB3, 0x4A, 0x62, 0xBC, 0x85, 0xE4,
        0xEC, 0xF9, 0x0C, 0x33, 0x6A, 0x0C, 0x37, 0xBD,
        0x9E, 0x0E, 0xF4, 0x26, 0x6B, 0x83, 0x5A, 0xC8,
        0x90, 0x6A, 0x83, 0xCF, 0x0B, 0x35, 0x13, 0x8A,
        0x65, 0xE5, 0xD9, 0xA6, 0x1F, 0xCC, 0x9B, 0x2D,
        0x5A, 0x33, 0x7B, 0x8A, 0xBE, 0xF8, 0x8A, 0x7F,
        0xB3, 0xC0, 0x94, 0x5D, 0x7C, 0xAF, 0x35, 0x61,
        0x1A, 0xE0, 0xE4, 0x46, 0x93, 0xA5, 0xBC, 0xE0,
        0xA6, 0xE2, 0xFE, 0xCA, 0xE9, 0xBD, 0xF4, 0xE3,
        0x56, 0xD6, 0x53, 0x6B, 0x58, 0x1A, 0x18, 0xF0,
        0x3A, 0x59, 0x16, 0x4E, 0xD5, 0x44, 0x7C, 0x7E,
        0xC8, 0xBD, 0x99, 0x7B, 0xE9, 0x53, 0xDE, 0xD9,
        0x32, 0x53, 0x5B, 0x5F, 0x43, 0x8A, 0x04, 0x31,
        0x9F, 0x5E, 0x0D, 0x8B, 0x0F, 0xEB, 0xC8, 0xDE,
        0x81, 0x46, 0x65, 0x8E, 0x52, 0xB9, 0x75, 0x9C,
        0x73, 0x93, 0x5B, 0x12, 0x0D, 0xC9, 0xB8, 0x54,
        0xF3, 0xC8, 0xF9, 0x4E, 0xC9, 0x33, 0x90, 0x57,
        0xD7, 0xD7, 0xCD, 0x91, 0xF7, 0xE0, 0xB9, 0x8D,
        0x84, 0xEC, 0x7B, 0x2F, 0x92, 0x32, 0x8D, 0x73,
        0x60, 0x18, 0xB0, 0x31, 0x65, 0xA8, 0x74, 0x5F,
        0x8E, 0x77, 0xEB, 0x80, 0x29, 0xF9, 0x78, 0x26,
        0x70, 0xCB, 0xD8, 0x6B, 0x43, 0x16, 0xC7, 0xBE,
        0x4A, 0x88, 0x03, 0x38, 0xBA, 0xCF, 0xB0, 0x15,
        0x69, 0x9B, 0xF3, 0x0D, 0x3A, 0x4B, 0x05, 0x32,
        0x54, 0x35, 0xBA, 0x5F, 0xA3, 0xB9, 0xD2, 0xB2,
        0xFE, 0x0B, 0x51, 0x9C, 0x2C, 0xB2, 0x46, 0xE5,
        0x3D, 0x1A, 0x34, 0x3D, 0x66, 0x1A, 0x66, 0x14,
        0x3C, 0x6F, 0x46, 0x8C, 0x55, 0x38, 0x64, 0x5C,
        0xC2, 0x6D, 0x4E, 0x2A, 0x87, 0x03, 0xEC, 0x9B,
        0x10, 0xFC, 0x89, 0xBE, 0x6F, 0x85, 0x99, 0x97,
        0x70, 0x8F, 0x31, 0x19, 0x4F, 0x0D, 0xFE, 0xE9,
        0x29, 0x98, 0xB2, 0x5E, 0x93, 0xB9, 0x70, 0x70,
        0xDE, 0x14, 0x40, 0x9D, 0x5B, 0xA4, 0x3D, 0xF8,
        0x8D, 0x15, 0xC2, 0xFB, 0xA9, 0x7B, 0xDD, 0xE6,
        0x18, 0xCC, 0x3F, 0xC0, 0x42, 0xF7, 0x74, 0x81,
        0x84, 0xBA, 0x9E, 0xC9, 0xCB, 0xA1, 0xB2, 0x00,
        0x68, 0x81, 0xD0, 0x51, 0x42, 0x64, 0x19, 0x8F,
        0xB6, 0x91, 0xC5, 0xC0, 0x38, 0xE0, 0x49, 0x50,
        0xCF, 0x69, 0x09, 0x93, 0x77, 0xFE, 0x66, 0xBA,
        0x64, 0xE2, 0x19, 0x52, 0xA4, 0x45, 0x81, 0x71,
        0x96, 0x64, 0xF5, 0xD9, 0x23, 0x97, 0xD2, 0x2A,
        0xA7, 0x03, 0x2B, 0xF5, 0x89, 0xAF, 0x8A, 0xCA,
        0x48, 0xDF, 0x6D, 0x14, 0xEB, 0x43, 0xCE, 0xF0,
        0xA9, 0xC8, 0xA8, 0xF9, 0xAD, 0x32, 0x95, 0x25,
        0xEF, 0x0A, 0xAA, 0x4F, 0x9E, 0x09, 0xC3, 0x51,
        0x3C, 0xF0, 0x29, 0xF3, 0xDE, 0xFC, 0xBB, 0x41,
        0x14, 0xFA, 0x0F, 0x66, 0x8D, 0xB4, 0x72, 0x2F,
        0xCC, 0xD9, 0xC2, 0x07, 0xB6, 0x6F, 0x10, 0x9E,
        0xD9, 0x5B, 0x45, 0x4B, 0xB6, 0x19, 0x5D, 0x59,
        0xC4, 0xA6, 0x78, 0xBA, 0x6F, 0x5A, 0x9B, 0x23,
        0x41, 0x21, 0xAD, 0x05, 0x16, 0xA1, 0xD4, 0x12,
        0x3D, 0x38, 0x26, 0xD9, 0x2A, 0x61, 0xB3, 0x5D,
        0xEB, 0x29, 0x5B, 0xAA, 0x2F, 0xE1, 0xB5, 0xEE,
        0x25, 0x02, 0x1D, 0xAE, 0xF8, 0x57, 0xB5, 0xDF,
        0x19, 0x2E, 0x17, 0x5E, 0x3A, 0x2A, 0x0D, 0x3F,
        0x08, 0x2F, 0x21, 0x1C, 0xB5, 0xBD, 0xC2, 0x36,
        0x27, 0x4F, 0x86, 0xC5, 0xDC, 0x74, 0xC3, 0x9B,
        0xE9, 0x7C, 0xCF, 0x5F, 0x57, 0x94, 0xEB, 0x64,
        0xEC, 0x64, 0x55, 0x45, 0x21, 0x0F, 0xC6, 0x67,
        0xD1, 0xE0, 0x74, 0x0E, 0x66, 0xCB, 0xED, 0xC2,
        0x06, 0x48, 0xCA, 0x1F, 0xA7, 0x34, 0x14, 0x59,
        0x6B, 0xA0, 0x89, 0x17, 0xA1, 0x9A, 0x46, 0x3A,
        0xD3, 0x02, 0x7C, 0x81, 0x83, 0x6B, 0x8F, 0x4F,
        0x02, 0xB9, 0x9F, 0xC5, 0x08, 0x3F, 0x06, 0xF3,
        0x4B, 0xD2, 0x30, 0x9C, 0x23, 0x42, 0xAD, 0x88,
        0xA8, 0x4F, 0xA9, 0x6E, 0x20, 0x7C, 0x01, 0x08,
        0xF6, 0x82, 0x54, 0x14, 0x94, 0x4F, 0x26, 0x4E,
        0xD6, 0xC4, 0x66, 0x7C, 0x78, 0x8D, 0x61, 0xA6,
        0xBC, 0x2C, 0x45, 0x6A, 0xF6, 0x6C, 0x2F, 0x76,
        0x9E, 0x16, 0x90, 0x17, 0x06, 0x91, 0x2C, 0xC9,
        0x0D, 0x4B, 0x6C, 0x90, 0xDC, 0xA1, 0x6C, 0xAC,
        0x8F, 0xFE, 0xD8, 0x39, 0x70, 0x20, 0xE2, 0x97,
        0x5E, 0x24, 0xFF, 0x4C, 0x80, 0x7C, 0x8A, 0xB7,
        0x31, 0xC8, 0x1D, 0x36, 0xCA, 0x84, 0xC9, 0x12,
        0x1A, 0x85, 0x13, 0xE0, 0xC9, 0xD0, 0xF4, 0x1B,
        0xC6, 0x8F, 0x88, 0xEA, 0xCA, 0xA3, 0x55, 0x99,
        0xFA, 0xE3, 0xBB, 0xA6, 0xFC, 0xC6, 0x52, 0x8D,
        0x47, 0xE4, 0x0C, 0x07, 0x64, 0xCF, 0x9C, 0x83,
        0x83, 0xB3, 0xA4, 0x45, 0x15, 0xE6, 0x1D, 0x92,
        0xCD, 0xAE, 0xC9, 0xCB, 0x90, 0x82, 0xB5, 0xA0,
        0xC0, 0x37, 0x94, 0x60, 0xD9, 0x17, 0x9A, 0x7D,
        0x9D, 0xF2, 0x9E, 0x0B, 0x4B, 0x6A, 0x41, 0x18,
        0x28, 0x52, 0x15, 0xE8, 0x7B, 0x6F, 0x11, 0x8E,
        0x97, 0x31, 0xE4, 0x66, 0xFB, 0x3F, 0xEB, 0xD1,
        0x95, 0xE1, 0x44, 0xFD, 0x20, 0x37, 0xD1, 0x16,
        0x62, 0x75, 0x79, 0xAC, 0x55, 0xFE, 0xD5, 0xE3,
        0x25, 0x85, 0xEC, 0x66, 0x38, 0xA0, 0xDF, 0xBE,
        0x6E, 0xD6, 0xC5, 0x87, 0x6C, 0xF8, 0x11, 0x4C,
        0x90, 0x2A, 0xEF, 0xA3, 0x63, 0xF4, 0xC9, 0xB7,
        0x2E, 0x7D, 0x5C, 0x85, 0x2D, 0xCC, 0x1A, 0xF2,
        0xB8, 0x85, 0x2A, 0x9D, 0x0F, 0x99, 0x59, 0x38,
        0x86, 0x50, 0x84, 0xCE, 0x52, 0x13, 0xB3, 0x08,
        0xA9, 0xCB, 0x37, 0xF6, 0x81, 0x96, 0x0D, 0x84,
        0xEF, 0xE1, 0xDF, 0x51, 0x34, 0xA5, 0x91, 0x5A,
        0xE5, 0x87, 0x8B, 0x10, 0xDA, 0x0F, 0xD4, 0xD9,
        0xAC, 0x2A, 0xEF, 0x0C, 0x7E, 0x01, 0xC2, 0xE9,
        0xE7, 0xC0, 0x17, 0xE7, 0xBA, 0x74, 0x0C, 0xEE,
        0x1A, 0x89, 0x94, 0x59, 0xBB, 0x75, 0x03, 0x3E,
        0xEA, 0xF3, 0x19, 0x0D, 0x67, 0x79, 0xED, 0x9E,
        0xDD, 0x84, 0x6A, 0x74, 0xE3, 0x21, 0x52, 0x8C,
        0x03, 0x08, 0x4A, 0x5D, 0x30, 0x87, 0x48, 0x39,
        0x71, 0x8A, 0x53, 0x54, 0x9B, 0x2E, 0xC6, 0xB2,
        0xB7, 0x30, 0xAA, 0x93, 0x5C, 0xA6, 0xE1, 0xC4,
        0xFD, 0x8B, 0xE0, 0x35, 0x7D, 0x93, 0xF6, 0x21,
        0x74, 0xEE, 0xED, 0xF8, 0xDA, 0xB7, 0x75, 0x5B,
        0x46, 0x65, 0x7E, 0x59, 0xD7, 0xAA, 0x00, 0xB9,
        0xF2, 0xF8, 0x5E, 0x4C, 0x0F, 0x77, 0xFA, 0x11,
        0xA5, 0xD6, 0x9A, 0x23, 0xB1, 0xEF, 0x3A, 0x09,
        0xF2, 0x19, 0xD8, 0x3B, 0x1F, 0x39, 0x1F, 0x84,
        0x13, 0x18, 0xEE, 0xF3, 0x5A, 0x32, 0x63, 0x67,
        0xBF, 0xA2, 0xB1, 0x5F, 0xD7, 0x14, 0x03, 0x20,
        0x92, 0xB9, 0xD0, 0x2B, 0xF6, 0x13, 0xAF, 0xF7,
        0x69, 0x6F, 0xAD, 0xF1, 0xDE, 0x2C, 0x81, 0x70,
        0x77, 0xCB, 0x7C, 0x99, 0x67, 0x76, 0xD6, 0x9E,
        0xC2, 0x41, 0xA2, 0x42, 0x54, 0xDA, 0x2D, 0x13,
        0x98, 0x76, 0x91, 0xEA, 0xC7, 0xEB, 0xA8, 0xCD,
        0x8D, 0xCF, 0xB3, 0x94, 0x7B, 0x1D, 0x99, 0xED,
        0xF9, 0x62, 0xD2, 0x15, 0xB3, 0x18, 0xBB, 0x5F,
        0x9A, 0xA0, 0x4D, 0x1C, 0x82, 0x62, 0x6A, 0x41,
        0x73, 0xD0, 0x2D, 0x41, 0x0C, 0x58, 0x6B, 0xCA,
        0x4E, 0x51, 0xCA, 0x4F, 0x3E, 0x15, 0x1B, 0x54,
        0xF1, 0x7A, 0x6B, 0xC9, 0x67, 0x76, 0x09, 0xBB,
        0xAF, 0x6C, 0x30, 0x38, 0xA6, 0x7C, 0xAD, 0xA6,
        0x6B, 0x4F, 0xDF, 0xB5, 0x10, 0x29, 0xE0, 0x78,
        0x07, 0xD7, 0x05, 0x96, 0x9D, 0x96, 0xC9, 0xAB,
        0xFB, 0x71, 0x62, 0xE4, 0x58, 0x10, 0xA1, 0xDC,
        0x4B, 0x56, 0xDA, 0x14, 0x77, 0xED, 0x90, 0x0A,
        0x89, 0xCC, 0xAC, 0x29, 0x8E, 0x17, 0x88, 0x42,
        0x69, 0xC3, 0x9E, 0x8D, 0x7A, 0xB9, 0x66, 0xF3,
        0x3D, 0xDA, 0xDB, 0xE5, 0x6A, 0x38, 0x4C, 0xA2,
        0x0A, 0x7B, 0x18, 0x99, 0xEC, 0x18, 0xE2, 0xAE,
        0x54, 0x70, 0x00, 0xB9, 0x04, 0xE3, 0x4E, 0x46,
        0x80, 0x1D, 0x85, 0x74, 0xDB, 0x00, 0x84, 0x17,
        0xBC, 0xFD, 0xD1, 0xA7, 0x4D, 0xC0, 0x18, 0xE5,
        0x07, 0xB7, 0x6B, 0x0F, 0xA0, 0x86, 0x26, 0x23,
        0x5B, 0x1C, 0xE2, 0x4B, 0xCF, 0xC3, 0x20, 0xFA,
        0xE3, 0x55, 0x1C, 0x1C, 0x92, 0x9B, 0x94, 0xC7,
        0xC4, 0x96, 0x53, 0x41, 0x82, 0x9D, 0x8A, 0x13,
        0x47, 0xD6, 0xA7, 0x38, 0x58, 0x03, 0xB0, 0x8B,
        0xCD, 0xA8, 0x4A, 0x27, 0xEA, 0x5E, 0x49, 0xCA,
        0x1E, 0x60, 0x06, 0xEA, 0x23, 0x2A, 0x53, 0xEE,
        0x41, 0x7E, 0xC8, 0x81, 0xD3, 0x32, 0x8A, 0x15,
        0x63, 0x82, 0xA6, 0xB2, 0x93, 0x89, 0x4D, 0xDF,
        0x9B, 0x36, 0x9C, 0xDE, 0x6B, 0x2F, 0xF5, 0x9C,
        0xB6, 0xA5, 0x64, 0xE2, 0x1C, 0x92, 0x79, 0xEC,
        0xA0, 0x31, 0x1F, 0x5D, 0x80, 0xCE, 0x39, 0xB9,
        0x8B, 0xF9, 0x0D, 0xB3, 0x27, 0xF7, 0x4D, 0x3F,
        0x76, 0x2D, 0x11, 0x7D, 0xF5, 0xF9, 0x13, 0x20,
        0x84, 0xFF, 0xB5, 0x55, 0xA5, 0xD1, 0x47, 0x22,
        0x1A, 0xF8, 0x63, 0xAB, 0xF7, 0x87, 0x15, 0xB7,
        0x21, 0x94, 0x52, 0x9A, 0x0E, 0x33, 0x4D, 0x4A,
        0x19, 0x1D, 0x42, 0xA9, 0x9B, 0xEA, 0x52, 0xAD,
        0xA2, 0xC7, 0xCC, 0x4A, 0x97, 0x74, 0xD5, 0xCB,
        0x28, 0xD4, 0xED, 0x82, 0xB6, 0x1F, 0x94, 0xE8,
        0x9F, 0x60, 0xF0, 0xC8, 0xEA, 0x52, 0xDC, 0x07,
        0x9D, 0x46, 0x58, 0xBF, 0x8C, 0x85, 0x6D, 0x61,
        0x52, 0xD9, 0x22, 0x51, 0x94, 0x8B, 0x3B, 0xA0,
        0x14, 0xD8, 0xBA, 0xF3, 0xDC, 0xD3, 0x6B, 0xC7,
        0x1F, 0x8E, 0x5B, 0x2C, 0xE6, 0xF5, 0x35, 0xB7,
        0xB9, 0xAE, 0x13, 0xDA, 0x4A, 0x1E, 0xAF, 0xFC,
        0x25, 0x3B, 0xE4, 0x3A, 0x9F, 0x60, 0x8E, 0xAC,
        0xE7, 0x33, 0xCF, 0xCE, 0x52, 0xEA, 0x5C, 0xDA,
        0x83, 0x59, 0xDB, 0x53, 0xFF, 0x3A, 0xF2, 0xCE,
        0xFE, 0x87, 0x79, 0xBC, 0xC5, 0x3C, 0x24, 0xA4,
        0xB1, 0x8D, 0x5E, 0x0D, 0x78, 0x1B, 0xEC, 0xF7,
        0x5B, 0x54, 0x77, 0x47, 0x3A, 0x20, 0x24, 0xAD,
        0x56, 0xC5, 0x4A, 0x7F, 0x99, 0x0E, 0xF6, 0xB1,
        0xDF, 0xAC, 0x50, 0x10, 0x88, 0x50, 0x9D, 0x3A,
        0x37, 0xF1, 0xC8, 0xD5, 0xC2, 0x64, 0x87, 0xE4,
        0x20, 0xB7, 0xF4, 0x35, 0x8E, 0x92, 0x69, 0x76,
        0x1F, 0xF1, 0xFA, 0x3A, 0xFC, 0xBE, 0xCA, 0xEB,
        0x68, 0xF5, 0xDD, 0xDE, 0x3A, 0xA8, 0xFD, 0x07,
        0x8C, 0xC4, 0x22, 0x4C, 0xEA, 0x67, 0x13, 0x2D,
        0x7E, 0xBF, 0x5D, 0x23, 0x2E, 0x43, 0xBA, 0xDD,
        0x21, 0x8C, 0x0B, 0x4D, 0xBE, 0x1E, 0x16, 0x52,
        0x98, 0x66, 0xB9, 0xAB, 0x93, 0x58, 0x85, 0xAC,
        0xB4, 0x15, 0xFB, 0xB1, 0xEE, 0xE6, 0x94, 0x08,
        0xA5, 0x21, 0xB4, 0x62, 0xEC, 0x59, 0xCD, 0x0D,
        0x3C, 0x54, 0x96, 0xD9, 0x85, 0xAE, 0xB0, 0xCE,
        0x37, 0x4F, 0x67, 0x72, 0xA4, 0xE6, 0x39, 0x3A,
        0x4E, 0xF0, 0x07, 0x43, 0x80, 0x90, 0xA8, 0xA9,
        0xE5, 0x2D, 0x2F, 0x55, 0x66, 0x6D, 0x70, 0xF0,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
        0x08, 0x0E, 0x12, 0x19, 0x20
    };
#endif
#ifndef WOLFSSL_NO_ML_DSA_87
    static const byte pk_87_draft[] = {
        0x2D, 0x1E, 0x6B, 0xED, 0x84, 0x52, 0xEB, 0xF1,
        0x26, 0xED, 0xE7, 0x0C, 0xA0, 0xA2, 0xB5, 0x0D,
        0x03, 0x34, 0x2D, 0x5B, 0x13, 0xB2, 0xAE, 0x21,
        0x0F, 0x45, 0x62, 0xA3, 0xBF, 0x67, 0x0C, 0xB1,
        0x5C, 0xE9, 0x25, 0xFD, 0x22, 0xF2, 0x62, 0x42,
        0xBA, 0xE3, 0x10, 0xB3, 0xAA, 0x41, 0x3B, 0x6E,
        0x78, 0xD4, 0x42, 0xD9, 0x35, 0xD1, 0x72, 0x8A,
        0x32, 0x48, 0xCC, 0x20, 0x5C, 0xCD, 0x8D, 0x3F,
        0xD8, 0x34, 0x95, 0x55, 0x20, 0xCD, 0xFB, 0x2C,
        0x73, 0xE9, 0x0E, 0x60, 0x8B, 0x2C, 0x3F, 0xA8,
        0xB7, 0xD1, 0x79, 0xFD, 0xDC, 0xC8, 0x81, 0x11,
        0xC9, 0xE8, 0x41, 0x71, 0xE9, 0x70, 0x9B, 0x53,
        0x59, 0x33, 0xE4, 0x92, 0xB6, 0x81, 0x9C, 0x6A,
        0x92, 0xED, 0xA2, 0x5A, 0xC4, 0x07, 0x77, 0x1A,
        0x8F, 0xED, 0xB4, 0xE7, 0x11, 0xFB, 0x89, 0xEB,
        0x7B, 0xDF, 0xCC, 0xEA, 0xC5, 0x3B, 0x4E, 0xF4,
        0x6B, 0x6F, 0xBE, 0xE1, 0x32, 0xA9, 0xD7, 0xAD,
        0xB4, 0x36, 0xE7, 0x4A, 0x6D, 0x67, 0x11, 0x83,
        0xAF, 0x31, 0x1A, 0x7A, 0x31, 0x42, 0x9B, 0x01,
        0x21, 0x17, 0x52, 0x75, 0x85, 0xF7, 0x92, 0x0F,
        0x34, 0x8A, 0x69, 0x11, 0x88, 0x5A, 0x02, 0x08,
        0xB6, 0x6D, 0xE3, 0x07, 0x93, 0xB1, 0x3F, 0xE1,
        0xD5, 0x7B, 0xD9, 0x51, 0xF7, 0xAA, 0xC0, 0x34,
        0x9A, 0x78, 0x5D, 0x26, 0xDB, 0xF1, 0xF0, 0xA9,
        0x1E, 0x5C, 0x9F, 0x4F, 0xA7, 0x43, 0x5C, 0x44,
        0xA9, 0x43, 0xF1, 0x38, 0x11, 0x45, 0xED, 0xEB,
        0x1C, 0x8A, 0x05, 0xEE, 0xFF, 0xAB, 0x20, 0x2C,
        0xF6, 0x2C, 0xEE, 0x77, 0x42, 0x36, 0x3E, 0xE6,
        0x9D, 0x8E, 0x45, 0x0F, 0xF6, 0x7C, 0x39, 0x62,
        0xD6, 0xFF, 0x97, 0xBC, 0x3D, 0x02, 0xD6, 0xDF,
        0x4A, 0x35, 0xDA, 0x3F, 0x89, 0xA4, 0x88, 0x33,
        0xCD, 0xF2, 0x90, 0xF0, 0xE9, 0x37, 0x2F, 0x65,
        0xA5, 0x88, 0x65, 0xFD, 0x40, 0x44, 0xAD, 0x09,
        0x09, 0x92, 0xAA, 0x15, 0x9E, 0xEE, 0xF7, 0x2B,
        0x0D, 0xA7, 0xCB, 0x3A, 0x5E, 0x0A, 0xED, 0xD6,
        0x7D, 0x82, 0x8B, 0xBA, 0xCF, 0xE5, 0x9E, 0xE4,
        0x62, 0xAB, 0x69, 0x6B, 0xBA, 0xD0, 0xE5, 0xA9,
        0xBB, 0x1F, 0x5A, 0x51, 0xE0, 0xFA, 0x5D, 0xD4,
        0x4D, 0x8E, 0xC0, 0xDC, 0x43, 0x06, 0xDF, 0x23,
        0x67, 0xB2, 0x4A, 0xA2, 0xFB, 0x75, 0x2F, 0x82,
        0xD8, 0x44, 0xE4, 0xC0, 0xCE, 0x15, 0x9E, 0x3F,
        0xD6, 0xB4, 0x70, 0x5F, 0x3B, 0xD0, 0x56, 0x3E,
        0x0A, 0x7A, 0x4B, 0x94, 0xBF, 0xBA, 0x01, 0x2B,
        0x9C, 0x8B, 0x91, 0x35, 0xF2, 0xDB, 0x4C, 0x8C,
        0x8D, 0xD6, 0xEE, 0xC8, 0x65, 0x8D, 0xF3, 0x05,
        0x59, 0xBE, 0x3A, 0x17, 0xA7, 0x72, 0x10, 0x56,
        0x14, 0xEF, 0xB8, 0xC1, 0xBE, 0x18, 0x11, 0x0B,
        0xE6, 0x70, 0xF8, 0x39, 0xA5, 0x72, 0x7D, 0xF9,
        0x47, 0xFB, 0xAC, 0xFD, 0x1F, 0xC3, 0x71, 0x33,
        0x58, 0x44, 0x15, 0xD3, 0x7C, 0x93, 0x2E, 0x70,
        0x92, 0xFA, 0xBB, 0xF2, 0xD0, 0x9D, 0x25, 0xC4,
        0xCF, 0x4A, 0xB8, 0xEC, 0xBE, 0x5D, 0x8B, 0x7F,
        0xA4, 0x7C, 0xAB, 0xAD, 0xE7, 0x1E, 0x93, 0x83,
        0x92, 0x86, 0x1E, 0x8D, 0x15, 0xA4, 0x1C, 0x5B,
        0x42, 0x25, 0xDA, 0x3D, 0x16, 0xD3, 0x93, 0xF2,
        0x85, 0x50, 0x86, 0x0A, 0x86, 0x35, 0x6B, 0x14,
        0xAB, 0x5F, 0x22, 0xD0, 0xCF, 0x03, 0x7C, 0xEB,
        0xB4, 0x0E, 0xAC, 0x87, 0xA2, 0x41, 0x42, 0xA0,
        0x21, 0x93, 0x00, 0xB6, 0x47, 0x6F, 0x96, 0xD0,
        0x41, 0xD1, 0xC3, 0x0E, 0x3C, 0x52, 0xD2, 0x45,
        0xAB, 0x6A, 0xE7, 0xA1, 0xE5, 0xFD, 0x73, 0xC5,
        0x82, 0x9D, 0x60, 0x62, 0x8B, 0x6D, 0x87, 0xFC,
        0x88, 0x9C, 0x3E, 0xEF, 0xAE, 0xAA, 0xB6, 0x1C,
        0x18, 0xEE, 0xD7, 0x51, 0x1A, 0x96, 0xC4, 0x93,
        0x25, 0x05, 0xD3, 0x83, 0x3D, 0xD8, 0x33, 0x16,
        0x14, 0x44, 0x88, 0xE2, 0xAF, 0xC4, 0xEC, 0x59,
        0x18, 0x12, 0xB9, 0x99, 0xC1, 0xC9, 0x5F, 0x31,
        0x79, 0x00, 0x03, 0xF6, 0xC9, 0x55, 0x14, 0xAA,
        0x29, 0x08, 0x78, 0x24, 0xAF, 0x1D, 0x99, 0x12,
        0x36, 0xD9, 0x4A, 0xD9, 0x50, 0xEF, 0x66, 0xFC,
        0x7F, 0xF4, 0xBC, 0x3B, 0xA0, 0xF6, 0xFD, 0xF2,
        0x62, 0xCA, 0xA5, 0x9D, 0x2B, 0x55, 0xB8, 0x33,
        0xBC, 0xA6, 0x7A, 0xA5, 0x1E, 0xE1, 0x14, 0x5F,
        0x94, 0xE2, 0xDC, 0xF0, 0x5B, 0xBD, 0x43, 0x07,
        0xD8, 0xB1, 0xE0, 0x81, 0x3F, 0x84, 0x54, 0x90,
        0xBF, 0x23, 0x59, 0x92, 0x3C, 0xA5, 0x98, 0xAB,
        0x7D, 0x99, 0xD2, 0xF0, 0xED, 0x8E, 0x0B, 0xC9,
        0x9F, 0xAF, 0xB0, 0x13, 0xED, 0xC7, 0xDD, 0xB8,
        0x61, 0x72, 0x07, 0x3D, 0xCC, 0x35, 0x73, 0xA0,
        0xCF, 0x0C, 0xD9, 0x7E, 0x93, 0xDC, 0x63, 0xB8,
        0x82, 0xEC, 0xF4, 0x30, 0xCE, 0x43, 0x92, 0xEA,
        0x5E, 0xD8, 0xC8, 0xA1, 0xEC, 0x79, 0xDC, 0xAE,
        0x64, 0xD4, 0x33, 0xEB, 0x53, 0x8C, 0xFC, 0x49,
        0x79, 0xBF, 0x7A, 0x28, 0x65, 0x1E, 0x8C, 0xD5,
        0x21, 0xB0, 0x8E, 0xCA, 0xAD, 0xF8, 0x96, 0x9A,
        0x98, 0x10, 0x00, 0x35, 0x6D, 0x58, 0x9A, 0xEF,
        0x84, 0x84, 0x86, 0x72, 0xBA, 0xCD, 0x38, 0x66,
        0x96, 0x9B, 0xC2, 0x83, 0xB0, 0x65, 0xC1, 0xAB,
        0xCF, 0x63, 0x8C, 0x2D, 0xC3, 0x42, 0xB2, 0x7D,
        0xF6, 0xB8, 0xF0, 0x3D, 0x26, 0x21, 0x8F, 0xAE,
        0x4E, 0x96, 0xF2, 0x55, 0x66, 0xBC, 0x6F, 0xED,
        0xE7, 0x19, 0xD3, 0x8D, 0xC0, 0xCD, 0x55, 0x20,
        0x5F, 0x10, 0xCA, 0xDA, 0x09, 0xED, 0x91, 0x4A,
        0x43, 0x33, 0xD3, 0x82, 0x11, 0x5C, 0x2F, 0x5D,
        0xEC, 0xCD, 0x54, 0xF9, 0x6C, 0xE4, 0xE5, 0xF2,
        0x68, 0xBC, 0xE9, 0x27, 0xB2, 0x1D, 0xCA, 0xB5,
        0xCD, 0x04, 0x01, 0x1E, 0x92, 0xF5, 0xF6, 0x01,
        0x86, 0x2B, 0x20, 0x20, 0x9B, 0xB0, 0xF9, 0x56,
        0xD9, 0x33, 0xD5, 0x0A, 0xEC, 0x1B, 0xF4, 0xCE,
        0xD2, 0xB2, 0xC2, 0xD4, 0x3F, 0x9A, 0x25, 0x76,
        0x8E, 0x29, 0x87, 0x52, 0x64, 0x86, 0x4A, 0xA5,
        0x7B, 0x5A, 0x91, 0x72, 0x6E, 0xBE, 0x6D, 0x73,
        0x0A, 0x8D, 0x89, 0x53, 0x82, 0x33, 0x70, 0x44,
        0x20, 0xBE, 0xE0, 0xB0, 0x1B, 0x76, 0x30, 0x43,
        0xA5, 0x5B, 0x8F, 0xAB, 0x7E, 0xB8, 0x61, 0x5F,
        0x43, 0x70, 0x1B, 0x1A, 0x71, 0x61, 0x56, 0xF9,
        0x13, 0x31, 0x2A, 0x64, 0x33, 0x14, 0x00, 0x98,
        0x72, 0xEC, 0x32, 0x88, 0x09, 0xFB, 0x64, 0x46,
        0x3D, 0x56, 0x02, 0xD9, 0x76, 0xD3, 0xAA, 0x90,
        0x0F, 0xBD, 0xF0, 0xF9, 0x96, 0x43, 0x7B, 0x62,
        0x19, 0x26, 0x22, 0x6A, 0x93, 0x91, 0xEC, 0x07,
        0x34, 0xF5, 0x22, 0x32, 0xB3, 0x65, 0x66, 0xE0,
        0x6B, 0x11, 0x7F, 0x97, 0x9F, 0x1A, 0x89, 0x46,
        0xCE, 0x8F, 0xBD, 0xFD, 0x2F, 0xCC, 0x3D, 0xBF,
        0xF2, 0x83, 0xA4, 0x30, 0xE1, 0x02, 0x72, 0xF8,
        0x74, 0xE6, 0x21, 0x96, 0x77, 0xE1, 0x57, 0x8A,
        0xF7, 0x9E, 0xB3, 0x31, 0xAF, 0xD8, 0xC5, 0xD7,
        0x20, 0xDC, 0xFD, 0xCF, 0x79, 0x06, 0x0F, 0x1F,
        0xE5, 0x84, 0x3D, 0x0B, 0x9C, 0xB3, 0xC7, 0xAB,
        0xB8, 0xF1, 0xC0, 0xD0, 0xB5, 0xC7, 0x01, 0xE2,
        0x0E, 0x3B, 0xAF, 0x7E, 0xAC, 0x44, 0x5A, 0x75,
        0x50, 0x0A, 0x76, 0x1C, 0x13, 0xDB, 0x25, 0xD4,
        0x0D, 0x19, 0x75, 0x4C, 0x02, 0xD9, 0xF3, 0xDF,
        0x6D, 0xBB, 0xCF, 0x47, 0xA6, 0xAE, 0xF6, 0xD1,
        0xFB, 0xF4, 0xB4, 0x55, 0xD3, 0xA5, 0x87, 0xA1,
        0x55, 0xFB, 0xBF, 0xCD, 0xF6, 0xA1, 0x64, 0x57,
        0x12, 0x75, 0x9A, 0x11, 0xA3, 0xCE, 0x42, 0x70,
        0x84, 0x54, 0x93, 0x12, 0xE1, 0x3A, 0x0F, 0xFA,
        0xCA, 0xF2, 0x25, 0x91, 0xF1, 0x4D, 0x8F, 0x84,
        0xB1, 0xB5, 0x35, 0xAC, 0xE9, 0x81, 0x77, 0x34,
        0x4D, 0x6F, 0x5D, 0x14, 0x9D, 0xB9, 0xE1, 0xF0,
        0x3F, 0x3C, 0xE7, 0xAD, 0x48, 0xE6, 0x8C, 0x51,
        0x86, 0xF4, 0x4A, 0xB4, 0xD0, 0x98, 0xEC, 0x3A,
        0x4E, 0xAB, 0x58, 0x2F, 0x08, 0x9E, 0x5A, 0x9D,
        0x45, 0x30, 0xB0, 0x85, 0xDF, 0x4A, 0xE7, 0x92,
        0xC6, 0xC8, 0x18, 0x93, 0x08, 0xCE, 0x9A, 0x8C,
        0xE2, 0x91, 0x8D, 0x91, 0x57, 0x7B, 0x37, 0xC8,
        0x80, 0xA2, 0x31, 0x10, 0x0D, 0x4E, 0xEF, 0x51,
        0x07, 0x94, 0x8E, 0xF8, 0x3C, 0x3C, 0x2E, 0xD5,
        0x03, 0x26, 0xB8, 0x72, 0x7F, 0xB9, 0xBC, 0xD7,
        0x95, 0xC4, 0x31, 0x08, 0xEC, 0x6F, 0xEE, 0x11,
        0xAF, 0xC0, 0xA2, 0xEC, 0xD7, 0xC8, 0x0B, 0xBE,
        0x15, 0xAE, 0xC9, 0x17, 0xBE, 0x37, 0xE2, 0x40,
        0x83, 0x65, 0xDE, 0xB3, 0x4E, 0xB4, 0x15, 0xB3,
        0x5C, 0x14, 0xF6, 0x5F, 0xA9, 0x1F, 0x70, 0xB5,
        0x23, 0x93, 0x78, 0xB9, 0x47, 0xF9, 0x1D, 0x2B,
        0x1E, 0x8D, 0xB1, 0x25, 0x7E, 0xE5, 0x85, 0x3C,
        0x16, 0x9F, 0xD0, 0xC2, 0x67, 0x8B, 0x0D, 0xD2,
        0x72, 0x4E, 0x74, 0x30, 0xE1, 0xAF, 0xB8, 0x66,
        0xCB, 0x53, 0xDF, 0xC4, 0xFB, 0xA5, 0x6D, 0x03,
        0xF2, 0xAE, 0xEE, 0x90, 0xFE, 0xD7, 0x30, 0xAF,
        0x33, 0x98, 0x09, 0xEB, 0x75, 0xC7, 0x3E, 0xC8,
        0x2F, 0xE7, 0x22, 0x5F, 0x2F, 0x0A, 0xBD, 0xA4,
        0x22, 0x88, 0x28, 0x19, 0x35, 0x83, 0x12, 0x86,
        0xEE, 0x72, 0xB4, 0x26, 0x89, 0x2F, 0xC7, 0x11,
        0x6E, 0xDD, 0x14, 0x98, 0x22, 0xE7, 0x73, 0x3E,
        0xFA, 0x46, 0x75, 0xF9, 0x40, 0xC1, 0x84, 0x22,
        0xBC, 0x75, 0x36, 0xC7, 0x82, 0xD3, 0xAE, 0x6E,
        0x0D, 0xBF, 0x6F, 0xC3, 0x4B, 0x67, 0x49, 0x19,
        0xF3, 0x4B, 0x12, 0xF2, 0x83, 0xFD, 0x39, 0x56,
        0x44, 0x05, 0x3A, 0x24, 0x6A, 0x35, 0x69, 0x12,
        0xCF, 0xE4, 0x93, 0xFE, 0x26, 0xCC, 0xD6, 0x01,
        0xA0, 0x4A, 0x84, 0xA8, 0x1D, 0x85, 0xE6, 0x83,
        0x0F, 0x3C, 0xE6, 0x6D, 0xD2, 0xCB, 0xB1, 0x14,
        0x8C, 0xEC, 0x10, 0xB3, 0x63, 0x4B, 0x9C, 0xF5,
        0x11, 0xE0, 0xF9, 0x86, 0x6F, 0xA7, 0xC0, 0x3B,
        0x9D, 0x25, 0xD7, 0x54, 0xCA, 0x40, 0x4D, 0x26,
        0xBA, 0x71, 0x8E, 0x25, 0xF5, 0xA7, 0xE3, 0x9B,
        0x25, 0x20, 0x7F, 0x29, 0x05, 0xB6, 0x27, 0x14,
        0x17, 0x67, 0x26, 0x10, 0xAD, 0xA3, 0x06, 0x03,
        0xFE, 0x82, 0x85, 0x5D, 0x01, 0x04, 0x4D, 0xE0,
        0x64, 0x38, 0x38, 0x5E, 0x83, 0x1E, 0x21, 0x9A,
        0x39, 0x02, 0xF8, 0xF9, 0x69, 0x85, 0x52, 0xE5,
        0xEC, 0x6A, 0xAC, 0x96, 0x86, 0xA7, 0x88, 0x69,
        0xB5, 0xB5, 0x7E, 0x03, 0x1D, 0xA9, 0x68, 0xCA,
        0x45, 0x0F, 0xF9, 0x14, 0xD6, 0x7B, 0xCF, 0x9C,
        0x03, 0x6F, 0xD1, 0xD9, 0x6F, 0x01, 0x3D, 0xF8,
        0xF3, 0x11, 0xF3, 0x29, 0x17, 0x90, 0xE8, 0x9B,
        0xED, 0x58, 0x9B, 0xF0, 0xBC, 0xC7, 0xBA, 0xF4,
        0x60, 0xC8, 0xAA, 0x30, 0xB4, 0x2F, 0x22, 0x8F,
        0xD3, 0xAC, 0x18, 0xC2, 0xB7, 0xC4, 0x7B, 0x31,
        0x9E, 0x0F, 0x7E, 0x9D, 0xBF, 0xD4, 0x63, 0xC2,
        0x8B, 0x1B, 0x58, 0x50, 0x33, 0x53, 0x6D, 0x79,
        0xBB, 0xF8, 0x0D, 0x91, 0x33, 0xD9, 0x07, 0xE7,
        0xB0, 0x81, 0xD4, 0xB4, 0x47, 0x61, 0x93, 0xF0,
        0xFB, 0x68, 0xBC, 0x1B, 0x41, 0xC2, 0xF5, 0x43,
        0x30, 0x7E, 0x76, 0xF9, 0xB1, 0xA3, 0xD6, 0xD4,
        0x26, 0xEA, 0x77, 0x75, 0x12, 0x7A, 0xC8, 0x30,
        0x9B, 0xCF, 0x45, 0xBE, 0x74, 0x7D, 0x8A, 0x8B,
        0xEC, 0xED, 0x11, 0xE6, 0xA1, 0xD1, 0xB8, 0xF1,
        0x90, 0xAD, 0x6D, 0x6A, 0xC6, 0x54, 0xE9, 0xDB,
        0xAD, 0x4C, 0x97, 0x39, 0xC8, 0xD8, 0x44, 0xA9,
        0x1A, 0x37, 0x16, 0x7E, 0x68, 0x45, 0x0C, 0xBB,
        0x10, 0xF4, 0xAE, 0x8E, 0x2B, 0x69, 0xFA, 0x95,
        0x3E, 0xA5, 0xC9, 0x91, 0xD3, 0xF1, 0xA3, 0x89,
        0x3F, 0x90, 0x86, 0x93, 0x1B, 0xF1, 0xA0, 0x89,
        0xC7, 0xF2, 0x23, 0x57, 0xD4, 0x8E, 0x2F, 0xD5,
        0x71, 0xCD, 0x36, 0xF1, 0x90, 0xB3, 0x98, 0x3E,
        0x19, 0xEA, 0xC8, 0x0F, 0x12, 0x9D, 0xBF, 0x58,
        0xED, 0xDC, 0x6B, 0x9A, 0x79, 0x84, 0xFC, 0xF0,
        0x4C, 0xC3, 0xB4, 0x0D, 0xB8, 0x7A, 0x8D, 0xAD,
        0x75, 0x40, 0xD5, 0xD5, 0xDE, 0xC8, 0xCA, 0x39,
        0x3E, 0x45, 0xE4, 0xBC, 0xF4, 0x33, 0xEA, 0x64,
        0xE1, 0x5E, 0x94, 0x42, 0x91, 0xAB, 0xBC, 0x42,
        0x2A, 0xB3, 0xD0, 0x60, 0x23, 0xCE, 0x57, 0x8E,
        0xFF, 0xAD, 0xA2, 0x2B, 0x64, 0xD9, 0x94, 0xA0,
        0x80, 0x0F, 0x8E, 0x50, 0x17, 0x08, 0x1D, 0x16,
        0xCF, 0x51, 0xD0, 0xB9, 0x28, 0xB6, 0x59, 0xEF,
        0x78, 0xCC, 0xC9, 0x96, 0xF9, 0xCA, 0x87, 0x7A,
        0xEE, 0xD9, 0x15, 0x5E, 0xDF, 0x5D, 0xBC, 0xC2,
        0x58, 0xE6, 0x04, 0xEE, 0x17, 0xDC, 0xB3, 0xF9,
        0x90, 0xF9, 0x88, 0x32, 0x9E, 0xA1, 0xDB, 0x1C,
        0x38, 0x56, 0x53, 0x90, 0x30, 0x69, 0x2E, 0x52,
        0x00, 0x2C, 0xF3, 0x0F, 0xD5, 0x80, 0x2E, 0x02,
        0x5B, 0x99, 0xBF, 0xCD, 0x11, 0x12, 0x64, 0x5B,
        0x56, 0xC6, 0x0A, 0xE6, 0x38, 0xE7, 0x4D, 0x21,
        0xE5, 0x98, 0x78, 0x9D, 0xE6, 0xCB, 0x60, 0xB4,
        0x2E, 0xE4, 0x98, 0x56, 0xCB, 0xAD, 0xE6, 0xDD,
        0x53, 0xF4, 0xC5, 0x67, 0xA2, 0x9F, 0xA0, 0x5C,
        0x7C, 0xFB, 0x24, 0x5A, 0xA7, 0x72, 0xD0, 0xE7,
        0x63, 0xF2, 0x5D, 0xBF, 0xD8, 0xE9, 0xF1, 0x6B,
        0xB4, 0x29, 0xA6, 0x28, 0xE6, 0x93, 0xD3, 0x87,
        0xB6, 0xD9, 0x3C, 0x39, 0x8D, 0xEA, 0x28, 0xC0,
        0x96, 0x3D, 0xF5, 0xC2, 0x3C, 0x29, 0xF2, 0x80,
        0x21, 0x8A, 0x03, 0x9D, 0x64, 0xF8, 0xBA, 0x81,
        0xC1, 0xDD, 0xA2, 0x88, 0x2A, 0x84, 0x2E, 0x3C,
        0xB5, 0x03, 0x95, 0xED, 0xAA, 0x6E, 0xE2, 0x6F,
        0x5E, 0x99, 0x3C, 0x63, 0xEE, 0xB8, 0x4F, 0x66,
        0x32, 0x77, 0x42, 0x23, 0x36, 0x29, 0x89, 0xB0,
        0xED, 0x5F, 0xF2, 0x5A, 0x65, 0x66, 0x3F, 0xD2,
        0x8B, 0x48, 0x68, 0x65, 0xDC, 0xE0, 0xB0, 0xC2,
        0x72, 0x73, 0xF1, 0xA4, 0xC6, 0x56, 0x2C, 0x5D,
        0xD8, 0xC6, 0x5C, 0x41, 0xCE, 0x30, 0x89, 0x59,
        0xA9, 0xD6, 0x45, 0x96, 0xD0, 0x8E, 0x7B, 0x25,
        0xE0, 0x13, 0xFB, 0xFE, 0x7C, 0xEA, 0xF3, 0x67,
        0x0D, 0xB2, 0x9A, 0x21, 0x3C, 0xCE, 0x99, 0x75,
        0xA9, 0x13, 0xCE, 0xF4, 0x23, 0x6E, 0x64, 0x00,
        0x30, 0x87, 0x70, 0x9C, 0xAD, 0x61, 0x81, 0x71,
        0x0E, 0x95, 0x19, 0x26, 0xCA, 0x55, 0x29, 0x71,
        0x99, 0xA6, 0x08, 0xAE, 0x54, 0x58, 0x75, 0xCD,
        0xC3, 0x8F, 0xE3, 0x83, 0xC1, 0x45, 0x62, 0xB4,
        0x8D, 0xCA, 0x66, 0x02, 0xEA, 0x34, 0x05, 0x5D,
        0x98, 0x3F, 0x38, 0xE6, 0x1C, 0xCE, 0x53, 0x1A,
        0xD9, 0x3F, 0x58, 0xEC, 0x16, 0x28, 0x45, 0xF5,
        0x38, 0xCE, 0x48, 0x43, 0x87, 0x1D, 0x3C, 0x4A,
        0xDF, 0x05, 0xF3, 0x5E, 0x29, 0x7E, 0xA6, 0x2E,
        0xFC, 0xDD, 0x5E, 0xF9, 0x40, 0x1B, 0xA0, 0x42,
        0xA2, 0x35, 0x15, 0x0A, 0x09, 0xD9, 0x47, 0x4A,
        0x3F, 0xB0, 0x3A, 0xAA, 0x19, 0xE7, 0xE3, 0x7A,
        0x22, 0x8D, 0x5F, 0x5B, 0x07, 0x41, 0x4C, 0x3D,
        0xA2, 0xAD, 0x2E, 0x5C, 0x75, 0xEC, 0xF0, 0x4C,
        0x11, 0x2B, 0x90, 0x76, 0x9E, 0x19, 0x96, 0x0E,
        0x97, 0x5E, 0x8D, 0x19, 0x17, 0xB3, 0xBF, 0xDA,
        0x84, 0xFD, 0xC6, 0xD2, 0x32, 0x6F, 0xB8, 0xA3,
        0xB0, 0x0F, 0x95, 0xD9, 0xC5, 0x26, 0x50, 0x11,
        0x15, 0x72, 0xBE, 0xC2, 0x1B, 0x12, 0x12, 0x7C,
        0xA5, 0x70, 0xD8, 0xA9, 0x8A, 0xB9, 0x77, 0xEB,
        0xD8, 0xD7, 0x9A, 0x59, 0x37, 0x5E, 0xE1, 0x4F,
        0x64, 0xB5, 0xB0, 0x4F, 0xD9, 0x69, 0xFE, 0xB0,
        0x3D, 0x0A, 0xF7, 0x34, 0x89, 0xE3, 0xBA, 0xEF,
        0xE7, 0xC7, 0xBC, 0x8D, 0xC7, 0xE8, 0x54, 0x83,
        0xEE, 0x62, 0xF0, 0x23, 0x98, 0x58, 0x0F, 0x83,
        0xB9, 0x6D, 0xD8, 0x44, 0x77, 0xB9, 0xC4, 0x8F,
        0x0B, 0xB3, 0x9F, 0x54, 0x06, 0xA3, 0x70, 0x36,
        0xD6, 0xF3, 0x6E, 0x2B, 0x1B, 0x6B, 0x53, 0xFE,
        0x6F, 0xF6, 0x1C, 0x32, 0x7B, 0x29, 0xD4, 0xE0,
        0x5D, 0xD2, 0xB8, 0x11, 0x74, 0xC6, 0x0B, 0x59,
        0xC7, 0x9C, 0xB1, 0x97, 0x6B, 0xC0, 0x6E, 0x7A,
        0xC3, 0x4D, 0xF3, 0xE3, 0x8F, 0x7D, 0x2C, 0x1C,
        0x0E, 0x31, 0x51, 0xB7, 0x14, 0x7A, 0xB8, 0x31,
        0x77, 0x47, 0x70, 0x14, 0x3B, 0x92, 0x7B, 0x5F,
        0xEC, 0x5D, 0xF7, 0x76, 0xC1, 0xD7, 0x2D, 0xB6,
        0xBC, 0x99, 0x81, 0xD6, 0x58, 0x67, 0x71, 0x3C,
        0xF2, 0x97, 0xC8, 0xB0, 0xF1, 0xE9, 0x8D, 0x0E,
        0x16, 0xF0, 0xCC, 0x22, 0x7A, 0x39, 0xE4, 0x7E,
        0x50, 0xBA, 0x01, 0x16, 0x15, 0x6D, 0x5B, 0x54,
        0x67, 0x53, 0x66, 0x04, 0xBE, 0x05, 0xCC, 0x2E,
        0xF4, 0x0A, 0xBC, 0xE8, 0x52, 0xF1, 0x5D, 0xFA,
        0x2C, 0xAC, 0xF8, 0x6A, 0x78, 0x9E, 0x5B, 0x7B,
        0x0E, 0x5B, 0xB4, 0xB7, 0x77, 0xCD, 0x7C, 0xC9,
        0xF6, 0x54, 0x77, 0x9B, 0x10, 0x2F, 0x78, 0xB5,
        0xAA, 0x4B, 0x94, 0xC3, 0xB4, 0xFD, 0xE5, 0x5F,
        0xA7, 0xF7, 0xBF, 0x54, 0xAC, 0x22, 0x5E, 0x1F,
        0x26, 0x16, 0x5B, 0x65, 0xF1, 0x6D, 0x03, 0x21,
        0x66, 0x9F, 0xD9, 0xF6, 0xE4, 0x7F, 0xCA, 0x1D,
        0xD3, 0x47, 0x09, 0x6D, 0xF5, 0xDD, 0xA8, 0x64,
        0x66, 0xA5, 0x7C, 0x5B, 0x06, 0x8D, 0x9C, 0x67,
        0xB7, 0x32, 0x03, 0x66, 0xEA, 0x19, 0xC8, 0x99,
        0x3F, 0xF9, 0x0B, 0xD8, 0xFB, 0x06, 0x93, 0xFB,
        0xA3, 0x70, 0xE6, 0x6D, 0x2B, 0x20, 0x3B, 0x99,
        0x70, 0x11, 0xB0, 0xD1, 0x5B, 0x94, 0xE2, 0x8B,
        0xAA, 0x2E, 0xBF, 0x01, 0x77, 0x4F, 0x7A, 0xE7,
        0x8F, 0x84, 0xED, 0xBD, 0xAD, 0x9F, 0x65, 0xA4,
        0x50, 0x42, 0x7A, 0x47, 0x74, 0xC6, 0x0C, 0xC8,
        0x9A, 0x02, 0x0B, 0x37, 0xDA, 0x21, 0xC7, 0x91,
        0xDA, 0xC8, 0xF7, 0xA7, 0x45, 0x7E, 0x30, 0xD0,
        0x8B, 0x01, 0x37, 0x51, 0x60, 0x03, 0x9C, 0x30,
        0x1B, 0x60, 0x51, 0xA9, 0x65, 0xE8, 0xA7, 0xCC,
        0xA2, 0xAE, 0xF9, 0x3B, 0xD5, 0x2F, 0x82, 0xC0,
        0x20, 0xBE, 0xCE, 0x90, 0xA1, 0x29, 0x02, 0x4E,
        0xFE, 0xA4, 0xB2, 0xFA, 0x21, 0x27, 0x0F, 0x8E,
        0xB5, 0xED, 0x6A, 0xAA, 0xE5, 0x59, 0x29, 0xAA,
        0xC5, 0x99, 0xA5, 0x77, 0x97, 0x29, 0x57, 0x66,
        0x0C, 0xC4, 0x7A, 0xC4, 0xE3, 0xCE, 0x77, 0x2B,
        0xBF, 0x10, 0x05, 0x2D, 0xE7, 0xED, 0xB1, 0xB8,
        0xA4, 0x49, 0x41, 0xF8, 0x84, 0xC9, 0xF8, 0xBE,
        0x13, 0x17, 0x46, 0x69, 0x94, 0x56, 0x29, 0xF4,
        0x6D, 0xE2, 0x46, 0x74, 0x44, 0xF3, 0x10, 0x6A,
        0x73, 0xFA, 0x27, 0x9C, 0xF0, 0x2A, 0x80, 0x0A,
        0x04, 0x7E, 0x20, 0xBD, 0x4D, 0x82, 0x0B, 0x38,
        0x9C, 0x3B, 0xB6, 0xA8, 0x68, 0xA5, 0x38, 0x4C,
        0xF5, 0x72, 0x4C, 0x20, 0x4C, 0xEF, 0xB1, 0xA6,
        0xA1, 0xBE, 0xB9, 0x72, 0x3E, 0x36, 0xDD, 0xDD,
        0xD9, 0xC7, 0x07, 0xC8, 0xF6, 0x3E, 0x8B, 0xC2,
        0x66, 0x83, 0xCC, 0x8B, 0x43, 0xC7, 0xDF, 0xDA,
        0xA4, 0x08, 0xAC, 0x4D, 0xD2, 0xBA, 0x9A, 0xEC,
        0xBC, 0x3B, 0x6D, 0xDA, 0xED, 0xCE, 0x09, 0x4A,
        0xAB, 0x58, 0xFF, 0x73, 0x2B, 0x19, 0x66, 0x38,
        0xD8, 0xB8, 0xEF, 0xC4, 0x28, 0xBB, 0xA9, 0x61,
        0x57, 0x93, 0xC4, 0xDD, 0x9F, 0x00, 0xF9, 0x0D,
        0x62, 0xC6, 0x76, 0xD1, 0x27, 0xA0, 0xE1, 0x8C,
        0x14, 0xC6, 0xEE, 0x9C, 0x99, 0x05, 0x10, 0xB0,
        0x54, 0xAD, 0xB4, 0xB4, 0x17, 0x0A, 0xC7, 0x12,
        0x7F, 0x93, 0x17, 0x5C, 0x1E, 0xB2, 0x25, 0x12
    };
    static const byte msg_87_draft[] = {
        0x14, 0x42, 0x63, 0x34, 0x94, 0x09, 0x60, 0x77,
        0x3B, 0xFF, 0x65, 0xF0, 0x8D, 0x1D, 0xE4, 0x89,
        0xC4, 0xC3, 0xED, 0x36
    };
    static const byte sig_87_draft[] = {
        0x13, 0xE8, 0x99, 0xEE, 0xDC, 0xCC, 0x0F, 0xBA,
        0x62, 0x91, 0x44, 0xE4, 0xAC, 0x06, 0x79, 0x06,
        0xB5, 0x32, 0x6B, 0x8F, 0x9A, 0x6C, 0xCB, 0xAB,
        0xE1, 0x44, 0x4A, 0xDD, 0x46, 0x45, 0x16, 0x0D,
        0x22, 0x57, 0x82, 0x87, 0x10, 0xD1, 0xEE, 0x10,
        0x60, 0x21, 0xB5, 0x64, 0x1E, 0x78, 0x81, 0x55,
        0x75, 0xD4, 0xF0, 0x95, 0xD0, 0x15, 0xD8, 0x46,
        0x5C, 0x92, 0xD2, 0xDD, 0xF4, 0xAB, 0xDF, 0xBE,
        0xB1, 0x1E, 0xE5, 0xE0, 0x70, 0xE6, 0xDA, 0x52,
        0xE5, 0x48, 0xDC, 0x04, 0xFD, 0xEF, 0x54, 0x72,
        0xE7, 0xE5, 0xF1, 0x82, 0x10, 0xAA, 0xCB, 0xA0,
        0x4F, 0x4F, 0x18, 0xAE, 0x66, 0x86, 0xB9, 0xAF,
        0x96, 0x57, 0xE3, 0x8E, 0x3B, 0x9B, 0xDD, 0xB4,
        0xAA, 0x84, 0xE6, 0x7B, 0x4D, 0x81, 0x92, 0xD0,
        0x03, 0x87, 0x3D, 0xD3, 0xEE, 0xE7, 0x47, 0x00,
        0xFB, 0xD8, 0x1E, 0x38, 0x1C, 0x21, 0x98, 0xB7,
        0xCC, 0xC1, 0x37, 0xC1, 0x71, 0xB2, 0x2F, 0x93,
        0x53, 0x41, 0x9C, 0x48, 0xC1, 0x4B, 0x8D, 0x63,
        0x0F, 0x99, 0x63, 0x40, 0x27, 0x5F, 0x6E, 0x60,
        0x4B, 0x95, 0xC4, 0x35, 0x20, 0x8A, 0xED, 0x2B,
        0xCA, 0x1B, 0x41, 0x9F, 0x83, 0x63, 0xF0, 0x95,
        0x0E, 0x24, 0x0D, 0x6F, 0x9E, 0xAB, 0x11, 0x8E,
        0x4B, 0xD3, 0xDA, 0x0E, 0xC3, 0xA2, 0xBE, 0x26,
        0xA8, 0xA0, 0x98, 0x57, 0x71, 0x3C, 0x36, 0xDD,
        0x69, 0xC3, 0x4E, 0xDD, 0x2C, 0x61, 0x9E, 0x88,
        0x26, 0x70, 0x71, 0xCF, 0x9E, 0xE5, 0xA6, 0x0C,
        0xA3, 0x14, 0x2D, 0xF1, 0x63, 0xF0, 0x1D, 0x8D,
        0x79, 0x6A, 0xC8, 0x50, 0xCF, 0xF3, 0x66, 0x60,
        0x78, 0xB3, 0x18, 0xFB, 0x5B, 0xD1, 0x73, 0x60,
        0xC8, 0x76, 0xC9, 0xC9, 0x0D, 0x8A, 0x7F, 0x41,
        0x2C, 0x8A, 0x31, 0x61, 0x6B, 0xE7, 0xA3, 0x74,
        0x58, 0x71, 0x54, 0x84, 0x86, 0x71, 0x5C, 0x94,
        0x26, 0x3A, 0x17, 0xB3, 0x6C, 0xA4, 0x99, 0x25,
        0x45, 0x0C, 0x57, 0x8A, 0xD9, 0xD4, 0xB1, 0xC2,
        0x00, 0x43, 0xF4, 0x5E, 0x84, 0x31, 0x99, 0x4F,
        0xA6, 0xD2, 0x6A, 0x14, 0x1B, 0xAD, 0x9E, 0x49,
        0x6E, 0x00, 0x9E, 0x91, 0x46, 0x16, 0xCA, 0x57,
        0x0C, 0x09, 0xF6, 0x38, 0xD0, 0x62, 0xBE, 0xC6,
        0x87, 0x33, 0x3A, 0xC7, 0x28, 0x38, 0x34, 0x53,
        0x7E, 0xFB, 0x60, 0x42, 0xF3, 0x7D, 0x83, 0xF7,
        0x29, 0x5D, 0xEA, 0x30, 0xD5, 0x00, 0x90, 0xB6,
        0x38, 0x4C, 0x17, 0x29, 0xEF, 0x17, 0xA0, 0xD5,
        0x87, 0x50, 0xC0, 0x03, 0x75, 0x14, 0xE5, 0xE1,
        0x22, 0x78, 0x53, 0xBC, 0x5A, 0xA3, 0x1E, 0x95,
        0xBE, 0xEC, 0x37, 0xB1, 0x51, 0x82, 0x69, 0x26,
        0x2E, 0xA3, 0x5A, 0xDA, 0x4F, 0xDA, 0x77, 0x62,
        0x7E, 0xED, 0xDA, 0xAF, 0x57, 0x97, 0x1B, 0xA3,
        0x6D, 0x46, 0x7B, 0x19, 0xA9, 0x0B, 0x99, 0x1C,
        0xD2, 0x55, 0xDB, 0x79, 0xB0, 0x15, 0x48, 0x86,
        0x52, 0x30, 0x31, 0xD6, 0xC5, 0xB1, 0xAE, 0x8F,
        0xCF, 0x9A, 0x43, 0x10, 0xBB, 0xC8, 0x19, 0x74,
        0x84, 0xB2, 0x92, 0x3B, 0xFE, 0x0B, 0x12, 0x15,
        0xA1, 0xC4, 0xD8, 0xC6, 0x83, 0x90, 0x89, 0x8A,
        0xD5, 0x3E, 0x33, 0x69, 0xB7, 0x05, 0x3F, 0xB1,
        0x8B, 0x0D, 0x87, 0x40, 0x70, 0x90, 0x2A, 0x5D,
        0x3B, 0x3D, 0x91, 0xD8, 0x1D, 0x4D, 0xF1, 0x08,
        0x7E, 0xF7, 0xDC, 0x05, 0x84, 0xEB, 0xDC, 0x63,
        0xD7, 0xBA, 0x3C, 0x0D, 0x31, 0xF8, 0x6D, 0xA6,
        0xC0, 0xFD, 0x08, 0x11, 0x5C, 0x53, 0xF6, 0xAE,
        0xFE, 0xC0, 0x82, 0x9A, 0x68, 0xD2, 0xA3, 0x44,
        0x2E, 0xEE, 0x47, 0x36, 0x70, 0x2D, 0x66, 0x81,
        0x0D, 0x62, 0x30, 0x8A, 0x8C, 0xC8, 0x2A, 0xA6,
        0x21, 0x82, 0xF5, 0x98, 0xF4, 0x4E, 0x25, 0x37,
        0x11, 0xB5, 0xD6, 0x07, 0x88, 0xBD, 0x0D, 0x69,
        0x0E, 0xF9, 0x8F, 0x9A, 0xD5, 0x93, 0xE0, 0x3C,
        0xEF, 0x38, 0xB9, 0xC9, 0x77, 0x98, 0x3F, 0x69,
        0x11, 0xBA, 0x1A, 0xB9, 0xF7, 0x35, 0xE9, 0x28,
        0xCD, 0xA3, 0x8C, 0x03, 0xE6, 0xAD, 0x83, 0x62,
        0xF4, 0x60, 0xAE, 0x4C, 0xD0, 0xF4, 0x6E, 0x00,
        0xEE, 0xEC, 0x74, 0xB6, 0x12, 0x34, 0x98, 0xAB,
        0x31, 0xE7, 0xA7, 0x9D, 0x33, 0x4D, 0x72, 0xA7,
        0xA7, 0xEE, 0xF3, 0xB5, 0x51, 0xE7, 0x8D, 0x31,
        0xBC, 0x2C, 0xAF, 0xFB, 0x13, 0x9C, 0xAC, 0xA4,
        0xD7, 0x9C, 0x8B, 0xBD, 0x52, 0xBD, 0x78, 0xF4,
        0x90, 0x65, 0x09, 0xBE, 0x42, 0xE7, 0x76, 0x3A,
        0xE6, 0xAC, 0xB8, 0x98, 0x28, 0x5E, 0xC9, 0x32,
        0x3E, 0x68, 0x67, 0x6A, 0x8C, 0xC7, 0x4A, 0x58,
        0xC8, 0xDA, 0x8B, 0xE9, 0x11, 0xED, 0x6F, 0x51,
        0x3B, 0x66, 0x08, 0x70, 0x73, 0x10, 0xFB, 0x45,
        0xCB, 0xD9, 0x7D, 0x5F, 0xF0, 0xD2, 0xAB, 0xA3,
        0x6F, 0xCE, 0xF7, 0x3D, 0x46, 0xCB, 0x7F, 0x01,
        0xC2, 0xCF, 0xE3, 0x8E, 0x68, 0xE8, 0x4F, 0x4A,
        0x30, 0x19, 0x16, 0xD2, 0xF5, 0x10, 0xD8, 0x2B,
        0x49, 0x69, 0xBE, 0x7A, 0x0E, 0x9C, 0xC6, 0x0E,
        0xFF, 0x5C, 0x0A, 0x87, 0x17, 0xB8, 0x22, 0x83,
        0x8C, 0x77, 0xAF, 0x42, 0x06, 0xB1, 0x25, 0x45,
        0x08, 0x9B, 0xB2, 0xDD, 0x6A, 0x3F, 0xF0, 0x12,
        0xC8, 0x64, 0x15, 0xBB, 0xA0, 0x4F, 0xD7, 0xD4,
        0xEC, 0x70, 0x7A, 0xF3, 0xB1, 0x7F, 0x25, 0x57,
        0x47, 0x66, 0xF1, 0xE9, 0x27, 0x38, 0xE0, 0x62,
        0x10, 0xF4, 0x8A, 0x5E, 0xF2, 0x55, 0x0E, 0xBD,
        0xF8, 0x5A, 0x5C, 0xA3, 0x44, 0x97, 0xCF, 0x1D,
        0x4D, 0x3A, 0x75, 0x86, 0x48, 0xEC, 0x41, 0x17,
        0x24, 0x43, 0x83, 0x5E, 0x50, 0x91, 0xBE, 0x8F,
        0x04, 0x78, 0x23, 0xD9, 0x62, 0x0C, 0x2A, 0xD5,
        0x1C, 0x96, 0x11, 0xAA, 0xEE, 0x39, 0xB2, 0x1E,
        0x6D, 0x6A, 0xEC, 0x87, 0x0C, 0x89, 0x15, 0xE2,
        0x66, 0x47, 0x6A, 0x50, 0xEE, 0xCA, 0x59, 0x96,
        0x22, 0xF7, 0x09, 0x1A, 0x34, 0xC2, 0x3F, 0x14,
        0xB4, 0x04, 0x29, 0xD9, 0x5E, 0x3E, 0xF9, 0x8F,
        0xED, 0x3E, 0x74, 0x94, 0x37, 0xF0, 0x4B, 0xB4,
        0xA3, 0x37, 0x52, 0x2E, 0x68, 0x09, 0xFC, 0x10,
        0x45, 0x03, 0xE2, 0x53, 0xB4, 0x1C, 0x4F, 0x03,
        0x01, 0xAF, 0x46, 0x7F, 0x74, 0xD3, 0x31, 0x25,
        0xFA, 0x83, 0xEF, 0x71, 0x24, 0x45, 0xA1, 0x71,
        0xFA, 0x40, 0xEB, 0xF4, 0xE6, 0x55, 0x3E, 0x45,
        0x4A, 0xFE, 0x25, 0x68, 0x02, 0x1D, 0x2B, 0x2A,
        0x19, 0x8D, 0xEC, 0x9B, 0xF7, 0x20, 0xF9, 0xD7,
        0x2F, 0x81, 0x52, 0x0B, 0xE8, 0x74, 0x66, 0xAF,
        0x70, 0xD0, 0x0E, 0x0E, 0x86, 0x0F, 0xF9, 0xAB,
        0xD0, 0x39, 0x78, 0xC3, 0xE4, 0x29, 0xB5, 0xAA,
        0x17, 0xB9, 0x7F, 0x9A, 0xE9, 0x34, 0x48, 0x85,
        0x3D, 0x6E, 0xFD, 0x16, 0x8A, 0x30, 0xC6, 0xCB,
        0xE8, 0xDE, 0x2D, 0x28, 0x8D, 0x9A, 0x24, 0xEA,
        0x5D, 0x2A, 0x58, 0x23, 0x33, 0x2B, 0x84, 0xFD,
        0x2C, 0xE7, 0x93, 0xA2, 0x2B, 0xEC, 0x43, 0x98,
        0x48, 0xD4, 0xE6, 0x0F, 0x3B, 0xB9, 0xC7, 0x5D,
        0x7E, 0xB0, 0x87, 0x1E, 0x80, 0x3D, 0x61, 0xB0,
        0x7E, 0x74, 0x9E, 0xD7, 0x60, 0x72, 0xB2, 0x7C,
        0x87, 0xB6, 0x9D, 0x6C, 0x01, 0x42, 0x61, 0xF6,
        0x47, 0xAF, 0xA8, 0x8C, 0x4F, 0x1E, 0xC5, 0x5A,
        0x75, 0xA5, 0x0F, 0xB4, 0xC7, 0x9D, 0x2C, 0x94,
        0xC0, 0x50, 0x3D, 0xB2, 0x0D, 0xFD, 0xF7, 0x1F,
        0x62, 0x88, 0x74, 0x18, 0x8C, 0xDD, 0x73, 0x85,
        0xC0, 0x33, 0x81, 0xDA, 0xBB, 0x85, 0x4D, 0x4A,
        0xA9, 0xF4, 0x7B, 0x66, 0x43, 0x8C, 0x43, 0xFF,
        0x53, 0xEF, 0x5E, 0x78, 0xAB, 0x45, 0x0B, 0x45,
        0x01, 0x91, 0x27, 0x8A, 0xF6, 0xE2, 0x6A, 0x7B,
        0x5E, 0x64, 0x61, 0xF5, 0x77, 0xF9, 0x85, 0x2F,
        0x81, 0xC9, 0x02, 0x03, 0xC7, 0x13, 0xF5, 0xB1,
        0xF6, 0xC3, 0xEF, 0x55, 0x8C, 0x90, 0x32, 0x51,
        0x6D, 0x8D, 0x62, 0xFD, 0x5E, 0x24, 0xE4, 0xF0,
        0xF5, 0x07, 0x18, 0xF5, 0x6B, 0x5A, 0x59, 0xA0,
        0x09, 0xD5, 0x93, 0x8D, 0xAD, 0x55, 0x91, 0xF6,
        0x1F, 0x4C, 0x65, 0x9A, 0x76, 0x05, 0x26, 0xEF,
        0x41, 0x20, 0x2F, 0xA7, 0xE5, 0xF6, 0xC7, 0xD5,
        0xE0, 0xB0, 0xC0, 0xC4, 0x3B, 0x52, 0x4B, 0x66,
        0x71, 0x2C, 0x5A, 0x7C, 0x53, 0xC8, 0x4C, 0x50,
        0xB8, 0x3E, 0xB9, 0xC9, 0x8D, 0x2F, 0xD0, 0x84,
        0xC9, 0xC5, 0xF2, 0x1F, 0xEE, 0x77, 0x42, 0xE6,
        0xEF, 0xC8, 0xCB, 0xBE, 0x57, 0x18, 0xB7, 0x0C,
        0x06, 0x2D, 0x82, 0xE2, 0xF9, 0x86, 0xF3, 0x8D,
        0xF1, 0xE7, 0x15, 0x89, 0xDC, 0x79, 0x87, 0x24,
        0x35, 0x62, 0xA2, 0x31, 0x9D, 0x7C, 0x00, 0xB2,
        0x6E, 0x53, 0x1E, 0x93, 0xC3, 0x84, 0x44, 0x61,
        0x8C, 0xE7, 0x58, 0x73, 0x4F, 0xDE, 0xCF, 0xD0,
        0xC6, 0x85, 0x37, 0x28, 0xC6, 0x10, 0x00, 0x78,
        0x4E, 0xDF, 0xFE, 0xD7, 0xB3, 0x30, 0x86, 0xE1,
        0x68, 0xD6, 0xCB, 0x63, 0xE3, 0xDA, 0xCA, 0xF3,
        0x55, 0x2F, 0x88, 0x5B, 0x47, 0x82, 0x62, 0xDE,
        0x5E, 0x1E, 0x63, 0xCE, 0x7A, 0x4C, 0x66, 0x95,
        0xD1, 0x19, 0x38, 0x35, 0xE4, 0x5A, 0x67, 0x91,
        0x8C, 0x42, 0xD3, 0x9B, 0xF8, 0x80, 0x38, 0x53,
        0x30, 0x31, 0x0F, 0x2C, 0x7B, 0xF9, 0x1E, 0x6C,
        0x3E, 0x29, 0xB7, 0x81, 0xD0, 0x98, 0x70, 0xC2,
        0x6D, 0x76, 0xBD, 0x8A, 0xE2, 0x09, 0xC4, 0x2B,
        0xC7, 0x43, 0x2D, 0xBB, 0x4C, 0x16, 0x52, 0x63,
        0x57, 0xA5, 0x63, 0x4E, 0xEC, 0xDE, 0x93, 0xC5,
        0x1D, 0xD4, 0xD6, 0xF0, 0x06, 0x5B, 0x2E, 0xC5,
        0x7A, 0xD3, 0xB5, 0x82, 0x66, 0x53, 0x95, 0x97,
        0xC8, 0xF4, 0x2B, 0x55, 0x27, 0x1D, 0x6F, 0x90,
        0xE9, 0x86, 0xF6, 0x82, 0x8D, 0x95, 0x9E, 0xE8,
        0x00, 0xDB, 0xEB, 0xCF, 0x48, 0x23, 0x6B, 0xA3,
        0xDE, 0x25, 0x27, 0xE0, 0xEC, 0xA4, 0xA3, 0xC2,
        0xA3, 0x4B, 0xBC, 0xDD, 0x6C, 0xBB, 0x3A, 0x9C,
        0x96, 0xDC, 0x3B, 0xE1, 0x10, 0xD3, 0x49, 0x94,
        0x66, 0xE2, 0x85, 0x7F, 0xBA, 0x98, 0x12, 0x3A,
        0x6D, 0xBA, 0x90, 0x14, 0x87, 0x7E, 0x24, 0xEA,
        0xDC, 0xCA, 0x40, 0xF8, 0xAE, 0x94, 0xB2, 0xFE,
        0xD2, 0x36, 0xCB, 0xE5, 0xBC, 0xA9, 0xDF, 0xE0,
        0xCB, 0xA9, 0xA0, 0xF8, 0x62, 0x41, 0x33, 0x18,
        0x59, 0xF9, 0xD6, 0xC0, 0x87, 0xB2, 0x76, 0xDE,
        0xC9, 0x35, 0x6F, 0x1F, 0xEF, 0x69, 0xB3, 0x59,
        0xF9, 0xFB, 0x38, 0x4A, 0x84, 0x02, 0x2D, 0xEC,
        0xB7, 0x01, 0x08, 0xDA, 0xC8, 0xE9, 0x3B, 0xB6,
        0xC3, 0x00, 0xC0, 0x34, 0x5F, 0xC6, 0x40, 0xC0,
        0x06, 0xEA, 0xEB, 0xC1, 0x51, 0x13, 0x81, 0x2F,
        0xB3, 0x7D, 0xD9, 0x6E, 0x2A, 0x06, 0xA4, 0x63,
        0xAF, 0xCE, 0x66, 0xC5, 0x9F, 0x8D, 0x71, 0x4A,
        0xA1, 0xFF, 0x49, 0x4F, 0x08, 0x6F, 0xB9, 0xEA,
        0xDA, 0x18, 0x45, 0x63, 0xCA, 0x9D, 0x88, 0x08,
        0xB1, 0x6C, 0x19, 0xA8, 0x24, 0xAD, 0x85, 0x7D,
        0xDE, 0x51, 0xE5, 0x08, 0xB7, 0x04, 0x12, 0x35,
        0xF3, 0x00, 0xED, 0x2C, 0x79, 0x9C, 0x18, 0x23,
        0x05, 0x38, 0x95, 0x76, 0xCF, 0x39, 0x3C, 0xAE,
        0xB0, 0xD3, 0xBA, 0x3E, 0x4E, 0xE4, 0xB5, 0x77,
        0xA3, 0xE3, 0x7B, 0x27, 0x5F, 0xD8, 0x05, 0x19,
        0x42, 0xAE, 0x91, 0x54, 0xE5, 0xBD, 0x7C, 0x35,
        0xE0, 0xF8, 0x95, 0x52, 0x3A, 0x29, 0xB0, 0xE6,
        0xB7, 0xAE, 0x20, 0xBE, 0x21, 0xDF, 0xF5, 0x67,
        0xEC, 0x82, 0x52, 0xFF, 0x5B, 0xD0, 0xAA, 0x14,
        0x50, 0x15, 0xE1, 0x1C, 0x6A, 0x1B, 0x94, 0x1B,
        0xCC, 0x76, 0x01, 0xBF, 0x03, 0x94, 0x42, 0xF2,
        0x00, 0x61, 0x96, 0x58, 0xD9, 0xD0, 0x40, 0x21,
        0xFA, 0xCE, 0x6B, 0xAB, 0x5D, 0x49, 0xD8, 0xD7,
        0xBC, 0x9A, 0x66, 0xC2, 0xBA, 0x3F, 0xDC, 0x49,
        0x0D, 0xA5, 0x5C, 0xB4, 0x67, 0x08, 0x38, 0xEB,
        0x2D, 0x07, 0x24, 0x5B, 0xB1, 0x22, 0x7B, 0x02,
        0x4A, 0x8A, 0x53, 0x38, 0xE9, 0x42, 0x8E, 0xA5,
        0x57, 0x41, 0xD6, 0x71, 0xA7, 0x9D, 0x6A, 0x14,
        0xD2, 0x7D, 0x13, 0xFB, 0x59, 0xD0, 0xDA, 0xE5,
        0x23, 0x9E, 0x1B, 0xC4, 0x21, 0x87, 0xBB, 0x78,
        0xE0, 0x38, 0x01, 0x1D, 0xA0, 0xD1, 0x36, 0x3F,
        0xD0, 0xA7, 0x8F, 0x86, 0x26, 0x1E, 0xB0, 0x26,
        0xDE, 0x7E, 0x17, 0x3A, 0x90, 0xFC, 0xC0, 0x17,
        0xDD, 0x78, 0xF5, 0xA3, 0x2D, 0x3E, 0x29, 0xCE,
        0x38, 0x45, 0x76, 0xA9, 0x55, 0x11, 0xB6, 0xB4,
        0xE5, 0x6E, 0xDD, 0x01, 0x4B, 0x16, 0x07, 0x99,
        0xBD, 0x19, 0x77, 0xF5, 0xD7, 0x9E, 0x39, 0x9E,
        0xAA, 0x8E, 0x2B, 0x75, 0xC5, 0xEB, 0x33, 0x56,
        0x6C, 0xD8, 0xB6, 0x3F, 0x3F, 0x4E, 0x81, 0x7E,
        0x29, 0x0A, 0x68, 0xED, 0x1E, 0x9F, 0xDC, 0x6B,
        0xFA, 0x18, 0xE3, 0xE5, 0x7D, 0x05, 0x7F, 0x22,
        0xFA, 0xA2, 0xF6, 0x0F, 0xB6, 0x34, 0x56, 0x72,
        0x55, 0x16, 0x5E, 0xF4, 0x18, 0xD1, 0x82, 0xFA,
        0xDD, 0xF7, 0xB8, 0x9F, 0x7D, 0x30, 0x10, 0x69,
        0xC4, 0x85, 0xD8, 0xE8, 0x34, 0x89, 0xD4, 0x93,
        0xBE, 0x56, 0xEE, 0xDC, 0x43, 0xD4, 0x82, 0x00,
        0xFD, 0x1E, 0x2B, 0x06, 0x69, 0x07, 0x1B, 0xBF,
        0x33, 0x61, 0x39, 0x28, 0xCA, 0x31, 0x91, 0x0B,
        0xF2, 0xEA, 0x32, 0x8E, 0xA8, 0x64, 0x13, 0x9A,
        0xEF, 0x79, 0x1A, 0x9A, 0xBE, 0x52, 0x13, 0x32,
        0x49, 0x93, 0x7D, 0xA8, 0x8C, 0x48, 0xD4, 0xC0,
        0x1D, 0x10, 0x8A, 0x46, 0x85, 0xAD, 0x29, 0xDF,
        0x2E, 0xCD, 0x41, 0x83, 0x82, 0x01, 0x28, 0x44,
        0x0E, 0xE5, 0x37, 0x8D, 0x6B, 0xCA, 0x61, 0x98,
        0xDE, 0x89, 0xA9, 0x7B, 0xBB, 0x44, 0x48, 0xA2,
        0x8D, 0x82, 0x3A, 0x57, 0x40, 0x60, 0x7C, 0x6E,
        0x69, 0x98, 0x98, 0x93, 0xFA, 0x7E, 0x29, 0x9A,
        0x74, 0x53, 0xD8, 0xDC, 0xB3, 0x4B, 0xDB, 0x7E,
        0xFE, 0x95, 0xB0, 0xC7, 0x23, 0x14, 0xEF, 0xCB,
        0x49, 0x3C, 0x09, 0xD7, 0x7B, 0xD0, 0x11, 0x9B,
        0xAC, 0xF2, 0xC2, 0x2E, 0x7C, 0xCB, 0xCD, 0x59,
        0x7F, 0x6A, 0x09, 0xFE, 0xFE, 0xDF, 0xA0, 0xA7,
        0xAC, 0x3C, 0x90, 0xBA, 0x75, 0x19, 0xF4, 0x01,
        0x60, 0x56, 0xD5, 0xFB, 0x41, 0x2B, 0xA0, 0x2D,
        0x0D, 0x45, 0xCF, 0xF3, 0xA6, 0x3D, 0x36, 0xEE,
        0xE1, 0xE4, 0x68, 0xE6, 0xEA, 0x2F, 0x67, 0x3A,
        0x7A, 0x02, 0x92, 0x6B, 0xB3, 0x18, 0xBA, 0x73,
        0xEE, 0x1B, 0x2C, 0x13, 0x7D, 0xEF, 0x4A, 0x39,
        0xE8, 0x03, 0xFF, 0x57, 0x35, 0x53, 0xE9, 0xA5,
        0xC6, 0xAA, 0x1A, 0x17, 0x21, 0xCA, 0x54, 0x38,
        0x7C, 0xB1, 0xDF, 0xB8, 0xFA, 0x7D, 0xA7, 0x26,
        0xB2, 0xAE, 0x7A, 0x05, 0x45, 0x3B, 0x40, 0x0A,
        0x19, 0xE5, 0x32, 0x52, 0x78, 0x9D, 0xC3, 0x20,
        0x63, 0x24, 0xB2, 0x58, 0x4B, 0x86, 0x1F, 0x00,
        0xA2, 0x50, 0xF9, 0x9F, 0xD9, 0xDC, 0x7D, 0x51,
        0x3D, 0xD7, 0xA6, 0x5A, 0x04, 0x03, 0x4E, 0xB3,
        0x3D, 0x2D, 0x56, 0xA4, 0x96, 0xB3, 0x6A, 0xBA,
        0x0A, 0x30, 0x08, 0xE3, 0x0F, 0xC1, 0x38, 0x24,
        0x88, 0x5D, 0x9E, 0x6F, 0x68, 0x1A, 0x7D, 0xB6,
        0x2D, 0xDD, 0xE3, 0x50, 0x1B, 0xD4, 0x07, 0x75,
        0xE2, 0xE2, 0xCC, 0x09, 0xCC, 0x8E, 0x4E, 0x67,
        0x02, 0x72, 0x02, 0xA8, 0x11, 0x70, 0xA5, 0x7F,
        0x4A, 0xC1, 0x98, 0xC1, 0x7F, 0xBF, 0x95, 0xBB,
        0xCE, 0xD3, 0x6D, 0x49, 0x30, 0xB9, 0x50, 0x8C,
        0xFA, 0x3E, 0x8B, 0xF6, 0xE5, 0x54, 0xE9, 0x1B,
        0xD7, 0xD6, 0xE5, 0x32, 0x33, 0xBB, 0x91, 0xAD,
        0xC8, 0x15, 0x76, 0x1A, 0x04, 0x35, 0xDE, 0xCC,
        0xE1, 0x67, 0x26, 0x4C, 0x2F, 0x4E, 0x34, 0x34,
        0x3D, 0x1E, 0x5A, 0xF7, 0xBC, 0xE6, 0x0C, 0x9B,
        0x7B, 0x7E, 0xE5, 0xDF, 0x72, 0x9A, 0x0D, 0xDD,
        0x4B, 0xE6, 0x6F, 0x82, 0xFB, 0x5E, 0x2C, 0xC0,
        0x7B, 0x03, 0x85, 0x76, 0x11, 0x0E, 0xFD, 0xC7,
        0xD5, 0x50, 0x26, 0xBE, 0x75, 0x5E, 0xC1, 0xF0,
        0x2E, 0x47, 0x62, 0xD6, 0xF1, 0xDA, 0xDF, 0xF4,
        0x1C, 0xEE, 0x63, 0x52, 0xC4, 0x45, 0x37, 0xE6,
        0x85, 0xA5, 0x0A, 0x07, 0x54, 0x63, 0x21, 0x7B,
        0x92, 0xF7, 0x33, 0x0C, 0xD9, 0x29, 0xCF, 0xE3,
        0xAB, 0xB5, 0xFC, 0xAA, 0x26, 0x20, 0x93, 0x55,
        0x8A, 0x07, 0x33, 0xB2, 0x7D, 0x95, 0x02, 0x7A,
        0x76, 0x9E, 0x7D, 0xBB, 0xC1, 0xF3, 0x6E, 0x84,
        0x10, 0x30, 0x4B, 0x5D, 0x59, 0x73, 0x68, 0xEC,
        0x2A, 0x63, 0x2D, 0x46, 0xE8, 0xC2, 0xF8, 0xEA,
        0x2B, 0xC4, 0x4F, 0xA7, 0x6E, 0xF4, 0x74, 0xEB,
        0x96, 0xA3, 0x64, 0x40, 0x9B, 0x23, 0x63, 0x42,
        0x4B, 0x8F, 0x85, 0x00, 0x43, 0x04, 0xAD, 0x61,
        0x76, 0x93, 0xBD, 0xC3, 0x88, 0xC3, 0xFC, 0x29,
        0x61, 0xBD, 0xB1, 0x5A, 0x1F, 0x5B, 0x20, 0xEF,
        0x95, 0xED, 0x99, 0x84, 0x96, 0xB2, 0x93, 0x81,
        0x82, 0xFF, 0xE3, 0xB9, 0x27, 0xEA, 0x9A, 0x23,
        0xF6, 0x42, 0x8D, 0xD3, 0x5C, 0x86, 0x11, 0xC8,
        0x39, 0xE3, 0x16, 0xE9, 0xA5, 0x32, 0x7C, 0xC9,
        0xEA, 0x82, 0x50, 0x9B, 0x21, 0x5C, 0xC9, 0x66,
        0xBE, 0x1C, 0x78, 0x48, 0xEF, 0x39, 0x2D, 0xA1,
        0xC6, 0xF3, 0x69, 0xA3, 0x36, 0x25, 0x3A, 0xA1,
        0x15, 0x2B, 0x6D, 0xCF, 0xDA, 0xA7, 0xCA, 0xDD,
        0x4D, 0x9A, 0x1D, 0x58, 0x9F, 0x73, 0xD3, 0xEF,
        0x0F, 0xBF, 0x03, 0x88, 0x2F, 0xDE, 0xB9, 0x44,
        0xB5, 0xB6, 0xCF, 0xE2, 0x6F, 0x6A, 0xB5, 0x12,
        0x38, 0x29, 0x55, 0x8C, 0x4C, 0x73, 0x6F, 0x0B,
        0x68, 0x7A, 0xC7, 0x06, 0x83, 0x80, 0xFE, 0x7F,
        0x61, 0xBE, 0x6B, 0x40, 0xE3, 0xF0, 0x4D, 0x7B,
        0x36, 0x82, 0x0F, 0xD8, 0x63, 0x29, 0xB3, 0x10,
        0x9D, 0x02, 0xEC, 0x63, 0x90, 0xEA, 0xFC, 0x8C,
        0xA7, 0x30, 0x56, 0x2B, 0x68, 0x08, 0x24, 0x24,
        0xFD, 0xA9, 0x8D, 0x0B, 0x64, 0xBC, 0x97, 0x34,
        0xB4, 0x0B, 0x63, 0xF7, 0xE3, 0x7A, 0xF6, 0x89,
        0x0A, 0xF7, 0xC2, 0xD9, 0x2F, 0x79, 0xEE, 0xA3,
        0xCC, 0xEA, 0xC6, 0x0A, 0x6F, 0x38, 0x06, 0x92,
        0xF8, 0x02, 0xB1, 0x55, 0x6A, 0x78, 0xFE, 0x55,
        0x83, 0xFF, 0x20, 0xA9, 0xC6, 0xA7, 0xBF, 0xCC,
        0x86, 0x3A, 0x9E, 0x7B, 0x62, 0x01, 0x4D, 0x16,
        0x05, 0xDE, 0x89, 0x4F, 0xB5, 0x85, 0xE2, 0xD4,
        0xF9, 0x41, 0x15, 0xE0, 0x29, 0xE5, 0x85, 0x7E,
        0x6A, 0x0A, 0x73, 0x89, 0x27, 0x5F, 0x53, 0x0D,
        0x3D, 0x80, 0xCF, 0xAB, 0x1F, 0x22, 0x5D, 0x38,
        0x33, 0x5D, 0x24, 0x67, 0x91, 0x97, 0xD4, 0x8A,
        0x01, 0x8A, 0x34, 0x18, 0x7D, 0xE3, 0xBC, 0xCE,
        0xDE, 0x94, 0xFF, 0x8E, 0xC5, 0x34, 0xC0, 0x2D,
        0xA7, 0x24, 0xD4, 0x59, 0x8D, 0x66, 0x9E, 0x85,
        0xA9, 0xC6, 0x0E, 0x45, 0x21, 0x4F, 0xAA, 0x65,
        0x44, 0xD6, 0xA4, 0x7D, 0x1C, 0x4E, 0xD7, 0x40,
        0x9D, 0x55, 0xB1, 0xA7, 0xF1, 0x15, 0xAE, 0x15,
        0x44, 0x3A, 0x1C, 0x31, 0x06, 0x40, 0xD1, 0x16,
        0x23, 0x84, 0x93, 0xEF, 0x3E, 0xE2, 0x87, 0x9B,
        0xB8, 0x46, 0x1F, 0x7D, 0x68, 0x73, 0x64, 0x70,
        0xD4, 0xB5, 0x73, 0xAE, 0x45, 0x49, 0x93, 0xF5,
        0x32, 0x30, 0x1E, 0x35, 0xCB, 0x9E, 0xEE, 0xDF,
        0xFE, 0xA8, 0x2F, 0xAC, 0x49, 0x77, 0x53, 0xF7,
        0x50, 0x19, 0xF2, 0xB3, 0xB0, 0x2C, 0x70, 0xB6,
        0x4A, 0x57, 0x95, 0x31, 0xC3, 0x26, 0x07, 0x2A,
        0xCF, 0x1B, 0xD0, 0xAA, 0xA0, 0x9F, 0x0A, 0x97,
        0x8B, 0x78, 0xAB, 0x22, 0xBD, 0x61, 0x19, 0xF8,
        0x8D, 0xD2, 0xD5, 0x72, 0xF8, 0x91, 0x9D, 0x47,
        0x4F, 0x59, 0x1D, 0xAE, 0x9F, 0xCE, 0x47, 0x53,
        0xC9, 0x85, 0xFB, 0x25, 0x04, 0x25, 0xF2, 0x65,
        0x61, 0xFF, 0xA9, 0x44, 0x3F, 0x23, 0x76, 0x68,
        0x9F, 0xEB, 0x48, 0xC4, 0xCE, 0x51, 0x46, 0x04,
        0x52, 0x6A, 0x10, 0x0A, 0xF3, 0x3F, 0x0D, 0x43,
        0x37, 0xD1, 0x60, 0x42, 0x22, 0xC4, 0xD9, 0xF9,
        0x3A, 0x8E, 0x69, 0xE4, 0xCC, 0xD3, 0x66, 0x69,
        0x09, 0x0C, 0x5D, 0xFB, 0x0E, 0x95, 0x49, 0x42,
        0x29, 0xFF, 0x9B, 0x20, 0xCC, 0xB1, 0xAC, 0x81,
        0xB8, 0x1A, 0x36, 0xD6, 0x3A, 0x85, 0x0D, 0xDB,
        0x33, 0x33, 0x4D, 0xAA, 0x51, 0x46, 0xBF, 0x36,
        0xFE, 0x18, 0x80, 0x1E, 0x3B, 0xEB, 0xD0, 0xE9,
        0x1B, 0x5E, 0x1C, 0xFE, 0x7A, 0x98, 0x26, 0x85,
        0x0A, 0xF4, 0x39, 0x7D, 0x1B, 0x07, 0xD3, 0xB7,
        0x19, 0xE5, 0x7B, 0xB8, 0x32, 0xAF, 0x42, 0x34,
        0xC0, 0xCD, 0x9F, 0xD4, 0x0B, 0x88, 0x2F, 0xCE,
        0xDA, 0x93, 0x7E, 0xF9, 0xA2, 0xDA, 0x24, 0x59,
        0x2B, 0xCB, 0x5D, 0x1B, 0xE8, 0x3E, 0xC5, 0xF0,
        0x3D, 0xBD, 0xFB, 0xCB, 0x33, 0x5D, 0x90, 0xD5,
        0xC8, 0xA0, 0x2E, 0xE5, 0x3D, 0x50, 0x8E, 0xB5,
        0xDE, 0x4A, 0x96, 0x1B, 0x95, 0x8F, 0x75, 0x1E,
        0x5F, 0x89, 0xA1, 0xD2, 0x88, 0x95, 0xA3, 0xDB,
        0x7B, 0x62, 0xEF, 0x4A, 0xE1, 0x6D, 0x28, 0xFB,
        0x78, 0x9B, 0x32, 0x03, 0xAD, 0x24, 0x63, 0xD6,
        0xEA, 0xB8, 0x3A, 0x6D, 0x20, 0xCE, 0xA1, 0x31,
        0x4A, 0xE0, 0x2A, 0x3F, 0xF6, 0xF6, 0x53, 0x15,
        0x4A, 0xE1, 0x44, 0x23, 0x81, 0x86, 0x21, 0x47,
        0x41, 0xC2, 0x36, 0x14, 0x81, 0x83, 0xBC, 0x39,
        0xAE, 0xDF, 0x44, 0xDA, 0x97, 0xF7, 0x31, 0xCE,
        0x3D, 0xCB, 0x61, 0xA4, 0xCF, 0xE1, 0x4F, 0x9E,
        0x84, 0xAA, 0x05, 0xAB, 0x1C, 0x1B, 0x95, 0x1D,
        0x20, 0x15, 0x52, 0x33, 0xFA, 0xFA, 0xF1, 0x6C,
        0xF1, 0xBD, 0x0B, 0xAF, 0xE1, 0x99, 0xE6, 0x5D,
        0x56, 0x34, 0x53, 0xBF, 0xE5, 0x5D, 0x5F, 0x47,
        0x4A, 0xB1, 0x05, 0x94, 0xD7, 0x38, 0xA8, 0xC1,
        0x06, 0x28, 0x8D, 0x69, 0xD0, 0x7A, 0x16, 0x88,
        0x60, 0x14, 0x63, 0xF3, 0xBD, 0x21, 0x46, 0x81,
        0x9C, 0x83, 0x72, 0x6D, 0x14, 0xC6, 0xA8, 0x08,
        0x39, 0xB8, 0x79, 0x0B, 0x57, 0x16, 0xE7, 0x72,
        0xF6, 0xC2, 0x4C, 0x2B, 0xEB, 0x7E, 0x2C, 0xF3,
        0x7B, 0x3F, 0x42, 0xAC, 0xDD, 0x47, 0x3E, 0x8C,
        0xCD, 0xBE, 0x48, 0x4D, 0x6E, 0x07, 0xB0, 0x73,
        0xDE, 0xCB, 0x17, 0x4A, 0xC3, 0xB8, 0xBB, 0x2E,
        0xF5, 0x4E, 0x6D, 0xF9, 0xE0, 0x20, 0x71, 0xFA,
        0x60, 0x0A, 0xE5, 0x59, 0x67, 0xEB, 0x6F, 0x70,
        0x2F, 0x71, 0x91, 0x59, 0xF0, 0xEB, 0x06, 0x5C,
        0xC4, 0x60, 0x48, 0xE8, 0x75, 0xE7, 0xCF, 0x42,
        0x71, 0xAD, 0x2E, 0xDA, 0xF9, 0x10, 0x82, 0x9A,
        0xF6, 0x13, 0xBA, 0x89, 0xFC, 0x61, 0x2A, 0x00,
        0xFD, 0xAE, 0x53, 0x7B, 0x09, 0x3A, 0xE8, 0xCB,
        0xE6, 0xB7, 0x0D, 0x03, 0x01, 0xFA, 0x2E, 0x13,
        0xA9, 0x16, 0x38, 0x1C, 0x92, 0xEC, 0xB4, 0x51,
        0xA3, 0x6E, 0x3F, 0xA8, 0xB7, 0x37, 0x36, 0x20,
        0xC0, 0x71, 0xA3, 0x05, 0x34, 0xED, 0xCB, 0x4A,
        0x3F, 0x11, 0x31, 0x17, 0xA5, 0x02, 0xD6, 0xA7,
        0x2D, 0xE6, 0xC7, 0x7B, 0xBB, 0xF6, 0xAE, 0x99,
        0x85, 0x9A, 0xAC, 0xE6, 0x4A, 0x92, 0x8C, 0x37,
        0x4B, 0xD2, 0xC4, 0x65, 0x2A, 0xC9, 0x7E, 0xB7,
        0x44, 0xD2, 0x9A, 0x70, 0xCE, 0xA9, 0xA1, 0x9D,
        0x70, 0x13, 0x49, 0x7B, 0xCA, 0xB6, 0x96, 0x31,
        0x43, 0x3F, 0x9E, 0xD1, 0xFE, 0x20, 0xF8, 0x0B,
        0x59, 0x83, 0xE1, 0x28, 0x8B, 0xB6, 0xA2, 0xBE,
        0x91, 0x54, 0x3E, 0xD4, 0x79, 0x28, 0xBB, 0x5E,
        0x46, 0x2D, 0x01, 0xE9, 0xC0, 0xB7, 0xFF, 0xFA,
        0xC0, 0x6C, 0x10, 0xF1, 0x52, 0xF4, 0x3C, 0x32,
        0x9E, 0x89, 0xDF, 0x8A, 0x79, 0x99, 0x6A, 0x09,
        0x79, 0x8A, 0x36, 0x76, 0x40, 0xBE, 0x9F, 0xB5,
        0x3D, 0xCE, 0x27, 0xBD, 0x0B, 0xAA, 0x9B, 0xF0,
        0x21, 0xBF, 0x10, 0xD2, 0xFC, 0xFE, 0x5B, 0x13,
        0xFD, 0x7D, 0x84, 0xD1, 0xC1, 0xEB, 0xC0, 0xBC,
        0xEC, 0x26, 0xD0, 0x87, 0x80, 0xD1, 0x3B, 0x99,
        0x47, 0x67, 0x26, 0x61, 0xE0, 0xFA, 0x5F, 0xAE,
        0x6F, 0x31, 0x5B, 0x6D, 0xE4, 0x01, 0x68, 0xC2,
        0x35, 0x1D, 0xE3, 0x1F, 0x41, 0xFF, 0x6C, 0x53,
        0x32, 0x26, 0xE1, 0xBC, 0xE3, 0xF8, 0xE2, 0x16,
        0xAF, 0x3B, 0xE6, 0x4C, 0x69, 0x33, 0x72, 0xA0,
        0x66, 0xB1, 0x75, 0xF7, 0x26, 0xCF, 0xCD, 0x64,
        0x2B, 0xAE, 0x98, 0x02, 0x92, 0xC1, 0xCB, 0x65,
        0xE0, 0x1F, 0x07, 0x29, 0x64, 0x0A, 0xB0, 0x09,
        0xCB, 0x98, 0x89, 0x2D, 0x6C, 0xFE, 0x40, 0x03,
        0x34, 0x55, 0xDE, 0xE7, 0x30, 0x33, 0xB6, 0xD5,
        0xE1, 0x9C, 0x59, 0x9F, 0x8A, 0x40, 0x0E, 0xB1,
        0x41, 0x52, 0x7D, 0xF2, 0xBB, 0xDD, 0xEF, 0x50,
        0xBB, 0xD5, 0xFB, 0x55, 0xAA, 0x5E, 0xFD, 0xB3,
        0x5D, 0x08, 0x56, 0x9B, 0x02, 0x97, 0xE2, 0x48,
        0x14, 0x69, 0xF1, 0x7B, 0x87, 0xB5, 0x08, 0x93,
        0x6A, 0x9C, 0x5C, 0x11, 0x08, 0x9A, 0xE9, 0xE4,
        0xB0, 0xCA, 0xC5, 0x74, 0x93, 0x93, 0xC8, 0x03,
        0xE4, 0x70, 0x39, 0xF5, 0x1B, 0x5C, 0xBD, 0x42,
        0xA6, 0xC9, 0xE1, 0x9E, 0xC3, 0xF6, 0x3C, 0x23,
        0x32, 0xE8, 0x77, 0x68, 0xA9, 0x60, 0xFA, 0x02,
        0x18, 0x6B, 0x7A, 0x2B, 0x02, 0x92, 0x65, 0x09,
        0x11, 0x46, 0x73, 0x04, 0x63, 0xDF, 0x8B, 0x37,
        0x5F, 0x24, 0xAA, 0x83, 0xBD, 0xD4, 0x1D, 0x13,
        0x04, 0xFC, 0x2F, 0xB5, 0x2D, 0xA1, 0x0F, 0x1F,
        0xED, 0x65, 0x29, 0x08, 0xCF, 0x8C, 0x52, 0x8F,
        0xB2, 0x62, 0x5F, 0x39, 0x3F, 0xC8, 0xC7, 0xB3,
        0x3F, 0xAD, 0x45, 0xBA, 0xD4, 0x7D, 0x38, 0x3D,
        0x2C, 0x04, 0xCF, 0x32, 0xE8, 0x07, 0x42, 0x5F,
        0x93, 0xD2, 0x35, 0x07, 0x21, 0xB7, 0xB2, 0xF5,
        0x96, 0x64, 0x8E, 0xB5, 0xE1, 0x38, 0x6B, 0x43,
        0xD1, 0x2E, 0xFD, 0xDB, 0x8F, 0xE2, 0x43, 0x6A,
        0xEC, 0x27, 0x8E, 0xE7, 0x68, 0x75, 0xB5, 0x23,
        0xC5, 0x43, 0x1D, 0x99, 0x48, 0x57, 0x73, 0xD9,
        0xAD, 0xBC, 0xD0, 0x14, 0xDD, 0x87, 0xBC, 0x68,
        0xFB, 0x82, 0xEE, 0x47, 0x4B, 0x22, 0xA5, 0x43,
        0x3A, 0xF9, 0xF9, 0x91, 0xFC, 0x34, 0xB2, 0x58,
        0x34, 0xDF, 0x13, 0x09, 0x9A, 0x46, 0xF5, 0x68,
        0xAF, 0xD1, 0x15, 0x5F, 0x32, 0x1B, 0x9D, 0xA9,
        0xE9, 0xC0, 0x63, 0x47, 0xAB, 0x3C, 0x1F, 0x59,
        0xF7, 0xEA, 0x0E, 0xD6, 0xCF, 0x47, 0xB3, 0xE9,
        0xAF, 0x65, 0x7A, 0xA7, 0xAE, 0x9B, 0xF8, 0x26,
        0x0B, 0x96, 0x9D, 0xE4, 0xAD, 0x24, 0xD3, 0xA8,
        0xCE, 0x95, 0xE5, 0x77, 0xD0, 0x44, 0x13, 0x05,
        0x06, 0x4E, 0x07, 0xB9, 0xA2, 0xC7, 0x5C, 0x3C,
        0x43, 0x80, 0x1F, 0xCE, 0xB7, 0x36, 0xFE, 0x3D,
        0x27, 0x1B, 0xE1, 0xF3, 0x6B, 0xFF, 0xC8, 0xE4,
        0x3D, 0xB1, 0x4A, 0x16, 0x24, 0x76, 0xBA, 0xEA,
        0x9D, 0x34, 0x6B, 0x52, 0x11, 0xAB, 0xD0, 0x06,
        0x08, 0xB1, 0x5A, 0xF3, 0xB5, 0xE6, 0x3A, 0x00,
        0xFF, 0x92, 0x8D, 0x1E, 0xA1, 0xA1, 0x8D, 0x75,
        0xFA, 0x7C, 0x6C, 0x1B, 0x0F, 0xB6, 0x27, 0x2E,
        0x55, 0xC3, 0xFE, 0x7E, 0x4D, 0x42, 0x05, 0xE5,
        0xCF, 0x0A, 0x1F, 0x87, 0x18, 0x30, 0x4E, 0x14,
        0xF2, 0xB4, 0xCC, 0x54, 0x3D, 0x04, 0x37, 0x34,
        0x1A, 0x4A, 0x31, 0x16, 0x01, 0xA9, 0x2E, 0x92,
        0x56, 0x6B, 0x7D, 0xFB, 0x42, 0x64, 0xE8, 0x70,
        0xE1, 0xB3, 0xA8, 0x75, 0xED, 0xBC, 0x00, 0x3A,
        0x56, 0x19, 0x70, 0xCF, 0x8A, 0x66, 0x9F, 0x3D,
        0x1B, 0x69, 0x28, 0x8C, 0xC6, 0xE3, 0x59, 0xCE,
        0x28, 0xCA, 0x65, 0xF9, 0xDA, 0xE8, 0xCE, 0xCA,
        0x74, 0x3C, 0x1C, 0x8D, 0x9F, 0xFB, 0x55, 0x08,
        0x82, 0x4A, 0x83, 0x61, 0xE3, 0x3B, 0x43, 0x1A,
        0x2E, 0x9E, 0x9A, 0x99, 0x78, 0x47, 0xD2, 0xE6,
        0xE4, 0x3C, 0x83, 0xF0, 0x22, 0x62, 0xE2, 0x94,
        0x6D, 0xF7, 0x72, 0x6D, 0x54, 0xE3, 0xE6, 0xC9,
        0xCC, 0xDB, 0x6D, 0x3F, 0x13, 0x63, 0x46, 0xC1,
        0x1E, 0x59, 0x42, 0xE7, 0xA1, 0xBF, 0x85, 0x0C,
        0x2E, 0x99, 0xB4, 0xFA, 0xCE, 0x75, 0xFD, 0x40,
        0x88, 0x69, 0x33, 0x90, 0x7C, 0xCD, 0xFC, 0x0D,
        0xE1, 0x17, 0x70, 0x20, 0x31, 0x94, 0x1D, 0x00,
        0x1E, 0x2A, 0x68, 0x3C, 0x55, 0x78, 0xFD, 0x33,
        0x54, 0x21, 0x2C, 0xEA, 0xD9, 0x69, 0xBF, 0x1C,
        0x81, 0x23, 0x9E, 0xEC, 0xC7, 0x74, 0xFD, 0x0B,
        0x88, 0x3D, 0x0E, 0xEE, 0x82, 0x4B, 0x10, 0xB8,
        0x79, 0xCF, 0x70, 0x7C, 0xB2, 0x68, 0x47, 0x45,
        0x22, 0x06, 0x1E, 0x92, 0x7B, 0x12, 0x43, 0x24,
        0x41, 0x15, 0xC6, 0x69, 0xE9, 0xEB, 0x27, 0x2B,
        0x60, 0xA6, 0x44, 0xF5, 0x19, 0xEF, 0xEC, 0x06,
        0x34, 0x08, 0xB6, 0x58, 0x47, 0x2E, 0x91, 0x61,
        0xA1, 0xF7, 0x44, 0xFD, 0x66, 0x16, 0x9F, 0x0C,
        0xAE, 0x36, 0xB4, 0x2E, 0x23, 0x79, 0xCB, 0xE8,
        0x1E, 0x6E, 0x51, 0xA0, 0xF5, 0x34, 0x15, 0x18,
        0x4E, 0xA0, 0x06, 0xB2, 0x27, 0x0B, 0x33, 0xE2,
        0xCA, 0x36, 0x4C, 0xDB, 0x33, 0xAA, 0xAE, 0x77,
        0xFF, 0xD9, 0x53, 0xDB, 0x39, 0x70, 0x4D, 0x49,
        0x0C, 0xE9, 0xAC, 0x6F, 0x2D, 0xD1, 0xC7, 0xA1,
        0x8E, 0x61, 0x74, 0x19, 0xA9, 0xAA, 0xFB, 0x37,
        0xE7, 0x23, 0x9B, 0x23, 0x6A, 0x4B, 0x74, 0xCE,
        0x63, 0xE4, 0xA0, 0xAD, 0xFF, 0x85, 0x5D, 0xCD,
        0x78, 0xF6, 0x45, 0x8E, 0x76, 0x0B, 0xFD, 0x1D,
        0x2A, 0xB9, 0x5E, 0x83, 0xC0, 0x3B, 0x6F, 0xAE,
        0x0C, 0xD3, 0xC5, 0xCE, 0xEE, 0xEE, 0x1C, 0x69,
        0x51, 0x59, 0x65, 0xA3, 0x35, 0xFC, 0xF7, 0x8E,
        0x80, 0xAA, 0x73, 0x93, 0x39, 0x54, 0x21, 0x27,
        0x17, 0x0B, 0x2C, 0x3E, 0xE1, 0x0B, 0x0E, 0xAA,
        0x09, 0x9A, 0xC7, 0xAD, 0x4C, 0xD7, 0x6E, 0x7F,
        0xE4, 0xC1, 0x16, 0x4E, 0x62, 0xF4, 0xE5, 0x80,
        0x7D, 0xC0, 0x06, 0x1F, 0x77, 0xE4, 0xA8, 0xA5,
        0x28, 0xD7, 0x10, 0x37, 0x59, 0x30, 0xCB, 0x75,
        0x5B, 0x28, 0xBF, 0xFD, 0x92, 0x8C, 0xB0, 0x7B,
        0xB4, 0xA1, 0x07, 0xCD, 0xCA, 0xBB, 0x30, 0x8A,
        0x48, 0x65, 0x0D, 0xA4, 0xE5, 0x74, 0xD9, 0xBF,
        0x56, 0x07, 0xF5, 0x83, 0xDA, 0xC3, 0x40, 0xD7,
        0x20, 0x93, 0xEF, 0xB1, 0x2B, 0xBF, 0x93, 0x41,
        0x0F, 0x1E, 0xF5, 0xC9, 0x51, 0x6C, 0x74, 0x4D,
        0x23, 0x15, 0xEC, 0x9E, 0x00, 0x0A, 0x8D, 0xC5,
        0xD1, 0x7A, 0x7B, 0x6F, 0x0D, 0x07, 0x9D, 0x78,
        0x4B, 0x6D, 0x90, 0x19, 0x3F, 0x6E, 0x3E, 0xE7,
        0xEA, 0x0E, 0xAB, 0xFC, 0x6F, 0x68, 0xC5, 0x2B,
        0x37, 0xCB, 0xCE, 0x82, 0x18, 0xAF, 0xA3, 0x67,
        0x0A, 0x80, 0xBC, 0x17, 0xB9, 0x5D, 0x7B, 0x40,
        0x53, 0x62, 0x26, 0x35, 0x8F, 0x04, 0xAC, 0xD9,
        0x2A, 0x1B, 0xE1, 0x5B, 0x26, 0xA4, 0xE5, 0x81,
        0x7E, 0x62, 0x8B, 0xA6, 0x79, 0xB3, 0x52, 0x72,
        0x03, 0xCD, 0x36, 0x32, 0x62, 0x8E, 0xC8, 0x3A,
        0xA4, 0xF2, 0x18, 0x6D, 0x2F, 0x00, 0x5D, 0x5D,
        0xFE, 0x6F, 0x7F, 0xDB, 0x4F, 0xED, 0xAC, 0x9E,
        0x89, 0xD6, 0x66, 0xE3, 0x03, 0xBB, 0x56, 0x83,
        0x06, 0x15, 0x6C, 0x56, 0xF0, 0x95, 0x34, 0xE2,
        0x5C, 0x61, 0x9A, 0xB3, 0xB9, 0x50, 0x18, 0xF4,
        0x89, 0x6B, 0xAC, 0xAA, 0x48, 0x34, 0xF6, 0xD2,
        0xD8, 0xFE, 0x14, 0xA9, 0x38, 0xAA, 0x10, 0xE5,
        0x30, 0x54, 0xF0, 0x00, 0x84, 0x44, 0xAC, 0x2E,
        0xEA, 0x25, 0x38, 0xC1, 0x23, 0x0E, 0x6A, 0x18,
        0xC9, 0x2B, 0x01, 0xD9, 0x14, 0x7F, 0xDC, 0xEF,
        0xC9, 0xC8, 0xDA, 0xC1, 0xD4, 0xEC, 0xC8, 0xCF,
        0x1F, 0x96, 0x2E, 0xFA, 0x1B, 0x8C, 0xD3, 0xC9,
        0x69, 0x00, 0x0B, 0x7E, 0xBA, 0xC5, 0x98, 0xDC,
        0xA4, 0x5E, 0xB4, 0x0B, 0xCF, 0xB1, 0x98, 0x51,
        0x48, 0x38, 0x51, 0xCF, 0x34, 0x0F, 0x3E, 0x8C,
        0x23, 0x7A, 0x9E, 0xFF, 0x1C, 0x9F, 0x21, 0xE4,
        0x97, 0x55, 0x41, 0xC6, 0x1A, 0x8F, 0xEF, 0x2A,
        0xC6, 0x05, 0x7F, 0x59, 0xDC, 0xB2, 0x3A, 0x80,
        0xE8, 0x06, 0x10, 0xCD, 0x85, 0xDB, 0x20, 0x3C,
        0x35, 0xD2, 0x4B, 0xC8, 0x2B, 0x9C, 0xD7, 0x82,
        0x46, 0xF5, 0x9F, 0xEB, 0xB2, 0x48, 0x32, 0xD7,
        0xCD, 0x66, 0x4C, 0x99, 0x51, 0x88, 0xE0, 0x28,
        0x1C, 0xD7, 0x86, 0x79, 0x00, 0xDC, 0x0D, 0xF4,
        0x4D, 0x40, 0x90, 0x80, 0x26, 0x8B, 0x79, 0xE9,
        0x56, 0x82, 0x88, 0x5F, 0x22, 0x87, 0x70, 0x73,
        0x4F, 0xA5, 0x35, 0x18, 0xEC, 0x80, 0xCE, 0x23,
        0x06, 0xCE, 0x14, 0x48, 0x52, 0x4E, 0xF0, 0x18,
        0x43, 0x03, 0xD4, 0x50, 0xC7, 0x6E, 0xA6, 0x3B,
        0x73, 0x3E, 0xB0, 0xC8, 0xDC, 0x48, 0xBF, 0x12,
        0x42, 0x3A, 0xD2, 0x38, 0x89, 0xCF, 0xCD, 0xD8,
        0x91, 0xE5, 0x95, 0x00, 0x47, 0x24, 0x0D, 0xC0,
        0xC3, 0x8A, 0xB2, 0xDB, 0xC1, 0x65, 0xB8, 0x1E,
        0x63, 0x10, 0x02, 0xEA, 0x6F, 0x74, 0x11, 0x9E,
        0x27, 0xF9, 0xF8, 0x60, 0x73, 0xBF, 0x2D, 0xF7,
        0x10, 0x81, 0x86, 0x76, 0x98, 0x0C, 0x4C, 0xB6,
        0xBD, 0x53, 0xF9, 0xA5, 0x72, 0x17, 0x78, 0xB8,
        0x9F, 0x59, 0xC6, 0x8C, 0x89, 0x35, 0xF5, 0x03,
        0x1C, 0x8A, 0x93, 0x36, 0x7D, 0x71, 0x70, 0x57,
        0xFD, 0x4D, 0x5E, 0xFA, 0xBE, 0xDE, 0x70, 0x2C,
        0xC6, 0x45, 0xEF, 0xB6, 0xD7, 0xF4, 0x4C, 0x86,
        0x0F, 0xFF, 0x76, 0x37, 0xAA, 0xD9, 0x72, 0x24,
        0x8C, 0x84, 0x4D, 0x15, 0x13, 0x39, 0x20, 0x07,
        0x38, 0x91, 0xC3, 0x13, 0x5D, 0x29, 0x78, 0x68,
        0xB7, 0xDA, 0x86, 0xF0, 0x97, 0xD8, 0xFB, 0x39,
        0xC1, 0x3B, 0xA1, 0x4C, 0x4F, 0x24, 0x75, 0x16,
        0xAB, 0xA4, 0xC5, 0xF8, 0xCE, 0x38, 0x18, 0x48,
        0x2C, 0x8F, 0xF6, 0x0C, 0xCA, 0x51, 0xFD, 0xB2,
        0xCE, 0xE9, 0x6B, 0xC1, 0x13, 0x8D, 0xC0, 0x4A,
        0x86, 0xF8, 0x57, 0x72, 0x75, 0x91, 0xAA, 0xE6,
        0xF8, 0x7C, 0x30, 0x05, 0x9B, 0x3E, 0x81, 0xB6,
        0x80, 0x55, 0xB2, 0x4E, 0xA2, 0xFA, 0x98, 0x36,
        0x86, 0x49, 0x8B, 0xFC, 0x9D, 0x9E, 0x7D, 0x59,
        0x50, 0x79, 0xEB, 0x64, 0x6E, 0x85, 0xB2, 0x12,
        0xCE, 0xDD, 0x21, 0xD0, 0x08, 0x7E, 0x0F, 0x2A,
        0xF6, 0x63, 0xEB, 0x77, 0x2A, 0x98, 0x47, 0xB1,
        0xDF, 0x21, 0x97, 0xAF, 0x13, 0x62, 0x6B, 0x89,
        0x7C, 0x24, 0x63, 0x7A, 0xF5, 0xBF, 0xE8, 0x18,
        0x16, 0xA8, 0xC9, 0x0D, 0x30, 0x48, 0x37, 0x5B,
        0x69, 0x94, 0x97, 0x14, 0x3E, 0x57, 0x71, 0x85,
        0xA7, 0x0E, 0x11, 0x50, 0x58, 0xA3, 0xA9, 0x11,
        0x2B, 0x2C, 0x43, 0x51, 0xB6, 0xCA, 0xD0, 0x09,
        0x28, 0x2B, 0x4F, 0x7C, 0xB8, 0xBD, 0xFC, 0x28,
        0x57, 0x77, 0xD7, 0xDF, 0xE8, 0xF5, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x03, 0x06, 0x0B, 0x11, 0x17,
        0x1F, 0x27, 0x2E
    };
#endif
#endif

    key = (dilithium_key*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ExpectNotNull(key);

    if (key != NULL) {
        XMEMSET(key, 0, sizeof(*key));
    }

    ExpectIntEQ(wc_dilithium_init_ex(key, NULL, INVALID_DEVID), 0);
#ifndef WOLFSSL_NO_ML_DSA_44
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
    ExpectIntEQ(wc_dilithium_import_public(pk_44, (word32)sizeof(pk_44), key),
        0);
    ExpectIntEQ(wc_dilithium_verify_msg(sig_44, (word32)sizeof(sig_44), msg_44,
        (word32)sizeof(msg_44), &res, key), 0);
    ExpectIntEQ(res, 1);
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44_DRAFT), 0);
    ExpectIntEQ(wc_dilithium_import_public(pk_44_draft,
        (word32)sizeof(pk_44_draft), key), 0);
    ExpectIntEQ(wc_dilithium_verify_msg(sig_44_draft,
        (word32)sizeof(sig_44_draft), msg_44_draft,
        (word32)sizeof(msg_44_draft), &res, key), 0);
    ExpectIntEQ(res, 1);
#endif
#endif
#ifndef WOLFSSL_NO_ML_DSA_65
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65), 0);
    ExpectIntEQ(wc_dilithium_import_public(pk_65, (word32)sizeof(pk_65), key),
        0);
    ExpectIntEQ(wc_dilithium_verify_msg(sig_65, (word32)sizeof(sig_65), msg_65,
        (word32)sizeof(msg_65), &res, key), 0);
    ExpectIntEQ(res, 1);
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_65_DRAFT), 0);
    ExpectIntEQ(wc_dilithium_import_public(pk_65_draft,
        (word32)sizeof(pk_65_draft), key), 0);
    ExpectIntEQ(wc_dilithium_verify_msg(sig_65_draft,
        (word32)sizeof(sig_65_draft), msg_65_draft,
        (word32)sizeof(msg_65_draft), &res, key), 0);
    ExpectIntEQ(res, 1);
#endif
#endif
#ifndef WOLFSSL_NO_ML_DSA_87
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87), 0);
    ExpectIntEQ(wc_dilithium_import_public(pk_87, (word32)sizeof(pk_87), key),
        0);
    ExpectIntEQ(wc_dilithium_verify_msg(sig_87, (word32)sizeof(sig_87), msg_87,
        (word32)sizeof(msg_87), &res, key), 0);
    ExpectIntEQ(res, 1);
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
    ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_87_DRAFT), 0);
    ExpectIntEQ(wc_dilithium_import_public(pk_87_draft,
        (word32)sizeof(pk_87_draft), key), 0);
    ExpectIntEQ(wc_dilithium_verify_msg(sig_87_draft,
        (word32)sizeof(sig_87_draft), msg_87_draft,
        (word32)sizeof(msg_87_draft), &res, key), 0);
    ExpectIntEQ(res, 1);
#endif
#endif

    wc_dilithium_free(key);
    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

/*
 * Testing wc_SetSubjectBuffer
 */
static int test_wc_SetSubjectBuffer(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
    Cert   cert;
    XFILE  file = XBADFILE;
    byte*  der = NULL;
    word32 derSz;

    derSz = FOURK_BUF;
    ExpectNotNull(der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectTrue((file = XFOPEN("./certs/ca-cert.der", "rb")) != XBADFILE);
    ExpectTrue((derSz = (word32)XFREAD(der, 1, FOURK_BUF, file)) > 0);
    if (file != XBADFILE)
        XFCLOSE(file);

    ExpectIntEQ(wc_InitCert(&cert), 0);
    ExpectIntEQ(wc_SetSubjectBuffer(&cert, der, (int)derSz), 0);
    ExpectIntEQ(wc_SetSubjectBuffer(NULL, der, (int)derSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
} /* End test_wc_SetSubjectBuffer*/

/*
 * Testing wc_SetSubjectKeyIdFromPublicKey_ex
 */
static int test_wc_SetSubjectKeyIdFromPublicKey_ex(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
    WC_RNG      rng;
    Cert        cert;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    RsaKey      rsaKey;
    int         bits = 2048;
#endif
#if defined(HAVE_ECC)
    ecc_key     eccKey;
    int         ret;
#endif
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
    ed25519_key ed25519Key;
#endif
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
    ed448_key   ed448Key;
#endif

#ifndef HAVE_FIPS
    ExpectIntEQ(wc_InitRng_ex(&rng, HEAP_HINT, testDevId), 0);
#else
    ExpectIntEQ(wc_InitRng(&rng), 0);
#endif

    ExpectIntEQ(wc_InitCert(&cert), 0);

#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    /* RSA */
    XMEMSET(&rsaKey, 0, sizeof(RsaKey));
    ExpectIntEQ(wc_InitRsaKey(&rsaKey, HEAP_HINT), 0);
    ExpectIntEQ(MAKE_RSA_KEY(&rsaKey, bits, WC_RSA_EXPONENT, &rng), 0);
    ExpectIntEQ(wc_SetSubjectKeyIdFromPublicKey_ex(&cert, RSA_TYPE, &rsaKey),
        0);
    DoExpectIntEQ(wc_FreeRsaKey(&rsaKey), 0);
#endif

#if defined(HAVE_ECC)
    /* ECC */
    XMEMSET(&eccKey, 0, sizeof(ecc_key));
    ExpectIntEQ(wc_ecc_init(&eccKey), 0);
    ret = wc_ecc_make_key(&rng, KEY14, &eccKey);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &eccKey.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);
    ExpectIntEQ(wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ECC_TYPE, &eccKey),
        0);
    DoExpectIntEQ(wc_ecc_free(&eccKey), 0);
#endif

#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
    /* ED25519 */
    XMEMSET(&ed25519Key, 0, sizeof(ed25519_key));
    ExpectIntEQ(wc_ed25519_init(&ed25519Key), 0);
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &ed25519Key), 0);
    ExpectIntEQ(wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ED25519_TYPE,
        &ed25519Key), 0);
    wc_ed25519_free(&ed25519Key);
#endif

#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
    /* ED448 */
    XMEMSET(&ed448Key, 0, sizeof(ed448_key));
    ExpectIntEQ(wc_ed448_init(&ed448Key), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &ed448Key), 0);
    ExpectIntEQ(wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ED448_TYPE,
        &ed448Key), 0);
    wc_ed448_free(&ed448Key);
#endif

    wc_FreeRng(&rng);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif /* WOLFSSL_CERT_EXT && WOLFSSL_CERT_GEN */
    return EXPECT_RESULT();
} /* End test_wc_SetSubjectKeyIdFromPublicKey_ex*/

/*
 * Testing wc_SetAuthKeyIdFromPublicKey_ex
 */
static int test_wc_SetAuthKeyIdFromPublicKey_ex(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
    WC_RNG      rng;
    Cert        cert;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    RsaKey      rsaKey;
    int         bits = 2048;
#endif
#if defined(HAVE_ECC)
    ecc_key     eccKey;
    int         ret;
#endif
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
    ed25519_key ed25519Key;
#endif
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
    ed448_key   ed448Key;
#endif

#ifndef HAVE_FIPS
    ExpectIntEQ(wc_InitRng_ex(&rng, HEAP_HINT, testDevId), 0);
#else
    ExpectIntEQ(wc_InitRng(&rng), 0);
#endif

    ExpectIntEQ(wc_InitCert(&cert), 0);

#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    /* RSA */
    XMEMSET(&rsaKey, 0, sizeof(RsaKey));
    ExpectIntEQ(wc_InitRsaKey(&rsaKey, HEAP_HINT), 0);
    ExpectIntEQ(MAKE_RSA_KEY(&rsaKey, bits, WC_RSA_EXPONENT, &rng), 0);
    ExpectIntEQ(wc_SetAuthKeyIdFromPublicKey_ex(&cert, RSA_TYPE, &rsaKey), 0);
    DoExpectIntEQ(wc_FreeRsaKey(&rsaKey), 0);
#endif

#if defined(HAVE_ECC)
    /* ECC */
    XMEMSET(&eccKey, 0, sizeof(ecc_key));
    ExpectIntEQ(wc_ecc_init(&eccKey), 0);
    ret = wc_ecc_make_key(&rng, KEY14, &eccKey);
#if defined(WOLFSSL_ASYNC_CRYPT)
    ret = wc_AsyncWait(ret, &eccKey.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
    ExpectIntEQ(ret, 0);
    ExpectIntEQ(wc_SetAuthKeyIdFromPublicKey_ex(&cert, ECC_TYPE, &eccKey), 0);
    DoExpectIntEQ(wc_ecc_free(&eccKey), 0);
#endif

#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
    /* ED25519 */
    XMEMSET(&ed25519Key, 0, sizeof(ed25519_key));
    ExpectIntEQ(wc_ed25519_init(&ed25519Key), 0);
    ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &ed25519Key), 0);
    ExpectIntEQ(wc_SetAuthKeyIdFromPublicKey_ex(&cert, ED25519_TYPE,
        &ed25519Key), 0);
    wc_ed25519_free(&ed25519Key);
#endif

#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
    /* ED448 */
    XMEMSET(&ed448Key, 0, sizeof(ed448_key));
    ExpectIntEQ(wc_ed448_init(&ed448Key), 0);
    ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &ed448Key), 0);
    ExpectIntEQ(wc_SetAuthKeyIdFromPublicKey_ex(&cert, ED448_TYPE, &ed448Key),
        0);
    wc_ed448_free(&ed448Key);
#endif

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif /* defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)*/
    return EXPECT_RESULT();
} /* End test_wc_SetAuthKeyIdFromPublicKey_ex*/

/*
 * Testing wc_PKCS7_New()
 */
static int test_wc_PKCS7_New(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7)
    PKCS7* pkcs7 = NULL;

    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
} /* END test-wc_PKCS7_New */

/*
 * Testing wc_PKCS7_Init()
 */
static int test_wc_PKCS7_Init(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7)
    PKCS7* pkcs7 = NULL;
    void*  heap = NULL;

    ExpectNotNull(pkcs7 = wc_PKCS7_New(heap, testDevId));

    ExpectIntEQ(wc_PKCS7_Init(pkcs7, heap, testDevId), 0);
    /* Pass in bad args. */
    ExpectIntEQ(wc_PKCS7_Init(NULL, heap, testDevId), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
} /* END test-wc_PKCS7_Init */


/*
 * Testing wc_PKCS7_InitWithCert()
 */
static int test_wc_PKCS7_InitWithCert(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7)
    PKCS7* pkcs7 = NULL;

#ifndef NO_RSA
    #if defined(USE_CERT_BUFFERS_2048)
        unsigned char    cert[sizeof(client_cert_der_2048)];
        int              certSz = (int)sizeof(cert);

        XMEMSET(cert, 0, certSz);
        XMEMCPY(cert, client_cert_der_2048, sizeof(client_cert_der_2048));
    #elif defined(USE_CERT_BUFFERS_1024)
        unsigned char    cert[sizeof(client_cert_der_1024)];
        int              certSz = (int)sizeof(cert);

        XMEMSET(cert, 0, certSz);
        XMEMCPY(cert, client_cert_der_1024, sizeof_client_cert_der_1024);
    #else
        unsigned char   cert[ONEK_BUF];
        XFILE           fp = XBADFILE;
        int             certSz;

        ExpectTrue((fp = XFOPEN("./certs/1024/client-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, sizeof_client_cert_der_1024,
            fp), 0);
        if (fp != XBADFILE)
            XFCLOSE(fp);
    #endif
#elif defined(HAVE_ECC)
    #if defined(USE_CERT_BUFFERS_256)
        unsigned char    cert[sizeof(cliecc_cert_der_256)];
        int              certSz = (int)sizeof(cert);

        XMEMSET(cert, 0, certSz);
        XMEMCPY(cert, cliecc_cert_der_256, sizeof(cliecc_cert_der_256));
    #else
        unsigned char   cert[ONEK_BUF];
        XFILE           fp = XBADFILE;
        int             certSz;

        ExpectTrue((fp = XFOPEN("./certs/client-ecc-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, sizeof(cliecc_cert_der_256),
            fp), 0);
        if (fp != XBADFILE)
            XFCLOSE(fp);
    #endif
#else
        #error PKCS7 requires ECC or RSA
#endif

#ifdef HAVE_ECC
    {
    /* bad test case from ZD 11011, malformed cert gives bad ECC key */
        static unsigned char certWithInvalidEccKey[] = {
        0x30, 0x82, 0x03, 0x5F, 0x30, 0x82, 0x03, 0x04, 0xA0, 0x03, 0x02, 0x01,
        0x02, 0x02, 0x14, 0x61, 0xB3, 0x1E, 0x59, 0xF3, 0x68, 0x6C, 0xA4, 0x79,
        0x42, 0x83, 0x2F, 0x1A, 0x50, 0x71, 0x03, 0xBE, 0x31, 0xAA, 0x2C, 0x30,
        0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30,
        0x81, 0x8D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
        0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x08,
        0x0C, 0x06, 0x4F, 0x72, 0x65, 0x67, 0x6F, 0x6E, 0x31, 0x0E, 0x30, 0x0C,
        0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x05, 0x53, 0x61, 0x6C, 0x65, 0x6D,
        0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0A, 0x43,
        0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x45, 0x43, 0x43, 0x31, 0x0D, 0x30,
        0x0B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x04, 0x46, 0x61, 0x73, 0x74,
        0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77,
        0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63,
        0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
        0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40,
        0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30,
        0x1E, 0x17, 0x0D, 0x32, 0x30, 0x30, 0x36, 0x31, 0x39, 0x31, 0x33, 0x32,
        0x33, 0x34, 0x31, 0x5A, 0x17, 0x0D, 0x32, 0x33, 0x30, 0x33, 0x31, 0x36,
        0x31, 0x33, 0x32, 0x33, 0x34, 0x31, 0x5A, 0x30, 0x81, 0x8D, 0x31, 0x0B,
        0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
        0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x06, 0x4F, 0x72,
        0x65, 0x67, 0x6F, 0x6E, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04,
        0x07, 0x0C, 0x05, 0x53, 0x61, 0x6C, 0x65, 0x6D, 0x31, 0x13, 0x30, 0x11,
        0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0A, 0x43, 0x6C, 0x69, 0x65, 0x6E,
        0x74, 0x20, 0x45, 0x43, 0x43, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55,
        0x04, 0x0B, 0x0C, 0x04, 0x46, 0x61, 0x73, 0x74, 0x31, 0x18, 0x30, 0x26,
        0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77,
        0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F,
        0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09,
        0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66,
        0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x59, 0x30, 0x13, 0x06,
        0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86,
        0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x02, 0x00, 0x04, 0x55, 0xBF,
        0xF4, 0x0F, 0x44, 0x50, 0x9A, 0x3D, 0xCE, 0x9B, 0xB7, 0xF0, 0xC5, 0x4D,
        0xF5, 0x70, 0x7B, 0xD4, 0xEC, 0x24, 0x8E, 0x19, 0x80, 0xEC, 0x5A, 0x4C,
        0xA2, 0x24, 0x03, 0x62, 0x2C, 0x9B, 0xDA, 0xEF, 0xA2, 0x35, 0x12, 0x43,
        0x84, 0x76, 0x16, 0xC6, 0x56, 0x95, 0x06, 0xCC, 0x01, 0xA9, 0xBD, 0xF6,
        0x75, 0x1A, 0x42, 0xF7, 0xBD, 0xA9, 0xB2, 0x36, 0x22, 0x5F, 0xC7, 0x5D,
        0x7F, 0xB4, 0xA3, 0x82, 0x01, 0x3E, 0x30, 0x82, 0x01, 0x3A, 0x30, 0x1D,
        0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xEB, 0xD4, 0x4B,
        0x59, 0x6B, 0x95, 0x61, 0x3F, 0x51, 0x57, 0xB6, 0x04, 0x4D, 0x89, 0x41,
        0x88, 0x44, 0x5C, 0xAB, 0xF2, 0x30, 0x81, 0xCD, 0x06, 0x03, 0x55, 0x1D,
        0x23, 0x04, 0x81, 0xC5, 0x30, 0x81, 0xC2, 0x80, 0x14, 0xEB, 0xD4, 0x4B,
        0x59, 0x72, 0x95, 0x61, 0x3F, 0x51, 0x57, 0xB6, 0x04, 0x4D, 0x89, 0x41,
        0x88, 0x44, 0x5C, 0xAB, 0xF2, 0xA1, 0x81, 0x93, 0xA4, 0x81, 0x90, 0x30,
        0x81, 0x8D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
        0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x08, 0x08,
        0x0C, 0x06, 0x4F, 0x72, 0x65, 0x67, 0x6F, 0x6E, 0x31, 0x0E, 0x30, 0x0C,
        0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x05, 0x53, 0x61, 0x6C, 0x65, 0x6D,
        0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0A, 0x43,
        0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x45, 0x43, 0x43, 0x31, 0x0D, 0x30,
        0x0B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x04, 0x46, 0x61, 0x73, 0x74,
        0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77,
        0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63,
        0x6F, 0x6D, 0x30, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
        0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40,
        0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82,
        0x14, 0x61, 0xB3, 0x1E, 0x59, 0xF3, 0x68, 0x6C, 0xA4, 0x79, 0x42, 0x83,
        0x2F, 0x1A, 0x50, 0x71, 0x03, 0xBE, 0x32, 0xAA, 0x2C, 0x30, 0x0C, 0x06,
        0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30,
        0x1C, 0x06, 0x03, 0x55, 0x1D, 0x11, 0x04, 0x15, 0x30, 0x13, 0x82, 0x0B,
        0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x87,
        0x04, 0x23, 0x00, 0x00, 0x01, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x25,
        0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07,
        0x03, 0x01, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,
        0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02,
        0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xE4, 0xA0, 0x23, 0x26,
        0x2B, 0x0B, 0x42, 0x0F, 0x97, 0x37, 0x6D, 0xCB, 0x14, 0x23, 0xC3, 0xC3,
        0xE6, 0x44, 0xCF, 0x5F, 0x4C, 0x26, 0xA3, 0x72, 0x64, 0x7A, 0x9C, 0xCB,
        0x64, 0xAB, 0xA6, 0xBE, 0x02, 0x21, 0x00, 0xAA, 0xC5, 0xA3, 0x50, 0xF6,
        0xF1, 0xA5, 0xDB, 0x05, 0xE0, 0x75, 0xD2, 0xF7, 0xBA, 0x49, 0x5F, 0x8F,
        0x7D, 0x1C, 0x44, 0xB1, 0x6E, 0xDF, 0xC8, 0xDA, 0x10, 0x48, 0x2D, 0x53,
        0x08, 0xA8, 0xB4
        };
#endif
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        /* If initialization is not successful, it's free'd in init func. */
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)cert, (word32)certSz),
            0);
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;

        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        /* Valid initialization usage. */
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

        /* Pass in bad args. No need free for null checks, free at end.*/
        ExpectIntEQ(wc_PKCS7_InitWithCert(NULL, (byte*)cert, (word32)certSz),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, (word32)certSz),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#ifdef HAVE_ECC
        ExpectIntLT(wc_PKCS7_InitWithCert(pkcs7, certWithInvalidEccKey,
            sizeof(certWithInvalidEccKey)), 0);
    }
#endif

    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
} /* END test_wc_PKCS7_InitWithCert */


/*
 * Testing wc_PKCS7_EncodeData()
 */
static int test_wc_PKCS7_EncodeData(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7)
    PKCS7* pkcs7 = NULL;
    byte   output[FOURK_BUF];
    byte   data[] = "My encoded DER cert.";

#ifndef NO_RSA
    #if defined(USE_CERT_BUFFERS_2048)
        unsigned char cert[sizeof(client_cert_der_2048)];
        unsigned char key[sizeof(client_key_der_2048)];
        int certSz = (int)sizeof(cert);
        int keySz = (int)sizeof(key);

        XMEMSET(cert, 0, certSz);
        XMEMSET(key, 0, keySz);
        XMEMCPY(cert, client_cert_der_2048, certSz);
        XMEMCPY(key, client_key_der_2048, keySz);
    #elif defined(USE_CERT_BUFFERS_1024)
        unsigned char cert[sizeof(sizeof_client_cert_der_1024)];
        unsigned char key[sizeof_client_key_der_1024];
        int certSz = (int)sizeof(cert);
        int keySz = (int)sizeof(key);

        XMEMSET(cert, 0, certSz);
        XMEMSET(key, 0, keySz);
        XMEMCPY(cert, client_cert_der_1024, certSz);
        XMEMCPY(key, client_key_der_1024, keySz);
    #else
        unsigned char cert[ONEK_BUF];
        unsigned char key[ONEK_BUF];
        XFILE         fp = XBADFILE;
        int           certSz;
        int           keySz;

        ExpectTrue((fp = XFOPEN("./certs/1024/client-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, sizeof_client_cert_der_1024,
            fp), 0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }

        ExpectTrue((fp = XFOPEN("./certs/1024/client-key.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(keySz = (int)XFREAD(key, 1, sizeof_client_key_der_1024, fp),
            0);
        if (fp != XBADFILE)
            XFCLOSE(fp);
    #endif
#elif defined(HAVE_ECC)
    #if defined(USE_CERT_BUFFERS_256)
        unsigned char    cert[sizeof(cliecc_cert_der_256)];
        unsigned char    key[sizeof(ecc_clikey_der_256)];
        int              certSz = (int)sizeof(cert);
        int              keySz = (int)sizeof(key);
        XMEMSET(cert, 0, certSz);
        XMEMSET(key, 0, keySz);
        XMEMCPY(cert, cliecc_cert_der_256, sizeof_cliecc_cert_der_256);
        XMEMCPY(key, ecc_clikey_der_256, sizeof_ecc_clikey_der_256);
    #else
        unsigned char   cert[ONEK_BUF];
        unsigned char   key[ONEK_BUF];
        XFILE           fp = XBADFILE;
        int             certSz, keySz;

        ExpectTrue((fp = XFOPEN("./certs/client-ecc-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, sizeof_cliecc_cert_der_256,
            fp), 0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }

        ExpectTrue((fp = XFOPEN("./certs/client-ecc-key.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(keySz = (int)XFREAD(key, 1, sizeof_ecc_clikey_der_256, fp),
            0);
        if (fp != XBADFILE)
            XFCLOSE(fp);
    #endif
#endif

    XMEMSET(output, 0, sizeof(output));

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);

    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)cert, (word32)certSz), 0);

    if (pkcs7 != NULL) {
        pkcs7->content = data;
        pkcs7->contentSz = sizeof(data);
        pkcs7->privateKey = key;
        pkcs7->privateKeySz = (word32)keySz;
    }
    ExpectIntGT(wc_PKCS7_EncodeData(pkcs7, output, (word32)sizeof(output)), 0);

    /* Test bad args. */
    ExpectIntEQ(wc_PKCS7_EncodeData(NULL, output, (word32)sizeof(output)),
                                                            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeData(pkcs7, NULL, (word32)sizeof(output)),
                                                            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeData(pkcs7, output, 5), WC_NO_ERR_TRACE(BUFFER_E));

    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_PKCS7_EncodeData */


#if defined(HAVE_PKCS7) && defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && \
    !defined(NO_RSA) && !defined(NO_SHA256)
/* RSA sign raw digest callback */
static int rsaSignRawDigestCb(PKCS7* pkcs7, byte* digest, word32 digestSz,
                              byte* out, word32 outSz, byte* privateKey,
                              word32 privateKeySz, int devid, int hashOID)
{
    /* specific DigestInfo ASN.1 encoding prefix for a SHA2565 digest */
    byte digInfoEncoding[] = {
        0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
        0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
        0x00, 0x04, 0x20
    };

    int ret;
    byte digestInfo[ONEK_BUF];
    byte sig[FOURK_BUF];
    word32 digestInfoSz = 0;
    word32 idx = 0;
    RsaKey rsa;

    /* SHA-256 required only for this example callback due to above
     * digInfoEncoding[] */
    if (pkcs7 == NULL || digest == NULL || out == NULL ||
        (sizeof(digestInfo) < sizeof(digInfoEncoding) + digestSz) ||
        (hashOID != SHA256h)) {
        return -1;
    }

    /* build DigestInfo */
    XMEMCPY(digestInfo, digInfoEncoding, sizeof(digInfoEncoding));
    digestInfoSz += sizeof(digInfoEncoding);
    XMEMCPY(digestInfo + digestInfoSz, digest, digestSz);
    digestInfoSz += digestSz;

    /* set up RSA key */
    ret = wc_InitRsaKey_ex(&rsa, pkcs7->heap, devid);
    if (ret != 0) {
        return ret;
    }

    ret = wc_RsaPrivateKeyDecode(privateKey, &idx, &rsa, privateKeySz);

    /* sign DigestInfo */
    if (ret == 0) {
        ret = wc_RsaSSL_Sign(digestInfo, digestInfoSz, sig, sizeof(sig),
                             &rsa, pkcs7->rng);
        if (ret > 0) {
            if (ret > (int)outSz) {
                /* output buffer too small */
                ret = -1;
            }
            else {
                /* success, ret holds sig size */
                XMEMCPY(out, sig, ret);
            }
        }
    }

    wc_FreeRsaKey(&rsa);

    return ret;
}
#endif

#if defined(HAVE_PKCS7) && defined(ASN_BER_TO_DER)
typedef struct encodeSignedDataStream {
    byte out[FOURK_BUF*3];
    int  idx;
    word32 outIdx;
} encodeSignedDataStream;


/* content is 8k of partially created bundle */
static int GetContentCB(PKCS7* pkcs7, byte** content, void* ctx)
{
    int ret = 0;
    encodeSignedDataStream* strm = (encodeSignedDataStream*)ctx;

    if (strm->outIdx  < pkcs7->contentSz) {
        ret = (pkcs7->contentSz > strm->outIdx + FOURK_BUF)?
                FOURK_BUF : pkcs7->contentSz - strm->outIdx;
        *content = strm->out + strm->outIdx;
        strm->outIdx += ret;
    }

    (void)pkcs7;
    return ret;
}

static int StreamOutputCB(PKCS7* pkcs7, const byte* output, word32 outputSz,
    void* ctx)
{
    encodeSignedDataStream* strm = (encodeSignedDataStream*)ctx;

    XMEMCPY(strm->out + strm->idx, output, outputSz);
    strm->idx += outputSz;
    (void)pkcs7;
    return 0;
}
#endif


/*
 * Testing wc_PKCS7_EncodeSignedData()
 */
static int test_wc_PKCS7_EncodeSignedData(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7)
    PKCS7* pkcs7 = NULL;
    WC_RNG rng;
    byte   output[FOURK_BUF];
    byte   badOut[1];
    word32 outputSz = (word32)sizeof(output);
    word32 badOutSz = 0;
    byte   data[] = "Test data to encode.";
#ifndef NO_RSA
    int    encryptOid = RSAk;
    #if defined(USE_CERT_BUFFERS_2048)
        byte        key[sizeof(client_key_der_2048)];
        byte        cert[sizeof(client_cert_der_2048)];
        word32      keySz = (word32)sizeof(key);
        word32      certSz = (word32)sizeof(cert);
        XMEMSET(key, 0, keySz);
        XMEMSET(cert, 0, certSz);
        XMEMCPY(key, client_key_der_2048, keySz);
        XMEMCPY(cert, client_cert_der_2048, certSz);
    #elif defined(USE_CERT_BUFFERS_1024)
        byte        key[sizeof_client_key_der_1024];
        byte        cert[sizeof(sizeof_client_cert_der_1024)];
        word32      keySz = (word32)sizeof(key);
        word32      certSz = (word32)sizeof(cert);
        XMEMSET(key, 0, keySz);
        XMEMSET(cert, 0, certSz);
        XMEMCPY(key, client_key_der_1024, keySz);
        XMEMCPY(cert, client_cert_der_1024, certSz);
    #else
        unsigned char   cert[ONEK_BUF];
        unsigned char   key[ONEK_BUF];
        XFILE           fp = XBADFILE;
        int             certSz;
        int             keySz;

        ExpectTrue((fp = XFOPEN("./certs/1024/client-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, sizeof_client_cert_der_1024,
            fp), 0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }

        ExpectTrue((fp = XFOPEN("./certs/1024/client-key.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(keySz = (int)XFREAD(key, 1, sizeof_client_key_der_1024, fp),
            0);
        if (fp != XBADFILE)
            XFCLOSE(fp);
    #endif
#elif defined(HAVE_ECC)
    int    encryptOid = ECDSAk;
    #if defined(USE_CERT_BUFFERS_256)
        unsigned char    cert[sizeof(cliecc_cert_der_256)];
        unsigned char    key[sizeof(ecc_clikey_der_256)];
        int              certSz = (int)sizeof(cert);
        int              keySz = (int)sizeof(key);
        XMEMSET(cert, 0, certSz);
        XMEMSET(key, 0, keySz);
        XMEMCPY(cert, cliecc_cert_der_256, certSz);
        XMEMCPY(key, ecc_clikey_der_256, keySz);
    #else
        unsigned char   cert[ONEK_BUF];
        unsigned char   key[ONEK_BUF];
        XFILE           fp = XBADFILE;
        int             certSz;
        int             keySz;

        ExpectTrue((fp = XFOPEN("./certs/client-ecc-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, ONEK_BUF, fp), 0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }

        ExpectTrue((fp = XFOPEN("./certs/client-ecc-key.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(keySz = (int)XFREAD(key, 1, ONEK_BUF, fp), 0);
        if (fp != XBADFILE)
            XFCLOSE(fp);
    #endif
#endif

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    XMEMSET(output, 0, outputSz);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);

    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0);

    if (pkcs7 != NULL) {
        pkcs7->content = data;
        pkcs7->contentSz = (word32)sizeof(data);
        pkcs7->privateKey = key;
        pkcs7->privateKeySz = (word32)sizeof(key);
        pkcs7->encryptOID = encryptOid;
    #ifdef NO_SHA
        pkcs7->hashOID = SHA256h;
    #else
        pkcs7->hashOID = SHAh;
    #endif
        pkcs7->rng = &rng;
    }

    ExpectIntGT(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);

#if defined(ASN_BER_TO_DER) && !defined(NO_RSA)
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    /* reinitialize and test setting stream mode */
    {
        int signedSz = 0;
        encodeSignedDataStream strm;

        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);

        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0);

        if (pkcs7 != NULL) {
            pkcs7->content = data;
            pkcs7->contentSz = (word32)sizeof(data);
            pkcs7->privateKey = key;
            pkcs7->privateKeySz = (word32)sizeof(key);
            pkcs7->encryptOID = encryptOid;
        #ifdef NO_SHA
            pkcs7->hashOID = SHA256h;
        #else
            pkcs7->hashOID = SHAh;
        #endif
            pkcs7->rng = &rng;
        }
        ExpectIntEQ(wc_PKCS7_GetStreamMode(pkcs7), 0);
        ExpectIntEQ(wc_PKCS7_SetStreamMode(pkcs7, 1, NULL, NULL, NULL), 0);
        ExpectIntEQ(wc_PKCS7_SetStreamMode(NULL, 1, NULL, NULL, NULL),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_PKCS7_GetStreamMode(pkcs7), 1);

        ExpectIntGT(signedSz = wc_PKCS7_EncodeSignedData(pkcs7, output,
            outputSz), 0);
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;

        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

        /* use exact signed buffer size since BER encoded */
        ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, (word32)signedSz),
            0);
        wc_PKCS7_Free(pkcs7);

        /* now try with using callbacks for IO */
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);

        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0);

        if (pkcs7 != NULL) {
            pkcs7->contentSz  = FOURK_BUF*2;
            pkcs7->privateKey = key;
            pkcs7->privateKeySz = (word32)sizeof(key);
            pkcs7->encryptOID = encryptOid;
        #ifdef NO_SHA
            pkcs7->hashOID = SHA256h;
        #else
            pkcs7->hashOID = SHAh;
        #endif
            pkcs7->rng = &rng;
        }
        XMEMSET(&strm, 0, sizeof(strm));
        ExpectIntEQ(wc_PKCS7_SetStreamMode(pkcs7, 1, GetContentCB,
            StreamOutputCB, (void*)&strm), 0);

        ExpectIntGT(signedSz = wc_PKCS7_EncodeSignedData(pkcs7, NULL, 0), 0);
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;

        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

        /* use exact signed buffer size since BER encoded */
        ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, strm.out, (word32)signedSz), 0);
    }
#endif
#ifndef NO_PKCS7_STREAM
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    {
        word32 z;
        int ret;

        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

        /* test for streaming mode */
        ret = -1;
        for (z = 0; z < outputSz && ret != 0; z++) {
            ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
            if (ret < 0){
                ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
            }
        }
        ExpectIntEQ(ret, 0);
        ExpectIntNE(pkcs7->contentSz, 0);
        ExpectNotNull(pkcs7->contentDynamic);
    }
#endif /* !NO_PKCS7_STREAM */


    /* Pass in bad args. */
    ExpectIntEQ(wc_PKCS7_EncodeSignedData(NULL, output, outputSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeSignedData(pkcs7, NULL, outputSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeSignedData(pkcs7, badOut,
                                badOutSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->hashOID = 0; /* bad hashOID */
    }
    ExpectIntEQ(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

#if defined(HAVE_PKCS7) && defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && \
    !defined(NO_RSA) && !defined(NO_SHA256)
    /* test RSA sign raw digest callback, if using RSA and compiled in.
     * Example callback assumes SHA-256, so only run test if compiled in. */
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0);

    if (pkcs7 != NULL) {
        pkcs7->content = data;
        pkcs7->contentSz = (word32)sizeof(data);
        pkcs7->privateKey = key;
        pkcs7->privateKeySz = (word32)sizeof(key);
        pkcs7->encryptOID = RSAk;
        pkcs7->hashOID = SHA256h;
        pkcs7->rng = &rng;
    }

    ExpectIntEQ(wc_PKCS7_SetRsaSignRawDigestCb(pkcs7, rsaSignRawDigestCb), 0);

    ExpectIntGT(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz), 0);
#endif

    wc_PKCS7_Free(pkcs7);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);

#endif
    return EXPECT_RESULT();
} /* END test_wc_PKCS7_EncodeSignedData */


/*
 * Testing wc_PKCS7_EncodeSignedData_ex() and wc_PKCS7_VerifySignedData_ex()
 */
static int test_wc_PKCS7_EncodeSignedData_ex(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7)
    int        i;
    PKCS7*     pkcs7 = NULL;
    WC_RNG     rng;
    byte       outputHead[FOURK_BUF/2];
    byte       outputFoot[FOURK_BUF/2];
    word32     outputHeadSz = (word32)sizeof(outputHead);
    word32     outputFootSz = (word32)sizeof(outputFoot);
    byte       data[FOURK_BUF];
    wc_HashAlg hash;
#ifdef NO_SHA
    enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
#else
    enum wc_HashType hashType = WC_HASH_TYPE_SHA;
#endif
    byte        hashBuf[WC_MAX_DIGEST_SIZE];
    word32      hashSz = (word32)wc_HashGetDigestSize(hashType);

#ifndef NO_RSA
    #if defined(USE_CERT_BUFFERS_2048)
        byte        key[sizeof(client_key_der_2048)];
        byte        cert[sizeof(client_cert_der_2048)];
        word32      keySz = (word32)sizeof(key);
        word32      certSz = (word32)sizeof(cert);
        XMEMSET(key, 0, keySz);
        XMEMSET(cert, 0, certSz);
        XMEMCPY(key, client_key_der_2048, keySz);
        XMEMCPY(cert, client_cert_der_2048, certSz);
    #elif defined(USE_CERT_BUFFERS_1024)
        byte        key[sizeof_client_key_der_1024];
        byte        cert[sizeof(sizeof_client_cert_der_1024)];
        word32      keySz = (word32)sizeof(key);
        word32      certSz = (word32)sizeof(cert);
        XMEMSET(key, 0, keySz);
        XMEMSET(cert, 0, certSz);
        XMEMCPY(key, client_key_der_1024, keySz);
        XMEMCPY(cert, client_cert_der_1024, certSz);
    #else
        unsigned char  cert[ONEK_BUF];
        unsigned char  key[ONEK_BUF];
        XFILE          fp = XBADFILE;
        int            certSz;
        int            keySz;

        ExpectTure((fp = XFOPEN("./certs/1024/client-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, sizeof_client_cert_der_1024,
            fp), 0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }

        ExpectTrue((fp = XFOPEN("./certs/1024/client-key.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(keySz = (int)XFREAD(key, 1, sizeof_client_key_der_1024, fp),
            0);
        if (fp != XBADFILE)
            XFCLOSE(fp);
    #endif
#elif defined(HAVE_ECC)
    #if defined(USE_CERT_BUFFERS_256)
        unsigned char   cert[sizeof(cliecc_cert_der_256)];
        unsigned char   key[sizeof(ecc_clikey_der_256)];
        int             certSz = (int)sizeof(cert);
        int             keySz = (int)sizeof(key);

        XMEMSET(cert, 0, certSz);
        XMEMSET(key, 0, keySz);
        XMEMCPY(cert, cliecc_cert_der_256, sizeof_cliecc_cert_der_256);
        XMEMCPY(key, ecc_clikey_der_256, sizeof_ecc_clikey_der_256);
    #else
        unsigned char cert[ONEK_BUF];
        unsigned char key[ONEK_BUF];
        XFILE         fp = XBADFILE;
        int           certSz;
        int           keySz;

        ExpectTrue((fp = XFOPEN("./certs/client-ecc-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, sizeof_cliecc_cert_der_256,
            fp), 0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }

        ExpectTrue((fp = XFOPEN("./certs/client-ecc-key.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(keySz = (int)XFREAD(key, 1, sizeof_ecc_clikey_der_256, fp),
            0);
        if (fp != XBADFILE)
            XFCLOSE(fp);
    #endif
#endif

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    /* initialize large data with sequence */
    for (i=0; i<(int)sizeof(data); i++)
        data[i] = i & 0xff;

    XMEMSET(outputHead, 0, outputHeadSz);
    XMEMSET(outputFoot, 0, outputFootSz);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);

    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0);

    if (pkcs7 != NULL) {
        pkcs7->content = NULL; /* not used for ex */
        pkcs7->contentSz = (word32)sizeof(data);
        pkcs7->privateKey = key;
        pkcs7->privateKeySz = (word32)sizeof(key);
        pkcs7->encryptOID = RSAk;
    #ifdef NO_SHA
        pkcs7->hashOID = SHA256h;
    #else
        pkcs7->hashOID = SHAh;
    #endif
        pkcs7->rng = &rng;
    }

    /* calculate hash for content */
    XMEMSET(&hash, 0, sizeof(wc_HashAlg));
    ExpectIntEQ(wc_HashInit(&hash, hashType), 0);
    ExpectIntEQ(wc_HashUpdate(&hash, hashType, data, sizeof(data)), 0);
    ExpectIntEQ(wc_HashFinal(&hash, hashType, hashBuf), 0);
    DoExpectIntEQ(wc_HashFree(&hash, hashType), 0);

    /* Perform PKCS7 sign using hash directly */
    ExpectIntEQ(wc_PKCS7_EncodeSignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, &outputHeadSz, outputFoot, &outputFootSz), 0);
    ExpectIntGT(outputHeadSz, 0);
    ExpectIntGT(outputFootSz, 0);

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

    /* required parameter even on verify when using _ex, if using outputHead
     * and outputFoot */
    if (pkcs7 != NULL) {
        pkcs7->contentSz = (word32)sizeof(data);
    }
    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, outputHeadSz, outputFoot, outputFootSz), 0);

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    /* assembly complete PKCS7 sign and use normal verify */
    {
        byte* output = NULL;
        word32 outputSz = 0;
    #ifndef NO_PKCS7_STREAM
        word32 z;
        int ret;
    #endif /* !NO_PKCS7_STREAM */

        ExpectNotNull(output = (byte*)XMALLOC(
            outputHeadSz + sizeof(data) + outputFootSz, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        if (output != NULL) {
            XMEMCPY(&output[outputSz], outputHead, outputHeadSz);
            outputSz += outputHeadSz;
            XMEMCPY(&output[outputSz], data, sizeof(data));
            outputSz += sizeof(data);
            XMEMCPY(&output[outputSz], outputFoot, outputFootSz);
            outputSz += outputFootSz;
        }

        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
        ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);

    #ifndef NO_PKCS7_STREAM
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;

        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

        /* test for streaming mode */
        ret = -1;
        for (z = 0; z < outputSz && ret != 0; z++) {
            ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
            if (ret < 0){
                ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
            }
        }
        ExpectIntEQ(ret, 0);
        ExpectIntNE(pkcs7->contentSz, 0);
        ExpectNotNull(pkcs7->contentDynamic);

        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    #endif /* !NO_PKCS7_STREAM */

        XFREE(output, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    }

    /* Pass in bad args. */
    ExpectIntEQ(wc_PKCS7_EncodeSignedData_ex(NULL, hashBuf, hashSz, outputHead,
        &outputHeadSz, outputFoot, &outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeSignedData_ex(pkcs7, NULL, hashSz, outputHead,
        &outputHeadSz, outputFoot, &outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeSignedData_ex(pkcs7, hashBuf, 0, outputHead,
        &outputHeadSz, outputFoot, &outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeSignedData_ex(pkcs7, hashBuf, hashSz, NULL,
        &outputHeadSz, outputFoot, &outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeSignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, NULL, outputFoot, &outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeSignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, &outputHeadSz, NULL, &outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeSignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, &outputHeadSz, outputFoot, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->hashOID = 0; /* bad hashOID */
    }
    ExpectIntEQ(wc_PKCS7_EncodeSignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, &outputHeadSz, outputFoot, &outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(NULL, hashBuf, hashSz, outputHead,
        outputHeadSz, outputFoot, outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, NULL, hashSz, outputHead,
        outputHeadSz, outputFoot, outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_PKCS7_STREAM
    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, 0, outputHead,
        outputHeadSz, outputFoot, outputFootSz), WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
#else
    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, 0, outputHead,
        outputHeadSz, outputFoot, outputFootSz), WC_NO_ERR_TRACE(BUFFER_E));
#endif
    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz, NULL,
        outputHeadSz, outputFoot, outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_PKCS7_STREAM
    /* can pass in 0 buffer length with streaming API */
    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, 0, outputFoot, outputFootSz), WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
#else
    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, 0, outputFoot, outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, outputHeadSz, NULL, outputFootSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_PKCS7_STREAM
    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, outputHeadSz, outputFoot, 0), WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
#else
    ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
        outputHead, outputHeadSz, outputFoot, 0), WC_NO_ERR_TRACE(BUFFER_E));
#endif

    wc_PKCS7_Free(pkcs7);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* END test_wc_PKCS7_EncodeSignedData_ex */


#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM)

/**
 * Loads certs/keys from files or buffers into the argument buffers,
 * helper function called by CreatePKCS7SignedData().
 *
 * Returns 0 on success, negative on error.
 */
static int LoadPKCS7SignedDataCerts(
        int useIntermediateCertChain, int pkAlgoType,
        byte* intCARoot, word32* intCARootSz,
        byte* intCA1, word32* intCA1Sz,
        byte* intCA2, word32* intCA2Sz,
        byte* cert, word32* certSz,
        byte* key, word32* keySz)
{
    EXPECT_DECLS;
    int ret = 0;
    XFILE fp = XBADFILE;

#ifndef NO_RSA
    const char* intCARootRSA   = "./certs/ca-cert.der";
    const char* intCA1RSA      = "./certs/intermediate/ca-int-cert.der";
    const char* intCA2RSA      = "./certs/intermediate/ca-int2-cert.der";
    const char* intServCertRSA = "./certs/intermediate/server-int-cert.der";
    const char* intServKeyRSA  = "./certs/server-key.der";

    #if !defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_1024)
        const char* cli1024Cert    = "./certs/1024/client-cert.der";
        const char* cli1024Key     = "./certs/1024/client-key.der";
    #endif
#endif
#ifdef HAVE_ECC
    const char* intCARootECC   = "./certs/ca-ecc-cert.der";
    const char* intCA1ECC      = "./certs/intermediate/ca-int-ecc-cert.der";
    const char* intCA2ECC      = "./certs/intermediate/ca-int2-ecc-cert.der";
    const char* intServCertECC = "./certs/intermediate/server-int-ecc-cert.der";
    const char* intServKeyECC  = "./certs/ecc-key.der";

    #ifndef USE_CERT_BUFFERS_256
        const char* cliEccCert     = "./certs/client-ecc-cert.der";
        const char* cliEccKey      = "./certs/client-ecc-key.der";
    #endif
#endif

    if (cert == NULL || certSz == NULL || key == NULL || keySz == NULL ||
        ((useIntermediateCertChain == 1) &&
        (intCARoot == NULL || intCARootSz == NULL || intCA1 == NULL ||
         intCA1Sz == NULL || intCA2 == NULL || intCA2Sz == NULL))) {
        return BAD_FUNC_ARG;
    }

    /* Read/load certs and keys to use for signing based on PK type and chain */
    switch (pkAlgoType) {
#ifndef NO_RSA
        case RSA_TYPE:
            if (useIntermediateCertChain == 1) {
                ExpectTrue((fp = XFOPEN(intCARootRSA, "rb")) != XBADFILE);
                *intCARootSz = (word32)XFREAD(intCARoot, 1, *intCARootSz, fp);
                if (fp != XBADFILE) {
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*intCARootSz, 0);

                ExpectTrue((fp = XFOPEN(intCA1RSA, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *intCA1Sz = (word32)XFREAD(intCA1, 1, *intCA1Sz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*intCA1Sz, 0);

                ExpectTrue((fp = XFOPEN(intCA2RSA, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *intCA2Sz = (word32)XFREAD(intCA2, 1, *intCA2Sz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*intCA2Sz, 0);

                ExpectTrue((fp = XFOPEN(intServCertRSA, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *certSz = (word32)XFREAD(cert, 1, *certSz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*certSz, 0);

                ExpectTrue((fp = XFOPEN(intServKeyRSA, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *keySz = (word32)XFREAD(key, 1, *keySz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*keySz, 0);
            }
            else {
            #if defined(USE_CERT_BUFFERS_2048)
                *keySz  = sizeof_client_key_der_2048;
                *certSz = sizeof_client_cert_der_2048;
                XMEMCPY(key, client_key_der_2048, *keySz);
                XMEMCPY(cert, client_cert_der_2048, *certSz);
            #elif defined(USE_CERT_BUFFERS_1024)
                *keySz  = sizeof_client_key_der_1024;
                *certSz = sizeof_client_cert_der_1024;
                XMEMCPY(key, client_key_der_1024, *keySz);
                XMEMCPY(cert, client_cert_der_1024, *certSz);
            #else
                ExpectTrue((fp = XFOPEN(cli1024Key, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *keySz = (word32)XFREAD(key, 1, *keySz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*keySz, 0);

                ExpectTrue((fp = XFOPEN(cli1024Cert, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *certSz = (word32)XFREAD(cert, 1, *certSz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*certSz, 0);
            #endif /* USE_CERT_BUFFERS_2048 */
            }
            break;
#endif /* !NO_RSA */
#ifdef HAVE_ECC
        case ECC_TYPE:
            if (useIntermediateCertChain == 1) {
                ExpectTrue((fp = XFOPEN(intCARootECC, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *intCARootSz = (word32)XFREAD(intCARoot, 1, *intCARootSz,
                                                  fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*intCARootSz, 0);

                ExpectTrue((fp = XFOPEN(intCA1ECC, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *intCA1Sz = (word32)XFREAD(intCA1, 1, *intCA1Sz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*intCA1Sz, 0);

                ExpectTrue((fp = XFOPEN(intCA2ECC, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *intCA2Sz = (word32)XFREAD(intCA2, 1, *intCA2Sz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*intCA2Sz, 0);

                ExpectTrue((fp = XFOPEN(intServCertECC, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *certSz = (word32)XFREAD(cert, 1, *certSz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*certSz, 0);

                ExpectTrue((fp = XFOPEN(intServKeyECC, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *keySz = (word32)XFREAD(key, 1, *keySz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*keySz, 0);
            }
            else {
            #if defined(USE_CERT_BUFFERS_256)
                *keySz  = sizeof_ecc_clikey_der_256;
                *certSz = sizeof_cliecc_cert_der_256;
                XMEMCPY(key, ecc_clikey_der_256, *keySz);
                XMEMCPY(cert, cliecc_cert_der_256, *certSz);
            #else
                ExpectTrue((fp = XFOPEN(cliEccKey, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *keySz = (word32)XFREAD(key, 1, *keySz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*keySz, 0);

                ExpectTrue((fp = XFOPEN(cliEccCert, "rb")) != XBADFILE);
                if (fp != XBADFILE) {
                    *certSz = (word32)XFREAD(cert, 1, *certSz, fp);
                    XFCLOSE(fp);
                    fp = XBADFILE;
                }
                ExpectIntGT(*certSz, 0);
            #endif /* USE_CERT_BUFFERS_256 */
            }
            break;
#endif /* HAVE_ECC */
        default:
            WOLFSSL_MSG("Unsupported SignedData PK type");
            ret = BAD_FUNC_ARG;
            break;
    }

    if (EXPECT_FAIL() && (ret == 0)) {
        ret = BAD_FUNC_ARG;
    }
    return ret;
}

/**
 * Creates a PKCS7/CMS SignedData bundle to use for testing.
 *
 * output          output buffer to place SignedData
 * outputSz        size of output buffer
 * data            data buffer to be signed
 * dataSz          size of data buffer
 * withAttribs     [1/0] include attributes in SignedData message
 * detachedSig     [1/0] create detached signature, no content
 * useIntCertChain [1/0] use certificate chain and include intermediate and
 *                 root CAs in bundle
 * pkAlgoType      RSA_TYPE or ECC_TYPE, choose what key/cert type to use
 *
 * Return size of bundle created on success, negative on error */
static int CreatePKCS7SignedData(unsigned char* output, int outputSz,
                                 byte* data, word32 dataSz,
                                 int withAttribs, int detachedSig,
                                 int useIntermediateCertChain,
                                 int pkAlgoType)
{
    EXPECT_DECLS;
    int ret = 0;
    WC_RNG rng;
    PKCS7* pkcs7 = NULL;

    static byte messageTypeOid[] =
               { 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
                 0x09, 0x02 };
    static byte messageType[] = { 0x13, 2, '1', '9' };

    PKCS7Attrib attribs[] =
    {
        { messageTypeOid, sizeof(messageTypeOid), messageType,
                                       sizeof(messageType) }
    };

    byte intCARoot[TWOK_BUF];
    byte intCA1[TWOK_BUF];
    byte intCA2[TWOK_BUF];
    byte cert[TWOK_BUF];
    byte key[TWOK_BUF];

    word32 intCARootSz = sizeof(intCARoot);
    word32 intCA1Sz    = sizeof(intCA1);
    word32 intCA2Sz    = sizeof(intCA2);
    word32 certSz      = sizeof(cert);
    word32 keySz       = sizeof(key);

    XMEMSET(intCARoot, 0, intCARootSz);
    XMEMSET(intCA1, 0, intCA1Sz);
    XMEMSET(intCA2, 0, intCA2Sz);
    XMEMSET(cert, 0, certSz);
    XMEMSET(key, 0, keySz);

    ret = LoadPKCS7SignedDataCerts(useIntermediateCertChain, pkAlgoType,
                intCARoot, &intCARootSz, intCA1, &intCA1Sz, intCA2, &intCA2Sz,
                cert, &certSz, key, &keySz);
    ExpectIntEQ(ret, 0);

    XMEMSET(output, 0, outputSz);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0);

    if (useIntermediateCertChain == 1) {
        /* Add intermediate and root CA certs into SignedData Certs SET */
        ExpectIntEQ(wc_PKCS7_AddCertificate(pkcs7, intCA2, intCA2Sz), 0);
        ExpectIntEQ(wc_PKCS7_AddCertificate(pkcs7, intCA1, intCA1Sz), 0);
        ExpectIntEQ(wc_PKCS7_AddCertificate(pkcs7, intCARoot, intCARootSz), 0);
    }

    if (pkcs7 != NULL) {
        pkcs7->content = data;
        pkcs7->contentSz = dataSz;
        pkcs7->privateKey = key;
        pkcs7->privateKeySz = (word32)sizeof(key);
        if (pkAlgoType == RSA_TYPE) {
            pkcs7->encryptOID = RSAk;
        }
        else {
            pkcs7->encryptOID = ECDSAk;
        }
    #ifdef NO_SHA
        pkcs7->hashOID = SHA256h;
    #else
        pkcs7->hashOID = SHAh;
    #endif
        pkcs7->rng = &rng;
        if (withAttribs) {
            /* include a signed attribute */
            pkcs7->signedAttribs   = attribs;
            pkcs7->signedAttribsSz = (sizeof(attribs)/sizeof(PKCS7Attrib));
        }
    }

    if (detachedSig) {
        ExpectIntEQ(wc_PKCS7_SetDetached(pkcs7, 1), 0);
    }

    outputSz = wc_PKCS7_EncodeSignedData(pkcs7, output, (word32)outputSz);
    ExpectIntGT(outputSz, 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    if (detachedSig && (pkcs7 != NULL)) {
        pkcs7->content = data;
        pkcs7->contentSz = dataSz;
    }
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, (word32)outputSz), 0);

    wc_PKCS7_Free(pkcs7);
    wc_FreeRng(&rng);

    if (EXPECT_FAIL()) {
        outputSz = 0;
    }
    return outputSz;
}
#endif

/*
 * Testing wc_PKCS_VerifySignedData()
 */
static int test_wc_PKCS7_VerifySignedData_RSA(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    PKCS7* pkcs7 = NULL;
    byte   output[6000]; /* Large size needed for bundles with int CA certs */
    word32 outputSz = sizeof(output);
    byte   data[] = "Test data to encode.";
    byte   badOut[1];
    word32 badOutSz = 0;
    byte   badContent[] = "This is different content than was signed";
    wc_HashAlg hash;
#ifdef NO_SHA
    enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
#else
    enum wc_HashType hashType = WC_HASH_TYPE_SHA;
#endif
    byte        hashBuf[WC_MAX_DIGEST_SIZE];
    word32      hashSz = (word32)wc_HashGetDigestSize(hashType);
#ifndef NO_RSA
    PKCS7DecodedAttrib* decodedAttrib = NULL;
    /* contentType OID (1.2.840.113549.1.9.3) */
    static const byte contentTypeOid[] =
        { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01, 0x09, 0x03 };

    /* PKCS#7 DATA content type (contentType defaults to DATA) */
    static const byte dataType[] =
        { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };

    /* messageDigest OID (1.2.840.113549.1.9.4) */
    static const byte messageDigestOid[] =
        { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04 };
#ifndef NO_ASN_TIME
    /* signingTime OID () */
    static const byte signingTimeOid[] =
        { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05};
#endif
#if !defined(NO_ASN) && !defined(NO_ASN_TIME)
    int dateLength = 0;
    byte dateFormat;
    const byte* datePart = NULL;
    struct tm timearg;
    time_t now;
    struct tm* nowTm = NULL;
#ifdef NEED_TMP_TIME
    struct tm tmpTimeStorage;
    struct tm* tmpTime = &tmpTimeStorage;
#endif
#endif /* !NO_ASN && !NO_ASN_TIME */
#ifndef NO_PKCS7_STREAM
    word32 z;
    int ret;
#endif /* !NO_PKCS7_STREAM */

    XMEMSET(&hash, 0, sizeof(wc_HashAlg));

    /* Success test with RSA certs/key */
    ExpectIntGT((outputSz = (word32)CreatePKCS7SignedData(output, (int)outputSz, data,
        (word32)sizeof(data), 0, 0, 0, RSA_TYPE)), 0);

    /* calculate hash for content, used later */
    ExpectIntEQ(wc_HashInit(&hash, hashType), 0);
    ExpectIntEQ(wc_HashUpdate(&hash, hashType, data, sizeof(data)), 0);
    ExpectIntEQ(wc_HashFinal(&hash, hashType, hashBuf), 0);
    DoExpectIntEQ(wc_HashFree(&hash, hashType), 0);

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);

#ifndef NO_PKCS7_STREAM
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

    /* test for streaming */
    ret = -1;
    for (z = 0; z < outputSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
    ExpectIntNE(pkcs7->contentSz, 0);
    ExpectNotNull(pkcs7->contentDynamic);
#endif /* !NO_PKCS7_STREAM */

    /* Check that decoded signed attributes are correct */

    /* messageDigest should be first */
    if (pkcs7 != NULL) {
        decodedAttrib = pkcs7->decodedAttrib;
    }
    ExpectNotNull(decodedAttrib);
    ExpectIntEQ(decodedAttrib->oidSz, (word32)sizeof(messageDigestOid));
    ExpectIntEQ(XMEMCMP(decodedAttrib->oid, messageDigestOid,
        decodedAttrib->oidSz), 0);
    /* + 2 for OCTET STRING and length bytes */
    ExpectIntEQ(decodedAttrib->valueSz, hashSz + 2);
    ExpectNotNull(decodedAttrib->value);
    ExpectIntEQ(XMEMCMP(decodedAttrib->value + 2, hashBuf, hashSz), 0);

#ifndef NO_ASN_TIME
    /* signingTime should be second */
    if (decodedAttrib != NULL) {
        decodedAttrib = decodedAttrib->next;
    }
    ExpectNotNull(decodedAttrib);
    ExpectIntEQ(decodedAttrib->oidSz, (word32)sizeof(signingTimeOid));
    ExpectIntEQ(XMEMCMP(decodedAttrib->oid, signingTimeOid,
        decodedAttrib->oidSz), 0);

    ExpectIntGT(decodedAttrib->valueSz, 0);
    ExpectNotNull(decodedAttrib->value);
#endif

    /* Verify signingTime if ASN and time are available */
#if !defined(NO_ASN) && !defined(NO_ASN_TIME)
    ExpectIntEQ(wc_GetDateInfo(decodedAttrib->value, decodedAttrib->valueSz,
        &datePart, &dateFormat, &dateLength), 0);
    ExpectNotNull(datePart);
    ExpectIntGT(dateLength, 0);
    XMEMSET(&timearg, 0, sizeof(timearg));
    ExpectIntEQ(wc_GetDateAsCalendarTime(datePart, dateLength, dateFormat,
         &timearg), 0);

    /* Get current time and compare year/month/day against attribute value */
    ExpectIntEQ(wc_GetTime(&now, sizeof(now)), 0);
    nowTm = (struct tm*)XGMTIME((time_t*)&now, tmpTime);
    ExpectNotNull(nowTm);

    ExpectIntEQ(timearg.tm_year, nowTm->tm_year);
    ExpectIntEQ(timearg.tm_mon, nowTm->tm_mon);
    ExpectIntEQ(timearg.tm_mday, nowTm->tm_mday);
#endif /* !NO_ASN && !NO_ASN_TIME */

    /* contentType should be third */
    if (decodedAttrib != NULL) {
        decodedAttrib = decodedAttrib->next;
    }
    ExpectNotNull(decodedAttrib);
    ExpectIntEQ(decodedAttrib->oidSz, (word32)sizeof(contentTypeOid));
    ExpectIntEQ(XMEMCMP(decodedAttrib->oid, contentTypeOid,
        decodedAttrib->oidSz), 0);
    ExpectIntEQ(decodedAttrib->valueSz, (int)sizeof(dataType) + 2);
    ExpectNotNull(decodedAttrib->value);
    ExpectIntEQ(XMEMCMP(decodedAttrib->value + 2, dataType, sizeof(dataType)),
        0);
#endif /* !NO_RSA */

    /* Test bad args. */
    ExpectIntEQ(wc_PKCS7_VerifySignedData(NULL, output, outputSz),
                                          WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, NULL, outputSz),
                                          WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    #ifndef NO_PKCS7_STREAM
        /* can pass in 0 buffer length with streaming API */
        ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, badOut,
                                    badOutSz), WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
    #else
        ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, badOut,
                                    badOutSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    #endif
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_RSA
    /* Try RSA certs/key/sig first */
    outputSz = sizeof(output);
    XMEMSET(output, 0, outputSz);
    ExpectIntGT((outputSz = (word32)CreatePKCS7SignedData(output, (int)outputSz, data,
                                                  (word32)sizeof(data),
                                                  1, 1, 0, RSA_TYPE)), 0);
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    if (pkcs7 != NULL) {
        pkcs7->content = badContent;
        pkcs7->contentSz = sizeof(badContent);
    }
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz),
                WC_NO_ERR_TRACE(SIG_VERIFY_E));

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_PKCS7_STREAM
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    if (pkcs7 != NULL) {
        pkcs7->content = badContent;
        pkcs7->contentSz = sizeof(badContent);
    }
    /* test for streaming */
    ret = -1;
    for (z = 0; z < outputSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
        if (ret == WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)){
            continue;
        }
        else if (ret < 0) {
            break;
        }
    }
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(SIG_VERIFY_E));
    ExpectIntNE(pkcs7->contentSz, 0);
    ExpectNotNull(pkcs7->contentDynamic);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
#endif /* !NO_PKCS7_STREAM */


    /* Test success case with detached signature and valid content */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    if (pkcs7 != NULL) {
        pkcs7->content = data;
        pkcs7->contentSz = sizeof(data);
    }
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_PKCS7_STREAM
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    if (pkcs7 != NULL) {
        pkcs7->content = data;
        pkcs7->contentSz = sizeof(data);
    }

    /* test for streaming */
    ret = -1;
    for (z = 0; z < outputSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
    ExpectIntNE(pkcs7->contentSz, 0);
    ExpectNotNull(pkcs7->contentDynamic);

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
#endif /* !NO_PKCS7_STREAM */

    /* verify using pre-computed content digest only (no content) */
    {
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_Init(pkcs7, NULL, 0), 0);
        ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
            output, outputSz, NULL, 0), 0);
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;
    }
#endif /* !NO_RSA */

    /* Test verify on signedData containing intermediate/root CA certs */
#ifndef NO_RSA
    outputSz = sizeof(output);
    XMEMSET(output, 0, outputSz);
    ExpectIntGT((outputSz = (word32)CreatePKCS7SignedData(output, (int)outputSz, data,
                                                  (word32)sizeof(data),
                                                  0, 0, 1, RSA_TYPE)), 0);
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_PKCS7_STREAM
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

    /* test for streaming */
    ret = -1;
    for (z = 0; z < outputSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
    ExpectIntNE(pkcs7->contentSz, 0);
    ExpectNotNull(pkcs7->contentDynamic);

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
#endif /* !NO_PKCS7_STREAM */

#endif /* !NO_RSA */
#if defined(ASN_BER_TO_DER) && !defined(NO_PKCS7_STREAM) && \
        !defined(NO_FILESYSTEM)
    {
        XFILE signedBundle = XBADFILE;
        int   signedBundleSz = 0;
        int   chunkSz = 1;
        int   i, rc = 0;
        byte* buf = NULL;

        ExpectTrue((signedBundle = XFOPEN("./certs/test-stream-sign.p7b",
            "rb")) != XBADFILE);
        ExpectTrue(XFSEEK(signedBundle, 0, XSEEK_END) == 0);
        ExpectIntGT(signedBundleSz = (int)XFTELL(signedBundle), 0);
        ExpectTrue(XFSEEK(signedBundle, 0, XSEEK_SET) == 0);
        ExpectNotNull(buf = (byte*)XMALLOC(signedBundleSz, HEAP_HINT,
            DYNAMIC_TYPE_FILE));
        if (buf != NULL) {
            ExpectIntEQ(XFREAD(buf, 1, (size_t)signedBundleSz, signedBundle),
                signedBundleSz);
        }
        if (signedBundle != XBADFILE) {
            XFCLOSE(signedBundle);
            signedBundle = XBADFILE;
        }

        if (buf != NULL) {
            ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
            ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
            for (i = 0; i < signedBundleSz;) {
                int sz = (i + chunkSz > signedBundleSz)? signedBundleSz - i :
                    chunkSz;
                rc = wc_PKCS7_VerifySignedData(pkcs7, buf + i, (word32)sz);
                if (rc < 0 ) {
                    if (rc == WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) {
                        i += sz;
                        continue;
                    }
                    break;
                }
                else {
                    break;
                }
            }
            ExpectIntEQ(rc, WC_NO_ERR_TRACE(PKCS7_SIGNEEDS_CHECK));
            wc_PKCS7_Free(pkcs7);
            pkcs7 = NULL;
        }

        /* now try with malformed bundle */
        if (buf != NULL) {
            ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
            ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
            buf[signedBundleSz - 2] = buf[signedBundleSz - 2] + 1;
            for (i = 0; i < signedBundleSz;) {
                int sz = (i + chunkSz > signedBundleSz)? signedBundleSz - i :
                    chunkSz;
                rc = wc_PKCS7_VerifySignedData(pkcs7, buf + i, (word32)sz);
                if (rc < 0 ) {
                    if (rc == WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) {
                        i += sz;
                        continue;
                    }
                    break;
                }
                else {
                    break;
                }
            }
            ExpectIntEQ(rc, WC_NO_ERR_TRACE(ASN_PARSE_E));
            wc_PKCS7_Free(pkcs7);
            pkcs7 = NULL;
        }

        if (buf != NULL)
            XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_FILE);
    }
#endif /* BER and stream */
#endif
    return EXPECT_RESULT();
} /* END test_wc_PKCS7_VerifySignedData()_RSA */

/*
 * Testing wc_PKCS_VerifySignedData()
 */
static int test_wc_PKCS7_VerifySignedData_ECC(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && defined(HAVE_ECC)
    PKCS7* pkcs7 = NULL;
    byte   output[6000]; /* Large size needed for bundles with int CA certs */
    word32 outputSz = sizeof(output);
    byte   data[] = "Test data to encode.";
    byte   badContent[] = "This is different content than was signed";
    wc_HashAlg hash;
#ifndef NO_PKCS7_STREAM
    word32 z;
    int ret;
#endif /* !NO_PKCS7_STREAM */
#ifdef NO_SHA
    enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
#else
    enum wc_HashType hashType = WC_HASH_TYPE_SHA;
#endif
    byte        hashBuf[WC_MAX_DIGEST_SIZE];
    word32      hashSz = (word32)wc_HashGetDigestSize(hashType);

    XMEMSET(&hash, 0, sizeof(wc_HashAlg));

    /* Success test with ECC certs/key */
    outputSz = sizeof(output);
    XMEMSET(output, 0, outputSz);
    ExpectIntGT((outputSz = (word32)CreatePKCS7SignedData(output, (int)outputSz, data,
        (word32)sizeof(data), 0, 0, 0, ECC_TYPE)), 0);

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_PKCS7_STREAM
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

    /* test for streaming */
    ret = -1;
    for (z = 0; z < outputSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
    ExpectIntNE(pkcs7->contentSz, 0);
    ExpectNotNull(pkcs7->contentDynamic);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
#endif /* !NO_PKCS7_STREAM */

    /* Invalid content should error, use detached signature so we can
     * easily change content */
    outputSz = sizeof(output);
    XMEMSET(output, 0, outputSz);
    ExpectIntGT((outputSz = (word32)CreatePKCS7SignedData(output, (int)outputSz, data,
        (word32)sizeof(data), 1, 1, 0, ECC_TYPE)), 0);
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    if (pkcs7 != NULL) {
        pkcs7->content = badContent;
        pkcs7->contentSz = sizeof(badContent);
    }
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz),
        WC_NO_ERR_TRACE(SIG_VERIFY_E));
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_PKCS7_STREAM
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    if (pkcs7 != NULL) {
        pkcs7->content = badContent;
        pkcs7->contentSz = sizeof(badContent);
    }

    /* test for streaming */
    ret = -1;
    for (z = 0; z < outputSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
        if (ret == WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)){
            continue;
        }
        else if (ret < 0) {
            break;
        }
    }
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(SIG_VERIFY_E));
    ExpectIntNE(pkcs7->contentSz, 0);
    ExpectNotNull(pkcs7->contentDynamic);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
#endif /* !NO_PKCS7_STREAM */


    /* Test success case with detached signature and valid content */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    if (pkcs7 != NULL) {
        pkcs7->content = data;
        pkcs7->contentSz = sizeof(data);
    }
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_PKCS7_STREAM
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    if (pkcs7 != NULL) {
        pkcs7->content = data;
        pkcs7->contentSz = sizeof(data);
    }

    /* test for streaming */
    ret = -1;
    for (z = 0; z < outputSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
    ExpectIntNE(pkcs7->contentSz, 0);
    ExpectNotNull(pkcs7->contentDynamic);

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
#endif /* !NO_PKCS7_STREAM */

    /* verify using pre-computed content digest only (no content) */
    {
        /* calculate hash for content */
        ExpectIntEQ(wc_HashInit(&hash, hashType), 0);
        ExpectIntEQ(wc_HashUpdate(&hash, hashType, data, sizeof(data)), 0);
        ExpectIntEQ(wc_HashFinal(&hash, hashType, hashBuf), 0);
        ExpectIntEQ(wc_HashFree(&hash, hashType), 0);

        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_Init(pkcs7, NULL, 0), 0);
        ExpectIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
            output, outputSz, NULL, 0), 0);
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;
    }

    /* Test verify on signedData containing intermediate/root CA certs */
    outputSz = sizeof(output);
    XMEMSET(output, 0, outputSz);
    ExpectIntGT((outputSz = (word32)CreatePKCS7SignedData(output, (int)outputSz, data,
        (word32)sizeof(data), 0, 0, 1, ECC_TYPE)), 0);
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_PKCS7_STREAM
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

    /* test for streaming */
    ret = -1;
    for (z = 0; z < outputSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, output + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
    ExpectIntNE(pkcs7->contentSz, 0);
    ExpectNotNull(pkcs7->contentDynamic);

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
#endif /* !NO_PKCS7_STREAM */

#endif
    return EXPECT_RESULT();
} /* END test_wc_PKCS7_VerifySignedData_ECC() */


#if defined(HAVE_PKCS7) && !defined(NO_AES) && defined(HAVE_AES_CBC) && \
    !defined(NO_AES_256)
static const byte defKey[] = {
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
};
static byte aesHandle[32]; /* simulated hardware key handle */

/* return 0 on success */
static int myDecryptionFunc(PKCS7* pkcs7, int encryptOID, byte* iv, int ivSz,
        byte* aad, word32 aadSz, byte* authTag, word32 authTagSz,
        byte* in, int inSz, byte* out, void* usrCtx)
{
    int ret;
    Aes aes;

    if (usrCtx == NULL) {
        /* no simulated handle passed in */
        return -1;
    }

    switch (encryptOID) {
        case AES256CBCb:
            if (ivSz  != AES_BLOCK_SIZE)
                return BAD_FUNC_ARG;
            break;

        default:
            WOLFSSL_MSG("Unsupported content cipher type for test");
            return ALGO_ID_E;
    };

    /* simulate using handle to get key */
    ret = wc_AesInit(&aes, HEAP_HINT, INVALID_DEVID);
    if (ret == 0) {
        ret = wc_AesSetKey(&aes, (byte*)usrCtx, 32, iv, AES_DECRYPTION);
        if (ret == 0)
            ret = wc_AesCbcDecrypt(&aes, out, in, (word32)inSz);
        wc_AesFree(&aes);
    }

    (void)aad;
    (void)aadSz;
    (void)authTag;
    (void)authTagSz;
    (void)pkcs7;
    return ret;
}


/* returns key size on success */
static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId,
        word32 keyIdSz, byte* orginKey, word32 orginKeySz,
        byte* out, word32 outSz, int keyWrapAlgo, int type, int direction)
{
    int ret = -1;

    (void)cekSz;
    (void)cek;
    (void)outSz;
    (void)keyIdSz;
    (void)direction;
    (void)orginKey; /* used with KAKRI */
    (void)orginKeySz;

    if (out == NULL)
        return BAD_FUNC_ARG;

    if (keyId[0] != 0x00) {
        return -1;
    }

    if (type != (int)PKCS7_KEKRI) {
        return -1;
    }

    switch (keyWrapAlgo) {
        case AES256_WRAP:
            /* simulate setting a handle for later decryption but use key
             * as handle in the test case here */
            ret = wc_AesKeyUnWrap(defKey, sizeof(defKey), cek, cekSz,
                                      aesHandle, sizeof(aesHandle), NULL);
            if (ret < 0)
                return ret;

            ret = wc_PKCS7_SetDecodeEncryptedCtx(pkcs7, (void*)aesHandle);
            if (ret < 0)
                return ret;

            /* return key size on success */
            return sizeof(defKey);

        default:
            WOLFSSL_MSG("Unsupported key wrap algorithm in example");
            return BAD_KEYWRAP_ALG_E;
    };
}
#endif /* HAVE_PKCS7 && !NO_AES && HAVE_AES_CBC && !NO_AES_256 */


/*
 * Testing wc_PKCS7_EncodeEnvelopedData()
 */
static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7)
    PKCS7*      pkcs7 = NULL;
#ifdef ASN_BER_TO_DER
    int encodedSz = 0;
#endif
#ifdef ECC_TIMING_RESISTANT
    WC_RNG      rng;
#endif
    word32      tempWrd32   = 0;
    byte*       tmpBytePtr = NULL;
    const char  input[] = "Test data to encode.";
    int         i;
    int         testSz = 0;
    #if !defined(NO_RSA) && (!defined(NO_AES) || (!defined(NO_SHA) || \
        !defined(NO_SHA256) || defined(WOLFSSL_SHA512)))
        byte*   rsaCert     = NULL;
        byte*   rsaPrivKey  = NULL;
        word32  rsaCertSz;
        word32  rsaPrivKeySz;
        #if !defined(NO_FILESYSTEM) && (!defined(USE_CERT_BUFFERS_1024) && \
                                           !defined(USE_CERT_BUFFERS_2048) )
            static const char* rsaClientCert = "./certs/client-cert.der";
            static const char* rsaClientKey = "./certs/client-key.der";
            rsaCertSz = (word32)sizeof(rsaClientCert);
            rsaPrivKeySz = (word32)sizeof(rsaClientKey);
        #endif
    #endif
    #if defined(HAVE_ECC) && (!defined(NO_AES) || (!defined(NO_SHA) ||\
        !defined(NO_SHA256) || defined(WOLFSSL_SHA512)))
        byte*   eccCert     = NULL;
        byte*   eccPrivKey  = NULL;
        word32  eccCertSz;
        word32  eccPrivKeySz;
        #if !defined(NO_FILESYSTEM) && !defined(USE_CERT_BUFFERS_256)
            static const char* eccClientCert = "./certs/client-ecc-cert.der";
            static const char* eccClientKey = "./certs/ecc-client-key.der";
        #endif
    #endif
    /* Generic buffer size. */
    byte    output[ONEK_BUF];
    byte    decoded[sizeof(input)/sizeof(char)];
    int     decodedSz = 0;
#ifndef NO_FILESYSTEM
    XFILE certFile = XBADFILE;
    XFILE keyFile = XBADFILE;
#endif

#ifdef ECC_TIMING_RESISTANT
    XMEMSET(&rng, 0, sizeof(WC_RNG));
#endif

#if !defined(NO_RSA) && (!defined(NO_AES) || (!defined(NO_SHA) ||\
    !defined(NO_SHA256) || defined(WOLFSSL_SHA512)))
    /* RSA certs and keys. */
    #if defined(USE_CERT_BUFFERS_1024)
        rsaCertSz = (word32)sizeof_client_cert_der_1024;
        /* Allocate buffer space. */
        ExpectNotNull(rsaCert = (byte*)XMALLOC(rsaCertSz, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        /* Init buffer. */
        if (rsaCert != NULL) {
            XMEMCPY(rsaCert, client_cert_der_1024, rsaCertSz);
        }
        rsaPrivKeySz = (word32)sizeof_client_key_der_1024;
        ExpectNotNull(rsaPrivKey = (byte*)XMALLOC(rsaPrivKeySz, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        if (rsaPrivKey != NULL) {
            XMEMCPY(rsaPrivKey, client_key_der_1024, rsaPrivKeySz);
        }
    #elif defined(USE_CERT_BUFFERS_2048)
        rsaCertSz = (word32)sizeof_client_cert_der_2048;
        /* Allocate buffer */
        ExpectNotNull(rsaCert = (byte*)XMALLOC(rsaCertSz, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        /* Init buffer. */
        if (rsaCert != NULL) {
            XMEMCPY(rsaCert, client_cert_der_2048, rsaCertSz);
        }
        rsaPrivKeySz = (word32)sizeof_client_key_der_2048;
        ExpectNotNull(rsaPrivKey = (byte*)XMALLOC(rsaPrivKeySz, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        if (rsaPrivKey != NULL) {
            XMEMCPY(rsaPrivKey, client_key_der_2048, rsaPrivKeySz);
        }
    #else
        /* File system. */
        ExpectTrue((certFile = XFOPEN(rsaClientCert, "rb")) != XBADFILE);
        rsaCertSz = (word32)FOURK_BUF;
        ExpectNotNull(rsaCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        ExpectTrue((rsaCertSz = (word32)XFREAD(rsaCert, 1, rsaCertSz,
            certFile)) > 0);
        if (certFile != XBADFILE)
            XFCLOSE(certFile);
        ExpectTrue((keyFile = XFOPEN(rsaClientKey, "rb")) != XBADFILE);
        ExpectNotNull(rsaPrivKey = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        rsaPrivKeySz = (word32)FOURK_BUF;
        ExpectTrue((rsaPrivKeySz = (word32)XFREAD(rsaPrivKey, 1, rsaPrivKeySz,
            keyFile)) > 0);
        if (keyFile != XBADFILE)
            XFCLOSE(keyFile);
    #endif /* USE_CERT_BUFFERS */
#endif /* NO_RSA */

/* ECC */
#if defined(HAVE_ECC) && (!defined(NO_AES) || (!defined(NO_SHA) ||\
    !defined(NO_SHA256) || defined(WOLFSSL_SHA512)))

    #ifdef USE_CERT_BUFFERS_256
        ExpectNotNull(eccCert = (byte*)XMALLOC(TWOK_BUF, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        /* Init buffer. */
        eccCertSz = (word32)sizeof_cliecc_cert_der_256;
        if (eccCert != NULL) {
            XMEMCPY(eccCert, cliecc_cert_der_256, eccCertSz);
        }
        ExpectNotNull(eccPrivKey = (byte*)XMALLOC(TWOK_BUF, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        eccPrivKeySz = (word32)sizeof_ecc_clikey_der_256;
        if (eccPrivKey != NULL) {
            XMEMCPY(eccPrivKey, ecc_clikey_der_256, eccPrivKeySz);
        }
    #else /* File system. */
        ExpectTrue((certFile = XFOPEN(eccClientCert, "rb")) != XBADFILE);
        eccCertSz = (word32)FOURK_BUF;
        ExpectNotNull(eccCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        ExpectTrue((eccCertSz = (word32)XFREAD(eccCert, 1, eccCertSz,
            certFile)) > 0);
        if (certFile != XBADFILE) {
            XFCLOSE(certFile);
        }
        ExpectTrue((keyFile = XFOPEN(eccClientKey, "rb")) != XBADFILE);
        eccPrivKeySz = (word32)FOURK_BUF;
        ExpectNotNull(eccPrivKey = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        ExpectTrue((eccPrivKeySz = (word32)XFREAD(eccPrivKey, 1, eccPrivKeySz,
            keyFile)) > 0);
        if (keyFile != XBADFILE) {
            XFCLOSE(keyFile);
        }
    #endif /* USE_CERT_BUFFERS_256 */
#endif /* END HAVE_ECC */

#ifndef NO_FILESYSTEM
    /* Silence. */
    (void)keyFile;
    (void)certFile;
#endif

    {
    const pkcs7EnvelopedVector testVectors[] = {
    /* DATA is a global variable defined in the makefile. */
#if !defined(NO_RSA)
    #ifndef NO_DES3
        {(byte*)input, (word32)(sizeof(input)/sizeof(char)), DATA, DES3b, 0, 0,
            rsaCert, rsaCertSz, rsaPrivKey, rsaPrivKeySz},
    #endif /* NO_DES3 */
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
        #ifndef NO_AES_128
        {(byte*)input, (word32)(sizeof(input)/sizeof(char)), DATA, AES128CBCb,
            0, 0, rsaCert, rsaCertSz, rsaPrivKey, rsaPrivKeySz},
        #endif
        #ifndef NO_AES_192
        {(byte*)input, (word32)(sizeof(input)/sizeof(char)), DATA, AES192CBCb,
            0, 0, rsaCert, rsaCertSz, rsaPrivKey, rsaPrivKeySz},
        #endif
        #ifndef NO_AES_256
        {(byte*)input, (word32)(sizeof(input)/sizeof(char)), DATA, AES256CBCb,
            0, 0, rsaCert, rsaCertSz, rsaPrivKey, rsaPrivKeySz},
        #endif
    #endif /* NO_AES && HAVE_AES_CBC */

#endif /* NO_RSA */
#if defined(HAVE_ECC)
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
        #if !defined(NO_SHA) && !defined(NO_AES_128)
            {(byte*)input, (word32)(sizeof(input)/sizeof(char)), DATA,
                AES128CBCb, AES128_WRAP, dhSinglePass_stdDH_sha1kdf_scheme,
                eccCert, eccCertSz, eccPrivKey, eccPrivKeySz},
        #endif
        #if !defined(NO_SHA256) && !defined(NO_AES_256)
            {(byte*)input, (word32)(sizeof(input)/sizeof(char)), DATA,
                AES256CBCb, AES256_WRAP, dhSinglePass_stdDH_sha256kdf_scheme,
                eccCert, eccCertSz, eccPrivKey, eccPrivKeySz},
        #endif
        #if defined(WOLFSSL_SHA512) && !defined(NO_AES_256)
            {(byte*)input, (word32)(sizeof(input)/sizeof(char)), DATA,
                AES256CBCb, AES256_WRAP, dhSinglePass_stdDH_sha512kdf_scheme,
                eccCert, eccCertSz, eccPrivKey, eccPrivKeySz},
        #endif
    #endif /* NO_AES && HAVE_AES_CBC*/
#endif /* END HAVE_ECC */
    }; /* END pkcs7EnvelopedVector */

#ifdef ECC_TIMING_RESISTANT
    ExpectIntEQ(wc_InitRng(&rng), 0);
#endif

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, testDevId), 0);

    testSz = (int)sizeof(testVectors)/(int)sizeof(pkcs7EnvelopedVector);
    for (i = 0; i < testSz; i++) {
    #ifdef ASN_BER_TO_DER
        encodeSignedDataStream strm;

        /* test setting stream mode, the first one using IO callbacks */
        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (testVectors + i)->cert,
                                    (word32)(testVectors + i)->certSz), 0);
        if (pkcs7 != NULL) {
        #ifdef ECC_TIMING_RESISTANT
            pkcs7->rng = &rng;
        #endif

            if (i != 0)
                pkcs7->content       = (byte*)(testVectors + i)->content;
            pkcs7->contentSz     = (testVectors + i)->contentSz;
            pkcs7->contentOID    = (testVectors + i)->contentOID;
            pkcs7->encryptOID    = (testVectors + i)->encryptOID;
            pkcs7->keyWrapOID    = (testVectors + i)->keyWrapOID;
            pkcs7->keyAgreeOID   = (testVectors + i)->keyAgreeOID;
            pkcs7->privateKey    = (testVectors + i)->privateKey;
            pkcs7->privateKeySz  = (testVectors + i)->privateKeySz;
        }

        if (i == 0) {
            XMEMSET(&strm, 0, sizeof(strm));
            ExpectIntEQ(wc_PKCS7_SetStreamMode(pkcs7, 1, GetContentCB,
                StreamOutputCB, (void*)&strm), 0);
            encodedSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, NULL, 0);
        }
        else {
            ExpectIntEQ(wc_PKCS7_SetStreamMode(pkcs7, 1, NULL, NULL, NULL), 0);
            encodedSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, output,
                (word32)sizeof(output));
        }

        switch ((testVectors + i)->encryptOID) {
        #ifndef NO_DES3
            case DES3b:
            case DESb:
                ExpectIntEQ(encodedSz, WC_NO_ERR_TRACE(BAD_FUNC_ARG));
                break;
        #endif
        #ifdef HAVE_AESCCM
        #ifdef WOLFSSL_AES_128
            case AES128CCMb:
                ExpectIntEQ(encodedSz, WC_NO_ERR_TRACE(BAD_FUNC_ARG));
                break;
        #endif
        #ifdef WOLFSSL_AES_192
            case AES192CCMb:
                ExpectIntEQ(encodedSz, WC_NO_ERR_TRACE(BAD_FUNC_ARG));
                break;
        #endif
        #ifdef WOLFSSL_AES_256
            case AES256CCMb:
                ExpectIntEQ(encodedSz, WC_NO_ERR_TRACE(BAD_FUNC_ARG));
                break;
        #endif
        #endif
            default:
                ExpectIntGE(encodedSz, 0);
        }

        if (encodedSz > 0) {
            if (i == 0) {
                decodedSz = wc_PKCS7_DecodeEnvelopedData(pkcs7,
                    strm.out, (word32)encodedSz, decoded,
                    (word32)sizeof(decoded));
            }
            else {
                decodedSz = wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
                    (word32)encodedSz, decoded, (word32)sizeof(decoded));
            }
            ExpectIntGE(decodedSz, 0);
            /* Verify the size of each buffer. */
            ExpectIntEQ((word32)sizeof(input)/sizeof(char), decodedSz);
        }
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    #endif

        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (testVectors + i)->cert,
                                    (word32)(testVectors + i)->certSz), 0);
        if (pkcs7 != NULL) {
#ifdef ECC_TIMING_RESISTANT
            pkcs7->rng = &rng;
#endif

            pkcs7->content       = (byte*)(testVectors + i)->content;
            pkcs7->contentSz     = (testVectors + i)->contentSz;
            pkcs7->contentOID    = (testVectors + i)->contentOID;
            pkcs7->encryptOID    = (testVectors + i)->encryptOID;
            pkcs7->keyWrapOID    = (testVectors + i)->keyWrapOID;
            pkcs7->keyAgreeOID   = (testVectors + i)->keyAgreeOID;
            pkcs7->privateKey    = (testVectors + i)->privateKey;
            pkcs7->privateKeySz  = (testVectors + i)->privateKeySz;
        }

    #ifdef ASN_BER_TO_DER
        /* test without setting stream mode */
        ExpectIntEQ(wc_PKCS7_GetStreamMode(pkcs7), 0);
    #endif

        ExpectIntGE(wc_PKCS7_EncodeEnvelopedData(pkcs7, output,
            (word32)sizeof(output)), 0);

        decodedSz = wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
            (word32)sizeof(output), decoded, (word32)sizeof(decoded));
        ExpectIntGE(decodedSz, 0);
        /* Verify the size of each buffer. */
        ExpectIntEQ((word32)sizeof(input)/sizeof(char), decodedSz);

        /* Don't free the last time through the loop. */
        if (i < testSz - 1) {
            wc_PKCS7_Free(pkcs7);
            pkcs7 = NULL;
            ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        }
    }  /* END test loop. */
    }

    /* Test bad args. */
    ExpectIntEQ(wc_PKCS7_EncodeEnvelopedData(NULL, output,
                    (word32)sizeof(output)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeEnvelopedData(pkcs7, NULL,
                    (word32)sizeof(output)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeEnvelopedData(pkcs7, output, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Decode.  */
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(NULL, output,
        (word32)sizeof(output), decoded, (word32)sizeof(decoded)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
        (word32)sizeof(output), NULL, (word32)sizeof(decoded)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
        (word32)sizeof(output), decoded, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, NULL,
        (word32)sizeof(output), decoded, (word32)sizeof(decoded)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output, 0, decoded,
        (word32)sizeof(decoded)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Should get a return of BAD_FUNC_ARG with structure data. Order matters.*/
#if defined(HAVE_ECC) && !defined(NO_AES) && defined(HAVE_AES_CBC)
    /* only a failure for KARI test cases */
    if (pkcs7 != NULL) {
        tempWrd32 = pkcs7->singleCertSz;
        pkcs7->singleCertSz = 0;
    }
    #if defined(WOLFSSL_ASN_TEMPLATE)
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
        (word32)sizeof(output), decoded, (word32)sizeof(decoded)),
        WC_NO_ERR_TRACE(BUFFER_E));
    #else
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
        (word32)sizeof(output), decoded, (word32)sizeof(decoded)),
        WC_NO_ERR_TRACE(ASN_PARSE_E));
    #endif
    if (pkcs7 != NULL) {
        pkcs7->singleCertSz = tempWrd32;

        tmpBytePtr = pkcs7->singleCert;
        pkcs7->singleCert = NULL;
    }
  #ifndef NO_RSA
    #if defined(NO_PKCS7_STREAM)
    /* when none streaming mode is used and PKCS7 is in bad state buffer error
     * is returned from kari parse which gets set to bad func arg */
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
        (word32)sizeof(output), decoded, (word32)sizeof(decoded)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    #else
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
        (word32)sizeof(output), decoded, (word32)sizeof(decoded)),
        WC_NO_ERR_TRACE(ASN_PARSE_E));
    #endif
  #endif /* !NO_RSA */
    if (pkcs7 != NULL) {
        pkcs7->singleCert = tmpBytePtr;
    }
#endif
    if (pkcs7 != NULL) {
        tempWrd32 = pkcs7->privateKeySz;
        pkcs7->privateKeySz = 0;
    }

    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
        (word32)sizeof(output), decoded, (word32)sizeof(decoded)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->privateKeySz = tempWrd32;

        tmpBytePtr = pkcs7->privateKey;
        pkcs7->privateKey = NULL;
    }
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
        (word32)sizeof(output), decoded, (word32)sizeof(decoded)),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->privateKey = tmpBytePtr;
    }

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#if !defined(NO_AES) && defined(HAVE_AES_CBC) && !defined(NO_AES_256)
    /* test of decrypt callback with KEKRI enveloped data */
    {
        int envelopedSz = 0;
        const byte keyId[] = { 0x00 };

        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        if (pkcs7 != NULL) {
            pkcs7->content      = (byte*)input;
            pkcs7->contentSz    = (word32)(sizeof(input)/sizeof(char));
            pkcs7->contentOID   = DATA;
            pkcs7->encryptOID   = AES256CBCb;
        }
        ExpectIntGT(wc_PKCS7_AddRecipient_KEKRI(pkcs7, AES256_WRAP,
                    (byte*)defKey, sizeof(defKey), (byte*)keyId,
                    sizeof(keyId), NULL, NULL, 0, NULL, 0, 0), 0);
        ExpectIntEQ(wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID), 0);
        ExpectIntGT((envelopedSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, output,
                        (word32)sizeof(output))), 0);
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;

        /* decode envelopedData */
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_SetWrapCEKCb(pkcs7, myCEKwrapFunc), 0);
        ExpectIntEQ(wc_PKCS7_SetDecodeEncryptedCb(pkcs7, myDecryptionFunc), 0);
        ExpectIntGT((decodedSz = wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
                        (word32)envelopedSz, decoded, sizeof(decoded))), 0);
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;
    }
#endif /* !NO_AES && !NO_AES_256 */

#ifndef NO_RSA
    XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* NO_RSA */
#ifdef HAVE_ECC
    XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* HAVE_ECC */

#ifdef ECC_TIMING_RESISTANT
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif

#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_DES3) && \
    !defined(NO_RSA) && !defined(NO_SHA)
    {
        byte   out[7];
        byte   *cms = NULL;
        word32 cmsSz;
        XFILE  cmsFile = XBADFILE;

        XMEMSET(out, 0, sizeof(out));
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectTrue((cmsFile = XFOPEN("./certs/test/ktri-keyid-cms.msg", "rb"))
            != XBADFILE);
        cmsSz = (word32)FOURK_BUF;
        ExpectNotNull(cms = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,
            DYNAMIC_TYPE_TMP_BUFFER));
        ExpectTrue((cmsSz = (word32)XFREAD(cms, 1, cmsSz, cmsFile)) > 0);
        if (cmsFile != XBADFILE)
            XFCLOSE(cmsFile);

        ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)client_cert_der_2048,
            sizeof_client_cert_der_2048), 0);
        if (pkcs7 != NULL) {
            pkcs7->privateKey   = (byte*)client_key_der_2048;
            pkcs7->privateKeySz = sizeof_client_key_der_2048;
        }
        ExpectIntLT(wc_PKCS7_DecodeEnvelopedData(pkcs7, cms, cmsSz, out,
            2), 0);
        ExpectIntGT(wc_PKCS7_DecodeEnvelopedData(pkcs7, cms, cmsSz, out,
            sizeof(out)), 0);
        XFREE(cms, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
        ExpectIntEQ(XMEMCMP(out, "test", 4), 0);
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;
    }
#endif /* USE_CERT_BUFFERS_2048 && !NO_DES3 && !NO_RSA && !NO_SHA */
#endif /* HAVE_PKCS7 */
    return EXPECT_RESULT();
} /* END test_wc_PKCS7_EncodeDecodeEnvelopedData() */


/*
 * Testing wc_PKCS7_EncodeEncryptedData()
 */
static int test_wc_PKCS7_EncodeEncryptedData(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_PKCS7_ENCRYPTED_DATA)
    PKCS7*      pkcs7 = NULL;
    byte*       tmpBytePtr = NULL;
    byte        encrypted[TWOK_BUF];
    byte        decoded[TWOK_BUF];
    word32      tmpWrd32 = 0;
    int         tmpInt = 0;
    int         decodedSz = 0;
    int         encryptedSz = 0;
    int         testSz = 0;
    int         i = 0;
    const byte data[] = { /* Hello World */
        0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
        0x72,0x6c,0x64
    };
    #ifndef NO_DES3
        byte desKey[] = {
            0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
        };
        byte des3Key[] = {
            0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
            0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
            0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
        };
    #endif
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
        #ifndef NO_AES_128
        byte aes128Key[] = {
            0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
            0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
        };
        #endif
        #ifndef NO_AES_192
        byte aes192Key[] = {
            0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
            0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
            0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
        };
        #endif
        #ifndef NO_AES_256
        byte aes256Key[] = {
            0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
            0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
            0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
            0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
        };
        #endif
    #endif /* !NO_AES && HAVE_AES_CBC */
    const pkcs7EncryptedVector testVectors[] =
    {
    #ifndef NO_DES3
        {data, (word32)sizeof(data), DATA, DES3b, des3Key, sizeof(des3Key)},

        {data, (word32)sizeof(data), DATA, DESb, desKey, sizeof(desKey)},
    #endif /* !NO_DES3 */
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
        #ifndef NO_AES_128
        {data, (word32)sizeof(data), DATA, AES128CBCb, aes128Key,
         sizeof(aes128Key)},
        #endif

        #ifndef NO_AES_192
        {data, (word32)sizeof(data), DATA, AES192CBCb, aes192Key,
         sizeof(aes192Key)},
        #endif

        #ifndef NO_AES_256
        {data, (word32)sizeof(data), DATA, AES256CBCb, aes256Key,
         sizeof(aes256Key)},
        #endif

    #endif /* !NO_AES && HAVE_AES_CBC */
    };

    testSz = sizeof(testVectors) / sizeof(pkcs7EncryptedVector);

    for (i = 0; i < testSz; i++) {
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, testDevId), 0);
        if (pkcs7 != NULL) {
            pkcs7->content              = (byte*)testVectors[i].content;
            pkcs7->contentSz            = testVectors[i].contentSz;
            pkcs7->contentOID           = testVectors[i].contentOID;
            pkcs7->encryptOID           = testVectors[i].encryptOID;
            pkcs7->encryptionKey        = testVectors[i].encryptionKey;
            pkcs7->encryptionKeySz      = testVectors[i].encryptionKeySz;
            pkcs7->heap                 = HEAP_HINT;
        }

        /* encode encryptedData */
        ExpectIntGT(encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, encrypted,
            sizeof(encrypted)), 0);

        /* Decode encryptedData */
        ExpectIntGT(decodedSz = wc_PKCS7_DecodeEncryptedData(pkcs7, encrypted,
            (word32)encryptedSz, decoded, sizeof(decoded)), 0);

        ExpectIntEQ(XMEMCMP(decoded, data, decodedSz), 0);
        /* Keep values for last itr. */
        if (i < testSz - 1) {
            wc_PKCS7_Free(pkcs7);
            pkcs7 = NULL;
        }
    }
    if (pkcs7 == NULL || testSz == 0) {
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, testDevId), 0);
    }

    ExpectIntEQ(wc_PKCS7_EncodeEncryptedData(NULL, encrypted,
        sizeof(encrypted)),WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeEncryptedData(pkcs7, NULL,
        sizeof(encrypted)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_EncodeEncryptedData(pkcs7, encrypted,
        0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Testing the struct. */
    if (pkcs7 != NULL) {
        tmpBytePtr = pkcs7->content;
        pkcs7->content = NULL;
    }
    ExpectIntEQ(wc_PKCS7_EncodeEncryptedData(pkcs7, encrypted,
        sizeof(encrypted)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->content = tmpBytePtr;
        tmpWrd32 = pkcs7->contentSz;
        pkcs7->contentSz = 0;
    }
    ExpectIntEQ(wc_PKCS7_EncodeEncryptedData(pkcs7, encrypted,
        sizeof(encrypted)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->contentSz = tmpWrd32;
        tmpInt = pkcs7->encryptOID;
        pkcs7->encryptOID = 0;
    }
    ExpectIntEQ(wc_PKCS7_EncodeEncryptedData(pkcs7, encrypted,
        sizeof(encrypted)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->encryptOID = tmpInt;
        tmpBytePtr = pkcs7->encryptionKey;
        pkcs7->encryptionKey = NULL;
    }
    ExpectIntEQ(wc_PKCS7_EncodeEncryptedData(pkcs7, encrypted,
        sizeof(encrypted)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->encryptionKey = tmpBytePtr;
        tmpWrd32 = pkcs7->encryptionKeySz;
        pkcs7->encryptionKeySz = 0;
    }
    ExpectIntEQ(wc_PKCS7_EncodeEncryptedData(pkcs7, encrypted,
        sizeof(encrypted)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->encryptionKeySz = tmpWrd32;
    }

    ExpectIntEQ(wc_PKCS7_DecodeEncryptedData(NULL, encrypted, (word32)encryptedSz,
        decoded, sizeof(decoded)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_DecodeEncryptedData(pkcs7, NULL, (word32)encryptedSz,
        decoded, sizeof(decoded)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_DecodeEncryptedData(pkcs7, encrypted, 0,
        decoded, sizeof(decoded)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_DecodeEncryptedData(pkcs7, encrypted, (word32)encryptedSz,
        NULL, sizeof(decoded)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_DecodeEncryptedData(pkcs7, encrypted, (word32)encryptedSz,
        decoded, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* Test struct fields */

    if (pkcs7 != NULL) {
        tmpBytePtr = pkcs7->encryptionKey;
        pkcs7->encryptionKey = NULL;
    }
    ExpectIntEQ(wc_PKCS7_DecodeEncryptedData(pkcs7, encrypted, (word32)encryptedSz,
        decoded, sizeof(decoded)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    if (pkcs7 != NULL) {
        pkcs7->encryptionKey = tmpBytePtr;
        pkcs7->encryptionKeySz = 0;
    }
    ExpectIntEQ(wc_PKCS7_DecodeEncryptedData(pkcs7, encrypted, (word32)encryptedSz,
        decoded, sizeof(decoded)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
} /* END test_wc_PKCS7_EncodeEncryptedData() */

/*
 * Testing wc_PKCS7_Degenerate()
 */
static int test_wc_PKCS7_Degenerate(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM)
    PKCS7* pkcs7 = NULL;
    char   fName[] = "./certs/test-degenerate.p7b";
    XFILE  f = XBADFILE;
    byte   der[4096];
    word32 derSz = 0;
#ifndef NO_PKCS7_STREAM
    word32 z;
    int ret;
#endif /* !NO_PKCS7_STREAM */
    ExpectTrue((f = XFOPEN(fName, "rb")) != XBADFILE);
    ExpectTrue((derSz = (word32)XFREAD(der, 1, sizeof(der), f)) > 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    /* test degenerate success */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
#ifndef NO_RSA
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);

    #ifndef NO_PKCS7_STREAM
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

    /* test for streaming */
    ret = -1;
    for (z = 0; z < derSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, der + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
    #endif /* !NO_PKCS7_STREAM */
#else
    ExpectIntNE(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);
#endif /* NO_RSA */
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    /* test with turning off degenerate cases */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    wc_PKCS7_AllowDegenerate(pkcs7, 0); /* override allowing degenerate case */
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, der, derSz),
        WC_NO_ERR_TRACE(PKCS7_NO_SIGNER_E));

    #ifndef NO_PKCS7_STREAM
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    wc_PKCS7_AllowDegenerate(pkcs7, 0); /* override allowing degenerate case */

    /* test for streaming */
    ret = -1;
    for (z = 0; z < derSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, der + z, 1);
        if (ret == WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)){
            continue;
        }
        else
            break;
    }
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(PKCS7_NO_SIGNER_E));
    #endif /* !NO_PKCS7_STREAM */

    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
} /* END test_wc_PKCS7_Degenerate() */

#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && \
    defined(ASN_BER_TO_DER) && !defined(NO_DES3) && !defined(NO_SHA)
static byte berContent[] = {
    0x30, 0x80, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
    0xF7, 0x0D, 0x01, 0x07, 0x03, 0xA0, 0x80, 0x30,
    0x80, 0x02, 0x01, 0x00, 0x31, 0x82, 0x01, 0x48,
    0x30, 0x82, 0x01, 0x44, 0x02, 0x01, 0x00, 0x30,
    0x81, 0xAC, 0x30, 0x81, 0x9E, 0x31, 0x0B, 0x30,
    0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
    0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03,
    0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E,
    0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E,
    0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42,
    0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x15,
    0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C,
    0x0C, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C,
    0x5F, 0x31, 0x30, 0x32, 0x34, 0x31, 0x19, 0x30,
    0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10,
    0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D,
    0x69, 0x6E, 0x67, 0x2D, 0x31, 0x30, 0x32, 0x34,
    0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04,
    0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77,
    0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63,
    0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09,
    0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09,
    0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40,
    0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E,
    0x63, 0x6F, 0x6D, 0x02, 0x09, 0x00, 0xBB, 0xD3,
    0x10, 0x03, 0xE6, 0x9D, 0x28, 0x03, 0x30, 0x0D,
    0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
    0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x81, 0x80,
    0x2F, 0xF9, 0x77, 0x4F, 0x04, 0x5C, 0x16, 0x62,
    0xF0, 0x77, 0x8D, 0x95, 0x4C, 0xB1, 0x44, 0x9A,
    0x8C, 0x3C, 0x8C, 0xE4, 0xD1, 0xC1, 0x14, 0x72,
    0xD0, 0x4A, 0x1A, 0x94, 0x27, 0x0F, 0xAA, 0xE8,
    0xD0, 0xA2, 0xE7, 0xED, 0x4C, 0x7F, 0x0F, 0xC7,
    0x1B, 0xFB, 0x81, 0x0E, 0x76, 0x8F, 0xDD, 0x32,
    0x11, 0x68, 0xA0, 0x13, 0xD2, 0x8D, 0x95, 0xEF,
    0x80, 0x53, 0x81, 0x0E, 0x1F, 0xC8, 0xD6, 0x76,
    0x5C, 0x31, 0xD3, 0x77, 0x33, 0x29, 0xA6, 0x1A,
    0xD3, 0xC6, 0x14, 0x36, 0xCA, 0x8E, 0x7D, 0x72,
    0xA0, 0x29, 0x4C, 0xC7, 0x3A, 0xAF, 0xFE, 0xF7,
    0xFC, 0xD7, 0xE2, 0x8F, 0x6A, 0x20, 0x46, 0x09,
    0x40, 0x22, 0x2D, 0x79, 0x38, 0x11, 0xB1, 0x4A,
    0xE3, 0x48, 0xE8, 0x10, 0x37, 0xA0, 0x22, 0xF7,
    0xB4, 0x79, 0xD1, 0xA9, 0x3D, 0xC2, 0xAB, 0x37,
    0xAE, 0x82, 0x68, 0x1A, 0x16, 0xEF, 0x33, 0x0C,
    0x30, 0x80, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
    0xF7, 0x0D, 0x01, 0x07, 0x01, 0x30, 0x14, 0x06,
    0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03,
    0x07, 0x04, 0x08, 0xAD, 0xD0, 0x38, 0x9B, 0x16,
    0x4B, 0x7F, 0x99, 0xA0, 0x80, 0x04, 0x82, 0x03,
    0xE8, 0x6D, 0x48, 0xFB, 0x8A, 0xBD, 0xED, 0x6C,
    0xCD, 0xC6, 0x48, 0xFD, 0xB7, 0xB0, 0x7C, 0x86,
    0x2C, 0x8D, 0xF0, 0x23, 0x12, 0xD8, 0xA3, 0x2A,
    0x21, 0x6F, 0x8B, 0x75, 0xBB, 0x47, 0x7F, 0xC9,
    0xBA, 0xBA, 0xFF, 0x91, 0x09, 0x01, 0x7A, 0x5C,
    0x96, 0x02, 0xB8, 0x8E, 0xF8, 0x67, 0x7E, 0x8F,
    0xF9, 0x51, 0x0E, 0xFF, 0x8E, 0xE2, 0x61, 0xC0,
    0xDF, 0xFA, 0xE2, 0x4C, 0x50, 0x90, 0xAE, 0xA1,
    0x15, 0x38, 0x3D, 0xBE, 0x88, 0xD7, 0x57, 0xC0,
    0x11, 0x44, 0xA2, 0x61, 0x05, 0x49, 0x6A, 0x94,
    0x04, 0x10, 0xD9, 0xC2, 0x2D, 0x15, 0x20, 0x0D,
    0xBD, 0xA2, 0xEF, 0xE4, 0x68, 0xFA, 0x39, 0x75,
    0x7E, 0xD8, 0x64, 0x44, 0xCB, 0xE0, 0x00, 0x6D,
    0x57, 0x4E, 0x8A, 0x17, 0xA9, 0x83, 0x6C, 0x7F,
    0xFE, 0x01, 0xEE, 0xDE, 0x99, 0x3A, 0xB2, 0xFF,
    0xD3, 0x72, 0x78, 0xBA, 0xF1, 0x23, 0x54, 0x48,
    0x02, 0xD8, 0x38, 0xA9, 0x54, 0xE5, 0x4A, 0x81,
    0xB9, 0xC0, 0x67, 0xB2, 0x7D, 0x3C, 0x6F, 0xCE,
    0xA4, 0xDD, 0x34, 0x5F, 0x60, 0xB1, 0xA3, 0x7A,
    0xE4, 0x43, 0xF2, 0x89, 0x64, 0x35, 0x09, 0x32,
    0x51, 0xFB, 0x5C, 0x67, 0x0C, 0x3B, 0xFC, 0x36,
    0x6B, 0x37, 0x43, 0x6C, 0x03, 0xCD, 0x44, 0xC7,
    0x2B, 0x62, 0xD6, 0xD1, 0xF4, 0x07, 0x7B, 0x19,
    0x91, 0xF0, 0xD7, 0xF5, 0x54, 0xBC, 0x0F, 0x42,
    0x6B, 0x69, 0xF7, 0xA3, 0xC8, 0xEE, 0xB9, 0x7A,
    0x9E, 0x3D, 0xDF, 0x53, 0x47, 0xF7, 0x50, 0x67,
    0x00, 0xCF, 0x2B, 0x3B, 0xE9, 0x85, 0xEE, 0xBD,
    0x4C, 0x64, 0x66, 0x0B, 0x77, 0x80, 0x9D, 0xEF,
    0x11, 0x32, 0x77, 0xA8, 0xA4, 0x5F, 0xEE, 0x2D,
    0xE0, 0x43, 0x87, 0x76, 0x87, 0x53, 0x4E, 0xD7,
    0x1A, 0x04, 0x7B, 0xE1, 0xD1, 0xE1, 0xF5, 0x87,
    0x51, 0x13, 0xE0, 0xC2, 0xAA, 0xA3, 0x4B, 0xAA,
    0x9E, 0xB4, 0xA6, 0x1D, 0x4E, 0x28, 0x57, 0x0B,
    0x80, 0x90, 0x81, 0x4E, 0x04, 0xF5, 0x30, 0x8D,
    0x51, 0xCE, 0x57, 0x2F, 0x88, 0xC5, 0x70, 0xC4,
    0x06, 0x8F, 0xDD, 0x37, 0xC1, 0x34, 0x1E, 0x0E,
    0x15, 0x32, 0x23, 0x92, 0xAB, 0x40, 0xEA, 0xF7,
    0x43, 0xE2, 0x1D, 0xE2, 0x4B, 0xC9, 0x91, 0xF4,
    0x63, 0x21, 0x34, 0xDB, 0xE9, 0x86, 0x83, 0x1A,
    0xD2, 0x52, 0xEF, 0x7A, 0xA2, 0xEE, 0xA4, 0x11,
    0x56, 0xD3, 0x6C, 0xF5, 0x6D, 0xE4, 0xA5, 0x2D,
    0x99, 0x02, 0x10, 0xDF, 0x29, 0xC5, 0xE3, 0x0B,
    0xC4, 0xA1, 0xEE, 0x5F, 0x4A, 0x10, 0xEE, 0x85,
    0x73, 0x2A, 0x92, 0x15, 0x2C, 0xC8, 0xF4, 0x8C,
    0xD7, 0x3D, 0xBC, 0xAD, 0x18, 0xE0, 0x59, 0xD3,
    0xEE, 0x75, 0x90, 0x1C, 0xCC, 0x76, 0xC6, 0x64,
    0x17, 0xD2, 0xD0, 0x91, 0xA6, 0xD0, 0xC1, 0x4A,
    0xAA, 0x58, 0x22, 0xEC, 0x45, 0x98, 0xF2, 0xCC,
    0x4C, 0xE4, 0xBF, 0xED, 0xF6, 0x44, 0x72, 0x36,
    0x65, 0x3F, 0xE3, 0xB5, 0x8B, 0x3E, 0x54, 0x9C,
    0x82, 0x86, 0x5E, 0xB0, 0xF2, 0x12, 0xE5, 0x69,
    0xFA, 0x46, 0xA2, 0x54, 0xFC, 0xF5, 0x4B, 0xE0,
    0x24, 0x3B, 0x99, 0x04, 0x1A, 0x7A, 0xF7, 0xD1,
    0xFF, 0x68, 0x97, 0xB2, 0x85, 0x82, 0x95, 0x27,
    0x2B, 0xF4, 0xE7, 0x1A, 0x74, 0x19, 0xEC, 0x8C,
    0x4E, 0xA7, 0x0F, 0xAD, 0x4F, 0x5A, 0x02, 0x80,
    0xC1, 0x6A, 0x9E, 0x54, 0xE4, 0x8E, 0xA3, 0x41,
    0x3F, 0x6F, 0x9C, 0x82, 0x9F, 0x83, 0xB0, 0x44,
    0x01, 0x5F, 0x10, 0x9D, 0xD3, 0xB6, 0x33, 0x5B,
    0xAF, 0xAC, 0x6B, 0x57, 0x2A, 0x01, 0xED, 0x0E,
    0x17, 0xB9, 0x80, 0x76, 0x12, 0x1C, 0x51, 0x56,
    0xDD, 0x6D, 0x94, 0xAB, 0xD2, 0xE5, 0x15, 0x2D,
    0x3C, 0xC5, 0xE8, 0x62, 0x05, 0x8B, 0x40, 0xB1,
    0xC2, 0x83, 0xCA, 0xAC, 0x4B, 0x8B, 0x39, 0xF7,
    0xA0, 0x08, 0x43, 0x5C, 0xF7, 0xE8, 0xED, 0x40,
    0x72, 0x73, 0xE3, 0x6B, 0x18, 0x67, 0xA0, 0xB6,
    0x0F, 0xED, 0x8F, 0x9A, 0xE4, 0x27, 0x62, 0x23,
    0xAA, 0x6D, 0x6C, 0x31, 0xC9, 0x9D, 0x6B, 0xE0,
    0xBF, 0x9D, 0x7D, 0x2E, 0x76, 0x71, 0x06, 0x39,
    0xAC, 0x96, 0x1C, 0xAF, 0x30, 0xF2, 0x62, 0x9C,
    0x84, 0x3F, 0x43, 0x5E, 0x19, 0xA8, 0xE5, 0x3C,
    0x9D, 0x43, 0x3C, 0x43, 0x41, 0xE8, 0x82, 0xE7,
    0x5B, 0xF3, 0xE2, 0x15, 0xE3, 0x52, 0x20, 0xFD,
    0x0D, 0xB2, 0x4D, 0x48, 0xAD, 0x53, 0x7E, 0x0C,
    0xF0, 0xB9, 0xBE, 0xC9, 0x58, 0x4B, 0xC8, 0xA8,
    0xA3, 0x36, 0xF1, 0x2C, 0xD2, 0xE1, 0xC8, 0xC4,
    0x3C, 0x48, 0x70, 0xC2, 0x6D, 0x6C, 0x3D, 0x99,
    0xAC, 0x43, 0x19, 0x69, 0xCA, 0x67, 0x1A, 0xC9,
    0xE1, 0x47, 0xFA, 0x0A, 0xE6, 0x5B, 0x6F, 0x61,
    0xD0, 0x03, 0xE4, 0x03, 0x4B, 0xFD, 0xE2, 0xA5,
    0x8D, 0x83, 0x01, 0x7E, 0xC0, 0x7B, 0x2E, 0x0B,
    0x29, 0xDD, 0xD6, 0xDC, 0x71, 0x46, 0xBD, 0x9A,
    0x40, 0x46, 0x1E, 0x0A, 0xB1, 0x00, 0xE7, 0x71,
    0x29, 0x77, 0xFC, 0x9A, 0x76, 0x8A, 0x5F, 0x66,
    0x9B, 0x63, 0x91, 0x12, 0x78, 0xBF, 0x67, 0xAD,
    0xA1, 0x72, 0x9E, 0xC5, 0x3E, 0xE5, 0xCB, 0xAF,
    0xD6, 0x5A, 0x0D, 0xB6, 0x9B, 0xA3, 0x78, 0xE8,
    0xB0, 0x8F, 0x69, 0xED, 0xC1, 0x73, 0xD5, 0xE5,
    0x1C, 0x18, 0xA0, 0x58, 0x4C, 0x49, 0xBD, 0x91,
    0xCE, 0x15, 0x0D, 0xAA, 0x5A, 0x07, 0xEA, 0x1C,
    0xA7, 0x4B, 0x11, 0x31, 0x80, 0xAF, 0xA1, 0x0A,
    0xED, 0x6C, 0x70, 0xE4, 0xDB, 0x75, 0x86, 0xAE,
    0xBF, 0x4A, 0x05, 0x72, 0xDE, 0x84, 0x8C, 0x7B,
    0x59, 0x81, 0x58, 0xE0, 0xC0, 0x15, 0xB5, 0xF3,
    0xD5, 0x73, 0x78, 0x83, 0x53, 0xDA, 0x92, 0xC1,
    0xE6, 0x71, 0x74, 0xC7, 0x7E, 0xAA, 0x36, 0x06,
    0xF0, 0xDF, 0xBA, 0xFB, 0xEF, 0x54, 0xE8, 0x11,
    0xB2, 0x33, 0xA3, 0x0B, 0x9E, 0x0C, 0x59, 0x75,
    0x13, 0xFA, 0x7F, 0x88, 0xB9, 0x86, 0xBD, 0x1A,
    0xDB, 0x52, 0x12, 0xFB, 0x6D, 0x1A, 0xCB, 0x49,
    0x94, 0x94, 0xC4, 0xA9, 0x99, 0xC0, 0xA4, 0xB6,
    0x60, 0x36, 0x09, 0x94, 0x2A, 0xD5, 0xC4, 0x26,
    0xF4, 0xA3, 0x6A, 0x0E, 0x57, 0x8B, 0x7C, 0xA4,
    0x1D, 0x75, 0xE8, 0x2A, 0xF3, 0xC4, 0x3C, 0x7D,
    0x45, 0x6D, 0xD8, 0x24, 0xD1, 0x3B, 0xF7, 0xCF,
    0xE4, 0x45, 0x2A, 0x55, 0xE5, 0xA9, 0x1F, 0x1C,
    0x8F, 0x55, 0x8D, 0xC1, 0xF7, 0x74, 0xCC, 0x26,
    0xC7, 0xBA, 0x2E, 0x5C, 0xC1, 0x71, 0x0A, 0xAA,
    0xD9, 0x6D, 0x76, 0xA7, 0xF9, 0xD1, 0x18, 0xCB,
    0x5A, 0x52, 0x98, 0xA8, 0x0D, 0x3F, 0x06, 0xFC,
    0x49, 0x11, 0x21, 0x5F, 0x86, 0x19, 0x33, 0x81,
    0xB5, 0x7A, 0xDA, 0xA1, 0x47, 0xBF, 0x7C, 0xD7,
    0x05, 0x96, 0xC7, 0xF5, 0xC1, 0x61, 0xE5, 0x18,
    0xA5, 0x38, 0x68, 0xED, 0xB4, 0x17, 0x62, 0x0D,
    0x01, 0x5E, 0xC3, 0x04, 0xA6, 0xBA, 0xB1, 0x01,
    0x60, 0x5C, 0xC1, 0x3A, 0x34, 0x97, 0xD6, 0xDB,
    0x67, 0x73, 0x4D, 0x33, 0x96, 0x01, 0x67, 0x44,
    0xEA, 0x47, 0x5E, 0x44, 0xB5, 0xE5, 0xD1, 0x6C,
    0x20, 0xA9, 0x6D, 0x4D, 0xBC, 0x02, 0xF0, 0x70,
    0xE4, 0xDD, 0xE9, 0xD5, 0x5C, 0x28, 0x29, 0x0B,
    0xB4, 0x60, 0x2A, 0xF1, 0xF7, 0x1A, 0xF0, 0x36,
    0xAE, 0x51, 0x3A, 0xAE, 0x6E, 0x48, 0x7D, 0xC7,
    0x5C, 0xF3, 0xDC, 0xF6, 0xED, 0x27, 0x4E, 0x8E,
    0x48, 0x18, 0x3E, 0x08, 0xF1, 0xD8, 0x3D, 0x0D,
    0xE7, 0x2F, 0x65, 0x8A, 0x6F, 0xE2, 0x1E, 0x06,
    0xC1, 0x04, 0x58, 0x7B, 0x4A, 0x75, 0x60, 0x92,
    0x13, 0xC6, 0x40, 0x2D, 0x3A, 0x8A, 0xD1, 0x03,
    0x05, 0x1F, 0x28, 0x66, 0xC2, 0x57, 0x2A, 0x4C,
    0xE1, 0xA3, 0xCB, 0xA1, 0x95, 0x30, 0x10, 0xED,
    0xDF, 0xAE, 0x70, 0x49, 0x4E, 0xF6, 0xB4, 0x5A,
    0xB6, 0x22, 0x56, 0x37, 0x05, 0xE7, 0x3E, 0xB2,
    0xE3, 0x96, 0x62, 0xEC, 0x09, 0x53, 0xC0, 0x50,
    0x3D, 0xA7, 0xBC, 0x9B, 0x39, 0x02, 0x26, 0x16,
    0xB5, 0x34, 0x17, 0xD4, 0xCA, 0xFE, 0x1D, 0xE4,
    0x5A, 0xDA, 0x4C, 0xC2, 0xCA, 0x8E, 0x79, 0xBF,
    0xD8, 0x4C, 0xBB, 0xFA, 0x30, 0x7B, 0xA9, 0x3E,
    0x52, 0x19, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00
};
#endif /* HAVE_PKCS7 && !NO_FILESYSTEM && ASN_BER_TO_DER &&
        * !NO_DES3 && !NO_SHA
        */

/*
 * Testing wc_PKCS7_BER()
 */
static int test_wc_PKCS7_BER(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && \
    !defined(NO_SHA) && defined(ASN_BER_TO_DER)
    PKCS7* pkcs7 = NULL;
    char   fName[] = "./certs/test-ber-exp02-05-2022.p7b";
    XFILE  f = XBADFILE;
    byte   der[4096];
#ifndef NO_DES3
    byte   decoded[2048];
#endif
    word32 derSz = 0;
#if !defined(NO_PKCS7_STREAM) && !defined(NO_RSA)
    word32 z;
    int ret;
#endif /* !NO_PKCS7_STREAM && !NO_RSA */

    ExpectTrue((f = XFOPEN(fName, "rb")) != XBADFILE);
    ExpectTrue((derSz = (word32)XFREAD(der, 1, sizeof(der), f)) > 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
#ifndef NO_RSA
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);

    #ifndef NO_PKCS7_STREAM
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);

    /* test for streaming */
    ret = -1;
    for (z = 0; z < derSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, der + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
    #endif /* !NO_PKCS7_STREAM */
#else
    ExpectIntNE(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);
#endif
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_DES3
    /* decode BER content */
    ExpectTrue((f = XFOPEN("./certs/1024/client-cert.der", "rb")) != XBADFILE);
    ExpectTrue((derSz = (word32)XFREAD(der, 1, sizeof(der), f)) > 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
#ifndef NO_RSA
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, der, derSz), 0);
#else
    ExpectIntNE(wc_PKCS7_InitWithCert(pkcs7, der, derSz), 0);
#endif

    ExpectTrue((f = XFOPEN("./certs/1024/client-key.der", "rb")) != XBADFILE);
    ExpectTrue((derSz = (word32)XFREAD(der, 1, sizeof(der), f)) > 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    if (pkcs7 != NULL) {
        pkcs7->privateKey   = der;
        pkcs7->privateKeySz = derSz;
    }
#ifndef NO_RSA
#ifdef WOLFSSL_SP_MATH
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, berContent,
        sizeof(berContent), decoded, sizeof(decoded)), WC_NO_ERR_TRACE(WC_KEY_SIZE_E));
#else
    ExpectIntGT(wc_PKCS7_DecodeEnvelopedData(pkcs7, berContent,
        sizeof(berContent), decoded, sizeof(decoded)), 0);
#endif
#else
    ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, berContent,
        sizeof(berContent), decoded, sizeof(decoded)), WC_NO_ERR_TRACE(NOT_COMPILED_IN));
#endif
    wc_PKCS7_Free(pkcs7);
#endif /* !NO_DES3 */
#endif
    return EXPECT_RESULT();
} /* END test_wc_PKCS7_BER() */

static int test_wc_PKCS7_signed_enveloped(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_RSA) && !defined(NO_AES) && \
    !defined(NO_FILESYSTEM)
    XFILE  f = XBADFILE;
    PKCS7* pkcs7 = NULL;
#ifdef HAVE_AES_CBC
    PKCS7* inner = NULL;
#endif
    WC_RNG rng;
    unsigned char key[FOURK_BUF/2];
    unsigned char cert[FOURK_BUF/2];
    unsigned char env[FOURK_BUF];
    int envSz  = FOURK_BUF;
    int keySz = 0;
    int certSz = 0;
    unsigned char sig[FOURK_BUF * 2];
    int sigSz = FOURK_BUF * 2;
#ifdef HAVE_AES_CBC
    unsigned char decoded[FOURK_BUF];
    int decodedSz = FOURK_BUF;
#endif
#ifndef NO_PKCS7_STREAM
    int z;
    int ret;
#endif /* !NO_PKCS7_STREAM */

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    /* load cert */
    ExpectTrue((f = XFOPEN(cliCertDerFile, "rb")) != XBADFILE);
    ExpectIntGT((certSz = (int)XFREAD(cert, 1, sizeof(cert), f)), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    /* load key */
    ExpectTrue((f = XFOPEN(cliKeyFile, "rb")) != XBADFILE);
    ExpectIntGT((keySz = (int)XFREAD(key, 1, sizeof(key), f)), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    ExpectIntGT(keySz = wolfSSL_KeyPemToDer(key, keySz, key, keySz, NULL), 0);

    /* sign cert for envelope */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, (word32)certSz), 0);
    if (pkcs7 != NULL) {
        pkcs7->content    = cert;
        pkcs7->contentSz  = (word32)certSz;
        pkcs7->contentOID = DATA;
        pkcs7->privateKey   = key;
        pkcs7->privateKeySz = (word32)keySz;
        pkcs7->encryptOID   = RSAk;
        pkcs7->hashOID      = SHA256h;
        pkcs7->rng          = &rng;
    }
    ExpectIntGT((sigSz = wc_PKCS7_EncodeSignedData(pkcs7, sig, (word32)sigSz)), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    DoExpectIntEQ(wc_FreeRng(&rng), 0);

#ifdef HAVE_AES_CBC
    /* create envelope */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, (word32)certSz), 0);
    if (pkcs7 != NULL) {
        pkcs7->content   = sig;
        pkcs7->contentSz = (word32)sigSz;
        pkcs7->contentOID = DATA;
        pkcs7->encryptOID = AES256CBCb;
        pkcs7->privateKey   = key;
        pkcs7->privateKeySz = (word32)keySz;
    }
    ExpectIntGT((envSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, env, (word32)envSz)), 0);
    ExpectIntLT(wc_PKCS7_EncodeEnvelopedData(pkcs7, env, 2), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
#endif

    /* create bad signed enveloped data */
    sigSz = FOURK_BUF * 2;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, (word32)certSz), 0);
    if (pkcs7 != NULL) {
        pkcs7->content    = env;
        pkcs7->contentSz  = (word32)envSz;
        pkcs7->contentOID = DATA;
        pkcs7->privateKey   = key;
        pkcs7->privateKeySz = (word32)keySz;
        pkcs7->encryptOID   = RSAk;
        pkcs7->hashOID      = SHA256h;
        pkcs7->rng = &rng;
    }

    /* Set no certs in bundle for this test. */
    if (pkcs7 != NULL) {
        ExpectIntEQ(wc_PKCS7_SetNoCerts(pkcs7, 1), 0);
        ExpectIntEQ(wc_PKCS7_SetNoCerts(NULL, 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_PKCS7_GetNoCerts(pkcs7), 1);
    }
    ExpectIntGT((sigSz = wc_PKCS7_EncodeSignedData(pkcs7, sig, (word32)sigSz)), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    /* check verify fails */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, sig, (word32)sigSz),
            WC_NO_ERR_TRACE(PKCS7_SIGNEEDS_CHECK));

    /* try verifying the signature manually */
    {
        RsaKey rKey;
        word32 idx = 0;
        byte digest[MAX_SEQ_SZ + MAX_ALGO_SZ + MAX_OCTET_STR_SZ +
            WC_MAX_DIGEST_SIZE];
        int  digestSz = 0;

        ExpectIntEQ(wc_InitRsaKey(&rKey, HEAP_HINT), 0);
        ExpectIntEQ(wc_RsaPrivateKeyDecode(key, &idx, &rKey, (word32)keySz), 0);
        ExpectIntGT(digestSz = wc_RsaSSL_Verify(pkcs7->signature,
            pkcs7->signatureSz, digest, sizeof(digest), &rKey), 0);
        ExpectIntEQ(digestSz, pkcs7->pkcs7DigestSz);
        ExpectIntEQ(XMEMCMP(digest, pkcs7->pkcs7Digest, digestSz), 0);
        ExpectIntEQ(wc_FreeRsaKey(&rKey), 0);
        /* verify was success */
    }

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    /* initializing the PKCS7 struct with the signing certificate should pass */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, (word32)certSz), 0);
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, sig, (word32)sigSz), 0);

#ifndef NO_PKCS7_STREAM
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, (word32)certSz), 0);

    /* test for streaming */
    ret = -1;
    for (z = 0; z < sigSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, sig + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
#endif /* !NO_PKCS7_STREAM */

    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    /* create valid degenerate bundle */
    sigSz = FOURK_BUF * 2;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    if (pkcs7 != NULL) {
        pkcs7->content    = env;
        pkcs7->contentSz  = (word32)envSz;
        pkcs7->contentOID = DATA;
        pkcs7->privateKey   = key;
        pkcs7->privateKeySz = (word32)keySz;
        pkcs7->encryptOID   = RSAk;
        pkcs7->hashOID      = SHA256h;
        pkcs7->rng = &rng;
    }
    ExpectIntEQ(wc_PKCS7_SetSignerIdentifierType(pkcs7, DEGENERATE_SID), 0);
    ExpectIntGT((sigSz = wc_PKCS7_EncodeSignedData(pkcs7, sig, (word32)sigSz)), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    wc_FreeRng(&rng);

    /* check verify */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, sig, (word32)sigSz), 0);
    ExpectNotNull(pkcs7->content);

#ifndef NO_PKCS7_STREAM
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    /* create valid degenerate bundle */
    sigSz = FOURK_BUF * 2;
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    if (pkcs7 != NULL) {
        pkcs7->content    = env;
        pkcs7->contentSz  = (word32)envSz;
        pkcs7->contentOID = DATA;
        pkcs7->privateKey   = key;
        pkcs7->privateKeySz = (word32)keySz;
        pkcs7->encryptOID   = RSAk;
        pkcs7->hashOID      = SHA256h;
        pkcs7->rng = &rng;
    }
    ExpectIntEQ(wc_PKCS7_SetSignerIdentifierType(pkcs7, DEGENERATE_SID), 0);
    ExpectIntGT((sigSz = wc_PKCS7_EncodeSignedData(pkcs7, sig, (word32)sigSz)), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
    wc_FreeRng(&rng);

    /* check verify */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, testDevId), 0);
    /* test for streaming */
    ret = -1;
    for (z = 0; z < sigSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, sig + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
#endif /* !NO_PKCS7_STREAM */

#ifdef HAVE_AES_CBC
    /* check decode */
    ExpectNotNull(inner = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_PKCS7_InitWithCert(inner, cert, (word32)certSz), 0);
    if (inner != NULL) {
        inner->privateKey   = key;
        inner->privateKeySz = (word32)keySz;
    }
    ExpectIntGT((decodedSz = wc_PKCS7_DecodeEnvelopedData(inner, pkcs7->content,
                   pkcs7->contentSz, decoded, (word32)decodedSz)), 0);
    wc_PKCS7_Free(inner);
    inner = NULL;
#endif
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifdef HAVE_AES_CBC
    /* check cert set */
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, decoded, (word32)decodedSz), 0);
    ExpectNotNull(pkcs7->singleCert);
    ExpectIntNE(pkcs7->singleCertSz, 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

#ifndef NO_PKCS7_STREAM
    ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, 0));
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
    /* test for streaming */
    ret = -1;
    for (z = 0; z < decodedSz && ret != 0; z++) {
        ret = wc_PKCS7_VerifySignedData(pkcs7, decoded + z, 1);
        if (ret < 0){
            ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
        }
    }
    ExpectIntEQ(ret, 0);
    ExpectNotNull(pkcs7->singleCert);
    ExpectIntNE(pkcs7->singleCertSz, 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;
#endif /* !NO_PKCS7_STREAM */
#endif

    {
        /* arbitrary custom SKID */
        const byte customSKID[] = {
            0x40, 0x25, 0x77, 0x56
        };

        ExpectIntEQ(wc_InitRng(&rng), 0);
        sigSz = FOURK_BUF * 2;
        ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
        if (pkcs7 != NULL) {
            ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, (word32)certSz), 0);
            pkcs7->content    = cert;
            pkcs7->contentSz  = (word32)certSz;
            pkcs7->contentOID = DATA;
            pkcs7->privateKey   = key;
            pkcs7->privateKeySz = (word32)keySz;
            pkcs7->encryptOID   = RSAk;
            pkcs7->hashOID      = SHA256h;
            pkcs7->rng          = &rng;
            ExpectIntEQ(wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID), 0);
            ExpectIntEQ(wc_PKCS7_SetCustomSKID(pkcs7, customSKID,
                        sizeof(customSKID)), 0);
            ExpectIntGT((sigSz = wc_PKCS7_EncodeSignedData(pkcs7, sig,
                (word32)sigSz)), 0);
        }
        wc_PKCS7_Free(pkcs7);
        pkcs7 = NULL;
        wc_FreeRng(&rng);
    }
#endif /* HAVE_PKCS7 && !NO_RSA && !NO_AES */
    return EXPECT_RESULT();
}

static int test_wc_PKCS7_NoDefaultSignedAttribs(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) \
    && !defined(NO_AES)
    PKCS7* pkcs7 = NULL;
    void*  heap = NULL;

    ExpectNotNull(pkcs7 = wc_PKCS7_New(heap, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, heap, testDevId), 0);

    ExpectIntEQ(wc_PKCS7_NoDefaultSignedAttribs(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_NoDefaultSignedAttribs(pkcs7), 0);

    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
}

static int test_wc_PKCS7_SetOriEncryptCtx(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) \
    && !defined(NO_AES)
    PKCS7*       pkcs7 = NULL;
    void*        heap = NULL;
    WOLFSSL_CTX* ctx = NULL;

    ExpectNotNull(pkcs7 = wc_PKCS7_New(heap, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, heap, testDevId), 0);

    ExpectIntEQ(wc_PKCS7_SetOriEncryptCtx(NULL, ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_SetOriEncryptCtx(pkcs7, ctx), 0);

    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
}

static int test_wc_PKCS7_SetOriDecryptCtx(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) \
    && !defined(NO_AES)
    PKCS7*       pkcs7 = NULL;
    void*        heap = NULL;
    WOLFSSL_CTX* ctx = NULL;

    ExpectNotNull(pkcs7 = wc_PKCS7_New(heap, testDevId));
    ExpectIntEQ(wc_PKCS7_Init(pkcs7, heap, testDevId), 0);

    ExpectIntEQ(wc_PKCS7_SetOriDecryptCtx(NULL, ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_PKCS7_SetOriDecryptCtx(pkcs7, ctx), 0);

    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
}

static int test_wc_PKCS7_DecodeCompressedData(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) \
    && !defined(NO_AES) && defined(HAVE_LIBZ)
    PKCS7* pkcs7 = NULL;
    void*  heap = NULL;
    byte   out[4096];
    byte*  decompressed = NULL;
    int    outSz;
    int    decompressedSz;
    const char* cert = "./certs/client-cert.pem";
    byte*  cert_buf = NULL;
    size_t cert_sz = 0;

    ExpectIntEQ(load_file(cert, &cert_buf, &cert_sz), 0);
    ExpectNotNull((decompressed = (byte*)XMALLOC(cert_sz, heap,
        DYNAMIC_TYPE_TMP_BUFFER)));
    decompressedSz = (int)cert_sz;
    ExpectNotNull((pkcs7 = wc_PKCS7_New(heap, testDevId)));

    if (pkcs7 != NULL) {
        pkcs7->content    = (byte*)cert_buf;
        pkcs7->contentSz  = (word32)cert_sz;
        pkcs7->contentOID = DATA;
    }

    ExpectIntGT((outSz = wc_PKCS7_EncodeCompressedData(pkcs7, out,
        sizeof(out))), 0);
    wc_PKCS7_Free(pkcs7);
    pkcs7 = NULL;

    /* compressed key should be smaller than when started */
    ExpectIntLT(outSz, cert_sz);

    /* test decompression */
    ExpectNotNull((pkcs7 = wc_PKCS7_New(heap, testDevId)));
    ExpectIntEQ(pkcs7->contentOID, 0);

    /* fail case with out buffer too small */
    ExpectIntLT(wc_PKCS7_DecodeCompressedData(pkcs7, out, outSz,
        decompressed, outSz), 0);

    /* success case */
    ExpectIntEQ(wc_PKCS7_DecodeCompressedData(pkcs7, out, outSz,
        decompressed, decompressedSz), cert_sz);
    ExpectIntEQ(pkcs7->contentOID, DATA);
    ExpectIntEQ(XMEMCMP(decompressed, cert_buf, cert_sz), 0);
    XFREE(decompressed, heap, DYNAMIC_TYPE_TMP_BUFFER);
    decompressed = NULL;

    /* test decompression function with different 'max' inputs */
    outSz = sizeof(out);
    ExpectIntGT((outSz = wc_Compress(out, outSz, cert_buf, (word32)cert_sz, 0)),
        0);
    ExpectIntLT(wc_DeCompressDynamic(&decompressed, 1, DYNAMIC_TYPE_TMP_BUFFER,
        out, outSz, 0, heap), 0);
    ExpectNull(decompressed);
    ExpectIntGT(wc_DeCompressDynamic(&decompressed, -1, DYNAMIC_TYPE_TMP_BUFFER,
        out, outSz, 0, heap), 0);
    ExpectNotNull(decompressed);
    ExpectIntEQ(XMEMCMP(decompressed, cert_buf, cert_sz), 0);
    XFREE(decompressed, heap, DYNAMIC_TYPE_TMP_BUFFER);
    decompressed = NULL;

    ExpectIntGT(wc_DeCompressDynamic(&decompressed, DYNAMIC_TYPE_TMP_BUFFER, 5,
        out, outSz, 0, heap), 0);
    ExpectNotNull(decompressed);
    ExpectIntEQ(XMEMCMP(decompressed, cert_buf, cert_sz), 0);
    XFREE(decompressed, heap, DYNAMIC_TYPE_TMP_BUFFER);

    if (cert_buf != NULL)
        free(cert_buf);
    wc_PKCS7_Free(pkcs7);
#endif
    return EXPECT_RESULT();
}

static int test_wc_i2d_PKCS12(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12) \
    && !defined(NO_FILESYSTEM) && !defined(NO_RSA) \
    && !defined(NO_AES) && !defined(NO_SHA)
    WC_PKCS12* pkcs12 = NULL;
    unsigned char der[FOURK_BUF * 2];
    unsigned char* pt;
    int derSz = 0;
    unsigned char out[FOURK_BUF * 2];
    int outSz = FOURK_BUF * 2;
    const char p12_f[] = "./certs/test-servercert.p12";
    XFILE f = XBADFILE;

    ExpectTrue((f =  XFOPEN(p12_f, "rb")) != XBADFILE);
    ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectNotNull(pkcs12 = wc_PKCS12_new());
    ExpectIntEQ(wc_d2i_PKCS12(der, (word32)derSz, pkcs12), 0);
    ExpectIntEQ(wc_i2d_PKCS12(pkcs12, NULL, &outSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectIntEQ(outSz, derSz);

    outSz = derSz - 1;
    pt = out;
    ExpectIntLE(wc_i2d_PKCS12(pkcs12, &pt, &outSz), 0);

    outSz = derSz;
    ExpectIntEQ(wc_i2d_PKCS12(pkcs12, &pt, &outSz), derSz);
    ExpectIntEQ((pt == out), 0);

    pt = NULL;
    ExpectIntEQ(wc_i2d_PKCS12(pkcs12, &pt, NULL), derSz);
    XFREE(pt, NULL, DYNAMIC_TYPE_PKCS);
    wc_PKCS12_free(pkcs12);
    pkcs12 = NULL;

    /* Run the same test but use wc_d2i_PKCS12_fp. */
    ExpectNotNull(pkcs12 = wc_PKCS12_new());
    ExpectIntEQ(wc_d2i_PKCS12_fp("./certs/test-servercert.p12", &pkcs12), 0);
    ExpectIntEQ(wc_i2d_PKCS12(pkcs12, NULL, &outSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectIntEQ(outSz, derSz);
    wc_PKCS12_free(pkcs12);
    pkcs12 = NULL;

    /* wc_d2i_PKCS12_fp can also allocate the PKCS12 object for the caller. */
    ExpectIntEQ(wc_d2i_PKCS12_fp("./certs/test-servercert.p12", &pkcs12), 0);
    ExpectIntEQ(wc_i2d_PKCS12(pkcs12, NULL, &outSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectIntEQ(outSz, derSz);
    wc_PKCS12_free(pkcs12);
    pkcs12 = NULL;
#endif
    return EXPECT_RESULT();
}


/* Testing wc_SignatureGetSize() for signature type ECC */
static int test_wc_SignatureGetSize_ecc(void)
{
    EXPECT_DECLS;
#if !defined(NO_SIG_WRAPPER) && defined(HAVE_ECC) && !defined(NO_ECC256)
    enum wc_SignatureType sig_type;
    word32 key_len;
    ecc_key ecc;
    const char* qx =
        "fa2737fb93488d19caef11ae7faf6b7f4bcd67b286e3fc54e8a65c2b74aeccb0";
    const char* qy =
        "d4ccd6dae698208aa8c3a6f39e45510d03be09b2f124bfc067856c324f9b4d09";
    const char* d =
        "be34baa8d040a3b991f9075b56ba292f755b90e4b6dc10dad36715c33cfdac25";

    XMEMSET(&ecc, 0, sizeof(ecc_key));

    ExpectIntEQ(wc_ecc_init(&ecc), 0);
    ExpectIntEQ(wc_ecc_import_raw(&ecc, qx, qy, d, "SECP256R1"), 0);
    /* Input for signature type ECC */
    sig_type = WC_SIGNATURE_TYPE_ECC;
    key_len = sizeof(ecc_key);
    ExpectIntGT(wc_SignatureGetSize(sig_type, &ecc, key_len), 0);

    /* Test bad args */
    /* // NOLINTBEGIN(clang-analyzer-optin.core.EnumCastOutOfRange) */
    sig_type = (enum wc_SignatureType) 100;
    /* // NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange) */
    ExpectIntEQ(wc_SignatureGetSize(sig_type, &ecc, key_len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    sig_type = WC_SIGNATURE_TYPE_ECC;
    ExpectIntEQ(wc_SignatureGetSize(sig_type, NULL, key_len), 0);
    key_len = (word32)0;
    ExpectIntEQ(wc_SignatureGetSize(sig_type, &ecc, key_len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_ecc_free(&ecc), 0);
#endif /* !NO_SIG_WRAPPER && HAVE_ECC && !NO_ECC256 */
    return EXPECT_RESULT();
} /* END test_wc_SignatureGetSize_ecc() */

/* Testing wc_SignatureGetSize() for signature type rsa */
static int test_wc_SignatureGetSize_rsa(void)
{
    EXPECT_DECLS;
#if !defined(NO_SIG_WRAPPER) && !defined(NO_RSA)
    enum wc_SignatureType sig_type;
    word32 key_len;
    word32 idx = 0;
    RsaKey rsa_key;
    byte* tmp = NULL;
    size_t bytes;

    XMEMSET(&rsa_key, 0, sizeof(RsaKey));

    #ifdef USE_CERT_BUFFERS_1024
        bytes = (size_t)sizeof_client_key_der_1024;
        if (bytes < (size_t)sizeof_client_key_der_1024)
            bytes = (size_t)sizeof_client_cert_der_1024;
    #elif defined(USE_CERT_BUFFERS_2048)
        bytes = (size_t)sizeof_client_key_der_2048;
        if (bytes < (size_t)sizeof_client_cert_der_2048)
            bytes = (size_t)sizeof_client_cert_der_2048;
    #else
        bytes = FOURK_BUF;
    #endif

    ExpectNotNull(tmp = (byte*)XMALLOC(bytes, HEAP_HINT,
        DYNAMIC_TYPE_TMP_BUFFER));
    if (tmp != NULL) {
    #ifdef USE_CERT_BUFFERS_1024
        XMEMCPY(tmp, client_key_der_1024, (size_t)sizeof_client_key_der_1024);
    #elif defined(USE_CERT_BUFFERS_2048)
        XMEMCPY(tmp, client_key_der_2048, (size_t)sizeof_client_key_der_2048);
    #elif !defined(NO_FILESYSTEM)
        XFILE file = XBADFILE;
        ExpectTrue((file = XFOPEN(clientKey, "rb")) != XBADFILE);
        ExpectIntGT(bytes = (size_t)XFREAD(tmp, 1, FOURK_BUF, file), 0);
        if (file != XBADFILE)
            XFCLOSE(file);
        }
    #else
        ExpectFail();
    #endif
    }

    ExpectIntEQ(wc_InitRsaKey_ex(&rsa_key, HEAP_HINT, testDevId), 0);
    ExpectIntEQ(wc_RsaPrivateKeyDecode(tmp, &idx, &rsa_key, (word32)bytes), 0);
    /* Input for signature type RSA */
    sig_type = WC_SIGNATURE_TYPE_RSA;
    key_len = sizeof(RsaKey);
    ExpectIntGT(wc_SignatureGetSize(sig_type, &rsa_key, key_len), 0);

    /* Test bad args */
    /* // NOLINTBEGIN(clang-analyzer-optin.core.EnumCastOutOfRange) */
    sig_type = (enum wc_SignatureType)100;
    /* // NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange) */
    ExpectIntEQ(wc_SignatureGetSize(sig_type, &rsa_key, key_len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    sig_type = WC_SIGNATURE_TYPE_RSA;
    ExpectIntEQ(wc_SignatureGetSize(sig_type, NULL, key_len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    key_len = (word32)0;
    ExpectIntEQ(wc_SignatureGetSize(sig_type, &rsa_key, key_len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRsaKey(&rsa_key), 0);
    XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* !NO_SIG_WRAPPER && !NO_RSA */
    return EXPECT_RESULT();
} /* END test_wc_SignatureGetSize_rsa(void) */

/*----------------------------------------------------------------------------*
 | hash.h Tests
 *----------------------------------------------------------------------------*/

static int test_wc_HashInit(void)
{
    EXPECT_DECLS;
    int i;  /* 0 indicates tests passed, 1 indicates failure */

    wc_HashAlg hash;

    /* enum for holding supported algorithms, #ifndef's restrict if disabled */
    enum wc_HashType enumArray[] = {
    #ifndef NO_MD5
        WC_HASH_TYPE_MD5,
    #endif
    #ifndef NO_SHA
        WC_HASH_TYPE_SHA,
    #endif
    #ifdef WOLFSSL_SHA224
        WC_HASH_TYPE_SHA224,
    #endif
    #ifndef NO_SHA256
        WC_HASH_TYPE_SHA256,
    #endif
    #ifdef WOLFSSL_SHA384
        WC_HASH_TYPE_SHA384,
    #endif
    #ifdef WOLFSSL_SHA512
        WC_HASH_TYPE_SHA512,
    #endif
    };
    /* dynamically finds the length */
    int enumlen = (sizeof(enumArray)/sizeof(enum wc_HashType));

    /* For loop to test various arguments... */
    for (i = 0; i < enumlen; i++) {
        /* check for bad args */
        ExpectIntEQ(wc_HashInit(&hash, enumArray[i]), 0);
        wc_HashFree(&hash, enumArray[i]);

        /* check for null ptr */
        ExpectIntEQ(wc_HashInit(NULL, enumArray[i]), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    }  /* end of for loop */

    return EXPECT_RESULT();
}  /* end of test_wc_HashInit */
/*
 * Unit test function for wc_HashSetFlags()
 */
static int test_wc_HashSetFlags(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_HASH_FLAGS
    wc_HashAlg hash;
    word32 flags = 0;
    int i, j;
    int notSupportedLen;

    /* enum for holding supported algorithms, #ifndef's restrict if disabled */
    enum wc_HashType enumArray[] = {
    #ifndef NO_MD5
            WC_HASH_TYPE_MD5,
    #endif
    #ifndef NO_SHA
            WC_HASH_TYPE_SHA,
    #endif
    #ifdef WOLFSSL_SHA224
            WC_HASH_TYPE_SHA224,
    #endif
    #ifndef NO_SHA256
            WC_HASH_TYPE_SHA256,
    #endif
    #ifdef WOLFSSL_SHA384
            WC_HASH_TYPE_SHA384,
    #endif
    #ifdef WOLFSSL_SHA512
            WC_HASH_TYPE_SHA512,
    #endif
    #ifdef WOLFSSL_SHA3
            WC_HASH_TYPE_SHA3_224,
    #endif
    };
    enum wc_HashType notSupported[] = {
              WC_HASH_TYPE_MD5_SHA,
              WC_HASH_TYPE_MD2,
              WC_HASH_TYPE_MD4,
              WC_HASH_TYPE_BLAKE2B,
              WC_HASH_TYPE_BLAKE2S,
              WC_HASH_TYPE_NONE,
     };

    /* dynamically finds the length */
    int enumlen = (sizeof(enumArray)/sizeof(enum wc_HashType));

    /* For loop to test various arguments... */
    for (i = 0; i < enumlen; i++) {
        ExpectIntEQ(wc_HashInit(&hash, enumArray[i]), 0);
        ExpectIntEQ(wc_HashSetFlags(&hash, enumArray[i], flags), 0);
        ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == 0);
        ExpectIntEQ(wc_HashSetFlags(NULL, enumArray[i], flags), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        wc_HashFree(&hash, enumArray[i]);

    }
    /* For loop to test not supported cases */
    notSupportedLen = (sizeof(notSupported)/sizeof(enum wc_HashType));
    for (j = 0; j < notSupportedLen; j++) {
        ExpectIntEQ(wc_HashInit(&hash, notSupported[j]), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_HashSetFlags(&hash, notSupported[j], flags),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_HashFree(&hash, notSupported[j]), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    }
#endif
    return EXPECT_RESULT();
}  /* END test_wc_HashSetFlags */
/*
 * Unit test function for wc_HashGetFlags()
 */
static int test_wc_HashGetFlags(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_HASH_FLAGS
    wc_HashAlg hash;
    word32 flags = 0;
    int i, j;

    /* enum for holding supported algorithms, #ifndef's restrict if disabled */
    enum wc_HashType enumArray[] = {
    #ifndef NO_MD5
            WC_HASH_TYPE_MD5,
    #endif
    #ifndef NO_SHA
            WC_HASH_TYPE_SHA,
    #endif
    #ifdef WOLFSSL_SHA224
            WC_HASH_TYPE_SHA224,
    #endif
    #ifndef NO_SHA256
            WC_HASH_TYPE_SHA256,
    #endif
    #ifdef WOLFSSL_SHA384
            WC_HASH_TYPE_SHA384,
    #endif
    #ifdef WOLFSSL_SHA512
            WC_HASH_TYPE_SHA512,
    #endif
    #ifdef WOLFSSL_SHA3
            WC_HASH_TYPE_SHA3_224,
    #endif
    };
    enum wc_HashType notSupported[] = {
              WC_HASH_TYPE_MD5_SHA,
              WC_HASH_TYPE_MD2,
              WC_HASH_TYPE_MD4,
              WC_HASH_TYPE_BLAKE2B,
              WC_HASH_TYPE_BLAKE2S,
              WC_HASH_TYPE_NONE,
    };
    int enumlen = (sizeof(enumArray)/sizeof(enum wc_HashType));
    int notSupportedLen;

    /* For loop to test various arguments... */
    for (i = 0; i < enumlen; i++) {
        ExpectIntEQ(wc_HashInit(&hash, enumArray[i]), 0);
        ExpectIntEQ(wc_HashGetFlags(&hash, enumArray[i], &flags), 0);
        ExpectTrue((flags & WC_HASH_FLAG_ISCOPY) == 0);
        ExpectIntEQ(wc_HashGetFlags(NULL, enumArray[i], &flags), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        wc_HashFree(&hash, enumArray[i]);
    }
    /* For loop to test not supported cases */
    notSupportedLen = (sizeof(notSupported)/sizeof(enum wc_HashType));
    for (j = 0; j < notSupportedLen; j++) {
        ExpectIntEQ(wc_HashInit(&hash, notSupported[j]), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_HashGetFlags(&hash, notSupported[j], &flags),
            WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wc_HashFree(&hash, notSupported[j]), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    }
#endif
    return EXPECT_RESULT();
}  /* END test_wc_HashGetFlags */

/*----------------------------------------------------------------------------*
 | Compatibility Tests
 *----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*
 | ASN.1 Tests
 *----------------------------------------------------------------------------*/

static int test_wolfSSL_ASN1_BIT_STRING(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(OPENSSL_ALL)
    ASN1_BIT_STRING* str = NULL;
    ASN1_BIT_STRING* str2 = NULL;
    unsigned char* der = NULL;

    ExpectNotNull(str = ASN1_BIT_STRING_new());
    /* Empty data testing. */
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 1), 0);
    ASN1_BIT_STRING_free(str);
    str = NULL;

    ExpectNotNull(str = ASN1_BIT_STRING_new());

    /* Invalid parameter testing. */
    ExpectIntEQ(ASN1_BIT_STRING_set_bit(NULL, 42, 1), 0);
    ExpectIntEQ(ASN1_BIT_STRING_set_bit(str, -1, 1), 0);
    ExpectIntEQ(ASN1_BIT_STRING_set_bit(str, 42, 2), 0);
    ExpectIntEQ(ASN1_BIT_STRING_set_bit(str, 42, -1), 0);

    /* No bit string - bit is always 0. */
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(NULL, 42), 0);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(NULL, -1), 0);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, -1), 0);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 0), 0);

    ExpectIntEQ(ASN1_BIT_STRING_set_bit(str, 42, 1), 1);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 42), 1);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 41), 0);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, -1), 0);
    ExpectIntEQ(ASN1_BIT_STRING_set_bit(str, 84, 1), 1);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 84), 1);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 83), 0);
    ExpectIntEQ(ASN1_BIT_STRING_set_bit(str, 91, 0), 1);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 91), 0);
    ExpectIntEQ(ASN1_BIT_STRING_set_bit(str, 89, 0), 1);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 89), 0);
    ExpectIntEQ(ASN1_BIT_STRING_set_bit(str, 42, 0), 1);
    ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 42), 0);

    ExpectIntEQ(i2d_ASN1_BIT_STRING(str, NULL), 14);
    ExpectIntEQ(i2d_ASN1_BIT_STRING(str, &der), 14);
#ifdef WOLFSSL_ASN_TEMPLATE
    {
        const unsigned char* tmp = der;
        ExpectNotNull(d2i_ASN1_BIT_STRING(&str2, &tmp, 14));
    }
#endif

    ASN1_BIT_STRING_free(str);
    ASN1_BIT_STRING_free(str2);
    ASN1_BIT_STRING_free(NULL);
    XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_INTEGER(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
    ASN1_INTEGER* a = NULL;
    ASN1_INTEGER* dup = NULL;
    const unsigned char invalidLenDer[] = {
        0x02, 0x20, 0x00
    };
    const unsigned char longDer[] = {
        0x02, 0x20,
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
    };
    const unsigned char* p;

    /* Invalid parameter testing. */
    ASN1_INTEGER_free(NULL);
    ExpectNull(wolfSSL_ASN1_INTEGER_dup(NULL));

    ExpectNotNull(a = ASN1_INTEGER_new());
    ExpectNotNull(dup = wolfSSL_ASN1_INTEGER_dup(a));
    ASN1_INTEGER_free(dup);
    dup = NULL;
    ASN1_INTEGER_free(a);
    a = NULL;

    p = invalidLenDer;
    ExpectNull(d2i_ASN1_INTEGER(NULL, &p, sizeof(invalidLenDer)));

    p = longDer;
    ExpectNotNull(a = d2i_ASN1_INTEGER(NULL, &p, sizeof(longDer)));
    ExpectPtrNE(p, longDer);
    ExpectNotNull(dup = wolfSSL_ASN1_INTEGER_dup(a));
    ASN1_INTEGER_free(dup);
    ASN1_INTEGER_free(a);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_INTEGER_cmp(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
    ASN1_INTEGER* a = NULL;
    ASN1_INTEGER* b = NULL;

    ExpectNotNull(a = ASN1_INTEGER_new());
    ExpectNotNull(b = ASN1_INTEGER_new());
    ExpectIntEQ(ASN1_INTEGER_set(a, 1), 1);
    ExpectIntEQ(ASN1_INTEGER_set(b, 1), 1);

    /* Invalid parameter testing. */
    ExpectIntEQ(wolfSSL_ASN1_INTEGER_cmp(NULL, NULL), -1);
    ExpectIntEQ(wolfSSL_ASN1_INTEGER_cmp(a, NULL), -1);
    ExpectIntEQ(wolfSSL_ASN1_INTEGER_cmp(NULL, b), -1);

    ExpectIntEQ(wolfSSL_ASN1_INTEGER_cmp(a, b), 0);
    ExpectIntEQ(ASN1_INTEGER_set(b, -1), 1);
    ExpectIntGT(wolfSSL_ASN1_INTEGER_cmp(a, b), 0);
    ExpectIntEQ(ASN1_INTEGER_set(a, -2), 1);
    ExpectIntLT(wolfSSL_ASN1_INTEGER_cmp(a, b), 0);
    ExpectIntEQ(ASN1_INTEGER_set(b, 1), 1);
    ExpectIntLT(wolfSSL_ASN1_INTEGER_cmp(a, b), 0);
    ExpectIntEQ(ASN1_INTEGER_set(a, 0x01), 1);
    ExpectIntEQ(ASN1_INTEGER_set(b, 0x1000), 1);
    ExpectIntLT(wolfSSL_ASN1_INTEGER_cmp(a, b), 0);
    ExpectIntGT(wolfSSL_ASN1_INTEGER_cmp(b, a), 0);

    ASN1_INTEGER_free(b);
    ASN1_INTEGER_free(a);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_INTEGER_BN(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
    ASN1_INTEGER* ai = NULL;
    ASN1_INTEGER* ai2 = NULL;
    BIGNUM* bn = NULL;
    BIGNUM* bn2 = NULL;

    ExpectNotNull(ai = ASN1_INTEGER_new());
    ExpectNotNull(bn2 = BN_new());

    /* Invalid parameter testing. */
    ExpectNull(bn = ASN1_INTEGER_to_BN(NULL, NULL));
    ExpectNull(ai2 = BN_to_ASN1_INTEGER(NULL, NULL));

    /* at the moment hard setting since no set function */
    if (ai != NULL) {
        ai->data[0] = 0xff; /* No DER encoding. */
        ai->length = 1;
    }
#if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
    ExpectNotNull(bn = ASN1_INTEGER_to_BN(ai, NULL));
    BN_free(bn);
    bn = NULL;
#else
    ExpectNull(ASN1_INTEGER_to_BN(ai, NULL));
#endif

    if (ai != NULL) {
        ai->data[0] = 0x02; /* tag for ASN_INTEGER */
        ai->data[1] = 0x04; /* bad length of integer */
        ai->data[2] = 0x03;
        ai->length = 3;
    }
#if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
    /* Interpreted as a number 0x020403. */
    ExpectNotNull(bn = ASN1_INTEGER_to_BN(ai, NULL));
    BN_free(bn);
    bn = NULL;
#else
    ExpectNull(ASN1_INTEGER_to_BN(ai, NULL));
#endif

    if (ai != NULL) {
        ai->data[0] = 0x02; /* tag for ASN_INTEGER */
        ai->data[1] = 0x01; /* length of integer */
        ai->data[2] = 0x03;
        ai->length = 3;
    }
    ExpectNotNull(bn = ASN1_INTEGER_to_BN(ai, NULL));
    ExpectNotNull(ai2 = BN_to_ASN1_INTEGER(bn, NULL));
    ExpectIntEQ(ASN1_INTEGER_cmp(ai, ai2), 0);
    ExpectNotNull(bn2 = ASN1_INTEGER_to_BN(ai2, bn2));
    ExpectIntEQ(BN_cmp(bn, bn2), 0);

    if (ai != NULL) {
        ai->data[0] = 0x02; /* tag for ASN_INTEGER */
        ai->data[1] = 0x02; /* length of integer */
        ai->data[2] = 0x00; /* padding byte to ensure positive */
        ai->data[3] = 0xff;
        ai->length = 4;
    }
    ExpectNotNull(bn = ASN1_INTEGER_to_BN(ai, bn));
    ExpectNotNull(ai2 = BN_to_ASN1_INTEGER(bn, ai2));
    ExpectIntEQ(ASN1_INTEGER_cmp(ai, ai2), 0);
    ExpectNotNull(bn2 = ASN1_INTEGER_to_BN(ai2, bn2));
    ExpectIntEQ(BN_cmp(bn, bn2), 0);

    if (ai != NULL) {
        ai->data[0] = 0x02; /* tag for ASN_INTEGER */
        ai->data[1] = 0x01; /* length of integer */
        ai->data[2] = 0x00;
        ai->length = 3;
    }
    ExpectNotNull(bn = ASN1_INTEGER_to_BN(ai, bn));
    ExpectNotNull(ai2 = BN_to_ASN1_INTEGER(bn, ai2));
    ExpectIntEQ(ASN1_INTEGER_cmp(ai, ai2), 0);
    ExpectNotNull(bn2 = ASN1_INTEGER_to_BN(ai2, bn2));
    ExpectIntEQ(BN_cmp(bn, bn2), 0);

    if (ai != NULL) {
        ai->data[0] = 0x02; /* tag for ASN_INTEGER */
        ai->data[1] = 0x01; /* length of integer */
        ai->data[2] = 0x01;
        ai->length = 3;
        ai->negative = 1;
    }
    ExpectNotNull(bn = ASN1_INTEGER_to_BN(ai, bn));
    ExpectNotNull(ai2 = BN_to_ASN1_INTEGER(bn, ai2));
    ExpectIntEQ(ASN1_INTEGER_cmp(ai, ai2), 0);
    ExpectNotNull(bn2 = ASN1_INTEGER_to_BN(ai2, bn2));
    ExpectIntEQ(BN_cmp(bn, bn2), 0);

    BN_free(bn2);
    BN_free(bn);
    ASN1_INTEGER_free(ai2);
    ASN1_INTEGER_free(ai);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_INTEGER_get_set(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
    ASN1_INTEGER *a = NULL;
    long val;

    ExpectNotNull(a = ASN1_INTEGER_new());
    /* Invalid parameter testing. */
    ExpectIntEQ(ASN1_INTEGER_get(NULL), 0);
#if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
    ExpectIntEQ(ASN1_INTEGER_get(a), 0);
#else
    ExpectIntEQ(ASN1_INTEGER_get(a), -1);
#endif
    ASN1_INTEGER_free(a);
    a = NULL;

    ExpectNotNull(a = ASN1_INTEGER_new());
    val = 0;
    ExpectIntEQ(ASN1_INTEGER_set(NULL, val), 0);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* 0 */
    ExpectNotNull(a = ASN1_INTEGER_new());
    val = 0;
    ExpectIntEQ(ASN1_INTEGER_set(a, val), 1);
    ExpectTrue(ASN1_INTEGER_get(a) == val);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* 40 */
    ExpectNotNull(a = ASN1_INTEGER_new());
    val = 40;
    ExpectIntEQ(ASN1_INTEGER_set(a, val), 1);
    ExpectTrue(ASN1_INTEGER_get(a) == val);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* -40 */
    ExpectNotNull(a = ASN1_INTEGER_new());
    val = -40;
    ExpectIntEQ(ASN1_INTEGER_set(a, val), 1);
    ExpectTrue(ASN1_INTEGER_get(a) == val);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* 128 */
    ExpectNotNull(a = ASN1_INTEGER_new());
    val = 128;
    ExpectIntEQ(ASN1_INTEGER_set(a, val), 1);
    ExpectTrue(ASN1_INTEGER_get(a) == val);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* -128 */
    ExpectNotNull(a = ASN1_INTEGER_new());
    val = -128;
    ExpectIntEQ(ASN1_INTEGER_set(a, val), 1);
    ExpectTrue(ASN1_INTEGER_get(a) == val);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* 200 */
    ExpectNotNull(a = ASN1_INTEGER_new());
    val = 200;
    ExpectIntEQ(ASN1_INTEGER_set(a, val), 1);
    ExpectTrue(ASN1_INTEGER_get(a) == val);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* int max (2147483647) */
    ExpectNotNull(a = ASN1_INTEGER_new());
    val = 2147483647;
    ExpectIntEQ(ASN1_INTEGER_set(a, val), 1);
    ExpectTrue(ASN1_INTEGER_get(a) == val);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* int min (-2147483648) */
    ExpectNotNull(a = ASN1_INTEGER_new());
    val = -2147483647 - 1;
    ExpectIntEQ(ASN1_INTEGER_set(a, val), 1);
    ExpectTrue(ASN1_INTEGER_get(a) == val);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* long max positive */
    ExpectNotNull(a = ASN1_INTEGER_new());
    val = (long)(((unsigned long)-1) >> 1);
    ExpectIntEQ(ASN1_INTEGER_set(a, val), 1);
    ExpectTrue(ASN1_INTEGER_get(a) == val);
    ASN1_INTEGER_free(a);
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA)
typedef struct ASN1IntTestVector {
    const byte* der;
    const size_t derSz;
    const long value;
} ASN1IntTestVector;
#endif
static int test_wolfSSL_d2i_ASN1_INTEGER(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    size_t i;
    WOLFSSL_ASN1_INTEGER* a = NULL;
    WOLFSSL_ASN1_INTEGER* b = NULL;
    WOLFSSL_ASN1_INTEGER* c = NULL;
    const byte* p = NULL;
    byte* p2 = NULL;
    byte* reEncoded = NULL;
    int reEncodedSz = 0;

    static const byte zeroDer[] = {
        0x02, 0x01, 0x00
    };
    static const byte oneDer[] = {
        0x02, 0x01, 0x01
    };
    static const byte negativeDer[] = {
        0x02, 0x03, 0xC1, 0x16, 0x0D
    };
    static const byte positiveDer[] = {
        0x02, 0x03, 0x01, 0x00, 0x01
    };
    static const byte primeDer[] = {
        0x02, 0x82, 0x01, 0x01, 0x00, 0xc0, 0x95, 0x08, 0xe1, 0x57, 0x41,
        0xf2, 0x71, 0x6d, 0xb7, 0xd2, 0x45, 0x41, 0x27, 0x01, 0x65, 0xc6,
        0x45, 0xae, 0xf2, 0xbc, 0x24, 0x30, 0xb8, 0x95, 0xce, 0x2f, 0x4e,
        0xd6, 0xf6, 0x1c, 0x88, 0xbc, 0x7c, 0x9f, 0xfb, 0xa8, 0x67, 0x7f,
        0xfe, 0x5c, 0x9c, 0x51, 0x75, 0xf7, 0x8a, 0xca, 0x07, 0xe7, 0x35,
        0x2f, 0x8f, 0xe1, 0xbd, 0x7b, 0xc0, 0x2f, 0x7c, 0xab, 0x64, 0xa8,
        0x17, 0xfc, 0xca, 0x5d, 0x7b, 0xba, 0xe0, 0x21, 0xe5, 0x72, 0x2e,
        0x6f, 0x2e, 0x86, 0xd8, 0x95, 0x73, 0xda, 0xac, 0x1b, 0x53, 0xb9,
        0x5f, 0x3f, 0xd7, 0x19, 0x0d, 0x25, 0x4f, 0xe1, 0x63, 0x63, 0x51,
        0x8b, 0x0b, 0x64, 0x3f, 0xad, 0x43, 0xb8, 0xa5, 0x1c, 0x5c, 0x34,
        0xb3, 0xae, 0x00, 0xa0, 0x63, 0xc5, 0xf6, 0x7f, 0x0b, 0x59, 0x68,
        0x78, 0x73, 0xa6, 0x8c, 0x18, 0xa9, 0x02, 0x6d, 0xaf, 0xc3, 0x19,
        0x01, 0x2e, 0xb8, 0x10, 0xe3, 0xc6, 0xcc, 0x40, 0xb4, 0x69, 0xa3,
        0x46, 0x33, 0x69, 0x87, 0x6e, 0xc4, 0xbb, 0x17, 0xa6, 0xf3, 0xe8,
        0xdd, 0xad, 0x73, 0xbc, 0x7b, 0x2f, 0x21, 0xb5, 0xfd, 0x66, 0x51,
        0x0c, 0xbd, 0x54, 0xb3, 0xe1, 0x6d, 0x5f, 0x1c, 0xbc, 0x23, 0x73,
        0xd1, 0x09, 0x03, 0x89, 0x14, 0xd2, 0x10, 0xb9, 0x64, 0xc3, 0x2a,
        0xd0, 0xa1, 0x96, 0x4a, 0xbc, 0xe1, 0xd4, 0x1a, 0x5b, 0xc7, 0xa0,
        0xc0, 0xc1, 0x63, 0x78, 0x0f, 0x44, 0x37, 0x30, 0x32, 0x96, 0x80,
        0x32, 0x23, 0x95, 0xa1, 0x77, 0xba, 0x13, 0xd2, 0x97, 0x73, 0xe2,
        0x5d, 0x25, 0xc9, 0x6a, 0x0d, 0xc3, 0x39, 0x60, 0xa4, 0xb4, 0xb0,
        0x69, 0x42, 0x42, 0x09, 0xe9, 0xd8, 0x08, 0xbc, 0x33, 0x20, 0xb3,
        0x58, 0x22, 0xa7, 0xaa, 0xeb, 0xc4, 0xe1, 0xe6, 0x61, 0x83, 0xc5,
        0xd2, 0x96, 0xdf, 0xd9, 0xd0, 0x4f, 0xad, 0xd7
    };
    static const byte garbageDer[] = {0xDE, 0xAD, 0xBE, 0xEF};

    static const ASN1IntTestVector testVectors[] = {
        {zeroDer, sizeof(zeroDer), 0},
        {oneDer, sizeof(oneDer), 1},
        {negativeDer, sizeof(negativeDer), -4123123},
        {positiveDer, sizeof(positiveDer), 65537},
        {primeDer, sizeof(primeDer), 0}
    };
    static const size_t NUM_TEST_VECTORS =
        sizeof(testVectors)/sizeof(testVectors[0]);

    /* Check d2i error conditions */
    /* NULL pointer to input. */
    ExpectNull((a = wolfSSL_d2i_ASN1_INTEGER(&b, NULL, 1)));
    ExpectNull(b);
    /* NULL input. */
    ExpectNull((a = wolfSSL_d2i_ASN1_INTEGER(&b, &p, 1)));
    ExpectNull(b);
    /* 0 length. */
    p = testVectors[0].der;
    ExpectNull((a = wolfSSL_d2i_ASN1_INTEGER(&b, &p, 0)));
    ExpectNull(b);
    /* Negative length. */
    p = testVectors[0].der;
    ExpectNull((a = wolfSSL_d2i_ASN1_INTEGER(&b, &p, -1)));
    ExpectNull(b);
    /* Garbage DER input. */
    p = garbageDer;
    ExpectNull((a = wolfSSL_d2i_ASN1_INTEGER(&b, &p, sizeof(garbageDer))));
    ExpectNull(b);

    /* Check i2d error conditions */
    /* NULL input. */
    ExpectIntLT(wolfSSL_i2d_ASN1_INTEGER(NULL, &p2), 0);
    /* 0 length input data buffer (a->length == 0). */
    ExpectNotNull((a = wolfSSL_ASN1_INTEGER_new()));
    ExpectIntLT(wolfSSL_i2d_ASN1_INTEGER(a, &p2), 0);
    if (a != NULL)
        a->data = NULL;
    /* NULL input data buffer. */
    ExpectIntLT(wolfSSL_i2d_ASN1_INTEGER(a, &p2), 0);
    if (a != NULL) {
        /* Reset a->data. */
        a->data = a->intData;
    }
    /* Set a to valid value. */
    ExpectIntEQ(wolfSSL_ASN1_INTEGER_set(a, 1), WOLFSSL_SUCCESS);
    /* NULL output buffer. */
    ExpectIntEQ(wolfSSL_i2d_ASN1_INTEGER(a, NULL), 3);
    wolfSSL_ASN1_INTEGER_free(a);
    a = NULL;

    for (i = 0; i < NUM_TEST_VECTORS; ++i) {
        p = testVectors[i].der;
        ExpectNotNull(a = wolfSSL_d2i_ASN1_INTEGER(&b, &p,
            testVectors[i].derSz));
        ExpectIntEQ(wolfSSL_ASN1_INTEGER_cmp(a, b), 0);

        if (testVectors[i].derSz <= sizeof(long)) {
            ExpectNotNull(c = wolfSSL_ASN1_INTEGER_new());
            ExpectIntEQ(wolfSSL_ASN1_INTEGER_set(c, testVectors[i].value), 1);
            ExpectIntEQ(wolfSSL_ASN1_INTEGER_cmp(a, c), 0);
            wolfSSL_ASN1_INTEGER_free(c);
            c = NULL;
        }

        /* Convert to DER without a pre-allocated output buffer. */
        ExpectIntGT((reEncodedSz = wolfSSL_i2d_ASN1_INTEGER(a, &reEncoded)), 0);
        ExpectIntEQ(reEncodedSz, testVectors[i].derSz);
        ExpectIntEQ(XMEMCMP(reEncoded, testVectors[i].der, reEncodedSz), 0);

        /* Convert to DER with a pre-allocated output buffer. In this case, the
         * output buffer pointer should be incremented just past the end of the
         * encoded data. */
        p2 = reEncoded;
        ExpectIntGT((reEncodedSz = wolfSSL_i2d_ASN1_INTEGER(a, &p2)), 0);
        ExpectIntEQ(reEncodedSz, testVectors[i].derSz);
        ExpectPtrEq(reEncoded, p2 - reEncodedSz);
        ExpectIntEQ(XMEMCMP(reEncoded, testVectors[i].der, reEncodedSz), 0);

        XFREE(reEncoded, NULL, DYNAMIC_TYPE_ASN1);
        reEncoded = NULL;
        wolfSSL_ASN1_INTEGER_free(a);
        a = NULL;
    }
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_a2i_ASN1_INTEGER(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_BIO)
    BIO* bio = NULL;
    BIO* out = NULL;
    BIO* fixed = NULL;
    ASN1_INTEGER* ai = NULL;
    char buf[] = "123456\n12345\n1123456789123456\\\n78901234567890 \r\n\n";
    char tmp[1024];
    int  tmpSz;

    const char expected1[] = "123456";
    const char expected2[] = "112345678912345678901234567890";
    char longStr[] = "123456781234567812345678123456781234567812345678\n"
        "123456781234567812345678123456781234567812345678\\\n12345678\n";

    ExpectNotNull(out = BIO_new(BIO_s_mem()));
    ExpectNotNull(ai = ASN1_INTEGER_new());

    ExpectNotNull(bio = BIO_new_mem_buf(buf, -1));

    /* Invalid parameter testing. */
    ExpectIntEQ(a2i_ASN1_INTEGER(NULL, NULL, NULL, -1), 0);
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, NULL, NULL, -1), 0);
    ExpectIntEQ(a2i_ASN1_INTEGER(NULL, ai, NULL, -1), 0);
    ExpectIntEQ(a2i_ASN1_INTEGER(NULL, NULL, tmp, -1), 0);
    ExpectIntEQ(a2i_ASN1_INTEGER(NULL, NULL, NULL, 1024), 0);
    ExpectIntEQ(a2i_ASN1_INTEGER(NULL, ai, tmp, 1024), 0);
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, NULL, tmp, 1024), 0);
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, ai, NULL, 1024), 0);
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, ai, tmp, -1), 0);
    ExpectIntEQ(i2a_ASN1_INTEGER(NULL, NULL), 0);
    ExpectIntEQ(i2a_ASN1_INTEGER(bio, NULL), 0);
    ExpectIntEQ(i2a_ASN1_INTEGER(NULL, ai), 0);

    /* No data to read from BIO. */
    ExpectIntEQ(a2i_ASN1_INTEGER(out, ai, tmp, 1024), 0);

    /* read first line */
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, ai, tmp, 1024), 1);
    ExpectIntEQ(i2a_ASN1_INTEGER(out, ai), 6);
    XMEMSET(tmp, 0, 1024);
    tmpSz = BIO_read(out, tmp, 1024);
    ExpectIntEQ(tmpSz, 6);
    ExpectIntEQ(XMEMCMP(tmp, expected1, tmpSz), 0);

    /* fail on second line (not % 2) */
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, ai, tmp, 1024), 0);

    /* read 3rd long line */
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, ai, tmp, 1024), 1);
    ExpectIntEQ(i2a_ASN1_INTEGER(out, ai), 30);
    XMEMSET(tmp, 0, 1024);
    tmpSz = BIO_read(out, tmp, 1024);
    ExpectIntEQ(tmpSz, 30);
    ExpectIntEQ(XMEMCMP(tmp, expected2, tmpSz), 0);

    /* fail on empty line */
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, ai, tmp, 1024), 0);

    BIO_free(bio);
    bio = NULL;

    /* Make long integer, requiring dynamic memory, even longer. */
    ExpectNotNull(bio = BIO_new_mem_buf(longStr, -1));
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, ai, tmp, 1024), 1);
    ExpectIntEQ(i2a_ASN1_INTEGER(out, ai), 48);
    XMEMSET(tmp, 0, 1024);
    tmpSz = BIO_read(out, tmp, 1024);
    ExpectIntEQ(tmpSz, 48);
    ExpectIntEQ(a2i_ASN1_INTEGER(bio, ai, tmp, 1024), 1);
    ExpectIntEQ(i2a_ASN1_INTEGER(out, ai), 56);
    XMEMSET(tmp, 0, 1024);
    tmpSz = BIO_read(out, tmp, 1024);
    ExpectIntEQ(tmpSz, 56);
    ExpectIntEQ(wolfSSL_ASN1_INTEGER_set(ai, 1), 1);
    BIO_free(bio);
    BIO_free(out);

    ExpectNotNull(fixed = BIO_new(wolfSSL_BIO_s_fixed_mem()));
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    /* Ensure there is 0 bytes available to write into. */
    ExpectIntEQ(BIO_write(fixed, tmp, 1), 1);
    ExpectIntEQ(i2a_ASN1_INTEGER(fixed, ai), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    ExpectIntEQ(i2a_ASN1_INTEGER(fixed, ai), 0);
    BIO_free(fixed);

    ASN1_INTEGER_free(ai);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2c_ASN1_INTEGER(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
    ASN1_INTEGER *a = NULL;
    unsigned char *pp = NULL,*tpp = NULL;
    int ret = 0;

    ExpectNotNull(a = wolfSSL_ASN1_INTEGER_new());

    /* Invalid parameter testing. */
    /* Set pp to an invalid value. */
    pp = NULL;
    ExpectIntEQ(i2c_ASN1_INTEGER(NULL, &pp), 0);
    ExpectIntEQ(i2c_ASN1_INTEGER(a, &pp), 0);
    ExpectIntEQ(i2c_ASN1_INTEGER(NULL, NULL), 0);

    /* 40 */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 1;
        a->intData[2] = 40;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 1);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
                DYNAMIC_TYPE_TMP_BUFFER));
    tpp = pp;
    ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
    ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 1);
    tpp--;
    ExpectIntEQ(*tpp, 40);
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    pp = NULL;

    /* 128 */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 1;
        a->intData[2] = 128;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 2);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
                DYNAMIC_TYPE_TMP_BUFFER));
    tpp = pp;
    if (tpp != NULL) {
        ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
        ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 2);
        tpp--;
        ExpectIntEQ(*(tpp--), 128);
        ExpectIntEQ(*tpp, 0);
    }
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    pp = NULL;

    /* -40 */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 1;
        a->intData[2] = 40;
        a->negative = 1;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 1);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
                DYNAMIC_TYPE_TMP_BUFFER));
    tpp = pp;
    if (tpp != NULL) {
        ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
        ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 1);
        tpp--;
        ExpectIntEQ(*tpp, 216);
    }
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    pp = NULL;

    /* -128 */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 1;
        a->intData[2] = 128;
        a->negative = 1;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 1);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
                DYNAMIC_TYPE_TMP_BUFFER));
    tpp = pp;
    if (tpp != NULL) {
        ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
        ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 1);
        tpp--;
        ExpectIntEQ(*tpp, 128);
    }
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    pp = NULL;

    /* -200 */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 1;
        a->intData[2] = 200;
        a->negative = 1;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 2);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
            DYNAMIC_TYPE_TMP_BUFFER));
    tpp = pp;
    if (tpp != NULL) {
        ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
        ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 2);
        tpp--;
        ExpectIntEQ(*(tpp--), 56);
        ExpectIntEQ(*tpp, 255);
    }
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    pp = NULL;

    /* Empty */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 0;
        a->negative = 0;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 1);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
                DYNAMIC_TYPE_TMP_BUFFER));
    tpp = pp;
    if (tpp != NULL) {
        ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
        ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 1);
        tpp--;
        ExpectIntEQ(*tpp, 0);
    }
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    pp = NULL;

    /* 0 */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 1;
        a->intData[2] = 0;
        a->negative = 1;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 1);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
                DYNAMIC_TYPE_TMP_BUFFER));
    if (tpp != NULL) {
        tpp = pp;
        ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
        ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 1);
        tpp--;
        ExpectIntEQ(*tpp, 0);
    }
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    pp = NULL;

    /* 0x100 */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 2;
        a->intData[2] = 0x01;
        a->intData[3] = 0x00;
        a->negative = 0;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 2);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
                DYNAMIC_TYPE_TMP_BUFFER));
    if (tpp != NULL) {
        tpp = pp;
        ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
        ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 2);
        tpp -= 2;
        ExpectIntEQ(tpp[0], 0x01);
        ExpectIntEQ(tpp[1], 0x00);
    }
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    pp = NULL;

    /* -0x8000 => 0x8000 */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 2;
        a->intData[2] = 0x80;
        a->intData[3] = 0x00;
        a->negative = 1;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 2);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
                DYNAMIC_TYPE_TMP_BUFFER));
    tpp = pp;
    if (tpp != NULL) {
        ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
        ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 2);
        tpp -= 2;
        ExpectIntEQ(tpp[0], 0x80);
        ExpectIntEQ(tpp[1], 0x00);
    }
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    pp = NULL;

    /* -0x8001 => 0xFF7FFF */
    if (a != NULL) {
        a->intData[0] = ASN_INTEGER;
        a->intData[1] = 2;
        a->intData[2] = 0x80;
        a->intData[3] = 0x01;
        a->negative = 1;
    }
    ExpectIntEQ(ret = i2c_ASN1_INTEGER(a, NULL), 3);
    ExpectNotNull(pp = (unsigned char*)XMALLOC(ret + 1, NULL,
                DYNAMIC_TYPE_TMP_BUFFER));
    tpp = pp;
    if (tpp != NULL) {
        ExpectNotNull(XMEMSET(tpp, 0, ret + 1));
        ExpectIntEQ(i2c_ASN1_INTEGER(a, &tpp), 3);
        tpp -= 3;
        ExpectIntEQ(tpp[0], 0xFF);
        ExpectIntEQ(tpp[1], 0x7F);
        ExpectIntEQ(tpp[2], 0xFF);
    }
    XFREE(pp, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    wolfSSL_ASN1_INTEGER_free(a);
#endif /* OPENSSL_EXTRA && !NO_ASN */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_OBJECT(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    ASN1_OBJECT* a = NULL;
    ASN1_OBJECT s;
    const unsigned char der[] = { 0x06, 0x01, 0x00 };

    /* Invalid parameter testing. */
    ASN1_OBJECT_free(NULL);
    ExpectNull(wolfSSL_ASN1_OBJECT_dup(NULL));

    /* Test that a static ASN1_OBJECT can be freed. */
    XMEMSET(&s, 0, sizeof(ASN1_OBJECT));
    ASN1_OBJECT_free(&s);
    ExpectNotNull(a = wolfSSL_ASN1_OBJECT_dup(&s));
    ASN1_OBJECT_free(a);
    a = NULL;
    s.obj = der;
    s.objSz = sizeof(der);
    ExpectNotNull(a = wolfSSL_ASN1_OBJECT_dup(&s));
    ASN1_OBJECT_free(a);
    ASN1_OBJECT_free(&s);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_get_object(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
    const unsigned char* derBuf = cliecc_cert_der_256;
    const unsigned char* nullPtr = NULL;
    const unsigned char objDerInvalidLen[] = { 0x30, 0x81 };
    const unsigned char objDerBadLen[] = { 0x30, 0x04 };
    const unsigned char objDerNotObj[] = { 0x02, 0x01, 0x00 };
    const unsigned char objDerNoData[] = { 0x06, 0x00 };
    const unsigned char* p;
    unsigned char objDer[10];
    unsigned char* der;
    unsigned char* derPtr;
    int len = sizeof_cliecc_cert_der_256;
    long asnLen = 0;
    int tag = 0;
    int cls = 0;
    ASN1_OBJECT* a = NULL;
    ASN1_OBJECT s;

    XMEMSET(&s, 0, sizeof(ASN1_OBJECT));

    /* Invalid encoding at length. */
    p = objDerInvalidLen;
    ExpectIntEQ(ASN1_get_object(&p, &asnLen, &tag, &cls, sizeof(objDerBadLen)),
        0x80);
    p = objDerBadLen;
    /* Error = 0x80, Constructed = 0x20 */
    ExpectIntEQ(ASN1_get_object(&p, &asnLen, &tag, &cls, sizeof(objDerBadLen)),
        0x80 | 0x20);

    /* Read a couple TLV triplets and make sure they match the expected values
     */

    /* SEQUENCE */
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, len) & 0x80, 0);
    ExpectIntEQ(asnLen, 861);
    ExpectIntEQ(tag, 0x10);
    ExpectIntEQ(cls, 0);

    /* SEQUENCE */
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls,
            len - (derBuf - cliecc_cert_der_256)) & 0x80, 0);
    ExpectIntEQ(asnLen, 772);
    ExpectIntEQ(tag, 0x10);
    ExpectIntEQ(cls, 0);

    /* [0] */
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls,
            len - (derBuf - cliecc_cert_der_256)) & 0x80, 0);
    ExpectIntEQ(asnLen, 3);
    ExpectIntEQ(tag, 0);
    ExpectIntEQ(cls, 0x80);

    /* INTEGER */
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls,
            len - (derBuf - cliecc_cert_der_256)) & 0x80, 0);
    ExpectIntEQ(asnLen, 1);
    ExpectIntEQ(tag, 0x2);
    ExpectIntEQ(cls, 0);
    derBuf += asnLen;

    /* INTEGER */
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls,
            len - (derBuf - cliecc_cert_der_256)) & 0x80, 0);
    ExpectIntEQ(asnLen, 20);
    ExpectIntEQ(tag, 0x2);
    ExpectIntEQ(cls, 0);
    derBuf += asnLen;

    /* SEQUENCE */
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls,
            len - (derBuf - cliecc_cert_der_256)) & 0x80, 0);
    ExpectIntEQ(asnLen, 10);
    ExpectIntEQ(tag, 0x10);
    ExpectIntEQ(cls, 0);

    /* Found OBJECT_ID. */

    /* Invalid parameter testing. */
    ExpectIntEQ(ASN1_get_object(NULL, NULL, NULL, NULL, 0), 0x80);
    ExpectIntEQ(ASN1_get_object(&nullPtr, NULL, NULL, NULL, 0), 0x80);
    ExpectIntEQ(ASN1_get_object(NULL, &asnLen, &tag, &cls, len), 0x80);
    ExpectIntEQ(ASN1_get_object(&nullPtr, &asnLen, &tag, &cls, len), 0x80);
    ExpectIntEQ(ASN1_get_object(&derBuf, NULL, &tag, &cls, len), 0x80);
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, NULL, &cls, len), 0x80);
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, NULL, len), 0x80);
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, 0), 0x80);
    ExpectIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, -1), 0x80);
    ExpectNull(d2i_ASN1_OBJECT(NULL, NULL, -1));
    ExpectNull(d2i_ASN1_OBJECT(NULL, &nullPtr, -1));
    ExpectNull(d2i_ASN1_OBJECT(NULL, &derBuf, -1));
    ExpectNull(d2i_ASN1_OBJECT(NULL, NULL, 0));
    ExpectNull(d2i_ASN1_OBJECT(&a, NULL, len));
    ExpectNull(d2i_ASN1_OBJECT(&a, &nullPtr, len));
    ExpectNull(d2i_ASN1_OBJECT(&a, &derBuf, -1));
    ExpectNull(c2i_ASN1_OBJECT(NULL, NULL, -1));
    ExpectNull(c2i_ASN1_OBJECT(NULL, &nullPtr, -1));
    ExpectNull(c2i_ASN1_OBJECT(NULL, &derBuf, -1));
    ExpectNull(c2i_ASN1_OBJECT(NULL, NULL, 1));
    ExpectNull(c2i_ASN1_OBJECT(NULL, &nullPtr, 1));

    /* Invalid encoding at length. */
    p = objDerInvalidLen;
    ExpectNull(d2i_ASN1_OBJECT(&a, &p, sizeof(objDerInvalidLen)));
    p = objDerBadLen;
    ExpectNull(d2i_ASN1_OBJECT(&a, &p, sizeof(objDerBadLen)));
    p = objDerNotObj;
    ExpectNull(d2i_ASN1_OBJECT(&a, &p, sizeof(objDerNotObj)));
    p = objDerNoData;
    ExpectNull(d2i_ASN1_OBJECT(&a, &p, sizeof(objDerNoData)));

    /* Create an ASN OBJECT from content */
    p = derBuf + 2;
    ExpectNotNull(a = c2i_ASN1_OBJECT(NULL, &p, 8));
    ASN1_OBJECT_free(a);
    a = NULL;
    /* Create an ASN OBJECT from DER */
    ExpectNotNull(d2i_ASN1_OBJECT(&a, &derBuf, len));

    /* Invalid parameter testing. */
    ExpectIntEQ(i2d_ASN1_OBJECT(NULL, NULL), 0);
    ExpectIntEQ(i2d_ASN1_OBJECT(&s, NULL), 0);

    ExpectIntEQ(i2d_ASN1_OBJECT(a, NULL), 10);
    der = NULL;
    ExpectIntEQ(i2d_ASN1_OBJECT(a, &der), 10);
    derPtr = objDer;
    ExpectIntEQ(i2d_ASN1_OBJECT(a, &derPtr), 10);
    ExpectPtrNE(derPtr, objDer);
    ExpectIntEQ(XMEMCMP(der, objDer, 10), 0);
    XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);

    ASN1_OBJECT_free(a);
#endif /* OPENSSL_EXTRA && HAVE_ECC && USE_CERT_BUFFERS_256 */
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2a_ASN1_OBJECT(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && !defined(NO_BIO)
    ASN1_OBJECT* obj = NULL;
    ASN1_OBJECT* a = NULL;
    BIO *bio = NULL;
    const unsigned char notObjDer[] = { 0x04, 0x01, 0xff };
    const unsigned char* p;

    ExpectNotNull(obj = OBJ_nid2obj(NID_sha256));
    ExpectTrue((bio = BIO_new(BIO_s_mem())) != NULL);

    ExpectIntGT(wolfSSL_i2a_ASN1_OBJECT(bio, obj), 0);
    ExpectIntGT(wolfSSL_i2a_ASN1_OBJECT(bio, NULL), 0);

    ExpectIntEQ(wolfSSL_i2a_ASN1_OBJECT(NULL, obj), 0);

    /* No DER encoding in ASN1_OBJECT. */
    ExpectNotNull(a = wolfSSL_ASN1_OBJECT_new());
    ExpectIntEQ(wolfSSL_i2a_ASN1_OBJECT(bio, a), 0);
    ASN1_OBJECT_free(a);
    a = NULL;
    /* DER encoding */
    p = notObjDer;
    ExpectNotNull(a = c2i_ASN1_OBJECT(NULL, &p, 3));
    ExpectIntEQ(wolfSSL_i2a_ASN1_OBJECT(bio, a), 5);
    ASN1_OBJECT_free(a);

    BIO_free(bio);
    ASN1_OBJECT_free(obj);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2t_ASN1_OBJECT(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
    char buf[50] = {0};
    ASN1_OBJECT* obj;
    const char* oid = "2.5.29.19";
    const char* ln  = "X509v3 Basic Constraints";

    obj = NULL;
    ExpectIntEQ(i2t_ASN1_OBJECT(NULL, sizeof(buf), obj), 0);
    ExpectIntEQ(i2t_ASN1_OBJECT(buf, sizeof(buf), NULL), 0);
    ExpectIntEQ(i2t_ASN1_OBJECT(buf, 0, NULL), 0);

    ExpectNotNull(obj = OBJ_txt2obj(oid, 0));
    XMEMSET(buf, 0, sizeof(buf));
    ExpectIntEQ(i2t_ASN1_OBJECT(buf, sizeof(buf), obj), XSTRLEN(ln));
    ExpectIntEQ(XSTRNCMP(buf, ln, XSTRLEN(ln)), 0);
    ASN1_OBJECT_free(obj);
#endif /* OPENSSL_EXTRA && WOLFSSL_CERT_EXT && WOLFSSL_CERT_GEN */
    return EXPECT_RESULT();
}

static int test_wolfSSL_sk_ASN1_OBJECT(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
    WOLFSSL_STACK* sk = NULL;
    WOLFSSL_ASN1_OBJECT* obj;

    ExpectNotNull(obj = wolfSSL_ASN1_OBJECT_new());

    ExpectNotNull(sk = wolfSSL_sk_new_asn1_obj());
    wolfSSL_sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    ExpectNotNull(sk = wolfSSL_sk_new_asn1_obj());
    ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(NULL, NULL), -1);
    ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(sk, NULL), 0);
    ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(NULL, obj), -1);
    ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(sk, obj), 1);
    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
    sk = NULL;
    /* obj freed in pop_free call. */

    ExpectNotNull(obj = wolfSSL_ASN1_OBJECT_new());
    ExpectNotNull(sk = wolfSSL_sk_new_asn1_obj());
    ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(sk, obj), 1);
    ExpectPtrEq(obj, wolfSSL_sk_ASN1_OBJECT_pop(sk));
    wolfSSL_sk_ASN1_OBJECT_free(sk);
    wolfSSL_ASN1_OBJECT_free(obj);
#endif /* !NO_ASN && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_STRING(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    ASN1_STRING* str = NULL;
    ASN1_STRING* c = NULL;
    const char data[]  = "hello wolfSSL";
    const char data2[] = "Same len data";
    const char longData[] =
        "This string must be longer than CTC_NAME_SIZE that is defined as 64.";

    ExpectNotNull(str = ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
    ASN1_STRING_free(str);
    str = NULL;

    ExpectNotNull(str = ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
    ExpectIntEQ(ASN1_STRING_type(str), V_ASN1_OCTET_STRING);
    ExpectIntEQ(ASN1_STRING_type(NULL), 0);
    /* Check setting to NULL works. */
    ExpectIntEQ(ASN1_STRING_set(str, NULL, 0), 1);
    ExpectIntEQ(ASN1_STRING_set(str, (const void*)data, sizeof(data)), 1);
    ExpectIntEQ(ASN1_STRING_set(str, (const void*)data, -1), 1);
    ExpectIntEQ(ASN1_STRING_set(str, NULL, -1), 0);
    ExpectIntEQ(ASN1_STRING_set(NULL, NULL, 0), 0);

    ExpectIntEQ(wolfSSL_ASN1_STRING_copy(NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_ASN1_STRING_copy(str, NULL), 0);
    ExpectIntEQ(wolfSSL_ASN1_STRING_copy(NULL, str), 0);
    ExpectNull(wolfSSL_ASN1_STRING_dup(NULL));

    ExpectNotNull(c = wolfSSL_ASN1_STRING_dup(str));
    ExpectIntEQ(ASN1_STRING_cmp(NULL, NULL), -1);
    ExpectIntEQ(ASN1_STRING_cmp(str, NULL), -1);
    ExpectIntEQ(ASN1_STRING_cmp(NULL, c), -1);
    ExpectIntEQ(ASN1_STRING_cmp(str, c), 0);
    ExpectIntEQ(ASN1_STRING_set(c, (const void*)data2, -1), 1);
    ExpectIntGT(ASN1_STRING_cmp(str, c), 0);
    ExpectIntEQ(ASN1_STRING_set(str, (const void*)longData, -1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_copy(c, str), 1);
    ExpectIntEQ(ASN1_STRING_cmp(str, c), 0);
    /* Check setting back to smaller size frees dynamic data. */
    ExpectIntEQ(ASN1_STRING_set(str, (const void*)data, -1), 1);
    ExpectIntLT(ASN1_STRING_cmp(str, c), 0);
    ExpectIntGT(ASN1_STRING_cmp(c, str), 0);

    ExpectNull(ASN1_STRING_get0_data(NULL));
    ExpectNotNull(ASN1_STRING_get0_data(str));
    ExpectNull(ASN1_STRING_data(NULL));
    ExpectNotNull(ASN1_STRING_data(str));
    ExpectIntEQ(ASN1_STRING_length(NULL), 0);
    ExpectIntGT(ASN1_STRING_length(str), 0);

    ASN1_STRING_free(c);
    ASN1_STRING_free(str);
    ASN1_STRING_free(NULL);

#ifndef NO_WOLFSSL_STUB
    ExpectNull(d2i_DISPLAYTEXT(NULL, NULL, 0));
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_STRING_to_UTF8(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_ASN) && !defined(NO_RSA) && \
    !defined(NO_FILESYSTEM)
    WOLFSSL_X509* x509 = NULL;
    WOLFSSL_X509_NAME* subject = NULL;
    WOLFSSL_X509_NAME_ENTRY* e = NULL;
    WOLFSSL_ASN1_STRING* a = NULL;
    FILE* file = XBADFILE;
    int idx = 0;
    char targetOutput[16] = "www.wolfssl.com";
    unsigned char* actual_output = NULL;
    int len = 0;

    ExpectNotNull(file = fopen("./certs/server-cert.pem", "rb"));
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(file, NULL, NULL, NULL));
    if (file != XBADFILE)
        fclose(file);

    /* wolfSSL_ASN1_STRING_to_UTF8(): NID_commonName */
    ExpectNotNull(subject = wolfSSL_X509_get_subject_name(x509));
    ExpectIntEQ((idx = wolfSSL_X509_NAME_get_index_by_NID(subject,
                    NID_commonName, -1)), 5);
    ExpectNotNull(e = wolfSSL_X509_NAME_get_entry(subject, idx));
    ExpectNotNull(a = wolfSSL_X509_NAME_ENTRY_get_data(e));
    ExpectIntEQ((len = wolfSSL_ASN1_STRING_to_UTF8(&actual_output, a)), 15);
    ExpectIntEQ(strncmp((const char*)actual_output, targetOutput, (size_t)len), 0);
    a = NULL;

    /* wolfSSL_ASN1_STRING_to_UTF8(NULL, valid) */
    ExpectIntEQ((len = wolfSSL_ASN1_STRING_to_UTF8(NULL, a)), -1);

    /* wolfSSL_ASN1_STRING_to_UTF8(valid, NULL) */
    ExpectIntEQ((len = wolfSSL_ASN1_STRING_to_UTF8(&actual_output, NULL)), -1);

    /* wolfSSL_ASN1_STRING_to_UTF8(NULL, NULL) */
    ExpectIntEQ((len = wolfSSL_ASN1_STRING_to_UTF8(NULL, NULL)), -1);

    wolfSSL_X509_free(x509);
    XFREE(actual_output, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    ExpectNotNull(a = ASN1_STRING_new());
    ExpectIntEQ(wolfSSL_ASN1_STRING_to_UTF8(&actual_output, a), -1);
    ASN1_STRING_free(a);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2s_ASN1_STRING(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
    WOLFSSL_ASN1_STRING* str = NULL;
    const char* data = "test_wolfSSL_i2s_ASN1_STRING";
    char* ret = NULL;

    ExpectNotNull(str = ASN1_STRING_new());

    ExpectNull(ret = wolfSSL_i2s_ASN1_STRING(NULL, NULL));
    XFREE(ret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ret = NULL;
    /* No data. */
    ExpectNull(ret = wolfSSL_i2s_ASN1_STRING(NULL, str));
    XFREE(ret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ret = NULL;

    ExpectIntEQ(ASN1_STRING_set(str, data, 0), 1);
    ExpectNotNull(ret = wolfSSL_i2s_ASN1_STRING(NULL, str));
    XFREE(ret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    ret = NULL;

    ExpectIntEQ(ASN1_STRING_set(str, data, -1), 1);
    /* No type. */
    ExpectNotNull(ret = wolfSSL_i2s_ASN1_STRING(NULL, str));
    XFREE(ret, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    ASN1_STRING_free(str);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_STRING_canon(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_TEST_STATIC_BUILD)
#if !defined(NO_CERTS) && (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
    defined(OPENSSL_EXTRA_X509_SMALL))
    WOLFSSL_ASN1_STRING* orig = NULL;
    WOLFSSL_ASN1_STRING* canon = NULL;
    const char* data = "test_wolfSSL_ASN1_STRING_canon";
    const char* whitespaceOnly = "\t\r\n";
    const char* modData = "  \x01\f\t\x02\r\n\v\xff\nTt \n";
    const char* canonData = "\x01 \x02 \xff tt";
    const char longData[] =
        "This string must be longer than CTC_NAME_SIZE that is defined as 64.";

    ExpectNotNull(orig = ASN1_STRING_new());
    ExpectNotNull(canon = ASN1_STRING_new());

    /* Invalid parameter testing. */
    ExpectIntEQ(wolfSSL_ASN1_STRING_canon(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_ASN1_STRING_canon(canon, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_ASN1_STRING_canon(NULL, orig), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_ASN1_STRING_canon(canon, orig), 1);
    ExpectIntEQ(ASN1_STRING_cmp(orig, canon), 0);

    ExpectIntEQ(ASN1_STRING_set(orig, longData, (int)XSTRLEN(data)), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_canon(canon, orig), 1);
    ExpectIntEQ(ASN1_STRING_cmp(orig, canon), 0);

    ExpectIntEQ(ASN1_STRING_set(orig, data, (int)XSTRLEN(data)), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_canon(canon, orig), 1);
    ExpectIntEQ(ASN1_STRING_cmp(orig, canon), 0);

    ASN1_STRING_free(orig);
    orig = NULL;

    ExpectNotNull(orig = ASN1_STRING_type_new(MBSTRING_UTF8));
    ExpectIntEQ(ASN1_STRING_set(orig, modData, 15), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_canon(canon, orig), 1);
    ExpectIntEQ(ASN1_STRING_set(orig, canonData, 8), 1);
    ExpectIntEQ(ASN1_STRING_cmp(orig, canon), 0);
    ASN1_STRING_free(orig);
    orig = NULL;

    ExpectNotNull(orig = ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING));
    ExpectIntEQ(ASN1_STRING_set(orig, whitespaceOnly, 3), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_canon(canon, orig), 1);
    ASN1_STRING_free(orig);
    orig = NULL;
    ExpectNotNull(orig = ASN1_STRING_type_new(MBSTRING_UTF8));
    ExpectIntEQ(ASN1_STRING_cmp(orig, canon), 0);

    ASN1_STRING_free(orig);
    ASN1_STRING_free(canon);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_STRING_print(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_ASN) && !defined(NO_CERTS) && \
    !defined(NO_BIO)
    ASN1_STRING* asnStr = NULL;
    const char HELLO_DATA[]= \
                      {'H','e','l','l','o',' ','w','o','l','f','S','S','L','!'};
    #define MAX_UNPRINTABLE_CHAR 32
    #define MAX_BUF 255
    unsigned char unprintableData[MAX_UNPRINTABLE_CHAR + sizeof(HELLO_DATA)];
    unsigned char expected[sizeof(unprintableData)+1];
    unsigned char rbuf[MAX_BUF];
    BIO *bio = NULL;
    int p_len;
    int i;

    /* setup */

    for (i = 0; i < (int)sizeof(HELLO_DATA); i++) {
        unprintableData[i]  = (unsigned char)HELLO_DATA[i];
        expected[i]         = (unsigned char)HELLO_DATA[i];
    }

    for (i = 0; i < (int)MAX_UNPRINTABLE_CHAR; i++) {
        unprintableData[sizeof(HELLO_DATA)+i] = i;

        if (i == (int)'\n' || i == (int)'\r')
            expected[sizeof(HELLO_DATA)+i] = i;
        else
            expected[sizeof(HELLO_DATA)+i] = '.';
    }

    unprintableData[sizeof(unprintableData)-1] = '\0';
    expected[sizeof(expected)-1] = '\0';

    XMEMSET(rbuf, 0, MAX_BUF);
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(BIO_set_write_buf_size(bio, MAX_BUF), 0);

    ExpectNotNull(asnStr = ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
    ExpectIntEQ(ASN1_STRING_set(asnStr,(const void*)unprintableData,
            (int)sizeof(unprintableData)), 1);
    /* test */
    ExpectIntEQ(wolfSSL_ASN1_STRING_print(NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print(bio, NULL), 0);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print(NULL, asnStr), 0);
    ExpectIntEQ(p_len = wolfSSL_ASN1_STRING_print(bio, asnStr), 46);
    ExpectIntEQ(BIO_read(bio, (void*)rbuf, 46), 46);

    ExpectStrEQ((char*)rbuf, (const char*)expected);

    BIO_free(bio);
    bio = NULL;

    ExpectNotNull(bio = BIO_new(wolfSSL_BIO_s_fixed_mem()));
    ExpectIntEQ(BIO_set_write_buf_size(bio, 1), 1);
    /* Ensure there is 0 bytes available to write into. */
    ExpectIntEQ(BIO_write(bio, rbuf, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print(bio, asnStr), 0);
    ExpectIntEQ(BIO_set_write_buf_size(bio, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print(bio, asnStr), 0);
    ExpectIntEQ(BIO_set_write_buf_size(bio, 45), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print(bio, asnStr), 0);
    BIO_free(bio);

    ASN1_STRING_free(asnStr);
#endif /* OPENSSL_EXTRA && !NO_ASN && !NO_CERTS && !NO_BIO */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_STRING_print_ex(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && !defined(NO_BIO)
    ASN1_STRING* asn_str = NULL;
    const char data[] = "Hello wolfSSL!";
    ASN1_STRING* esc_str = NULL;
    const char esc_data[] = "a+;<>";
    ASN1_STRING* neg_int = NULL;
    const char neg_int_data[] = "\xff";
    ASN1_STRING* neg_enum = NULL;
    const char neg_enum_data[] = "\xff";
    BIO *bio = NULL;
    BIO *fixed = NULL;
    unsigned long flags;
    int p_len;
    unsigned char rbuf[255];

    /* setup */
    XMEMSET(rbuf, 0, 255);
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(BIO_set_write_buf_size(bio, 255), 0);
    ExpectNotNull(fixed = BIO_new(wolfSSL_BIO_s_fixed_mem()));

    ExpectNotNull(asn_str = ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
    ExpectIntEQ(ASN1_STRING_set(asn_str, (const void*)data, sizeof(data)), 1);
    ExpectNotNull(esc_str = ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
    ExpectIntEQ(ASN1_STRING_set(esc_str, (const void*)esc_data,
        sizeof(esc_data)), 1);
    ExpectNotNull(neg_int = ASN1_STRING_type_new(V_ASN1_NEG_INTEGER));
    ExpectIntEQ(ASN1_STRING_set(neg_int, (const void*)neg_int_data,
        sizeof(neg_int_data) - 1), 1);
    ExpectNotNull(neg_enum = ASN1_STRING_type_new(V_ASN1_NEG_ENUMERATED));
    ExpectIntEQ(ASN1_STRING_set(neg_enum, (const void*)neg_enum_data,
        sizeof(neg_enum_data) - 1), 1);

    /* Invalid parameter testing. */
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(NULL, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(bio, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(NULL, asn_str, 0), 0);

    /* no flags */
    XMEMSET(rbuf, 0, 255);
    flags = 0;
    ExpectIntEQ(p_len = wolfSSL_ASN1_STRING_print_ex(bio, asn_str, flags), 15);
    ExpectIntEQ(BIO_read(bio, (void*)rbuf, 15), 15);
    ExpectStrEQ((char*)rbuf, "Hello wolfSSL!");
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    /* Ensure there is 0 bytes available to write into. */
    ExpectIntEQ(BIO_write(fixed, rbuf, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 14), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);

    /* RFC2253 Escape */
    XMEMSET(rbuf, 0, 255);
    flags = ASN1_STRFLGS_ESC_2253;
    ExpectIntEQ(p_len = wolfSSL_ASN1_STRING_print_ex(bio, esc_str, flags), 9);
    ExpectIntEQ(BIO_read(bio, (void*)rbuf, 9), 9);
    ExpectStrEQ((char*)rbuf, "a\\+\\;\\<\\>");
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    /* Ensure there is 0 bytes available to write into. */
    ExpectIntEQ(BIO_write(fixed, rbuf, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, esc_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, esc_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 8), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, esc_str, flags), 0);

    /* Show type */
    XMEMSET(rbuf, 0, 255);
    flags = ASN1_STRFLGS_SHOW_TYPE;
    ExpectIntEQ(p_len = wolfSSL_ASN1_STRING_print_ex(bio, asn_str, flags), 28);
    ExpectIntEQ(BIO_read(bio, (void*)rbuf, 28), 28);
    ExpectStrEQ((char*)rbuf, "OCTET STRING:Hello wolfSSL!");
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    /* Ensure there is 0 bytes available to write into. */
    ExpectIntEQ(BIO_write(fixed, rbuf, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 12), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 27), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);

    /* Dump All */
    XMEMSET(rbuf, 0, 255);
    flags = ASN1_STRFLGS_DUMP_ALL;
    ExpectIntEQ(p_len = wolfSSL_ASN1_STRING_print_ex(bio, asn_str, flags), 31);
    ExpectIntEQ(BIO_read(bio, (void*)rbuf, 31), 31);
    ExpectStrEQ((char*)rbuf, "#48656C6C6F20776F6C6653534C2100");
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    /* Ensure there is 0 bytes available to write into. */
    ExpectIntEQ(BIO_write(fixed, rbuf, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 30), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);

    /* Dump Der */
    XMEMSET(rbuf, 0, 255);
    flags = ASN1_STRFLGS_DUMP_ALL | ASN1_STRFLGS_DUMP_DER;
    ExpectIntEQ(p_len = wolfSSL_ASN1_STRING_print_ex(bio, asn_str, flags), 35);
    ExpectIntEQ(BIO_read(bio, (void*)rbuf, 35), 35);
    ExpectStrEQ((char*)rbuf, "#040F48656C6C6F20776F6C6653534C2100");
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    /* Ensure there is 0 bytes available to write into. */
    ExpectIntEQ(BIO_write(fixed, rbuf, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 2), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 30), 1);
    ExpectIntEQ(wolfSSL_ASN1_STRING_print_ex(fixed, asn_str, flags), 0);

    /* Dump All + Show type */
    XMEMSET(rbuf, 0, 255);
    flags = ASN1_STRFLGS_DUMP_ALL | ASN1_STRFLGS_SHOW_TYPE;
    ExpectIntEQ(p_len = wolfSSL_ASN1_STRING_print_ex(bio, asn_str, flags), 44);
    ExpectIntEQ(BIO_read(bio, (void*)rbuf, 44), 44);
    ExpectStrEQ((char*)rbuf, "OCTET STRING:#48656C6C6F20776F6C6653534C2100");

    /* Dump All + Show type - Negative Integer. */
    XMEMSET(rbuf, 0, 255);
    flags = ASN1_STRFLGS_DUMP_ALL | ASN1_STRFLGS_SHOW_TYPE;
    ExpectIntEQ(p_len = wolfSSL_ASN1_STRING_print_ex(bio, neg_int, flags), 11);
    ExpectIntEQ(BIO_read(bio, (void*)rbuf, 11), 11);
    ExpectStrEQ((char*)rbuf, "INTEGER:#FF");

    /* Dump All + Show type - Negative Enumerated. */
    XMEMSET(rbuf, 0, 255);
    flags = ASN1_STRFLGS_DUMP_ALL | ASN1_STRFLGS_SHOW_TYPE;
    ExpectIntEQ(p_len = wolfSSL_ASN1_STRING_print_ex(bio, neg_enum, flags), 14);
    ExpectIntEQ(BIO_read(bio, (void*)rbuf, 14), 14);
    ExpectStrEQ((char*)rbuf, "ENUMERATED:#FF");

    BIO_free(fixed);
    BIO_free(bio);
    ASN1_STRING_free(asn_str);
    ASN1_STRING_free(esc_str);
    ASN1_STRING_free(neg_int);
    ASN1_STRING_free(neg_enum);

    ExpectStrEQ(wolfSSL_ASN1_tag2str(-1), "(unknown)");
    ExpectStrEQ(wolfSSL_ASN1_tag2str(31), "(unknown)");
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_UNIVERSALSTRING_to_string(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_ASN)
    ASN1_STRING* asn1str_test = NULL;
    ASN1_STRING* asn1str_answer = NULL;
    /* Each character is encoded using 4 bytes */
    char input[] = {
            0, 0, 0, 'T',
            0, 0, 0, 'e',
            0, 0, 0, 's',
            0, 0, 0, 't',
    };
    char output[] = "Test";
    char badInput[] = {
            1, 0, 0, 'T',
            0, 1, 0, 'e',
            0, 0, 1, 's',
    };

    ExpectIntEQ(ASN1_UNIVERSALSTRING_to_string(NULL), 0);
    /* Test wrong type. */
    ExpectNotNull(asn1str_test = ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
    ExpectIntEQ(ASN1_UNIVERSALSTRING_to_string(asn1str_test), 0);
    ASN1_STRING_free(asn1str_test);
    asn1str_test = NULL;

    ExpectNotNull(asn1str_test = ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING));

    /* Test bad length. */
    ExpectIntEQ(ASN1_STRING_set(asn1str_test, input, sizeof(input) - 1), 1);
    ExpectIntEQ(ASN1_UNIVERSALSTRING_to_string(asn1str_test), 0);
    /* Test bad input. */
    ExpectIntEQ(ASN1_STRING_set(asn1str_test, badInput + 0, 4), 1);
    ExpectIntEQ(ASN1_UNIVERSALSTRING_to_string(asn1str_test), 0);
    ExpectIntEQ(ASN1_STRING_set(asn1str_test, badInput + 4, 4), 1);
    ExpectIntEQ(ASN1_UNIVERSALSTRING_to_string(asn1str_test), 0);
    ExpectIntEQ(ASN1_STRING_set(asn1str_test, badInput + 8, 4), 1);
    ExpectIntEQ(ASN1_UNIVERSALSTRING_to_string(asn1str_test), 0);

    ExpectIntEQ(ASN1_STRING_set(asn1str_test, input, sizeof(input)), 1);
    ExpectIntEQ(ASN1_UNIVERSALSTRING_to_string(asn1str_test), 1);

    ExpectNotNull(
        asn1str_answer = ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING));
    ExpectIntEQ(ASN1_STRING_set(asn1str_answer, output, sizeof(output)-1), 1);

    ExpectIntEQ(ASN1_STRING_cmp(asn1str_test, asn1str_answer), 0);

    ASN1_STRING_free(asn1str_test);
    ASN1_STRING_free(asn1str_answer);
#endif /* OPENSSL_ALL && !NO_ASN */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_GENERALIZEDTIME_free(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
    WOLFSSL_ASN1_GENERALIZEDTIME* asn1_gtime = NULL;

    ExpectNotNull(asn1_gtime = ASN1_GENERALIZEDTIME_new());
    if (asn1_gtime != NULL)
        XMEMCPY(asn1_gtime->data, "20180504123500Z", ASN_GENERALIZED_TIME_SIZE);
    ASN1_GENERALIZEDTIME_free(asn1_gtime);
#endif /* OPENSSL_EXTRA && !NO_ASN_TIME */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_GENERALIZEDTIME_print(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) && !defined(NO_BIO)
    WOLFSSL_ASN1_GENERALIZEDTIME* gtime = NULL;
    BIO* bio = NULL;
    unsigned char buf[24];
    int i;

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    BIO_set_write_buf_size(bio, 24);

    ExpectNotNull(gtime = ASN1_GENERALIZEDTIME_new());
    /* Type not set. */
    ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, gtime), 0);
    ExpectIntEQ(wolfSSL_ASN1_TIME_set_string(gtime, "20180504123500Z"), 1);

    /* Invalid parameters testing. */
    ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(NULL, gtime), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, gtime), 1);
    ExpectIntEQ(BIO_read(bio, buf, sizeof(buf)), 20);
    ExpectIntEQ(XMEMCMP(buf, "May 04 12:35:00 2018", 20), 0);

    BIO_free(bio);
    bio = NULL;

    ExpectNotNull(bio = BIO_new(wolfSSL_BIO_s_fixed_mem()));
    ExpectIntEQ(BIO_set_write_buf_size(bio, 1), 1);
    /* Ensure there is 0 bytes available to write into. */
    ExpectIntEQ(BIO_write(bio, buf, 1), 1);
    ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, gtime), 0);
    for (i = 1; i < 20; i++) {
        ExpectIntEQ(BIO_set_write_buf_size(bio, i), 1);
        ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, gtime), 0);
    }
    BIO_free(bio);

    wolfSSL_ASN1_GENERALIZEDTIME_free(gtime);
#endif /* OPENSSL_EXTRA && !NO_ASN_TIME && !NO_BIO */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_TIME(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
    WOLFSSL_ASN1_TIME* asn_time = NULL;
    unsigned char *data = NULL;

    ExpectNotNull(asn_time = ASN1_TIME_new());

#ifndef NO_WOLFSSL_STUB
    ExpectNotNull(ASN1_TIME_set(asn_time, 1));
#endif
    ExpectIntEQ(ASN1_TIME_set_string(NULL, NULL), 0);
    ExpectIntEQ(ASN1_TIME_set_string(asn_time, NULL), 0);
    ExpectIntEQ(ASN1_TIME_set_string(NULL,
        "String longer than CTC_DATA_SIZE that is 32 bytes"), 0);
    ExpectIntEQ(ASN1_TIME_set_string(NULL, "101219181011Z"), 1);
    ExpectIntEQ(ASN1_TIME_set_string(asn_time, "101219181011Z"), 1);

    ExpectIntEQ(wolfSSL_ASN1_TIME_get_length(NULL), 0);
    ExpectIntEQ(wolfSSL_ASN1_TIME_get_length(asn_time), ASN_UTC_TIME_SIZE - 1);
    ExpectNull(wolfSSL_ASN1_TIME_get_data(NULL));
    ExpectNotNull(data = wolfSSL_ASN1_TIME_get_data(asn_time));
    ExpectIntEQ(XMEMCMP(data, "101219181011Z", 14), 0);

    ExpectIntEQ(ASN1_TIME_check(NULL), 0);
    ExpectIntEQ(ASN1_TIME_check(asn_time), 1);

    ExpectIntEQ(ASN1_TIME_set_string_X509(asn_time, "101219181011Z"), 1);
    ExpectIntEQ(ASN1_TIME_set_string_X509(asn_time, "101219181011Za"), 0);

    ASN1_TIME_free(asn_time);
    ASN1_TIME_free(NULL);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_TIME_to_string(void)
{
    EXPECT_DECLS;
#ifndef NO_ASN_TIME
#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \
    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
    WOLFSSL_ASN1_TIME* t = NULL;
    char buf[ASN_GENERALIZED_TIME_SIZE];

    ExpectNotNull((t = ASN1_TIME_new()));
    ExpectIntEQ(ASN1_TIME_set_string(t, "030222211515Z"), 1);

    /* Invalid parameter testing. */
    ExpectNull(ASN1_TIME_to_string(NULL, NULL, 4));
    ExpectNull(ASN1_TIME_to_string(t, NULL, 4));
    ExpectNull(ASN1_TIME_to_string(NULL, buf, 4));
    ExpectNull(ASN1_TIME_to_string(NULL, NULL, 5));
    ExpectNull(ASN1_TIME_to_string(NULL, buf, 5));
    ExpectNull(ASN1_TIME_to_string(t, NULL, 5));
    ExpectNull(ASN1_TIME_to_string(t, buf, 4));
    /* Buffer needs to be longer than minimum of 5 characters. */
    ExpectNull(ASN1_TIME_to_string(t, buf, 5));

    ASN1_TIME_free(t);
#endif
#endif /* NO_ASN_TIME */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_TIME_diff_compare(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
    ASN1_TIME* fromTime = NULL;
    ASN1_TIME* closeToTime = NULL;
    ASN1_TIME* toTime = NULL;
    ASN1_TIME* invalidTime = NULL;
    int daysDiff = 0;
    int secsDiff = 0;

    ExpectNotNull((fromTime = ASN1_TIME_new()));
    /* Feb 22, 2003, 21:15:15 */
    ExpectIntEQ(ASN1_TIME_set_string(fromTime, "030222211515Z"), 1);
    ExpectNotNull((closeToTime = ASN1_TIME_new()));
    /* Feb 22, 2003, 21:16:15 */
    ExpectIntEQ(ASN1_TIME_set_string(closeToTime, "030222211615Z"), 1);
    ExpectNotNull((toTime = ASN1_TIME_new()));
    /* Dec 19, 2010, 18:10:11 */
    ExpectIntEQ(ASN1_TIME_set_string(toTime, "101219181011Z"), 1);
    ExpectNotNull((invalidTime = ASN1_TIME_new()));
    /* Dec 19, 2010, 18:10:11 but 'U' instead of 'Z' which is invalid. */
    ExpectIntEQ(ASN1_TIME_set_string(invalidTime, "102519181011U"), 1);

    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, fromTime, invalidTime), 0);
    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, invalidTime, toTime), 0);

    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, fromTime, toTime), 1);

    /* Error conditions. */
    ExpectIntEQ(ASN1_TIME_diff(NULL, &secsDiff, fromTime, toTime), 0);
    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, NULL, fromTime, toTime), 0);

    /* If both times are NULL, difference is 0. */
    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, NULL, NULL), 1);
    ExpectIntEQ(daysDiff, 0);
    ExpectIntEQ(secsDiff, 0);

    /* If one time is NULL, it defaults to the current time. */
    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, NULL, toTime), 1);
    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, fromTime, NULL), 1);

    /* Normal operation. Both times non-NULL. */
    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, fromTime, toTime), 1);
    ExpectIntEQ(daysDiff, 2856);
    ExpectIntEQ(secsDiff, 75296);
    /* Swapping the times should return negative values. */
    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, toTime, fromTime), 1);
    ExpectIntEQ(daysDiff, -2856);
    ExpectIntEQ(secsDiff, -75296);

    /* Compare with invalid time string. */
    ExpectIntEQ(ASN1_TIME_compare(fromTime, invalidTime), -2);
    ExpectIntEQ(ASN1_TIME_compare(invalidTime, toTime), -2);
    /* Compare with days difference of 0. */
    ExpectIntEQ(ASN1_TIME_compare(fromTime, closeToTime), -1);
    ExpectIntEQ(ASN1_TIME_compare(closeToTime, fromTime), 1);
    /* Days and seconds differences not 0. */
    ExpectIntEQ(ASN1_TIME_compare(fromTime, toTime), -1);
    ExpectIntEQ(ASN1_TIME_compare(toTime, fromTime), 1);
    /* Same time. */
    ExpectIntEQ(ASN1_TIME_compare(fromTime, fromTime), 0);

    /* Compare regression test: No seconds difference, just difference in days.
     */
    ASN1_TIME_set_string(fromTime, "19700101000000Z");
    ASN1_TIME_set_string(toTime, "19800101000000Z");
    ExpectIntEQ(ASN1_TIME_compare(fromTime, toTime), -1);
    ExpectIntEQ(ASN1_TIME_compare(toTime, fromTime), 1);
    ExpectIntEQ(ASN1_TIME_compare(fromTime, fromTime), 0);

    /* Edge case with Unix epoch. */
    ExpectNotNull(ASN1_TIME_set_string(fromTime, "19700101000000Z"));
    ExpectNotNull(ASN1_TIME_set_string(toTime, "19800101000000Z"));
    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, fromTime, toTime), 1);
    ExpectIntEQ(daysDiff, 3652);
    ExpectIntEQ(secsDiff, 0);

    /* Edge case with year > 2038 (year 2038 problem). */
    ExpectNotNull(ASN1_TIME_set_string(toTime, "99991231235959Z"));
    ExpectIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, fromTime, toTime), 1);
    ExpectIntEQ(daysDiff, 2932896);
    ExpectIntEQ(secsDiff, 86399);

    ASN1_TIME_free(fromTime);
    ASN1_TIME_free(closeToTime);
    ASN1_TIME_free(toTime);
    ASN1_TIME_free(invalidTime);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_TIME_adj(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) && \
    !defined(USER_TIME) && !defined(TIME_OVERRIDES)
    const int year = 365*24*60*60;
    const int day  = 24*60*60;
    const int hour = 60*60;
    const int mini = 60;
    const byte asn_utc_time = ASN_UTC_TIME;
#if !defined(TIME_T_NOT_64BIT) && !defined(NO_64BIT)
    const byte asn_gen_time = ASN_GENERALIZED_TIME;
#endif
    WOLFSSL_ASN1_TIME* asn_time = NULL;
    WOLFSSL_ASN1_TIME* s = NULL;
    int offset_day;
    long offset_sec;
    char date_str[CTC_DATE_SIZE + 1];
    time_t t;

    ExpectNotNull(s = wolfSSL_ASN1_TIME_new());
    /* UTC notation test */
    /* 2000/2/15 20:30:00 */
    t = (time_t)30 * year + 45 * day + 20 * hour + 30 * mini + 7 * day;
    offset_day = 7;
    offset_sec = 45 * mini;
    /* offset_sec = -45 * min;*/
    ExpectNotNull(asn_time =
            wolfSSL_ASN1_TIME_adj(s, t, offset_day, offset_sec));
    ExpectTrue(asn_time->type == asn_utc_time);
    ExpectNotNull(XSTRNCPY(date_str, (const char*)&asn_time->data,
        CTC_DATE_SIZE));
    date_str[CTC_DATE_SIZE] = '\0';
    ExpectIntEQ(0, XMEMCMP(date_str, "000222211500Z", 13));

    /* negative offset */
    offset_sec = -45 * mini;
    asn_time = wolfSSL_ASN1_TIME_adj(s, t, offset_day, offset_sec);
    ExpectNotNull(asn_time);
    ExpectTrue(asn_time->type == asn_utc_time);
    ExpectNotNull(XSTRNCPY(date_str, (const char*)&asn_time->data,
        CTC_DATE_SIZE));
    date_str[CTC_DATE_SIZE] = '\0';
    ExpectIntEQ(0, XMEMCMP(date_str, "000222194500Z", 13));

    XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
    s = NULL;
    XMEMSET(date_str, 0, sizeof(date_str));

    /* Generalized time will overflow time_t if not long */
#if !defined(TIME_T_NOT_64BIT) && !defined(NO_64BIT)
    s = (WOLFSSL_ASN1_TIME*)XMALLOC(sizeof(WOLFSSL_ASN1_TIME), NULL,
                                    DYNAMIC_TYPE_OPENSSL);
    /* GeneralizedTime notation test */
    /* 2055/03/01 09:00:00 */
    t = (time_t)85 * year + 59 * day + 9 * hour + 21 * day;
        offset_day = 12;
        offset_sec = 10 * mini;
    ExpectNotNull(asn_time = wolfSSL_ASN1_TIME_adj(s, t, offset_day,
        offset_sec));
    ExpectTrue(asn_time->type == asn_gen_time);
    ExpectNotNull(XSTRNCPY(date_str, (const char*)&asn_time->data,
        CTC_DATE_SIZE));
    date_str[CTC_DATE_SIZE] = '\0';
    ExpectIntEQ(0, XMEMCMP(date_str, "20550313091000Z", 15));

    XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
    s = NULL;
    XMEMSET(date_str, 0, sizeof(date_str));
#endif /* !TIME_T_NOT_64BIT && !NO_64BIT */

    /* if WOLFSSL_ASN1_TIME struct is not allocated */
    s = NULL;

    t = (time_t)30 * year + 45 * day + 20 * hour + 30 * mini + 15 + 7 * day;
    offset_day = 7;
    offset_sec = 45 * mini;
    ExpectNotNull(asn_time = wolfSSL_ASN1_TIME_adj(s, t, offset_day,
        offset_sec));
    ExpectTrue(asn_time->type == asn_utc_time);
    ExpectNotNull(XSTRNCPY(date_str, (const char*)&asn_time->data,
        CTC_DATE_SIZE));
    date_str[CTC_DATE_SIZE] = '\0';
    ExpectIntEQ(0, XMEMCMP(date_str, "000222211515Z", 13));
    XFREE(asn_time, NULL, DYNAMIC_TYPE_OPENSSL);
    asn_time = NULL;

    ExpectNotNull(asn_time = wolfSSL_ASN1_TIME_adj(NULL, t, offset_day,
        offset_sec));
    ExpectTrue(asn_time->type == asn_utc_time);
    ExpectNotNull(XSTRNCPY(date_str, (const char*)&asn_time->data,
        CTC_DATE_SIZE));
    date_str[CTC_DATE_SIZE] = '\0';
    ExpectIntEQ(0, XMEMCMP(date_str, "000222211515Z", 13));
    XFREE(asn_time, NULL, DYNAMIC_TYPE_OPENSSL);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_TIME_to_tm(void)
{
    EXPECT_DECLS;
#if (defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \
      defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || \
      defined(OPENSSL_ALL)) && !defined(NO_ASN_TIME)
    ASN1_TIME asnTime;
    struct tm tm;
    time_t testTime = 1683926567; /* Fri May 12 09:22:47 PM UTC 2023 */

    XMEMSET(&tm, 0, sizeof(struct tm));

    XMEMSET(&asnTime, 0, sizeof(ASN1_TIME));
    ExpectIntEQ(ASN1_TIME_set_string(&asnTime, "000222211515Z"), 1);
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, NULL), 1);
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, &tm), 1);

    ExpectIntEQ(tm.tm_sec, 15);
    ExpectIntEQ(tm.tm_min, 15);
    ExpectIntEQ(tm.tm_hour, 21);
    ExpectIntEQ(tm.tm_mday, 22);
    ExpectIntEQ(tm.tm_mon, 1);
    ExpectIntEQ(tm.tm_year, 100);
    ExpectIntEQ(tm.tm_isdst, 0);
#ifdef XMKTIME
    ExpectIntEQ(tm.tm_wday, 2);
    ExpectIntEQ(tm.tm_yday, 52);
#endif

    ExpectIntEQ(ASN1_TIME_set_string(&asnTime, "500222211515Z"), 1);
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, &tm), 1);
    ExpectIntEQ(tm.tm_year, 50);

    /* Get current time. */
    ExpectIntEQ(ASN1_TIME_to_tm(NULL, NULL), 0);
    ExpectIntEQ(ASN1_TIME_to_tm(NULL, &tm), 1);

    XMEMSET(&asnTime, 0, sizeof(ASN1_TIME));
    /* 0 length. */
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, &tm), 0);
    /* No type. */
    asnTime.length = 1;
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, &tm), 0);
    /* Not UTCTIME length. */
    asnTime.type = V_ASN1_UTCTIME;
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, &tm), 0);
    /* Not GENERALIZEDTIME length. */
    asnTime.type = V_ASN1_GENERALIZEDTIME;
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, &tm), 0);

    /* Not Zulu timezone. */
    ExpectIntEQ(ASN1_TIME_set_string(&asnTime, "000222211515U"), 1);
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, &tm), 0);
    ExpectIntEQ(ASN1_TIME_set_string(&asnTime, "20000222211515U"), 1);
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, &tm), 0);

#ifdef XMKTIME
    ExpectNotNull(ASN1_TIME_adj(&asnTime, testTime, 0, 0));
    ExpectIntEQ(ASN1_TIME_to_tm(&asnTime, &tm), 1);
    ExpectIntEQ(tm.tm_sec, 47);
    ExpectIntEQ(tm.tm_min, 22);
    ExpectIntEQ(tm.tm_hour, 21);
    ExpectIntEQ(tm.tm_mday, 12);
    ExpectIntEQ(tm.tm_mon, 4);
    ExpectIntEQ(tm.tm_year, 123);
    ExpectIntEQ(tm.tm_wday, 5);
    ExpectIntEQ(tm.tm_yday, 131);
    /* Confirm that when used with a tm struct from ASN1_TIME_adj, all other
       fields are zeroed out as expected. */
    ExpectIntEQ(tm.tm_isdst, 0);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_TIME_to_generalizedtime(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
    WOLFSSL_ASN1_TIME *t = NULL;
    WOLFSSL_ASN1_TIME *out = NULL;
    WOLFSSL_ASN1_TIME *gtime = NULL;
    int tlen = 0;
    unsigned char *data = NULL;

    ExpectNotNull(t = wolfSSL_ASN1_TIME_new());
    ExpectNull(wolfSSL_ASN1_TIME_to_generalizedtime(NULL, &out));
    /* type not set. */
    ExpectNull(wolfSSL_ASN1_TIME_to_generalizedtime(t, &out));
    XFREE(t, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    t = NULL;

    /* UTC Time test */
    ExpectNotNull(t = wolfSSL_ASN1_TIME_new());
    if (t != NULL) {
        XMEMSET(t->data, 0, ASN_GENERALIZED_TIME_SIZE);
        t->type = ASN_UTC_TIME;
        t->length = ASN_UTC_TIME_SIZE;
        XMEMCPY(t->data, "050727123456Z", ASN_UTC_TIME_SIZE);
    }

    ExpectIntEQ(tlen = wolfSSL_ASN1_TIME_get_length(t), ASN_UTC_TIME_SIZE);
    ExpectStrEQ((char*)(data = wolfSSL_ASN1_TIME_get_data(t)), "050727123456Z");

    out = NULL;
    ExpectNotNull(gtime = wolfSSL_ASN1_TIME_to_generalizedtime(t, &out));
    wolfSSL_ASN1_TIME_free(gtime);
    gtime = NULL;
    ExpectNotNull(out = wolfSSL_ASN1_TIME_new());
    ExpectNotNull(gtime = wolfSSL_ASN1_TIME_to_generalizedtime(t, &out));
    ExpectPtrEq(gtime, out);
    ExpectIntEQ(gtime->type, ASN_GENERALIZED_TIME);
    ExpectIntEQ(gtime->length, ASN_GENERALIZED_TIME_SIZE);
    ExpectStrEQ((char*)gtime->data, "20050727123456Z");

    /* Generalized Time test */
    ExpectNotNull(XMEMSET(t, 0, ASN_GENERALIZED_TIME_SIZE));
    ExpectNotNull(XMEMSET(out, 0, ASN_GENERALIZED_TIME_SIZE));
    ExpectNotNull(XMEMSET(data, 0, ASN_GENERALIZED_TIME_SIZE));
    if (t != NULL) {
        t->type = ASN_GENERALIZED_TIME;
        t->length = ASN_GENERALIZED_TIME_SIZE;
        XMEMCPY(t->data, "20050727123456Z", ASN_GENERALIZED_TIME_SIZE);
    }

    ExpectIntEQ(tlen = wolfSSL_ASN1_TIME_get_length(t),
        ASN_GENERALIZED_TIME_SIZE);
    ExpectStrEQ((char*)(data = wolfSSL_ASN1_TIME_get_data(t)),
        "20050727123456Z");
    ExpectNotNull(gtime = wolfSSL_ASN1_TIME_to_generalizedtime(t, &out));
    ExpectIntEQ(gtime->type, ASN_GENERALIZED_TIME);
    ExpectIntEQ(gtime->length, ASN_GENERALIZED_TIME_SIZE);
    ExpectStrEQ((char*)gtime->data, "20050727123456Z");

    /* UTC Time to Generalized Time 1900's test */
    ExpectNotNull(XMEMSET(t, 0, ASN_GENERALIZED_TIME_SIZE));
    ExpectNotNull(XMEMSET(out, 0, ASN_GENERALIZED_TIME_SIZE));
    ExpectNotNull(XMEMSET(data, 0, ASN_GENERALIZED_TIME_SIZE));
    if (t != NULL) {
        t->type = ASN_UTC_TIME;
        t->length = ASN_UTC_TIME_SIZE;
        XMEMCPY(t->data, "500727123456Z", ASN_UTC_TIME_SIZE);
    }

    ExpectNotNull(gtime = wolfSSL_ASN1_TIME_to_generalizedtime(t, &out));
    ExpectIntEQ(gtime->type, ASN_GENERALIZED_TIME);
    ExpectIntEQ(gtime->length, ASN_GENERALIZED_TIME_SIZE);
    ExpectStrEQ((char*)gtime->data, "19500727123456Z");
    XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    /* Null parameter test */
    ExpectNotNull(XMEMSET(t, 0, ASN_GENERALIZED_TIME_SIZE));
    gtime = NULL;
    out = NULL;
    if (t != NULL) {
        t->type = ASN_UTC_TIME;
        t->length = ASN_UTC_TIME_SIZE;
        XMEMCPY(t->data, "050727123456Z", ASN_UTC_TIME_SIZE);
    }
    ExpectNotNull(gtime = wolfSSL_ASN1_TIME_to_generalizedtime(t, NULL));
    ExpectIntEQ(gtime->type, ASN_GENERALIZED_TIME);
    ExpectIntEQ(gtime->length, ASN_GENERALIZED_TIME_SIZE);
    ExpectStrEQ((char*)gtime->data, "20050727123456Z");

    XFREE(gtime, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(t, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_TIME_print(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(NO_BIO) && \
    (defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \
     defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || \
     defined(OPENSSL_ALL)) && defined(USE_CERT_BUFFERS_2048) && \
    !defined(NO_ASN_TIME)
    BIO*  bio = NULL;
    BIO*  fixed = NULL;
    X509*  x509 = NULL;
    const unsigned char* der = client_cert_der_2048;
    ASN1_TIME* notAfter = NULL;
    ASN1_TIME* notBefore = NULL;
    unsigned char buf[25];

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectNotNull(fixed = BIO_new(wolfSSL_BIO_s_fixed_mem()));
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_buffer(der,
                sizeof_client_cert_der_2048, WOLFSSL_FILETYPE_ASN1));
    ExpectNotNull(notBefore = X509_get_notBefore(x509));

    ExpectIntEQ(ASN1_TIME_print(NULL, NULL), 0);
    ExpectIntEQ(ASN1_TIME_print(bio, NULL), 0);
    ExpectIntEQ(ASN1_TIME_print(NULL, notBefore), 0);

    ExpectIntEQ(ASN1_TIME_print(bio, notBefore), 1);
    ExpectIntEQ(BIO_read(bio, buf, sizeof(buf)), 24);
    ExpectIntEQ(XMEMCMP(buf, "Dec 13 22:19:28 2023 GMT", sizeof(buf) - 1), 0);

    /* Test BIO_write fails. */
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    /* Ensure there is 0 bytes available to write into. */
    ExpectIntEQ(BIO_write(fixed, buf, 1), 1);
    ExpectIntEQ(ASN1_TIME_print(fixed, notBefore), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 1), 1);
    ExpectIntEQ(ASN1_TIME_print(fixed, notBefore), 0);
    ExpectIntEQ(BIO_set_write_buf_size(fixed, 23), 1);
    ExpectIntEQ(ASN1_TIME_print(fixed, notBefore), 0);

    /* create a bad time and test results */
    ExpectNotNull(notAfter = X509_get_notAfter(x509));
    ExpectIntEQ(ASN1_TIME_check(notAfter), 1);
    if (EXPECT_SUCCESS()) {
        notAfter->data[8] = 0;
        notAfter->data[3] = 0;
    }
    ExpectIntNE(ASN1_TIME_print(bio, notAfter), 1);
    ExpectIntEQ(BIO_read(bio, buf, sizeof(buf)), 14);
    ExpectIntEQ(XMEMCMP(buf, "Bad time value", 14), 0);
    ExpectIntEQ(ASN1_TIME_check(notAfter), 0);

    BIO_free(bio);
    BIO_free(fixed);
    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_UTCTIME_print(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) && !defined(NO_BIO)
    BIO*  bio = NULL;
    ASN1_UTCTIME* utc = NULL;
    unsigned char buf[25];
    const char* validDate   = "190424111501Z";   /* UTC =   YYMMDDHHMMSSZ */
    const char* invalidDate = "190424111501X";   /* UTC =   YYMMDDHHMMSSZ */
    const char* genDate     = "20190424111501Z"; /* GEN = YYYYMMDDHHMMSSZ */

    /* Valid date */
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectNotNull(utc = (ASN1_UTCTIME*)XMALLOC(sizeof(ASN1_UTCTIME), NULL,
                                                           DYNAMIC_TYPE_ASN1));
    if (utc != NULL) {
        utc->type = ASN_UTC_TIME;
        utc->length = ASN_UTC_TIME_SIZE;
        XMEMCPY(utc->data, (byte*)validDate, ASN_UTC_TIME_SIZE);
    }

    ExpectIntEQ(ASN1_UTCTIME_print(NULL, NULL), 0);
    ExpectIntEQ(ASN1_UTCTIME_print(bio, NULL), 0);
    ExpectIntEQ(ASN1_UTCTIME_print(NULL, utc), 0);

    ExpectIntEQ(ASN1_UTCTIME_print(bio, utc), 1);
    ExpectIntEQ(BIO_read(bio, buf, sizeof(buf)), 24);
    ExpectIntEQ(XMEMCMP(buf, "Apr 24 11:15:01 2019 GMT", sizeof(buf)-1), 0);

    XMEMSET(buf, 0, sizeof(buf));
    BIO_free(bio);
    bio = NULL;

    /* Invalid format */
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    if (utc != NULL) {
        utc->type = ASN_UTC_TIME;
        utc->length = ASN_UTC_TIME_SIZE;
        XMEMCPY(utc->data, (byte*)invalidDate, ASN_UTC_TIME_SIZE);
    }
    ExpectIntEQ(ASN1_UTCTIME_print(bio, utc), 0);
    ExpectIntEQ(BIO_read(bio, buf, sizeof(buf)), 14);
    ExpectIntEQ(XMEMCMP(buf, "Bad time value", 14), 0);

    /* Invalid type */
    if (utc != NULL) {
        utc->type = ASN_GENERALIZED_TIME;
        utc->length = ASN_GENERALIZED_TIME_SIZE;
        XMEMCPY(utc->data, (byte*)genDate, ASN_GENERALIZED_TIME_SIZE);
    }
    ExpectIntEQ(ASN1_UTCTIME_print(bio, utc), 0);

    XFREE(utc, NULL, DYNAMIC_TYPE_ASN1);
    BIO_free(bio);
#endif /* OPENSSL_EXTRA && !NO_ASN_TIME && !NO_BIO */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ASN1_TYPE(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) || \
    defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
    WOLFSSL_ASN1_TYPE* t = NULL;
    WOLFSSL_ASN1_OBJECT* obj = NULL;
#ifndef NO_ASN_TIME
    WOLFSSL_ASN1_TIME* time = NULL;
#endif
    WOLFSSL_ASN1_STRING* str = NULL;
    unsigned char data[] = { 0x00 };

    ASN1_TYPE_set(NULL, V_ASN1_NULL, NULL);

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ASN1_TYPE_set(t, V_ASN1_EOC, NULL);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ASN1_TYPE_set(t, V_ASN1_NULL, NULL);
    ASN1_TYPE_set(t, V_ASN1_NULL, data);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ExpectNotNull(obj = wolfSSL_ASN1_OBJECT_new());
    ASN1_TYPE_set(t, V_ASN1_OBJECT, obj);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;

#ifndef NO_ASN_TIME
    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ExpectNotNull(time = wolfSSL_ASN1_TIME_new());
    ASN1_TYPE_set(t, V_ASN1_UTCTIME, time);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ExpectNotNull(time = wolfSSL_ASN1_TIME_new());
    ASN1_TYPE_set(t, V_ASN1_GENERALIZEDTIME, time);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;
#endif

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ExpectNotNull(str = wolfSSL_ASN1_STRING_new());
    ASN1_TYPE_set(t, V_ASN1_UTF8STRING, str);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ExpectNotNull(str = wolfSSL_ASN1_STRING_new());
    ASN1_TYPE_set(t, V_ASN1_PRINTABLESTRING, str);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ExpectNotNull(str = wolfSSL_ASN1_STRING_new());
    ASN1_TYPE_set(t, V_ASN1_T61STRING, str);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ExpectNotNull(str = wolfSSL_ASN1_STRING_new());
    ASN1_TYPE_set(t, V_ASN1_IA5STRING, str);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ExpectNotNull(str = wolfSSL_ASN1_STRING_new());
    ASN1_TYPE_set(t, V_ASN1_UNIVERSALSTRING, str);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;

    ExpectNotNull(t = wolfSSL_ASN1_TYPE_new());
    ExpectNotNull(str = wolfSSL_ASN1_STRING_new());
    ASN1_TYPE_set(t, V_ASN1_SEQUENCE, str);
    wolfSSL_ASN1_TYPE_free(t);
    t = NULL;
#endif
    return EXPECT_RESULT();
}

/* Testing code used in old dpp.c in hostap */
#if defined(OPENSSL_ALL) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
typedef struct {
    /* AlgorithmIdentifier ecPublicKey with optional parameters present
     * as an OID identifying the curve */
    X509_ALGOR *alg;
    /* Compressed format public key per ANSI X9.63 */
    ASN1_BIT_STRING *pub_key;
} DPP_BOOTSTRAPPING_KEY;

ASN1_SEQUENCE(DPP_BOOTSTRAPPING_KEY) = {
    ASN1_SIMPLE(DPP_BOOTSTRAPPING_KEY, alg, X509_ALGOR),
    ASN1_SIMPLE(DPP_BOOTSTRAPPING_KEY, pub_key, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(DPP_BOOTSTRAPPING_KEY)

IMPLEMENT_ASN1_FUNCTIONS(DPP_BOOTSTRAPPING_KEY)

typedef struct {
    int type;
    union {
        ASN1_BIT_STRING *str1;
        ASN1_BIT_STRING *str2;
        ASN1_BIT_STRING *str3;
    } d;
} ASN1_CHOICE_TEST;

ASN1_CHOICE(ASN1_CHOICE_TEST) = {
    ASN1_IMP(ASN1_CHOICE_TEST, d.str1, ASN1_BIT_STRING, 1),
    ASN1_IMP(ASN1_CHOICE_TEST, d.str2, ASN1_BIT_STRING, 2),
    ASN1_IMP(ASN1_CHOICE_TEST, d.str3, ASN1_BIT_STRING, 3)
} ASN1_CHOICE_END(ASN1_CHOICE_TEST)

IMPLEMENT_ASN1_FUNCTIONS(ASN1_CHOICE_TEST)

/* Test nested objects */
typedef struct {
    DPP_BOOTSTRAPPING_KEY* key;
    ASN1_INTEGER* asnNum;
    ASN1_INTEGER* expNum;
    STACK_OF(ASN1_GENERALSTRING) *strList;
    ASN1_CHOICE_TEST* str;
} TEST_ASN1_NEST1;

ASN1_SEQUENCE(TEST_ASN1_NEST1) = {
    ASN1_SIMPLE(TEST_ASN1_NEST1, key, DPP_BOOTSTRAPPING_KEY),
    ASN1_SIMPLE(TEST_ASN1_NEST1, asnNum, ASN1_INTEGER),
    ASN1_EXP(TEST_ASN1_NEST1, expNum, ASN1_INTEGER, 0),
    ASN1_EXP_SEQUENCE_OF(TEST_ASN1_NEST1, strList, ASN1_GENERALSTRING, 1),
    ASN1_SIMPLE(TEST_ASN1_NEST1, str, ASN1_CHOICE_TEST)
} ASN1_SEQUENCE_END(TEST_ASN1_NEST1)

IMPLEMENT_ASN1_FUNCTIONS(TEST_ASN1_NEST1)

typedef struct {
    ASN1_INTEGER* num;
    DPP_BOOTSTRAPPING_KEY* key;
    TEST_ASN1_NEST1* asn1_obj;
} TEST_ASN1_NEST2;

ASN1_SEQUENCE(TEST_ASN1_NEST2) = {
    ASN1_SIMPLE(TEST_ASN1_NEST2, num, ASN1_INTEGER),
    ASN1_SIMPLE(TEST_ASN1_NEST2, key, DPP_BOOTSTRAPPING_KEY),
    ASN1_SIMPLE(TEST_ASN1_NEST2, asn1_obj, TEST_ASN1_NEST1)
} ASN1_SEQUENCE_END(TEST_ASN1_NEST2)

IMPLEMENT_ASN1_FUNCTIONS(TEST_ASN1_NEST2)
/* End nested objects */

typedef struct {
    ASN1_INTEGER *integer;
} TEST_ASN1;

ASN1_SEQUENCE(TEST_ASN1) = {
    ASN1_SIMPLE(TEST_ASN1, integer, ASN1_INTEGER),
} ASN1_SEQUENCE_END(TEST_ASN1)

IMPLEMENT_ASN1_FUNCTIONS(TEST_ASN1)

typedef STACK_OF(ASN1_INTEGER) TEST_ASN1_ITEM;

ASN1_ITEM_TEMPLATE(TEST_ASN1_ITEM) =
        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, MemName, ASN1_INTEGER)
ASN1_ITEM_TEMPLATE_END(TEST_ASN1_ITEM)

IMPLEMENT_ASN1_FUNCTIONS(TEST_ASN1_ITEM)
#endif

static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void)
{
    EXPECT_DECLS;
    /* Testing code used in dpp.c in hostap */
#if defined(OPENSSL_ALL) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    EC_KEY *eckey = NULL;
    EVP_PKEY *key = NULL;
    size_t len = 0;
    unsigned char *der = NULL;
    unsigned char *der2 = NULL;
    const unsigned char *tmp = NULL;
    DPP_BOOTSTRAPPING_KEY *bootstrap = NULL, *bootstrap2 = NULL;
    const unsigned char *in = ecc_clikey_der_256;
    WOLFSSL_ASN1_OBJECT* ec_obj = NULL;
    WOLFSSL_ASN1_OBJECT* group_obj = NULL;
    const EC_GROUP *group = NULL;
    const EC_POINT *point = NULL;
    int nid;
    TEST_ASN1 *test_asn1 = NULL;
    TEST_ASN1 *test_asn1_2 = NULL;

    const unsigned char badObjDer[] = { 0x06, 0x00 };
    const unsigned char goodObjDer[] = {
        0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01
    };
    WOLFSSL_ASN1_ITEM emptyTemplate;

    XMEMSET(&emptyTemplate, 0, sizeof(WOLFSSL_ASN1_ITEM));

    ExpectNotNull(bootstrap = DPP_BOOTSTRAPPING_KEY_new());

    der = NULL;
    ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(NULL, &der), -1);
    ExpectIntEQ(wolfSSL_ASN1_item_i2d(bootstrap, &der, NULL), -1);
    ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), -1);

    ExpectNotNull(key = d2i_PrivateKey(EVP_PKEY_EC, NULL, &in,
                                       (long)sizeof_ecc_clikey_der_256));
    ExpectNotNull(eckey = EVP_PKEY_get1_EC_KEY(key));
    ExpectNotNull(group = EC_KEY_get0_group(eckey));
    ExpectNotNull(point = EC_KEY_get0_public_key(eckey));
    nid = EC_GROUP_get_curve_name(group);

    ec_obj = OBJ_nid2obj(EVP_PKEY_EC);
    group_obj = OBJ_nid2obj(nid);
    if ((ec_obj != NULL) && (group_obj != NULL)) {
        ExpectIntEQ(X509_ALGOR_set0(bootstrap->alg, ec_obj, V_ASN1_OBJECT,
            group_obj), 1);
        if (EXPECT_SUCCESS()) {
            ec_obj = NULL;
            group_obj = NULL;
        }
    }
    wolfSSL_ASN1_OBJECT_free(group_obj);
    wolfSSL_ASN1_OBJECT_free(ec_obj);
    ExpectIntEQ(EC_POINT_point2oct(group, point, 0, NULL, 0, NULL), 0);
#ifdef HAVE_COMP_KEY
    ExpectIntGT((len = EC_POINT_point2oct(
                                   group, point, POINT_CONVERSION_COMPRESSED,
                                   NULL, 0, NULL)), 0);
#else
    ExpectIntGT((len = EC_POINT_point2oct(
                                   group, point, POINT_CONVERSION_UNCOMPRESSED,
                                   NULL, 0, NULL)), 0);
#endif
    ExpectNotNull(der = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1));
#ifdef HAVE_COMP_KEY
    ExpectIntEQ(EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
                                   der, len-1, NULL), 0);
    ExpectIntEQ(EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
                                   der, len, NULL), len);
#else
    ExpectIntEQ(EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED,
                                   der, len-1, NULL), 0);
    ExpectIntEQ(EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED,
                                   der, len, NULL), len);
#endif
    if (EXPECT_SUCCESS()) {
        bootstrap->pub_key->data = der;
        bootstrap->pub_key->length = (int)len;
        /* Not actually used */
        bootstrap->pub_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
        bootstrap->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    }

    ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, NULL), 16+len);
    der = NULL;
    ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), 16+len);
    der2 = NULL;
#ifdef WOLFSSL_ASN_TEMPLATE
    tmp = der;
    ExpectNotNull(d2i_DPP_BOOTSTRAPPING_KEY(&bootstrap2, &tmp, 16+len));
    ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap2, &der2), 16+len);
    ExpectBufEQ(der, der2, 49);
#endif

    XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
    XFREE(der2, NULL, DYNAMIC_TYPE_ASN1);
    EVP_PKEY_free(key);
    EC_KEY_free(eckey);
    DPP_BOOTSTRAPPING_KEY_free(bootstrap);
    DPP_BOOTSTRAPPING_KEY_free(bootstrap2);
    bootstrap = NULL;
    DPP_BOOTSTRAPPING_KEY_free(NULL);

    /* Create bootstrap key with bad OBJECT_ID DER data, parameter that is
     * a NULL and an empty BIT_STRING. */
    ExpectNotNull(bootstrap = DPP_BOOTSTRAPPING_KEY_new());
    ExpectNotNull(bootstrap->alg->algorithm = wolfSSL_ASN1_OBJECT_new());
    if (EXPECT_SUCCESS()) {
        bootstrap->alg->algorithm->obj = badObjDer;
        bootstrap->alg->algorithm->objSz = (unsigned int)sizeof(badObjDer);
    }
    ExpectNotNull(bootstrap->alg->parameter = wolfSSL_ASN1_TYPE_new());
    if (EXPECT_SUCCESS()) {
        bootstrap->alg->parameter->type = V_ASN1_NULL;
        bootstrap->alg->parameter->value.ptr = NULL;
        bootstrap->pub_key->data = NULL;
        bootstrap->pub_key->length = 0;
        /* Not actually used */
        bootstrap->pub_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
        bootstrap->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    }
    /* Encode with bad OBJECT_ID. */
    der = NULL;
    ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), -1);

    /* Fix OBJECT_ID and encode with empty BIT_STRING. */
    if (EXPECT_SUCCESS()) {
        bootstrap->alg->algorithm->obj = goodObjDer;
        bootstrap->alg->algorithm->objSz = (unsigned int)sizeof(goodObjDer);
        bootstrap->alg->algorithm->grp = 2;
    }
    der = NULL;
    ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), 16);
    ExpectIntEQ(wolfSSL_ASN1_item_i2d(bootstrap, &der, &emptyTemplate), -1);
    XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
    DPP_BOOTSTRAPPING_KEY_free(bootstrap);

    /* Test integer */
    ExpectNotNull(test_asn1 = TEST_ASN1_new());
    der = NULL;
    ExpectIntEQ(ASN1_INTEGER_set(test_asn1->integer, 100), 1);
    ExpectIntEQ(i2d_TEST_ASN1(test_asn1, &der), 5);
    tmp = der;
    ExpectNotNull(d2i_TEST_ASN1(&test_asn1_2, &tmp, 5));
    der2 = NULL;
    ExpectIntEQ(i2d_TEST_ASN1(test_asn1_2, &der2), 5);
    ExpectBufEQ(der, der2, 5);
    XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
    XFREE(der2, NULL, DYNAMIC_TYPE_ASN1);
    TEST_ASN1_free(test_asn1);
    TEST_ASN1_free(test_asn1_2);

    /* Test integer cases. */
    ExpectNull(wolfSSL_ASN1_item_new(NULL));
    TEST_ASN1_free(NULL);

    /* Test nested asn1 objects */
    {
        TEST_ASN1_NEST2 *nested_asn1 = NULL;
        TEST_ASN1_NEST2 *nested_asn1_2 = NULL;
        int i;

        ExpectNotNull(nested_asn1 = TEST_ASN1_NEST2_new());
        /* Populate nested_asn1 with some random data */
        /* nested_asn1->num */
        ExpectIntEQ(ASN1_INTEGER_set(nested_asn1->num, 30003), 1);
        /* nested_asn1->key */
        ec_obj = OBJ_nid2obj(EVP_PKEY_EC);
        group_obj = OBJ_nid2obj(NID_secp256k1);
        ExpectIntEQ(X509_ALGOR_set0(nested_asn1->key->alg, ec_obj,
                V_ASN1_OBJECT, group_obj), 1);
        if (EXPECT_SUCCESS()) {
            ec_obj = NULL;
            group_obj = NULL;
        }
        else {
            wolfSSL_ASN1_OBJECT_free(ec_obj);
            wolfSSL_ASN1_OBJECT_free(group_obj);
        }
        ExpectIntEQ(ASN1_BIT_STRING_set_bit(nested_asn1->key->pub_key, 50, 1),
                1);
        /* nested_asn1->asn1_obj->key */
        ec_obj = OBJ_nid2obj(EVP_PKEY_EC);
        group_obj = OBJ_nid2obj(NID_secp256k1);
        ExpectIntEQ(X509_ALGOR_set0(nested_asn1->asn1_obj->key->alg, ec_obj,
                V_ASN1_OBJECT, group_obj), 1);
        if (EXPECT_SUCCESS()) {
            ec_obj = NULL;
            group_obj = NULL;
        }
        else {
            wolfSSL_ASN1_OBJECT_free(ec_obj);
            wolfSSL_ASN1_OBJECT_free(group_obj);
        }
        ExpectIntEQ(ASN1_BIT_STRING_set_bit(nested_asn1->asn1_obj->key->pub_key,
                500, 1), 1);
        /* nested_asn1->asn1_obj->asnNum */
        ExpectIntEQ(ASN1_INTEGER_set(nested_asn1->asn1_obj->asnNum, 666666), 1);
        /* nested_asn1->asn1_obj->expNum */
        ExpectIntEQ(ASN1_INTEGER_set(nested_asn1->asn1_obj->expNum, 22222), 1);
        /* nested_asn1->asn1_obj->strList */
        for (i = 10; i >= 0; i--) {
            ASN1_GENERALSTRING* genStr = NULL;
            char fmtStr[20];

            ExpectIntGT(snprintf(fmtStr, sizeof(fmtStr), "Bonjour #%d", i), 0);
            ExpectNotNull(genStr = ASN1_GENERALSTRING_new());
            ExpectIntEQ(ASN1_GENERALSTRING_set(genStr, fmtStr, -1), 1);
            ExpectIntGT(
                    sk_ASN1_GENERALSTRING_push(nested_asn1->asn1_obj->strList,
                            genStr), 0);
            if (EXPECT_FAIL()) {
                ASN1_GENERALSTRING_free(genStr);
            }
        }
        /* nested_asn1->asn1_obj->str */
        ExpectNotNull(nested_asn1->asn1_obj->str->d.str2
                = ASN1_BIT_STRING_new());
        ExpectIntEQ(ASN1_BIT_STRING_set_bit(nested_asn1->asn1_obj->str->d.str2,
                150, 1), 1);
        if (nested_asn1 != NULL) {
            nested_asn1->asn1_obj->str->type = 2;
        }

        der = NULL;
        ExpectIntEQ(i2d_TEST_ASN1_NEST2(nested_asn1, &der), 285);
#ifdef WOLFSSL_ASN_TEMPLATE
        tmp = der;
        ExpectNotNull(d2i_TEST_ASN1_NEST2(&nested_asn1_2, &tmp, 285));
        der2 = NULL;
        ExpectIntEQ(i2d_TEST_ASN1_NEST2(nested_asn1_2, &der2), 285);
        ExpectBufEQ(der, der2, 285);
        XFREE(der2, NULL, DYNAMIC_TYPE_ASN1);
#endif
        XFREE(der, NULL, DYNAMIC_TYPE_ASN1);

        TEST_ASN1_NEST2_free(nested_asn1);
        TEST_ASN1_NEST2_free(nested_asn1_2);
    }

    /* Test ASN1_ITEM_TEMPLATE */
    {
        TEST_ASN1_ITEM* asn1_item = NULL;
        TEST_ASN1_ITEM* asn1_item2 = NULL;
        int i;

        ExpectNotNull(asn1_item = TEST_ASN1_ITEM_new());
        for (i = 0; i < 11; i++) {
            ASN1_INTEGER* asn1_num = NULL;

            ExpectNotNull(asn1_num = ASN1_INTEGER_new());
            ExpectIntEQ(ASN1_INTEGER_set(asn1_num, i), 1);
            ExpectIntGT(wolfSSL_sk_insert(asn1_item, asn1_num, -1), 0);
            if (EXPECT_FAIL()) {
                ASN1_INTEGER_free(asn1_num);
            }
        }

        der = NULL;
        ExpectIntEQ(i2d_TEST_ASN1_ITEM(asn1_item, &der), 35);
        tmp = der;
        ExpectNotNull(d2i_TEST_ASN1_ITEM(&asn1_item2, &tmp, 35));
        der2 = NULL;
        ExpectIntEQ(i2d_TEST_ASN1_ITEM(asn1_item2, &der2), 35);
        ExpectBufEQ(der, der2, 35);
        XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
        XFREE(der2, NULL, DYNAMIC_TYPE_ASN1);

        TEST_ASN1_ITEM_free(asn1_item);
        TEST_ASN1_ITEM_free(asn1_item2);
    }

#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /* OPENSSL_ALL && HAVE_ECC && USE_CERT_BUFFERS_256 */
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2d_ASN1_TYPE(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    /* Taken from one of sssd's certs othernames */
    unsigned char str_bin[] = {
        0x04, 0x10, 0xa4, 0x9b, 0xc8, 0xf4, 0x85, 0x8e, 0x89, 0x4d, 0x85, 0x8d,
        0x27, 0xbd, 0x63, 0xaa, 0x93, 0x93
    };
    ASN1_TYPE* asn1type = NULL;
    unsigned char* der = NULL;

    /* Create ASN1_TYPE manually as we don't have a d2i version yet */
    {
        ASN1_STRING* str = NULL;
        ExpectNotNull(str = ASN1_STRING_type_new(V_ASN1_SEQUENCE));
        ExpectIntEQ(ASN1_STRING_set(str, str_bin, sizeof(str_bin)), 1);
        ExpectNotNull(asn1type = ASN1_TYPE_new());
        if (asn1type != NULL) {
            ASN1_TYPE_set(asn1type, V_ASN1_SEQUENCE, str);
        }
        else {
            ASN1_STRING_free(str);
        }
    }

    ExpectIntEQ(i2d_ASN1_TYPE(asn1type, NULL), sizeof(str_bin));
    ExpectIntEQ(i2d_ASN1_TYPE(asn1type, &der), sizeof(str_bin));
    ExpectBufEQ(der, str_bin, sizeof(str_bin));

    ASN1_TYPE_free(asn1type);
    XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2d_ASN1_SEQUENCE(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    /* Taken from one of sssd's certs othernames */
    unsigned char str_bin[] = {
      0x04, 0x10, 0xa4, 0x9b, 0xc8, 0xf4, 0x85, 0x8e, 0x89, 0x4d, 0x85, 0x8d,
      0x27, 0xbd, 0x63, 0xaa, 0x93, 0x93
    };
    ASN1_STRING* str = NULL;
    unsigned char* der = NULL;

    ExpectNotNull(str = ASN1_STRING_type_new(V_ASN1_SEQUENCE));
    ExpectIntEQ(ASN1_STRING_set(str, str_bin, sizeof(str_bin)), 1);
    ExpectIntEQ(i2d_ASN1_SEQUENCE(str, NULL), sizeof(str_bin));
    ExpectIntEQ(i2d_ASN1_SEQUENCE(str, &der), sizeof(str_bin));

    ASN1_STRING_free(str);
    XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
#endif
    return EXPECT_RESULT();
}

static int test_ASN1_strings(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    char text[] = "\0\0test string";
    unsigned char* der = NULL;
    ASN1_STRING* str = NULL;

    /* Set the length byte */
    text[1] = XSTRLEN(text + 2);

    /* GENERALSTRING */
    {
        const unsigned char* p = (const unsigned char*)text;
        text[0] = ASN_GENERALSTRING;
        ExpectNotNull(d2i_ASN1_GENERALSTRING(&str, &p, sizeof(text)));
        ExpectIntEQ(i2d_ASN1_GENERALSTRING(str, &der), 13);
        ASN1_STRING_free(str);
        str = NULL;
        XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
        der = NULL;
    }

    /* OCTET_STRING */
    {
        const unsigned char* p = (const unsigned char*)text;
        text[0] = ASN_OCTET_STRING;
        ExpectNotNull(d2i_ASN1_OCTET_STRING(&str, &p, sizeof(text)));
        ExpectIntEQ(i2d_ASN1_OCTET_STRING(str, &der), 13);
        ASN1_STRING_free(str);
        str = NULL;
        XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
        der = NULL;
    }

    /* UTF8STRING */
    {
        const unsigned char* p = (const unsigned char*)text;
        text[0] = ASN_UTF8STRING;
        ExpectNotNull(d2i_ASN1_UTF8STRING(&str, &p, sizeof(text)));
        ExpectIntEQ(i2d_ASN1_UTF8STRING(str, &der), 13);
        ASN1_STRING_free(str);
        str = NULL;
        XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
        der = NULL;
    }

#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_lhash(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_ALL
    const char testStr[] = "Like a true nature's child\n"
                           "We were born\n"
                           "Born to be wild";

#ifdef NO_SHA
    ExpectIntEQ(lh_strhash(testStr), 0xf9dc8a43);
#else
    ExpectIntEQ(lh_strhash(testStr), 0x5b7541dc);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_NAME(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
    !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA) && defined(WOLFSSL_CERT_GEN) && \
    (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
     defined(OPENSSL_EXTRA))
    X509* x509 = NULL;
    const unsigned char* c = NULL;
    unsigned char buf[4096];
    int bytes = 0;
    XFILE f = XBADFILE;
    const X509_NAME* a = NULL;
    const X509_NAME* b = NULL;
    X509_NAME* d2i_name = NULL;
    int sz = 0;
    unsigned char* tmp = NULL;
    char file[] = "./certs/ca-cert.der";
#ifndef OPENSSL_EXTRA_X509_SMALL
    byte empty[] = { /* CN=empty emailAddress= */
        0x30, 0x21, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03,
        0x55, 0x04, 0x03, 0x0C, 0x05, 0x65, 0x6D, 0x70,
        0x74, 0x79, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x09,
        0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09,
        0x01, 0x16, 0x00
    };
#endif

#ifndef OPENSSL_EXTRA_X509_SMALL
    /* test compile of deprecated function, returns 0 */
    ExpectIntEQ(CRYPTO_thread_id(), 0);
#endif

    ExpectNotNull(a = X509_NAME_new());
    X509_NAME_free((X509_NAME*)a);
    a = NULL;

    ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    c = buf;
    ExpectNotNull(x509 = wolfSSL_X509_d2i_ex(NULL, c, bytes, HEAP_HINT));

    /* test cmp function */
    ExpectNotNull(a = X509_get_issuer_name(x509));
    ExpectNotNull(b = X509_get_subject_name(x509));

#ifndef OPENSSL_EXTRA_X509_SMALL
    ExpectIntEQ(X509_NAME_cmp(a, b), 0); /* self signed should be 0 */
#endif

    tmp = buf;
    ExpectIntGT((sz = i2d_X509_NAME((X509_NAME*)a, &tmp)), 0);
    if (sz > 0 && tmp == buf) {
        fprintf(stderr, "\nERROR - %s line %d failed with:", __FILE__,
            __LINE__);
        fprintf(stderr, " Expected pointer to be incremented\n");
        abort();
    }

#ifndef OPENSSL_EXTRA_X509_SMALL
    tmp = buf;
    ExpectNotNull(d2i_name = d2i_X509_NAME(NULL, &tmp, sz));
#endif

    /* if output parameter is NULL, should still return required size. */
    ExpectIntGT((sz = i2d_X509_NAME((X509_NAME*)b, NULL)), 0);
    /* retry but with the function creating a buffer */
    tmp = NULL;
    ExpectIntGT((sz = i2d_X509_NAME((X509_NAME*)b, &tmp)), 0);
    XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
    tmp = NULL;

#ifdef WOLFSSL_CERT_NAME_ALL
    /* test for givenName and name */
    {
        WOLFSSL_X509_NAME_ENTRY* entry = NULL;
        const byte gName[] = "test-given-name";
        const byte name[] = "test-name";

        ExpectNotNull(entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL,
            NID_givenName, ASN_UTF8STRING, gName, sizeof(gName)));
        ExpectIntEQ(wolfSSL_X509_NAME_add_entry((X509_NAME*)b, entry, -1, 0),
            1);
        wolfSSL_X509_NAME_ENTRY_free(entry);
        entry = NULL;

        ExpectNotNull(entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL,
            NID_name, ASN_UTF8STRING, name, sizeof(name)));
        ExpectIntEQ(wolfSSL_X509_NAME_add_entry((X509_NAME*)b, entry, -1, 0),
            1);
        wolfSSL_X509_NAME_ENTRY_free(entry);

        tmp = NULL;
        ExpectIntGT((sz = i2d_X509_NAME((X509_NAME*)b, &tmp)), 0);
        XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
    }
#endif

    b = NULL;
    ExpectNotNull(b = X509_NAME_dup((X509_NAME*)a));
#ifndef OPENSSL_EXTRA_X509_SMALL
    ExpectIntEQ(X509_NAME_cmp(a, b), 0);
#endif
    X509_NAME_free((X509_NAME*)b);
    X509_NAME_free(d2i_name);
    d2i_name = NULL;
    X509_free(x509);

#ifndef OPENSSL_EXTRA_X509_SMALL
    /* test with an empty domain component */
    tmp = empty;
    sz  = sizeof(empty);
    ExpectNotNull(d2i_name = d2i_X509_NAME(NULL, &tmp, sz));
    ExpectIntEQ(X509_NAME_entry_count(d2i_name), 2);

    /* size of empty emailAddress will be 0 */
    tmp = buf;
    ExpectIntEQ(X509_NAME_get_text_by_NID(d2i_name, NID_emailAddress,
                (char*)tmp, sizeof(buf)), 0);

    /* should contain no organization name */
    tmp = buf;
    ExpectIntEQ(X509_NAME_get_text_by_NID(d2i_name, NID_organizationName,
                (char*)tmp, sizeof(buf)), -1);
    X509_NAME_free(d2i_name);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_NAME_hash(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA) && !defined(NO_SHA) && !defined(NO_BIO)
    BIO* bio = NULL;
    X509* x509 = NULL;

    ExpectNotNull(bio = BIO_new(BIO_s_file()));
    ExpectIntGT(BIO_read_filename(bio, svrCertFile), 0);
    ExpectNotNull(PEM_read_bio_X509(bio, &x509, NULL, NULL));
    ExpectIntEQ(X509_NAME_hash(X509_get_subject_name(x509)), 0x137DC03F);
    ExpectIntEQ(X509_NAME_hash(X509_get_issuer_name(x509)), 0xFDB2DA4);
    X509_free(x509);
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_NAME_print_ex(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
     (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
     defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
     defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))) && \
    !defined(NO_BIO) && !defined(NO_RSA)
    int memSz = 0;
    byte* mem = NULL;
    BIO* bio = NULL;
    BIO* membio = NULL;
    X509* x509 = NULL;
    X509_NAME* name = NULL;

    const char* expNormal  = "C=US, CN=wolfssl.com";
    const char* expEqSpace = "C = US, CN = wolfssl.com";
    const char* expReverse = "CN=wolfssl.com, C=US";

    const char* expNotEscaped = "C= US,+\"\\ , CN=#wolfssl.com<>;";
    const char* expNotEscapedRev = "CN=#wolfssl.com<>;, C= US,+\"\\ ";
    const char* expRFC5523 =
        "CN=\\#wolfssl.com\\<\\>\\;, C=\\ US\\,\\+\\\"\\\\\\ ";

    /* Test with real cert (svrCertFile) first */
    ExpectNotNull(bio = BIO_new(BIO_s_file()));
    ExpectIntGT(BIO_read_filename(bio, svrCertFile), 0);
    ExpectNotNull(PEM_read_bio_X509(bio, &x509, NULL, NULL));
    ExpectNotNull(name = X509_get_subject_name(x509));

    /* Test without flags */
    ExpectNotNull(membio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, 0), WOLFSSL_SUCCESS);
    BIO_free(membio);
    membio = NULL;

    /* Test flag: XN_FLAG_RFC2253 */
    ExpectNotNull(membio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(X509_NAME_print_ex(membio, name, 0,
                XN_FLAG_RFC2253), WOLFSSL_SUCCESS);
    BIO_free(membio);
    membio = NULL;

    /* Test flag: XN_FLAG_RFC2253 | XN_FLAG_DN_REV */
    ExpectNotNull(membio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(X509_NAME_print_ex(membio, name, 0,
                XN_FLAG_RFC2253 | XN_FLAG_DN_REV), WOLFSSL_SUCCESS);
    BIO_free(membio);
    membio = NULL;

    X509_free(x509);
    BIO_free(bio);
    name = NULL;

    /* Test normal case without escaped characters */
    {
        /* Create name: "/C=US/CN=wolfssl.com" */
        ExpectNotNull(name = X509_NAME_new());
        ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName",
                    MBSTRING_UTF8, (byte*)"US", 2, -1, 0),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName",
                    MBSTRING_UTF8, (byte*)"wolfssl.com", 11, -1, 0),
                    WOLFSSL_SUCCESS);

        /* Test without flags */
        ExpectNotNull(membio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, 0), WOLFSSL_SUCCESS);
        ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0);
        ExpectIntEQ(memSz, XSTRLEN(expNormal));
        ExpectIntEQ(XSTRNCMP((char*)mem, expNormal, XSTRLEN(expNormal)), 0);
        BIO_free(membio);
        membio = NULL;

        /* Test with XN_FLAG_ONELINE which should enable XN_FLAG_SPC_EQ for
           spaces aroun '=' */
        ExpectNotNull(membio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, XN_FLAG_ONELINE),
            WOLFSSL_SUCCESS);
        ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0);
        ExpectIntEQ(memSz, XSTRLEN(expEqSpace));
        ExpectIntEQ(XSTRNCMP((char*)mem, expEqSpace, XSTRLEN(expEqSpace)), 0);
        BIO_free(membio);
        membio = NULL;

        /* Test flags: XN_FLAG_RFC2253 - should be reversed */
        ExpectNotNull(membio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(X509_NAME_print_ex(membio, name, 0,
                    XN_FLAG_RFC2253), WOLFSSL_SUCCESS);
        ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0);
        ExpectIntEQ(memSz, XSTRLEN(expReverse));
        BIO_free(membio);
        membio = NULL;

        /* Test flags: XN_FLAG_DN_REV - reversed */
        ExpectNotNull(membio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(X509_NAME_print_ex(membio, name, 0,
                    XN_FLAG_DN_REV), WOLFSSL_SUCCESS);
        ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0);
        ExpectIntEQ(memSz, XSTRLEN(expReverse));
        ExpectIntEQ(XSTRNCMP((char*)mem, expReverse, XSTRLEN(expReverse)), 0);
        BIO_free(membio);
        membio = NULL;

        X509_NAME_free(name);
        name = NULL;
    }

    /* Test RFC2253 characters are escaped with backslashes */
    {
        ExpectNotNull(name = X509_NAME_new());
        ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName",
                    /* space at beginning and end, and: ,+"\ */
                    MBSTRING_UTF8, (byte*)" US,+\"\\ ", 8, -1, 0),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName",
                    /* # at beginning, and: <>;*/
                    MBSTRING_UTF8, (byte*)"#wolfssl.com<>;", 15, -1, 0),
                    WOLFSSL_SUCCESS);

        /* Test without flags */
        ExpectNotNull(membio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, 0), WOLFSSL_SUCCESS);
        ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0);
        ExpectIntEQ(memSz, XSTRLEN(expNotEscaped));
        ExpectIntEQ(XSTRNCMP((char*)mem, expNotEscaped,
                    XSTRLEN(expNotEscaped)), 0);
        BIO_free(membio);
        membio = NULL;

        /* Test flags: XN_FLAG_RFC5523 - should be reversed and escaped */
        ExpectNotNull(membio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(X509_NAME_print_ex(membio, name, 0,
                    XN_FLAG_RFC2253), WOLFSSL_SUCCESS);
        ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0);
        ExpectIntEQ(memSz, XSTRLEN(expRFC5523));
        ExpectIntEQ(XSTRNCMP((char*)mem, expRFC5523, XSTRLEN(expRFC5523)), 0);
        BIO_free(membio);
        membio = NULL;

        /* Test flags: XN_FLAG_DN_REV - reversed but not escaped */
        ExpectNotNull(membio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(X509_NAME_print_ex(membio, name, 0,
                    XN_FLAG_DN_REV), WOLFSSL_SUCCESS);
        ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0);
        ExpectIntEQ(memSz, XSTRLEN(expNotEscapedRev));
        ExpectIntEQ(XSTRNCMP((char*)mem, expNotEscapedRev,
                    XSTRLEN(expNotEscapedRev)), 0);
        BIO_free(membio);

        X509_NAME_free(name);
    }
#endif
    return EXPECT_RESULT();
}

#ifndef NO_BIO
static int test_wolfSSL_X509_INFO_multiple_info(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA)
    STACK_OF(X509_INFO) *info_stack = NULL;
    X509_INFO *info = NULL;
    int len;
    int i;
    const char* files[] = {
        cliCertFile,
        cliKeyFile,
        /* This needs to be the order as svrCertFile contains the
         * intermediate cert as well. */
        svrKeyFile,
        svrCertFile,
        NULL,
    };
    const char** curFile;
    BIO *fileBIO = NULL;
    BIO *concatBIO = NULL;
    byte tmp[FOURK_BUF];

    /* concatenate the cert and the key file to force PEM_X509_INFO_read_bio
     * to group objects together. */
    ExpectNotNull(concatBIO = BIO_new(BIO_s_mem()));
    for (curFile = files; EXPECT_SUCCESS() && *curFile != NULL; curFile++) {
        int fileLen = 0;
        ExpectNotNull(fileBIO = BIO_new_file(*curFile, "rb"));
        ExpectIntGT(fileLen = wolfSSL_BIO_get_len(fileBIO), 0);
        if (EXPECT_SUCCESS()) {
            while ((len = BIO_read(fileBIO, tmp, sizeof(tmp))) > 0) {
                ExpectIntEQ(BIO_write(concatBIO, tmp, len), len);
                fileLen -= len;
                if (EXPECT_FAIL())
                    break;
            }
            /* Make sure we read the entire file */
            ExpectIntEQ(fileLen, 0);
        }
        BIO_free(fileBIO);
        fileBIO = NULL;
    }

    ExpectNotNull(info_stack = PEM_X509_INFO_read_bio(concatBIO, NULL, NULL,
        NULL));
    ExpectIntEQ(sk_X509_INFO_num(info_stack), 3);
    for (i = 0; i < sk_X509_INFO_num(info_stack); i++) {
        ExpectNotNull(info = sk_X509_INFO_value(info_stack, i));
        ExpectNotNull(info->x509);
        ExpectNull(info->crl);
        if (i != 0) {
            ExpectNotNull(info->x_pkey);
            ExpectIntEQ(X509_check_private_key(info->x509,
                                               info->x_pkey->dec_pkey), 1);
        }
        else {
            ExpectNull(info->x_pkey);
        }
    }

    sk_X509_INFO_pop_free(info_stack, X509_INFO_free);
    BIO_free(concatBIO);
#endif
    return EXPECT_RESULT();
}
#endif

#ifndef NO_BIO
static int test_wolfSSL_X509_INFO(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA)
    STACK_OF(X509_INFO) *info_stack = NULL;
    X509_INFO *info = NULL;
    BIO *cert = NULL;
    int i;
    /* PEM in hex format to avoid null terminator */
    byte data[] = {
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47,
        0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x63, 0x2d, 0x2d, 0x2d, 0x2d,
        0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x4d, 0x54, 0x42, 0x75, 0x51, 0x3d,
        0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x2d, 0x2d,
        0x2d, 0x2d, 0x2d
    };
    /* PEM in hex format to avoid null terminator */
    byte data2[] = {
        0x41, 0x53, 0x4e, 0x31, 0x20, 0x4f, 0x49, 0x44, 0x3a, 0x20, 0x70, 0x72,
        0x69, 0x6d, 0x65, 0x32, 0x35, 0x36, 0x76, 0x31, 0x0a, 0x2d, 0x2d, 0x2d,
        0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x45, 0x43, 0x20, 0x50,
        0x41, 0x52, 0x41, 0x4d, 0x45, 0x54, 0x45, 0x52, 0x53, 0x2d, 0x2d, 0x2d,
        0x2d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x2d, 0x0a, 0x42, 0x67, 0x67, 0x71,
        0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x4d, 0x42, 0x42, 0x77, 0x3d, 0x3d,
        0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
    };

    ExpectNotNull(cert = BIO_new_file(cliCertFileExt, "rb"));
    ExpectNotNull(info_stack = PEM_X509_INFO_read_bio(cert, NULL, NULL, NULL));
    for (i = 0; i < sk_X509_INFO_num(info_stack); i++) {
        ExpectNotNull(info = sk_X509_INFO_value(info_stack, i));
        ExpectNotNull(info->x509);
        ExpectNull(info->crl);
        ExpectNull(info->x_pkey);
    }
    sk_X509_INFO_pop_free(info_stack, X509_INFO_free);
    info_stack = NULL;
    BIO_free(cert);
    cert = NULL;

    ExpectNotNull(cert = BIO_new_file(cliCertFileExt, "rb"));
    ExpectNotNull(info_stack = PEM_X509_INFO_read_bio(cert, NULL, NULL, NULL));
    sk_X509_INFO_pop_free(info_stack, X509_INFO_free);
    info_stack = NULL;
    BIO_free(cert);
    cert = NULL;

    /* This case should fail due to invalid input. */
    ExpectNotNull(cert = BIO_new(BIO_s_mem()));
    ExpectIntEQ(BIO_write(cert, data, sizeof(data)), sizeof(data));
    ExpectNull(info_stack = PEM_X509_INFO_read_bio(cert, NULL, NULL, NULL));
    sk_X509_INFO_pop_free(info_stack, X509_INFO_free);
    info_stack = NULL;
    BIO_free(cert);
    cert = NULL;
    ExpectNotNull(cert = BIO_new(BIO_s_mem()));
    ExpectIntEQ(BIO_write(cert, data2, sizeof(data2)), sizeof(data2));
    ExpectNull(info_stack = PEM_X509_INFO_read_bio(cert, NULL, NULL, NULL));
    sk_X509_INFO_pop_free(info_stack, X509_INFO_free);
    BIO_free(cert);
#endif
    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_X509_subject_name_hash(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA) && (!defined(NO_SHA) || !defined(NO_SHA256))
    X509* x509 = NULL;
    X509_NAME* subjectName = NULL;
    unsigned long ret1 = 0;
    unsigned long ret2 = 0;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
                SSL_FILETYPE_PEM));
    ExpectNotNull(subjectName = wolfSSL_X509_get_subject_name(x509));

    /* These two
     *   - X509_subject_name_hash(x509)
     *   - X509_NAME_hash(X509_get_subject_name(x509))
     *  should give the same hash, if !defined(NO_SHA) is true. */

    ret1 = X509_subject_name_hash(x509);
    ExpectIntNE(ret1, 0);

#if !defined(NO_SHA)
    ret2 = X509_NAME_hash(X509_get_subject_name(x509));
    ExpectIntNE(ret2, 0);

    ExpectIntEQ(ret1, ret2);
#else
    (void) ret2;
#endif

    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_issuer_name_hash(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \
    && !defined(NO_RSA) && (!defined(NO_SHA) || !defined(NO_SHA256))
    X509* x509 = NULL;
    X509_NAME* issuertName = NULL;
    unsigned long ret1 = 0;
    unsigned long ret2 = 0;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
                SSL_FILETYPE_PEM));
    ExpectNotNull(issuertName = wolfSSL_X509_get_issuer_name(x509));

    /* These two
     *   - X509_issuer_name_hash(x509)
     *   - X509_NAME_hash(X509_get_issuer_name(x509))
     *  should give the same hash, if !defined(NO_SHA) is true. */

    ret1 = X509_issuer_name_hash(x509);
    ExpectIntNE(ret1, 0);

#if !defined(NO_SHA)
    ret2 = X509_NAME_hash(X509_get_issuer_name(x509));
    ExpectIntNE(ret2, 0);

    ExpectIntEQ(ret1, ret2);
#else
    (void) ret2;
#endif

    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_check_host(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \
    && !defined(NO_SHA) && !defined(NO_RSA)
    X509* x509 = NULL;
    const char altName[] = "example.com";
    const char badAltName[] = "a.example.com";

    /* cliCertFile has subjectAltName set to 'example.com', '127.0.0.1' */
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
                SSL_FILETYPE_PEM));

    ExpectIntEQ(X509_check_host(x509, altName, XSTRLEN(altName), 0, NULL),
            WOLFSSL_SUCCESS);

    ExpectIntEQ(X509_check_host(x509, badAltName, XSTRLEN(badAltName), 0, NULL),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(X509_check_host(x509, NULL, 0, 0, NULL),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* Check WOLFSSL_LEFT_MOST_WILDCARD_ONLY flag set */
    ExpectIntEQ(X509_check_host(x509, altName, XSTRLEN(altName),
            WOLFSSL_LEFT_MOST_WILDCARD_ONLY, NULL), WOLFSSL_SUCCESS);

    ExpectIntEQ(X509_check_host(x509, NULL, 0,
            WOLFSSL_LEFT_MOST_WILDCARD_ONLY, NULL),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(X509_check_host(x509, badAltName, XSTRLEN(badAltName),
            WOLFSSL_LEFT_MOST_WILDCARD_ONLY, NULL),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    X509_free(x509);

    ExpectIntEQ(X509_check_host(NULL, altName, XSTRLEN(altName), 0, NULL),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* Check again with WOLFSSL_LEFT_MOST_WILDCARD_ONLY flag set */
    ExpectIntEQ(X509_check_host(NULL, altName, XSTRLEN(altName),
            WOLFSSL_LEFT_MOST_WILDCARD_ONLY, NULL),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_check_email(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA)
    X509* x509 = NULL;
    const char goodEmail[] = "info@wolfssl.com";
    const char badEmail[] = "disinfo@wolfssl.com";

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
                SSL_FILETYPE_PEM));

    /* Should fail on non-matching email address */
    ExpectIntEQ(wolfSSL_X509_check_email(x509, badEmail, XSTRLEN(badEmail), 0),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Should succeed on matching email address */
    ExpectIntEQ(wolfSSL_X509_check_email(x509, goodEmail, XSTRLEN(goodEmail), 0),
            WOLFSSL_SUCCESS);
    /* Should compute length internally when not provided */
    ExpectIntEQ(wolfSSL_X509_check_email(x509, goodEmail, 0, 0),
            WOLFSSL_SUCCESS);
    /* Should fail when email address is NULL */
    ExpectIntEQ(wolfSSL_X509_check_email(x509, NULL, 0, 0),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    X509_free(x509);

    /* Should fail when x509 is NULL */
    ExpectIntEQ(wolfSSL_X509_check_email(NULL, goodEmail, 0, 0),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif /* OPENSSL_EXTRA && WOLFSSL_CERT_GEN */
    return EXPECT_RESULT();
}

static int test_wc_PemToDer(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(WOLFSSL_PEM_TO_DER) && !defined(NO_FILESYSTEM)
    int ret;
    DerBuffer* pDer = NULL;
    const char* ca_cert = "./certs/server-cert.pem";
    byte* cert_buf = NULL;
    size_t cert_sz = 0;
    int eccKey = 0;
    EncryptedInfo info;

    XMEMSET(&info, 0, sizeof(info));

    ExpectIntEQ(ret = load_file(ca_cert, &cert_buf, &cert_sz), 0);
    ExpectIntEQ(ret = wc_PemToDer(cert_buf, (long int)cert_sz, CERT_TYPE, &pDer, NULL,
        &info, &eccKey), 0);
    wc_FreeDer(&pDer);
    pDer = NULL;

    if (cert_buf != NULL) {
        free(cert_buf);
        cert_buf = NULL;
    }

#ifdef HAVE_ECC
    {
        const char* ecc_private_key = "./certs/ecc-privOnlyKey.pem";
        byte key_buf[256] = {0};

        /* Test fail of loading a key with cert type */
        ExpectIntEQ(load_file(ecc_private_key, &cert_buf, &cert_sz), 0);
        key_buf[0] = '\n';
        ExpectNotNull(XMEMCPY(key_buf + 1, cert_buf, cert_sz));
        ExpectIntNE((ret = wc_PemToDer(key_buf, (long int)cert_sz + 1, CERT_TYPE,
            &pDer, NULL, &info, &eccKey)), 0);

    #ifdef OPENSSL_EXTRA
        ExpectIntEQ((ret = wc_PemToDer(key_buf, cert_sz + 1, PRIVATEKEY_TYPE,
            &pDer, NULL, &info, &eccKey)), 0);
    #endif
        wc_FreeDer(&pDer);
        if (cert_buf != NULL)
            free(cert_buf);
    }
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wc_AllocDer(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS)
    DerBuffer* pDer = NULL;
    word32 testSize = 1024;

    ExpectIntEQ(wc_AllocDer(NULL, testSize, CERT_TYPE, HEAP_HINT),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_AllocDer(&pDer, testSize, CERT_TYPE, HEAP_HINT), 0);
    ExpectNotNull(pDer);
    wc_FreeDer(&pDer);
#endif
    return EXPECT_RESULT();
}

static int test_wc_CertPemToDer(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(WOLFSSL_PEM_TO_DER) && !defined(NO_FILESYSTEM)
    const char* ca_cert = "./certs/ca-cert.pem";
    byte* cert_buf = NULL;
    size_t cert_sz = 0;
    size_t cert_dersz = 0;
    byte* cert_der = NULL;

    ExpectIntEQ(load_file(ca_cert, &cert_buf, &cert_sz), 0);
    cert_dersz = cert_sz; /* DER will be smaller than PEM */
    ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
    ExpectIntGE(wc_CertPemToDer(cert_buf, (int)cert_sz, cert_der,
        (int)cert_dersz, CERT_TYPE), 0);

    ExpectIntEQ(wc_CertPemToDer(NULL, (int)cert_sz, NULL, -1, CERT_TYPE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CertPemToDer(cert_buf, (int)cert_sz, NULL, -1, CERT_TYPE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CertPemToDer(NULL, (int)cert_sz, cert_der, -1, CERT_TYPE),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CertPemToDer(NULL, (int)cert_sz, NULL, (int)cert_dersz,
        CERT_TYPE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CertPemToDer(NULL, (int)cert_sz, cert_der,
        (int)cert_dersz, CERT_TYPE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CertPemToDer(cert_buf, (int)cert_sz, NULL,
        (int)cert_dersz, CERT_TYPE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_CertPemToDer(cert_buf, (int)cert_sz, cert_der, -1,
        CERT_TYPE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    if (cert_der != NULL)
        free(cert_der);
    if (cert_buf != NULL)
        free(cert_buf);
#endif
    return EXPECT_RESULT();
}

static int test_wc_KeyPemToDer(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_PEM_TO_DER) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    int ret = 0;
    const byte cert_buf[] = \
    "-----BEGIN PRIVATE KEY-----\n"
    "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDMG5KgWxP002pA\n"
    "QJIdA4H5N0oM1Wf0LrHcos5RYUlrHDkC2b5p2BUpVRPmgDAFD2+8leim98x0BvcB\n"
    "k48TNzrVynuwyVEY664+iQyzEBO5v27HPRydOddprbLCvRO036XINGIjauy1jHFi\n"
    "HaDVx3bexSwgp9aefUGAszFXi4q1J4GacV7Cr2b/wBqUHqWv4ZXPu6R9/UYngTkD\n"
    "UDJL5gLlLfcLzNyyodKPHPCIAKdWn6mSVdcHk8XVpK4y9lgz4E7YDWA6ohKZgWgG\n"
    "2RDha8CMilFMDgYa0G0SiS9g3PQx0qh3AMXJJsKSVhScFCZufAE0kV6KvjP7jAqP\n"
    "XBiSkRGPAgMBAAECggEAW7hmRyY2jRX2UMJThrM9VIs6fRLnYI0dQ0tsEJj536ay\n"
    "nevQjArc05KWW0Yujg+WRDZPcry3RUqd9Djlmhp/F3Si6dpF1b+PMS3wJYVrf9Sd\n"
    "SO5W7faArU4vnyBNe0HnY1Ta5xSVI65lg1RSIs88RTZwsooJwXYDGf0shq0/21CE\n"
    "V8HOb27DDYNcEnm35lzaONjFnMqQQT2Vs9anRrPiSEXNleEvTgLVXZtGTyCGTz6v\n"
    "x86Y8eSWL9YNHvPE1I+mDPuocfSR7eRNgRu7SK3mn94W5mqd7Ns072YKX/2XN1mO\n"
    "66+ZFHO6v4dK1u7cSjuwrU1EhLHpUsgDz6Bna5InyQKBgQDv5l8RPy8UneKSADaf\n"
    "M5L/5675I/5t4nqVjvbnQje00YveLTAEjlJBNR93Biln3sYgnvNamYDCxyEuUZ/I\n"
    "S/vmBL9PoxfGZow4FcsIBOEbIn3E0SYJgCBNWthquUvGpKsYDnThJuhO+1cVmxAJ\n"
    "BUOjLFnJYHM0a+Vmk9GexT2OBwKBgQDZzkUBOK7Im3eiYytFocUJyhqMH30d49X9\n"
    "ujC7kGw4UWAqVe7YCSvlBa8nzWpRWK2kRpu3M0272RU0V4geyWqT+nr/SvRRPtNP\n"
    "F5dY8l3yR7hjtSejqqjOfBcZT6ETJxI4tiG0+Nl5BlfM5M+0nxnkWpRcHuOR3j79\n"
    "YUFERyN+OQKBgQCjlOKeUAc6d65W/+4/AFvsQ378Q57qLtSHxsR1TKHPmlNVXFqx\n"
    "wJo1/JNIBduWCEHxXHF0BdfW+RGXE/FwEt/hKLuLAhrkHmjelX2sKieU6R/5ZOQa\n"
    "9lMQbDHGFDOncAF6leD85hriQGBRSzrT69MDIOrYdfwYcroqCAGX0cb3YQKBgQC8\n"
    "iIFQylj5SyHmjcMSNjKSA8CxFDzAV8yPIdE3Oo+CvGXqn5HsrRuy1hXE9VmXapR8\n"
    "A6ackSszdHiXY0FvrNe1mfdH7wDHJwPQjdIzazCJHS3uGQxj7sDKY7226ie6pXJv\n"
    "ZrCMr2/IBAaSVGm6ppHKCeIsT4ybYm7R85KEYLPHeQKBgBeJOMBinXQfWN/1jT9b\n"
    "6Ywrutvp2zP8hVxQGSZJ0WG4iewZyFLsPUlbWRXOSYNPElHmdD0ZomdLVm+lSpAA\n"
    "XSH5FJ/IFCwqq7Eft6Gf8NFRV+NjPMUny+PnjHe4oFP8YK/Ek22K3ttNG8Hw69Aw\n"
    "AQue5o6oVfhgLiJzMdo/77gw\n"
    "-----END PRIVATE KEY-----\n";
    const int cert_sz = sizeof(cert_buf);
    const char cert_pw[] = "password";
    int cert_dersz = 0;
    byte* cert_der = NULL;

    /* Bad arg: Cert buffer is NULL */
    ExpectIntEQ(wc_KeyPemToDer(NULL, cert_sz, cert_der, cert_dersz, ""),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Bad arg: Cert DER buffer non-NULL but size zero (or less) */
    ExpectIntEQ(wc_KeyPemToDer(cert_buf, cert_sz, (byte*)&cert_der, 0, ""),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Test normal operation */
    cert_dersz = cert_sz; /* DER will be smaller than PEM */
    ExpectNotNull(cert_der = (byte*)malloc((size_t)cert_dersz));
    ExpectIntGE(ret = wc_KeyPemToDer(cert_buf, cert_sz, cert_der, cert_dersz,
        cert_pw), 0);
    ExpectIntLE(ret, cert_sz);
    if (cert_der != NULL) {
        free(cert_der);
        cert_der = NULL;
    }

    /* Test NULL for DER buffer to return needed DER buffer size */
    ExpectIntGT(ret = wc_KeyPemToDer(cert_buf, cert_sz, NULL, 0, ""), 0);
    ExpectIntLE(ret, cert_sz);
    if (EXPECT_SUCCESS())
        cert_dersz = ret;
    ExpectNotNull(cert_der = (byte*)malloc((size_t)cert_dersz));
    ExpectIntGE(ret = wc_KeyPemToDer(cert_buf, cert_sz, cert_der, cert_dersz,
        cert_pw), 0);
    ExpectIntLE(ret, cert_sz);
    if (cert_der != NULL)
        free(cert_der);
#endif
    return EXPECT_RESULT();
}

static int test_wc_PubKeyPemToDer(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_PEM_TO_DER) && !defined(NO_FILESYSTEM) && \
   (defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER))
    int ret = 0;
    const char* key = "./certs/ecc-client-keyPub.pem";
    byte* cert_buf = NULL;
    size_t cert_sz = 0, cert_dersz = 0;
    byte* cert_der = NULL;

    ExpectIntEQ(wc_PubKeyPemToDer(cert_buf, (int)cert_sz,
        cert_der, (int)cert_dersz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(load_file(key, &cert_buf, &cert_sz), 0);
    cert_dersz = cert_sz; /* DER will be smaller than PEM */
    ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
    ExpectIntGE(wc_PubKeyPemToDer(cert_buf, (int)cert_sz, cert_der,
        (int)cert_dersz), 0);
    if (cert_der != NULL) {
        free(cert_der);
        cert_der = NULL;
    }

    /* Test NULL for DER buffer to return needed DER buffer size */
    ExpectIntGT(ret = wc_PubKeyPemToDer(cert_buf, (int)cert_sz, NULL, 0), 0);
    ExpectIntLE(ret, cert_sz);
    cert_dersz = (size_t)ret;
    ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
    ExpectIntGE(wc_PubKeyPemToDer(cert_buf, (int)cert_sz, cert_der,
        (int)cert_dersz), 0);
    if (cert_der != NULL) {
        free(cert_der);
    }

    if (cert_buf != NULL) {
        free(cert_buf);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wc_PemPubKeyToDer(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && \
    (defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER))
    const char* key = "./certs/ecc-client-keyPub.pem";
    size_t cert_dersz = 1024;
    byte* cert_der = NULL;

    ExpectIntGE(wc_PemPubKeyToDer(NULL, cert_der, (int)cert_dersz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
    ExpectIntGE(wc_PemPubKeyToDer(key, cert_der, (int)cert_dersz), 0);
    if (cert_der != NULL) {
        free(cert_der);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wc_GetPubKeyDerFromCert(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) || defined(HAVE_ECC)
    int ret;
    word32 idx = 0;
    byte keyDer[TWOK_BUF];  /* large enough for up to RSA 2048 */
    word32 keyDerSz = (word32)sizeof(keyDer);
    DecodedCert decoded;
#if !defined(NO_RSA) && defined(WOLFSSL_CERT_REQ) && !defined(NO_FILESYSTEM)
    byte certBuf[6000]; /* for PEM and CSR, client-cert.pem is 5-6kB */
    word32 certBufSz = sizeof(certBuf);
#endif
#if ((!defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_1024)) || \
     defined(WOLFSSL_CERT_REQ)) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
    XFILE fp = XBADFILE;
#endif
#ifndef NO_RSA
    RsaKey rsaKey;
    #if defined(USE_CERT_BUFFERS_2048)
        byte* rsaCertDer = (byte*)client_cert_der_2048;
        word32 rsaCertDerSz = sizeof_client_cert_der_2048;
    #elif defined(USE_CERT_BUFFERS_1024)
        byte* rsaCertDer = (byte*)client_cert_der_1024;
        word32 rsaCertDerSz = sizeof_client_cert_der_1024;
    #else
        unsigned char rsaCertDer[TWOK_BUF];
        word32 rsaCertDerSz;
    #endif
#endif
#ifdef HAVE_ECC
    ecc_key eccKey;
    #if defined(USE_CERT_BUFFERS_256)
        byte* eccCert = (byte*)cliecc_cert_der_256;
        word32 eccCertSz = sizeof_cliecc_cert_der_256;
    #else
        unsigned char eccCert[ONEK_BUF];
        word32 eccCertSz;
        XFILE fp2 = XBADFILE;
    #endif
#endif

#ifndef NO_RSA

#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
    ExpectTrue((fp = XFOPEN("./certs/1024/client-cert.der", "rb")) != XBADFILE);
    ExpectIntGT(rsaCertDerSz = (word32)XFREAD(rsaCertDer, 1, sizeof(rsaCertDer),
        fp), 0);
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }
#endif

    /* good test case - RSA DER cert */
    wc_InitDecodedCert(&decoded, rsaCertDer, rsaCertDerSz, NULL);
    ExpectIntEQ(wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL), 0);

    ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz), 0);
    ExpectIntGT(keyDerSz, 0);

    /* sanity check, verify we can import DER public key */
    ret = wc_InitRsaKey(&rsaKey, HEAP_HINT);
    ExpectIntEQ(ret, 0);
    ExpectIntEQ(wc_RsaPublicKeyDecode(keyDer, &idx, &rsaKey, keyDerSz), 0);
    if (ret == 0) {
        wc_FreeRsaKey(&rsaKey);
    }

    /* test LENGTH_ONLY_E case */
    keyDerSz = 0;
    ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, NULL, &keyDerSz),
        WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectIntGT(keyDerSz, 0);

    /* bad args: DecodedCert NULL */
    ExpectIntEQ(wc_GetPubKeyDerFromCert(NULL, keyDer, &keyDerSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* bad args: output key buff size */
    ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, keyDer, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* bad args: zero size output key buffer */
    keyDerSz = 0;
    ExpectIntEQ(ret = wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wc_FreeDecodedCert(&decoded);

    /* Certificate Request Tests */
    #if defined(WOLFSSL_CERT_REQ) && !defined(NO_FILESYSTEM)
    {
        XMEMSET(certBuf, 0, sizeof(certBuf));
        ExpectTrue((fp = XFOPEN("./certs/csr.signed.der", "rb")) != XBADFILE);
        ExpectIntGT(certBufSz = (word32)XFREAD(certBuf, 1, certBufSz, fp), 0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
        }

        wc_InitDecodedCert(&decoded, certBuf, certBufSz, NULL);
        ExpectIntEQ(wc_ParseCert(&decoded, CERTREQ_TYPE, VERIFY, NULL), 0);

        /* good test case - RSA DER certificate request */
        keyDerSz = sizeof(keyDer);
        ExpectIntEQ(ret = wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz),
            0);
        ExpectIntGT(keyDerSz, 0);

        /* sanity check, verify we can import DER public key */
        ret = wc_InitRsaKey(&rsaKey, HEAP_HINT);
        ExpectIntEQ(ret, 0);
        idx = 0;
        ExpectIntEQ(wc_RsaPublicKeyDecode(keyDer, &idx, &rsaKey, keyDerSz), 0);
        if (ret == 0) {
            wc_FreeRsaKey(&rsaKey);
        }

        wc_FreeDecodedCert(&decoded);
    }
    #endif /* WOLFSSL_CERT_REQ */
#endif /* NO_RSA */

#ifdef HAVE_ECC
    #ifndef USE_CERT_BUFFERS_256
        ExpectTrue((fp2 = XFOPEN("./certs/client-ecc-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(eccCertSz = (word32)XFREAD(eccCert, 1, ONEK_BUF, fp2), 0);
        if (fp2 != XBADFILE) {
            XFCLOSE(fp2);
        }
    #endif

    wc_InitDecodedCert(&decoded, eccCert, eccCertSz, NULL);
    ExpectIntEQ(wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL), 0);

    /* good test case - ECC */
    XMEMSET(keyDer, 0, sizeof(keyDer));
    keyDerSz = sizeof(keyDer);
    ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz), 0);
    ExpectIntGT(keyDerSz, 0);

    /* sanity check, verify we can import DER public key */
    ret = wc_ecc_init(&eccKey);
    ExpectIntEQ(ret, 0);
    idx = 0; /* reset idx to 0, used above in RSA case */
    ExpectIntEQ(wc_EccPublicKeyDecode(keyDer, &idx, &eccKey, keyDerSz), 0);
    if (ret == 0) {
        wc_ecc_free(&eccKey);
    }

    /* test LENGTH_ONLY_E case */
    keyDerSz = 0;
    ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, NULL, &keyDerSz),
        WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectIntGT(keyDerSz, 0);

    wc_FreeDecodedCert(&decoded);
#endif
#endif /* !NO_RSA || HAVE_ECC */
    return EXPECT_RESULT();
}

static int test_wc_CheckCertSigPubKey(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA) && defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_ECC)
    int ret = 0;
    const char* ca_cert = "./certs/ca-cert.pem";
    byte* cert_buf = NULL;
    size_t cert_sz = 0;
    byte* cert_der = NULL;
    word32 cert_dersz = 0;
    byte keyDer[TWOK_BUF];  /* large enough for up to RSA 2048 */
    word32 keyDerSz = (word32)sizeof(keyDer);
    DecodedCert decoded;

    ExpectIntEQ(load_file(ca_cert, &cert_buf, &cert_sz), 0);
    cert_dersz = (word32)cert_sz; /* DER will be smaller than PEM */
    ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
    ExpectIntGE(ret = wc_CertPemToDer(cert_buf, (int)cert_sz, cert_der,
        (int)cert_dersz, CERT_TYPE), 0);

    wc_InitDecodedCert(&decoded, cert_der, cert_dersz, NULL);
    ExpectIntEQ(wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL), 0);

    ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz), 0);
    ExpectIntGT(keyDerSz, 0);

    /* Good test case. */
    ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer,
        keyDerSz, RSAk), 0);

    /* No certificate. */
    ExpectIntEQ(wc_CheckCertSigPubKey(NULL, cert_dersz, NULL, keyDer, keyDerSz,
        ECDSAk), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Bad cert size. */
    ExpectIntNE(ret = wc_CheckCertSigPubKey(cert_der, 0, NULL, keyDer, keyDerSz,
        RSAk), 0);
    ExpectTrue(ret == WC_NO_ERR_TRACE(ASN_PARSE_E) || ret == WC_NO_ERR_TRACE(BUFFER_E));

    /* No public key. */
    ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, NULL,
        keyDerSz, RSAk), WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));

    /* Bad public key size. */
    ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer, 0,
        RSAk), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Wrong aglo. */
    ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer,
        keyDerSz, ECDSAk), WC_NO_ERR_TRACE(ASN_PARSE_E));

    wc_FreeDecodedCert(&decoded);
    if (cert_der != NULL)
        free(cert_der);
    if (cert_buf != NULL)
        free(cert_buf);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_certs(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA)
    X509*  x509ext = NULL;
    X509*  x509 = NULL;
#ifdef OPENSSL_ALL
    WOLFSSL_X509_EXTENSION* ext = NULL;
    ASN1_OBJECT* obj = NULL;
#endif
    WOLFSSL*     ssl = NULL;
    WOLFSSL_CTX* ctx = NULL;
    STACK_OF(ASN1_OBJECT)* sk = NULL;
    ASN1_STRING* asn1_str = NULL;
    AUTHORITY_KEYID* akey = NULL;
    BASIC_CONSTRAINTS* bc = NULL;
    int crit = 0;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(SSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(SSLv23_client_method()));
#endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile, SSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));
    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntEQ(SSL_CTX_check_private_key(ctx), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    #endif
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntEQ(SSL_CTX_check_private_key(ctx), SSL_SUCCESS);
    #endif
    ExpectNotNull(ssl = SSL_new(ctx));

    /* Invalid parameters. */
    ExpectIntEQ(SSL_use_certificate_file(NULL, NULL, WOLFSSL_FILETYPE_PEM),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(SSL_use_certificate_file(ssl, NULL, WOLFSSL_FILETYPE_PEM),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_certificate_file(NULL, "./certs/server-cert.pem",
        WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif

    #ifdef HAVE_PK_CALLBACKS
    ExpectIntEQ((int)SSL_set_tlsext_debug_arg(ssl, NULL), WOLFSSL_SUCCESS);
    #endif /* HAVE_PK_CALLBACKS */

    /* Invalid parameters. */
    ExpectNotNull(x509 = wolfSSL_X509_new());
    ExpectIntEQ(SSL_use_certificate(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_certificate(ssl, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_certificate(NULL, x509), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* No data in certificate. */
    ExpectIntEQ(SSL_use_certificate(ssl, x509), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    wolfSSL_X509_free(x509);
    x509 = NULL;

    /* create and use x509 */
#ifdef OPENSSL_ALL
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
        WOLFSSL_FILETYPE_PEM));
#endif
    ExpectNotNull(x509ext = wolfSSL_X509_load_certificate_file(cliCertFileExt,
        WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ(SSL_use_certificate(ssl, x509ext), WOLFSSL_SUCCESS);

    #if !defined(NO_CHECK_PRIVATE_KEY)
    /* with loading in a new cert the check on private key should now fail */
    ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif


    #if defined(USE_CERT_BUFFERS_2048)
        /* Invalid parameters. */
        ExpectIntEQ(SSL_use_certificate_ASN1(NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        ExpectIntEQ(SSL_use_certificate_ASN1(ssl, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        ExpectIntEQ(SSL_use_certificate_ASN1(NULL,
                (unsigned char*)server_cert_der_2048, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        /* No data. */
        ExpectIntEQ(SSL_use_certificate_ASN1(ssl,
                (unsigned char*)server_cert_der_2048, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

        ExpectIntEQ(SSL_use_certificate_ASN1(ssl,
                                  (unsigned char*)server_cert_der_2048,
                                  sizeof_server_cert_der_2048), WOLFSSL_SUCCESS);
    #endif

    #if !defined(NO_SHA) && !defined(NO_SHA256) && !defined(NO_PWDBASED)
    /************* Get Digest of Certificate ******************/
    {
        byte   digest[64]; /* max digest size */
        word32 digestSz;

        XMEMSET(digest, 0, sizeof(digest));
        ExpectIntEQ(X509_digest(x509ext, wolfSSL_EVP_sha1(), digest, &digestSz),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(X509_digest(x509ext, wolfSSL_EVP_sha256(), digest, &digestSz),
                    WOLFSSL_SUCCESS);

        ExpectIntEQ(X509_digest(NULL, wolfSSL_EVP_sha1(), digest, &digestSz),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    }
    #endif /* !NO_SHA && !NO_SHA256 && !NO_PWDBASED */

    /* test and checkout X509 extensions */
    ExpectNotNull(bc = (BASIC_CONSTRAINTS*)X509_get_ext_d2i(x509ext,
        NID_basic_constraints, &crit, NULL));
    ExpectIntEQ(crit, 0);

#ifdef OPENSSL_ALL
    ExpectNotNull(ext = X509V3_EXT_i2d(NID_basic_constraints, crit, bc));
    X509_EXTENSION_free(ext);
    ext = NULL;

    ExpectNotNull(ext = X509_EXTENSION_new());
    X509_EXTENSION_set_critical(ext, 1);
    ExpectNotNull(obj = OBJ_nid2obj(NID_basic_constraints));
    ExpectIntEQ(X509_EXTENSION_set_object(ext, obj), SSL_SUCCESS);
    ASN1_OBJECT_free(obj);
    obj = NULL;
    X509_EXTENSION_free(ext);
    ext = NULL;

    ExpectNotNull(ext = X509_EXTENSION_new());
    X509_EXTENSION_set_critical(ext, 0);
    ExpectIntEQ(X509_EXTENSION_set_data(ext, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    asn1_str = (ASN1_STRING*)X509_get_ext_d2i(x509ext, NID_key_usage, &crit,
            NULL);
    ExpectIntEQ(X509_EXTENSION_set_data(ext, asn1_str), SSL_SUCCESS);
    ASN1_STRING_free(asn1_str); /* X509_EXTENSION_set_data has made a copy
                                 * and X509_get_ext_d2i has created new */
    asn1_str = NULL;
    X509_EXTENSION_free(ext);
    ext = NULL;

#endif
    BASIC_CONSTRAINTS_free(bc);
    bc = NULL;

    ExpectNotNull(asn1_str = (ASN1_STRING*)X509_get_ext_d2i(x509ext,
        NID_key_usage, &crit, NULL));
    ExpectIntEQ(crit, 1);
    ExpectIntEQ(asn1_str->type, NID_key_usage);
#ifdef OPENSSL_ALL
    ExpectNotNull(ext = X509V3_EXT_i2d(NID_key_usage, crit, asn1_str));
    X509_EXTENSION_free(ext);
    ext = NULL;
#endif
    ASN1_STRING_free(asn1_str);
    asn1_str = NULL;

#ifdef OPENSSL_ALL
    ExpectNotNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509,
        NID_ext_key_usage, &crit, NULL));
    ExpectNotNull(ext = X509V3_EXT_i2d(NID_ext_key_usage, crit, sk));
    X509_EXTENSION_free(ext);
    ext = NULL;
    EXTENDED_KEY_USAGE_free(sk);
    sk = NULL;
#else
    sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext, NID_ext_key_usage,
            &crit, NULL);
    ExpectNull(sk);
#endif

    ExpectNotNull(akey = (AUTHORITY_KEYID*)X509_get_ext_d2i(x509ext,
        NID_authority_key_identifier, &crit, NULL));
#ifdef OPENSSL_ALL
    ExpectNotNull(ext = X509V3_EXT_i2d(NID_authority_key_identifier, crit,
        akey));
    X509_EXTENSION_free(ext);
    ext = NULL;
#endif
    wolfSSL_AUTHORITY_KEYID_free(akey);
    akey = NULL;

    /* NID not yet supported */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
        NID_private_key_usage_period, &crit, NULL));
    ExpectIntEQ(crit, -1);
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    ExpectNotNull(sk = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(x509ext,
        NID_subject_alt_name, &crit, NULL));
    {
        int i;
        for (i = 0; i < sk_GENERAL_NAME_num(sk); i++) {
            GENERAL_NAME* gen = sk_GENERAL_NAME_value(sk, i);
            ExpectIntEQ(gen->type, GEN_DNS);
            ExpectIntEQ(gen->d.dNSName->type, V_ASN1_IA5STRING);
        }
    }
    sk_GENERAL_NAME_free(sk);
    sk = NULL;

    /* NID not yet supported */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
        NID_issuer_alt_name, &crit, NULL));
    ExpectIntEQ(crit, -1);
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    /* NID not yet supported */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
        NID_info_access, &crit, NULL));
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    /* NID not yet supported */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
        NID_sinfo_access, &crit, NULL));
    ExpectIntEQ(crit, -1);
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    /* NID not yet supported */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
        NID_name_constraints, &crit, NULL));
    ExpectIntEQ(crit, -1);
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    /* no cert policy set */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
            NID_certificate_policies, &crit, NULL));
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    /* NID not yet supported */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
        NID_policy_mappings, &crit, NULL));
    ExpectIntEQ(crit, -1);
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    /* NID not yet supported */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
        NID_policy_constraints, &crit, NULL));
    ExpectIntEQ(crit, -1);
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    /* NID not yet supported */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
        NID_inhibit_any_policy, &crit, NULL));
    ExpectIntEQ(crit, -1);
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    /* NID not yet supported */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
        NID_tlsfeature, &crit, NULL));
    ExpectIntEQ(crit, -1);
    sk_ASN1_OBJECT_free(sk);
    sk = NULL;

    /* test invalid cases */
    crit = 0;
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext, -1, &crit,
        NULL));
    ExpectIntEQ(crit, -1);
    /* NULL passed for criticality. */
    ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(NULL,
        NID_tlsfeature, NULL, NULL));

    ExpectIntEQ(SSL_get_hit(ssl), 0);
#ifdef OPENSSL_ALL
    X509_free(x509);
#endif
    X509_free(x509ext);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && !NO_CERTS */
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_check_private_key(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA) && \
        defined(USE_CERT_BUFFERS_2048) && !defined(NO_CHECK_PRIVATE_KEY)
    X509*  x509 = NULL;
    EVP_PKEY* pkey = NULL;
    const byte* key;

    /* Check with correct key */
    ExpectNotNull((x509 = X509_load_certificate_file(cliCertFile,
        SSL_FILETYPE_PEM)));
    key = client_key_der_2048;
    ExpectNotNull(d2i_PrivateKey(EVP_PKEY_RSA, &pkey, &key,
        (long)sizeof_client_key_der_2048));
    ExpectIntEQ(X509_check_private_key(x509, pkey), 1);
    EVP_PKEY_free(pkey);
    pkey = NULL;

    /* Check with wrong key */
    key = server_key_der_2048;
    ExpectNotNull(d2i_PrivateKey(EVP_PKEY_RSA, &pkey, &key,
        (long)sizeof_server_key_der_2048));
    ExpectIntEQ(X509_check_private_key(x509, pkey), 0);

    /* test for incorrect parameter */
    ExpectIntEQ(X509_check_private_key(NULL, pkey), 0);
    ExpectIntEQ(X509_check_private_key(x509, NULL), 0);
    ExpectIntEQ(X509_check_private_key(NULL, NULL), 0);

    EVP_PKEY_free(pkey);
    X509_free(x509);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_private_keys(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    WOLFSSL*     ssl = NULL;
    WOLFSSL_CTX* ctx = NULL;
    EVP_PKEY* pkey = NULL;

    OpenSSL_add_all_digests();
    OpenSSL_add_all_algorithms();

#ifndef NO_RSA
    #ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
    #else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
    #endif
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
        WOLFSSL_FILETYPE_PEM));
    /* Have to load a cert before you can check the private key against that
     * certificates public key! */
    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntEQ(wolfSSL_CTX_check_private_key(ctx), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    #endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
        WOLFSSL_FILETYPE_PEM));
    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntEQ(wolfSSL_CTX_check_private_key(ctx), WOLFSSL_SUCCESS);
    #endif
    ExpectNotNull(ssl = SSL_new(ctx));

    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif

    /* Invalid parameters. */
    ExpectIntEQ(SSL_use_PrivateKey_file(NULL, NULL, WOLFSSL_FILETYPE_PEM),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(SSL_use_PrivateKey_file(NULL, svrKeyFile, WOLFSSL_FILETYPE_PEM),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(SSL_use_PrivateKey_file(ssl, NULL, WOLFSSL_FILETYPE_PEM),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

#ifdef USE_CERT_BUFFERS_2048
    {
    const unsigned char* server_key = (const unsigned char*)server_key_der_2048;
    unsigned char buf[FOURK_BUF];
    word32 bufSz;

    /* Invalid parameters. */
    ExpectIntEQ(SSL_use_RSAPrivateKey_ASN1(NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_RSAPrivateKey_ASN1(ssl, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_RSAPrivateKey_ASN1(NULL,
        (unsigned char*)client_key_der_2048, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_PrivateKey_ASN1(0, NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_PrivateKey_ASN1(0, ssl, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_PrivateKey_ASN1(0, NULL, (unsigned char*)server_key, 0),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, ctx, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, NULL, (unsigned char*)server_key,
        0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(SSL_use_RSAPrivateKey_ASN1(ssl,
                (unsigned char*)client_key_der_2048,
                sizeof_client_key_der_2048), WOLFSSL_SUCCESS);
    #if !defined(NO_CHECK_PRIVATE_KEY)
    /* Should mismatch now that a different private key loaded */
    ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif

    ExpectIntEQ(SSL_use_PrivateKey_ASN1(0, ssl,
                (unsigned char*)server_key,
                sizeof_server_key_der_2048), WOLFSSL_SUCCESS);
    #if !defined(NO_CHECK_PRIVATE_KEY)
    /* After loading back in DER format of original key, should match */
    ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif

    /* test loading private key to the WOLFSSL_CTX */
    ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, ctx,
                (unsigned char*)client_key_der_2048,
                sizeof_client_key_der_2048), WOLFSSL_SUCCESS);

    #if !defined(NO_CHECK_PRIVATE_KEY)
    /* Should mismatch now that a different private key loaded */
    ExpectIntNE(wolfSSL_CTX_check_private_key(ctx), WOLFSSL_SUCCESS);
    #endif

    ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, ctx,
                (unsigned char*)server_key,
                sizeof_server_key_der_2048), WOLFSSL_SUCCESS);
    #if !defined(NO_CHECK_PRIVATE_KEY)
    /* After loading back in DER format of original key, should match */
    ExpectIntEQ(wolfSSL_CTX_check_private_key(ctx), WOLFSSL_SUCCESS);
    #endif

    /* Invalid parameters. */
    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectIntEQ(SSL_use_PrivateKey(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_PrivateKey(ssl, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_use_PrivateKey(NULL, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* pkey is empty - no key data to use. */
    ExpectIntEQ(SSL_use_PrivateKey(ssl, pkey), WC_NO_ERR_TRACE(ASN_PARSE_E));
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;

    /* set PKEY and test again */
    ExpectNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey,
                &server_key, (long)sizeof_server_key_der_2048));
    ExpectIntEQ(SSL_use_PrivateKey(ssl, pkey), WOLFSSL_SUCCESS);

    /* reuse PKEY structure and test
     * this should be checked with a memory management sanity checker */
    ExpectFalse(server_key == (const unsigned char*)server_key_der_2048);
    server_key = (const unsigned char*)server_key_der_2048;
    ExpectNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey,
                &server_key, (long)sizeof_server_key_der_2048));
    ExpectIntEQ(SSL_use_PrivateKey(ssl, pkey), WOLFSSL_SUCCESS);

    /* check striping PKCS8 header with wolfSSL_d2i_PrivateKey */
    bufSz = FOURK_BUF;
    ExpectIntGT((bufSz = (word32)wc_CreatePKCS8Key(buf, &bufSz,
                    (byte*)server_key_der_2048, sizeof_server_key_der_2048,
                    RSAk, NULL, 0)), 0);
    server_key = (const unsigned char*)buf;
    ExpectNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey, &server_key,
                (long)bufSz));
    }
#endif


    EVP_PKEY_free(pkey);
    pkey = NULL;
    SSL_free(ssl); /* frees x509 also since loaded into ssl */
    ssl = NULL;
    SSL_CTX_free(ctx);
    ctx = NULL;
#endif /* end of RSA private key match tests */


#ifdef HAVE_ECC
    #ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
    #else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
    #endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, eccCertFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, eccKeyFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif
    SSL_free(ssl);
    ssl = NULL;


    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, cliEccKeyFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
    ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif

    SSL_free(ssl);
    ssl = NULL;
    SSL_CTX_free(ctx);
    ctx = NULL;
#endif /* end of ECC private key match tests */

#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
    #ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
    #else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
    #endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, edCertFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, edKeyFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif
    SSL_free(ssl);
    ssl = NULL;


    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, cliEdKeyFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif

    SSL_free(ssl);
    ssl = NULL;
    SSL_CTX_free(ctx);
    ctx = NULL;
#endif /* end of Ed25519 private key match tests */

#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
    #ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
    #else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
    #endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, ed448CertFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, ed448KeyFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif
    SSL_free(ssl);
    ssl = NULL;


    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, cliEd448KeyFile,
                                                         WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    #if !defined(NO_CHECK_PRIVATE_KEY)
    ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
    #endif

    SSL_free(ssl);
    ssl = NULL;
    SSL_CTX_free(ctx);
    ctx = NULL;
#endif /* end of Ed448 private key match tests */

    EVP_cleanup();

    /* test existence of no-op macros in wolfssl/openssl/ssl.h */
    CONF_modules_free();
    ENGINE_cleanup();
    CONF_modules_unload();

    (void)ssl;
    (void)ctx;
    (void)pkey;
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_def_callback(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    char buf[10];
    const char* defpwd = "DEF PWD";
    int defpwdLen = (int)XSTRLEN(defpwd);
    int smallLen = 1;

    /* Bad parameters. */
    ExpectIntEQ(wolfSSL_PEM_def_callback(NULL, sizeof(buf), 0, NULL), 0);
    ExpectIntEQ(wolfSSL_PEM_def_callback(NULL, sizeof(buf), 0, (void*)defpwd),
        0);
    ExpectIntEQ(wolfSSL_PEM_def_callback(buf, sizeof(buf), 0, NULL), 0);

    XMEMSET(buf, 0, sizeof(buf));
    ExpectIntEQ(wolfSSL_PEM_def_callback(buf, sizeof(buf), 0, (void*)defpwd),
        defpwdLen);
    ExpectIntEQ(XMEMCMP(buf, defpwd, defpwdLen), 0);
    ExpectIntEQ(buf[defpwdLen], 0);
    /* Size of buffer is smaller than default password. */
    XMEMSET(buf, 0, sizeof(buf));
    ExpectIntEQ(wolfSSL_PEM_def_callback(buf, smallLen, 0, (void*)defpwd),
        smallLen);
    ExpectIntEQ(XMEMCMP(buf, defpwd, smallLen), 0);
    ExpectIntEQ(buf[smallLen], 0);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_read_PrivateKey(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && (!defined(NO_RSA) || \
    !defined(NO_DSA) || defined(HAVE_ECC) || !defined(NO_DH))
    XFILE file = XBADFILE;
#if !defined(NO_RSA)
    const char* fname_rsa = "./certs/server-key.pem";
    RSA* rsa = NULL;
    WOLFSSL_EVP_PKEY_CTX* ctx = NULL;
    unsigned char* sig = NULL;
    size_t sigLen = 0;
    const unsigned char tbs[] = {0, 1, 2, 3, 4, 5, 6, 7};
    size_t tbsLen = sizeof(tbs);
#endif
#if !defined(NO_DSA)
    const char* fname_dsa = "./certs/dsa2048.pem";
#endif
#if defined(HAVE_ECC)
    const char* fname_ec = "./certs/ecc-key.pem";
#endif
#if !defined(NO_DH)
    const char* fname_dh = "./certs/dh-priv-2048.pem";
#endif
    EVP_PKEY* pkey = NULL;

    /* Check error case. */
    ExpectNull(pkey = PEM_read_PrivateKey(NULL, NULL, NULL, NULL));

    /* not a PEM key. */
    ExpectTrue((file = XFOPEN("./certs/ecc-key.der", "rb")) != XBADFILE);
    ExpectNull(PEM_read_PrivateKey(file, NULL, NULL, NULL));
    if (file != XBADFILE)
        XFCLOSE(file);
    file = XBADFILE;

#ifndef NO_RSA
    /* Read in an RSA key. */
    ExpectTrue((file = XFOPEN(fname_rsa, "rb")) != XBADFILE);
    ExpectNotNull(pkey = PEM_read_PrivateKey(file, NULL, NULL, NULL));
    if (file != XBADFILE)
        XFCLOSE(file);
    file = XBADFILE;

    /* Make sure the key is usable by signing some data with it. */
    ExpectNotNull(rsa = EVP_PKEY_get0_RSA(pkey));
    ExpectIntGT((sigLen = RSA_size(rsa)), 0);
    ExpectNotNull(sig = (unsigned char*)XMALLOC(sigLen, HEAP_HINT,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));
    ExpectIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_sign(ctx, sig, &sigLen, tbs, tbsLen),
        WOLFSSL_SUCCESS);

    XFREE(sig, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey);
    pkey = NULL;
#endif

#ifndef NO_DSA
    /* Read in a DSA key. */
    ExpectTrue((file = XFOPEN(fname_dsa, "rb")) != XBADFILE);
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)
    ExpectNotNull(pkey = PEM_read_PrivateKey(file, NULL, NULL, NULL));
    EVP_PKEY_free(pkey);
    pkey = NULL;
#else
    ExpectNull(PEM_read_PrivateKey(file, NULL, NULL, NULL));
#endif
    if (file != XBADFILE)
        XFCLOSE(file);
    file = XBADFILE;
#endif

#ifdef HAVE_ECC
    /* Read in an EC key. */
    ExpectTrue((file = XFOPEN(fname_ec, "rb")) != XBADFILE);
    ExpectNotNull(pkey = EVP_PKEY_new());
    ExpectPtrEq(PEM_read_PrivateKey(file, &pkey, NULL, NULL), pkey);
    if (file != XBADFILE)
        XFCLOSE(file);
    file = XBADFILE;
    EVP_PKEY_free(pkey);
    pkey = NULL;
#endif

#ifndef NO_DH
    /* Read in a DH key. */
    ExpectTrue((file = XFOPEN(fname_dh, "rb")) != XBADFILE);
#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || \
     defined(WOLFSSL_OPENSSH)) && (!defined(HAVE_FIPS) || \
     (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
    ExpectNotNull(pkey = PEM_read_PrivateKey(file, NULL, NULL, NULL));
    EVP_PKEY_free(pkey);
    pkey = NULL;
#else
    ExpectNull(PEM_read_PrivateKey(file, NULL, NULL, NULL));
#endif
    if (file != XBADFILE)
        XFCLOSE(file);
    file = XBADFILE;
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_read_PUBKEY(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) \
    && !defined(NO_FILESYSTEM)
    XFILE file = XBADFILE;
    const char* fname = "./certs/client-keyPub.pem";
    EVP_PKEY* pkey = NULL;

    /* Check error case. */
    ExpectNull(pkey = PEM_read_PUBKEY(NULL, NULL, NULL, NULL));

    /* Read in an RSA key. */
    ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
    ExpectNotNull(pkey = PEM_read_PUBKEY(file, NULL, NULL, NULL));
    EVP_PKEY_free(pkey);
    pkey = NULL;
    if (file != XBADFILE)
        XFCLOSE(file);
    file = XBADFILE;
    ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
    ExpectNotNull(pkey = EVP_PKEY_new());
    ExpectPtrEq(PEM_read_PUBKEY(file, &pkey, NULL, NULL), pkey);
    EVP_PKEY_free(pkey);
    if (file != XBADFILE)
        XFCLOSE(file);
#endif
    return EXPECT_RESULT();
}

/* test loading RSA key using BIO */
static int test_wolfSSL_PEM_PrivateKey_rsa(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    defined(USE_CERT_BUFFERS_2048) && !defined(NO_FILESYSTEM) && \
    !defined(NO_BIO)
    BIO*      bio = NULL;
    XFILE file = XBADFILE;
    const char* fname = "./certs/server-key.pem";
    const char* fname_rsa_p8 = "./certs/server-keyPkcs8.pem";
    EVP_PKEY* pkey  = NULL;
    size_t sz = 0;
    byte* buf = NULL;
    EVP_PKEY* pkey2 = NULL;
    EVP_PKEY* pkey3 = NULL;
    RSA* rsa_key = NULL;
#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)
    unsigned char extra[10];
    int i;
    BIO* pub_bio = NULL;
    const unsigned char* server_key = (const unsigned char*)server_key_der_2048;
#endif

    ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
    ExpectTrue(XFSEEK(file, 0, XSEEK_END) == 0);
    ExpectIntGT(sz = XFTELL(file), 0);
    ExpectTrue(XFSEEK(file, 0, XSEEK_SET) == 0);
    ExpectNotNull(buf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE));
    if (buf != NULL) {
        ExpectIntEQ(XFREAD(buf, 1, sz, file), sz);
    }
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }

    /* Test using BIO new mem and loading PEM private key */
    ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
    ExpectNotNull((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)));
    XFREE(buf, NULL, DYNAMIC_TYPE_FILE);
    buf = NULL;
    BIO_free(bio);
    bio = NULL;

    /* New empty EVP_PKEY */
    ExpectNotNull(pkey2 = EVP_PKEY_new());
    if (pkey2 != NULL) {
        pkey2->type = EVP_PKEY_RSA;
    }
    /* Test parameter copy */
    ExpectIntEQ(EVP_PKEY_copy_parameters(pkey2, pkey), 0);
    EVP_PKEY_free(pkey2);
    EVP_PKEY_free(pkey);
    pkey  = NULL;

    /* Qt unit test case : rsa pkcs8 key */
    ExpectTrue((file = XFOPEN(fname_rsa_p8, "rb")) != XBADFILE);
    ExpectTrue(XFSEEK(file, 0, XSEEK_END) == 0);
    ExpectIntGT(sz = XFTELL(file), 0);
    ExpectTrue(XFSEEK(file, 0, XSEEK_SET) == 0);
    ExpectNotNull(buf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE));
    if (buf) {
        ExpectIntEQ(XFREAD(buf, 1, sz, file), sz);
    }
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }

    ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
    ExpectNotNull((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)));
    XFREE(buf, NULL, DYNAMIC_TYPE_FILE);
    buf = NULL;
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(pkey3 = EVP_PKEY_new());

    ExpectNotNull(rsa_key = EVP_PKEY_get1_RSA(pkey));
    ExpectIntEQ(EVP_PKEY_set1_RSA(pkey3, rsa_key), WOLFSSL_SUCCESS);

#ifdef WOLFSSL_ERROR_CODE_OPENSSL
    ExpectIntEQ(EVP_PKEY_cmp(pkey, pkey3), 1/* match */);
#else
    ExpectIntEQ(EVP_PKEY_cmp(pkey, pkey3), 0);
#endif

    RSA_free(rsa_key);
    EVP_PKEY_free(pkey3);
    EVP_PKEY_free(pkey);
    pkey  = NULL;
    pkey2 = NULL;

#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)
    #define BIO_PEM_TEST_CHAR 'a'
    XMEMSET(extra, BIO_PEM_TEST_CHAR, sizeof(extra));

    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(BIO_set_write_buf_size(bio, 4096), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectNotNull(pub_bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(BIO_set_write_buf_size(pub_bio, 4096), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectNull(d2i_PrivateKey(EVP_PKEY_EC, &pkey, &server_key,
        (long)sizeof_server_key_der_2048));
    ExpectNull(pkey);

    ExpectNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey, &server_key,
        (long)sizeof_server_key_der_2048));
    ExpectIntEQ(PEM_write_bio_PrivateKey(NULL, pkey, NULL, NULL, 0, NULL, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_bio_PrivateKey(bio,  NULL, NULL, NULL, 0, NULL, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_bio_PrivateKey(bio,  pkey, NULL, NULL, 0, NULL, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntGT(BIO_pending(bio), 0);
    ExpectIntEQ(BIO_pending(bio), 1679);
    /* Check if the pubkey API writes only the public key */
#ifdef WOLFSSL_KEY_GEN
    ExpectIntEQ(PEM_write_bio_PUBKEY(NULL, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_bio_PUBKEY(pub_bio, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_bio_PUBKEY(pub_bio, pkey), WOLFSSL_SUCCESS);
    ExpectIntGT(BIO_pending(pub_bio), 0);
    /* Previously both the private key and the pubkey calls would write
     * out the private key and the PEM header was the only difference.
     * The public PEM should be significantly shorter than the
     * private key versison. */
    ExpectIntEQ(BIO_pending(pub_bio), 451);
#else
    /* Not supported. */
    ExpectIntEQ(PEM_write_bio_PUBKEY(pub_bio, pkey), 0);
#endif

    /* test creating new EVP_PKEY with good args */
    ExpectNotNull((pkey2 = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)));
    if (pkey && pkey->pkey.ptr && pkey2 && pkey2->pkey.ptr) {
        ExpectIntEQ((int)XMEMCMP(pkey->pkey.ptr, pkey2->pkey.ptr,
            pkey->pkey_sz), 0);
    }

    /* test of reuse of EVP_PKEY */
    ExpectNull(PEM_read_bio_PrivateKey(bio, &pkey, NULL, NULL));
    ExpectIntEQ(BIO_pending(bio), 0);
    ExpectIntEQ(PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL),
            SSL_SUCCESS);
    /* add 10 extra bytes after PEM */
    ExpectIntEQ(BIO_write(bio, extra, 10), 10);
    ExpectNotNull(PEM_read_bio_PrivateKey(bio, &pkey, NULL, NULL));
    ExpectNotNull(pkey);
    if (pkey && pkey->pkey.ptr && pkey2 && pkey2->pkey.ptr) {
        ExpectIntEQ((int)XMEMCMP(pkey->pkey.ptr, pkey2->pkey.ptr,
            pkey->pkey_sz), 0);
    }
    /* check 10 extra bytes still there */
    ExpectIntEQ(BIO_pending(bio), 10);
    ExpectIntEQ(BIO_read(bio, extra, 10), 10);
    for (i = 0; i < 10; i++) {
        ExpectIntEQ(extra[i], BIO_PEM_TEST_CHAR);
    }

    BIO_free(pub_bio);
    BIO_free(bio);
    bio = NULL;
    EVP_PKEY_free(pkey);
    pkey  = NULL;
    EVP_PKEY_free(pkey2);
#endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN */
#endif /* OPENSSL_EXTRA && !NO_CERTS && !NO_RSA && USE_CERT_BUFFERS_2048 &&
        * !NO_FILESYSTEM && !NO_BIO */
    return EXPECT_RESULT();
}

/* test loading ECC key using BIO */
static int test_wolfSSL_PEM_PrivateKey_ecc(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && defined(HAVE_ECC) && \
    !defined(NO_FILESYSTEM) && !defined(NO_BIO)
    BIO*      bio = NULL;
    EVP_PKEY* pkey  = NULL;
    XFILE file = XBADFILE;
    const char* fname = "./certs/ecc-key.pem";
    const char* fname_ecc_p8  = "./certs/ecc-keyPkcs8.pem";

    size_t sz = 0;
    byte* buf = NULL;
    EVP_PKEY* pkey2 = NULL;
    EVP_PKEY* pkey3 = NULL;
    EC_KEY*   ec_key = NULL;
    int nid = 0;
    BIO* pub_bio = NULL;

    ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
    ExpectTrue(XFSEEK(file, 0, XSEEK_END) == 0);
    ExpectIntGT(sz = XFTELL(file), 0);
    ExpectTrue(XFSEEK(file, 0, XSEEK_SET) == 0);
    ExpectNotNull(buf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE));
    if (buf) {
        ExpectIntEQ(XFREAD(buf, 1, sz, file), sz);
    }
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }

    /* Test using BIO new mem and loading PEM private key */
    ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
    ExpectNotNull((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)));
    BIO_free(bio);
    bio = NULL;
    XFREE(buf, NULL, DYNAMIC_TYPE_FILE);
    buf = NULL;
    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectNotNull(pub_bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntGT(BIO_pending(bio), 0);
    /* No parameters. */
    ExpectIntEQ(BIO_pending(bio), 227);
    /* Check if the pubkey API writes only the public key */
#ifdef WOLFSSL_KEY_GEN
    ExpectIntEQ(PEM_write_bio_PUBKEY(pub_bio, pkey), WOLFSSL_SUCCESS);
    ExpectIntGT(BIO_pending(pub_bio), 0);
    /* Previously both the private key and the pubkey calls would write
     * out the private key and the PEM header was the only difference.
     * The public PEM should be significantly shorter than the
     * private key versison. */
    ExpectIntEQ(BIO_pending(pub_bio), 178);
#endif
    BIO_free(pub_bio);
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(pkey2 = EVP_PKEY_new());
    ExpectNotNull(pkey3 = EVP_PKEY_new());
    if (pkey2 != NULL) {
         pkey2->type = EVP_PKEY_EC;
    }
    /* Test parameter copy */
    ExpectIntEQ(EVP_PKEY_copy_parameters(pkey2, pkey), 1);


    /* Qt unit test case 1*/
    ExpectNotNull(ec_key = EVP_PKEY_get1_EC_KEY(pkey));
    ExpectIntEQ(EVP_PKEY_set1_EC_KEY(pkey3, ec_key), WOLFSSL_SUCCESS);
    #ifdef WOLFSSL_ERROR_CODE_OPENSSL
    ExpectIntEQ(EVP_PKEY_cmp(pkey, pkey3), 1/* match */);
    #else
    ExpectIntEQ(EVP_PKEY_cmp(pkey, pkey3), 0);
    #endif
    /* Test default digest */
    ExpectIntEQ(EVP_PKEY_get_default_digest_nid(pkey, &nid), 1);
    ExpectIntEQ(nid, NID_sha256);
    EC_KEY_free(ec_key);
    ec_key = NULL;
    EVP_PKEY_free(pkey3);
    pkey3 = NULL;
    EVP_PKEY_free(pkey2);
    pkey2 = NULL;
    EVP_PKEY_free(pkey);
    pkey  = NULL;

    /* Qt unit test case ec pkcs8 key */
    ExpectTrue((file = XFOPEN(fname_ecc_p8, "rb")) != XBADFILE);
    ExpectTrue(XFSEEK(file, 0, XSEEK_END) == 0);
    ExpectIntGT(sz = XFTELL(file), 0);
    ExpectTrue(XFSEEK(file, 0, XSEEK_SET) == 0);
    ExpectNotNull(buf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE));
    if (buf) {
        ExpectIntEQ(XFREAD(buf, 1, sz, file), sz);
    }
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }

    ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
    ExpectNotNull((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)));
    XFREE(buf, NULL, DYNAMIC_TYPE_FILE);
    buf = NULL;
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(pkey3 = EVP_PKEY_new());
    /* Qt unit test case */
    ExpectNotNull(ec_key = EVP_PKEY_get1_EC_KEY(pkey));
    ExpectIntEQ(EVP_PKEY_set1_EC_KEY(pkey3, ec_key), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
    ExpectIntEQ(EVP_PKEY_cmp(pkey, pkey3), 1/* match */);
#else
    ExpectIntEQ(EVP_PKEY_cmp(pkey, pkey3), 0);
#endif
    EC_KEY_free(ec_key);
    EVP_PKEY_free(pkey3);
    EVP_PKEY_free(pkey);
    pkey  = NULL;
#endif
    return EXPECT_RESULT();
}

/* test loading DSA key using BIO */
static int test_wolfSSL_PEM_PrivateKey_dsa(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_DSA) && \
    !defined(NO_FILESYSTEM) && !defined(NO_BIO)
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
    BIO*      bio = NULL;
    EVP_PKEY* pkey  = NULL;

    ExpectNotNull(bio = BIO_new_file("./certs/dsa2048.pem", "rb"));
    /* Private DSA EVP_PKEY */
    ExpectNotNull(pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, NULL,
        NULL));
    BIO_free(bio);
    bio = NULL;

    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
#if defined(OPENSSL_ALL) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
#ifdef WOLFSSL_ASN_TEMPLATE
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
        NULL), 1216);
#else
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
        NULL), 1212);
#endif
#endif

#ifdef WOLFSSL_KEY_GEN
    ExpectIntEQ(PEM_write_bio_PUBKEY(bio, pkey), 1);
#ifdef WOLFSSL_ASN_TEMPLATE
    ExpectIntEQ(BIO_pending(bio), 2394);
#else
    ExpectIntEQ(BIO_pending(bio), 2390);
#endif
    BIO_reset(bio);
#endif

    ExpectIntEQ(PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL),
        1);
    ExpectIntEQ(BIO_pending(bio), 1196);

    BIO_free(bio);
    bio = NULL;

    EVP_PKEY_free(pkey);
    pkey  = NULL;
#endif
#endif
    return EXPECT_RESULT();
}

/* test loading DH key using BIO */
static int test_wolfSSL_PEM_PrivateKey_dh(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_DH) && \
    !defined(NO_FILESYSTEM) && !defined(NO_BIO)
#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || \
     defined(WOLFSSL_OPENSSH)) && (!defined(HAVE_FIPS) || \
     (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
    BIO*      bio = NULL;
    EVP_PKEY* pkey  = NULL;
    int       expectedBytes = 0;

    ExpectNotNull(bio = BIO_new_file("./certs/dh-priv-2048.pem", "rb"));
    /* Private DH EVP_PKEY */
    ExpectNotNull(pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, NULL,
        NULL));
    BIO_free(bio);
    bio = NULL;

    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));

#if defined(OPENSSL_ALL) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
    expectedBytes += 806;
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
        NULL), expectedBytes);
#endif
#ifdef WOLFSSL_KEY_GEN
    ExpectIntEQ(PEM_write_bio_PUBKEY(bio, pkey), 0);
#endif

    ExpectIntEQ(PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL),
        1);
    expectedBytes += 806;
    ExpectIntEQ(BIO_pending(bio), expectedBytes);

    BIO_free(bio);
    bio = NULL;

    EVP_PKEY_free(pkey);
    pkey  = NULL;
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_PrivateKey(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
    (!defined(NO_RSA) || defined(HAVE_ECC)) && defined(USE_CERT_BUFFERS_2048)
#ifndef NO_BIO
    BIO*      bio = NULL;
#endif
    EVP_PKEY* pkey  = NULL;
    const unsigned char* server_key = (const unsigned char*)server_key_der_2048;

#ifndef NO_BIO

    /* test creating new EVP_PKEY with bad arg */
    ExpectNull((pkey = PEM_read_bio_PrivateKey(NULL, NULL, NULL, NULL)));

    /* Test bad EVP_PKEY type. */
    /* New HMAC EVP_PKEY */
    ExpectNotNull(bio = BIO_new_mem_buf("", 1));
    ExpectNotNull(pkey = EVP_PKEY_new());
    if (pkey != NULL) {
        pkey->type = EVP_PKEY_HMAC;
    }
    ExpectIntEQ(PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL),
        0);
#if defined(OPENSSL_ALL) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
        NULL), 0);
#endif
#ifdef WOLFSSL_KEY_GEN
    ExpectIntEQ(PEM_write_bio_PUBKEY(bio, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
    EVP_PKEY_free(pkey);
    pkey = NULL;
    BIO_free(bio);
    bio = NULL;


    /* key is DES encrypted */
    #if !defined(NO_DES3) && defined(WOLFSSL_ENCRYPTED_KEYS) && \
        !defined(NO_RSA) && !defined(NO_BIO) && !defined(NO_FILESYSTEM) && \
        !defined(NO_MD5) && defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
    {
        XFILE f = XBADFILE;
        wc_pem_password_cb* passwd_cb = NULL;
        void* passwd_cb_userdata;
        SSL_CTX* ctx = NULL;
        char passwd[] = "bad password";

    #ifndef WOLFSSL_NO_TLS12
        #ifndef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = SSL_CTX_new(TLSv1_2_server_method()));
        #else
        ExpectNotNull(ctx = SSL_CTX_new(TLSv1_2_client_method()));
        #endif
    #else
        #ifndef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = SSL_CTX_new(wolfTLSv1_3_server_method()));
        #else
        ExpectNotNull(ctx = SSL_CTX_new(wolfTLSv1_3_client_method()));
        #endif
    #endif

        ExpectNotNull(bio = BIO_new_file("./certs/server-keyEnc.pem", "rb"));
        SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
        ExpectNotNull(passwd_cb = SSL_CTX_get_default_passwd_cb(ctx));
        ExpectNull(passwd_cb_userdata =
            SSL_CTX_get_default_passwd_cb_userdata(ctx));

        /* fail case with password call back */
        ExpectNull(pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL,
                    (void*)passwd));
        BIO_free(bio);
        ExpectNotNull(bio = BIO_new_file("./certs/server-keyEnc.pem", "rb"));
        ExpectNull(pkey = PEM_read_bio_PrivateKey(bio, NULL, passwd_cb,
                    (void*)passwd));
        BIO_free(bio);

        ExpectTrue((f = XFOPEN("./certs/server-keyEnc.pem", "rb")) != XBADFILE);
        ExpectNotNull(bio = BIO_new_fp(f, BIO_CLOSE));
        if ((bio == NULL) && (f != XBADFILE)) {
            XFCLOSE(f);
        }

        /* use callback that works */
        ExpectNotNull(pkey = PEM_read_bio_PrivateKey(bio, NULL, passwd_cb,
                (void*)"yassl123"));

        ExpectIntEQ(SSL_CTX_use_PrivateKey(ctx, pkey), SSL_SUCCESS);

        EVP_PKEY_free(pkey);
        pkey  = NULL;
        BIO_free(bio);
        bio = NULL;
        SSL_CTX_free(ctx);
    }
    #endif /* !defined(NO_DES3) */

#endif /* !NO_BIO */

    #if defined(HAVE_ECC) && !defined(NO_FILESYSTEM)
    {
        unsigned char buf[2048];
        size_t bytes = 0;
        XFILE f = XBADFILE;
        SSL_CTX* ctx = NULL;

    #ifndef WOLFSSL_NO_TLS12
        #ifndef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = SSL_CTX_new(TLSv1_2_server_method()));
        #else
        ExpectNotNull(ctx = SSL_CTX_new(TLSv1_2_client_method()));
        #endif
    #else
        #ifndef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = SSL_CTX_new(wolfTLSv1_3_server_method()));
        #else
        ExpectNotNull(ctx = SSL_CTX_new(wolfTLSv1_3_client_method()));
        #endif
    #endif

        ExpectTrue((f = XFOPEN("./certs/ecc-key.der", "rb")) != XBADFILE);
        ExpectIntGT(bytes = (size_t)XFREAD(buf, 1, sizeof(buf), f), 0);
        if (f != XBADFILE)
            XFCLOSE(f);

        server_key = buf;
        pkey = NULL;
        ExpectNull(d2i_PrivateKey(EVP_PKEY_RSA, &pkey, &server_key, (long int)bytes));
        ExpectNull(pkey);
        ExpectNotNull(d2i_PrivateKey(EVP_PKEY_EC, &pkey, &server_key, (long int)bytes));
        ExpectIntEQ(SSL_CTX_use_PrivateKey(ctx, pkey), SSL_SUCCESS);

        EVP_PKEY_free(pkey);
        pkey = NULL;
        SSL_CTX_free(ctx);
        server_key = NULL;
    }
    #endif

#ifndef NO_BIO
    (void)bio;
#endif
    (void)pkey;
    (void)server_key;
#endif /* OPENSSL_EXTRA && !NO_CERTS && !NO_RSA && USE_CERT_BUFFERS_2048 */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_file_RSAKey(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && \
    defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && \
    !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    RSA* rsa = NULL;
    XFILE fp = XBADFILE;

    ExpectTrue((fp = XFOPEN("./certs/rsa-pub-2048.pem", "rb")) != XBADFILE);
    ExpectNotNull((rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL)));
    if (fp != XBADFILE)
        XFCLOSE(fp);
    ExpectIntEQ(RSA_size(rsa), 256);

    ExpectIntEQ(PEM_write_RSAPublicKey(XBADFILE, rsa), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_RSAPublicKey(stderr, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_RSAPublicKey(stderr, rsa), WOLFSSL_SUCCESS);

    ExpectIntEQ(PEM_write_RSA_PUBKEY(XBADFILE, rsa), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_RSA_PUBKEY(stderr, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_RSA_PUBKEY(stderr, rsa), WOLFSSL_SUCCESS);

    RSA_free(rsa);
#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && \
         (defined(WOLFSSL_KEY_GEN) || WOLFSSL_CERT_GEN) && \
         !defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined(NO_CERTS) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_file_RSAPrivateKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \
    !defined(NO_FILESYSTEM) && \
    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
    RSA* rsa = NULL;
    XFILE f = NULL;

    ExpectTrue((f = XFOPEN(svrKeyFile, "r")) != XBADFILE);
    ExpectNotNull((rsa = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL)));
    ExpectIntEQ(RSA_size(rsa), 256);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    ExpectIntEQ(PEM_write_RSAPrivateKey(XBADFILE, rsa, NULL, NULL, 0, NULL,
        NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_RSAPrivateKey(stderr, NULL, NULL, NULL, 0, NULL,
        NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_RSAPrivateKey(stderr, rsa, NULL, NULL, 0, NULL, NULL),
        WOLFSSL_SUCCESS);

    RSA_free(rsa);

#ifdef HAVE_ECC
    ExpectTrue((f = XFOPEN(eccKeyFile, "r")) != XBADFILE);
    ExpectNull((rsa = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL)));
    if (f != XBADFILE)
        XFCLOSE(f);
#endif /* HAVE_ECC */
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_read_RSA_PUBKEY(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
       !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    XFILE file = XBADFILE;
    const char* fname = "./certs/client-keyPub.pem";
    RSA *rsa = NULL;

    ExpectNull(wolfSSL_PEM_read_RSA_PUBKEY(XBADFILE, NULL, NULL, NULL));

    ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
    ExpectNotNull((rsa = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL)));
    ExpectIntEQ(RSA_size(rsa), 256);
    RSA_free(rsa);
    if (file != XBADFILE)
       XFCLOSE(file);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */
    return EXPECT_RESULT();
}

#ifndef NO_BIO
static int test_wolfSSL_PEM_bio_RSAKey(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && \
    defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && \
    !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    RSA* rsa = NULL;
    BIO* bio = NULL;

    /* PrivateKey */
    ExpectNotNull(bio = BIO_new_file(svrKeyFile, "rb"));
    ExpectNull((rsa = PEM_read_bio_RSAPrivateKey(NULL, NULL, NULL, NULL)));
    ExpectNotNull(PEM_read_bio_RSAPrivateKey(bio, &rsa, NULL, NULL));
    ExpectNotNull(rsa);
    ExpectIntEQ(RSA_size(rsa), 256);
    ExpectIntEQ(PEM_write_bio_RSAPrivateKey(NULL, NULL, NULL, NULL, 0, NULL, \
                                            NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, \
                                            NULL), WOLFSSL_SUCCESS);
    BIO_free(bio);
    bio = NULL;
    RSA_free(rsa);
    rsa = NULL;

    /* PUBKEY */
    ExpectNotNull(bio = BIO_new_file("./certs/rsa-pub-2048.pem", "rb"));
    ExpectNull((rsa = PEM_read_bio_RSA_PUBKEY(NULL, NULL, NULL, NULL)));
    ExpectNotNull((rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)));
    ExpectIntEQ(RSA_size(rsa), 256);
    ExpectIntEQ(PEM_write_bio_RSA_PUBKEY(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_RSA_PUBKEY(bio, rsa), WOLFSSL_SUCCESS);
    BIO_free(bio);
    bio = NULL;

    RSA_free(rsa);
    rsa = NULL;

    /* Ensure that keys beginning with BEGIN RSA PUBLIC KEY can be read, too. */
    ExpectNotNull(bio = BIO_new_file("./certs/server-keyPub.pem", "rb"));
    ExpectNotNull((rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)));
    BIO_free(bio);
    bio = NULL;
    RSA_free(rsa);
    rsa = NULL;

    #ifdef HAVE_ECC
    /* ensure that non-rsa keys do not work */
    ExpectNotNull(bio = BIO_new_file(eccKeyFile, "rb")); /* ecc key */
    ExpectNull((rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL)));
    ExpectNull((rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)));
    BIO_free(bio);
    bio = NULL;
    RSA_free(rsa);
    rsa = NULL;
    #endif /* HAVE_ECC */
#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && \
         (defined(WOLFSSL_KEY_GEN) || WOLFSSL_CERT_GEN) && \
         !defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined(NO_CERTS) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_bio_RSAPrivateKey(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    RSA* rsa = NULL;
    RSA* rsa_dup = NULL;
    BIO* bio = NULL;

    ExpectNotNull(bio = BIO_new_file(svrKeyFile, "rb"));
    ExpectNotNull((rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL)));
    ExpectIntEQ(RSA_size(rsa), 256);

#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
    ExpectNull(rsa_dup = RSAPublicKey_dup(NULL));
    /* Test duplicating empty key. */
    ExpectNotNull(rsa_dup = RSA_new());
    ExpectNull(RSAPublicKey_dup(rsa_dup));
    RSA_free(rsa_dup);
    rsa_dup = NULL;
    ExpectNotNull(rsa_dup = RSAPublicKey_dup(rsa));
    ExpectPtrNE(rsa_dup, rsa);
#endif

    /* test if valgrind complains about unreleased memory */
    RSA_up_ref(rsa);
    RSA_free(rsa);

    BIO_free(bio);
    bio = NULL;
    RSA_free(rsa);
    rsa = NULL;
    RSA_free(rsa_dup);
    rsa_dup = NULL;

#ifdef HAVE_ECC
    ExpectNotNull(bio = BIO_new_file(eccKeyFile, "rb"));
    ExpectNull((rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL)));

    BIO_free(bio);
#endif /* HAVE_ECC */
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_bio_DSAKey(void)
{
    EXPECT_DECLS;
#ifndef HAVE_SELFTEST
#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) && !defined(NO_CERTS) && \
    defined(WOLFSSL_KEY_GEN) && !defined(NO_FILESYSTEM) && !defined(NO_DSA)
    DSA* dsa = NULL;
    BIO* bio = NULL;

    /* PrivateKey */
    ExpectNotNull(bio = BIO_new_file("./certs/1024/dsa1024.pem", "rb"));
    ExpectNull((dsa = PEM_read_bio_DSAPrivateKey(NULL, NULL, NULL, NULL)));
    ExpectNotNull((dsa = PEM_read_bio_DSAPrivateKey(bio, NULL, NULL, NULL)));
    ExpectIntEQ(BN_num_bytes(dsa->g), 128);
    ExpectIntEQ(PEM_write_bio_DSAPrivateKey(NULL, NULL, NULL, NULL, 0, NULL,
        NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_DSAPrivateKey(bio, dsa, NULL, NULL, 0, NULL,
        NULL), WOLFSSL_SUCCESS);
    BIO_free(bio);
    bio = NULL;
    DSA_free(dsa);
    dsa = NULL;

    /* PUBKEY */
    ExpectNotNull(bio = BIO_new_file("./certs/1024/dsa-pub-1024.pem", "rb"));
    ExpectNull((dsa = PEM_read_bio_DSA_PUBKEY(NULL, NULL, NULL, NULL)));
    ExpectNotNull((dsa = PEM_read_bio_DSA_PUBKEY(bio, NULL, NULL, NULL)));
    ExpectIntEQ(BN_num_bytes(dsa->g), 128);
    ExpectIntEQ(PEM_write_bio_DSA_PUBKEY(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_DSA_PUBKEY(bio, dsa), WOLFSSL_SUCCESS);
    BIO_free(bio);
    bio = NULL;
    DSA_free(dsa);
    dsa = NULL;

    #ifdef HAVE_ECC
    /* ensure that non-dsa keys do not work */
    ExpectNotNull(bio = BIO_new_file(eccKeyFile, "rb")); /* ecc key */
    ExpectNull((dsa = PEM_read_bio_DSAPrivateKey(bio, NULL, NULL, NULL)));
    ExpectNull((dsa = PEM_read_bio_DSA_PUBKEY(bio, NULL, NULL, NULL)));
    BIO_free(bio);
    bio = NULL;
    DSA_free(dsa);
    dsa = NULL;
    #endif /* HAVE_ECC */
#endif /* defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) && \
         !defined(NO_CERTS) && defined(WOLFSSL_KEY_GEN) && \
         !defined(NO_FILESYSTEM) && !defined(NO_DSA) */
#endif /* HAVE_SELFTEST */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_bio_ECKey(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && \
    defined(WOLFSSL_KEY_GEN) && !defined(NO_FILESYSTEM) && defined(HAVE_ECC)
    EC_KEY* ec = NULL;
    EC_KEY* ec2;
    BIO* bio = NULL;
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
    unsigned char* pem = NULL;
    int pLen;
#endif
    static char ec_key_bad_1[] = "-----BEGIN PUBLIC KEY-----\n"
                                 "MAA=\n"
                                 "-----END PUBLIC KEY-----";
    static char ec_priv_key_bad_1[] = "-----BEGIN EC PRIVATE KEY-----\n"
                                      "MAA=\n"
                                      "-----END EC PRIVATE KEY-----";

    /* PrivateKey */
    ExpectNotNull(bio = BIO_new_file("./certs/ecc-key.pem", "rb"));
    ExpectNull((ec = PEM_read_bio_ECPrivateKey(NULL, NULL, NULL, NULL)));
    ec2 = NULL;
    ExpectNotNull((ec = PEM_read_bio_ECPrivateKey(bio, &ec2, NULL, NULL)));
    ExpectIntEQ(ec == ec2, 1);
    ExpectIntEQ(wc_ecc_size((ecc_key*)ec->internal), 32);
    ExpectIntEQ(PEM_write_bio_ECPrivateKey(NULL, NULL, NULL, NULL, 0, NULL,
        NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_bio_ECPrivateKey(bio, NULL, NULL, NULL, 0, NULL,
        NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_bio_ECPrivateKey(NULL, ec, NULL, NULL, 0, NULL, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    BIO_free(bio);
    bio = NULL;
    /* Public key data - fail. */
    ExpectNotNull(bio = BIO_new_file("./certs/ecc-client-keyPub.pem", "rb"));
    ExpectNull(PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_ECPrivateKey(bio, ec, NULL, NULL, 0, NULL, \
                                           NULL), WOLFSSL_SUCCESS);
    BIO_free(bio);
    bio = NULL;

    ExpectIntEQ(PEM_write_ECPrivateKey(XBADFILE, NULL, NULL, NULL, 0, NULL,
        NULL),WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_ECPrivateKey(stderr, NULL, NULL, NULL, 0, NULL, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_ECPrivateKey(XBADFILE, ec, NULL, NULL, 0, NULL, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_ECPrivateKey(stderr, ec, NULL, NULL, 0, NULL, NULL),
        WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_PEM_write_mem_ECPrivateKey(NULL, NULL, NULL, 0, NULL,
        NULL), 0);
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
    ExpectIntEQ(wolfSSL_PEM_write_mem_ECPrivateKey(ec, NULL, NULL, 0, NULL,
        NULL), 0);
    ExpectIntEQ(wolfSSL_PEM_write_mem_ECPrivateKey(NULL, NULL, NULL, 0, &pem,
        NULL), 0);
    ExpectIntEQ(wolfSSL_PEM_write_mem_ECPrivateKey(NULL, NULL, NULL, 0, NULL,
        &pLen), 0);
    ExpectIntEQ(wolfSSL_PEM_write_mem_ECPrivateKey(NULL, NULL, NULL, 0, &pem,
        &pLen), 0);
    ExpectIntEQ(wolfSSL_PEM_write_mem_ECPrivateKey(ec, NULL, NULL, 0, NULL,
        &pLen), 0);
    ExpectIntEQ(wolfSSL_PEM_write_mem_ECPrivateKey(ec, NULL, NULL, 0, &pem,
        NULL), 0);
    ExpectIntEQ(wolfSSL_PEM_write_mem_ECPrivateKey(ec, NULL, NULL, 0, &pem,
        &pLen), 1);
    ExpectIntGT(pLen, 0);
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    EC_KEY_free(ec);
    ec = NULL;

    /* PUBKEY */
    ExpectNotNull(bio = BIO_new_file("./certs/ecc-client-keyPub.pem", "rb"));
    ExpectNull((ec = PEM_read_bio_EC_PUBKEY(NULL, NULL, NULL, NULL)));
    ec2 = NULL;
    ExpectNotNull((ec = PEM_read_bio_EC_PUBKEY(bio, &ec2, NULL, NULL)));
    ExpectIntEQ(ec == ec2, 1);
    ExpectIntEQ(wc_ecc_size((ecc_key*)ec->internal), 32);
    ExpectIntEQ(PEM_write_bio_EC_PUBKEY(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    BIO_free(bio);
    bio = NULL;
    /* Test 0x30, 0x00 fails. */
    ExpectNotNull(bio = BIO_new_mem_buf((unsigned char*)ec_key_bad_1,
        sizeof(ec_key_bad_1)));
    ExpectNull(PEM_read_bio_EC_PUBKEY(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;

    /* Private key data - fail. */
    ExpectNotNull(bio = BIO_new_file("./certs/ecc-key.pem", "rb"));
    ExpectNull(PEM_read_bio_EC_PUBKEY(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_EC_PUBKEY(bio, ec), WOLFSSL_SUCCESS);
    BIO_free(bio);
    bio = NULL;

    /* Same test as above, but with a file pointer rather than a BIO. */
    ExpectIntEQ(PEM_write_EC_PUBKEY(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_EC_PUBKEY(NULL, ec), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_EC_PUBKEY(stderr, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_write_EC_PUBKEY(stderr, ec), WOLFSSL_SUCCESS);

    EC_KEY_free(ec);
    ec = NULL;

    #ifndef NO_RSA
    /* ensure that non-ec keys do not work */
    ExpectNotNull(bio = BIO_new_file(svrKeyFile, "rb")); /* rsa key */
    ExpectNull((ec = PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL)));
    ExpectNull((ec = PEM_read_bio_EC_PUBKEY(bio, NULL, NULL, NULL)));
    BIO_free(bio);
    bio = NULL;
    EC_KEY_free(ec);
    ec = NULL;
    #endif /* !NO_RSA */
    /* Test 0x30, 0x00 fails. */
    ExpectNotNull(bio = BIO_new_mem_buf((unsigned char*)ec_priv_key_bad_1,
        sizeof(ec_priv_key_bad_1)));
    ExpectNull(PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_PUBKEY(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
    BIO*      bio = NULL;
    EVP_PKEY* pkey  = NULL;

    /* test creating new EVP_PKEY with bad arg */
    ExpectNull((pkey = PEM_read_bio_PUBKEY(NULL, NULL, NULL, NULL)));

    /* test loading ECC key using BIO */
#if defined(HAVE_ECC) && !defined(NO_FILESYSTEM)
    {
        XFILE file = XBADFILE;
        const char* fname = "./certs/ecc-client-keyPub.pem";
        size_t sz = 0;
        byte* buf = NULL;

        EVP_PKEY* pkey2 = NULL;
        EC_KEY*   ec_key = NULL;

        ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
        ExpectIntEQ(XFSEEK(file, 0, XSEEK_END), 0);
        ExpectIntGT(sz = XFTELL(file), 0);
        ExpectIntEQ(XFSEEK(file, 0, XSEEK_SET), 0);
        ExpectNotNull(buf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE));
        if (buf != NULL) {
            ExpectIntEQ(XFREAD(buf, 1, sz, file), sz);
        }
        if (file != XBADFILE) {
            XFCLOSE(file);
        }

        /* Test using BIO new mem and loading PEM private key */
        ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
        ExpectNotNull((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)));
        BIO_free(bio);
        bio = NULL;
        EVP_PKEY_free(pkey);
        pkey = NULL;
        ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
        ExpectNotNull(pkey = EVP_PKEY_new());
        ExpectPtrEq(PEM_read_bio_PUBKEY(bio, &pkey, NULL, NULL), pkey);
        XFREE(buf, NULL, DYNAMIC_TYPE_FILE);
        BIO_free(bio);
        bio = NULL;

        /* Qt unit test case*/
        ExpectNotNull(pkey2 = EVP_PKEY_new());
        ExpectNotNull(ec_key = EVP_PKEY_get1_EC_KEY(pkey));
        ExpectIntEQ(EVP_PKEY_set1_EC_KEY(pkey2, ec_key), WOLFSSL_SUCCESS);
    #ifdef WOLFSSL_ERROR_CODE_OPENSSL
        ExpectIntEQ(EVP_PKEY_cmp(pkey, pkey2), 1/* match */);
    #else
        ExpectIntEQ(EVP_PKEY_cmp(pkey, pkey2), 0);
    #endif

        EC_KEY_free(ec_key);
        EVP_PKEY_free(pkey2);
        EVP_PKEY_free(pkey);
        pkey = NULL;
    }
#endif

    (void)bio;
    (void)pkey;
#endif
    return EXPECT_RESULT();
}

#endif /* !NO_BIO */

static int test_DSA_do_sign_verify(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
    !defined(NO_DSA)
    unsigned char digest[WC_SHA_DIGEST_SIZE];
    DSA_SIG* sig = NULL;
    DSA* dsa = NULL;
    word32  bytes;
    byte sigBin[DSA_SIG_SIZE];
    int dsacheck;

#ifdef USE_CERT_BUFFERS_1024
    byte    tmp[ONEK_BUF];

    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024);
    bytes = sizeof_dsa_key_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
    byte    tmp[TWOK_BUF];

    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048);
    bytes = sizeof_dsa_key_der_2048;
#else
    byte    tmp[TWOK_BUF];
    XFILE   fp = XBADFILE;

    XMEMSET(tmp, 0, sizeof(tmp));
    ExpectTrue((fp = XFOPEN("./certs/dsa2048.der", "rb") != XBADFILE);
    ExpectIntGT(bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), fp), 0);
    if (fp != XBADFILE)
        XFCLOSE(fp);
#endif /* END USE_CERT_BUFFERS_1024 */

    XMEMSET(digest, 202, sizeof(digest));

    ExpectNotNull(dsa = DSA_new());
    ExpectIntEQ(DSA_LoadDer(dsa, tmp, (int)bytes), 1);

    ExpectIntEQ(wolfSSL_DSA_do_sign(digest, sigBin, dsa), 1);
    ExpectIntEQ(wolfSSL_DSA_do_verify(digest, sigBin, dsa, &dsacheck), 1);

    ExpectNotNull(sig = DSA_do_sign(digest, WC_SHA_DIGEST_SIZE, dsa));
    ExpectIntEQ(DSA_do_verify(digest, WC_SHA_DIGEST_SIZE, sig, dsa), 1);

    DSA_SIG_free(sig);
    DSA_free(dsa);
#endif
#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
    return EXPECT_RESULT();
}

static int test_wolfSSL_tmp_dh(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA) && !defined(NO_DH) && !defined(NO_BIO)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    byte buff[6000];
    static const unsigned char p[] = {
        0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13, 0xba,
        0x59, 0x06, 0x3c, 0xbc, 0x30, 0xd5, 0xf5, 0x00,
        0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a, 0xc6,
        0x25, 0x27, 0x1c, 0xe8, 0xd2, 0x96, 0x53, 0x0a,
        0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84, 0xbf,
        0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1, 0x8a,
        0xc5, 0xbe, 0x72, 0x5c, 0xa7, 0xe7, 0x91, 0xe6,
        0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66, 0x48,
        0xc7, 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9, 0x3d,
        0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46, 0x3e, 0x19,
        0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d, 0x9f,
        0x2b, 0x96, 0x17, 0x39, 0x6d, 0x30, 0x8d, 0x2a,
        0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75, 0xe6,
        0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa, 0x04,
        0x83, 0x57, 0x30, 0xfb, 0xda, 0x76, 0x93, 0x38,
        0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c, 0xe5,
        0xb7, 0xc8, 0x09, 0xae, 0x6f, 0x50, 0x35, 0x8e,
        0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e, 0x5a,
        0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76, 0xcc,
        0x16, 0x30, 0xdb, 0x0c, 0xfc, 0xc5, 0x62, 0xa7,
        0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0, 0x36,
        0xf6, 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40, 0x90,
        0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3, 0x1a, 0xc3,
        0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4, 0x48,
        0x4e, 0x22, 0x73, 0x6f, 0xc3, 0x5f, 0xd4, 0x9a,
        0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90, 0xab,
        0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58, 0x4b,
        0xa6, 0xb9, 0xcd, 0x29, 0xbf, 0x68, 0x1f, 0x08,
        0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6, 0xb6,
        0x06, 0x65, 0xf7, 0xa6, 0xdc, 0x00, 0x67, 0x6b,
        0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7, 0xfa,
        0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f, 0x93
    };
    int pSz = (int)sizeof(p);
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
    !defined(HAVE_SELFTEST)
    static const unsigned char bad_p[] = {
        0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13, 0xba,
        0x59, 0x06, 0x3c, 0xbc, 0x30, 0xd5, 0xf5, 0x00,
        0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a, 0xc6,
        0x25, 0x27, 0x1c, 0xe8, 0xd2, 0x96, 0x53, 0x0a,
        0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84, 0xbf,
        0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1, 0x8a,
        0xc5, 0xbe, 0x72, 0x5c, 0xa7, 0xe7, 0x91, 0xe6,
        0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66, 0x48,
        0xc7, 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9, 0x3d,
        0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46, 0x3e, 0x19,
        0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d, 0x9f,
        0x2b, 0x96, 0x17, 0x39, 0x6d, 0x30, 0x8d, 0x2a,
        0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75, 0xe6,
        0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa, 0x04,
        0x83, 0x57, 0x30, 0xfb, 0xda, 0x76, 0x93, 0x38,
        0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c, 0xe5,
        0xb7, 0xc8, 0x09, 0xae, 0x6f, 0x50, 0x35, 0x8e,
        0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e, 0x5a,
        0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76, 0xcc,
        0x16, 0x30, 0xdb, 0x0c, 0xfc, 0xc5, 0x62, 0xa7,
        0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0, 0x36,
        0xf6, 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40, 0x90,
        0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3, 0x1a, 0xc3,
        0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4, 0x48,
        0x4e, 0x22, 0x73, 0x6f, 0xc3, 0x5f, 0xd4, 0x9a,
        0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90, 0xab,
        0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58, 0x4b,
        0xa6, 0xb9, 0xcd, 0x29, 0xbf, 0x68, 0x1f, 0x08,
        0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6, 0xb6,
        0x06, 0x65, 0xf7, 0xa6, 0xdc, 0x00, 0x67, 0x6b,
        0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7, 0xfa,
        0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f, 0x91
    };
#endif
    static const unsigned char g[] = { 0x02 };
    int gSz = (int)sizeof(g);
#if !defined(NO_DSA)
    char file[] = "./certs/dsaparams.pem";
    DSA* dsa = NULL;
#else
    char file[] = "./certs/dh2048.pem";
#endif
    XFILE f = XBADFILE;
    int  bytes = 0;
    DH*  dh = NULL;
    DH*  dh2 = NULL;
    BIO*     bio = NULL;
    SSL*     ssl = NULL;
    SSL_CTX* ctx = NULL;
#ifndef NO_WOLFSSL_CLIENT
    SSL*     ssl_c = NULL;
    SSL_CTX* ctx_c = NULL;
#endif

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));
#endif
#ifndef NO_WOLFSSL_CLIENT
    ExpectNotNull(ctx_c = SSL_CTX_new(wolfSSLv23_client_method()));
    ExpectTrue(SSL_CTX_use_certificate_file(ctx_c, svrCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx_c, svrKeyFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(ssl_c = SSL_new(ctx_c));
#ifdef NO_WOLFSSL_SERVER
    ctx = ctx_c;
    ssl = ssl_c;
#endif
#endif

    XMEMSET(buff, 0, sizeof(buff));
    ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectNotNull(bio = BIO_new_mem_buf((void*)buff, bytes));

#if !defined(NO_DSA)
    dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
    ExpectNotNull(dsa);

    dh = wolfSSL_DSA_dup_DH(dsa);
#else
    dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
#endif
    ExpectNotNull(dh);
#if defined(WOLFSSL_DH_EXTRA) && \
    (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH))
    ExpectNotNull(dh2 = wolfSSL_DH_dup(dh));
    DH_free(dh2);
    dh2 = NULL;
#endif

    /* Failure cases */
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(NULL, NULL, 0, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , NULL, 0, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(NULL, p   , 0, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(NULL, NULL, 0, g   , 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , p  , 0, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , NULL, 0, g   , 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(NULL, p   , 0, g   , 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , p   , 1, g   , 1),
        WC_NO_ERR_TRACE(DH_KEY_SIZE_E));
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , buff, 6000, g   , 1),
        WC_NO_ERR_TRACE(DH_KEY_SIZE_E));
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
    !defined(HAVE_SELFTEST)
    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx, bad_p, pSz, g, gSz),
        WC_NO_ERR_TRACE(DH_CHECK_PUB_E));
#endif
    ExpectIntEQ((int)wolfSSL_SetTmpDH(NULL, NULL, 0, NULL, 0),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , NULL, 0, NULL, 0),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ((int)wolfSSL_SetTmpDH(NULL, p   , 0, NULL, 0),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ((int)wolfSSL_SetTmpDH(NULL, NULL, 0, g   , 0),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , p  , 0, NULL, 0),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , NULL, 0, g   , 0),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ((int)wolfSSL_SetTmpDH(NULL, p   , 0, g   , 0),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , p   , 1, g   , 1),
        WC_NO_ERR_TRACE(DH_KEY_SIZE_E));
    ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , buff, 6000, g   , 1),
        WC_NO_ERR_TRACE(DH_KEY_SIZE_E));
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
    !defined(HAVE_SELFTEST)
#ifndef NO_WOLFSSL_SERVER
    /* Parameters will be tested later so it passes now. */
    ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl, bad_p, pSz, g, gSz),
        WOLFSSL_SUCCESS);
#endif
#endif
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl_c, p, pSz, g, gSz),
        WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
    ExpectIntEQ((int)SSL_CTX_set_tmp_dh(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)SSL_CTX_set_tmp_dh(ctx , NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)SSL_CTX_set_tmp_dh(NULL, dh  ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)SSL_set_tmp_dh(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)SSL_set_tmp_dh(ssl , NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ((int)SSL_set_tmp_dh(NULL, dh  ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* No p/g to use. */
    dh2 = wolfSSL_DH_new();
    ExpectIntEQ((int)SSL_CTX_set_tmp_dh(ctx , dh2 ), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ((int)SSL_set_tmp_dh(ssl , dh2 ), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    DH_free(dh2);
    dh2 = NULL;

    ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ((int)SSL_CTX_set_tmp_dh(ctx, dh), WOLFSSL_SUCCESS);
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ((int)SSL_set_tmp_dh(ssl, dh), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ((int)SSL_set_tmp_dh(ssl, dh), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif

    BIO_free(bio);
#if !defined(NO_DSA)
    DSA_free(dsa);
#endif
    DH_free(dh);
    dh = NULL;
#ifndef NO_WOLFSSL_CLIENT
    if (ssl != ssl_c) {
        SSL_free(ssl_c);
    }
#endif
    SSL_free(ssl);
#ifndef NO_WOLFSSL_CLIENT
    if (ctx != ctx_c) {
        SSL_CTX_free(ctx_c);
    }
#endif
    SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ctrl(void)
{
    EXPECT_DECLS;
#if defined (OPENSSL_EXTRA) && !defined(NO_BIO)
    byte buff[6000];
    BIO* bio = NULL;
    int  bytes;
    BUF_MEM* ptr = NULL;

    XMEMSET(buff, 0, sizeof(buff));

    bytes = sizeof(buff);
    ExpectNotNull(bio = BIO_new_mem_buf((void*)buff, bytes));
    ExpectNotNull(BIO_s_socket());

    ExpectIntEQ((int)wolfSSL_BIO_get_mem_ptr(bio, &ptr), WOLFSSL_SUCCESS);

    /* needs tested after stubs filled out @TODO
        SSL_ctrl
        SSL_CTX_ctrl
    */

    BIO_free(bio);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_BIO) */
    return EXPECT_RESULT();
}


static int test_wolfSSL_EVP_PKEY_new_mac_key(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    static const unsigned char pw[] = "password";
    static const int pwSz = sizeof(pw) - 1;
    size_t checkPwSz = 0;
    const unsigned char* checkPw = NULL;
    WOLFSSL_EVP_PKEY* key = NULL;

    ExpectNull(key = wolfSSL_EVP_PKEY_new_mac_key(0, NULL, pw, pwSz));
    ExpectNull(key = wolfSSL_EVP_PKEY_new_mac_key(0, NULL, NULL, pwSz));

    ExpectNotNull(key = wolfSSL_EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, pw,
        pwSz));
    if (key != NULL) {
        ExpectIntEQ(key->type, EVP_PKEY_HMAC);
        ExpectIntEQ(key->save_type, EVP_PKEY_HMAC);
        ExpectIntEQ(key->pkey_sz, pwSz);
        ExpectIntEQ(XMEMCMP(key->pkey.ptr, pw, pwSz), 0);
    }
    ExpectNotNull(checkPw = wolfSSL_EVP_PKEY_get0_hmac(key, &checkPwSz));
    ExpectIntEQ((int)checkPwSz, pwSz);
    ExpectIntEQ(XMEMCMP(checkPw, pw, pwSz), 0);
    wolfSSL_EVP_PKEY_free(key);
    key = NULL;

    ExpectNotNull(key = wolfSSL_EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, pw,
        0));
    ExpectIntEQ(key->pkey_sz, 0);
    if (EXPECT_SUCCESS()) {
        /* Allocation for key->pkey.ptr may fail - OK key len is 0 */
        checkPw = wolfSSL_EVP_PKEY_get0_hmac(key, &checkPwSz);
    }
    ExpectTrue((checkPwSz == 0) || (checkPw != NULL));
    ExpectIntEQ((int)checkPwSz, 0);
    wolfSSL_EVP_PKEY_free(key);
    key = NULL;

    ExpectNotNull(key = wolfSSL_EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, NULL,
        0));
    ExpectIntEQ(key->pkey_sz, 0);
    if (EXPECT_SUCCESS()) {
        /* Allocation for key->pkey.ptr may fail - OK key len is 0 */
        checkPw = wolfSSL_EVP_PKEY_get0_hmac(key, &checkPwSz);
    }
    ExpectTrue((checkPwSz == 0) || (checkPw != NULL));
    ExpectIntEQ((int)checkPwSz, 0);
    wolfSSL_EVP_PKEY_free(key);
    key = NULL;
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}


static int test_wolfSSL_EVP_PKEY_new_CMAC_key(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
    const char *priv = "ABCDEFGHIJKLMNOP";
    const WOLFSSL_EVP_CIPHER* cipher = EVP_aes_128_cbc();
    WOLFSSL_EVP_PKEY* key = NULL;

    ExpectNull(key = wolfSSL_EVP_PKEY_new_CMAC_key(
        NULL, NULL, AES_128_KEY_SIZE, cipher));
    ExpectNull(key = wolfSSL_EVP_PKEY_new_CMAC_key(
        NULL, (const unsigned char *)priv, 0, cipher));
    ExpectNull(key = wolfSSL_EVP_PKEY_new_CMAC_key(
        NULL, (const unsigned char *)priv, AES_128_KEY_SIZE, NULL));

    ExpectNotNull(key = wolfSSL_EVP_PKEY_new_CMAC_key(
        NULL, (const unsigned char *)priv, AES_128_KEY_SIZE, cipher));
    wolfSSL_EVP_PKEY_free(key);
#endif /* WOLFSSL_CMAC && !NO_AES && WOLFSSL_AES_DIRECT */
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_Digest(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SHA256) && !defined(NO_PWDBASED)
    const char* in = "abc";
    int   inLen = (int)XSTRLEN(in);
    byte  out[WC_SHA256_DIGEST_SIZE];
    unsigned int outLen;
    const char* expOut =
        "\xBA\x78\x16\xBF\x8F\x01\xCF\xEA\x41\x41\x40\xDE\x5D\xAE\x22"
        "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00"
        "\x15\xAD";

    ExpectIntEQ(wolfSSL_EVP_Digest((unsigned char*)in, inLen, out, &outLen,
        "SHA256", NULL), 1);
    ExpectIntEQ(outLen, WC_SHA256_DIGEST_SIZE);
    ExpectIntEQ(XMEMCMP(out, expOut, WC_SHA256_DIGEST_SIZE), 0);
#endif /* OPEN_EXTRA && ! NO_SHA256 */
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_Digest_all(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    const char* digests[] = {
#ifndef NO_MD5
        "MD5",
#endif
#ifndef NO_SHA
        "SHA",
#endif
#ifdef WOLFSSL_SHA224
        "SHA224",
#endif
#ifndef NO_SHA256
        "SHA256",
#endif
#ifdef WOLFSSL_SHA384
        "SHA384",
#endif
#ifdef WOLFSSL_SHA512
        "SHA512",
#endif
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224)
        "SHA512_224",
#endif
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256)
        "SHA512_256",
#endif
#ifdef WOLFSSL_SHA3
#ifndef WOLFSSL_NOSHA3_224
        "SHA3_224",
#endif
#ifndef WOLFSSL_NOSHA3_256
        "SHA3_256",
#endif
        "SHA3_384",
#ifndef WOLFSSL_NOSHA3_512
        "SHA3_512",
#endif
#endif /* WOLFSSL_SHA3 */
        NULL
    };
    const char** d;
    const unsigned char in[] = "abc";
    int   inLen = XSTR_SIZEOF(in);
    byte  out[WC_MAX_DIGEST_SIZE];
    unsigned int outLen;

    for (d = digests; *d != NULL; d++) {
        ExpectIntEQ(EVP_Digest(in, inLen, out, &outLen, *d, NULL), 1);
        ExpectIntGT(outLen, 0);
        ExpectIntEQ(EVP_MD_size(*d), outLen);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_MD_size(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    WOLFSSL_EVP_MD_CTX mdCtx;

#ifdef WOLFSSL_SHA3
#ifndef WOLFSSL_NOSHA3_224
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA3_224"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA3_224_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA3_224_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
#endif
#ifndef WOLFSSL_NOSHA3_256
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA3_256"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA3_256_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA3_256_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
#endif
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA3_384"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA3_384_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA3_384_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
#ifndef WOLFSSL_NOSHA3_512
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA3_512"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA3_512_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA3_512_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
#endif
#endif /* WOLFSSL_SHA3 */

#ifndef NO_SHA256
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA256"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA256_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA256_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA256_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA256_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

#endif

#ifndef NO_MD5
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "MD5"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_MD5_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_MD5_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_MD5_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_MD5_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

#endif

#ifdef WOLFSSL_SHA224
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA224"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA224_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA224_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA224_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA224_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

#endif

#ifdef WOLFSSL_SHA384
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA384"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA384_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA384_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA384_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA384_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

#endif

#ifdef WOLFSSL_SHA512
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA512"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA512_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA512_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA512_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA512_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

#endif

#ifndef NO_SHA
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA1"), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)),
        WC_SHA_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA_DIGEST_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA_BLOCK_SIZE);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
#endif
    /* error case */
    wolfSSL_EVP_MD_CTX_init(&mdCtx);

    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, ""), 0);
    ExpectIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), 0);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), 0);
    /* Cleanup is valid on uninit'ed struct */
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_MD_pkey_type(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    const WOLFSSL_EVP_MD* md;

#ifndef NO_MD5
    ExpectNotNull(md = EVP_md5());
    ExpectIntEQ(EVP_MD_pkey_type(md), NID_md5WithRSAEncryption);
#endif
#ifndef NO_SHA
    ExpectNotNull(md = EVP_sha1());
    ExpectIntEQ(EVP_MD_pkey_type(md), NID_sha1WithRSAEncryption);
#endif
#ifdef WOLFSSL_SHA224
    ExpectNotNull(md = EVP_sha224());
    ExpectIntEQ(EVP_MD_pkey_type(md), NID_sha224WithRSAEncryption);
#endif
    ExpectNotNull(md = EVP_sha256());
    ExpectIntEQ(EVP_MD_pkey_type(md), NID_sha256WithRSAEncryption);
#ifdef WOLFSSL_SHA384
    ExpectNotNull(md = EVP_sha384());
    ExpectIntEQ(EVP_MD_pkey_type(md), NID_sha384WithRSAEncryption);
#endif
#ifdef WOLFSSL_SHA512
    ExpectNotNull(md = EVP_sha512());
    ExpectIntEQ(EVP_MD_pkey_type(md), NID_sha512WithRSAEncryption);
#endif
#endif
    return EXPECT_RESULT();
}

#ifdef OPENSSL_EXTRA
static int test_hmac_signing(const WOLFSSL_EVP_MD *type, const byte* testKey,
        size_t testKeySz, const char* testData, size_t testDataSz,
        const byte* testResult, size_t testResultSz)
{
    EXPECT_DECLS;
    unsigned char check[WC_MAX_DIGEST_SIZE];
    size_t checkSz = -1;
    WOLFSSL_EVP_PKEY* key = NULL;
    WOLFSSL_EVP_MD_CTX mdCtx;

    ExpectNotNull(key = wolfSSL_EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
                                                      testKey, (int)testKeySz));
    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, type, NULL, key), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData,
                                                  (unsigned int)testDataSz), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
    ExpectIntEQ((int)checkSz, (int)testResultSz);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
    ExpectIntEQ((int)checkSz,(int)testResultSz);
    ExpectIntEQ(XMEMCMP(testResult, check, testResultSz), 0);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

    ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, type, NULL, key), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData,
                                                  (unsigned int)testDataSz), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, testResult, checkSz), 1);

    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, type, NULL, key), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData, 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
    ExpectIntEQ((int)checkSz, (int)testResultSz);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
    ExpectIntEQ((int)checkSz,(int)testResultSz);
    ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData + 4,
                                              (unsigned int)testDataSz - 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
    ExpectIntEQ((int)checkSz,(int)testResultSz);
    ExpectIntEQ(XMEMCMP(testResult, check, testResultSz), 0);

    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, type, NULL, key), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData + 4,
                                              (unsigned int)testDataSz - 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, testResult, checkSz), 1);

    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

    wolfSSL_EVP_PKEY_free(key);

    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_EVP_MD_hmac_signing(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    static const unsigned char testKey[] =
    {
        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
        0x0b, 0x0b, 0x0b, 0x0b
    };
    static const char testData[] = "Hi There";
#ifdef WOLFSSL_SHA224
    static const unsigned char testResultSha224[] =
    {
        0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19,
        0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f,
        0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f,
        0x53, 0x68, 0x4b, 0x22
    };
#endif
#ifndef NO_SHA256
    static const unsigned char testResultSha256[] =
    {
        0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
        0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
        0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
        0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7
    };
#endif
#ifdef WOLFSSL_SHA384
    static const unsigned char testResultSha384[] =
    {
        0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
        0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f,
        0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
        0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
        0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
        0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6
    };
#endif
#ifdef WOLFSSL_SHA512
    static const unsigned char testResultSha512[] =
    {
        0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
        0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
        0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
        0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
        0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
        0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
        0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
        0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54
    };
#endif
#ifdef WOLFSSL_SHA3
    #ifndef WOLFSSL_NOSHA3_224
    static const unsigned char testResultSha3_224[] =
    {
        0x3b, 0x16, 0x54, 0x6b, 0xbc, 0x7b, 0xe2, 0x70,
        0x6a, 0x03, 0x1d, 0xca, 0xfd, 0x56, 0x37, 0x3d,
        0x98, 0x84, 0x36, 0x76, 0x41, 0xd8, 0xc5, 0x9a,
        0xf3, 0xc8, 0x60, 0xf7
    };
    #endif
    #ifndef WOLFSSL_NOSHA3_256
    static const unsigned char testResultSha3_256[] =
    {
        0xba, 0x85, 0x19, 0x23, 0x10, 0xdf, 0xfa, 0x96,
        0xe2, 0xa3, 0xa4, 0x0e, 0x69, 0x77, 0x43, 0x51,
        0x14, 0x0b, 0xb7, 0x18, 0x5e, 0x12, 0x02, 0xcd,
        0xcc, 0x91, 0x75, 0x89, 0xf9, 0x5e, 0x16, 0xbb
    };
    #endif
    #ifndef WOLFSSL_NOSHA3_384
    static const unsigned char testResultSha3_384[] =
    {
        0x68, 0xd2, 0xdc, 0xf7, 0xfd, 0x4d, 0xdd, 0x0a,
        0x22, 0x40, 0xc8, 0xa4, 0x37, 0x30, 0x5f, 0x61,
        0xfb, 0x73, 0x34, 0xcf, 0xb5, 0xd0, 0x22, 0x6e,
        0x1b, 0xc2, 0x7d, 0xc1, 0x0a, 0x2e, 0x72, 0x3a,
        0x20, 0xd3, 0x70, 0xb4, 0x77, 0x43, 0x13, 0x0e,
        0x26, 0xac, 0x7e, 0x3d, 0x53, 0x28, 0x86, 0xbd
    };
    #endif
    #ifndef WOLFSSL_NOSHA3_512
    static const unsigned char testResultSha3_512[] =
    {
        0xeb, 0x3f, 0xbd, 0x4b, 0x2e, 0xaa, 0xb8, 0xf5,
        0xc5, 0x04, 0xbd, 0x3a, 0x41, 0x46, 0x5a, 0xac,
        0xec, 0x15, 0x77, 0x0a, 0x7c, 0xab, 0xac, 0x53,
        0x1e, 0x48, 0x2f, 0x86, 0x0b, 0x5e, 0xc7, 0xba,
        0x47, 0xcc, 0xb2, 0xc6, 0xf2, 0xaf, 0xce, 0x8f,
        0x88, 0xd2, 0x2b, 0x6d, 0xc6, 0x13, 0x80, 0xf2,
        0x3a, 0x66, 0x8f, 0xd3, 0x88, 0x8b, 0xb8, 0x05,
        0x37, 0xc0, 0xa0, 0xb8, 0x64, 0x07, 0x68, 0x9e
    };
    #endif
#endif

#ifndef NO_SHA256
    ExpectIntEQ(test_hmac_signing(wolfSSL_EVP_sha256(), testKey,
        sizeof(testKey), testData, XSTRLEN(testData), testResultSha256,
        sizeof(testResultSha256)), TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA224
    ExpectIntEQ(test_hmac_signing(wolfSSL_EVP_sha224(), testKey,
        sizeof(testKey), testData, XSTRLEN(testData), testResultSha224,
        sizeof(testResultSha224)), TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA384
    ExpectIntEQ(test_hmac_signing(wolfSSL_EVP_sha384(), testKey,
        sizeof(testKey), testData, XSTRLEN(testData), testResultSha384,
        sizeof(testResultSha384)), TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA512
    ExpectIntEQ(test_hmac_signing(wolfSSL_EVP_sha512(), testKey,
        sizeof(testKey), testData, XSTRLEN(testData), testResultSha512,
        sizeof(testResultSha512)), TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA3
    #ifndef WOLFSSL_NOSHA3_224
    ExpectIntEQ(test_hmac_signing(wolfSSL_EVP_sha3_224(), testKey,
        sizeof(testKey), testData, XSTRLEN(testData), testResultSha3_224,
        sizeof(testResultSha3_224)), TEST_SUCCESS);
    #endif
    #ifndef WOLFSSL_NOSHA3_256
    ExpectIntEQ(test_hmac_signing(wolfSSL_EVP_sha3_256(), testKey,
        sizeof(testKey), testData, XSTRLEN(testData), testResultSha3_256,
        sizeof(testResultSha3_256)), TEST_SUCCESS);
    #endif
    #ifndef WOLFSSL_NOSHA3_384
    ExpectIntEQ(test_hmac_signing(wolfSSL_EVP_sha3_384(), testKey,
        sizeof(testKey), testData, XSTRLEN(testData), testResultSha3_384,
        sizeof(testResultSha3_384)), TEST_SUCCESS);
    #endif
    #ifndef WOLFSSL_NOSHA3_512
    ExpectIntEQ(test_hmac_signing(wolfSSL_EVP_sha3_512(), testKey,
        sizeof(testKey), testData, XSTRLEN(testData), testResultSha3_512,
        sizeof(testResultSha3_512)), TEST_SUCCESS);
    #endif
#endif
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}


static int test_wolfSSL_EVP_MD_rsa_signing(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048)
    WOLFSSL_EVP_PKEY* privKey = NULL;
    WOLFSSL_EVP_PKEY* pubKey = NULL;
    WOLFSSL_EVP_PKEY_CTX* keyCtx = NULL;
    const char testData[] = "Hi There";
    WOLFSSL_EVP_MD_CTX mdCtx;
    WOLFSSL_EVP_MD_CTX mdCtxCopy;
    int ret;
    size_t checkSz = -1;
    int sz = 2048 / 8;
    const unsigned char* cp;
    const unsigned char* p;
    unsigned char check[2048/8];
    size_t i;
    int paddings[] = {
            RSA_PKCS1_PADDING,
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && defined(WC_RSA_PSS)
            RSA_PKCS1_PSS_PADDING,
#endif
    };


    cp = client_key_der_2048;
    ExpectNotNull((privKey = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, &cp,
                                                  sizeof_client_key_der_2048)));
    p = client_keypub_der_2048;
    ExpectNotNull((pubKey = wolfSSL_d2i_PUBKEY(NULL, &p,
                                               sizeof_client_keypub_der_2048)));

    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    wolfSSL_EVP_MD_CTX_init(&mdCtxCopy);
    ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
                                                             NULL, privKey), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData,
                                          (unsigned int)XSTRLEN(testData)), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
    ExpectIntEQ((int)checkSz, sz);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
    ExpectIntEQ((int)checkSz,sz);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_copy_ex(&mdCtxCopy, &mdCtx), 1);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_copy_ex(&mdCtxCopy, &mdCtx), 1);
    ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtxCopy);
    ExpectIntEQ(ret, 1);
    ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
    ExpectIntEQ(ret, 1);

    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
                                                              NULL, pubKey), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData,
                                               (unsigned int)XSTRLEN(testData)),
                1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1);
    ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
    ExpectIntEQ(ret, 1);

    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
                                                             NULL, privKey), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData, 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
    ExpectIntEQ((int)checkSz, sz);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
    ExpectIntEQ((int)checkSz, sz);
    ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData + 4,
                                      (unsigned int)XSTRLEN(testData) - 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
    ExpectIntEQ((int)checkSz, sz);
    ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
    ExpectIntEQ(ret, 1);

    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
                                                              NULL, pubKey), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData + 4,
                                           (unsigned int)XSTRLEN(testData) - 4),
                1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1);
    ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
    ExpectIntEQ(ret, 1);

    /* Check all signing padding types */
    for (i = 0; i < sizeof(paddings)/sizeof(int); i++) {
        wolfSSL_EVP_MD_CTX_init(&mdCtx);
        ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, &keyCtx,
                wolfSSL_EVP_sha256(), NULL, privKey), 1);
        ExpectIntEQ(wolfSSL_EVP_PKEY_CTX_set_rsa_padding(keyCtx,
                paddings[i]), 1);
        ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData,
                (unsigned int)XSTRLEN(testData)), 1);
        ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
        ExpectIntEQ((int)checkSz, sz);
        ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
        ExpectIntEQ((int)checkSz,sz);
        ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
        ExpectIntEQ(ret, 1);

        wolfSSL_EVP_MD_CTX_init(&mdCtx);
        ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, &keyCtx,
                wolfSSL_EVP_sha256(), NULL, pubKey), 1);
        ExpectIntEQ(wolfSSL_EVP_PKEY_CTX_set_rsa_padding(keyCtx,
                paddings[i]), 1);
        ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData,
                (unsigned int)XSTRLEN(testData)), 1);
        ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1);
        ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
        ExpectIntEQ(ret, 1);
    }

    wolfSSL_EVP_PKEY_free(pubKey);
    wolfSSL_EVP_PKEY_free(privKey);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_EVP_MD_ecc_signing(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
    WOLFSSL_EVP_PKEY* privKey = NULL;
    WOLFSSL_EVP_PKEY* pubKey = NULL;
    const char testData[] = "Hi There";
    WOLFSSL_EVP_MD_CTX mdCtx;
    int ret;
    size_t checkSz = -1;
    const unsigned char* cp;
    const unsigned char* p;
    unsigned char check[2048/8];

    cp = ecc_clikey_der_256;
    ExpectNotNull(privKey = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL, &cp,
                                                   sizeof_ecc_clikey_der_256));
    p = ecc_clikeypub_der_256;
    ExpectNotNull((pubKey = wolfSSL_d2i_PUBKEY(NULL, &p,
                                                sizeof_ecc_clikeypub_der_256)));

    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
                                                             NULL, privKey), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData,
                                          (unsigned int)XSTRLEN(testData)), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
    ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
    ExpectIntEQ(ret, 1);

    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
                                                              NULL, pubKey), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData,
                                               (unsigned int)XSTRLEN(testData)),
                1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1);
    ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
    ExpectIntEQ(ret, 1);

    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
                                                             NULL, privKey), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData, 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData + 4,
                                      (unsigned int)XSTRLEN(testData) - 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
    ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
    ExpectIntEQ(ret, 1);

    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
                                                              NULL, pubKey), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, 4), 1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData + 4,
                                           (unsigned int)XSTRLEN(testData) - 4),
                1);
    ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1);
    ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx);
    ExpectIntEQ(ret, 1);

    wolfSSL_EVP_PKEY_free(pubKey);
    wolfSSL_EVP_PKEY_free(privKey);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_CTX_add_extra_chain_cert(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined(NO_BIO)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    char caFile[] = "./certs/client-ca.pem";
    char clientFile[] = "./certs/client-cert.pem";
    SSL_CTX* ctx = NULL;
    X509* x509 = NULL;
    BIO *bio = NULL;
    X509 *cert = NULL;
    X509 *ca = NULL;
    STACK_OF(X509) *chain = NULL;
    STACK_OF(X509) *chain2 = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(caFile,
        WOLFSSL_FILETYPE_PEM));

    /* Negative tests. */
    ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(NULL, x509), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), WOLFSSL_SUCCESS);

    ExpectNotNull(x509 = wolfSSL_X509_new());
    /* Empty certificate. */
    ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    wolfSSL_X509_free(x509);
    x509 = NULL;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(clientFile,
        WOLFSSL_FILETYPE_PEM));

    /* additional test of getting EVP_PKEY key size from X509
     * Do not run with user RSA because wolfSSL_RSA_size is not currently
     * allowed with user RSA */
    {
        EVP_PKEY* pkey = NULL;
    #if defined(HAVE_ECC)
        X509* ecX509 = NULL;
    #endif /* HAVE_ECC */

        ExpectNotNull(pkey = X509_get_pubkey(x509));
        /* current RSA key is 2048 bit (256 bytes) */
        ExpectIntEQ(EVP_PKEY_size(pkey), 256);

        EVP_PKEY_free(pkey);
        pkey = NULL;

#if defined(HAVE_ECC)
    #if defined(USE_CERT_BUFFERS_256)
        ExpectNotNull(ecX509 = wolfSSL_X509_load_certificate_buffer(
                    cliecc_cert_der_256, sizeof_cliecc_cert_der_256,
                    SSL_FILETYPE_ASN1));
    #else
        ExpectNotNull(ecX509 = wolfSSL_X509_load_certificate_file(
            cliEccCertFile, SSL_FILETYPE_PEM));
    #endif
        pkey = X509_get_pubkey(ecX509);
        ExpectNotNull(pkey);
        /* current ECC key is 256 bit (32 bytes) */
        ExpectIntEQ(EVP_PKEY_size(pkey), 32);

        X509_free(ecX509);
        ecX509 = NULL;
        EVP_PKEY_free(pkey);
        pkey = NULL;
#endif /* HAVE_ECC */
    }

    ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), SSL_SUCCESS);
    if (EXPECT_SUCCESS()) {
        x509 = NULL;
    }

#ifdef WOLFSSL_ENCRYPTED_KEYS
    ExpectNull(SSL_CTX_get_default_passwd_cb(ctx));
    ExpectNull(SSL_CTX_get_default_passwd_cb_userdata(ctx));
#endif
    SSL_CTX_free(ctx);
    ctx = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
    /* Test haproxy use case */
    ExpectNotNull(bio = BIO_new_file(svrCertFile, "r"));
    /* Read Certificate */
    ExpectNotNull(cert = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL));
    ExpectNotNull(ca = PEM_read_bio_X509(bio, NULL, NULL, NULL));
    ExpectNotNull(chain = sk_X509_new_null());
    ExpectIntEQ(sk_X509_push(chain, ca), 1);
    if (EXPECT_SUCCESS()) {
        ca = NULL;
    }
    ExpectNotNull(chain2 = X509_chain_up_ref(chain));
    ExpectNotNull(ca = sk_X509_shift(chain2));
    ExpectIntEQ(SSL_CTX_use_certificate(ctx, cert), 1);
    ExpectIntEQ(SSL_CTX_add_extra_chain_cert(ctx, ca), 1);
    if (EXPECT_SUCCESS()) {
        ca = NULL;
    }

    BIO_free(bio);
    X509_free(cert);
    X509_free(ca);
    X509_free(x509);
    sk_X509_pop_free(chain, X509_free);
    sk_X509_pop_free(chain2, X509_free);
    SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
         !defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined (NO_BIO) */
    return EXPECT_RESULT();
}

#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
static int test_wolfSSL_ERR_peek_last_error_line(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
    !defined(NO_FILESYSTEM) && defined(DEBUG_WOLFSSL) && \
    !defined(NO_OLD_TLS) && !defined(WOLFSSL_NO_TLS12) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(NO_ERROR_QUEUE)
    callback_functions client_cb;
    callback_functions server_cb;
    int         line = 0;
    int         flag = ERR_TXT_STRING;
    const char* file = NULL;
    const char* data = NULL;

    /* create a failed connection and inspect the error */
    XMEMSET(&client_cb, 0, sizeof(callback_functions));
    XMEMSET(&server_cb, 0, sizeof(callback_functions));
    client_cb.method  = wolfTLSv1_1_client_method;
    server_cb.method  = wolfTLSv1_2_server_method;

    test_wolfSSL_client_server_nofail(&client_cb, &server_cb);

    ExpectIntGT(ERR_get_error_line_data(NULL, NULL, &data, &flag), 0);
    ExpectNotNull(data);

    /* check clearing error state */
    ERR_remove_state(0);
    ExpectIntEQ((int)ERR_peek_last_error_line(NULL, NULL), 0);
    ERR_peek_last_error_line(NULL, &line);
    ExpectIntEQ(line, 0);
    ERR_peek_last_error_line(&file, NULL);
    ExpectNull(file);

    /* retry connection to fill error queue */
    XMEMSET(&client_cb, 0, sizeof(callback_functions));
    XMEMSET(&server_cb, 0, sizeof(callback_functions));
    client_cb.method  = wolfTLSv1_1_client_method;
    server_cb.method  = wolfTLSv1_2_server_method;

    test_wolfSSL_client_server_nofail(&client_cb, &server_cb);

    /* check that error code was stored */
    ExpectIntNE((int)ERR_peek_last_error_line(NULL, NULL), 0);
    ERR_peek_last_error_line(NULL, &line);
    ExpectIntNE(line, 0);
    ERR_peek_last_error_line(&file, NULL);
    ExpectNotNull(file);

    fprintf(stderr, "\nTesting error print out\n");
    ERR_print_errors_fp(stderr);
    fprintf(stderr, "Done testing print out\n\n");
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) &&
        * !defined(NO_FILESYSTEM) && !defined(DEBUG_WOLFSSL) */
    return EXPECT_RESULT();
}
#endif /* !NO_WOLFSSL_CLIENT && !NO_WOLFSSL_SERVER */

#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
       !defined(NO_FILESYSTEM) && !defined(NO_RSA)
static int verify_cb(int ok, X509_STORE_CTX *ctx)
{
    (void) ok;
    (void) ctx;
    fprintf(stderr, "ENTER verify_cb\n");
    return SSL_SUCCESS;
}
#endif

static int test_wolfSSL_X509_Name_canon(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
    !defined(NO_FILESYSTEM) && !defined(NO_SHA) && \
     defined(WOLFSSL_CERT_GEN) && \
    (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && !defined(NO_RSA)
    const long ex_hash1 = 0x0fdb2da4;
    const long ex_hash2 = 0x9f3e8c9e;
    X509_NAME *name = NULL;
    X509 *x509 = NULL;
    XFILE file = XBADFILE;
    unsigned long hash = 0;
    byte digest[WC_MAX_DIGEST_SIZE] = {0};
    byte  *pbuf = NULL;
    word32 len = 0;
    (void) ex_hash2;

    ExpectTrue((file = XFOPEN(caCertFile, "rb")) != XBADFILE);
    ExpectNotNull(x509 = PEM_read_X509(file, NULL, NULL, NULL));
    ExpectNotNull(name = X509_get_issuer_name(x509));

    /* When output buffer is NULL, should return necessary output buffer
     * length.*/
    ExpectIntGT(wolfSSL_i2d_X509_NAME_canon(name, NULL), 0);
    ExpectIntGT((len = (word32)wolfSSL_i2d_X509_NAME_canon(name, &pbuf)), 0);
    ExpectIntEQ(wc_ShaHash((const byte*)pbuf, (word32)len, digest), 0);

    hash = (((unsigned long)digest[3] << 24) |
            ((unsigned long)digest[2] << 16) |
            ((unsigned long)digest[1] <<  8) |
            ((unsigned long)digest[0]));
    ExpectIntEQ(hash, ex_hash1);

    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }
    X509_free(x509);
    x509 = NULL;
    XFREE(pbuf, NULL, DYNAMIC_TYPE_OPENSSL);
    pbuf = NULL;

    ExpectTrue((file = XFOPEN(cliCertFile, "rb")) != XBADFILE);
    ExpectNotNull(x509 = PEM_read_X509(file, NULL, NULL, NULL));
    ExpectNotNull(name = X509_get_issuer_name(x509));

    ExpectIntGT((len = (word32)wolfSSL_i2d_X509_NAME_canon(name, &pbuf)), 0);
    ExpectIntEQ(wc_ShaHash((const byte*)pbuf, (word32)len, digest), 0);

    hash = (((unsigned long)digest[3] << 24) |
            ((unsigned long)digest[2] << 16) |
            ((unsigned long)digest[1] <<  8) |
            ((unsigned long)digest[0]));

    ExpectIntEQ(hash, ex_hash2);

    if (file != XBADFILE)
        XFCLOSE(file);
    X509_free(x509);
    XFREE(pbuf, NULL, DYNAMIC_TYPE_OPENSSL);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
    const int  MAX_DIR = 4;
    const char paths[][32] = {
                             "./certs/ed25519",
                             "./certs/ecc",
                             "./certs/crl",
                             "./certs/",
                            };

    char CertCrl_path[MAX_FILENAME_SZ];
    char *p;
    X509_STORE* str = NULL;
    X509_LOOKUP* lookup = NULL;
    WOLFSSL_STACK* sk = NULL;
    int len, total_len, i;

    (void)sk;

    XMEMSET(CertCrl_path, 0, MAX_FILENAME_SZ);

    /* illegal string */
    ExpectNotNull((str = wolfSSL_X509_STORE_new()));
    ExpectNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file()));
    ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, "",
                                    SSL_FILETYPE_PEM,NULL), 0);

    /* free store */
    X509_STORE_free(str);
    str = NULL;

    /* short folder string */
    ExpectNotNull((str = wolfSSL_X509_STORE_new()));
    ExpectNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file()));
    ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, "./",
                                    SSL_FILETYPE_PEM,NULL), 1);
    #if defined(WOLFSSL_INT_H)
    /* only available when including internal.h */
    ExpectNotNull(sk = lookup->dirs->dir_entry);
    #endif
    /* free store */
    X509_STORE_free(str);
    str = NULL;

    /* typical function check */
    p = &CertCrl_path[0];
    total_len = 0;

    for (i = MAX_DIR - 1; i>=0 && total_len < MAX_FILENAME_SZ; i--) {
        len = (int)XSTRLEN((const char*)&paths[i]);
        total_len += len;
        XSTRNCPY(p, paths[i], MAX_FILENAME_SZ - total_len);
        p += len;
        if (i != 0) *(p++) = SEPARATOR_CHAR;
    }

    ExpectNotNull((str = wolfSSL_X509_STORE_new()));
    ExpectNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file()));
    ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, CertCrl_path,
                                    SSL_FILETYPE_PEM,NULL), 1);
    #if defined(WOLFSSL_INT_H)
    /* only available when including internal.h */
    ExpectNotNull(sk = lookup->dirs->dir_entry);
    #endif

    X509_STORE_free(str);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_LOOKUP_ctrl_file(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
    !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \
    defined(WOLFSSL_SIGNER_DER_CERT)
    X509_STORE_CTX* ctx = NULL;
    X509_STORE* str = NULL;
    X509_LOOKUP* lookup = NULL;

    X509* cert1 = NULL;
    X509* x509Ca = NULL;
    X509* x509Svr = NULL;
    X509* issuer = NULL;

    WOLFSSL_STACK* sk = NULL;
    X509_NAME* caName = NULL;
    X509_NAME* issuerName = NULL;

    XFILE file1 = XBADFILE;
    int i;
    int cert_count = 0;
    int cmp;

    char der[] = "certs/ca-cert.der";

#ifdef HAVE_CRL
    char pem[][100] = {
        "./certs/crl/crl.pem",
        "./certs/crl/crl2.pem",
        "./certs/crl/caEccCrl.pem",
        "./certs/crl/eccCliCRL.pem",
        "./certs/crl/eccSrvCRL.pem",
        ""
    };
#endif
    ExpectTrue((file1 = XFOPEN("./certs/ca-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(cert1 = wolfSSL_PEM_read_X509(file1, NULL, NULL, NULL));
    if (file1 != XBADFILE)
        XFCLOSE(file1);

    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectNotNull((str = wolfSSL_X509_STORE_new()));
    ExpectNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file()));
    ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, caCertFile,
                                    SSL_FILETYPE_PEM,NULL), 1);
    ExpectNotNull(sk = wolfSSL_CertManagerGetCerts(str->cm));
    ExpectIntEQ((cert_count = sk_X509_num(sk)), 1);

    /* check if CA cert is loaded into the store */
    for (i = 0; i < cert_count; i++) {
        x509Ca = sk_X509_value(sk, i);
        ExpectIntEQ(0, wolfSSL_X509_cmp(x509Ca, cert1));
    }

    ExpectNotNull((x509Svr =
            wolfSSL_X509_load_certificate_file(svrCertFile, SSL_FILETYPE_PEM)));

    ExpectIntEQ(X509_STORE_CTX_init(ctx, str, x509Svr, NULL), SSL_SUCCESS);

    ExpectNull(X509_STORE_CTX_get0_current_issuer(NULL));
    issuer = X509_STORE_CTX_get0_current_issuer(ctx);
    ExpectNull(issuer);

    ExpectIntEQ(X509_verify_cert(ctx), 1);

    issuer = X509_STORE_CTX_get0_current_issuer(ctx);
    ExpectNotNull(issuer);
    caName = X509_get_subject_name(x509Ca);
    ExpectNotNull(caName);
    issuerName = X509_get_subject_name(issuer);
    ExpectNotNull(issuerName);
    cmp = X509_NAME_cmp(caName, issuerName);
    ExpectIntEQ(cmp, 0);

    /* load der format */
    issuer = NULL;
    X509_STORE_CTX_free(ctx);
    ctx = NULL;
    X509_STORE_free(str);
    str = NULL;
    sk_X509_pop_free(sk, NULL);
    sk = NULL;
    X509_free(x509Svr);
    x509Svr = NULL;

    ExpectNotNull((str = wolfSSL_X509_STORE_new()));
    ExpectNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file()));
    ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, der,
                                    SSL_FILETYPE_ASN1,NULL), 1);
    ExpectNotNull(sk = wolfSSL_CertManagerGetCerts(str->cm));
    ExpectIntEQ((cert_count = sk_X509_num(sk)), 1);
    /* check if CA cert is loaded into the store */
    for (i = 0; i < cert_count; i++) {
        x509Ca = sk_X509_value(sk, i);
        ExpectIntEQ(0, wolfSSL_X509_cmp(x509Ca, cert1));
    }

    X509_STORE_free(str);
    str = NULL;
    sk_X509_pop_free(sk, NULL);
    sk = NULL;
    X509_free(cert1);
    cert1 = NULL;

#ifdef HAVE_CRL
    ExpectNotNull(str = wolfSSL_X509_STORE_new());
    ExpectNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file()));
    ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, caCertFile,
                                                    SSL_FILETYPE_PEM,NULL), 1);
    ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD,
                                "certs/server-revoked-cert.pem",
                                 SSL_FILETYPE_PEM,NULL), 1);
    if (str) {
        ExpectIntEQ(wolfSSL_CertManagerVerify(str->cm, svrCertFile,
                    WOLFSSL_FILETYPE_PEM), 1);
        /* since store hasn't yet known the revoked cert*/
        ExpectIntEQ(wolfSSL_CertManagerVerify(str->cm,
                    "certs/server-revoked-cert.pem",
                    WOLFSSL_FILETYPE_PEM), 1);
    }
    for (i = 0; pem[i][0] != '\0'; i++)
    {
        ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, pem[i],
                                        SSL_FILETYPE_PEM, NULL), 1);
    }

    if (str) {
        /* since store knows crl list */
        ExpectIntEQ(wolfSSL_CertManagerVerify(str->cm,
                    "certs/server-revoked-cert.pem",
                    WOLFSSL_FILETYPE_PEM ), WC_NO_ERR_TRACE(CRL_CERT_REVOKED));
    }

    ExpectIntEQ(X509_LOOKUP_ctrl(NULL, 0, NULL, 0, NULL), 0);
    X509_STORE_free(str);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_trusted_stack_cleanup(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA)
    X509_STORE_CTX_cleanup(NULL);
    X509_STORE_CTX_trusted_stack(NULL, NULL);

    res = TEST_SUCCESS;
#endif
    return res;
}

static int test_wolfSSL_X509_STORE_CTX_get_issuer(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    X509_STORE_CTX* ctx = NULL;
    X509_STORE* str = NULL;
    X509* x509Ca = NULL;
    X509* x509Svr = NULL;
    X509* issuer = NULL;
    X509_NAME* caName = NULL;
    X509_NAME* issuerName = NULL;

    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectNotNull((str = wolfSSL_X509_STORE_new()));
    ExpectNotNull((x509Ca =
            wolfSSL_X509_load_certificate_file(caCertFile, SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_add_cert(str, x509Ca), SSL_SUCCESS);
    ExpectNotNull((x509Svr =
            wolfSSL_X509_load_certificate_file(svrCertFile, SSL_FILETYPE_PEM)));

    ExpectIntEQ(X509_STORE_CTX_init(ctx, str, x509Svr, NULL), SSL_SUCCESS);

    /* Issuer0 is not set until chain is built for verification */
    ExpectNull(X509_STORE_CTX_get0_current_issuer(NULL));
    ExpectNull(issuer = X509_STORE_CTX_get0_current_issuer(ctx));

    /* Issuer1 will use the store to make a new issuer */
    ExpectIntEQ(X509_STORE_CTX_get1_issuer(&issuer, ctx, x509Svr), 1);
    ExpectNotNull(issuer);
    X509_free(issuer);

    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(issuer = X509_STORE_CTX_get0_current_issuer(ctx));
    ExpectNotNull(caName = X509_get_subject_name(x509Ca));
    ExpectNotNull(issuerName = X509_get_subject_name(issuer));
#ifdef WOLFSSL_SIGNER_DER_CERT
    ExpectIntEQ(X509_NAME_cmp(caName, issuerName), 0);
#endif

    X509_STORE_CTX_free(ctx);
    X509_free(x509Svr);
    X509_STORE_free(str);
    X509_free(x509Ca);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PKCS7_certs(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && !defined(NO_BIO) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(HAVE_PKCS7)
    STACK_OF(X509)* sk = NULL;
    STACK_OF(X509_INFO)* info_sk = NULL;
    PKCS7 *p7 = NULL;
    BIO* bio = NULL;
    const byte* p = NULL;
    int buflen = 0;
    int i;

    /* Test twice. Once with d2i and once without to test
     * that everything is free'd correctly. */
    for (i = 0; i < 2; i++) {
        ExpectNotNull(p7 = PKCS7_new());
        if (p7 != NULL) {
            p7->version = 1;
        #ifdef NO_SHA
            p7->hashOID = SHA256h;
        #else
            p7->hashOID = SHAh;
        #endif
        }
        ExpectNotNull(bio = BIO_new(BIO_s_file()));
        ExpectIntGT(BIO_read_filename(bio, svrCertFile), 0);
        ExpectNotNull(info_sk = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL));
        ExpectIntEQ(sk_X509_INFO_num(info_sk), 2);
        ExpectNotNull(sk = sk_X509_new_null());
        while (EXPECT_SUCCESS() && (sk_X509_INFO_num(info_sk) > 0)) {
            X509_INFO* info = NULL;
            ExpectNotNull(info = sk_X509_INFO_shift(info_sk));
            ExpectIntGT(sk_X509_push(sk, info->x509), 0);
            if (EXPECT_SUCCESS() && (info != NULL)) {
                info->x509 = NULL;
            }
            X509_INFO_free(info);
        }
        sk_X509_INFO_pop_free(info_sk, X509_INFO_free);
        info_sk = NULL;
        BIO_free(bio);
        bio = NULL;
        ExpectNotNull(bio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(wolfSSL_PKCS7_encode_certs(p7, sk, bio), 1);
        if ((sk != NULL) && ((p7 == NULL) || (bio == NULL))) {
            sk_X509_pop_free(sk, X509_free);
        }
        sk = NULL;
        ExpectIntGT((buflen = BIO_get_mem_data(bio, &p)), 0);

        if (i == 0) {
            PKCS7_free(p7);
            p7 = NULL;
            ExpectNotNull(d2i_PKCS7(&p7, &p, buflen));
            if (p7 != NULL) {
                /* Reset certs to force wolfSSL_PKCS7_to_stack to regenerate
                 * them */
                ((WOLFSSL_PKCS7*)p7)->certs = NULL;
            }
            /* PKCS7_free free's the certs */
            ExpectNotNull(wolfSSL_PKCS7_to_stack(p7));
        }

        BIO_free(bio);
        bio = NULL;
        PKCS7_free(p7);
        p7 = NULL;
    }
#endif /* defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
         !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(HAVE_PKCS7) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    X509_STORE_CTX* ctx = NULL;
    X509_STORE* str = NULL;
    X509* x509 = NULL;
#ifdef OPENSSL_ALL
    X509* x5092 = NULL;
    STACK_OF(X509) *sk = NULL;
    STACK_OF(X509) *sk2 = NULL;
    STACK_OF(X509) *sk3 = NULL;
#endif

    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectNotNull((str = wolfSSL_X509_STORE_new()));
    ExpectNotNull((x509 =
                wolfSSL_X509_load_certificate_file(svrCertFile, SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_add_cert(str, x509), SSL_SUCCESS);
#ifdef OPENSSL_ALL
    /* sk_X509_new only in OPENSSL_ALL */
    sk = sk_X509_new_null();
    ExpectNotNull(sk);
    ExpectIntEQ(X509_STORE_CTX_init(ctx, str, x509, sk), SSL_SUCCESS);
#else
    ExpectIntEQ(X509_STORE_CTX_init(ctx, str, x509, NULL), SSL_SUCCESS);
#endif
    ExpectIntEQ(SSL_get_ex_data_X509_STORE_CTX_idx(), 0);
    X509_STORE_CTX_set_error(ctx, -5);
    X509_STORE_CTX_set_error(NULL, -5);

    X509_STORE_CTX_free(ctx);
    ctx = NULL;
#ifdef OPENSSL_ALL
    sk_X509_pop_free(sk, NULL);
    sk = NULL;
#endif
    X509_STORE_free(str);
    str = NULL;
    X509_free(x509);
    x509 = NULL;

    ExpectNotNull(ctx = X509_STORE_CTX_new());
    X509_STORE_CTX_set_verify_cb(ctx, verify_cb);
    X509_STORE_CTX_free(ctx);
    ctx = NULL;

#ifdef OPENSSL_ALL
    /* test X509_STORE_CTX_get(1)_chain */
    ExpectNotNull((x509 = X509_load_certificate_file(svrCertFile,
                                                     SSL_FILETYPE_PEM)));
    ExpectNotNull((x5092 = X509_load_certificate_file(cliCertFile,
                                                     SSL_FILETYPE_PEM)));
    ExpectNotNull((sk = sk_X509_new_null()));
    ExpectIntEQ(sk_X509_push(sk, x509), 1);
    if (EXPECT_FAIL()) {
        X509_free(x509);
        x509 = NULL;
    }
    ExpectNotNull((str = X509_STORE_new()));
    ExpectNotNull((ctx = X509_STORE_CTX_new()));
    ExpectIntEQ(X509_STORE_CTX_init(ctx, str, x5092, sk), 1);
    ExpectNull((sk2 = X509_STORE_CTX_get_chain(NULL)));
    ExpectNull((sk2 = X509_STORE_CTX_get_chain(ctx)));
    ExpectNull((sk3 = X509_STORE_CTX_get1_chain(NULL)));
    ExpectNull((sk3 = X509_STORE_CTX_get1_chain(ctx)));
    X509_STORE_CTX_free(ctx);
    ctx = NULL;
    X509_STORE_free(str);
    str = NULL;
    /* CTX certs not freed yet */
    X509_free(x5092);
    x5092 = NULL;
    sk_X509_pop_free(sk, NULL);
    sk = NULL;
    /* sk3 is dup so free here */
    sk_X509_pop_free(sk3, NULL);
    sk3 = NULL;
#endif

    /* test X509_STORE_CTX_get/set_ex_data */
    {
        int i = 0, tmpData = 5;
        void* tmpDataRet;
        ExpectNotNull(ctx = X509_STORE_CTX_new());
    #ifdef HAVE_EX_DATA
        for (i = 0; i < MAX_EX_DATA; i++) {
            ExpectIntEQ(X509_STORE_CTX_set_ex_data(ctx, i, &tmpData),
                        WOLFSSL_SUCCESS);
            tmpDataRet = (int*)X509_STORE_CTX_get_ex_data(ctx, i);
            ExpectNotNull(tmpDataRet);
            ExpectIntEQ(tmpData, *(int*)tmpDataRet);
        }
    #else
        ExpectIntEQ(X509_STORE_CTX_set_ex_data(ctx, i, &tmpData),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        tmpDataRet = (int*)X509_STORE_CTX_get_ex_data(ctx, i);
        ExpectNull(tmpDataRet);
    #endif
        X509_STORE_CTX_free(ctx);
        ctx = NULL;
    }

    /* test X509_STORE_get/set_ex_data */
    {
        int i = 0, tmpData = 99;
        void* tmpDataRet;
        ExpectNotNull(str = X509_STORE_new());
    #ifdef HAVE_EX_DATA
        for (i = 0; i < MAX_EX_DATA; i++) {
            ExpectIntEQ(X509_STORE_set_ex_data(str, i, &tmpData),
                        WOLFSSL_SUCCESS);
            tmpDataRet = (int*)X509_STORE_get_ex_data(str, i);
            ExpectNotNull(tmpDataRet);
            ExpectIntEQ(tmpData, *(int*)tmpDataRet);
        }
    #else
        ExpectIntEQ(X509_STORE_set_ex_data(str, i, &tmpData),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        tmpDataRet = (int*)X509_STORE_get_ex_data(str, i);
        ExpectNull(tmpDataRet);
    #endif
        X509_STORE_free(str);
        str = NULL;
    }

#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
        * !defined(NO_FILESYSTEM) && !defined(NO_RSA) */

    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA)

typedef struct {
    const char *caFile;
    const char *caIntFile;
    const char *caInt2File;
    const char *leafFile;
    X509 *x509Ca;
    X509 *x509CaInt;
    X509 *x509CaInt2;
    X509 *x509Leaf;
    STACK_OF(X509)* expectedChain;
} X509_STORE_test_data;

static X509 * test_wolfSSL_X509_STORE_CTX_ex_helper(const char *file)
{
    XFILE fp = XBADFILE;
    X509 *x = NULL;

    fp = XFOPEN(file, "rb");
    if (fp == NULL) {
        return NULL;
    }
    x = PEM_read_X509(fp, 0, 0, 0);
    XFCLOSE(fp);

    return x;
}

static int test_wolfSSL_X509_STORE_CTX_ex1(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;
    int i = 0;

    /* Test case 1, add X509 certs to store and verify */
    ExpectNotNull(store = X509_STORE_new());
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509Ca), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
    for (i = 0; i < sk_X509_num(chain); i++) {
        ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
                             sk_X509_value(testData->expectedChain, i)), 0);
    }
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex2(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;
    int i = 0;

    /* Test case 2, add certs by filename to store and verify */
    ExpectNotNull(store = X509_STORE_new());
    ExpectIntEQ(X509_STORE_load_locations(
        store, testData->caFile, NULL), 1);
    ExpectIntEQ(X509_STORE_load_locations(
        store, testData->caIntFile, NULL), 1);
    ExpectIntEQ(X509_STORE_load_locations(
        store, testData->caInt2File, NULL), 1);
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
    for (i = 0; i < sk_X509_num(chain); i++) {
        ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
                             sk_X509_value(testData->expectedChain, i)), 0);
    }
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex3(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;
    int i = 0;

    /* Test case 3, mix and match X509 with files */
    ExpectNotNull(store = X509_STORE_new());
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
    ExpectIntEQ(X509_STORE_load_locations(
        store, testData->caFile, NULL), 1);
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
    for (i = 0; i < sk_X509_num(chain); i++) {
        ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
                             sk_X509_value(testData->expectedChain, i)), 0);
    }
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex4(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;
    STACK_OF(X509)* inter = NULL;
    int i = 0;

    /* Test case 4, CA loaded by file, intermediates passed on init */
    ExpectNotNull(store = X509_STORE_new());
    ExpectIntEQ(X509_STORE_load_locations(
        store, testData->caFile, NULL), 1);
    ExpectNotNull(inter = sk_X509_new_null());
    ExpectIntGE(sk_X509_push(inter, testData->x509CaInt), 1);
    ExpectIntGE(sk_X509_push(inter, testData->x509CaInt2), 1);
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, inter), 1);
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
    for (i = 0; i < sk_X509_num(chain); i++) {
        ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
                             sk_X509_value(testData->expectedChain, i)), 0);
    }
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    sk_X509_free(inter);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex5(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;
    STACK_OF(X509)* trusted = NULL;
    int i = 0;

    /* Test case 5, manually set trusted stack */
    ExpectNotNull(store = X509_STORE_new());
    ExpectNotNull(trusted = sk_X509_new_null());
    ExpectIntGE(sk_X509_push(trusted, testData->x509Ca), 1);
    ExpectIntGE(sk_X509_push(trusted, testData->x509CaInt), 1);
    ExpectIntGE(sk_X509_push(trusted, testData->x509CaInt2), 1);
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
    X509_STORE_CTX_trusted_stack(ctx, trusted);
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
    for (i = 0; i < sk_X509_num(chain); i++) {
        ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
                             sk_X509_value(testData->expectedChain, i)), 0);
    }
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    sk_X509_free(trusted);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex6(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;
    STACK_OF(X509)* trusted = NULL;
    STACK_OF(X509)* inter = NULL;
    int i = 0;

    /* Test case 6, manually set trusted stack will be unified with
     * any intermediates provided on init */
    ExpectNotNull(store = X509_STORE_new());
    ExpectNotNull(trusted = sk_X509_new_null());
    ExpectNotNull(inter = sk_X509_new_null());
    ExpectIntGE(sk_X509_push(trusted, testData->x509Ca), 1);
    ExpectIntGE(sk_X509_push(inter, testData->x509CaInt), 1);
    ExpectIntGE(sk_X509_push(inter, testData->x509CaInt2), 1);
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, inter), 1);
    X509_STORE_CTX_trusted_stack(ctx, trusted);
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
    for (i = 0; i < sk_X509_num(chain); i++) {
        ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
                             sk_X509_value(testData->expectedChain, i)), 0);
    }
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    sk_X509_free(trusted);
    sk_X509_free(inter);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex7(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;
    int i = 0;

    /* Test case 7, certs added to store after ctx init are still used */
    ExpectNotNull(store = X509_STORE_new());
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
    ExpectIntNE(X509_verify_cert(ctx), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509Ca), 1);
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
    for (i = 0; i < sk_X509_num(chain); i++) {
        ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
                             sk_X509_value(testData->expectedChain, i)), 0);
    }
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex8(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;
    int i = 0;

    /* Test case 8, Only full chain verifies */
    ExpectNotNull(store = X509_STORE_new());
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
    ExpectIntNE(X509_verify_cert(ctx), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
    ExpectIntNE(X509_verify_cert(ctx), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
    ExpectIntNE(X509_verify_cert(ctx), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509Ca), 1);
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
    for (i = 0; i < sk_X509_num(chain); i++) {
        ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
                             sk_X509_value(testData->expectedChain, i)), 0);
    }
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex9(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    X509_STORE_CTX* ctx2 = NULL;
    STACK_OF(X509)* trusted = NULL;

    /* Test case 9, certs added to store should not be reflected in ctx that
     * has been manually set with a trusted stack, but are reflected in ctx
     * that has not set trusted stack */
    ExpectNotNull(store = X509_STORE_new());
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectNotNull(ctx2 = X509_STORE_CTX_new());
    ExpectNotNull(trusted = sk_X509_new_null());
    ExpectIntGE(sk_X509_push(trusted, testData->x509Ca), 1);
    ExpectIntGE(sk_X509_push(trusted, testData->x509CaInt), 1);
    ExpectIntGE(sk_X509_push(trusted, testData->x509CaInt2), 1);
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
    ExpectIntEQ(X509_STORE_CTX_init(ctx2, store, testData->x509Leaf, NULL), 1);
    ExpectIntNE(X509_verify_cert(ctx), 1);
    ExpectIntNE(X509_verify_cert(ctx2), 1);
    X509_STORE_CTX_trusted_stack(ctx, trusted);
    /* CTX1 should now verify */
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectIntNE(X509_verify_cert(ctx2), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509Ca), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
    /* CTX2 should now verify */
    ExpectIntEQ(X509_verify_cert(ctx2), 1);
    X509_STORE_CTX_free(ctx);
    X509_STORE_CTX_free(ctx2);
    X509_STORE_free(store);
    sk_X509_free(trusted);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex10(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;

    /* Test case 10, ensure partial chain flag works */
    ExpectNotNull(store = X509_STORE_new());
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
    /* Fails because chain is incomplete */
    ExpectIntNE(X509_verify_cert(ctx), 1);
    ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN), 1);
    /* Partial chain now OK */
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_ex11(X509_STORE_test_data *testData)
{
    EXPECT_DECLS;
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    STACK_OF(X509)* chain = NULL;

    /* Test case 11, test partial chain flag on ctx itself */
    ExpectNotNull(store = X509_STORE_new());
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
    ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
    /* Fails because chain is incomplete */
    ExpectIntNE(X509_verify_cert(ctx), 1);
    X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_PARTIAL_CHAIN);
    /* Partial chain now OK */
    ExpectIntEQ(X509_verify_cert(ctx), 1);
    ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_X509_STORE_CTX_ex(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    X509_STORE_test_data testData;
    XMEMSET((void *)&testData, 0, sizeof(X509_STORE_test_data));
    testData.caFile =     "./certs/ca-cert.pem";
    testData.caIntFile =  "./certs/intermediate/ca-int-cert.pem";
    testData.caInt2File = "./certs/intermediate/ca-int2-cert.pem";
    testData.leafFile =   "./certs/intermediate/server-chain.pem";

    ExpectNotNull(testData.x509Ca = \
                  test_wolfSSL_X509_STORE_CTX_ex_helper(testData.caFile));
    ExpectNotNull(testData.x509CaInt = \
                  test_wolfSSL_X509_STORE_CTX_ex_helper(testData.caIntFile));
    ExpectNotNull(testData.x509CaInt2 = \
                  test_wolfSSL_X509_STORE_CTX_ex_helper(testData.caInt2File));
    ExpectNotNull(testData.x509Leaf = \
                  test_wolfSSL_X509_STORE_CTX_ex_helper(testData.leafFile));
    ExpectNotNull(testData.expectedChain = sk_X509_new_null());
    ExpectIntGE(sk_X509_push(testData.expectedChain, testData.x509Leaf), 1);
    ExpectIntGE(sk_X509_push(testData.expectedChain, testData.x509CaInt2), 1);
    ExpectIntGE(sk_X509_push(testData.expectedChain, testData.x509CaInt), 1);
    ExpectIntGE(sk_X509_push(testData.expectedChain, testData.x509Ca), 1);

    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex1(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex2(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex3(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex4(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex5(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex6(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex7(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex8(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex9(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex10(&testData), 1);
    ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex11(&testData), 1);

    if(testData.x509Ca) {
        X509_free(testData.x509Ca);
    }
    if(testData.x509CaInt) {
        X509_free(testData.x509CaInt);
    }
    if(testData.x509CaInt2) {
        X509_free(testData.x509CaInt2);
    }
    if(testData.x509Leaf) {
        X509_free(testData.x509Leaf);
    }
    if (testData.expectedChain) {
        sk_X509_free(testData.expectedChain);
    }

#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
        * !defined(NO_FILESYSTEM) && !defined(NO_RSA) */

    return EXPECT_RESULT();
}


#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
static int test_X509_STORE_untrusted_load_cert_to_stack(const char* filename,
        STACK_OF(X509)* chain)
{
    EXPECT_DECLS;
    XFILE fp = XBADFILE;
    X509* cert = NULL;

    ExpectTrue((fp = XFOPEN(filename, "rb"))
            != XBADFILE);
    ExpectNotNull(cert = PEM_read_X509(fp, 0, 0, 0 ));
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }
    ExpectIntGT(sk_X509_push(chain, cert), 0);
    if (EXPECT_FAIL())
        X509_free(cert);

    return EXPECT_RESULT();
}

static int test_X509_STORE_untrusted_certs(const char** filenames, int ret,
        int err, int loadCA)
{
    EXPECT_DECLS;
    X509_STORE_CTX* ctx = NULL;
    X509_STORE* str = NULL;
    XFILE fp = XBADFILE;
    X509* cert = NULL;
    STACK_OF(X509)* untrusted = NULL;

    ExpectTrue((fp = XFOPEN("./certs/intermediate/server-int-cert.pem", "rb"))
            != XBADFILE);
    ExpectNotNull(cert = PEM_read_X509(fp, 0, 0, 0 ));
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }

    ExpectNotNull(str = X509_STORE_new());
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectNotNull(untrusted = sk_X509_new_null());

    ExpectIntEQ(X509_STORE_set_flags(str, 0), 1);
    if (loadCA) {
        ExpectIntEQ(X509_STORE_load_locations(str, "./certs/ca-cert.pem", NULL),
                1);
    }
    for (; *filenames; filenames++) {
        ExpectIntEQ(test_X509_STORE_untrusted_load_cert_to_stack(*filenames,
                untrusted), TEST_SUCCESS);
    }

    ExpectIntEQ(X509_STORE_CTX_init(ctx, str, cert, untrusted), 1);
    ExpectIntEQ(X509_verify_cert(ctx), ret);
    ExpectIntEQ(X509_STORE_CTX_get_error(ctx), err);

    X509_free(cert);
    X509_STORE_free(str);
    X509_STORE_CTX_free(ctx);
    sk_X509_pop_free(untrusted, NULL);

    return EXPECT_RESULT();
}
#endif

static int test_X509_STORE_untrusted(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    const char* untrusted1[] = {
        "./certs/intermediate/ca-int2-cert.pem",
        NULL
    };
    const char* untrusted2[] = {
        "./certs/intermediate/ca-int-cert.pem",
        "./certs/intermediate/ca-int2-cert.pem",
        NULL
    };
    const char* untrusted3[] = {
        "./certs/intermediate/ca-int-cert.pem",
        "./certs/intermediate/ca-int2-cert.pem",
        "./certs/ca-cert.pem",
        NULL
    };
    /* Adding unrelated certs that should be ignored */
    const char* untrusted4[] = {
        "./certs/client-ca.pem",
        "./certs/intermediate/ca-int-cert.pem",
        "./certs/server-cert.pem",
        "./certs/intermediate/ca-int2-cert.pem",
        NULL
    };

    /* Only immediate issuer in untrusted chain. Fails since can't build chain
     * to loaded CA. */
    ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted1, 0,
            X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, 1), TEST_SUCCESS);
    /* Succeeds because path to loaded CA is available. */
    ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted2, 1, 0, 1),
            TEST_SUCCESS);
    /* Root CA in untrusted chain is OK so long as CA has been loaded
     * properly */
    ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 1, 0, 1),
            TEST_SUCCESS);
    /* Still needs properly loaded CA, while including it in untrusted
     * list is not an error, it also doesnt count for verify */
    ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 0,
                X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, 0),
            TEST_SUCCESS);
    /* Succeeds because path to loaded CA is available. */
    ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted4, 1, 0, 1),
            TEST_SUCCESS);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_set_flags(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    X509_STORE* store = NULL;
    X509* x509 = NULL;

    ExpectNotNull((store = wolfSSL_X509_STORE_new()));
    ExpectNotNull((x509 = wolfSSL_X509_load_certificate_file(svrCertFile,
        WOLFSSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_add_cert(store, x509), WOLFSSL_SUCCESS);

#ifdef HAVE_CRL
    ExpectIntEQ(X509_STORE_set_flags(store, WOLFSSL_CRL_CHECKALL),
        WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(X509_STORE_set_flags(store, WOLFSSL_CRL_CHECKALL),
        WC_NO_ERR_TRACE(NOT_COMPILED_IN));
#endif

    wolfSSL_X509_free(x509);
    wolfSSL_X509_STORE_free(store);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) &&
        * !defined(NO_FILESYSTEM) && !defined(NO_RSA) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_LOOKUP_load_file(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \
   (!defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH))
    WOLFSSL_X509_STORE*  store = NULL;
    WOLFSSL_X509_LOOKUP* lookup = NULL;

    ExpectNotNull(store = wolfSSL_X509_STORE_new());
    ExpectNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()));
    ExpectIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/client-ca.pem",
        X509_FILETYPE_PEM), 1);
    ExpectIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/crl/crl2.pem",
        X509_FILETYPE_PEM), 1);

    if (store != NULL) {
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm, cliCertFile,
            WOLFSSL_FILETYPE_PEM), 1);
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm, svrCertFile,
            WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
    }
    ExpectIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/ca-cert.pem",
        X509_FILETYPE_PEM), 1);
    if (store != NULL) {
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm, svrCertFile,
            WOLFSSL_FILETYPE_PEM), 1);
    }

    wolfSSL_X509_STORE_free(store);
#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_CRL) &&
        * !defined(NO_FILESYSTEM) && !defined(NO_RSA) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_set_time(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    WOLFSSL_X509_STORE_CTX* ctx = NULL;
    time_t c_time;

    ExpectNotNull(ctx = wolfSSL_X509_STORE_CTX_new());
    c_time = 365*24*60*60;
    wolfSSL_X509_STORE_CTX_set_time(ctx, 0, c_time);
    ExpectTrue((ctx->param->flags & WOLFSSL_USE_CHECK_TIME) ==
        WOLFSSL_USE_CHECK_TIME);
    ExpectTrue(ctx->param->check_time == c_time);
    wolfSSL_X509_STORE_CTX_free(ctx);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_get0_set1_param(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    SSL_CTX* ctx = NULL;
    WOLFSSL_X509_VERIFY_PARAM* pParam = NULL;
    WOLFSSL_X509_VERIFY_PARAM* pvpm = NULL;
    char testIPv4[] = "127.0.0.1";
    char testhostName[] = "foo.hoge.com";

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif

    ExpectNull(SSL_CTX_get0_param(NULL));
    ExpectNotNull(pParam = SSL_CTX_get0_param(ctx));

    ExpectNotNull(pvpm = (WOLFSSL_X509_VERIFY_PARAM *)XMALLOC(
        sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL));
    ExpectNotNull(XMEMSET(pvpm, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)));

    ExpectIntEQ(wolfSSL_X509_VERIFY_PARAM_set1_host(pvpm, testhostName,
        (int)XSTRLEN(testhostName)), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(pvpm, testIPv4),
        WOLFSSL_SUCCESS);
    wolfSSL_X509_VERIFY_PARAM_set_hostflags(pvpm, 0x01);

    ExpectIntEQ(SSL_CTX_set1_param(ctx, pvpm), 1);
    ExpectIntEQ(0, XSTRNCMP(pParam->hostName, testhostName,
        (int)XSTRLEN(testhostName)));
    ExpectIntEQ(0x01, pParam->hostFlags);
    ExpectIntEQ(0, XSTRNCMP(pParam->ipasc, testIPv4, WOLFSSL_MAX_IPSTR));

    /* test for incorrect parameter */
    ExpectIntEQ(1,SSL_CTX_set1_param(ctx, NULL));
    ExpectIntEQ(1,SSL_CTX_set1_param(NULL, pvpm));
    ExpectIntEQ(1,SSL_CTX_set1_param(NULL, NULL));

    SSL_CTX_free(ctx);

    XFREE(pvpm, NULL, DYNAMIC_TYPE_OPENSSL);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* OPENSSL_EXTRA && !defined(NO_RSA)*/
    return EXPECT_RESULT();
}

static int test_wolfSSL_get0_param(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    SSL_CTX* ctx = NULL;
    SSL*     ssl = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
        SSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    ExpectNotNull(SSL_get0_param(ssl));

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* OPENSSL_EXTRA && !defined(NO_RSA)*/
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_VERIFY_PARAM_set1_host(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    const char host[] = "www.example.com";
    WOLFSSL_X509_VERIFY_PARAM* pParam = NULL;

    ExpectNotNull(pParam = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
        sizeof(WOLFSSL_X509_VERIFY_PARAM), HEAP_HINT, DYNAMIC_TYPE_OPENSSL));
    if (pParam != NULL) {
        XMEMSET(pParam, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));

        X509_VERIFY_PARAM_set1_host(pParam, host, sizeof(host));

        ExpectIntEQ(XMEMCMP(pParam->hostName, host, sizeof(host)), 0);

        XMEMSET(pParam, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));

        ExpectIntNE(XMEMCMP(pParam->hostName, host, sizeof(host)), 0);

        XFREE(pParam, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
    }
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_set1_host(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    const char host[] = "www.test_wolfSSL_set1_host.com";
    const char emptyStr[] = "";
    SSL_CTX*   ctx = NULL;
    SSL*       ssl = NULL;
    WOLFSSL_X509_VERIFY_PARAM* pParam = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
        SSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    pParam = SSL_get0_param(ssl);

    /* we should get back host string */
    ExpectIntEQ(SSL_set1_host(ssl, host), WOLFSSL_SUCCESS);
    ExpectIntEQ(XMEMCMP(pParam->hostName, host, sizeof(host)), 0);

    /* we should get back empty string */
    ExpectIntEQ(SSL_set1_host(ssl, emptyStr), WOLFSSL_SUCCESS);
    ExpectIntEQ(XMEMCMP(pParam->hostName, emptyStr, sizeof(emptyStr)), 0);

    /* we should get back host string */
    ExpectIntEQ(SSL_set1_host(ssl, host), WOLFSSL_SUCCESS);
    ExpectIntEQ(XMEMCMP(pParam->hostName, host, sizeof(host)), 0);

    /* we should get back empty string */
    ExpectIntEQ(SSL_set1_host(ssl, NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(XMEMCMP(pParam->hostName, emptyStr, sizeof(emptyStr)), 0);

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_VERIFY_PARAM_set1_ip(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    unsigned char buf[16] = {0};
    WOLFSSL_X509_VERIFY_PARAM* param = NULL;

    ExpectNotNull(param = X509_VERIFY_PARAM_new());

    /* test 127.0.0.1 */
    buf[0] =0x7f; buf[1] = 0; buf[2] = 0; buf[3] = 1;
    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 4), SSL_SUCCESS);
    ExpectIntEQ(XSTRNCMP(param->ipasc, "127.0.0.1", sizeof(param->ipasc)), 0);

    /* test 2001:db8:3333:4444:5555:6666:7777:8888 */
    buf[0]=32;buf[1]=1;buf[2]=13;buf[3]=184;
    buf[4]=51;buf[5]=51;buf[6]=68;buf[7]=68;
    buf[8]=85;buf[9]=85;buf[10]=102;buf[11]=102;
    buf[12]=119;buf[13]=119;buf[14]=136;buf[15]=136;
    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS);
    ExpectIntEQ(XSTRNCMP(param->ipasc,
        "2001:db8:3333:4444:5555:6666:7777:8888", sizeof(param->ipasc)), 0);

    /* test 2001:db8:: */
    buf[0]=32;buf[1]=1;buf[2]=13;buf[3]=184;
    buf[4]=0;buf[5]=0;buf[6]=0;buf[7]=0;
    buf[8]=0;buf[9]=0;buf[10]=0;buf[11]=0;
    buf[12]=0;buf[13]=0;buf[14]=0;buf[15]=0;
    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS);
    ExpectIntEQ(XSTRNCMP(param->ipasc, "2001:db8::", sizeof(param->ipasc)), 0);

    /* test ::1234:5678 */
    buf[0]=0;buf[1]=0;buf[2]=0;buf[3]=0;
    buf[4]=0;buf[5]=0;buf[6]=0;buf[7]=0;
    buf[8]=0;buf[9]=0;buf[10]=0;buf[11]=0;
    buf[12]=18;buf[13]=52;buf[14]=86;buf[15]=120;
    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS);
    ExpectIntEQ(XSTRNCMP(param->ipasc, "::1234:5678", sizeof(param->ipasc)), 0);


    /* test 2001:db8::1234:5678 */
    buf[0]=32;buf[1]=1;buf[2]=13;buf[3]=184;
    buf[4]=0;buf[5]=0;buf[6]=0;buf[7]=0;
    buf[8]=0;buf[9]=0;buf[10]=0;buf[11]=0;
    buf[12]=18;buf[13]=52;buf[14]=86;buf[15]=120;
    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS);
    ExpectIntEQ(XSTRNCMP(param->ipasc, "2001:db8::1234:5678",
                                                sizeof(param->ipasc)), 0);

    /* test 2001:0db8:0001:0000:0000:0ab9:c0a8:0102*/
    /*      2001:db8:1::ab9:c0a8:102 */
    buf[0]=32;buf[1]=1;buf[2]=13;buf[3]=184;
    buf[4]=0;buf[5]=1;buf[6]=0;buf[7]=0;
    buf[8]=0;buf[9]=0;buf[10]=10;buf[11]=185;
    buf[12]=192;buf[13]=168;buf[14]=1;buf[15]=2;
    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS);
    ExpectIntEQ(XSTRNCMP(param->ipasc, "2001:db8:1::ab9:c0a8:102",
                                                sizeof(param->ipasc)), 0);

    XFREE(param, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_CTX_get0_store(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    X509_STORE* store = NULL;
    X509_STORE_CTX* ctx = NULL;
    X509_STORE_CTX* ctx_no_init = NULL;

    ExpectNotNull((store = X509_STORE_new()));
    ExpectNotNull(ctx = X509_STORE_CTX_new());
    ExpectNotNull(ctx_no_init = X509_STORE_CTX_new());
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, NULL, NULL), SSL_SUCCESS);

    ExpectNull(X509_STORE_CTX_get0_store(NULL));
    /* should return NULL if ctx has not bee initialized */
    ExpectNull(X509_STORE_CTX_get0_store(ctx_no_init));
    ExpectNotNull(X509_STORE_CTX_get0_store(ctx));

    wolfSSL_X509_STORE_CTX_free(ctx);
    wolfSSL_X509_STORE_CTX_free(ctx_no_init);
    X509_STORE_free(store);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_set_client_CA_list(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_CLIENT) && !defined(NO_BIO)
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL* ssl = NULL;
    X509_NAME* name = NULL;
    STACK_OF(X509_NAME)* names = NULL;
    STACK_OF(X509_NAME)* ca_list = NULL;
    int names_len = 0;
    int i;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    /* Send two X501 names in cert request */
    names = SSL_load_client_CA_file(cliCertFile);
    ExpectNotNull(names);
    ca_list = SSL_load_client_CA_file(caCertFile);
    ExpectNotNull(ca_list);
    ExpectNotNull(name = sk_X509_NAME_value(ca_list, 0));
    ExpectIntEQ(sk_X509_NAME_push(names, name), 2);
    if (EXPECT_FAIL()) {
        wolfSSL_X509_NAME_free(name);
        name = NULL;
    }
    SSL_CTX_set_client_CA_list(ctx, names);
    /* This should only free the stack structure */
    sk_X509_NAME_free(ca_list);
    ca_list = NULL;
    ExpectNotNull(ca_list = SSL_CTX_get_client_CA_list(ctx));
    ExpectIntEQ(sk_X509_NAME_num(ca_list), sk_X509_NAME_num(names));

    ExpectIntGT((names_len = sk_X509_NAME_num(names)), 0);
    for (i = 0; i < names_len; i++) {
        ExpectNotNull(name = sk_X509_NAME_value(names, i));
        ExpectIntEQ(sk_X509_NAME_find(names, name), i);
    }

    /* Needed to be able to create ssl object */
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
        SSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    /* load again as old names are responsibility of ctx to free*/
    names = SSL_load_client_CA_file(cliCertFile);
    ExpectNotNull(names);
    SSL_set_client_CA_list(ssl, names);
    ExpectNotNull(ca_list = SSL_get_client_CA_list(ssl));
    ExpectIntEQ(sk_X509_NAME_num(ca_list), sk_X509_NAME_num(names));

    ExpectIntGT((names_len = sk_X509_NAME_num(names)), 0);
    for (i = 0; i < names_len; i++) {
        ExpectNotNull(name = sk_X509_NAME_value(names, i));
        ExpectIntEQ(sk_X509_NAME_find(names, name), i);
    }

#if !defined(SINGLE_THREADED) && defined(SESSION_CERTS)
    {
        tcp_ready ready;
        func_args server_args;
        callback_functions server_cb;
        THREAD_TYPE serverThread;
        WOLFSSL* ssl_client = NULL;
        WOLFSSL_CTX* ctx_client = NULL;
        SOCKET_T sockfd = 0;

        /* wolfSSL_get_client_CA_list() with handshake */

        StartTCP();
        InitTcpReady(&ready);

        XMEMSET(&server_args, 0, sizeof(func_args));
        XMEMSET(&server_cb, 0, sizeof(callback_functions));

        server_args.signal    = &ready;
        server_args.callbacks = &server_cb;

        /* we are responsible for free'ing WOLFSSL_CTX */
        server_cb.ctx = ctx;
        server_cb.isSharedCtx = 1;

        ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx,
            cliCertFile, 0));

        start_thread(test_server_nofail, &server_args, &serverThread);
        wait_tcp_ready(&server_args);

        tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL);
        ExpectNotNull(ctx_client =
            wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
        ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_load_verify_locations(
            ctx_client, caCertFile, 0));
        ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_certificate_file(
            ctx_client, cliCertFile, SSL_FILETYPE_PEM));
        ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_PrivateKey_file(
            ctx_client, cliKeyFile, SSL_FILETYPE_PEM));

        ExpectNotNull(ssl_client = wolfSSL_new(ctx_client));
        ExpectIntEQ(wolfSSL_set_fd(ssl_client, sockfd), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_connect(ssl_client), WOLFSSL_SUCCESS);

        ExpectNotNull(ca_list = SSL_get_client_CA_list(ssl_client));
        /* We are expecting two cert names to be sent */
        ExpectIntEQ(sk_X509_NAME_num(ca_list), 2);

        ExpectNotNull(names = SSL_CTX_get_client_CA_list(ctx));
        for (i=0; i<sk_X509_NAME_num(ca_list); i++) {
            ExpectNotNull(name = sk_X509_NAME_value(ca_list, i));
            ExpectIntGE(sk_X509_NAME_find(names, name), 0);
        }

        wolfSSL_shutdown(ssl_client);
        wolfSSL_free(ssl_client);
        wolfSSL_CTX_free(ctx_client);

        CloseSocket(sockfd);

        join_thread(serverThread);
        FreeTcpReady(&ready);
    }
#endif

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && !NO_RSA && !NO_CERTS && !NO_WOLFSSL_CLIENT &&
        * !NO_BIO */
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_add_client_CA(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_CERTS) && \
    !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL_X509* x509 = NULL;
    WOLFSSL_X509* x509_a = NULL;
    STACK_OF(X509_NAME)* ca_list = NULL;

    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
    /* Add client cert */
    ExpectNotNull(x509 = X509_load_certificate_file(cliCertFile,
        SSL_FILETYPE_PEM));
    ExpectIntEQ(SSL_CTX_add_client_CA(ctx, x509), SSL_SUCCESS);
    ExpectNotNull(ca_list = SSL_CTX_get_client_CA_list(ctx));
    /* Add another client cert */
    ExpectNotNull(x509_a = X509_load_certificate_file(cliCertFile,
        SSL_FILETYPE_PEM));
    ExpectIntEQ(SSL_CTX_add_client_CA(ctx, x509_a), SSL_SUCCESS);

    /* test for incorrect parameter */
    ExpectIntEQ(SSL_CTX_add_client_CA(NULL, x509), 0);
    ExpectIntEQ(SSL_CTX_add_client_CA(ctx, NULL), 0);
    ExpectIntEQ(SSL_CTX_add_client_CA(NULL, NULL), 0);

    X509_free(x509);
    X509_free(x509_a);
    SSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA  && !NO_RSA && !NO_CERTS && !NO_WOLFSSL_CLIENT */
    return EXPECT_RESULT();
}
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES)
static THREAD_RETURN WOLFSSL_THREAD server_task_ech(void* args)
{
    callback_functions* callbacks = ((func_args*)args)->callbacks;
    WOLFSSL_CTX* ctx       = callbacks->ctx;
    WOLFSSL*  ssl   = NULL;
    SOCKET_T  sfd   = 0;
    SOCKET_T  cfd   = 0;
    word16    port;
    char      input[1024];
    int       idx;
    int       ret, err = 0;
    const char* privateName = "ech-private-name.com";
    int         privateNameLen = (int)XSTRLEN(privateName);

    ((func_args*)args)->return_code = TEST_FAIL;
    port = ((func_args*)args)->signal->port;

    AssertIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CTX_load_verify_locations(ctx, cliCertFile, 0));

    AssertIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
            WOLFSSL_FILETYPE_PEM));

    AssertIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
                 WOLFSSL_FILETYPE_PEM));

    if (callbacks->ctx_ready)
        callbacks->ctx_ready(ctx);

    ssl = wolfSSL_new(ctx);

    /* set the sni for the server */
    wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, privateName, privateNameLen);

    tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1, NULL, NULL);
    CloseSocket(sfd);
    AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_set_fd(ssl, cfd));

    if (callbacks->ssl_ready)
        callbacks->ssl_ready(ssl);

    do {
        err = 0; /* Reset error */
        ret = wolfSSL_accept(ssl);
        if (ret != WOLFSSL_SUCCESS) {
            err = wolfSSL_get_error(ssl, 0);
        }
    } while (ret != WOLFSSL_SUCCESS && err == WC_NO_ERR_TRACE(WC_PENDING_E));

    if (ret != WOLFSSL_SUCCESS) {
        char buff[WOLFSSL_MAX_ERROR_SZ];
        fprintf(stderr, "error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buff));
    }
    else {
        if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) {
            input[idx] = 0;
           fprintf(stderr, "Client message: %s\n", input);
        }

        AssertIntEQ(privateNameLen, wolfSSL_write(ssl, privateName,
            privateNameLen));
        ((func_args*)args)->return_code = TEST_SUCCESS;
    }

    if (callbacks->on_result)
        callbacks->on_result(ssl);

    wolfSSL_shutdown(ssl);
    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    CloseSocket(cfd);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif

    WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* HAVE_ECH && WOLFSSL_TLS13 */

#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
static void keyLog_callback(const WOLFSSL* ssl, const char* line)
{
    XFILE fp;
    const byte lf = '\n';

    AssertNotNull(ssl);
    AssertNotNull(line);

    fp = XFOPEN("./MyKeyLog.txt", "a");
    XFWRITE(line, 1, XSTRLEN(line), fp);
    XFWRITE((void*)&lf, 1, 1, fp);
    XFFLUSH(fp);
    XFCLOSE(fp);
}
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
static int test_wolfSSL_CTX_set_keylog_callback(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK) && \
                              !defined(NO_WOLFSSL_CLIENT)
    SSL_CTX* ctx = NULL;

    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
    SSL_CTX_set_keylog_callback(ctx, keyLog_callback );
    SSL_CTX_free(ctx);
    SSL_CTX_set_keylog_callback(NULL, NULL);
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK && !NO_WOLFSSL_CLIENT */
    return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_get_keylog_callback(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK) && \
                                !defined(NO_WOLFSSL_CLIENT)
    SSL_CTX* ctx = NULL;

    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
    ExpectPtrEq(SSL_CTX_get_keylog_callback(ctx),NULL);
    SSL_CTX_set_keylog_callback(ctx, keyLog_callback );
    ExpectPtrEq(SSL_CTX_get_keylog_callback(ctx),keyLog_callback);
    SSL_CTX_set_keylog_callback(ctx, NULL );
    ExpectPtrEq(SSL_CTX_get_keylog_callback(ctx),NULL);
    SSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK && !NO_WOLFSSL_CLIENT */
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
static int test_wolfSSL_Tls12_Key_Logging_client_ctx_ready(WOLFSSL_CTX* ctx)
{
    /* set keylog callback */
    wolfSSL_CTX_set_keylog_callback(ctx, keyLog_callback);
    return TEST_SUCCESS;
}
#endif

static int test_wolfSSL_Tls12_Key_Logging_test(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
    /* This test is intended for checking whether keylog callback is called
     * in client during TLS handshake between the client and a server.
     */
    test_ssl_cbf server_cbf;
    test_ssl_cbf client_cbf;
    XFILE fp = XBADFILE;
    char  buff[500];
    int   found = 0;

    XMEMSET(&server_cbf, 0, sizeof(test_ssl_cbf));
    XMEMSET(&client_cbf, 0, sizeof(test_ssl_cbf));
    server_cbf.method     = wolfTLSv1_2_server_method;
    client_cbf.ctx_ready = &test_wolfSSL_Tls12_Key_Logging_client_ctx_ready;

    /* clean up keylog file */
    ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "w")) != XBADFILE);
    if (fp != XBADFILE) {
        XFFLUSH(fp);
        XFCLOSE(fp);
        fp = XBADFILE;
    }

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
        &server_cbf, NULL), TEST_SUCCESS);

    /* check if the keylog file exists */
    ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "r")) != XBADFILE);
    XFFLUSH(fp); /* Just to make sure any buffers get flushed */

    XMEMSET(buff, 0, sizeof(buff));
    while (EXPECT_SUCCESS() && XFGETS(buff, (int)sizeof(buff), fp) != NULL) {
        if (0 == strncmp(buff,"CLIENT_RANDOM ", sizeof("CLIENT_RANDOM ")-1)) {
            found = 1;
            break;
        }
    }
    if (fp != XBADFILE) {
        XFCLOSE(fp);
    }
    /* a log starting with "CLIENT_RANDOM " should exit in the file */
    ExpectIntEQ(found, 1);
    /* clean up */
    ExpectIntEQ(rem_file("./MyKeyLog.txt"), 0);
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
    return EXPECT_RESULT();
}

#if defined(WOLFSSL_TLS13) && defined(OPENSSL_EXTRA) && \
    defined(HAVE_SECRET_CALLBACK)
static int test_wolfSSL_Tls13_Key_Logging_client_ctx_ready(WOLFSSL_CTX* ctx)
{
    /* set keylog callback */
    wolfSSL_CTX_set_keylog_callback(ctx, keyLog_callback);
    return TEST_SUCCESS;
}
#endif

static int test_wolfSSL_Tls13_Key_Logging_test(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && defined(OPENSSL_EXTRA) && \
    defined(HAVE_SECRET_CALLBACK)
/* This test is intended for checking whether keylog callback is called
 * in client during TLS handshake between the client and a server.
 */
    test_ssl_cbf server_cbf;
    test_ssl_cbf client_cbf;
    XFILE fp = XBADFILE;

    XMEMSET(&server_cbf, 0, sizeof(test_ssl_cbf));
    XMEMSET(&client_cbf, 0, sizeof(test_ssl_cbf));
    server_cbf.method    = wolfTLSv1_3_server_method;  /* TLS1.3 */
    client_cbf.ctx_ready = &test_wolfSSL_Tls13_Key_Logging_client_ctx_ready;

    /* clean up keylog file */
    ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "w")) != XBADFILE);
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
        &server_cbf, NULL), TEST_SUCCESS);

    /* check if the keylog file exists */
    {
        char buff[300] = {0};
        int  found[4]   = {0};
        int  numfnd = 0;
        int  i;

        ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "r")) != XBADFILE);

        while (EXPECT_SUCCESS() &&
                XFGETS(buff, (int)sizeof(buff), fp) != NULL) {
            if (0 == strncmp(buff, "CLIENT_HANDSHAKE_TRAFFIC_SECRET ",
                    sizeof("CLIENT_HANDSHAKE_TRAFFIC_SECRET ")-1)) {
                found[0] = 1;
                continue;
            }
            else if (0 == strncmp(buff, "SERVER_HANDSHAKE_TRAFFIC_SECRET ",
                    sizeof("SERVER_HANDSHAKE_TRAFFIC_SECRET ")-1)) {
                found[1] = 1;
                continue;
            }
            else if (0 == strncmp(buff, "CLIENT_TRAFFIC_SECRET_0 ",
                    sizeof("CLIENT_TRAFFIC_SECRET_0 ")-1)) {
                found[2] = 1;
                continue;
            }
            else if (0 == strncmp(buff, "SERVER_TRAFFIC_SECRET_0 ",
                    sizeof("SERVER_TRAFFIC_SECRET_0 ")-1)) {
                found[3] = 1;
                continue;
            }
        }
        if (fp != XBADFILE)
            XFCLOSE(fp);
        for (i = 0; i < 4; i++) {
            if (found[i] != 0)
                numfnd++;
        }
        ExpectIntEQ(numfnd, 4);
    }
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK && WOLFSSL_TLS13 */
    return EXPECT_RESULT();
}
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES)
static int test_wolfSSL_Tls13_ECH_params(void)
{
    EXPECT_DECLS;
#if !defined(NO_WOLFSSL_CLIENT)
    word32 outputLen = 0;
    byte testBuf[72];
    WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
    WOLFSSL     *ssl = wolfSSL_new(ctx);

    ExpectNotNull(ctx);
    ExpectNotNull(ssl);

    /* invalid ctx */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GenerateEchConfig(NULL,
        "ech-public-name.com", 0, 0, 0));
    /* invalid public name */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GenerateEchConfig(ctx, NULL, 0,
        0, 0));
    /* invalid algorithms */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GenerateEchConfig(ctx,
        "ech-public-name.com", 1000, 1000, 1000));

    /* invalid ctx */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GetEchConfigs(NULL, NULL,
        &outputLen));
    /* invalid output len */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GetEchConfigs(ctx, NULL, NULL));

    /* invalid ssl */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigsBase64(NULL,
        (char*)testBuf, sizeof(testBuf)));
    /* invalid configs64 */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigsBase64(ssl, NULL,
        sizeof(testBuf)));
    /* invalid size */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigsBase64(ssl,
        (char*)testBuf, 0));

    /* invalid ssl */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigs(NULL, testBuf,
        sizeof(testBuf)));
    /* invalid configs */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigs(ssl, NULL,
        sizeof(testBuf)));
    /* invalid size */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigs(ssl, testBuf, 0));

    /* invalid ssl */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_GetEchConfigs(NULL, NULL, &outputLen));
    /* invalid size */
    ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_GetEchConfigs(ssl, NULL, NULL));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT */

    return EXPECT_RESULT();
}

static int test_wolfSSL_Tls13_ECH(void)
{
    EXPECT_DECLS;
    tcp_ready ready;
    func_args client_args;
    func_args server_args;
    THREAD_TYPE serverThread;
    callback_functions server_cbf;
    callback_functions client_cbf;
    SOCKET_T sockfd = 0;
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;
    const char* publicName = "ech-public-name.com";
    const char* privateName = "ech-private-name.com";
    int privateNameLen = 20;
    char reply[1024];
    int replyLen = 0;
    byte rawEchConfig[128];
    word32 rawEchConfigLen = sizeof(rawEchConfig);

    InitTcpReady(&ready);
    ready.port = 22222;

    XMEMSET(&client_args, 0, sizeof(func_args));
    XMEMSET(&server_args, 0, sizeof(func_args));
    XMEMSET(&server_cbf, 0, sizeof(callback_functions));
    XMEMSET(&client_cbf, 0, sizeof(callback_functions));
    server_cbf.method     = wolfTLSv1_3_server_method;  /* TLS1.3 */

    /* create the server context here so we can get the ech config */
    ExpectNotNull(server_cbf.ctx =
        wolfSSL_CTX_new(wolfTLSv1_3_server_method()));

    /* generate ech config */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_GenerateEchConfig(server_cbf.ctx,
        publicName, 0, 0, 0));

    /* get the config for the client to use */
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CTX_GetEchConfigs(server_cbf.ctx, rawEchConfig,
        &rawEchConfigLen));

    server_args.callbacks = &server_cbf;
    server_args.signal    = &ready;

    /* start server task */
    start_thread(server_task_ech, &server_args, &serverThread);
    wait_tcp_ready(&server_args);

    /* run as a TLS1.3 client */
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
    ExpectIntEQ(WOLFSSL_SUCCESS,
            wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0));
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM));
    ExpectIntEQ(WOLFSSL_SUCCESS,
        wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));

    tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL);

    /* get connected the server task */
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    /* set the ech configs for the client */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigs(ssl, rawEchConfig,
        rawEchConfigLen));

    /* set the sni for the client */
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
        privateName, privateNameLen));

    ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_write(ssl, privateName, privateNameLen),
        privateNameLen);
    ExpectIntGT((replyLen = wolfSSL_read(ssl, reply, sizeof(reply))), 0);
    /* add th null terminator for string compare */
    reply[replyLen] = 0;
    /* check that the server replied with the private name */
    ExpectStrEQ(privateName, reply);
    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);

    CloseSocket(sockfd);

    join_thread(serverThread);

    FreeTcpReady(&ready);

    return EXPECT_RESULT();
}
#endif /* HAVE_ECH && WOLFSSL_TLS13 */

#if defined(HAVE_IO_TESTS_DEPENDENCIES) && \
defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
    defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
static int post_auth_version_cb(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    /* do handshake and then test version error */
    ExpectIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
    ExpectStrEQ("TLSv1.2", wolfSSL_get_version(ssl));
    return EXPECT_RESULT();
}

static int post_auth_version_client_cb(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    /* do handshake and then test version error */
    ExpectIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
    ExpectStrEQ("TLSv1.2", wolfSSL_get_version(ssl));
    ExpectIntEQ(wolfSSL_verify_client_post_handshake(ssl), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#if defined(OPENSSL_ALL) && !defined(NO_ERROR_QUEUE)
    /* check was added to error queue */
    ExpectIntEQ(wolfSSL_ERR_get_error(), -WC_NO_ERR_TRACE(UNSUPPORTED_PROTO_VERSION));

    /* check the string matches expected string */
    #ifndef NO_ERROR_STRINGS
    ExpectStrEQ(wolfSSL_ERR_error_string(-WC_NO_ERR_TRACE(UNSUPPORTED_PROTO_VERSION), NULL),
            "WRONG_SSL_VERSION");
    #endif
#endif
    return EXPECT_RESULT();
}

static int post_auth_cb(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    WOLFSSL_X509* x509 = NULL;
    /* do handshake and then test version error */
    ExpectIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
    ExpectStrEQ("TLSv1.3", wolfSSL_get_version(ssl));
    ExpectNull(x509 = wolfSSL_get_peer_certificate(ssl));
    wolfSSL_X509_free(x509);
    ExpectIntEQ(wolfSSL_verify_client_post_handshake(ssl), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

static int set_post_auth_cb(WOLFSSL* ssl)
{
    if (!wolfSSL_is_server(ssl)) {
        EXPECT_DECLS;
        ExpectIntEQ(wolfSSL_allow_post_handshake_auth(ssl), 0);
        return EXPECT_RESULT();
    }
    wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_POST_HANDSHAKE, NULL);
    return TEST_SUCCESS;
}
#endif

static int test_wolfSSL_Tls13_postauth(void)
{
    EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && \
    defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
    defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
    test_ssl_cbf server_cbf;
    test_ssl_cbf client_cbf;

    /* test version failure doing post auth with TLS 1.2 connection */
    XMEMSET(&server_cbf, 0, sizeof(server_cbf));
    XMEMSET(&client_cbf, 0, sizeof(client_cbf));
    server_cbf.method = wolfTLSv1_2_server_method;
    server_cbf.ssl_ready = set_post_auth_cb;
    server_cbf.on_result = post_auth_version_cb;
    client_cbf.ssl_ready = set_post_auth_cb;
    client_cbf.on_result = post_auth_version_client_cb;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
        &server_cbf, NULL), TEST_SUCCESS);

    /* tests on post auth with TLS 1.3 */
    XMEMSET(&server_cbf, 0, sizeof(server_cbf));
    XMEMSET(&client_cbf, 0, sizeof(client_cbf));
    server_cbf.method = wolfTLSv1_3_server_method;
    server_cbf.ssl_ready = set_post_auth_cb;
    client_cbf.ssl_ready = set_post_auth_cb;
    server_cbf.on_result = post_auth_cb;
    client_cbf.on_result = NULL;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
        &server_cbf, NULL), TEST_SUCCESS);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_X509_NID(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
    !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_ASN)
    int   sigType;
    int   nameSz;

    X509*  cert = NULL;
    EVP_PKEY*  pubKeyTmp = NULL;
    X509_NAME* name = NULL;

    char commonName[80];
    char countryName[80];
    char localityName[80];
    char stateName[80];
    char orgName[80];
    char orgUnit[80];

    /* ------ PARSE ORIGINAL SELF-SIGNED CERTIFICATE ------ */

    /* convert cert from DER to internal WOLFSSL_X509 struct */
    ExpectNotNull(cert = wolfSSL_X509_d2i_ex(&cert, client_cert_der_2048,
            sizeof_client_cert_der_2048, HEAP_HINT));

    /* ------ EXTRACT CERTIFICATE ELEMENTS ------ */

    /* extract PUBLIC KEY from cert */
    ExpectNotNull(pubKeyTmp = X509_get_pubkey(cert));

    /* extract signatureType */
    ExpectIntNE((sigType = wolfSSL_X509_get_signature_type(cert)), 0);

    /* extract subjectName info */
    ExpectNotNull(name = X509_get_subject_name(cert));
    ExpectIntEQ(X509_NAME_get_text_by_NID(name, -1, NULL, 0), -1);
    ExpectIntGT((nameSz = X509_NAME_get_text_by_NID(name, NID_commonName,
        NULL, 0)), 0);
    ExpectIntEQ(nameSz, 15);
    ExpectIntGT((nameSz = X509_NAME_get_text_by_NID(name, NID_commonName,
        commonName, sizeof(commonName))), 0);
    ExpectIntEQ(nameSz, 15);
    ExpectIntEQ(XMEMCMP(commonName, "www.wolfssl.com", nameSz), 0);
    ExpectIntGT((nameSz = X509_NAME_get_text_by_NID(name, NID_commonName,
        commonName, 9)), 0);
    ExpectIntEQ(nameSz, 8);
    ExpectIntEQ(XMEMCMP(commonName, "www.wolf", nameSz), 0);

    ExpectIntGT((nameSz = X509_NAME_get_text_by_NID(name, NID_countryName,
        countryName, sizeof(countryName))), 0);
    ExpectIntEQ(XMEMCMP(countryName, "US", nameSz), 0);

    ExpectIntGT((nameSz = X509_NAME_get_text_by_NID(name, NID_localityName,
        localityName, sizeof(localityName))), 0);
    ExpectIntEQ(XMEMCMP(localityName, "Bozeman", nameSz), 0);

    ExpectIntGT((nameSz = X509_NAME_get_text_by_NID(name,
        NID_stateOrProvinceName, stateName, sizeof(stateName))), 0);
    ExpectIntEQ(XMEMCMP(stateName, "Montana", nameSz), 0);

    ExpectIntGT((nameSz = X509_NAME_get_text_by_NID(name, NID_organizationName,
        orgName, sizeof(orgName))), 0);
    ExpectIntEQ(XMEMCMP(orgName, "wolfSSL_2048", nameSz), 0);

    ExpectIntGT((nameSz = X509_NAME_get_text_by_NID(name,
        NID_organizationalUnitName, orgUnit, sizeof(orgUnit))), 0);
    ExpectIntEQ(XMEMCMP(orgUnit, "Programming-2048", nameSz), 0);

    EVP_PKEY_free(pubKeyTmp);
    X509_free(cert);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_set_srp_username(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
    && !defined(NO_SHA256) && !defined(WC_NO_RNG) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL* ssl = NULL;
    const char *username = "TESTUSER";
    const char *password = "TESTPASSWORD";

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectIntEQ(wolfSSL_CTX_set_srp_username(ctx, (char *)username),
         SSL_SUCCESS);
    wolfSSL_CTX_free(ctx);
    ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectIntEQ(wolfSSL_CTX_set_srp_password(ctx, (char *)password),
        SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_set_srp_username(ctx, (char *)username),
        SSL_SUCCESS);

    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectNotNull(SSL_get_srp_username(ssl));
    ExpectStrEQ(SSL_get_srp_username(ssl), username);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && WOLFCRYPT_HAVE_SRP */
       /* && !NO_SHA256 && !WC_NO_RNG && !NO_WOLFSSL_CLIENT */
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_set_srp_password(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) && \
    !defined(NO_SHA256) && !defined(WC_NO_RNG) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX* ctx = NULL;
    const char *username = "TESTUSER";
    const char *password = "TESTPASSWORD";

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectIntEQ(wolfSSL_CTX_set_srp_password(ctx, (char *)password),
        SSL_SUCCESS);
    wolfSSL_CTX_free(ctx);
    ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectIntEQ(wolfSSL_CTX_set_srp_username(ctx, (char *)username),
        SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_set_srp_password(ctx, (char *)password),
        SSL_SUCCESS);
    wolfSSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && WOLFCRYPT_HAVE_SRP */
       /* && !NO_SHA256 && !WC_NO_RNG && !NO_WOLFSSL_CLIENT */
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    X509_STORE *store = NULL;

#ifdef HAVE_CRL
    X509_STORE_CTX *storeCtx = NULL;
    X509 *ca = NULL;
    X509 *cert = NULL;
    const char srvCert[] = "./certs/server-revoked-cert.pem";
    const char caCert[] = "./certs/ca-cert.pem";
#ifndef WOLFSSL_CRL_ALLOW_MISSING_CDP
    X509_CRL *crl = NULL;
    const char crlPem[] = "./certs/crl/crl.revoked";
    XFILE fp = XBADFILE;
#endif /* !WOLFSSL_CRL_ALLOW_MISSING_CDP */

    ExpectNotNull(store = (X509_STORE *)X509_STORE_new());
    ExpectNotNull((ca = wolfSSL_X509_load_certificate_file(caCert,
                           SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_add_cert(store, ca), SSL_SUCCESS);
    ExpectNotNull((cert = wolfSSL_X509_load_certificate_file(srvCert,
                    SSL_FILETYPE_PEM)));
    ExpectNotNull((storeCtx = X509_STORE_CTX_new()));
    ExpectIntEQ(X509_STORE_CTX_init(storeCtx, store, cert, NULL), SSL_SUCCESS);
    ExpectIntEQ(X509_verify_cert(storeCtx), SSL_SUCCESS);
    X509_STORE_free(store);
    store = NULL;
    X509_STORE_CTX_free(storeCtx);
    storeCtx = NULL;
    X509_free(cert);
    cert = NULL;
    X509_free(ca);
    ca = NULL;

#ifndef WOLFSSL_CRL_ALLOW_MISSING_CDP
    /* should fail to verify now after adding in CRL */
    ExpectNotNull(store = (X509_STORE *)X509_STORE_new());
    ExpectNotNull((ca = wolfSSL_X509_load_certificate_file(caCert,
                           SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_add_cert(store, ca), SSL_SUCCESS);
    ExpectTrue((fp = XFOPEN(crlPem, "rb")) != XBADFILE);
    ExpectNotNull(crl = (X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
                NULL, NULL));
    if (fp != XBADFILE)
        XFCLOSE(fp);
    ExpectIntEQ(X509_STORE_add_crl(store, crl), SSL_SUCCESS);
    ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK),SSL_SUCCESS);
    ExpectNotNull((storeCtx = X509_STORE_CTX_new()));
    ExpectNotNull((cert = wolfSSL_X509_load_certificate_file(srvCert,
                    SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_CTX_init(storeCtx, store, cert, NULL), SSL_SUCCESS);
    ExpectIntNE(X509_verify_cert(storeCtx), SSL_SUCCESS);
    ExpectIntEQ(X509_STORE_CTX_get_error(storeCtx),
                WOLFSSL_X509_V_ERR_CERT_REVOKED);
    X509_CRL_free(crl);
    crl = NULL;
    X509_STORE_free(store);
    store = NULL;
    X509_STORE_CTX_free(storeCtx);
    storeCtx = NULL;
    X509_free(cert);
    cert = NULL;
    X509_free(ca);
    ca = NULL;
#endif /* !WOLFSSL_CRL_ALLOW_MISSING_CDP */
#endif /* HAVE_CRL */



#ifndef WOLFCRYPT_ONLY
    {
    #if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
        SSL_CTX* ctx = NULL;
        SSL* ssl = NULL;
        int i;
        for (i = 0; i < 2; i++) {
        #ifndef NO_WOLFSSL_SERVER
            ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
        #else
            ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
        #endif
            ExpectNotNull(store = (X509_STORE *)X509_STORE_new());
            SSL_CTX_set_cert_store(ctx, store);
            ExpectNotNull(store = (X509_STORE *)X509_STORE_new());
            SSL_CTX_set_cert_store(ctx, store);
            ExpectNotNull(store = (X509_STORE *)X509_STORE_new());
            ExpectIntEQ(SSL_CTX_use_certificate_file(ctx, svrCertFile,
                    SSL_FILETYPE_PEM), SSL_SUCCESS);
            ExpectIntEQ(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
                    SSL_FILETYPE_PEM), SSL_SUCCESS);
            ExpectNotNull(ssl = SSL_new(ctx));
            if (i == 0) {
                ExpectIntEQ(SSL_set0_verify_cert_store(ssl, store),
                    SSL_SUCCESS);
            }
            else {
                ExpectIntEQ(SSL_set1_verify_cert_store(ssl, store), SSL_SUCCESS);
                #ifdef OPENSSL_ALL
                ExpectIntEQ(SSL_CTX_set1_verify_cert_store(ctx, store), SSL_SUCCESS);
                #endif
            }
            if (EXPECT_FAIL() || (i == 1)) {
                X509_STORE_free(store);
                store = NULL;
            }
            SSL_free(ssl);
            ssl = NULL;
            SSL_CTX_free(ctx);
            ctx = NULL;
        }
    #endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
    }
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_load_locations(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && \
    !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) && !defined(NO_RSA)
    SSL_CTX *ctx = NULL;
    X509_STORE *store = NULL;

    const char ca_file[] = "./certs/ca-cert.pem";
    const char client_pem_file[] = "./certs/client-cert.pem";
    const char client_der_file[] = "./certs/client-cert.der";
    const char ecc_file[] = "./certs/ecc-key.pem";
    const char certs_path[] = "./certs/";
    const char bad_path[] = "./bad-path/";
#ifdef HAVE_CRL
    const char crl_path[] = "./certs/crl/";
    const char crl_file[] = "./certs/crl/crl.pem";
#endif

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(SSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(SSLv23_client_method()));
#endif
    ExpectNotNull(store = SSL_CTX_get_cert_store(ctx));
    ExpectIntEQ(wolfSSL_CertManagerLoadCA(store->cm, ca_file, NULL),
        WOLFSSL_SUCCESS);

    /* Test bad arguments */
    ExpectIntEQ(X509_STORE_load_locations(NULL, ca_file, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_STORE_load_locations(store, NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_STORE_load_locations(store, client_der_file, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_STORE_load_locations(store, ecc_file, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_STORE_load_locations(store, NULL, bad_path),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

#ifdef HAVE_CRL
    /* Test with CRL */
    ExpectIntEQ(X509_STORE_load_locations(store, crl_file, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_STORE_load_locations(store, NULL, crl_path),
        WOLFSSL_SUCCESS);
#endif

    /* Test with CA */
    ExpectIntEQ(X509_STORE_load_locations(store, ca_file, NULL),
        WOLFSSL_SUCCESS);

    /* Test with client_cert and certs path */
    ExpectIntEQ(X509_STORE_load_locations(store, client_pem_file, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_STORE_load_locations(store, NULL, certs_path),
        WOLFSSL_SUCCESS);

#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
    /* Clear nodes */
    ERR_clear_error();
#endif

    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_X509_STORE_get0_objects(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \
    !defined(NO_WOLFSSL_DIR) && !defined(NO_RSA)
    X509_STORE *store = NULL;
    X509_STORE *store_cpy = NULL;
    SSL_CTX *ctx = NULL;
    X509_OBJECT *obj = NULL;
    STACK_OF(X509_OBJECT) *objs = NULL;
    int i;

    /* Setup store */
#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(SSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(SSLv23_client_method()));
#endif
    ExpectNotNull(store_cpy = X509_STORE_new());
    ExpectNotNull(store = SSL_CTX_get_cert_store(ctx));
    ExpectIntEQ(X509_STORE_load_locations(store, cliCertFile, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_STORE_load_locations(store, caCertFile, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_STORE_load_locations(store, svrCertFile, NULL),
        WOLFSSL_SUCCESS);
#ifdef HAVE_CRL
    ExpectIntEQ(X509_STORE_load_locations(store, NULL, crlPemDir),
        WOLFSSL_SUCCESS);
#endif
    /* Store ready */

    /* Similar to HaProxy ssl_set_cert_crl_file use case */
    ExpectNotNull(objs = X509_STORE_get0_objects(store));
#ifdef HAVE_CRL
#ifdef WOLFSSL_SIGNER_DER_CERT
    ExpectIntEQ(sk_X509_OBJECT_num(objs), 4);
#else
    ExpectIntEQ(sk_X509_OBJECT_num(objs), 1);
#endif
#else
#ifdef WOLFSSL_SIGNER_DER_CERT
    ExpectIntEQ(sk_X509_OBJECT_num(objs), 3);
#else
    ExpectIntEQ(sk_X509_OBJECT_num(objs), 0);
#endif
#endif
    for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
        obj = (X509_OBJECT*)sk_X509_OBJECT_value(objs, i);
        switch (X509_OBJECT_get_type(obj)) {
        case X509_LU_X509:
        {
            X509* x509 = NULL;
            X509_NAME *subj_name = NULL;
            ExpectNotNull(x509 = X509_OBJECT_get0_X509(obj));
            ExpectIntEQ(X509_STORE_add_cert(store_cpy, x509), WOLFSSL_SUCCESS);
            ExpectNotNull(subj_name = X509_get_subject_name(x509));
            ExpectPtrEq(obj, X509_OBJECT_retrieve_by_subject(objs, X509_LU_X509,
                    subj_name));
            break;
        }
        case X509_LU_CRL:
#ifdef HAVE_CRL
        {
            X509_CRL* crl = NULL;
            ExpectNotNull(crl = X509_OBJECT_get0_X509_CRL(obj));
            ExpectIntEQ(X509_STORE_add_crl(store_cpy, crl), WOLFSSL_SUCCESS);
            break;
        }
#endif
        case X509_LU_NONE:
        default:
            Fail(("X509_OBJECT_get_type should return x509 or crl "
                    "(when built with crl support)"),
                    ("Unrecognized X509_OBJECT type or none"));
        }
    }

    X509_STORE_free(store_cpy);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_CTX(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
    !defined(OPENSSL_EXTRA_NO_BN) && !defined(WOLFSSL_SP_MATH)
    WOLFSSL_BN_CTX* bn_ctx = NULL;
    WOLFSSL_BIGNUM* t = NULL;

    ExpectNotNull(bn_ctx = wolfSSL_BN_CTX_new());

    /* No implementation. */
    BN_CTX_init(NULL);

    ExpectNotNull(t = BN_CTX_get(NULL));
    BN_free(t);
    ExpectNotNull(t = BN_CTX_get(bn_ctx));
    BN_free(t);

#ifndef NO_WOLFSSL_STUB
    /* No implementation. */
    BN_CTX_start(NULL);
    BN_CTX_start(bn_ctx);
#endif

    BN_CTX_free(NULL);
    BN_CTX_free(bn_ctx);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_ASN) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
    !defined(OPENSSL_EXTRA_NO_BN) && !defined(WOLFSSL_SP_MATH)
    BIGNUM* a = NULL;
    BIGNUM* b = NULL;
    BIGNUM* c = NULL;
    BIGNUM* d = NULL;
    BIGNUM emptyBN;

    /* Setup */
    XMEMSET(&emptyBN, 0, sizeof(emptyBN));
    /* internal not set emptyBN. */

    ExpectNotNull(a = BN_new());
    ExpectNotNull(b = BN_new());
    ExpectNotNull(c = BN_dup(b));
    ExpectNotNull(d = BN_new());

    /* Invalid parameter testing. */
    BN_free(NULL);
    ExpectNull(BN_dup(NULL));
    ExpectNull(BN_dup(&emptyBN));

    ExpectNull(BN_copy(NULL, NULL));
    ExpectNull(BN_copy(b, NULL));
    ExpectNull(BN_copy(NULL, c));
    ExpectNull(BN_copy(b, &emptyBN));
    ExpectNull(BN_copy(&emptyBN, c));

    BN_clear(NULL);
    BN_clear(&emptyBN);

    ExpectIntEQ(BN_num_bytes(NULL), 0);
    ExpectIntEQ(BN_num_bytes(&emptyBN), 0);

    ExpectIntEQ(BN_num_bits(NULL), 0);
    ExpectIntEQ(BN_num_bits(&emptyBN), 0);

    ExpectIntEQ(BN_is_negative(NULL), 0);
    ExpectIntEQ(BN_is_negative(&emptyBN), 0);
    /* END Invalid Parameters */

    ExpectIntEQ(BN_set_word(a, 3), SSL_SUCCESS);
    ExpectIntEQ(BN_set_word(b, 2), SSL_SUCCESS);
    ExpectIntEQ(BN_set_word(c, 5), SSL_SUCCESS);

    ExpectIntEQ(BN_num_bits(a), 2);
    ExpectIntEQ(BN_num_bytes(a), 1);

#if !defined(WOLFSSL_SP_MATH) && (!defined(WOLFSSL_SP_MATH_ALL) || \
                                               defined(WOLFSSL_SP_INT_NEGATIVE))
    ExpectIntEQ(BN_set_word(a, 1), SSL_SUCCESS);
    ExpectIntEQ(BN_set_word(b, 5), SSL_SUCCESS);
    ExpectIntEQ(BN_is_word(a, (WOLFSSL_BN_ULONG)BN_get_word(a)), SSL_SUCCESS);
    ExpectIntEQ(BN_is_word(a, 3), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(BN_sub(c, a, b), SSL_SUCCESS);
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
    {
        /* Do additional tests on negative BN conversions. */
        char*         ret = NULL;
        ASN1_INTEGER* asn1 = NULL;
        BIGNUM*       tmp = NULL;

        /* Sanity check we have a negative BN. */
        ExpectIntEQ(BN_is_negative(c), 1);
        ExpectNotNull(ret = BN_bn2dec(c));
        ExpectIntEQ(XMEMCMP(ret, "-4", sizeof("-4")), 0);
        XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL);
        ret = NULL;

        /* Convert to ASN1_INTEGER and back to BN. */
        ExpectNotNull(asn1 = BN_to_ASN1_INTEGER(c, NULL));
        ExpectNotNull(tmp = ASN1_INTEGER_to_BN(asn1, NULL));

        /* After converting back BN should be negative and correct. */
        ExpectIntEQ(BN_is_negative(tmp), 1);
        ExpectNotNull(ret = BN_bn2dec(tmp));
        ExpectIntEQ(XMEMCMP(ret, "-4", sizeof("-4")), 0);
        XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL);
        ASN1_INTEGER_free(asn1);
        BN_free(tmp);
    }
#endif
    ExpectIntEQ(BN_get_word(c), 4);
#endif

    ExpectIntEQ(BN_set_word(a, 3), 1);
    ExpectIntEQ(BN_set_word(b, 3), 1);
    ExpectIntEQ(BN_set_word(c, 4), 1);

    /* NULL == NULL, NULL < num, num > NULL */
    ExpectIntEQ(BN_cmp(NULL, NULL), 0);
    ExpectIntEQ(BN_cmp(&emptyBN, &emptyBN), 0);
    ExpectIntLT(BN_cmp(NULL, b), 0);
    ExpectIntLT(BN_cmp(&emptyBN, b), 0);
    ExpectIntGT(BN_cmp(a, NULL), 0);
    ExpectIntGT(BN_cmp(a, &emptyBN), 0);

    ExpectIntEQ(BN_cmp(a, b), 0);
    ExpectIntLT(BN_cmp(a, c), 0);
    ExpectIntGT(BN_cmp(c, b), 0);

#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
    ExpectIntEQ(BN_print_fp(XBADFILE, NULL), 0);
    ExpectIntEQ(BN_print_fp(XBADFILE, &emptyBN), 0);
    ExpectIntEQ(BN_print_fp(stderr, NULL), 0);
    ExpectIntEQ(BN_print_fp(stderr, &emptyBN), 0);
    ExpectIntEQ(BN_print_fp(XBADFILE, a), 0);

    ExpectIntEQ(BN_print_fp(stderr, a), 1);
#endif

    BN_clear(a);

    BN_free(a);
    BN_free(b);
    BN_free(c);
    BN_clear_free(d);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_ASN) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_init(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
    !defined(OPENSSL_EXTRA_NO_BN) && !defined(WOLFSSL_SP_MATH)
#if !defined(USE_INTEGER_HEAP_MATH) && !defined(HAVE_WOLF_BIGINT)
    BIGNUM* ap = NULL;
    BIGNUM bv;
    BIGNUM cv;
    BIGNUM dv;

    ExpectNotNull(ap = BN_new());

    BN_init(NULL);
    XMEMSET(&bv, 0, sizeof(bv));
    ExpectNull(BN_dup(&bv));

    BN_init(&bv);
    BN_init(&cv);
    BN_init(&dv);

    ExpectIntEQ(BN_set_word(ap, 3), SSL_SUCCESS);
    ExpectIntEQ(BN_set_word(&bv, 2), SSL_SUCCESS);
    ExpectIntEQ(BN_set_word(&cv, 5), SSL_SUCCESS);

    /* a^b mod c = */
    ExpectIntEQ(BN_mod_exp(&dv, NULL, &bv, &cv, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(BN_mod_exp(&dv, ap, &bv, &cv, NULL), WOLFSSL_SUCCESS);

    /* check result  3^2 mod 5 */
    ExpectIntEQ(BN_get_word(&dv), 4);

    /* a*b mod c = */
    ExpectIntEQ(BN_mod_mul(&dv, NULL, &bv, &cv, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(BN_mod_mul(&dv, ap, &bv, &cv, NULL), SSL_SUCCESS);

    /* check result  3*2 mod 5 */
    ExpectIntEQ(BN_get_word(&dv), 1);

    BN_free(ap);
#endif
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_ASN) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_enc_dec(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && !defined(WOLFSSL_SP_MATH)
    BIGNUM* a = NULL;
    BIGNUM* b = NULL;
    BIGNUM* c = NULL;
    BIGNUM emptyBN;
    char* str = NULL;
    const char* emptyStr = "";
    const char* numberStr = "12345";
    const char* badStr = "g12345";
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
    const char* twoStr = "2";
#endif
    unsigned char binNum[] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
    unsigned char outNum[5];

    /* Setup */
    XMEMSET(&emptyBN, 0, sizeof(emptyBN));
    ExpectNotNull(a = BN_new());
    ExpectNotNull(b = BN_new());

    /* Invalid parameters */
    ExpectIntEQ(BN_bn2bin(NULL, NULL), -1);
    ExpectIntEQ(BN_bn2bin(&emptyBN, NULL), -1);
    ExpectIntEQ(BN_bn2bin(NULL, outNum), -1);
    ExpectIntEQ(BN_bn2bin(&emptyBN, outNum), -1);
    ExpectNull(BN_bn2hex(NULL));
    ExpectNull(BN_bn2hex(&emptyBN));
    ExpectNull(BN_bn2dec(NULL));
    ExpectNull(BN_bn2dec(&emptyBN));

    ExpectNotNull(c = BN_bin2bn(NULL, 0, NULL));
    BN_clear(c);
    BN_free(c);
    c = NULL;

    ExpectNotNull(BN_bin2bn(NULL, sizeof(binNum), a));
    BN_free(a);
    a = NULL;
    ExpectNotNull(a = BN_new());
    ExpectIntEQ(BN_set_word(a, 2), 1);
    ExpectNull(BN_bin2bn(binNum, -1, a));
    ExpectNull(BN_bin2bn(binNum, -1, NULL));
    ExpectNull(BN_bin2bn(binNum, sizeof(binNum), &emptyBN));

    ExpectIntEQ(BN_hex2bn(NULL, NULL), 0);
    ExpectIntEQ(BN_hex2bn(NULL, numberStr), 0);
    ExpectIntEQ(BN_hex2bn(&a, NULL), 0);
    ExpectIntEQ(BN_hex2bn(&a, emptyStr), 0);
    ExpectIntEQ(BN_hex2bn(&a, badStr), 0);
    ExpectIntEQ(BN_hex2bn(&c, badStr), 0);

    ExpectIntEQ(BN_dec2bn(NULL, NULL), 0);
    ExpectIntEQ(BN_dec2bn(NULL, numberStr), 0);
    ExpectIntEQ(BN_dec2bn(&a, NULL), 0);
    ExpectIntEQ(BN_dec2bn(&a, emptyStr), 0);
    ExpectIntEQ(BN_dec2bn(&a, badStr), 0);
    ExpectIntEQ(BN_dec2bn(&c, badStr), 0);

    ExpectIntEQ(BN_set_word(a, 2), 1);

    ExpectIntEQ(BN_bn2bin(a, NULL), 1);
    ExpectIntEQ(BN_bn2bin(a, outNum), 1);
    ExpectNotNull(BN_bin2bn(outNum, 1, b));
    ExpectIntEQ(BN_cmp(a, b), 0);
    ExpectNotNull(BN_bin2bn(binNum, sizeof(binNum), b));
    ExpectIntEQ(BN_cmp(a, b), -1);

    ExpectNotNull(str = BN_bn2hex(a));
    ExpectNotNull(BN_hex2bn(&b, str));
    ExpectIntEQ(BN_cmp(a, b), 0);
    ExpectNotNull(BN_hex2bn(&b, numberStr));
    ExpectIntEQ(BN_cmp(a, b), -1);
    XFREE(str, NULL, DYNAMIC_TYPE_OPENSSL);
    str = NULL;

#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
    ExpectNotNull(str = BN_bn2dec(a));
    ExpectStrEQ(str, twoStr);
    XFREE(str, NULL, DYNAMIC_TYPE_OPENSSL);
    str = NULL;

#ifndef NO_RSA
    ExpectNotNull(str = BN_bn2dec(a));
    ExpectNotNull(BN_dec2bn(&b, str));
    ExpectIntEQ(BN_cmp(a, b), 0);
    ExpectNotNull(BN_dec2bn(&b, numberStr));
    ExpectIntEQ(BN_cmp(a, b), -1);
    XFREE(str, NULL, DYNAMIC_TYPE_OPENSSL);
    str = NULL;
#else
    /* No implementation - fail with good parameters. */
    ExpectIntEQ(BN_dec2bn(&a, numberStr), 0);
#endif
#endif

    BN_free(b);
    BN_free(a);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_ASN) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_word(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && !defined(WOLFSSL_SP_MATH)
    BIGNUM* a = NULL;
    BIGNUM* b = NULL;
    BIGNUM* c = NULL;
    BIGNUM av;

    ExpectNotNull(a = BN_new());
    ExpectNotNull(b = BN_new());
    ExpectNotNull(c = BN_new());
    XMEMSET(&av, 0, sizeof(av));

    /* Invalid parameter. */
    ExpectIntEQ(BN_add_word(NULL, 3), 0);
    ExpectIntEQ(BN_add_word(&av, 3), 0);
    ExpectIntEQ(BN_sub_word(NULL, 3), 0);
    ExpectIntEQ(BN_sub_word(&av, 3), 0);
    ExpectIntEQ(BN_set_word(NULL, 3), 0);
    ExpectIntEQ(BN_set_word(&av, 3), 0);
    ExpectIntEQ(BN_get_word(NULL), 0);
    ExpectIntEQ(BN_get_word(&av), 0);
    ExpectIntEQ(BN_is_word(NULL, 3), 0);
    ExpectIntEQ(BN_is_word(&av, 3), 0);
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || \
    !defined(NO_DSA))
    ExpectIntEQ(BN_mod_word(NULL, 3), -1);
    ExpectIntEQ(BN_mod_word(&av, 3), -1);
#endif
    ExpectIntEQ(BN_one(NULL), 0);
    ExpectIntEQ(BN_one(&av), 0);
    BN_zero(NULL);
    BN_zero(&av);
    ExpectIntEQ(BN_is_one(NULL), 0);
    ExpectIntEQ(BN_is_one(&av), 0);
    ExpectIntEQ(BN_is_zero(NULL), 0);
    ExpectIntEQ(BN_is_zero(&av), 0);

    ExpectIntEQ(BN_set_word(a, 3), 1);
    ExpectIntEQ(BN_set_word(b, 2), 1);
    ExpectIntEQ(BN_set_word(c, 5), 1);

    /* a + 3 = */
    ExpectIntEQ(BN_add_word(a, 3), 1);

    /* check result 3 + 3*/
    ExpectIntEQ(BN_get_word(a), 6);
    ExpectIntEQ(BN_is_word(a, 6), 1);
    ExpectIntEQ(BN_is_word(a, 5), 0);

    /* set a back to 3 */
    ExpectIntEQ(BN_set_word(a, 3), 1);

    /* a - 3 = */
    ExpectIntEQ(BN_sub_word(a, 3), 1);

    /* check result 3 - 3*/
    ExpectIntEQ(BN_get_word(a), 0);

    ExpectIntEQ(BN_one(a), 1);
    ExpectIntEQ(BN_is_word(a, 1), 1);
    ExpectIntEQ(BN_is_word(a, 0), 0);
    ExpectIntEQ(BN_is_one(a), 1);
    ExpectIntEQ(BN_is_zero(a), 0);
    BN_zero(a);
    ExpectIntEQ(BN_is_word(a, 0), 1);
    ExpectIntEQ(BN_is_word(a, 1), 0);
    ExpectIntEQ(BN_is_zero(a), 1);
    ExpectIntEQ(BN_is_one(a), 0);

#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || \
    !defined(NO_DSA))
    ExpectIntEQ(BN_set_word(a, 5), 1);
    ExpectIntEQ(BN_mod_word(a, 3), 2);
    ExpectIntEQ(BN_mod_word(a, 0), -1);
#endif

    BN_free(c);
    BN_free(b);
    BN_free(a);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_ASN) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_bits(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
    !defined(OPENSSL_EXTRA_NO_BN) && !defined(WOLFSSL_SP_MATH)
    BIGNUM* a = NULL;
    BIGNUM emptyBN;

    /* Setup */
    XMEMSET(&emptyBN, 0, sizeof(emptyBN));
    ExpectNotNull(a = BN_new());

    /* Invalid parameters. */
    ExpectIntEQ(BN_set_bit(NULL, 1), 0);
    ExpectIntEQ(BN_set_bit(&emptyBN, 1), 0);
    ExpectIntEQ(BN_set_bit(a, -1), 0);
    ExpectIntEQ(BN_clear_bit(NULL, 1), 0);
    ExpectIntEQ(BN_clear_bit(&emptyBN, 1), 0);
    ExpectIntEQ(BN_clear_bit(a, -1), 0);
    ExpectIntEQ(BN_is_bit_set(NULL, 1), 0);
    ExpectIntEQ(BN_is_bit_set(&emptyBN, 1), 0);
    ExpectIntEQ(BN_is_bit_set(a, -1), 0);
    ExpectIntEQ(BN_is_odd(NULL), 0);
    ExpectIntEQ(BN_is_odd(&emptyBN), 0);

    ExpectIntEQ(BN_set_word(a, 0), 1);
    ExpectIntEQ(BN_is_zero(a), 1);
    ExpectIntEQ(BN_set_bit(a, 0x45), 1);
    ExpectIntEQ(BN_is_zero(a), 0);
    ExpectIntEQ(BN_is_bit_set(a, 0x45), 1);
    ExpectIntEQ(BN_clear_bit(a, 0x45), 1);
    ExpectIntEQ(BN_is_bit_set(a, 0x45), 0);
    ExpectIntEQ(BN_is_zero(a), 1);

    ExpectIntEQ(BN_set_bit(a, 0), 1);
    ExpectIntEQ(BN_is_odd(a), 1);
    ExpectIntEQ(BN_clear_bit(a, 0), 1);
    ExpectIntEQ(BN_is_odd(a), 0);
    ExpectIntEQ(BN_set_bit(a, 1), 1);
    ExpectIntEQ(BN_is_odd(a), 0);

    ExpectIntEQ(BN_set_bit(a, 129), 1);
    ExpectIntEQ(BN_get_word(a), WOLFSSL_BN_MAX_VAL);

#ifndef NO_WOLFSSL_STUB
    ExpectIntEQ(BN_mask_bits(a, 1), 0);
#endif

    BN_free(a);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_shift(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
    !defined(OPENSSL_EXTRA_NO_BN) && !defined(WOLFSSL_SP_MATH)
    BIGNUM* a = NULL;
    BIGNUM* b = NULL;
    BIGNUM emptyBN;

    /* Setup */
    XMEMSET(&emptyBN, 0, sizeof(emptyBN));
    ExpectNotNull(a = BN_new());
    ExpectNotNull(b = BN_new());

    /* Invalid parameters. */
    ExpectIntEQ(BN_lshift(NULL, NULL, 1), 0);
    ExpectIntEQ(BN_lshift(&emptyBN, NULL, 1), 0);
    ExpectIntEQ(BN_lshift(NULL, &emptyBN, 1), 0);
    ExpectIntEQ(BN_lshift(b, NULL, 1), 0);
    ExpectIntEQ(BN_lshift(b, &emptyBN, 1), 0);
    ExpectIntEQ(BN_lshift(NULL, a, 1), 0);
    ExpectIntEQ(BN_lshift(&emptyBN, a, 1), 0);
    ExpectIntEQ(BN_lshift(b, a, -1), 0);

    ExpectIntEQ(BN_rshift(NULL, NULL, 1), 0);
    ExpectIntEQ(BN_rshift(&emptyBN, NULL, 1), 0);
    ExpectIntEQ(BN_rshift(NULL, &emptyBN, 1), 0);
    ExpectIntEQ(BN_rshift(b, NULL, 1), 0);
    ExpectIntEQ(BN_rshift(b, &emptyBN, 1), 0);
    ExpectIntEQ(BN_rshift(NULL, a, 1), 0);
    ExpectIntEQ(BN_rshift(&emptyBN, a, 1), 0);
    ExpectIntEQ(BN_rshift(b, a, -1), 0);

    ExpectIntEQ(BN_set_word(a, 1), 1);
    ExpectIntEQ(BN_lshift(b, a, 1), 1);
    ExpectIntEQ(BN_is_word(b, 2), 1);
    ExpectIntEQ(BN_lshift(a, a, 1), 1);
    ExpectIntEQ(BN_is_word(a, 2), 1);
    ExpectIntEQ(BN_rshift(b, a, 1), 1);
    ExpectIntEQ(BN_is_word(b, 1), 1);
    ExpectIntEQ(BN_rshift(a, a, 1), 1);
    ExpectIntEQ(BN_is_word(a, 1), 1);

    BN_free(b);
    BN_free(a);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_math(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
    !defined(OPENSSL_EXTRA_NO_BN) && !defined(WOLFSSL_SP_MATH)
    BIGNUM* a = NULL;
    BIGNUM* b = NULL;
    BIGNUM* r = NULL;
    BIGNUM* rem = NULL;
    BIGNUM emptyBN;
    BN_ULONG val1;
    BN_ULONG val2;

    /* Setup */
    XMEMSET(&emptyBN, 0, sizeof(emptyBN));
    ExpectNotNull(a = BN_new());
    ExpectNotNull(b = BN_new());
    ExpectNotNull(r = BN_new());
    ExpectNotNull(rem = BN_new());

    /* Invalid parameters. */
    ExpectIntEQ(BN_add(NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_add(r, NULL, NULL), 0);
    ExpectIntEQ(BN_add(NULL, a, NULL), 0);
    ExpectIntEQ(BN_add(NULL, NULL, b), 0);
    ExpectIntEQ(BN_add(r, a, NULL), 0);
    ExpectIntEQ(BN_add(r, NULL, b), 0);
    ExpectIntEQ(BN_add(NULL, a, b), 0);

    ExpectIntEQ(BN_add(&emptyBN, &emptyBN, &emptyBN), 0);
    ExpectIntEQ(BN_add(r, &emptyBN, &emptyBN), 0);
    ExpectIntEQ(BN_add(&emptyBN, a, &emptyBN), 0);
    ExpectIntEQ(BN_add(&emptyBN, &emptyBN, b), 0);
    ExpectIntEQ(BN_add(r, a, &emptyBN), 0);
    ExpectIntEQ(BN_add(r, &emptyBN, b), 0);
    ExpectIntEQ(BN_add(&emptyBN, a, b), 0);

    ExpectIntEQ(BN_sub(NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_sub(r, NULL, NULL), 0);
    ExpectIntEQ(BN_sub(NULL, a, NULL), 0);
    ExpectIntEQ(BN_sub(NULL, NULL, b), 0);
    ExpectIntEQ(BN_sub(r, a, NULL), 0);
    ExpectIntEQ(BN_sub(r, NULL, b), 0);
    ExpectIntEQ(BN_sub(NULL, a, b), 0);

    ExpectIntEQ(BN_sub(&emptyBN, &emptyBN, &emptyBN), 0);
    ExpectIntEQ(BN_sub(r, &emptyBN, &emptyBN), 0);
    ExpectIntEQ(BN_sub(&emptyBN, a, &emptyBN), 0);
    ExpectIntEQ(BN_sub(&emptyBN, &emptyBN, b), 0);
    ExpectIntEQ(BN_sub(r, a, &emptyBN), 0);
    ExpectIntEQ(BN_sub(r, &emptyBN, b), 0);
    ExpectIntEQ(BN_sub(&emptyBN, a, b), 0);

    ExpectIntEQ(BN_mul(NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mul(r, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mul(NULL, a, NULL, NULL), 0);
    ExpectIntEQ(BN_mul(NULL, NULL, b, NULL), 0);
    ExpectIntEQ(BN_mul(r, a, NULL, NULL), 0);
    ExpectIntEQ(BN_mul(r, NULL, b, NULL), 0);
    ExpectIntEQ(BN_mul(NULL, a, b, NULL), 0);

    ExpectIntEQ(BN_mul(&emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mul(r, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mul(&emptyBN, a, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mul(&emptyBN, &emptyBN, b, NULL), 0);
    ExpectIntEQ(BN_mul(r, a, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mul(r, &emptyBN, b, NULL), 0);
    ExpectIntEQ(BN_mul(&emptyBN, a, b, NULL), 0);

    ExpectIntEQ(BN_div(NULL, NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_div(r, NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_div(NULL, rem, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_div(NULL, NULL, a, NULL, NULL), 0);
    ExpectIntEQ(BN_div(NULL, NULL, NULL, b, NULL), 0);
    ExpectIntEQ(BN_div(NULL, rem, a, b, NULL), 0);
    ExpectIntEQ(BN_div(r, NULL, a, b, NULL), 0);
    ExpectIntEQ(BN_div(r, rem, NULL, b, NULL), 0);
    ExpectIntEQ(BN_div(r, rem, a, NULL, NULL), 0);

    ExpectIntEQ(BN_div(&emptyBN, &emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_div(r, &emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_div(&emptyBN, rem, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_div(&emptyBN, &emptyBN, a, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_div(&emptyBN, &emptyBN, &emptyBN, b, NULL), 0);
    ExpectIntEQ(BN_div(&emptyBN, rem, a, b, NULL), 0);
    ExpectIntEQ(BN_div(r, &emptyBN, a, b, NULL), 0);
    ExpectIntEQ(BN_div(r, rem, &emptyBN, b, NULL), 0);
    ExpectIntEQ(BN_div(r, rem, a, &emptyBN, NULL), 0);

    ExpectIntEQ(BN_mod(NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod(r, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod(NULL, a, NULL, NULL), 0);
    ExpectIntEQ(BN_mod(NULL, NULL, b, NULL), 0);
    ExpectIntEQ(BN_mod(r, a, NULL, NULL), 0);
    ExpectIntEQ(BN_mod(r, NULL, b, NULL), 0);
    ExpectIntEQ(BN_mod(NULL, a, b, NULL), 0);

    ExpectIntEQ(BN_mod(&emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod(r, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod(&emptyBN, a, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod(&emptyBN, &emptyBN, b, NULL), 0);
    ExpectIntEQ(BN_mod(r, a, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod(r, &emptyBN, b, NULL), 0);
    ExpectIntEQ(BN_mod(&emptyBN, a, b, NULL), 0);
    /* END Invalid parameters. */

    val1 = 8;
    val2 = 3;
    ExpectIntEQ(BN_set_word(a, val1), 1);
    ExpectIntEQ(BN_set_word(b, val2), 1);
    ExpectIntEQ(BN_add(r, a, b), 1);
    ExpectIntEQ(BN_is_word(r, val1 + val2), 1);
    ExpectIntEQ(BN_sub(r, a, b), 1);
    ExpectIntEQ(BN_is_word(r, val1 - val2), 1);
    ExpectIntEQ(BN_mul(r, a, b, NULL), 1);
    ExpectIntEQ(BN_is_word(r, val1 * val2), 1);
    ExpectIntEQ(BN_div(r, rem, a, b, NULL), 1);
    ExpectIntEQ(BN_is_word(r, val1 / val2), 1);
    ExpectIntEQ(BN_is_word(rem, val1 % val2), 1);
    ExpectIntEQ(BN_mod(r, a, b, NULL), 1);
    ExpectIntEQ(BN_is_word(r, val1 % val2), 1);

    BN_free(rem);
    BN_free(r);
    BN_free(b);
    BN_free(a);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_math_mod(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
    !defined(OPENSSL_EXTRA_NO_BN) && !defined(WOLFSSL_SP_MATH)
    BIGNUM* a = NULL;
    BIGNUM* b = NULL;
    BIGNUM* m = NULL;
    BIGNUM* r = NULL;
    BIGNUM* t = NULL;
    BIGNUM emptyBN;
    BN_ULONG val1;
    BN_ULONG val2;
    BN_ULONG val3;

    /* Setup */
    XMEMSET(&emptyBN, 0, sizeof(emptyBN));
    ExpectNotNull(a = BN_new());
    ExpectNotNull(b = BN_new());
    ExpectNotNull(m = BN_new());
    ExpectNotNull(r = BN_new());

    /* Invalid parameters. */
    ExpectIntEQ(BN_mod_add(NULL, NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_add(r, NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_add(NULL, a, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_add(NULL, NULL, b, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_add(NULL, NULL, NULL, m, NULL), 0);
    ExpectIntEQ(BN_mod_add(NULL, a, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_add(r, NULL, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_add(r, a, NULL, m, NULL), 0);
    ExpectIntEQ(BN_mod_add(r, a, m, NULL, NULL), 0);

    ExpectIntEQ(BN_mod_add(&emptyBN, &emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_add(r, &emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_add(&emptyBN, a, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_add(&emptyBN, &emptyBN, b, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_add(&emptyBN, &emptyBN, &emptyBN, m, NULL), 0);
    ExpectIntEQ(BN_mod_add(&emptyBN, a, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_add(r, &emptyBN, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_add(r, a, &emptyBN, m, NULL), 0);
    ExpectIntEQ(BN_mod_add(r, a, m, &emptyBN, NULL), 0);

    ExpectIntEQ(BN_mod_mul(NULL, NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_mul(r, NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_mul(NULL, a, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_mul(NULL, NULL, b, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_mul(NULL, NULL, NULL, m, NULL), 0);
    ExpectIntEQ(BN_mod_mul(NULL, a, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_mul(r, NULL, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_mul(r, a, NULL, m, NULL), 0);
    ExpectIntEQ(BN_mod_mul(r, a, m, NULL, NULL), 0);

    ExpectIntEQ(BN_mod_mul(&emptyBN, &emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_mul(r, &emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_mul(&emptyBN, a, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_mul(&emptyBN, &emptyBN, b, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_mul(&emptyBN, &emptyBN, &emptyBN, m, NULL), 0);
    ExpectIntEQ(BN_mod_mul(&emptyBN, a, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_mul(r, &emptyBN, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_mul(r, a, &emptyBN, m, NULL), 0);
    ExpectIntEQ(BN_mod_mul(r, a, m, &emptyBN, NULL), 0);

    ExpectIntEQ(BN_mod_exp(NULL, NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_exp(r, NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_exp(NULL, a, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_exp(NULL, NULL, b, NULL, NULL), 0);
    ExpectIntEQ(BN_mod_exp(NULL, NULL, NULL, m, NULL), 0);
    ExpectIntEQ(BN_mod_exp(NULL, a, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_exp(r, NULL, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_exp(r, a, NULL, m, NULL), 0);
    ExpectIntEQ(BN_mod_exp(r, a, m, NULL, NULL), 0);

    ExpectIntEQ(BN_mod_exp(&emptyBN, &emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_exp(r, &emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_exp(&emptyBN, a, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_exp(&emptyBN, &emptyBN, b, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_mod_exp(&emptyBN, &emptyBN, &emptyBN, m, NULL), 0);
    ExpectIntEQ(BN_mod_exp(&emptyBN, a, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_exp(r, &emptyBN, b, m, NULL), 0);
    ExpectIntEQ(BN_mod_exp(r, a, &emptyBN, m, NULL), 0);
    ExpectIntEQ(BN_mod_exp(r, a, m, &emptyBN, NULL), 0);

    ExpectNull(BN_mod_inverse(r, NULL, NULL, NULL));
    ExpectNull(BN_mod_inverse(r, a, NULL, NULL));
    ExpectNull(BN_mod_inverse(r, NULL, m, NULL));
    ExpectNull(BN_mod_inverse(r, NULL, m, NULL));
    ExpectNull(BN_mod_inverse(r, a, NULL, NULL));

    ExpectNull(BN_mod_inverse(&emptyBN, &emptyBN, &emptyBN, NULL));
    ExpectNull(BN_mod_inverse(r, &emptyBN, &emptyBN, NULL));
    ExpectNull(BN_mod_inverse(&emptyBN, a, &emptyBN, NULL));
    ExpectNull(BN_mod_inverse(&emptyBN, &emptyBN, m, NULL));
    ExpectNull(BN_mod_inverse(&emptyBN, a, m, NULL));
    ExpectNull(BN_mod_inverse(r, &emptyBN, m, NULL));
    ExpectNull(BN_mod_inverse(r, a, &emptyBN, NULL));
    /* END Invalid parameters. */

    val1 = 9;
    val2 = 13;
    val3 = 5;
    ExpectIntEQ(BN_set_word(a, val1), 1);
    ExpectIntEQ(BN_set_word(b, val2), 1);
    ExpectIntEQ(BN_set_word(m, val3), 1);
    ExpectIntEQ(BN_mod_add(r, a, b, m, NULL), 1);
    ExpectIntEQ(BN_is_word(r, (val1 + val2) % val3), 1);
    ExpectIntEQ(BN_mod_mul(r, a, b, m, NULL), 1);
    ExpectIntEQ(BN_is_word(r, (val1 * val2) % val3), 1);

    ExpectIntEQ(BN_set_word(a, 2), 1);
    ExpectIntEQ(BN_set_word(b, 3), 1);
    ExpectIntEQ(BN_set_word(m, 5), 1);
    /* (2 ^ 3) % 5 = 8 % 5 = 3 */
    ExpectIntEQ(BN_mod_exp(r, a, b, m, NULL), 1);
    ExpectIntEQ(BN_is_word(r, 3), 1);

    /* (2 * 3) % 5 = 6 % 5 = 1 => inv = 3 */
    ExpectNotNull(BN_mod_inverse(r, a, m, NULL));
    ExpectIntEQ(BN_is_word(r, 3), 1);
    ExpectNotNull(t = BN_mod_inverse(NULL, a, m, NULL));
    ExpectIntEQ(BN_is_word(t, 3), 1);
    BN_free(t);
    /* No inverse case. No inverse when a divides b. */
    ExpectIntEQ(BN_set_word(a, 3), 1);
    ExpectIntEQ(BN_set_word(m, 9), 1);
    ExpectNull(BN_mod_inverse(r, a, m, NULL));

    BN_free(r);
    BN_free(m);
    BN_free(b);
    BN_free(a);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_math_other(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
    !defined(OPENSSL_EXTRA_NO_BN) && !defined(WOLFSSL_SP_MATH)
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    BIGNUM* a = NULL;
    BIGNUM* b = NULL;
    BIGNUM* r = NULL;
    BIGNUM emptyBN;

    /* Setup */
    XMEMSET(&emptyBN, 0, sizeof(emptyBN));
    ExpectNotNull(a = BN_new());
    ExpectNotNull(b = BN_new());
    ExpectNotNull(r = BN_new());

    /* Invalid parameters. */
    ExpectIntEQ(BN_gcd(NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_gcd(r, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_gcd(NULL, a, NULL, NULL), 0);
    ExpectIntEQ(BN_gcd(NULL, NULL, b, NULL), 0);
    ExpectIntEQ(BN_gcd(NULL, a, b, NULL), 0);
    ExpectIntEQ(BN_gcd(r, NULL, b, NULL), 0);
    ExpectIntEQ(BN_gcd(r, a, NULL, NULL), 0);

    ExpectIntEQ(BN_gcd(&emptyBN, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_gcd(r, &emptyBN, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_gcd(&emptyBN, a, &emptyBN, NULL), 0);
    ExpectIntEQ(BN_gcd(&emptyBN, &emptyBN, b, NULL), 0);
    ExpectIntEQ(BN_gcd(&emptyBN, a, b, NULL), 0);
    ExpectIntEQ(BN_gcd(r, &emptyBN, b, NULL), 0);
    ExpectIntEQ(BN_gcd(r, a, &emptyBN, NULL), 0);
    /* END Invalid parameters. */

    /* No common factors between 2 and 3. */
    ExpectIntEQ(BN_set_word(a, 2), 1);
    ExpectIntEQ(BN_set_word(b, 3), 1);
    ExpectIntEQ(BN_gcd(r, a, b, NULL), 1);
    ExpectIntEQ(BN_is_word(r, 1), 1);
    /* 3 is largest value that divides both 6 and 9. */
    ExpectIntEQ(BN_set_word(a, 6), 1);
    ExpectIntEQ(BN_set_word(b, 9), 1);
    ExpectIntEQ(BN_gcd(r, a, b, NULL), 1);
    ExpectIntEQ(BN_is_word(r, 3), 1);
    /* GCD of 0 and 0 is undefined. */
    ExpectIntEQ(BN_set_word(a, 0), 1);
    ExpectIntEQ(BN_set_word(b, 0), 1);
    ExpectIntEQ(BN_gcd(r, a, b, NULL), 0);

    /* Teardown */
    BN_free(r);
    BN_free(b);
    BN_free(a);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_rand(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(OPENSSL_EXTRA_NO_BN)
    BIGNUM* bn = NULL;
    BIGNUM* range = NULL;
    BIGNUM emptyBN;

    XMEMSET(&emptyBN, 0, sizeof(emptyBN));
    ExpectNotNull(bn = BN_new());
    ExpectNotNull(range = BN_new());

    /* Invalid parameters. */
    ExpectIntEQ(BN_rand(NULL, -1, 0, 0), 0);
    ExpectIntEQ(BN_rand(bn, -1, 0, 0), 0);
    ExpectIntEQ(BN_rand(NULL, 1, 0, 0), 0);
    ExpectIntEQ(BN_rand(&emptyBN, -1, 0, 0), 0);
    ExpectIntEQ(BN_rand(bn, -1, 0, 0), 0);
    ExpectIntEQ(BN_rand(&emptyBN, 1, 0, 0), 0);

    ExpectIntEQ(BN_pseudo_rand(NULL, -1, 0, 0), 0);
    ExpectIntEQ(BN_pseudo_rand(bn, -1, 0, 0), 0);
    ExpectIntEQ(BN_pseudo_rand(NULL, 1, 0, 0), 0);
    ExpectIntEQ(BN_pseudo_rand(&emptyBN, -1, 0, 0), 0);
    ExpectIntEQ(BN_pseudo_rand(bn, -1, 0, 0), 0);
    ExpectIntEQ(BN_pseudo_rand(&emptyBN, 1, 0, 0), 0);

    ExpectIntEQ(BN_rand_range(NULL, NULL), 0);
    ExpectIntEQ(BN_rand_range(bn, NULL), 0);
    ExpectIntEQ(BN_rand_range(NULL, range), 0);
    ExpectIntEQ(BN_rand_range(&emptyBN, &emptyBN), 0);
    ExpectIntEQ(BN_rand_range(bn, &emptyBN), 0);
    ExpectIntEQ(BN_rand_range(&emptyBN, range), 0);

    /* 0 bit random value must be 0 and so cannot set bit in any position. */
    ExpectIntEQ(BN_rand(bn, 0, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 0);
    ExpectIntEQ(BN_rand(bn, 0, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 0);
    ExpectIntEQ(BN_rand(bn, 0, WOLFSSL_BN_RAND_TOP_ANY,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 0);
    ExpectIntEQ(BN_rand(bn, 0, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 0);
    ExpectIntEQ(BN_rand(bn, 0, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 0);
    ExpectIntEQ(BN_pseudo_rand(bn, 0, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 0);
    ExpectIntEQ(BN_pseudo_rand(bn, 0, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 0);
    ExpectIntEQ(BN_pseudo_rand(bn, 0, WOLFSSL_BN_RAND_TOP_ANY,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 0);
    ExpectIntEQ(BN_pseudo_rand(bn, 0, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 0);
    ExpectIntEQ(BN_pseudo_rand(bn, 0, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 0);

    /* 1 bit random value must have no more than one top bit set. */
    ExpectIntEQ(BN_rand(bn, 1, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 0);
    ExpectIntEQ(BN_rand(bn, 1, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 0);
    ExpectIntEQ(BN_pseudo_rand(bn, 1, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 0);
    ExpectIntEQ(BN_pseudo_rand(bn, 1, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 0);
    /* END Invalid parameters. */

    /* 0 bit random: 0. */
    ExpectIntEQ(BN_rand(bn, 0, WOLFSSL_BN_RAND_TOP_ANY,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_is_zero(bn), 1);

    ExpectIntEQ(BN_set_word(bn, 2), 1); /* Make sure not zero. */
    ExpectIntEQ(BN_pseudo_rand(bn, 0, WOLFSSL_BN_RAND_TOP_ANY,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_is_zero(bn), 1);

    /* 1 bit random: 0 or 1. */
    ExpectIntEQ(BN_rand(bn, 1, WOLFSSL_BN_RAND_TOP_ANY,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntLT(BN_get_word(bn), 2); /* Make sure valid range. */
    ExpectIntEQ(BN_rand(bn, 1, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_get_word(bn), 1);
    ExpectIntEQ(BN_rand(bn, 1, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 1);
    ExpectIntEQ(BN_get_word(bn), 1);

    ExpectIntEQ(BN_pseudo_rand(bn, 1, WOLFSSL_BN_RAND_TOP_ANY,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntLT(BN_get_word(bn), 2); /* Make sure valid range. */
    ExpectIntEQ(BN_pseudo_rand(bn, 1, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_get_word(bn), 1);
    ExpectIntEQ(BN_pseudo_rand(bn, 1, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 1);
    ExpectIntEQ(BN_get_word(bn), 1);

    ExpectIntEQ(BN_rand(bn, 8, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_num_bits(bn), 8);
    ExpectIntEQ(BN_is_bit_set(bn, 7), 1);
    ExpectIntEQ(BN_pseudo_rand(bn, 8, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_num_bits(bn), 8);
    ExpectIntEQ(BN_is_bit_set(bn, 7), 1);

    ExpectIntEQ(BN_rand(bn, 8, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_is_bit_set(bn, 7), 1);
    ExpectIntEQ(BN_is_bit_set(bn, 6), 1);
    ExpectIntEQ(BN_pseudo_rand(bn, 8, WOLFSSL_BN_RAND_TOP_TWO,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_is_bit_set(bn, 7), 1);
    ExpectIntEQ(BN_is_bit_set(bn, 6), 1);

    ExpectIntEQ(BN_rand(bn, 8, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 1);
    ExpectIntEQ(BN_is_bit_set(bn, 0), 1);
    ExpectIntEQ(BN_pseudo_rand(bn, 8, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ODD), 1);
    ExpectIntEQ(BN_is_bit_set(bn, 0), 1);

    /* Regression test: Older versions of wolfSSL_BN_rand would round the
     * requested number of bits up to the nearest multiple of 8. E.g. in this
     * case, requesting a 13-bit random number would actually return a 16-bit
     * random number. */
    ExpectIntEQ(BN_rand(bn, 13, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_num_bits(bn), 13);

    ExpectIntEQ(BN_rand(range, 64, WOLFSSL_BN_RAND_TOP_ONE,
        WOLFSSL_BN_RAND_BOTTOM_ANY), 1);
    ExpectIntEQ(BN_rand_range(bn, range), 1);

    ExpectIntEQ(BN_set_word(range, 0), 1);
    ExpectIntEQ(BN_rand_range(bn, range), 1);
    ExpectIntEQ(BN_set_word(range, 1), 1);
    ExpectIntEQ(BN_rand_range(bn, range), 1);

    BN_free(bn);
    BN_free(range);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BN_prime(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
    !defined(OPENSSL_EXTRA_NO_BN) && !defined(WOLFSSL_SP_MATH)
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || !defined(NO_DSA))
    BIGNUM* a = NULL;
    BIGNUM* add = NULL;
    BIGNUM* rem = NULL;
    BIGNUM emptyBN;

    XMEMSET(&emptyBN, 0, sizeof(emptyBN));
    ExpectNotNull(a = BN_new());
    ExpectNotNull(add = BN_new());
    ExpectNotNull(rem = BN_new());

    /* Invalid parameters. */
    /* BN_generate_prime_ex()
     * prime - must have valid BIGNUM
     * bits  - Greater then 0
     * safe  - not supported, must be 0
     * add   - not supported, must be NULL
     * rem   - not supported, must be NULL
     * cb    - anything
     */
    ExpectIntEQ(BN_generate_prime_ex(NULL, -1, 1, add, rem, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(&emptyBN, -1, 1, add, rem, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(a, -1, 1, add, rem, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(NULL, 2, 1, add, rem, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(&emptyBN, 2, 1, add, rem, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(NULL, -1, 0, add, rem, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(&emptyBN, -1, 0, add, rem, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(NULL, -1, 1, NULL, rem, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(&emptyBN, -1, 1, NULL, rem, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(NULL, -1, 1, add, NULL, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(&emptyBN, -1, 1, add, NULL, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(NULL, 2, 0, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(&emptyBN, 2, 0, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(a, -1, 0, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(a, 0, 0, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(a, 2, 1, NULL, NULL, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(a, 2, 0, add, NULL, NULL), 0);
    ExpectIntEQ(BN_generate_prime_ex(a, 2, 0, NULL, rem, NULL), 0);

    ExpectIntEQ(BN_is_prime_ex(NULL, -1, NULL, NULL), -1);
    ExpectIntEQ(BN_is_prime_ex(&emptyBN, -1, NULL, NULL), -1);
    ExpectIntEQ(BN_is_prime_ex(a, -1, NULL, NULL), -1);
    ExpectIntEQ(BN_is_prime_ex(a, 2048, NULL, NULL), -1);
    ExpectIntEQ(BN_is_prime_ex(NULL, 1, NULL, NULL), -1);
    ExpectIntEQ(BN_is_prime_ex(&emptyBN, 1, NULL, NULL), -1);
    /* END Invalid parameters. */

    ExpectIntEQ(BN_generate_prime_ex(a, 512, 0, NULL, NULL, NULL), 1);
    ExpectIntEQ(BN_is_prime_ex(a, 8, NULL, NULL), 1);

    ExpectIntEQ(BN_clear_bit(a, 0), 1);
    ExpectIntEQ(BN_is_prime_ex(a, 8, NULL, NULL), 0);

    BN_free(rem);
    BN_free(add);
    BN_free(a);
#endif
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_ASN) */
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA)
#define TEST_ARG 0x1234
static void msg_cb(int write_p, int version, int content_type,
                   const void *buf, size_t len, SSL *ssl, void *arg)
{
    (void)write_p;
    (void)version;
    (void)content_type;
    (void)buf;
    (void)len;
    (void)ssl;

    AssertTrue(arg == (void*)TEST_ARG);
}
#endif

#if defined(OPENSSL_EXTRA) && defined(DEBUG_WOLFSSL) && \
      defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
#if defined(SESSION_CERTS)
#include "wolfssl/internal.h"
#endif
static int msgCb(SSL_CTX *ctx, SSL *ssl)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(SESSION_CERTS) && !defined(NO_BIO)
    STACK_OF(X509)* sk = NULL;
    X509* x509 = NULL;
    int i, num;
    BIO* bio = NULL;
#endif

    ExpectNotNull(ctx);
    ExpectNotNull(ssl);

    fprintf(stderr, "\n===== msgcb called ====\n");
#if defined(SESSION_CERTS) && defined(TEST_PEER_CERT_CHAIN)
    ExpectTrue(SSL_get_peer_cert_chain(ssl) != NULL);
    ExpectIntEQ(((WOLFSSL_X509_CHAIN *)SSL_get_peer_cert_chain(ssl))->count, 2);
    ExpectNotNull(SSL_get0_verified_chain(ssl));
#endif

#if defined(OPENSSL_ALL) && defined(SESSION_CERTS) && !defined(NO_BIO)
    ExpectNotNull(bio = BIO_new_fp(stderr, BIO_NOCLOSE));
    ExpectNotNull(sk = SSL_get_peer_cert_chain(ssl));
    if (sk == NULL) {
        BIO_free(bio);
        return TEST_FAIL;
    }
    num = sk_X509_num(sk);
    ExpectTrue(num > 0);
    for (i = 0; i < num; i++) {
        ExpectNotNull(x509 = sk_X509_value(sk,i));
        if (x509 == NULL)
            break;
        fprintf(stderr, "Certificate at index [%d] = :\n",i);
        X509_print(bio,x509);
        fprintf(stderr, "\n\n");
    }
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_msgCb(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(DEBUG_WOLFSSL) && \
      defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    test_ssl_cbf client_cb;
    test_ssl_cbf server_cb;

    XMEMSET(&client_cb, 0, sizeof(client_cb));
    XMEMSET(&server_cb, 0, sizeof(server_cb));
#ifndef WOLFSSL_NO_TLS12
    client_cb.method  = wolfTLSv1_2_client_method;
    server_cb.method  = wolfTLSv1_2_server_method;
#else
    client_cb.method  = wolfTLSv1_3_client_method;
    server_cb.method  = wolfTLSv1_3_server_method;
#endif

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
        &server_cb, msgCb), TEST_SUCCESS);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_either_side(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)) && \
    defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    test_ssl_cbf client_cb;
    test_ssl_cbf server_cb;

    XMEMSET(&client_cb, 0, sizeof(client_cb));
    XMEMSET(&server_cb, 0, sizeof(server_cb));

    /* Use different CTX for client and server */
    client_cb.ctx = wolfSSL_CTX_new(wolfSSLv23_method());
    ExpectNotNull(client_cb.ctx);
    server_cb.ctx = wolfSSL_CTX_new(wolfSSLv23_method());
    ExpectNotNull(server_cb.ctx);
    /* we are responsible for free'ing WOLFSSL_CTX */
    server_cb.isSharedCtx = client_cb.isSharedCtx = 1;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
        &server_cb, NULL), TEST_SUCCESS);

    wolfSSL_CTX_free(client_cb.ctx);
    wolfSSL_CTX_free(server_cb.ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DTLS_either_side(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)) && \
    defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS)
    test_ssl_cbf client_cb;
    test_ssl_cbf server_cb;

    XMEMSET(&client_cb, 0, sizeof(client_cb));
    XMEMSET(&server_cb, 0, sizeof(server_cb));

    /* Use different CTX for client and server */
    client_cb.ctx = wolfSSL_CTX_new(wolfDTLS_method());
    ExpectNotNull(client_cb.ctx);
    server_cb.ctx = wolfSSL_CTX_new(wolfDTLS_method());
    ExpectNotNull(server_cb.ctx);
    /* we are responsible for free'ing WOLFSSL_CTX */
    server_cb.isSharedCtx = client_cb.isSharedCtx = 1;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
        &server_cb, NULL), TEST_SUCCESS);

    wolfSSL_CTX_free(client_cb.ctx);
    wolfSSL_CTX_free(server_cb.ctx);
#endif
    return EXPECT_RESULT();
}

static int test_generate_cookie(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(OPENSSL_EXTRA) && defined(USE_WOLFSSL_IO)
    SSL_CTX* ctx = NULL;
    SSL* ssl = NULL;
    byte    buf[FOURK_BUF] = {0};

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLS_method()));
    ExpectNotNull(ssl = SSL_new(ctx));

    /* Test unconnected */
    ExpectIntEQ(EmbedGenerateCookie(ssl, buf, FOURK_BUF, NULL), WC_NO_ERR_TRACE(GEN_COOKIE_E));

    wolfSSL_CTX_SetGenCookie(ctx, EmbedGenerateCookie);

    wolfSSL_SetCookieCtx(ssl, ctx);

    ExpectNotNull(wolfSSL_GetCookieCtx(ssl));

    ExpectNull(wolfSSL_GetCookieCtx(NULL));

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_set_options(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    WOLFSSL*     ssl = NULL;
    WOLFSSL_CTX* ctx = NULL;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    char appData[] = "extra msg";
#endif
#ifdef OPENSSL_EXTRA
    unsigned char protos[] = {
        7, 't', 'l', 's', '/', '1', '.', '2',
        8, 'h', 't', 't', 'p', '/', '1', '.', '1'
    };
    unsigned int len = sizeof(protos);
    void *arg = (void *)TEST_ARG;
#endif

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
                                                WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
                                               WOLFSSL_FILETYPE_PEM));

    ExpectTrue(wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1)
               == WOLFSSL_OP_NO_TLSv1);
    ExpectTrue(wolfSSL_CTX_get_options(ctx) == WOLFSSL_OP_NO_TLSv1);

    ExpectIntGT((int)wolfSSL_CTX_set_options(ctx, (WOLFSSL_OP_COOKIE_EXCHANGE |
                WOLFSSL_OP_NO_SSLv2)), 0);
    ExpectTrue((wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_COOKIE_EXCHANGE) &
                WOLFSSL_OP_COOKIE_EXCHANGE) == WOLFSSL_OP_COOKIE_EXCHANGE);
    ExpectTrue((wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2) &
                WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2);
    ExpectTrue((wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_COMPRESSION) &
                WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION);
    ExpectFalse((wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_NO_COMPRESSION) &
                                           WOLFSSL_OP_NO_COMPRESSION));

    wolfSSL_CTX_free(ctx);
    ctx = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
                                               WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
                                               WOLFSSL_FILETYPE_PEM));
#ifdef OPENSSL_EXTRA
    ExpectTrue(wolfSSL_CTX_set_msg_callback(ctx, msg_cb) == WOLFSSL_SUCCESS);
#endif

    ExpectNotNull(ssl = wolfSSL_new(ctx));
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
#ifdef HAVE_EX_DATA
    ExpectIntEQ(wolfSSL_set_app_data(ssl, (void*)appData), WOLFSSL_SUCCESS);
    ExpectNotNull(wolfSSL_get_app_data((const WOLFSSL*)ssl));
    if (ssl != NULL) {
        ExpectIntEQ(XMEMCMP(wolfSSL_get_app_data((const WOLFSSL*)ssl),
                    appData, sizeof(appData)), 0);
    }
#else
    ExpectIntEQ(wolfSSL_set_app_data(ssl, (void*)appData), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectNull(wolfSSL_get_app_data((const WOLFSSL*)ssl));
#endif
#endif

    ExpectTrue(wolfSSL_set_options(ssl, WOLFSSL_OP_NO_TLSv1) ==
                                   WOLFSSL_OP_NO_TLSv1);

    ExpectTrue(wolfSSL_get_options(ssl) == WOLFSSL_OP_NO_TLSv1);

    ExpectIntGT((int)wolfSSL_set_options(ssl, (WOLFSSL_OP_COOKIE_EXCHANGE |
                                         WOLFSSL_OP_NO_SSLv2)), 0);

    ExpectTrue((wolfSSL_set_options(ssl, WOLFSSL_OP_COOKIE_EXCHANGE) &
                WOLFSSL_OP_COOKIE_EXCHANGE) == WOLFSSL_OP_COOKIE_EXCHANGE);

    ExpectTrue((wolfSSL_set_options(ssl, WOLFSSL_OP_NO_TLSv1_2) &
                WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2);

    ExpectTrue((wolfSSL_set_options(ssl, WOLFSSL_OP_NO_COMPRESSION) &
               WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION);

#ifdef OPENSSL_EXTRA
    ExpectFalse((wolfSSL_clear_options(ssl, WOLFSSL_OP_NO_COMPRESSION) &
                                       WOLFSSL_OP_NO_COMPRESSION));
#endif

#ifdef OPENSSL_EXTRA
    ExpectTrue(wolfSSL_set_msg_callback(ssl, msg_cb) == WOLFSSL_SUCCESS);
    wolfSSL_set_msg_callback_arg(ssl, arg);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
    ExpectTrue(wolfSSL_CTX_set_alpn_protos(ctx, protos, len) == 0);
#else
    ExpectTrue(wolfSSL_CTX_set_alpn_protos(ctx, protos, len) == WOLFSSL_SUCCESS);
#endif
#endif

#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_ALL) || \
    defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL)

#if defined(HAVE_ALPN) && !defined(NO_BIO)

#ifdef WOLFSSL_ERROR_CODE_OPENSSL
    ExpectTrue(wolfSSL_set_alpn_protos(ssl, protos, len) == 0);
#else
    ExpectTrue(wolfSSL_set_alpn_protos(ssl, protos, len) == WOLFSSL_SUCCESS);
#endif

#endif /* HAVE_ALPN && !NO_BIO */
#endif

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_sk_SSL_CIPHER(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    SSL*     ssl = NULL;
    SSL_CTX* ctx = NULL;
    STACK_OF(SSL_CIPHER) *sk = NULL;
    STACK_OF(SSL_CIPHER) *dupSk = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile, SSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectNotNull(sk = SSL_get_ciphers(ssl));
    ExpectNotNull(dupSk = sk_SSL_CIPHER_dup(sk));
    ExpectIntGT(sk_SSL_CIPHER_num(sk), 0);
    ExpectIntEQ(sk_SSL_CIPHER_num(sk), sk_SSL_CIPHER_num(dupSk));

    /* error case because connection has not been established yet */
    ExpectIntEQ(sk_SSL_CIPHER_find(sk, SSL_get_current_cipher(ssl)), -1);
    sk_SSL_CIPHER_free(dupSk);

    /* sk is pointer to internal struct that should be free'd in SSL_free */
    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
         !defined(NO_FILESYSTEM) && !defined(NO_RSA) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_set1_curves_list(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    SSL*     ssl = NULL;
    SSL_CTX* ctx = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, eccCertFile,
               SSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, eccKeyFile, SSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifdef HAVE_ECC
    ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "P-25X"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "P-256"), WOLFSSL_SUCCESS);
#endif
#ifdef HAVE_CURVE25519
    ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "X25519"), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "X25519"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#ifdef HAVE_CURVE448
    ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "X448"), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "X448"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif

    ExpectIntEQ(SSL_set1_curves_list(ssl, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifdef HAVE_ECC
    ExpectIntEQ(SSL_set1_curves_list(ssl, "P-25X"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_set1_curves_list(ssl, "P-256"), WOLFSSL_SUCCESS);
#endif

#ifdef HAVE_CURVE25519
    ExpectIntEQ(SSL_set1_curves_list(ssl, "X25519"), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(SSL_set1_curves_list(ssl, "X25519"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#ifdef HAVE_CURVE448
    ExpectIntEQ(SSL_set1_curves_list(ssl, "X448"), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(SSL_set1_curves_list(ssl, "X448"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
        (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) && defined(HAVE_ECC)
static int test_wolfSSL_curves_mismatch_ctx_ready(WOLFSSL_CTX* ctx)
{
    static int counter = 0;
    EXPECT_DECLS;

    if (counter % 2) {
        ExpectIntEQ(wolfSSL_CTX_set1_curves_list(ctx, "P-256"),
                WOLFSSL_SUCCESS);
    }
    else {
        ExpectIntEQ(wolfSSL_CTX_set1_curves_list(ctx, "P-384"),
                WOLFSSL_SUCCESS);
    }

    /* Ciphersuites that require curves */
    wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384:"
            "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES128-GCM-SHA256:"
            "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:"
            "ECDHE-ECDSA-AES128-GCM-SHA256:"
            "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:"
            "ECDHE-ECDSA-CHACHA20-POLY1305");

    counter++;
    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_curves_mismatch(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
        (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) && defined(HAVE_ECC)
    test_ssl_cbf func_cb_client;
    test_ssl_cbf func_cb_server;
    size_t i;
    struct {
        method_provider client_meth;
        method_provider server_meth;
        const char* desc;
        int client_last_err;
        int server_last_err;
    } test_params[] = {
#ifdef WOLFSSL_TLS13
        {wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3",
                WC_NO_ERR_TRACE(FATAL_ERROR), WC_NO_ERR_TRACE(BAD_KEY_SHARE_DATA)},
#endif
#ifndef WOLFSSL_NO_TLS12
        {wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2",
                WC_NO_ERR_TRACE(FATAL_ERROR),
#ifdef OPENSSL_EXTRA
                WC_NO_ERR_TRACE(WOLFSSL_ERROR_SYSCALL)
#else
                WC_NO_ERR_TRACE(MATCH_SUITE_ERROR)
#endif
        },
#endif
#ifndef NO_OLD_TLS
        {wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLS 1.1",
                WC_NO_ERR_TRACE(FATAL_ERROR),
#ifdef OPENSSL_EXTRA
                WC_NO_ERR_TRACE(WOLFSSL_ERROR_SYSCALL)
#else
                WC_NO_ERR_TRACE(MATCH_SUITE_ERROR)
#endif
        },
#endif
    };

    for (i = 0; i < XELEM_CNT(test_params) && !EXPECT_FAIL(); i++) {
        XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
        XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

        printf("\tTesting with %s...\n", test_params[i].desc);

        func_cb_client.ctx_ready = &test_wolfSSL_curves_mismatch_ctx_ready;
        func_cb_server.ctx_ready = &test_wolfSSL_curves_mismatch_ctx_ready;

        func_cb_client.method = test_params[i].client_meth;
        func_cb_server.method = test_params[i].server_meth;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
            &func_cb_server, NULL), -1001);
        ExpectIntEQ(func_cb_client.last_err, test_params[i].client_last_err);
        ExpectIntEQ(func_cb_server.last_err, test_params[i].server_last_err);

        if (!EXPECT_SUCCESS())
            break;
        printf("\t%s passed\n", test_params[i].desc);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_set1_sigalgs_list(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
    SSL*     ssl = NULL;
    SSL_CTX* ctx = NULL;

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
               SSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));

    ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_set1_sigalgs_list(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, ""), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, ""), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

#ifndef NO_RSA
    #ifndef NO_SHA256
        ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(NULL, "RSA+SHA256"),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(NULL, "RSA+SHA256"),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

        ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA+SHA256"),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA+SHA256"),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA-SHA256"),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA-SHA256"),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        #ifdef WC_RSA_PSS
            ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA-PSS+SHA256"),
                        WOLFSSL_SUCCESS);
            ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA-PSS+SHA256"),
                        WOLFSSL_SUCCESS);
            ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "PSS+SHA256"),
                        WOLFSSL_SUCCESS);
            ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "PSS+SHA256"),
                        WOLFSSL_SUCCESS);
        #endif
        #ifdef WOLFSSL_SHA512
            ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
                       "RSA+SHA256:RSA+SHA512"), WOLFSSL_SUCCESS);
            ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
                       "RSA+SHA256:RSA+SHA512"), WOLFSSL_SUCCESS);
        #elif defined(WOLFSSL_SHA384)
            ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
                       "RSA+SHA256:RSA+SHA384"), WOLFSSL_SUCCESS);
            ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
                       "RSA+SHA256:RSA+SHA384"), WOLFSSL_SUCCESS);
        #endif
        ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA:RSA+SHA256"),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA:RSA+SHA256"),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

        ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA+SHA256+SHA256"),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA+SHA256+RSA"),
                    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    #endif
#endif
#ifdef HAVE_ECC
    #ifndef NO_SHA256
        ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "ECDSA+SHA256"),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "ECDSA+SHA256"),
            WOLFSSL_SUCCESS);
        #ifdef WOLFSSL_SHA512
            ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
                       "ECDSA+SHA256:ECDSA+SHA512"), WOLFSSL_SUCCESS);
            ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
                       "ECDSA+SHA256:ECDSA+SHA512"), WOLFSSL_SUCCESS);
        #elif defined(WOLFSSL_SHA384)
            ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
                       "ECDSA+SHA256:ECDSA+SHA384"), WOLFSSL_SUCCESS);
            ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
                       "ECDSA+SHA256:ECDSA+SHA384"), WOLFSSL_SUCCESS);
        #endif
    #endif
#endif
#ifdef HAVE_ED25519
    ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "ED25519"), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "ED25519"), WOLFSSL_SUCCESS);
#endif
#ifdef HAVE_ED448
    ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "ED448"), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "ED448"), WOLFSSL_SUCCESS);
#endif
#ifndef NO_DSA
    #ifndef NO_SHA256
        ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "DSA+SHA256"),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "DSA+SHA256"),
                    WOLFSSL_SUCCESS);
    #endif
    #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
                                                defined(WOLFSSL_ALLOW_TLS_SHA1))
        ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "DSA+SHA1"),
                    WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "DSA+SHA1"),
                    WOLFSSL_SUCCESS);
    #endif
#endif

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif
    return EXPECT_RESULT();
}

/* Testing  wolfSSL_set_tlsext_status_type function.
 * PRE: OPENSSL and HAVE_CERTIFICATE_STATUS_REQUEST defined.
 */
static int test_wolfSSL_set_tlsext_status_type(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
    !defined(NO_RSA) && !defined(NO_WOLFSSL_SERVER)
    SSL*     ssl = NULL;
    SSL_CTX* ctx = NULL;

    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
    ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
        SSL_FILETYPE_PEM));
    ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectIntEQ(SSL_set_tlsext_status_type(ssl,TLSEXT_STATUSTYPE_ocsp),
        SSL_SUCCESS);
    ExpectIntEQ(SSL_get_tlsext_status_type(ssl), TLSEXT_STATUSTYPE_ocsp);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif  /* OPENSSL_EXTRA && HAVE_CERTIFICATE_STATUS_REQUEST && !NO_RSA */
    return EXPECT_RESULT();
}

#ifndef NO_BIO

static int test_wolfSSL_PEM_read_bio(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
   !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    byte buff[6000];
    XFILE f = XBADFILE;
    int  bytes = 0;
    X509* x509 = NULL;
    BIO*  bio = NULL;
    BUF_MEM* buf = NULL;

    ExpectTrue((f = XFOPEN(cliCertFile, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectNull(x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL));
    ExpectNotNull(bio = BIO_new_mem_buf((void*)buff, bytes));
    ExpectIntEQ(BIO_set_mem_eof_return(bio, -0xDEAD), 1);
    ExpectNotNull(x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL));
    ExpectIntEQ((int)BIO_set_fd(bio, 0, BIO_CLOSE), 1);
    /* BIO should return the set EOF value */
    ExpectIntEQ(BIO_read(bio, buff, sizeof(buff)), -0xDEAD);
    ExpectIntEQ(BIO_set_close(bio, BIO_NOCLOSE), 1);
    ExpectIntEQ(BIO_set_close(NULL, BIO_NOCLOSE), 1);
    ExpectIntEQ(SSL_SUCCESS, BIO_get_mem_ptr(bio, &buf));

    BIO_free(bio);
    BUF_MEM_free(buf);
    X509_free(x509);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) &&
        * !defined(NO_FILESYSTEM) && !defined(NO_RSA) */
    return EXPECT_RESULT();
}


#if defined(OPENSSL_EXTRA)
static long bioCallback(BIO *bio, int cmd, const char* argp, int argi,
                 long argl, long ret)
{
    (void)bio;
    (void)cmd;
    (void)argp;
    (void)argi;
    (void)argl;
    return ret;
}
#endif


static int test_wolfSSL_BIO(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    const unsigned char* p = NULL;
    byte buff[20];
    BIO* bio1 = NULL;
    BIO* bio2 = NULL;
    BIO* bio3 = NULL;
    char* bufPt = NULL;
    int i;

    for (i = 0; i < 20; i++) {
        buff[i] = i;
    }
    /* test BIO_free with NULL */
    ExpectIntEQ(BIO_free(NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* Creating and testing type BIO_s_bio */
    ExpectNotNull(bio1 = BIO_new(BIO_s_bio()));
    ExpectNotNull(bio2 = BIO_new(BIO_s_bio()));
    ExpectNotNull(bio3 = BIO_new(BIO_s_bio()));

    /* read/write before set up */
    ExpectIntEQ(BIO_read(bio1, buff, 2),  WOLFSSL_BIO_UNSET);
    ExpectIntEQ(BIO_write(bio1, buff, 2), WOLFSSL_BIO_UNSET);

    ExpectIntEQ(BIO_set_nbio(bio1, 1), 1);
    ExpectIntEQ(BIO_set_write_buf_size(bio1, 20), WOLFSSL_SUCCESS);
    ExpectIntEQ(BIO_set_write_buf_size(bio2, 8),  WOLFSSL_SUCCESS);
    ExpectIntEQ(BIO_make_bio_pair(bio1, bio2),    WOLFSSL_SUCCESS);

    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 10), 10);
    ExpectNotNull(XMEMCPY(bufPt, buff, 10));
    ExpectIntEQ(BIO_write(bio1, buff + 10, 10), 10);
    /* write buffer full */
    ExpectIntEQ(BIO_write(bio1, buff, 10), WOLFSSL_BIO_ERROR);
    ExpectIntEQ(BIO_flush(bio1), WOLFSSL_SUCCESS);
    ExpectIntEQ((int)BIO_ctrl_pending(bio1), 0);

    /* write the other direction with pair */
    ExpectIntEQ((int)BIO_nwrite(bio2, &bufPt, 10), 8);
    ExpectNotNull(XMEMCPY(bufPt, buff, 8));
    ExpectIntEQ(BIO_write(bio2, buff, 10), WOLFSSL_BIO_ERROR);

    /* try read */
    ExpectIntEQ((int)BIO_ctrl_pending(bio1), 8);
    ExpectIntEQ((int)BIO_ctrl_pending(bio2), 20);

    /* try read using ctrl function */
    ExpectIntEQ((int)BIO_ctrl(bio1, BIO_CTRL_WPENDING, 0, NULL), 8);
    ExpectIntEQ((int)BIO_ctrl(bio1, BIO_CTRL_PENDING, 0, NULL), 8);
    ExpectIntEQ((int)BIO_ctrl(bio2, BIO_CTRL_WPENDING, 0, NULL), 20);
    ExpectIntEQ((int)BIO_ctrl(bio2, BIO_CTRL_PENDING, 0, NULL), 20);

    ExpectIntEQ(BIO_nread(bio2, &bufPt, (int)BIO_ctrl_pending(bio2)), 20);
    for (i = 0; i < 20; i++) {
        ExpectIntEQ((int)bufPt[i], i);
    }
    ExpectIntEQ(BIO_nread(bio2, &bufPt, 1), 0);
    ExpectIntEQ(BIO_nread(bio1, &bufPt, (int)BIO_ctrl_pending(bio1)), 8);
    for (i = 0; i < 8; i++) {
        ExpectIntEQ((int)bufPt[i], i);
    }
    ExpectIntEQ(BIO_nread(bio1, &bufPt, 1), 0);
    ExpectIntEQ(BIO_ctrl_reset_read_request(bio1), 1);

    /* new pair */
    ExpectIntEQ(BIO_make_bio_pair(bio1, bio3), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    BIO_free(bio2); /* free bio2 and automatically remove from pair */
    bio2 = NULL;
    ExpectIntEQ(BIO_make_bio_pair(bio1, bio3), WOLFSSL_SUCCESS);
    ExpectIntEQ((int)BIO_ctrl_pending(bio3), 0);
    ExpectIntEQ(BIO_nread(bio3, &bufPt, 10), 0);

    /* test wrap around... */
    ExpectIntEQ(BIO_reset(bio1), 1);
    ExpectIntEQ(BIO_reset(bio3), 1);

    /* fill write buffer, read only small amount then write again */
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20);
    ExpectNotNull(XMEMCPY(bufPt, buff, 20));
    ExpectIntEQ(BIO_nread(bio3, &bufPt, 4), 4);
    for (i = 0; i < 4; i++) {
        ExpectIntEQ(bufPt[i], i);
    }

    /* try writing over read index */
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 5), 4);
    ExpectNotNull(XMEMSET(bufPt, 0, 4));
    ExpectIntEQ((int)BIO_ctrl_pending(bio3), 20);

    /* read and write 0 bytes */
    ExpectIntEQ(BIO_nread(bio3, &bufPt, 0), 0);
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 0), 0);

    /* should read only to end of write buffer then need to read again */
    ExpectIntEQ(BIO_nread(bio3, &bufPt, 20), 16);
    for (i = 0; i < 16; i++) {
        ExpectIntEQ(bufPt[i], buff[4 + i]);
    }

    ExpectIntEQ(BIO_nread(bio3, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(BIO_nread0(bio3, &bufPt), 4);
    for (i = 0; i < 4; i++) {
        ExpectIntEQ(bufPt[i], 0);
    }

    /* read index should not have advanced with nread0 */
    ExpectIntEQ(BIO_nread(bio3, &bufPt, 5), 4);
    for (i = 0; i < 4; i++) {
        ExpectIntEQ(bufPt[i], 0);
    }

    /* write and fill up buffer checking reset of index state */
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20);
    ExpectNotNull(XMEMCPY(bufPt, buff, 20));

    /* test reset on data in bio1 write buffer */
    ExpectIntEQ(BIO_reset(bio1), 1);
    ExpectIntEQ((int)BIO_ctrl_pending(bio3), 0);
    ExpectIntEQ(BIO_nread(bio3, &bufPt, 3), 0);
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20);
    ExpectIntEQ((int)BIO_ctrl(bio1, BIO_CTRL_INFO, 0, &p), 20);
    ExpectNotNull(p);
    ExpectNotNull(XMEMCPY(bufPt, buff, 20));
    ExpectIntEQ(BIO_nread(bio3, &bufPt, 6), 6);
    for (i = 0; i < 6; i++) {
        ExpectIntEQ(bufPt[i], i);
    }

    /* test case of writing twice with offset read index */
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 3), 3);
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 4), 3); /* try overwriting */
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 4), WOLFSSL_BIO_ERROR);
    ExpectIntEQ(BIO_nread(bio3, &bufPt, 0), 0);
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 4), WOLFSSL_BIO_ERROR);
    ExpectIntEQ(BIO_nread(bio3, &bufPt, 1), 1);
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 4), 1);
    ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 4), WOLFSSL_BIO_ERROR);

    BIO_free(bio1);
    bio1 = NULL;
    BIO_free(bio3);
    bio3 = NULL;

    #if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)
    {
        BIO* bioA = NULL;
        BIO* bioB = NULL;
        ExpectIntEQ(BIO_new_bio_pair(NULL, 256, NULL, 256), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(BIO_new_bio_pair(&bioA, 256, &bioB, 256), WOLFSSL_SUCCESS);
        BIO_free(bioA);
        bioA = NULL;
        BIO_free(bioB);
        bioB = NULL;
    }
    #endif /* OPENSSL_ALL || WOLFSSL_ASIO */

    /* BIOs with file pointers */
    #if !defined(NO_FILESYSTEM)
    {
        XFILE f1 = XBADFILE;
        XFILE f2 = XBADFILE;
        BIO*  f_bio1 = NULL;
        BIO*  f_bio2 = NULL;
        unsigned char cert[300];
        char testFile[] = "tests/bio_write_test.txt";
        char msg[]      = "bio_write_test.txt contains the first 300 bytes of certs/server-cert.pem\ncreated by tests/unit.test\n\n";

        ExpectNotNull(f_bio1 = BIO_new(BIO_s_file()));
        ExpectNotNull(f_bio2 = BIO_new(BIO_s_file()));

        /* Failure due to wrong BIO type */
        ExpectIntEQ((int)BIO_set_mem_eof_return(f_bio1, -1), 0);
        ExpectIntEQ((int)BIO_set_mem_eof_return(NULL, -1),   0);

        ExpectTrue((f1 = XFOPEN(svrCertFile, "rwb")) != XBADFILE);
        ExpectIntEQ((int)BIO_set_fp(f_bio1, f1, BIO_CLOSE), WOLFSSL_SUCCESS);
        ExpectIntEQ(BIO_write_filename(f_bio2, testFile),
                WOLFSSL_SUCCESS);

        ExpectIntEQ(BIO_read(f_bio1, cert, sizeof(cert)), sizeof(cert));
        ExpectIntEQ(BIO_tell(f_bio1),sizeof(cert));
        ExpectIntEQ(BIO_write(f_bio2, msg, sizeof(msg)), sizeof(msg));
        ExpectIntEQ(BIO_tell(f_bio2),sizeof(msg));
        ExpectIntEQ(BIO_write(f_bio2, cert, sizeof(cert)), sizeof(cert));
        ExpectIntEQ(BIO_tell(f_bio2),sizeof(cert) + sizeof(msg));

        ExpectIntEQ((int)BIO_get_fp(f_bio2, &f2), WOLFSSL_SUCCESS);
        ExpectIntEQ(BIO_reset(f_bio2), 1);
        ExpectIntEQ(BIO_tell(NULL),-1);
        ExpectIntEQ(BIO_tell(f_bio2),0);
        ExpectIntEQ(BIO_seek(f_bio2, 4), 0);
        ExpectIntEQ(BIO_tell(f_bio2),4);

        BIO_free(f_bio1);
        f_bio1 = NULL;
        BIO_free(f_bio2);
        f_bio2 = NULL;

        ExpectNotNull(f_bio1 = BIO_new_file(svrCertFile, "rwb"));
        ExpectIntEQ((int)BIO_set_mem_eof_return(f_bio1, -1), 0);
        ExpectIntEQ(BIO_read(f_bio1, cert, sizeof(cert)), sizeof(cert));
        BIO_free(f_bio1);
        f_bio1 = NULL;
    }
    #endif /* !defined(NO_FILESYSTEM) */

    /* BIO info callback */
    {
        const char* testArg = "test";
        BIO* cb_bio = NULL;
        ExpectNotNull(cb_bio = BIO_new(BIO_s_mem()));

        BIO_set_callback(cb_bio, bioCallback);
        ExpectNotNull(BIO_get_callback(cb_bio));
        BIO_set_callback(cb_bio, NULL);
        ExpectNull(BIO_get_callback(cb_bio));

        BIO_set_callback_arg(cb_bio, (char*)testArg);
        ExpectStrEQ(BIO_get_callback_arg(cb_bio), testArg);
        ExpectNull(BIO_get_callback_arg(NULL));

        BIO_free(cb_bio);
        cb_bio = NULL;
    }

    /* BIO_vfree */
    ExpectNotNull(bio1 = BIO_new(BIO_s_bio()));
    BIO_vfree(NULL);
    BIO_vfree(bio1);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BIO_BIO_ring_read(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL)
    BIO* bio1 = NULL;
    BIO* bio2 = NULL;
    byte data[50];
    byte tmp[50];

    XMEMSET(data, 42, sizeof(data));


    ExpectIntEQ(BIO_new_bio_pair(&bio1, sizeof(data), &bio2, sizeof(data)),
            SSL_SUCCESS);

    ExpectIntEQ(BIO_write(bio1, data, 40), 40);
    ExpectIntEQ(BIO_read(bio1, tmp, 20), -1);
    ExpectIntEQ(BIO_read(bio2, tmp, 20), 20);
    ExpectBufEQ(tmp, data, 20);
    ExpectIntEQ(BIO_write(bio1, data, 20), 20);
    ExpectIntEQ(BIO_read(bio2, tmp, 40), 40);
    ExpectBufEQ(tmp, data, 40);

    BIO_free(bio1);
    BIO_free(bio2);
#endif
    return EXPECT_RESULT();
}

#endif /* !NO_BIO */


static int test_wolfSSL_a2i_IPADDRESS(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(WOLFSSL_USER_IO)
    const unsigned char* data = NULL;
    int dataSz = 0;
    ASN1_OCTET_STRING *st = NULL;

    const unsigned char ipv4_exp[] = {0x7F, 0, 0, 1};
    const unsigned char ipv6_exp[] = {
        0x20, 0x21, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x77, 0x77
    };
    const unsigned char ipv6_home[] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
    };

    ExpectNull(st = a2i_IPADDRESS("127.0.0.1bad"));
    ExpectNotNull(st = a2i_IPADDRESS("127.0.0.1"));
    ExpectNotNull(data = ASN1_STRING_get0_data(st));
    ExpectIntEQ(dataSz = ASN1_STRING_length(st), WOLFSSL_IP4_ADDR_LEN);
    ExpectIntEQ(XMEMCMP(data, ipv4_exp, dataSz), 0);
    ASN1_STRING_free(st);
    st = NULL;

    ExpectNotNull(st = a2i_IPADDRESS("::1"));
    ExpectNotNull(data = ASN1_STRING_get0_data(st));
    ExpectIntEQ(dataSz = ASN1_STRING_length(st), WOLFSSL_IP6_ADDR_LEN);
    ExpectIntEQ(XMEMCMP(data, ipv6_home, dataSz), 0);
    ASN1_STRING_free(st);
    st = NULL;

    ExpectNotNull(st = a2i_IPADDRESS("2021:db8::ff00:42:7777"));
    ExpectNotNull(data = ASN1_STRING_get0_data(st));
    ExpectIntEQ(dataSz = ASN1_STRING_length(st), WOLFSSL_IP6_ADDR_LEN);
    ExpectIntEQ(XMEMCMP(data, ipv6_exp, dataSz), 0);
    ASN1_STRING_free(st);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_X509_cmp_time(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) \
&& !defined(USER_TIME) && !defined(TIME_OVERRIDES)
    WOLFSSL_ASN1_TIME asn_time;
    time_t t;

    ExpectIntEQ(0, wolfSSL_X509_cmp_time(NULL, &t));
    XMEMSET(&asn_time, 0, sizeof(WOLFSSL_ASN1_TIME));
    ExpectIntEQ(0, wolfSSL_X509_cmp_time(&asn_time, &t));

    ExpectIntEQ(ASN1_TIME_set_string(&asn_time, "000222211515Z"), 1);
    ExpectIntEQ(-1, wolfSSL_X509_cmp_time(&asn_time, NULL));
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_time_adj(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) && \
    !defined(USER_TIME) && !defined(TIME_OVERRIDES) && \
    defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA) && \
    !defined(NO_ASN_TIME)
    X509*  x509 = NULL;
    time_t t;
    time_t not_before;
    time_t not_after;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_buffer(
        client_cert_der_2048, sizeof_client_cert_der_2048,
        WOLFSSL_FILETYPE_ASN1));

    t = 0;
    not_before = wc_Time(0);
    not_after = wc_Time(0) + (60 * 24 * 30); /* 30 days after */
    ExpectNotNull(X509_time_adj(X509_get_notBefore(x509), not_before, &t));
    ExpectNotNull(X509_time_adj(X509_get_notAfter(x509), not_after, &t));
    /* Check X509_gmtime_adj, too. */
    ExpectNotNull(X509_gmtime_adj(X509_get_notAfter(x509), not_after));

    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_bad_altname(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA)
    const unsigned char malformed_alt_name_cert[] = {
        0x30, 0x82, 0x02, 0xf9, 0x30, 0x82, 0x01, 0xe1, 0xa0, 0x03, 0x02, 0x01,
        0x02, 0x02, 0x02, 0x10, 0x21, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
        0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x0f, 0x31, 0x0d,
        0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x61, 0x61, 0x31,
        0x31, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x32, 0x30, 0x37, 0x31,
        0x37, 0x32, 0x34, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x32,
        0x31, 0x34, 0x30, 0x36, 0x32, 0x36, 0x35, 0x33, 0x5a, 0x30, 0x0f, 0x31,
        0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x61, 0x61,
        0x61, 0x61, 0x30, 0x82, 0x01, 0x20, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
        0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
        0x0d, 0x00, 0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa8,
        0x8a, 0x5e, 0x26, 0x23, 0x1b, 0x31, 0xd3, 0x37, 0x1a, 0x70, 0xb2, 0xec,
        0x3f, 0x74, 0xd4, 0xb4, 0x44, 0xe3, 0x7a, 0xa5, 0xc0, 0xf5, 0xaa, 0x97,
        0x26, 0x9a, 0x04, 0xff, 0xda, 0xbe, 0xe5, 0x09, 0x03, 0x98, 0x3d, 0xb5,
        0xbf, 0x01, 0x2c, 0x9a, 0x0a, 0x3a, 0xfb, 0xbc, 0x3c, 0xe7, 0xbe, 0x83,
        0x5c, 0xb3, 0x70, 0xe8, 0x5c, 0xe3, 0xd1, 0x83, 0xc3, 0x94, 0x08, 0xcd,
        0x1a, 0x87, 0xe5, 0xe0, 0x5b, 0x9c, 0x5c, 0x6e, 0xb0, 0x7d, 0xe2, 0x58,
        0x6c, 0xc3, 0xb5, 0xc8, 0x9d, 0x11, 0xf1, 0x5d, 0x96, 0x0d, 0x66, 0x1e,
        0x56, 0x7f, 0x8f, 0x59, 0xa7, 0xa5, 0xe1, 0xc5, 0xe7, 0x81, 0x4c, 0x09,
        0x9d, 0x5e, 0x96, 0xf0, 0x9a, 0xc2, 0x8b, 0x70, 0xd5, 0xab, 0x79, 0x58,
        0x5d, 0xb7, 0x58, 0xaa, 0xfd, 0x75, 0x52, 0xaa, 0x4b, 0xa7, 0x25, 0x68,
        0x76, 0x59, 0x00, 0xee, 0x78, 0x2b, 0x91, 0xc6, 0x59, 0x91, 0x99, 0x38,
        0x3e, 0xa1, 0x76, 0xc3, 0xf5, 0x23, 0x6b, 0xe6, 0x07, 0xea, 0x63, 0x1c,
        0x97, 0x49, 0xef, 0xa0, 0xfe, 0xfd, 0x13, 0xc9, 0xa9, 0x9f, 0xc2, 0x0b,
        0xe6, 0x87, 0x92, 0x5b, 0xcc, 0xf5, 0x42, 0x95, 0x4a, 0xa4, 0x6d, 0x64,
        0xba, 0x7d, 0xce, 0xcb, 0x04, 0xd0, 0xf8, 0xe7, 0xe3, 0xda, 0x75, 0x60,
        0xd3, 0x8b, 0x6a, 0x64, 0xfc, 0x78, 0x56, 0x21, 0x69, 0x5a, 0xe8, 0xa7,
        0x8f, 0xfb, 0x8f, 0x82, 0xe3, 0xae, 0x36, 0xa2, 0x93, 0x66, 0x92, 0xcb,
        0x82, 0xa3, 0xbe, 0x84, 0x00, 0x86, 0xdc, 0x7e, 0x6d, 0x53, 0x77, 0x84,
        0x17, 0xb9, 0x55, 0x43, 0x0d, 0xf1, 0x16, 0x1f, 0xd5, 0x43, 0x75, 0x99,
        0x66, 0x19, 0x52, 0xd0, 0xac, 0x5f, 0x74, 0xad, 0xb2, 0x90, 0x15, 0x50,
        0x04, 0x74, 0x43, 0xdf, 0x6c, 0x35, 0xd0, 0xfd, 0x32, 0x37, 0xb3, 0x8d,
        0xf5, 0xe5, 0x09, 0x02, 0x01, 0x03, 0xa3, 0x61, 0x30, 0x5f, 0x30, 0x0c,
        0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
        0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x08, 0x30, 0x06, 0x82,
        0x04, 0x61, 0x2a, 0x00, 0x2a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
        0x04, 0x16, 0x04, 0x14, 0x92, 0x6a, 0x1e, 0x52, 0x3a, 0x1a, 0x57, 0x9f,
        0xc9, 0x82, 0x9a, 0xce, 0xc8, 0xc0, 0xa9, 0x51, 0x9d, 0x2f, 0xc7, 0x72,
        0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
        0x14, 0x6b, 0xf9, 0xa4, 0x2d, 0xa5, 0xe9, 0x39, 0x89, 0xa8, 0x24, 0x58,
        0x79, 0x87, 0x11, 0xfc, 0x6f, 0x07, 0x91, 0xef, 0xa6, 0x30, 0x0d, 0x06,
        0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
        0x03, 0x82, 0x01, 0x01, 0x00, 0x3f, 0xd5, 0x37, 0x2f, 0xc7, 0xf8, 0x8b,
        0x39, 0x1c, 0xe3, 0xdf, 0x77, 0xee, 0xc6, 0x4b, 0x5f, 0x84, 0xcf, 0xfa,
        0x33, 0x2c, 0xb2, 0xb5, 0x4b, 0x09, 0xee, 0x56, 0xc0, 0xf2, 0xf0, 0xeb,
        0xad, 0x1c, 0x02, 0xef, 0xae, 0x09, 0x53, 0xc0, 0x06, 0xad, 0x4e, 0xfd,
        0x3e, 0x8c, 0x13, 0xb3, 0xbf, 0x80, 0x05, 0x36, 0xb5, 0x3f, 0x2b, 0xc7,
        0x60, 0x53, 0x14, 0xbf, 0x33, 0x63, 0x47, 0xc3, 0xc6, 0x28, 0xda, 0x10,
        0x12, 0xe2, 0xc4, 0xeb, 0xc5, 0x64, 0x66, 0xc0, 0xcc, 0x6b, 0x84, 0xda,
        0x0c, 0xe9, 0xf6, 0xe3, 0xf8, 0x8e, 0x3d, 0x95, 0x5f, 0xba, 0x9f, 0xe1,
        0xc7, 0xed, 0x6e, 0x97, 0xcc, 0xbd, 0x7d, 0xe5, 0x4e, 0xab, 0xbc, 0x1b,
        0xf1, 0x3a, 0x09, 0x33, 0x09, 0xe1, 0xcc, 0xec, 0x21, 0x16, 0x8e, 0xb1,
        0x74, 0x9e, 0xc8, 0x13, 0x7c, 0xdf, 0x07, 0xaa, 0xeb, 0x70, 0xd7, 0x91,
        0x5c, 0xc4, 0xef, 0x83, 0x88, 0xc3, 0xe4, 0x97, 0xfa, 0xe4, 0xdf, 0xd7,
        0x0d, 0xff, 0xba, 0x78, 0x22, 0xfc, 0x3f, 0xdc, 0xd8, 0x02, 0x8d, 0x93,
        0x57, 0xf9, 0x9e, 0x39, 0x3a, 0x77, 0x00, 0xd9, 0x19, 0xaa, 0x68, 0xa1,
        0xe6, 0x9e, 0x13, 0xeb, 0x37, 0x16, 0xf5, 0x77, 0xa4, 0x0b, 0x40, 0x04,
        0xd3, 0xa5, 0x49, 0x78, 0x35, 0xfa, 0x3b, 0xf6, 0x02, 0xab, 0x85, 0xee,
        0xcb, 0x9b, 0x62, 0xda, 0x05, 0x00, 0x22, 0x2f, 0xf8, 0xbd, 0x0b, 0xe5,
        0x2c, 0xb2, 0x53, 0x78, 0x0a, 0xcb, 0x69, 0xc0, 0xb6, 0x9f, 0x96, 0xff,
        0x58, 0x22, 0x70, 0x9c, 0x01, 0x2e, 0x56, 0x60, 0x5d, 0x37, 0xe3, 0x40,
        0x25, 0xc9, 0x90, 0xc8, 0x0f, 0x41, 0x68, 0xb4, 0xfd, 0x10, 0xe2, 0x09,
        0x99, 0x08, 0x5d, 0x7b, 0xc9, 0xe3, 0x29, 0xd4, 0x5a, 0xcf, 0xc9, 0x34,
        0x55, 0xa1, 0x40, 0x44, 0xd6, 0x88, 0x16, 0xbb, 0xdd
    };

    X509* x509 = NULL;
    int certSize = (int)sizeof(malformed_alt_name_cert) / sizeof(unsigned char);
    const char *name = "aaaaa";
    int nameLen = (int)XSTRLEN(name);

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_buffer(
        malformed_alt_name_cert, certSize, SSL_FILETYPE_ASN1));

    /* malformed_alt_name_cert has a malformed alternative
     * name of "a*\0*". Ensure that it does not match "aaaaa" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name, nameLen,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), 1);

    /* Also make sure WOLFSSL_LEFT_MOST_WILDCARD_ONLY fails too */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name, nameLen,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), 1);

    X509_free(x509);

#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_name_match(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA)
    /* A certificate with the subject alternative name a* */
    const unsigned char cert_der[] = {
        0x30, 0x82, 0x03, 0xac, 0x30, 0x82, 0x02, 0x94, 0xa0, 0x03, 0x02, 0x01,
        0x02, 0x02, 0x14, 0x0f, 0xa5, 0x10, 0x85, 0xef, 0x58, 0x10, 0x59, 0xfc,
        0x0f, 0x20, 0x1f, 0x53, 0xf5, 0x30, 0x39, 0x34, 0x49, 0x54, 0x05, 0x30,
        0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
        0x05, 0x00, 0x30, 0x77, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
        0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
        0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31,
        0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f,
        0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
        0x04, 0x0a, 0x0c, 0x0b, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20,
        0x49, 0x6e, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
        0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e,
        0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f,
        0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e,
        0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x35, 0x33,
        0x30, 0x32, 0x30, 0x31, 0x35, 0x35, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
        0x30, 0x35, 0x32, 0x38, 0x32, 0x30, 0x31, 0x35, 0x35, 0x38, 0x5a, 0x30,
        0x77, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
        0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
        0x07, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e,
        0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d,
        0x61, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
        0x0b, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x49, 0x6e, 0x63,
        0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45,
        0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18,
        0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, 0x77,
        0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d,
        0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
        0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
        0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xf4, 0xca, 0x3d,
        0xd4, 0xbc, 0x9b, 0xea, 0x74, 0xfe, 0x73, 0xf4, 0x16, 0x23, 0x0b, 0x4a,
        0x09, 0x54, 0xf6, 0x7b, 0x10, 0x99, 0x11, 0x93, 0xb2, 0xdb, 0x4d, 0x7d,
        0x23, 0xab, 0xf9, 0xcd, 0xf6, 0x54, 0xd4, 0xf6, 0x39, 0x57, 0xee, 0x97,
        0xb2, 0xb9, 0xfc, 0x7e, 0x9c, 0xb3, 0xfb, 0x56, 0xb6, 0x84, 0xd6, 0x2d,
        0x59, 0x1c, 0xed, 0xda, 0x9b, 0x19, 0xf5, 0x8a, 0xa7, 0x8a, 0x89, 0xd6,
        0xa1, 0xc0, 0xe6, 0x16, 0xad, 0x04, 0xcf, 0x5a, 0x1f, 0xdf, 0x62, 0x6c,
        0x68, 0x45, 0xe9, 0x55, 0x2e, 0x42, 0xa3, 0x1b, 0x3b, 0x86, 0x23, 0x22,
        0xa1, 0x20, 0x48, 0xd1, 0x52, 0xc0, 0x8b, 0xab, 0xe2, 0x8a, 0x15, 0x68,
        0xbd, 0x89, 0x6f, 0x9f, 0x45, 0x75, 0xb4, 0x27, 0xc1, 0x72, 0x41, 0xfd,
        0x79, 0x89, 0xb0, 0x74, 0xa2, 0xe9, 0x61, 0x48, 0x4c, 0x54, 0xad, 0x6b,
        0x61, 0xbf, 0x0e, 0x27, 0x58, 0xb4, 0xf6, 0x9c, 0x2c, 0x9f, 0xc2, 0x3e,
        0x3b, 0xb3, 0x90, 0x41, 0xbc, 0x61, 0xcd, 0x01, 0x57, 0x90, 0x82, 0xec,
        0x46, 0xba, 0x4f, 0x89, 0x8e, 0x7f, 0x49, 0x4f, 0x46, 0x69, 0x37, 0x8b,
        0xa0, 0xba, 0x85, 0xe8, 0x42, 0xff, 0x9a, 0xa1, 0x53, 0x81, 0x5c, 0xf3,
        0x8e, 0x85, 0x1c, 0xd4, 0x90, 0x60, 0xa0, 0x37, 0x59, 0x04, 0x65, 0xa6,
        0xb5, 0x12, 0x00, 0xc3, 0x04, 0x51, 0xa7, 0x83, 0x96, 0x62, 0x3d, 0x49,
        0x97, 0xe8, 0x6b, 0x9a, 0x5d, 0x51, 0x24, 0xee, 0xad, 0x45, 0x18, 0x0f,
        0x3f, 0x97, 0xec, 0xdf, 0xcf, 0x42, 0x8a, 0x96, 0xc7, 0xd8, 0x82, 0x87,
        0x7f, 0x57, 0x70, 0x22, 0xfb, 0x29, 0x3e, 0x3c, 0xa3, 0xc1, 0xd5, 0x71,
        0xb3, 0x84, 0x06, 0x53, 0xa3, 0x86, 0x20, 0x35, 0xe3, 0x41, 0xb9, 0xd8,
        0x00, 0x22, 0x4f, 0x6d, 0xe6, 0xfd, 0xf0, 0xf4, 0xa2, 0x39, 0x0a, 0x1a,
        0x23, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x30, 0x30, 0x2e, 0x30, 0x0d,
        0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x06, 0x30, 0x04, 0x82, 0x02, 0x61,
        0x2a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
        0x45, 0x05, 0xf3, 0x4d, 0x3e, 0x7e, 0x9c, 0xf5, 0x08, 0xee, 0x2c, 0x13,
        0x32, 0xe3, 0xf2, 0x14, 0xe8, 0x0e, 0x71, 0x21, 0x30, 0x0d, 0x06, 0x09,
        0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
        0x82, 0x01, 0x01, 0x00, 0xa8, 0x28, 0xe5, 0x22, 0x65, 0xcf, 0x47, 0xfe,
        0x82, 0x17, 0x99, 0x20, 0xdb, 0xb1, 0x57, 0xd4, 0x91, 0x1a, 0x83, 0xde,
        0xc1, 0xaf, 0xc4, 0x1f, 0xfb, 0xa4, 0x6a, 0xad, 0xdc, 0x58, 0x72, 0xd9,
        0x9b, 0xab, 0xa5, 0xbb, 0xf4, 0x98, 0xd4, 0xdf, 0x36, 0xcb, 0xb5, 0x78,
        0xce, 0x4b, 0x25, 0x5b, 0x24, 0x92, 0xfe, 0xe8, 0xd4, 0xe4, 0xbd, 0x6f,
        0x71, 0x1a, 0x81, 0x2a, 0x6f, 0x35, 0x93, 0xf7, 0xcc, 0xed, 0xe5, 0x06,
        0xd2, 0x96, 0x41, 0xb5, 0xa9, 0x8a, 0xc0, 0xc9, 0x17, 0xe3, 0x13, 0x5e,
        0x94, 0x5e, 0xfa, 0xfc, 0xf0, 0x00, 0x2e, 0xe1, 0xd8, 0x1b, 0x23, 0x3f,
        0x7c, 0x4d, 0x9f, 0xfb, 0xb7, 0x95, 0xc1, 0x94, 0x7f, 0x7f, 0xb5, 0x4f,
        0x93, 0x6d, 0xc3, 0x2b, 0xb2, 0x28, 0x36, 0xd2, 0x7c, 0x01, 0x3c, 0xae,
        0x35, 0xdb, 0xc8, 0x95, 0x1b, 0x5f, 0x6c, 0x0f, 0x57, 0xb3, 0xcc, 0x97,
        0x98, 0x80, 0x06, 0xaa, 0xe4, 0x93, 0x1f, 0xb7, 0xa0, 0x54, 0xf1, 0x4f,
        0x6f, 0x11, 0xdf, 0xab, 0xd3, 0xbf, 0xf0, 0x3a, 0x81, 0x60, 0xaf, 0x7a,
        0xf7, 0x09, 0xd5, 0xae, 0x0c, 0x7d, 0xae, 0x8d, 0x47, 0x06, 0xbe, 0x11,
        0x6e, 0xf8, 0x7e, 0x49, 0xf8, 0xac, 0x24, 0x0a, 0x4b, 0xc2, 0xf6, 0xe8,
        0x2c, 0xec, 0x35, 0xef, 0xa9, 0x13, 0xb8, 0xd2, 0x9c, 0x92, 0x61, 0x91,
        0xec, 0x7b, 0x0c, 0xea, 0x9a, 0x71, 0x36, 0x15, 0x34, 0x2b, 0x7a, 0x25,
        0xac, 0xfe, 0xc7, 0x26, 0x89, 0x70, 0x3e, 0x64, 0x68, 0x97, 0x4b, 0xaa,
        0xc1, 0x24, 0x14, 0xbd, 0x45, 0x2f, 0xe0, 0xfe, 0xf4, 0x2b, 0x8e, 0x08,
        0x3e, 0xe4, 0xb5, 0x3d, 0x5d, 0xf4, 0xc3, 0xd6, 0x9c, 0xb5, 0x33, 0x1b,
        0x3b, 0xda, 0x6e, 0x99, 0x7b, 0x09, 0xd1, 0x30, 0x97, 0x23, 0x52, 0x6d,
        0x1b, 0x71, 0x3a, 0xf4, 0x54, 0xf0, 0xe5, 0x9e
        };

    WOLFSSL_X509* x509 = NULL;
    int certSize = (int)(sizeof(cert_der) / sizeof(unsigned char));
    const char *name1 = "aaaaa";
    int nameLen1 = (int)(XSTRLEN(name1));
    const char *name2 = "a";
    int nameLen2 = (int)(XSTRLEN(name2));
    const char *name3 = "abbbb";
    int nameLen3 = (int)(XSTRLEN(name3));
    const char *name4 = "bbb";
    int nameLen4 = (int)(XSTRLEN(name4));

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_buffer(
        cert_der, certSize, WOLFSSL_FILETYPE_ASN1));

    /* Ensure that "a*" matches "aaaaa" */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name1, nameLen1,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Ensure that "a*" matches "a" */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name2, nameLen2,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Ensure that "a*" matches "abbbb" */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name3, nameLen3,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Ensure that "a*" does not match "bbb" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name4, nameLen4,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), 1);

    /* WOLFSSL_LEFT_MOST_WILDCARD_ONLY flag should fail on all cases, since
     * 'a*' alt name does not have wildcard left-most */

    /* Ensure that "a*" does not match "aaaaa" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name1, nameLen1,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_SUCCESS);
    /* Ensure that "a*" does not match "a" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name2, nameLen2,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_SUCCESS);
    /* Ensure that "a*" does not match "abbbb" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name3, nameLen3,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_SUCCESS);
    /* Ensure that "a*" does not match "bbb" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name4, nameLen4,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_SUCCESS);

    wolfSSL_X509_free(x509);

#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_name_match2(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA)
    /* A certificate with the subject alternative name a*b* */
    const unsigned char cert_der[] = {
        0x30, 0x82, 0x03, 0xae, 0x30, 0x82, 0x02, 0x96, 0xa0, 0x03, 0x02, 0x01,
        0x02, 0x02, 0x14, 0x41, 0x8c, 0x8b, 0xaa, 0x0e, 0xd8, 0x5a, 0xc0, 0x52,
        0x46, 0x0e, 0xe5, 0xd8, 0xb9, 0x48, 0x93, 0x7e, 0x8a, 0x7c, 0x65, 0x30,
        0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
        0x05, 0x00, 0x30, 0x77, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
        0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
        0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31,
        0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f,
        0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
        0x04, 0x0a, 0x0c, 0x0b, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20,
        0x49, 0x6e, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
        0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e,
        0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f,
        0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e,
        0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x35, 0x33,
        0x30, 0x32, 0x30, 0x34, 0x33, 0x34, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x34,
        0x30, 0x35, 0x32, 0x38, 0x32, 0x30, 0x34, 0x33, 0x34, 0x30, 0x5a, 0x30,
        0x77, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
        0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
        0x07, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e,
        0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d,
        0x61, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
        0x0b, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x49, 0x6e, 0x63,
        0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45,
        0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18,
        0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, 0x77,
        0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d,
        0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
        0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
        0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa5, 0x60, 0x80,
        0xf3, 0xee, 0x19, 0xd2, 0xe4, 0x15, 0x94, 0x54, 0x12, 0x88, 0xee, 0xda,
        0x11, 0x11, 0x87, 0x99, 0x88, 0xb3, 0x71, 0xc7, 0x97, 0x78, 0x1b, 0x57,
        0x37, 0x1d, 0x0b, 0x1f, 0x2f, 0x2c, 0x35, 0x13, 0x75, 0xd3, 0x31, 0x3e,
        0x6f, 0x80, 0x21, 0xa5, 0xa3, 0xad, 0x10, 0x81, 0xb6, 0x37, 0xd4, 0x55,
        0x2e, 0xc1, 0xb8, 0x37, 0xa3, 0x3c, 0xe8, 0x81, 0x03, 0x3c, 0xda, 0x5f,
        0x6f, 0x45, 0x32, 0x2b, 0x0e, 0x99, 0x27, 0xfd, 0xe5, 0x6c, 0x07, 0xd9,
        0x4e, 0x0a, 0x8b, 0x23, 0x74, 0x96, 0x25, 0x97, 0xae, 0x6d, 0x19, 0xba,
        0xbf, 0x0f, 0xc8, 0xa1, 0xe5, 0xea, 0xa8, 0x00, 0x09, 0xc3, 0x9a, 0xef,
        0x09, 0x33, 0xc1, 0x33, 0x2e, 0x7b, 0x6d, 0xa7, 0x66, 0x87, 0xb6, 0x3a,
        0xb9, 0xdb, 0x4c, 0x5e, 0xb5, 0x55, 0x69, 0x37, 0x17, 0x92, 0x1f, 0xe3,
        0x53, 0x1a, 0x2d, 0x25, 0xd0, 0xcf, 0x72, 0x37, 0xc2, 0x89, 0x83, 0x78,
        0xcf, 0xac, 0x2e, 0x46, 0x92, 0x5c, 0x4a, 0xba, 0x7d, 0xa0, 0x22, 0x34,
        0xb1, 0x22, 0x26, 0x99, 0xda, 0xe8, 0x97, 0xe2, 0x0c, 0xd3, 0xbc, 0x97,
        0x7e, 0xa8, 0xb9, 0xe3, 0xe2, 0x7f, 0x56, 0xef, 0x22, 0xee, 0x15, 0x95,
        0xa6, 0xd1, 0xf4, 0xa7, 0xac, 0x4a, 0xab, 0xc1, 0x1a, 0xda, 0xc5, 0x5f,
        0xa5, 0x5e, 0x2f, 0x15, 0x9c, 0x36, 0xbe, 0xd3, 0x47, 0xb6, 0x86, 0xb9,
        0xc6, 0x59, 0x39, 0x36, 0xad, 0x84, 0x53, 0x95, 0x72, 0x91, 0x89, 0x51,
        0x32, 0x77, 0xf1, 0xa5, 0x93, 0xfe, 0xf0, 0x41, 0x7c, 0x64, 0xf1, 0xb0,
        0x8b, 0x81, 0x8d, 0x3a, 0x2c, 0x9e, 0xbe, 0x2e, 0x8b, 0xf7, 0x80, 0x63,
        0x35, 0x32, 0xfa, 0x26, 0xe0, 0x63, 0xbf, 0x5e, 0xaf, 0xf0, 0x08, 0xe0,
        0x80, 0x65, 0x38, 0xfa, 0x21, 0xaa, 0x91, 0x34, 0x48, 0x3d, 0x32, 0x5c,
        0xbf, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x32, 0x30, 0x30, 0x30, 0x0f,
        0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x08, 0x30, 0x06, 0x82, 0x04, 0x61,
        0x2a, 0x62, 0x2a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
        0x04, 0x14, 0x3d, 0x55, 0x74, 0xf8, 0x3a, 0x26, 0x03, 0x8c, 0x6a, 0x2e,
        0x91, 0x0e, 0x18, 0x70, 0xb4, 0xa4, 0xcc, 0x04, 0x00, 0xd3, 0x30, 0x0d,
        0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
        0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8f, 0x3b, 0xff, 0x46, 0x0c, 0xb5,
        0x21, 0xdc, 0xcf, 0x61, 0x9a, 0x25, 0x93, 0x99, 0x68, 0x2f, 0x16, 0x71,
        0x15, 0x00, 0x5f, 0xb0, 0x9b, 0x43, 0x5c, 0x47, 0xe2, 0x8e, 0xc8, 0xea,
        0xb3, 0x30, 0x4d, 0x87, 0x90, 0xcf, 0x24, 0x37, 0x5c, 0xfd, 0xc8, 0xc6,
        0x09, 0x36, 0xb2, 0xfb, 0xfd, 0xc1, 0x82, 0x92, 0x77, 0x5b, 0x9d, 0xeb,
        0xac, 0x47, 0xbc, 0xda, 0x7c, 0x89, 0x19, 0x03, 0x9e, 0xcd, 0x96, 0x2a,
        0x90, 0x55, 0x23, 0x19, 0xac, 0x9d, 0x49, 0xfb, 0xa0, 0x31, 0x7d, 0x6b,
        0x1a, 0x16, 0x13, 0xb1, 0xa9, 0xc9, 0xc4, 0xaf, 0xf1, 0xb4, 0xa7, 0x9b,
        0x08, 0x64, 0x6a, 0x09, 0xcd, 0x4a, 0x03, 0x4c, 0x93, 0xb6, 0xcf, 0x29,
        0xdb, 0x56, 0x88, 0x8e, 0xed, 0x08, 0x6d, 0x8d, 0x76, 0xa3, 0xd7, 0xc6,
        0x69, 0xa1, 0xf5, 0xd2, 0xd0, 0x0a, 0x4b, 0xfa, 0x88, 0x66, 0x6c, 0xe5,
        0x4a, 0xee, 0x13, 0xad, 0xad, 0x22, 0x25, 0x73, 0x39, 0x56, 0x74, 0x0e,
        0xda, 0xcd, 0x35, 0x67, 0xe3, 0x81, 0x5c, 0xc5, 0xae, 0x3c, 0x4f, 0x47,
        0x3e, 0x97, 0xde, 0xac, 0xf6, 0xe1, 0x26, 0xe2, 0xe0, 0x66, 0x48, 0x20,
        0x7c, 0x02, 0x81, 0x3e, 0x7d, 0x34, 0xb7, 0x73, 0x3e, 0x2e, 0xd6, 0x20,
        0x1c, 0xdf, 0xf1, 0xae, 0x86, 0x8b, 0xb2, 0xc2, 0x9b, 0x68, 0x9c, 0xf6,
        0x1a, 0x5e, 0x30, 0x06, 0x39, 0x0a, 0x1f, 0x7b, 0xd7, 0x18, 0x4b, 0x06,
        0x9d, 0xff, 0x84, 0x57, 0xcc, 0x92, 0xad, 0x81, 0x0a, 0x19, 0x11, 0xc4,
        0xac, 0x59, 0x00, 0xe8, 0x5a, 0x70, 0x78, 0xd6, 0x9f, 0xe0, 0x82, 0x2a,
        0x1f, 0x09, 0x36, 0x1c, 0x52, 0x98, 0xf7, 0x95, 0x8f, 0xf9, 0x48, 0x4f,
        0x30, 0x52, 0xb5, 0xf3, 0x8d, 0x13, 0x93, 0x27, 0xbe, 0xb4, 0x75, 0x39,
        0x65, 0xc6, 0x48, 0x4e, 0x32, 0xd7, 0xf4, 0xc3, 0x26, 0x8d
        };

    WOLFSSL_X509* x509 = NULL;
    int certSize = (int)(sizeof(cert_der) / sizeof(unsigned char));
    const char *name1 = "ab";
    int nameLen1 = (int)(XSTRLEN(name1));
    const char *name2 = "acccbccc";
    int nameLen2 = (int)(XSTRLEN(name2));
    const char *name3 = "accb";
    int nameLen3 = (int)(XSTRLEN(name3));
    const char *name4 = "accda";
    int nameLen4 = (int)(XSTRLEN(name4));
    const char *name5 = "acc\0bcc";
    int nameLen5 = 7;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_buffer(
        cert_der, certSize, WOLFSSL_FILETYPE_ASN1));

    /* Ensure that "a*b*" matches "ab" */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name1, nameLen1,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Ensure that "a*b*" matches "acccbccc" */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name2, nameLen2,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Ensure that "a*b*" matches "accb" */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name3, nameLen3,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Ensure that "a*b*" does not match "accda" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name4, nameLen4,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);

    /* WOLFSSL_LEFT_MOST_WILDCARD_ONLY flag should fail on all cases, since
     * 'a*b*' alt name does not have wildcard left-most */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name1, nameLen1,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_FAILURE);
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name2, nameLen2,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_FAILURE);
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name3, nameLen3,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_FAILURE);
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name4, nameLen4,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_FAILURE);

    /* Ensure that "a*b*" matches "ab", testing openssl behavior replication
     * on check len input handling, 0 for len is OK as it should then use
     * strlen(name1) */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name1, 0,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Openssl also allows for len to include NULL terminator */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name1, nameLen1 + 1,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Ensure that check string with NULL terminator in middle is
     * rejected */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name5, nameLen5,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);

    wolfSSL_X509_free(x509);

#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_name_match3(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA)
    /* A certificate with the subject alternative name *.example.com */
    const unsigned char cert_der[] = {
        0x30, 0x82, 0x03, 0xb7, 0x30, 0x82, 0x02, 0x9f, 0xa0, 0x03, 0x02, 0x01,
        0x02, 0x02, 0x14, 0x59, 0xbb, 0xf6, 0xde, 0xb8, 0x3d, 0x0e, 0x8c, 0xe4,
        0xbd, 0x98, 0xa3, 0xbe, 0x3e, 0x8f, 0xdc, 0xbd, 0x7f, 0xcc, 0xae, 0x30,
        0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
        0x05, 0x00, 0x30, 0x77, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
        0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
        0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31,
        0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f,
        0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
        0x04, 0x0a, 0x0c, 0x0b, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20,
        0x49, 0x6e, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
        0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e,
        0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f,
        0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e,
        0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x35, 0x33,
        0x31, 0x30, 0x30, 0x33, 0x37, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x34,
        0x30, 0x35, 0x32, 0x39, 0x30, 0x30, 0x33, 0x37, 0x34, 0x39, 0x5a, 0x30,
        0x77, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
        0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
        0x07, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e,
        0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d,
        0x61, 0x6e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
        0x0b, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x49, 0x6e, 0x63,
        0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45,
        0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18,
        0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, 0x77,
        0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d,
        0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
        0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
        0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0x78, 0x16,
        0x05, 0x65, 0xf2, 0x85, 0xf2, 0x61, 0x7f, 0xb1, 0x4d, 0x73, 0xe2, 0x82,
        0xb5, 0x3d, 0xf7, 0x9d, 0x05, 0x65, 0xed, 0x9d, 0xc3, 0x29, 0x7a, 0x92,
        0x2c, 0x06, 0x5f, 0xc8, 0x13, 0x55, 0x42, 0x4e, 0xbd, 0xe2, 0x56, 0x2a,
        0x4b, 0xac, 0xe6, 0x1b, 0x10, 0xc9, 0xdb, 0x9a, 0x45, 0x36, 0xed, 0xf3,
        0x26, 0x8c, 0x22, 0x88, 0x1e, 0x6d, 0x2b, 0x41, 0xfa, 0x0d, 0x43, 0x88,
        0x88, 0xde, 0x8d, 0x2e, 0xca, 0x6e, 0x7c, 0x62, 0x66, 0x3e, 0xfa, 0x4e,
        0x71, 0xea, 0x7d, 0x3b, 0x32, 0x33, 0x5c, 0x7a, 0x7e, 0xea, 0x74, 0xbd,
        0xb6, 0x8f, 0x4c, 0x1c, 0x7a, 0x79, 0x94, 0xf1, 0xe8, 0x02, 0x67, 0x98,
        0x25, 0xb4, 0x31, 0x80, 0xc1, 0xae, 0xbf, 0xef, 0xf2, 0x6c, 0x78, 0x42,
        0xef, 0xb5, 0xc6, 0x01, 0x47, 0x79, 0x8d, 0x92, 0xce, 0xc1, 0xb5, 0x98,
        0x76, 0xf0, 0x84, 0xa2, 0x53, 0x90, 0xe5, 0x39, 0xc7, 0xbd, 0xf2, 0xbb,
        0xe3, 0x3f, 0x00, 0xf6, 0xf0, 0x46, 0x86, 0xee, 0x55, 0xbd, 0x2c, 0x1f,
        0x97, 0x24, 0x7c, 0xbc, 0xda, 0x2f, 0x1b, 0x53, 0xef, 0x26, 0x56, 0xcc,
        0xb7, 0xd8, 0xca, 0x17, 0x20, 0x4e, 0x62, 0x03, 0x66, 0x32, 0xb3, 0xd1,
        0x71, 0x26, 0x6c, 0xff, 0xd1, 0x9e, 0x44, 0x86, 0x2a, 0xae, 0xba, 0x43,
        0x00, 0x13, 0x7e, 0x50, 0xdd, 0x3e, 0x27, 0x39, 0x70, 0x1c, 0x0c, 0x0b,
        0xe8, 0xa2, 0xae, 0x03, 0x09, 0x2e, 0xd8, 0x71, 0xee, 0x7b, 0x1a, 0x09,
        0x2d, 0xe1, 0xd5, 0xde, 0xf5, 0xa3, 0x36, 0x77, 0x90, 0x97, 0x99, 0xd7,
        0x6c, 0xb7, 0x5c, 0x9d, 0xf7, 0x7e, 0x41, 0x89, 0xfe, 0xe4, 0x08, 0xc6,
        0x0b, 0xe4, 0x9b, 0x5f, 0x51, 0xa6, 0x08, 0xb8, 0x99, 0x81, 0xe9, 0xce,
        0xb4, 0x2d, 0xb2, 0x92, 0x9f, 0xe5, 0x1a, 0x98, 0x76, 0x20, 0x70, 0x54,
        0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x3b, 0x30, 0x39, 0x30, 0x18,
        0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x11, 0x30, 0x0f, 0x82, 0x0d, 0x2a,
        0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
        0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x60,
        0xd4, 0x26, 0xbb, 0xcc, 0x7c, 0x29, 0xa2, 0x88, 0x3c, 0x76, 0x7d, 0xb4,
        0x86, 0x8b, 0x47, 0x64, 0x5b, 0x87, 0xe0, 0x30, 0x0d, 0x06, 0x09, 0x2a,
        0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
        0x01, 0x01, 0x00, 0xc3, 0x0d, 0x03, 0x67, 0xbb, 0x47, 0x8b, 0xf3, 0x20,
        0xdc, 0x7d, 0x2e, 0xe1, 0xd9, 0xf0, 0x01, 0xc4, 0x66, 0xc2, 0xe1, 0xcd,
        0xc3, 0x4a, 0x72, 0xf0, 0x6e, 0x38, 0xcf, 0x63, 0x01, 0x96, 0x9e, 0x84,
        0xb9, 0xce, 0x1d, 0xba, 0x4b, 0xe0, 0x70, 0x86, 0x2b, 0x5a, 0xab, 0xec,
        0xbf, 0xc2, 0xaa, 0x64, 0xa2, 0x6c, 0xd2, 0x42, 0x52, 0xd4, 0xbe, 0x8a,
        0xca, 0x9c, 0x03, 0xf3, 0xd6, 0x5f, 0xcd, 0x23, 0x9f, 0xf5, 0xa9, 0x04,
        0x40, 0x5b, 0x66, 0x78, 0xc0, 0xac, 0xa1, 0xdb, 0x5d, 0xd1, 0x94, 0xfc,
        0x47, 0x94, 0xf5, 0x45, 0xe3, 0x70, 0x13, 0x3f, 0x66, 0x6d, 0xdd, 0x73,
        0x68, 0x68, 0xe2, 0xd2, 0x89, 0xcb, 0x7f, 0xc6, 0xca, 0xd6, 0x96, 0x0b,
        0xcc, 0xdd, 0xa1, 0x74, 0xda, 0x33, 0xe8, 0x9e, 0xda, 0xb7, 0xd9, 0x12,
        0xab, 0x85, 0x9d, 0x0c, 0xde, 0xa0, 0x7d, 0x7e, 0xa1, 0x91, 0xed, 0xe5,
        0x32, 0x7c, 0xc5, 0xea, 0x1d, 0x4a, 0xb5, 0x38, 0x63, 0x17, 0xf3, 0x4f,
        0x2c, 0x4a, 0x58, 0x86, 0x09, 0x33, 0x86, 0xc4, 0xe7, 0x56, 0x6f, 0x32,
        0x71, 0xb7, 0xd0, 0x83, 0x12, 0x9e, 0x26, 0x0a, 0x3a, 0x45, 0xcb, 0xd7,
        0x4e, 0xab, 0xa4, 0xc3, 0xee, 0x4c, 0xc0, 0x38, 0xa1, 0xfa, 0xba, 0xfa,
        0xb7, 0x80, 0x69, 0x67, 0xa3, 0xef, 0x89, 0xba, 0xce, 0x89, 0x91, 0x3d,
        0x6a, 0x76, 0xe9, 0x3b, 0x32, 0x86, 0x76, 0x85, 0x6b, 0x4f, 0x7f, 0xbc,
        0x7a, 0x5b, 0x31, 0x92, 0x79, 0x35, 0xf8, 0xb9, 0xb1, 0xd7, 0xdb, 0xa9,
        0x6a, 0x8a, 0x91, 0x60, 0x65, 0xd4, 0x76, 0x54, 0x55, 0x57, 0xb9, 0x35,
        0xe0, 0xf5, 0xbb, 0x8f, 0xd4, 0x40, 0x75, 0xbb, 0x47, 0xa8, 0xf9, 0x0f,
        0xea, 0xc9, 0x6e, 0x84, 0xd5, 0xf5, 0x58, 0x2d, 0xe5, 0x76, 0x7b, 0xdf,
        0x97, 0x05, 0x5e, 0xaf, 0x50, 0xf5, 0x48
        };

    WOLFSSL_X509* x509 = NULL;
    int certSize = (int)(sizeof(cert_der) / sizeof(unsigned char));
    const char *name1 = "foo.example.com";
    int nameLen1 = (int)(XSTRLEN(name1));
    const char *name2 = "x.y.example.com";
    int nameLen2 = (int)(XSTRLEN(name2));
    const char *name3 = "example.com";
    int nameLen3 = (int)(XSTRLEN(name3));

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_buffer(
        cert_der, certSize, WOLFSSL_FILETYPE_ASN1));

    /* Ensure that "*.example.com" matches "foo.example.com" */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name1, nameLen1,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Ensure that "*.example.com" does NOT match "x.y.example.com" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name2, nameLen2,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);
    /* Ensure that "*.example.com" does NOT match "example.com" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name3, nameLen3,
        WOLFSSL_ALWAYS_CHECK_SUBJECT, NULL), WOLFSSL_SUCCESS);

    /* WOLFSSL_LEFT_MOST_WILDCARD_ONLY, should match "foo.example.com" */
    ExpectIntEQ(wolfSSL_X509_check_host(x509, name1, nameLen1,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_SUCCESS);
    /* WOLFSSL_LEFT_MOST_WILDCARD_ONLY, should NOT  match "x.y.example.com" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name2, nameLen2,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_SUCCESS);
    /* WOLFSSL_LEFT_MOST_WILDCARD_ONLY, should NOT match "example.com" */
    ExpectIntNE(wolfSSL_X509_check_host(x509, name3, nameLen3,
        WOLFSSL_ALWAYS_CHECK_SUBJECT | WOLFSSL_LEFT_MOST_WILDCARD_ONLY,
        NULL), WOLFSSL_SUCCESS);

    wolfSSL_X509_free(x509);

#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_max_altnames(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA)

    /* Only test if max alt names has not been modified */
#if WOLFSSL_MAX_ALT_NAMES <= 1024

    WOLFSSL_CTX* ctx = NULL;
    /* File contains a certificate encoded with 130 subject alternative names */
    const char* over_max_altnames_cert = \
        "./certs/test/cert-over-max-altnames.pem";

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif

    ExpectIntNE(wolfSSL_CTX_load_verify_locations_ex(ctx,
            over_max_altnames_cert, NULL, WOLFSSL_LOAD_FLAG_NONE),
            WOLFSSL_SUCCESS);
    wolfSSL_CTX_free(ctx);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_max_name_constraints(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
    !defined(IGNORE_NAME_CONSTRAINTS)

    /* Only test if max name constraints has not been modified */
#if WOLFSSL_MAX_NAME_CONSTRAINTS == 128

    WOLFSSL_CTX* ctx = NULL;
    /* File contains a certificate with 130 name constraints */
    const char* over_max_nc = "./certs/test/cert-over-max-nc.pem";

#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif

    ExpectIntNE(wolfSSL_CTX_load_verify_locations_ex(ctx, over_max_nc,
            NULL, WOLFSSL_LOAD_FLAG_NONE), WOLFSSL_SUCCESS);
    wolfSSL_CTX_free(ctx);
#endif

#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA)
    X509* x509 = NULL;
#ifndef NO_BIO
    BIO*  bio = NULL;
    X509_STORE_CTX* ctx = NULL;
    X509_STORE* store = NULL;
#endif
    char der[] = "certs/ca-cert.der";
    XFILE fp = XBADFILE;

    ExpectNotNull(x509 = X509_new());
    X509_free(x509);
    x509 = NULL;

#ifndef NO_BIO
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
        SSL_FILETYPE_PEM));

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));

#ifdef WOLFSSL_CERT_GEN
    ExpectIntEQ(i2d_X509_bio(bio, x509), SSL_SUCCESS);
#endif

    ExpectNotNull(ctx = X509_STORE_CTX_new());

    ExpectIntEQ(X509_verify_cert(ctx), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));

    ExpectNotNull(store = X509_STORE_new());
    ExpectIntEQ(X509_STORE_add_cert(store, x509), SSL_SUCCESS);
    ExpectIntEQ(X509_STORE_CTX_init(ctx, store, x509, NULL), SSL_SUCCESS);
    ExpectIntEQ(X509_verify_cert(ctx), SSL_SUCCESS);


    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    X509_free(x509);
    x509 = NULL;
    BIO_free(bio);
#endif

    /** d2i_X509_fp test **/
    ExpectTrue((fp = XFOPEN(der, "rb")) != XBADFILE);
    ExpectNotNull(x509 = (X509 *)d2i_X509_fp(fp, (X509 **)NULL));
    ExpectNotNull(x509);
    X509_free(x509);
    x509 = NULL;
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }
    ExpectTrue((fp = XFOPEN(der, "rb")) != XBADFILE);
    ExpectNotNull((X509 *)d2i_X509_fp(fp, (X509 **)&x509));
    ExpectNotNull(x509);
    X509_free(x509);
    if (fp != XBADFILE)
        XFCLOSE(fp);

    /* X509_up_ref test */
    ExpectIntEQ(X509_up_ref(NULL), 0);
    ExpectNotNull(x509 = X509_new());   /* refCount = 1 */
    ExpectIntEQ(X509_up_ref(x509), 1);  /* refCount = 2 */
    ExpectIntEQ(X509_up_ref(x509), 1);  /* refCount = 3 */
    X509_free(x509); /* refCount = 2 */
    X509_free(x509); /* refCount = 1 */
    X509_free(x509); /* refCount = 0, free */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_get_ext_count(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA)
    int ret = 0;
    WOLFSSL_X509* x509 = NULL;
    const char ocspRootCaFile[] = "./certs/ocsp/root-ca-cert.pem";
    XFILE f = XBADFILE;

    /* NULL parameter check */
    ExpectIntEQ(X509_get_ext_count(NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(svrCertFile,
        SSL_FILETYPE_PEM));
    ExpectIntEQ(X509_get_ext_count(x509), 5);
    wolfSSL_X509_free(x509);

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(ocspRootCaFile,
        SSL_FILETYPE_PEM));
    ExpectIntEQ(X509_get_ext_count(x509), 5);
    wolfSSL_X509_free(x509);

    ExpectTrue((f = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL));
    if (f != XBADFILE)
        XFCLOSE(f);

    /* wolfSSL_X509_get_ext_count() valid input */
    ExpectIntEQ((ret = wolfSSL_X509_get_ext_count(x509)), 5);

    /* wolfSSL_X509_get_ext_count() NULL argument */
    ExpectIntEQ((ret = wolfSSL_X509_get_ext_count(NULL)), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_sign2(void)
{
    EXPECT_DECLS;
    /* test requires WOLFSSL_AKID_NAME to match expected output */
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_CERTS) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES) && \
    defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_AKID_NAME) && \
    (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || \
    defined(WOLFSSL_IP_ALT_NAME))
    WOLFSSL_X509 *x509 = NULL;
    WOLFSSL_X509 *ca = NULL;
    const unsigned char *der = NULL;
    const unsigned char *pt = NULL;
    WOLFSSL_EVP_PKEY  *priv = NULL;
    WOLFSSL_X509_NAME *name = NULL;
    int derSz;
#ifndef NO_ASN_TIME
    WOLFSSL_ASN1_TIME *notBefore = NULL;
    WOLFSSL_ASN1_TIME *notAfter = NULL;

    const int year = 365*24*60*60;
    const int day  = 24*60*60;
    const int hour = 60*60;
    const int mini = 60;
    time_t t;
#endif

    const unsigned char expected[] = {
        0x30, 0x82, 0x05, 0x13, 0x30, 0x82, 0x03, 0xFB, 0xA0, 0x03, 0x02, 0x01,
        0x02, 0x02, 0x14, 0x08, 0xB0, 0x54, 0x7A, 0x03, 0x5A, 0xEC, 0x55, 0x8A,
        0x12, 0xE8, 0xF9, 0x8E, 0x34, 0xB6, 0x13, 0xD9, 0x59, 0xB8, 0xE8, 0x30,
        0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B,
        0x05, 0x00, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
        0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03,
        0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61,
        0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42,
        0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03,
        0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74,
        0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0A,
        0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x31, 0x18,
        0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77,
        0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D,
        0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
        0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F,
        0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x1E, 0x17,
        0x0D, 0x30, 0x30, 0x30, 0x32, 0x31, 0x35, 0x32, 0x30, 0x33, 0x30, 0x30,
        0x30, 0x5A, 0x17, 0x0D, 0x30, 0x31, 0x30, 0x32, 0x31, 0x34, 0x32, 0x30,
        0x33, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x81, 0x9E, 0x31, 0x0B, 0x30, 0x09,
        0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30,
        0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74,
        0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07,
        0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x15, 0x30,
        0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x77, 0x6F, 0x6C, 0x66,
        0x53, 0x53, 0x4C, 0x5F, 0x32, 0x30, 0x34, 0x38, 0x31, 0x19, 0x30, 0x17,
        0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x50, 0x72, 0x6F, 0x67, 0x72,
        0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x2D, 0x32, 0x30, 0x34, 0x38, 0x31,
        0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77,
        0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F,
        0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
        0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77,
        0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x82,
        0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
        0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82,
        0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xC3, 0x03, 0xD1, 0x2B, 0xFE,
        0x39, 0xA4, 0x32, 0x45, 0x3B, 0x53, 0xC8, 0x84, 0x2B, 0x2A, 0x7C, 0x74,
        0x9A, 0xBD, 0xAA, 0x2A, 0x52, 0x07, 0x47, 0xD6, 0xA6, 0x36, 0xB2, 0x07,
        0x32, 0x8E, 0xD0, 0xBA, 0x69, 0x7B, 0xC6, 0xC3, 0x44, 0x9E, 0xD4, 0x81,
        0x48, 0xFD, 0x2D, 0x68, 0xA2, 0x8B, 0x67, 0xBB, 0xA1, 0x75, 0xC8, 0x36,
        0x2C, 0x4A, 0xD2, 0x1B, 0xF7, 0x8B, 0xBA, 0xCF, 0x0D, 0xF9, 0xEF, 0xEC,
        0xF1, 0x81, 0x1E, 0x7B, 0x9B, 0x03, 0x47, 0x9A, 0xBF, 0x65, 0xCC, 0x7F,
        0x65, 0x24, 0x69, 0xA6, 0xE8, 0x14, 0x89, 0x5B, 0xE4, 0x34, 0xF7, 0xC5,
        0xB0, 0x14, 0x93, 0xF5, 0x67, 0x7B, 0x3A, 0x7A, 0x78, 0xE1, 0x01, 0x56,
        0x56, 0x91, 0xA6, 0x13, 0x42, 0x8D, 0xD2, 0x3C, 0x40, 0x9C, 0x4C, 0xEF,
        0xD1, 0x86, 0xDF, 0x37, 0x51, 0x1B, 0x0C, 0xA1, 0x3B, 0xF5, 0xF1, 0xA3,
        0x4A, 0x35, 0xE4, 0xE1, 0xCE, 0x96, 0xDF, 0x1B, 0x7E, 0xBF, 0x4E, 0x97,
        0xD0, 0x10, 0xE8, 0xA8, 0x08, 0x30, 0x81, 0xAF, 0x20, 0x0B, 0x43, 0x14,
        0xC5, 0x74, 0x67, 0xB4, 0x32, 0x82, 0x6F, 0x8D, 0x86, 0xC2, 0x88, 0x40,
        0x99, 0x36, 0x83, 0xBA, 0x1E, 0x40, 0x72, 0x22, 0x17, 0xD7, 0x52, 0x65,
        0x24, 0x73, 0xB0, 0xCE, 0xEF, 0x19, 0xCD, 0xAE, 0xFF, 0x78, 0x6C, 0x7B,
        0xC0, 0x12, 0x03, 0xD4, 0x4E, 0x72, 0x0D, 0x50, 0x6D, 0x3B, 0xA3, 0x3B,
        0xA3, 0x99, 0x5E, 0x9D, 0xC8, 0xD9, 0x0C, 0x85, 0xB3, 0xD9, 0x8A, 0xD9,
        0x54, 0x26, 0xDB, 0x6D, 0xFA, 0xAC, 0xBB, 0xFF, 0x25, 0x4C, 0xC4, 0xD1,
        0x79, 0xF4, 0x71, 0xD3, 0x86, 0x40, 0x18, 0x13, 0xB0, 0x63, 0xB5, 0x72,
        0x4E, 0x30, 0xC4, 0x97, 0x84, 0x86, 0x2D, 0x56, 0x2F, 0xD7, 0x15, 0xF7,
        0x7F, 0xC0, 0xAE, 0xF5, 0xFC, 0x5B, 0xE5, 0xFB, 0xA1, 0xBA, 0xD3, 0x02,
        0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, 0x4F, 0x30, 0x82, 0x01, 0x4B,
        0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01,
        0x01, 0xFF, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x1D, 0x11, 0x04, 0x15, 0x30,
        0x13, 0x82, 0x0B, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2E, 0x63,
        0x6F, 0x6D, 0x87, 0x04, 0x7F, 0x00, 0x00, 0x01, 0x30, 0x1D, 0x06, 0x03,
        0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x33, 0xD8, 0x45, 0x66, 0xD7,
        0x68, 0x87, 0x18, 0x7E, 0x54, 0x0D, 0x70, 0x27, 0x91, 0xC7, 0x26, 0xD7,
        0x85, 0x65, 0xC0, 0x30, 0x81, 0xDE, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04,
        0x81, 0xD6, 0x30, 0x81, 0xD3, 0x80, 0x14, 0x33, 0xD8, 0x45, 0x66, 0xD7,
        0x68, 0x87, 0x18, 0x7E, 0x54, 0x0D, 0x70, 0x27, 0x91, 0xC7, 0x26, 0xD7,
        0x85, 0x65, 0xC0, 0xA1, 0x81, 0xA4, 0xA4, 0x81, 0xA1, 0x30, 0x81, 0x9E,
        0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
        0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07,
        0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06,
        0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61,
        0x6E, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C,
        0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53, 0x4C, 0x5F, 0x32, 0x30, 0x34, 0x38,
        0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x50,
        0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x2D, 0x32,
        0x30, 0x34, 0x38, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03,
        0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73,
        0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A,
        0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E,
        0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63,
        0x6F, 0x6D, 0x82, 0x14, 0x08, 0xB0, 0x54, 0x7A, 0x03, 0x5A, 0xEC, 0x55,
        0x8A, 0x12, 0xE8, 0xF9, 0x8E, 0x34, 0xB6, 0x13, 0xD9, 0x59, 0xB8, 0xE8,
        0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06,
        0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2B,
        0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0D, 0x06, 0x09, 0x2A,
        0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82,
        0x01, 0x01, 0x00, 0x14, 0xFB, 0xD0, 0xCE, 0x31, 0x7F, 0xA5, 0x59, 0xFA,
        0x7C, 0x68, 0x26, 0xA7, 0xE8, 0x0D, 0x9F, 0x50, 0x57, 0xFA, 0x1C, 0x7C,
        0x5E, 0x43, 0xA4, 0x97, 0x47, 0xB6, 0x41, 0xAC, 0x63, 0xD3, 0x61, 0x8C,
        0x1F, 0x42, 0xEF, 0x53, 0xD0, 0xBA, 0x31, 0x4D, 0x99, 0x74, 0xA4, 0x60,
        0xDC, 0xC6, 0x6F, 0xCC, 0x1E, 0x25, 0x98, 0xE1, 0xA4, 0xA0, 0x67, 0x69,
        0x97, 0xE3, 0x97, 0x7C, 0x83, 0x28, 0xF1, 0xF4, 0x7D, 0x03, 0xA8, 0x31,
        0x77, 0xCC, 0xD1, 0x37, 0xEF, 0x7B, 0x4A, 0x71, 0x2D, 0x11, 0x7E, 0x92,
        0xF5, 0x67, 0xB7, 0x56, 0xBA, 0x28, 0xF8, 0xD6, 0xCE, 0x2A, 0x71, 0xE3,
        0x70, 0x6B, 0x09, 0x0F, 0x67, 0x6F, 0x7A, 0xE0, 0x89, 0xF6, 0x5E, 0x23,
        0x0C, 0x0A, 0x44, 0x4E, 0x65, 0x8E, 0x7B, 0x68, 0xD0, 0xAD, 0x76, 0x3E,
        0x2A, 0x0E, 0xA2, 0x05, 0x11, 0x74, 0x24, 0x08, 0x60, 0xED, 0x9F, 0x98,
        0x18, 0xE9, 0x91, 0x58, 0x36, 0xEC, 0xEC, 0x25, 0x6B, 0xBA, 0x9C, 0x87,
        0x38, 0x68, 0xDC, 0xDC, 0x15, 0x6F, 0x20, 0x68, 0xC4, 0xBF, 0x05, 0x5B,
        0x4A, 0x0C, 0x44, 0x2B, 0x92, 0x3F, 0x10, 0x99, 0xDC, 0xF6, 0x6C, 0x0E,
        0x34, 0x26, 0x6E, 0x6D, 0x4E, 0x12, 0xBC, 0x60, 0x8F, 0x27, 0x1D, 0x7A,
        0x00, 0x50, 0xBE, 0x23, 0xDE, 0x48, 0x47, 0x9F, 0xAD, 0x2F, 0x94, 0x3D,
        0x16, 0x73, 0x48, 0x6B, 0xC8, 0x97, 0xE6, 0xB4, 0xB3, 0x4B, 0xE1, 0x68,
        0x08, 0xC3, 0xE5, 0x34, 0x5F, 0x9B, 0xDA, 0xAB, 0xCA, 0x6D, 0x55, 0x32,
        0xEF, 0x6C, 0xEF, 0x9B, 0x8B, 0x5B, 0xC7, 0xF0, 0xC2, 0x0F, 0x8E, 0x93,
        0x09, 0x60, 0x3C, 0x0B, 0xDC, 0xBD, 0xDB, 0x4A, 0x2D, 0xD0, 0x98, 0xAA,
        0xAB, 0x6C, 0x6F, 0x6D, 0x6B, 0x6A, 0x5C, 0x33, 0xAC, 0xAD, 0xA8, 0x1B,
        0x38, 0x5D, 0x9F, 0xDA, 0xE7, 0x70, 0x07
    };

    pt = ca_key_der_2048;
    ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, &pt,
        sizeof_ca_key_der_2048));

    pt = client_cert_der_2048;
    ExpectNotNull(x509 = wolfSSL_d2i_X509(NULL, &pt,
        sizeof_client_cert_der_2048));

    pt = ca_cert_der_2048;
    ExpectNotNull(ca = wolfSSL_d2i_X509(NULL, &pt, sizeof_ca_cert_der_2048));
    ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca));
    ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);

#ifndef NO_ASN_TIME
    t = (time_t)30 * year + 45 * day + 20 * hour + 30 * mini + 7 * day;
    ExpectNotNull(notBefore = wolfSSL_ASN1_TIME_adj(NULL, t, 0, 0));
    ExpectNotNull(notAfter = wolfSSL_ASN1_TIME_adj(NULL, t, 365, 0));
    ExpectIntEQ(notAfter->length, 13);

    ExpectTrue(wolfSSL_X509_set_notBefore(x509, notBefore));
    ExpectTrue(wolfSSL_X509_set_notAfter(x509, notAfter));
#endif

    ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0);
    ExpectNotNull((der = wolfSSL_X509_get_der(x509, &derSz)));

    ExpectIntEQ(derSz, sizeof(expected));
#ifndef NO_ASN_TIME
    ExpectIntEQ(XMEMCMP(der, expected, derSz), 0);
#endif

    wolfSSL_X509_free(ca);
    wolfSSL_X509_free(x509);
    wolfSSL_EVP_PKEY_free(priv);
#ifndef NO_ASN_TIME
    wolfSSL_ASN1_TIME_free(notBefore);
    wolfSSL_ASN1_TIME_free(notAfter);
#endif
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_X509_sign(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_ASN_TIME) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && !defined(NO_RSA)
    int ret = 0;
    char *cn = NULL;
    word32 cnSz = 0;
    X509_NAME *name = NULL;
    X509 *x509 = NULL;
    X509 *ca = NULL;
    DecodedCert dCert;
    EVP_PKEY *pub = NULL;
    EVP_PKEY *priv = NULL;
    EVP_MD_CTX *mctx = NULL;
#if defined(USE_CERT_BUFFERS_1024)
    const unsigned char* rsaPriv = client_key_der_1024;
    const unsigned char* rsaPub = client_keypub_der_1024;
    const unsigned char* certIssuer = client_cert_der_1024;
    long clientKeySz = (long)sizeof_client_key_der_1024;
    long clientPubKeySz = (long)sizeof_client_keypub_der_1024;
    long certIssuerSz = (long)sizeof_client_cert_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
    const unsigned char* rsaPriv = client_key_der_2048;
    const unsigned char* rsaPub = client_keypub_der_2048;
    const unsigned char* certIssuer = client_cert_der_2048;
    long clientKeySz = (long)sizeof_client_key_der_2048;
    long clientPubKeySz = (long)sizeof_client_keypub_der_2048;
    long certIssuerSz = (long)sizeof_client_cert_der_2048;
#endif
    byte sn[16];
    int snSz = sizeof(sn);

    /* Set X509_NAME fields */
    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8,
                                       (byte*)"US", 2, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                             (byte*)"wolfssl.com", 11, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
                     (byte*)"support@wolfssl.com", 19, -1, 0), SSL_SUCCESS);

    /* Get private and public keys */
    ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, &rsaPriv,
                                                                  clientKeySz));
    ExpectNotNull(pub = wolfSSL_d2i_PUBKEY(NULL, &rsaPub, clientPubKeySz));
    ExpectNotNull(x509 = X509_new());
    /* Set version 3 */
    ExpectIntNE(X509_set_version(x509, 2L), 0);
    /* Set subject name, add pubkey, and sign certificate */
    ExpectIntEQ(X509_set_subject_name(x509, name), SSL_SUCCESS);
    X509_NAME_free(name);
    name = NULL;
    ExpectIntEQ(X509_set_pubkey(x509, pub), SSL_SUCCESS);
#ifdef WOLFSSL_ALT_NAMES
    /* Add some subject alt names */
    ExpectIntNE(wolfSSL_X509_add_altname(NULL,
                "ipsum", ASN_DNS_TYPE), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_add_altname(x509,
                NULL, ASN_DNS_TYPE), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_add_altname(x509,
                "sphygmomanometer",
                ASN_DNS_TYPE), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_add_altname(x509,
                "supercalifragilisticexpialidocious",
                ASN_DNS_TYPE), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_X509_add_altname(x509,
                "Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch",
                ASN_DNS_TYPE), SSL_SUCCESS);
#ifdef WOLFSSL_IP_ALT_NAME
    {
        unsigned char ip4_type[] = {127,128,0,255};
        unsigned char ip6_type[] = {0xdd, 0xcc, 0xba, 0xab,
                                    0xff, 0xee, 0x99, 0x88,
                                    0x77, 0x66, 0x55, 0x44,
                                    0x00, 0x33, 0x22, 0x11};
        ExpectIntEQ(wolfSSL_X509_add_altname_ex(x509, (char*)ip4_type,
                sizeof(ip4_type), ASN_IP_TYPE), SSL_SUCCESS);
        ExpectIntEQ(wolfSSL_X509_add_altname_ex(x509, (char*)ip6_type,
                sizeof(ip6_type), ASN_IP_TYPE), SSL_SUCCESS);
    }
#endif
#endif /* WOLFSSL_ALT_NAMES */

    {
        ASN1_UTCTIME* infinite_past = NULL;
        ExpectNotNull(infinite_past = ASN1_UTCTIME_set(NULL, 0));
        ExpectIntEQ(X509_set1_notBefore(x509, infinite_past), 1);
        ASN1_UTCTIME_free(infinite_past);
    }

    /* test valid sign case */
    ExpectIntGT(ret = X509_sign(x509, priv, EVP_sha256()), 0);

    /* test valid X509_sign_ctx case */
    ExpectNotNull(mctx = EVP_MD_CTX_new());
    ExpectIntEQ(EVP_DigestSignInit(mctx, NULL, EVP_sha256(), NULL, priv), 1);
    ExpectIntGT(X509_sign_ctx(x509, mctx), 0);

#if defined(OPENSSL_ALL) && defined(WOLFSSL_ALT_NAMES)
    ExpectIntEQ(X509_get_ext_count(x509), 1);
#endif
#if defined(WOLFSSL_ALT_NAMES) && defined(WOLFSSL_IP_ALT_NAME)
    ExpectIntEQ(wolfSSL_X509_check_ip_asc(x509, "127.128.0.255", 0), 1);
    ExpectIntEQ(wolfSSL_X509_check_ip_asc(x509, "DDCC:BAAB:FFEE:9988:7766:5544:0033:2211", 0), 1);
#endif

    ExpectIntEQ(wolfSSL_X509_get_serial_number(x509, sn, &snSz),
                WOLFSSL_SUCCESS);
    DEBUG_WRITE_CERT_X509(x509, "signed.pem");

    /* Variation in size depends on ASN.1 encoding when MSB is set.
     * WOLFSSL_ASN_TEMPLATE code does not generate a serial number
     * with the MSB set. See GenerateInteger in asn.c */
#ifndef USE_CERT_BUFFERS_1024
#ifndef WOLFSSL_ALT_NAMES
    /* Valid case - size should be 781-786 with 16 byte serial number */
    ExpectTrue((781 + snSz <= ret) && (ret <= 781 + 5 + snSz));
#elif defined(WOLFSSL_IP_ALT_NAME)
    /* Valid case - size should be 955-960 with 16 byte serial number */
    ExpectTrue((939 + snSz <= ret) && (ret <= 939 + 5 + snSz));
#else
    /* Valid case - size should be 926-931 with 16 byte serial number */
    ExpectTrue((910 + snSz <= ret) && (ret <= 910 + 5 + snSz));
#endif
#else
#ifndef WOLFSSL_ALT_NAMES
    /* Valid case - size should be 537-542 with 16 byte serial number */
    ExpectTrue((521 + snSz <= ret) && (ret <= 521 + 5 + snSz));
#elif defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
    /* Valid case - size should be 695-670 with 16 byte serial number */
    ExpectTrue((679 + snSz <= ret) && (ret <= 679 + 5 + snSz));
#else
    /* Valid case - size should be 666-671 with 16 byte serial number */
    ExpectTrue((650 + snSz <= ret) && (ret <= 650 + 5 + snSz));
#endif
#endif
    /* check that issuer name is as expected after signature */
    InitDecodedCert(&dCert, certIssuer, (word32)certIssuerSz, 0);
    ExpectIntEQ(ParseCert(&dCert, CERT_TYPE, NO_VERIFY, NULL), 0);

    ExpectNotNull(ca = d2i_X509(NULL, &certIssuer, (int)certIssuerSz));
    ExpectNotNull(name = X509_get_subject_name(ca));
    cnSz = X509_NAME_get_sz(name);
    ExpectNotNull(cn = (char*)XMALLOC(cnSz, HEAP_HINT, DYNAMIC_TYPE_OPENSSL));
    ExpectNotNull(cn = X509_NAME_oneline(name, cn, (int)cnSz));
    ExpectIntEQ(0, XSTRNCMP(cn, dCert.subject, XSTRLEN(cn)));
    XFREE(cn, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
    cn = NULL;

#ifdef WOLFSSL_MULTI_ATTRIB
    /* test adding multiple OU's to the signer */
    ExpectNotNull(name = X509_get_subject_name(ca));
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_UTF8,
                                       (byte*)"OU1", 3, -1, 0), SSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_UTF8,
                                       (byte*)"OU2", 3, -1, 0), SSL_SUCCESS);
    ExpectIntGT(X509_sign(ca, priv, EVP_sha256()), 0);
#endif

    ExpectNotNull(name = X509_get_subject_name(ca));
    ExpectIntEQ(X509_set_issuer_name(x509, name), SSL_SUCCESS);

    ExpectIntGT(X509_sign(x509, priv, EVP_sha256()), 0);
    ExpectNotNull(name = X509_get_issuer_name(x509));
    cnSz = X509_NAME_get_sz(name);
    ExpectNotNull(cn = (char*)XMALLOC(cnSz, HEAP_HINT, DYNAMIC_TYPE_OPENSSL));
    ExpectNotNull(cn = X509_NAME_oneline(name, cn, (int)cnSz));
    /* compare and don't include the multi-attrib "/OU=OU1/OU=OU2" above */
    ExpectIntEQ(0, XSTRNCMP(cn, dCert.issuer, XSTRLEN(dCert.issuer)));
    XFREE(cn, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
    cn = NULL;

    FreeDecodedCert(&dCert);

    /* Test invalid parameters */
    ExpectIntEQ(X509_sign(NULL, priv, EVP_sha256()), 0);
    ExpectIntEQ(X509_sign(x509, NULL, EVP_sha256()), 0);
    ExpectIntEQ(X509_sign(x509, priv, NULL), 0);

    ExpectIntEQ(X509_sign_ctx(NULL, mctx), 0);
    EVP_MD_CTX_free(mctx);
    mctx = NULL;
    ExpectNotNull(mctx = EVP_MD_CTX_new());
    ExpectIntEQ(X509_sign_ctx(x509, mctx), 0);
    ExpectIntEQ(X509_sign_ctx(x509, NULL), 0);

    /* test invalid version number */
#if defined(OPENSSL_ALL)
    ExpectIntNE(X509_set_version(x509, 6L), 0);
    ExpectIntGT(X509_sign(x509, priv, EVP_sha256()), 0);

    /* uses ParseCert which fails on bad version number */
    ExpectIntEQ(X509_get_ext_count(x509), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif

    EVP_MD_CTX_free(mctx);
    EVP_PKEY_free(priv);
    EVP_PKEY_free(pub);
    X509_free(x509);
    X509_free(ca);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_get0_tbs_sigalg(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD))
    X509* x509 = NULL;
    const X509_ALGOR* alg;

    ExpectNotNull(x509 = X509_new());

    ExpectNull(alg = X509_get0_tbs_sigalg(NULL));
    ExpectNotNull(alg = X509_get0_tbs_sigalg(x509));

    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_ALGOR_get0(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && \
    !defined(NO_SHA256) && !defined(NO_RSA)
    X509* x509 = NULL;
    const ASN1_OBJECT* obj = NULL;
    const X509_ALGOR* alg = NULL;
    X509_ALGOR* alg2 = NULL;
    int pptype = 0;
    const void *ppval = NULL;
    byte* der = NULL;
    const byte* tmp = NULL;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
        SSL_FILETYPE_PEM));
    ExpectNotNull(alg = X509_get0_tbs_sigalg(x509));

    /* Invalid case */
    X509_ALGOR_get0(&obj, NULL, NULL, NULL);
    ExpectNull(obj);

    /* Valid case */
    X509_ALGOR_get0(&obj, &pptype, &ppval, alg);
    ExpectNotNull(obj);
    ExpectNull(ppval);
    ExpectIntNE(pptype, 0);
    /* Make sure NID of X509_ALGOR is Sha256 with RSA */
    ExpectIntEQ(OBJ_obj2nid(obj), NID_sha256WithRSAEncryption);

    ExpectIntEQ(i2d_X509_ALGOR(alg, &der), 15);
    tmp = der;
    ExpectNotNull(d2i_X509_ALGOR(&alg2, &tmp, 15));

    XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
    X509_free(x509);
    X509_ALGOR_free(alg2);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_X509_VERIFY_PARAM(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    X509_VERIFY_PARAM *paramTo = NULL;
    X509_VERIFY_PARAM *paramFrom = NULL;
    char testIPv4[] = "127.0.0.1";
    char testIPv6[] = "0001:0000:0000:0000:0000:0000:0000:0000/32";
    char testhostName1[] = "foo.hoge.com";
    char testhostName2[] = "foobar.hoge.com";

    ExpectNotNull(paramTo = X509_VERIFY_PARAM_new());
    ExpectNotNull(XMEMSET(paramTo, 0, sizeof(X509_VERIFY_PARAM)));

    ExpectNotNull(paramFrom = X509_VERIFY_PARAM_new());
    ExpectNotNull(XMEMSET(paramFrom, 0, sizeof(X509_VERIFY_PARAM)));

    ExpectIntEQ(X509_VERIFY_PARAM_set1_host(paramFrom, testhostName1,
        (int)XSTRLEN(testhostName1)), 1);
    ExpectIntEQ(0, XSTRNCMP(paramFrom->hostName, testhostName1,
        (int)XSTRLEN(testhostName1)));

    X509_VERIFY_PARAM_set_hostflags(NULL, 0x00);

    X509_VERIFY_PARAM_set_hostflags(paramFrom, 0x01);
    ExpectIntEQ(0x01, paramFrom->hostFlags);

    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip_asc(NULL, testIPv4), 0);

    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip_asc(paramFrom, testIPv4), 1);
    ExpectIntEQ(0, XSTRNCMP(paramFrom->ipasc, testIPv4, WOLFSSL_MAX_IPSTR));

    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip_asc(paramFrom, NULL), 1);

    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip_asc(paramFrom, testIPv6), 1);
    ExpectIntEQ(0, XSTRNCMP(paramFrom->ipasc, testIPv6, WOLFSSL_MAX_IPSTR));

    /* null pointer */
    ExpectIntEQ(X509_VERIFY_PARAM_set1(NULL, paramFrom), 0);
    /* in the case of "from" null, returns success */
    ExpectIntEQ(X509_VERIFY_PARAM_set1(paramTo, NULL), 1);

    ExpectIntEQ(X509_VERIFY_PARAM_set1(NULL, NULL), 0);

    /* inherit flags test : VPARAM_DEFAULT */
    ExpectIntEQ(X509_VERIFY_PARAM_set1(paramTo, paramFrom), 1);
    ExpectIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1,
                                    (int)XSTRLEN(testhostName1)));
    ExpectIntEQ(0x01, paramTo->hostFlags);
    ExpectIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv6, WOLFSSL_MAX_IPSTR));

    /* inherit flags test : VPARAM OVERWRITE */
    ExpectIntEQ(X509_VERIFY_PARAM_set1_host(paramTo, testhostName2,
        (int)XSTRLEN(testhostName2)), 1);
    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4), 1);
    X509_VERIFY_PARAM_set_hostflags(paramTo, 0x00);

    if (paramTo != NULL) {
        paramTo->inherit_flags = X509_VP_FLAG_OVERWRITE;
    }

    ExpectIntEQ(X509_VERIFY_PARAM_set1(paramTo, paramFrom), 1);
    ExpectIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1,
        (int)XSTRLEN(testhostName1)));
    ExpectIntEQ(0x01, paramTo->hostFlags);
    ExpectIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv6, WOLFSSL_MAX_IPSTR));

    /* inherit flags test : VPARAM_RESET_FLAGS */
    ExpectIntEQ(X509_VERIFY_PARAM_set1_host(paramTo, testhostName2,
        (int)XSTRLEN(testhostName2)), 1);
    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4), 1);
    X509_VERIFY_PARAM_set_hostflags(paramTo, 0x10);

    if (paramTo != NULL) {
        paramTo->inherit_flags = X509_VP_FLAG_RESET_FLAGS;
    }

    ExpectIntEQ(X509_VERIFY_PARAM_set1(paramTo, paramFrom), 1);
    ExpectIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1,
                                        (int)XSTRLEN(testhostName1)));
    ExpectIntEQ(0x01, paramTo->hostFlags);
    ExpectIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv6, WOLFSSL_MAX_IPSTR));

    /* inherit flags test : VPARAM_LOCKED */
    ExpectIntEQ(X509_VERIFY_PARAM_set1_host(paramTo, testhostName2,
        (int)XSTRLEN(testhostName2)), 1);
    ExpectIntEQ(X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4), 1);
    X509_VERIFY_PARAM_set_hostflags(paramTo, 0x00);

    if (paramTo != NULL) {
        paramTo->inherit_flags = X509_VP_FLAG_LOCKED;
    }

    ExpectIntEQ(X509_VERIFY_PARAM_set1(paramTo, paramFrom), 1);
    ExpectIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName2,
                                    (int)XSTRLEN(testhostName2)));
    ExpectIntEQ(0x00, paramTo->hostFlags);
    ExpectIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv4, WOLFSSL_MAX_IPSTR));

    /* test for incorrect parameters */
    ExpectIntEQ(X509_VERIFY_PARAM_set_flags(NULL, X509_V_FLAG_CRL_CHECK_ALL),
        0);

    ExpectIntEQ(X509_VERIFY_PARAM_set_flags(NULL, 0), 0);

    /* inherit flags test : VPARAM_ONCE, not testable yet */

    ExpectIntEQ(X509_VERIFY_PARAM_set_flags(paramTo, X509_V_FLAG_CRL_CHECK_ALL),
        1);

    ExpectIntEQ(X509_VERIFY_PARAM_get_flags(paramTo),
        X509_V_FLAG_CRL_CHECK_ALL);

    ExpectIntEQ(X509_VERIFY_PARAM_clear_flags(paramTo,
        X509_V_FLAG_CRL_CHECK_ALL), 1);

    ExpectIntEQ(X509_VERIFY_PARAM_get_flags(paramTo), 0);

    X509_VERIFY_PARAM_free(paramTo);
    X509_VERIFY_PARAM_free(paramFrom);
    X509_VERIFY_PARAM_free(NULL); /* to confirm NULL parameter gives no harm */
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    !defined(WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY)

static int test_wolfSSL_check_domain_verify_count = 0;

static WC_INLINE int test_wolfSSL_check_domain_verify_cb(int preverify,
        WOLFSSL_X509_STORE_CTX* store)
{
    EXPECT_DECLS;
    ExpectIntEQ(X509_STORE_CTX_get_error(store), 0);
    ExpectIntEQ(preverify, 1);
    ExpectIntGT(++test_wolfSSL_check_domain_verify_count, 0);
    return EXPECT_SUCCESS();
}

static int test_wolfSSL_check_domain_client_cb(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    X509_VERIFY_PARAM *param = NULL;

    ExpectNotNull(param = SSL_get0_param(ssl));

    /* Domain check should only be done on the leaf cert */
    X509_VERIFY_PARAM_set_hostflags(param,
        X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
    ExpectIntEQ(X509_VERIFY_PARAM_set1_host(param,
        "wolfSSL Server Chain", 0), 1);
    wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_PEER,
        test_wolfSSL_check_domain_verify_cb);
    return EXPECT_RESULT();
}

static int test_wolfSSL_check_domain_server_cb(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    /* Use a cert with different domains in chain */
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx,
        "certs/intermediate/server-chain.pem"), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

static int test_wolfSSL_check_domain(void)
{
    EXPECT_DECLS;
    test_ssl_cbf func_cb_client;
    test_ssl_cbf func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

    func_cb_client.ssl_ready = &test_wolfSSL_check_domain_client_cb;
    func_cb_server.ctx_ready = &test_wolfSSL_check_domain_server_cb;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
        &func_cb_server, NULL), TEST_SUCCESS);

    /* Should have been called once for each cert in sent chain */
#ifdef WOLFSSL_VERIFY_CB_ALL_CERTS
    ExpectIntEQ(test_wolfSSL_check_domain_verify_count, 3);
#else
    ExpectIntEQ(test_wolfSSL_check_domain_verify_count, 1);
#endif

    return EXPECT_RESULT();
}

#else

static int test_wolfSSL_check_domain(void)
{
    EXPECT_DECLS;
    return EXPECT_RESULT();
}

#endif /* OPENSSL_EXTRA && HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */

static int test_wolfSSL_X509_get_X509_PUBKEY(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD))
    X509* x509 = NULL;
    X509_PUBKEY* pubKey;

    ExpectNotNull(x509 = X509_new());

    ExpectNull(pubKey = wolfSSL_X509_get_X509_PUBKEY(NULL));
    ExpectNotNull(pubKey = wolfSSL_X509_get_X509_PUBKEY(x509));

    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_PUBKEY_RSA(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && \
    !defined(NO_SHA256) && !defined(NO_RSA)
    X509* x509 = NULL;
    ASN1_OBJECT* obj = NULL;
    const ASN1_OBJECT* pa_oid = NULL;
    X509_PUBKEY* pubKey = NULL;
    X509_PUBKEY* pubKey2 = NULL;
    EVP_PKEY* evpKey = NULL;

    const unsigned char *pk = NULL;
    int ppklen;
    int pptype;
    X509_ALGOR *pa = NULL;
    const void *pval;

    ExpectNotNull(x509 = X509_load_certificate_file(cliCertFile,
        SSL_FILETYPE_PEM));

    ExpectNotNull(pubKey = X509_get_X509_PUBKEY(x509));
    ExpectIntEQ(X509_PUBKEY_get0_param(&obj, &pk, &ppklen, &pa, pubKey), 1);
    ExpectNotNull(pk);
    ExpectNotNull(pa);
    ExpectNotNull(pubKey);
    ExpectIntGT(ppklen, 0);

    ExpectIntEQ(OBJ_obj2nid(obj), NID_rsaEncryption);

    ExpectNotNull(evpKey = X509_PUBKEY_get(pubKey));
    ExpectNotNull(pubKey2 = X509_PUBKEY_new());
    ExpectIntEQ(X509_PUBKEY_set(&pubKey2, evpKey), 1);
    ExpectIntEQ(X509_PUBKEY_get0_param(&obj, &pk, &ppklen, &pa, pubKey2), 1);
    ExpectNotNull(pk);
    ExpectNotNull(pa);
    ExpectIntGT(ppklen, 0);
    X509_ALGOR_get0(&pa_oid, &pptype, &pval, pa);
    ExpectNotNull(pa_oid);
    ExpectNull(pval);
    ExpectIntEQ(pptype, V_ASN1_NULL);
    ExpectIntEQ(OBJ_obj2nid(pa_oid), EVP_PKEY_RSA);

    X509_PUBKEY_free(pubKey2);
    X509_free(x509);
    EVP_PKEY_free(evpKey);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_PUBKEY_EC(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && defined(HAVE_ECC)
    X509* x509 = NULL;
    ASN1_OBJECT* obj = NULL;
    ASN1_OBJECT* poid = NULL;
    const ASN1_OBJECT* pa_oid = NULL;
    X509_PUBKEY* pubKey = NULL;
    X509_PUBKEY* pubKey2 = NULL;
    EVP_PKEY* evpKey = NULL;

    const unsigned char *pk = NULL;
    int ppklen;
    int pptype;
    X509_ALGOR *pa = NULL;
    const void *pval;
    char buf[50];

    ExpectNotNull(x509 = X509_load_certificate_file(cliEccCertFile,
                                                    SSL_FILETYPE_PEM));
    ExpectNotNull(pubKey = X509_get_X509_PUBKEY(x509));
    ExpectNotNull(evpKey = X509_PUBKEY_get(pubKey));
    ExpectNotNull(pubKey2 = X509_PUBKEY_new());
    ExpectIntEQ(X509_PUBKEY_set(&pubKey2, evpKey), 1);
    ExpectIntEQ(X509_PUBKEY_get0_param(&obj, &pk, &ppklen, &pa, pubKey2), 1);
    ExpectNotNull(pk);
    ExpectNotNull(pa);
    ExpectIntGT(ppklen, 0);
    X509_ALGOR_get0(&pa_oid, &pptype, &pval, pa);
    ExpectNotNull(pa_oid);
    ExpectNotNull(pval);
    ExpectIntEQ(pptype, V_ASN1_OBJECT);
    ExpectIntEQ(OBJ_obj2nid(pa_oid), EVP_PKEY_EC);
    poid = (ASN1_OBJECT *)pval;
    ExpectIntGT(OBJ_obj2txt(buf, (int)sizeof(buf), poid, 0), 0);
    ExpectIntEQ(OBJ_txt2nid(buf), NID_X9_62_prime256v1);

    X509_PUBKEY_free(pubKey2);
    X509_free(x509);
    EVP_PKEY_free(evpKey);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_PUBKEY_DSA(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && !defined(NO_DSA)
    word32  bytes;
#ifdef USE_CERT_BUFFERS_1024
    byte    tmp[ONEK_BUF];
#elif defined(USE_CERT_BUFFERS_2048)
    byte    tmp[TWOK_BUF];
#else
    byte    tmp[TWOK_BUF];
#endif /* END USE_CERT_BUFFERS_1024 */
    const unsigned char* dsaKeyDer = tmp;

    ASN1_OBJECT* obj = NULL;
    ASN1_STRING* str;
    const ASN1_OBJECT* pa_oid = NULL;
    X509_PUBKEY* pubKey = NULL;
    EVP_PKEY* evpKey = NULL;

    const unsigned char *pk = NULL;
    int ppklen, pptype;
    X509_ALGOR *pa = NULL;
    const void *pval;

#ifdef USE_CERT_BUFFERS_1024
    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024);
    bytes = sizeof_dsa_key_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048);
    bytes = sizeof_dsa_key_der_2048;
#else
    {
        XFILE fp = XBADFILE;
        XMEMSET(tmp, 0, sizeof(tmp));
        ExpectTrue((fp = XFOPEN("./certs/dsa2048.der", "rb")) != XBADFILE);
        ExpectIntGT(bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), fp), 0);
        if (fp != XBADFILE)
            XFCLOSE(fp);
    }
#endif

    /* Initialize pkey with der format dsa key */
    ExpectNotNull(d2i_PrivateKey(EVP_PKEY_DSA, &evpKey, &dsaKeyDer, bytes));

    ExpectNotNull(pubKey = X509_PUBKEY_new());
    ExpectIntEQ(X509_PUBKEY_set(&pubKey, evpKey), 1);
    ExpectIntEQ(X509_PUBKEY_get0_param(&obj, &pk, &ppklen, &pa, pubKey), 1);
    ExpectNotNull(pk);
    ExpectNotNull(pa);
    ExpectIntGT(ppklen, 0);
    X509_ALGOR_get0(&pa_oid, &pptype, &pval, pa);
    ExpectNotNull(pa_oid);
    ExpectNotNull(pval);
    ExpectIntEQ(pptype, V_ASN1_SEQUENCE);
    ExpectIntEQ(OBJ_obj2nid(pa_oid), EVP_PKEY_DSA);
    str = (ASN1_STRING *)pval;
    DEBUG_WRITE_DER(ASN1_STRING_data(str), ASN1_STRING_length(str), "str.der");
#ifdef USE_CERT_BUFFERS_1024
    ExpectIntEQ(ASN1_STRING_length(str), 291);
#else
    ExpectIntEQ(ASN1_STRING_length(str), 549);
#endif /* END USE_CERT_BUFFERS_1024 */

    X509_PUBKEY_free(pubKey);
    EVP_PKEY_free(evpKey);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BUF(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    BUF_MEM* buf = NULL;
    ExpectNotNull(buf = BUF_MEM_new());
    ExpectIntEQ(BUF_MEM_grow(buf, 10), 10);
    ExpectIntEQ(BUF_MEM_grow(buf, -1), 0);
    BUF_MEM_free(buf);
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
static int stub_rand_seed(const void *buf, int num)
{
    (void)buf;
    (void)num;

    return 123;
}

static int stub_rand_bytes(unsigned char *buf, int num)
{
    (void)buf;
    (void)num;

    return 456;
}

static byte* was_stub_rand_cleanup_called(void)
{
    static byte was_called = 0;

    return &was_called;
}

static void stub_rand_cleanup(void)
{
    byte* was_called = was_stub_rand_cleanup_called();

    *was_called = 1;

    return;
}

static byte* was_stub_rand_add_called(void)
{
    static byte was_called = 0;

    return &was_called;
}

static int stub_rand_add(const void *buf, int num, double entropy)
{
    byte* was_called = was_stub_rand_add_called();

    (void)buf;
    (void)num;
    (void)entropy;

    *was_called = 1;

    return 0;
}

static int stub_rand_pseudo_bytes(unsigned char *buf, int num)
{
    (void)buf;
    (void)num;

    return 9876;
}

static int stub_rand_status(void)
{
    return 5432;
}
#endif /* OPENSSL_EXTRA && !WOLFSSL_NO_OPENSSL_RAND_CB */

static int test_wolfSSL_RAND_set_rand_method(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
    RAND_METHOD rand_methods = {NULL, NULL, NULL, NULL, NULL, NULL};
    unsigned char* buf = NULL;
    int num = 0;
    double entropy = 0;
    int ret;
    byte* was_cleanup_called = was_stub_rand_cleanup_called();
    byte* was_add_called = was_stub_rand_add_called();

    ExpectNotNull(buf = (byte*)XMALLOC(32 * sizeof(byte), NULL,
        DYNAMIC_TYPE_TMP_BUFFER));

    ExpectIntNE(wolfSSL_RAND_status(), 5432);
    ExpectIntEQ(*was_cleanup_called, 0);
    RAND_cleanup();
    ExpectIntEQ(*was_cleanup_called, 0);


    rand_methods.seed = &stub_rand_seed;
    rand_methods.bytes = &stub_rand_bytes;
    rand_methods.cleanup = &stub_rand_cleanup;
    rand_methods.add = &stub_rand_add;
    rand_methods.pseudorand = &stub_rand_pseudo_bytes;
    rand_methods.status = &stub_rand_status;

    ExpectIntEQ(RAND_set_rand_method(&rand_methods), WOLFSSL_SUCCESS);
    ExpectIntEQ(RAND_seed(buf, num), 123);
    ExpectIntEQ(RAND_bytes(buf, num), 456);
    ExpectIntEQ(RAND_pseudo_bytes(buf, num), 9876);
    ExpectIntEQ(RAND_status(), 5432);

    ExpectIntEQ(*was_add_called, 0);
    /* The function pointer for RAND_add returns int, but RAND_add itself
     * returns void. */
    RAND_add(buf, num, entropy);
    ExpectIntEQ(*was_add_called, 1);
    was_add_called = 0;
    ExpectIntEQ(*was_cleanup_called, 0);
    RAND_cleanup();
    ExpectIntEQ(*was_cleanup_called, 1);
    *was_cleanup_called = 0;


    ret = RAND_set_rand_method(NULL);
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);
    ExpectIntNE(RAND_status(), 5432);
    ExpectIntEQ(*was_cleanup_called, 0);
    RAND_cleanup();
    ExpectIntEQ(*was_cleanup_called, 0);

    RAND_set_rand_method(NULL);

    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* OPENSSL_EXTRA && !WOLFSSL_NO_OPENSSL_RAND_CB */
    return EXPECT_RESULT();
}

static int test_wolfSSL_RAND_bytes(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    const int size1 = RNG_MAX_BLOCK_LEN;        /* in bytes */
    const int size2 = RNG_MAX_BLOCK_LEN + 1;    /* in bytes */
    const int size3 = RNG_MAX_BLOCK_LEN * 2;    /* in bytes */
    const int size4 = RNG_MAX_BLOCK_LEN * 4;    /* in bytes */
    int  max_bufsize;
    byte *my_buf = NULL;

    /* sanity check */
    ExpectIntEQ(RAND_bytes(NULL, 16), 0);
    ExpectIntEQ(RAND_bytes(NULL, 0), 0);

    max_bufsize = size4;

    ExpectNotNull(my_buf = (byte*)XMALLOC(max_bufsize * sizeof(byte), NULL,
        DYNAMIC_TYPE_TMP_BUFFER));

    ExpectIntEQ(RAND_bytes(my_buf, 0), 1);
    ExpectIntEQ(RAND_bytes(my_buf, -1), 0);

    ExpectNotNull(XMEMSET(my_buf, 0, max_bufsize));
    ExpectIntEQ(RAND_bytes(my_buf, size1), 1);
    ExpectIntEQ(RAND_bytes(my_buf, size2), 1);
    ExpectIntEQ(RAND_bytes(my_buf, size3), 1);
    ExpectIntEQ(RAND_bytes(my_buf, size4), 1);

    XFREE(my_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RAND(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    byte seed[16];

    XMEMSET(seed, 0, sizeof(seed));

    /* No global methods set. */
    ExpectIntEQ(RAND_seed(seed, sizeof(seed)), 1);
    ExpectIntEQ(RAND_poll(), 1);
    RAND_cleanup();

    ExpectIntEQ(RAND_egd(NULL), -1);
#ifndef NO_FILESYSTEM
    {
        char fname[100];

        ExpectNotNull(RAND_file_name(fname, (sizeof(fname) - 1)));
        ExpectIntEQ(RAND_write_file(NULL), 0);
    }
#endif
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_PKCS8_Compat(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && defined(HAVE_ECC) && \
    !defined(NO_BIO)
    PKCS8_PRIV_KEY_INFO* pt = NULL;
    PKCS8_PRIV_KEY_INFO* pt2 = NULL;
    BIO* bio = NULL;
    XFILE f = XBADFILE;
    int bytes = 0;
    char pkcs8_buffer[512];
#if defined(OPENSSL_ALL) || defined(WOLFSSL_WPAS_SMALL)
    EVP_PKEY *pkey = NULL;
#endif

    /* file from wolfssl/certs/ directory */
    ExpectTrue((f = XFOPEN("./certs/ecc-keyPkcs8.pem", "rb")) != XBADFILE);
    ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer), f)),
        0);
    if (f != XBADFILE)
        XFCLOSE(f);
    ExpectNotNull(bio = BIO_new_mem_buf((void*)pkcs8_buffer, bytes));
    ExpectNotNull(pt = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL));

#if defined(OPENSSL_ALL) || defined(WOLFSSL_WPAS_SMALL)
    ExpectNotNull(pkey = EVP_PKCS82PKEY(pt));
    ExpectIntEQ(EVP_PKEY_type(pkey->type), EVP_PKEY_EC);

    /* gets PKCS8 pointer to pkey */
    ExpectNotNull(pt2 = EVP_PKEY2PKCS8(pkey));

    EVP_PKEY_free(pkey);
#endif

    BIO_free(bio);
    PKCS8_PRIV_KEY_INFO_free(pt);
    PKCS8_PRIV_KEY_INFO_free(pt2);
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_BIO)
static int NoPasswordCallBack(char* passwd, int sz, int rw, void* userdata)
{
    (void)passwd;
    (void)sz;
    (void)rw;
    (void)userdata;

    return -1;
}
#endif

static int test_wolfSSL_PKCS8_d2i(void)
{
    EXPECT_DECLS;
#if !defined(HAVE_FIPS) && defined(OPENSSL_EXTRA)
    /* This test ends up using HMAC as a part of PBKDF2, and HMAC
     * requires a 12 byte password in FIPS mode. This test ends up
     * trying to use an 8 byte password. */

#ifndef NO_FILESYSTEM
    unsigned char pkcs8_buffer[2048];
    const unsigned char* p = NULL;
    int bytes = 0;
    XFILE file = XBADFILE;
    WOLFSSL_EVP_PKEY* pkey = NULL;
#ifndef NO_BIO
    BIO* bio = NULL;
    #if defined(OPENSSL_ALL) && \
            ((!defined(NO_RSA) && !defined(NO_DES3)) || \
               defined(HAVE_ECC)) && \
        !defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
    WOLFSSL_EVP_PKEY* evpPkey = NULL;
    #endif
#endif
#ifndef NO_RSA
    const char rsaDerPkcs8File[] = "./certs/server-keyPkcs8.der";
    const char rsaPemPkcs8File[] = "./certs/server-keyPkcs8.pem";
    #ifndef NO_DES3
    const char rsaDerPkcs8EncFile[] = "./certs/server-keyPkcs8Enc.der";
    #endif
#endif /* NO_RSA */
#ifdef HAVE_ECC
    const char ecDerPkcs8File[] = "certs/ecc-keyPkcs8.der";
    const char ecPemPkcs8File[] = "certs/ecc-keyPkcs8.pem";
    #ifndef NO_DES3
    const char ecDerPkcs8EncFile[] = "certs/ecc-keyPkcs8Enc.der";
    #endif
#endif /* HAVE_ECC */
#endif /* !NO_FILESYSTEM */

#if defined(OPENSSL_ALL) && (!defined(NO_RSA) || defined(HAVE_ECC))
#ifndef NO_RSA
    #ifdef USE_CERT_BUFFERS_1024
    const unsigned char* rsa = (unsigned char*)server_key_der_1024;
    int rsaSz = sizeof_server_key_der_1024;
    #else
    const unsigned char* rsa = (unsigned char*)server_key_der_2048;
    int rsaSz = sizeof_server_key_der_2048;
    #endif
#endif
#ifdef HAVE_ECC
    const unsigned char* ec = (unsigned char*)ecc_key_der_256;
    int ecSz = sizeof_ecc_key_der_256;
#endif
#endif /* OPENSSL_ALL && (!NO_RSA || HAVE_ECC) */


#ifndef NO_FILESYSTEM
   (void)pkcs8_buffer;
   (void)p;
   (void)bytes;
   (void)file;
#ifndef NO_BIO
   (void)bio;
#endif
#endif

#ifdef OPENSSL_ALL
#ifndef NO_RSA
    /* Try to auto-detect normal RSA private key */
    ExpectNotNull(pkey = d2i_AutoPrivateKey(NULL, &rsa, rsaSz));
    EVP_PKEY_free(pkey);
    pkey = NULL;
#endif
#ifdef HAVE_ECC
    /* Try to auto-detect normal EC private key */
    ExpectNotNull(pkey = d2i_AutoPrivateKey(NULL, &ec, ecSz));
    EVP_PKEY_free(pkey);
    pkey = NULL;
#endif
#endif /* OPENSSL_ALL */

#ifndef NO_FILESYSTEM
#if defined(OPENSSL_ALL) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
    ExpectIntEQ(PEM_write_PKCS8PrivateKey(XBADFILE, pkey, NULL, NULL, 0, NULL,
        NULL), 0);
    ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, NULL, NULL, NULL, 0, NULL,
        NULL), 0);
#endif

#ifndef NO_RSA
    /* Get DER encoded RSA PKCS#8 data. */
    ExpectTrue((file = XFOPEN(rsaDerPkcs8File, "rb")) != XBADFILE);
    ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
    ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
        file)), 0);
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }

    p = pkcs8_buffer;
#ifdef OPENSSL_ALL
    /* Try to decode - auto-detect key type. */
    ExpectNotNull(pkey = d2i_AutoPrivateKey(NULL, &p, bytes));
#else
    ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p, bytes));
#endif

    /* Get PEM encoded RSA PKCS#8 data. */
    ExpectTrue((file = XFOPEN(rsaPemPkcs8File, "rb")) != XBADFILE);
    ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
        file)), 0);
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }
#if defined(OPENSSL_ALL) && \
    !defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(NULL, pkey, NULL, NULL, 0, NULL,
        NULL), 0);
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, NULL, NULL, NULL, 0, NULL,
        NULL), 0);
    /* Write PKCS#8 PEM to BIO. */
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
        NULL), bytes);
    /* Write PKCS#8 PEM to stderr. */
    ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, NULL, NULL, 0, NULL,
        NULL), bytes);
    /* Compare file and written data */
    ExpectIntEQ(BIO_get_mem_data(bio, &p), bytes);
    ExpectIntEQ(XMEMCMP(p, pkcs8_buffer, bytes), 0);
    BIO_free(bio);
    bio = NULL;
#if !defined(NO_AES) && defined(HAVE_AESGCM)
    ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_aes_128_gcm(),
        NULL, 0, PasswordCallBack, (void*)"yassl123"), 0);
#endif
#if !defined(NO_DES3) && !defined(NO_SHA)
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    /* Write Encrypted PKCS#8 PEM to BIO. */
    bytes = 1834;
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_des_ede3_cbc(),
        NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
    ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_des_ede3_cbc(),
        NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
    ExpectNotNull(evpPkey = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallBack,
        (void*)"yassl123"));
    EVP_PKEY_free(evpPkey);
    evpPkey = NULL;
    BIO_free(bio);
    bio = NULL;
#endif /* !NO_DES3 && !NO_SHA */
#endif /* !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 */
    EVP_PKEY_free(pkey);
    pkey = NULL;

    /* PKCS#8 encrypted RSA key */
#ifndef NO_DES3
    ExpectTrue((file = XFOPEN(rsaDerPkcs8EncFile, "rb")) != XBADFILE);
    ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
    ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
        file)), 0);
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }
#if defined(OPENSSL_ALL) && \
    !defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
    ExpectNotNull(bio = BIO_new_mem_buf((void*)pkcs8_buffer, bytes));
    ExpectNotNull(pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, PasswordCallBack,
        (void*)"yassl123"));
    EVP_PKEY_free(pkey);
    pkey = NULL;
    BIO_free(bio);
    bio = NULL;
#endif /* OPENSSL_ALL && !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 */
#endif /* !NO_DES3 */
#endif /* NO_RSA */

#ifdef HAVE_ECC
    /* PKCS#8 encode EC key */
    ExpectTrue((file = XFOPEN(ecDerPkcs8File, "rb")) != XBADFILE);
    ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
    ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
        file)), 0);
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }

    p = pkcs8_buffer;
#ifdef OPENSSL_ALL
    /* Try to decode - auto-detect key type. */
    ExpectNotNull(pkey = d2i_AutoPrivateKey(NULL, &p, bytes));
#else
    ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_EC, NULL, &p, bytes));
#endif

    /* Get PEM encoded RSA PKCS#8 data. */
    ExpectTrue((file = XFOPEN(ecPemPkcs8File, "rb")) != XBADFILE);
    ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
    ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
        file)), 0);
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }
#if defined(OPENSSL_ALL) && \
    !defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8) && \
    defined(HAVE_AES_CBC)
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    /* Write PKCS#8 PEM to BIO. */
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
        NULL), bytes);
    ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, NULL, NULL, 0, NULL,
        NULL), bytes);
    /* Compare file and written data */
    ExpectIntEQ(BIO_get_mem_data(bio, &p), bytes);
    ExpectIntEQ(XMEMCMP(p, pkcs8_buffer, bytes), 0);
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    /* Write Encrypted PKCS#8 PEM to BIO. */
    bytes = 379;
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_aes_256_cbc(),
        NULL, 0, NoPasswordCallBack, (void*)"yassl123"), 0);
    ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_aes_256_cbc(),
        NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
    ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_aes_128_cbc(),
        NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
    ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_aes_128_cbc(),
        (char*)"yassl123", 8, PasswordCallBack, NULL), bytes);
    ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_aes_256_cbc(),
        NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
    ExpectNotNull(evpPkey = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallBack,
        (void*)"yassl123"));
    EVP_PKEY_free(evpPkey);
    evpPkey = NULL;
    BIO_free(bio);
    bio = NULL;
#endif /* OPENSSL_ALL && !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 && HAVE_AES_CBC */
    EVP_PKEY_free(pkey);
    pkey = NULL;

    /* PKCS#8 encrypted EC key */
#ifndef NO_DES3
    ExpectTrue((file = XFOPEN(ecDerPkcs8EncFile, "rb")) != XBADFILE);
    ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
    ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
        file)), 0);
    if (file != XBADFILE) {
        XFCLOSE(file);
        file = XBADFILE;
    }
#if defined(OPENSSL_ALL) && \
    !defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
    ExpectNotNull(bio = BIO_new_mem_buf((void*)pkcs8_buffer, bytes));
    ExpectNotNull(pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, PasswordCallBack,
                                                            (void*)"yassl123"));
    EVP_PKEY_free(pkey);
    pkey = NULL;
    BIO_free(bio);
    bio = NULL;
#endif /* OPENSSL_ALL && !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 */
#endif /* !NO_DES3 */
#endif /* HAVE_ECC */

#endif /* !NO_FILESYSTEM */
#endif /* HAVE_FIPS && OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

#if !defined(SINGLE_THREADED) && defined(ERROR_QUEUE_PER_THREAD) && \
    !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
    defined(DEBUG_WOLFSSL)
#define LOGGING_THREADS 5
#define ERROR_COUNT 10
/* copied from logging.c since this is not exposed otherwise */
#ifndef ERROR_QUEUE_MAX
#ifdef ERROR_QUEUE_PER_THREAD
    #define ERROR_QUEUE_MAX 16
#else
    /* this breaks from compat of unlimited error queue size */
    #define ERROR_QUEUE_MAX 100
#endif
#endif

static volatile int loggingThreadsReady;
static THREAD_RETURN WOLFSSL_THREAD test_logging(void* args)
{
    const char* file;
    int line;
    unsigned long err;
    int errorCount = 0;
    int i;

    (void)args;

    while (!loggingThreadsReady);
    for (i = 0; i < ERROR_COUNT; i++)
        ERR_put_error(ERR_LIB_PEM, SYS_F_ACCEPT, -990 - i, __FILE__, __LINE__);

    while ((err = ERR_get_error_line(&file, &line))) {
        AssertIntEQ(err, 990 + errorCount);
        errorCount++;
    }
    AssertIntEQ(errorCount, ERROR_COUNT);

    /* test max queue behavior, trying to add an arbitrary 3 errors over */
    ERR_clear_error(); /* ERR_get_error_line() does not remove */
    errorCount = 0;
    for (i = 0; i < ERROR_QUEUE_MAX + 3; i++)
        ERR_put_error(ERR_LIB_PEM, SYS_F_ACCEPT, -990 - i, __FILE__, __LINE__);

    while ((err = ERR_get_error_line(&file, &line))) {
        AssertIntEQ(err, 990 + errorCount);
        errorCount++;
    }

    /* test that the 3 errors over the max were dropped */
    AssertIntEQ(errorCount, ERROR_QUEUE_MAX);

    WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif

static int test_error_queue_per_thread(void)
{
    int res = TEST_SKIPPED;
#if !defined(SINGLE_THREADED) && defined(ERROR_QUEUE_PER_THREAD) && \
    !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
    defined(DEBUG_WOLFSSL)
    THREAD_TYPE loggingThreads[LOGGING_THREADS];
    int i;

    ERR_clear_error(); /* clear out any error nodes */

    loggingThreadsReady = 0;
    for (i = 0; i < LOGGING_THREADS; i++)
        start_thread(test_logging, NULL, &loggingThreads[i]);
    loggingThreadsReady = 1;
    for (i = 0; i < LOGGING_THREADS; i++)
        join_thread(loggingThreads[i]);

    res = TEST_SUCCESS;
#endif
    return res;
}

static int test_wolfSSL_ERR_put_error(void)
{
    EXPECT_DECLS;
#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
    defined(DEBUG_WOLFSSL)
    const char* file;
    int line;

    ERR_clear_error(); /* clear out any error nodes */
    ERR_put_error(0,SYS_F_ACCEPT, 0, "this file", 0);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 0);
    ERR_put_error(0,SYS_F_BIND, 1, "this file", 1);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 1);
    ERR_put_error(0,SYS_F_CONNECT, 2, "this file", 2);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 2);
    ERR_put_error(0,SYS_F_FOPEN, 3, "this file", 3);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 3);
    ERR_put_error(0,SYS_F_FREAD, 4, "this file", 4);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 4);
    ERR_put_error(0,SYS_F_GETADDRINFO, 5, "this file", 5);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 5);
    ERR_put_error(0,SYS_F_GETSOCKOPT, 6, "this file", 6);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 6);
    ERR_put_error(0,SYS_F_GETSOCKNAME, 7, "this file", 7);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 7);
    ERR_put_error(0,SYS_F_GETHOSTBYNAME, 8, "this file", 8);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 8);
    ERR_put_error(0,SYS_F_GETNAMEINFO, 9, "this file", 9);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 9);
    ERR_put_error(0,SYS_F_GETSERVBYNAME, 10, "this file", 10);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 10);
    ERR_put_error(0,SYS_F_IOCTLSOCKET, 11, "this file", 11);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 11);
    ERR_put_error(0,SYS_F_LISTEN, 12, "this file", 12);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 12);
    ERR_put_error(0,SYS_F_OPENDIR, 13, "this file", 13);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 13);
    ERR_put_error(0,SYS_F_SETSOCKOPT, 14, "this file", 14);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 14);
    ERR_put_error(0,SYS_F_SOCKET, 15, "this file", 15);
    ExpectIntEQ(ERR_get_error_line(&file, &line), 15);

#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
    ERR_put_error(ERR_LIB_ASN1, SYS_F_ACCEPT, ASN1_R_HEADER_TOO_LONG,
            "this file", 100);
    ExpectIntEQ(wolfSSL_ERR_peek_last_error_line(&file, &line),
            (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG);
    ExpectIntEQ(line, 100);
    ExpectIntEQ(wolfSSL_ERR_peek_error(),
            (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG);
    ExpectIntEQ(ERR_get_error_line(&file, &line), ASN1_R_HEADER_TOO_LONG);
#endif

    /* try reading past end of error queue */
    file = NULL;
    ExpectIntEQ(ERR_get_error_line(&file, &line), 0);
    ExpectNull(file);
    ExpectIntEQ(ERR_get_error_line_data(&file, &line, NULL, NULL), 0);

    PEMerr(4,4);
    ExpectIntEQ(ERR_get_error(), 4);
    /* Empty and free up all error nodes */
    ERR_clear_error();

    /* Verify all nodes are cleared */
    ERR_put_error(0,SYS_F_ACCEPT, 0, "this file", 0);
    ERR_clear_error();
    ExpectIntEQ(ERR_get_error_line(&file, &line), 0);
#endif
    return EXPECT_RESULT();
}

/*
 * This is a regression test for a bug where the peek/get error functions were
 * drawing from the end of the queue rather than the front.
 */
static int test_wolfSSL_ERR_get_error_order(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_HAVE_ERROR_QUEUE) && defined(OPENSSL_EXTRA)
    /* Empty the queue. */
    wolfSSL_ERR_clear_error();

    wolfSSL_ERR_put_error(0, 0, WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), "test", 0);
    wolfSSL_ERR_put_error(0, 0, WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E), "test", 0);

    ExpectIntEQ(wolfSSL_ERR_peek_error(), -WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
    ExpectIntEQ(wolfSSL_ERR_get_error(), -WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
    ExpectIntEQ(wolfSSL_ERR_peek_error(), -WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E));
    ExpectIntEQ(wolfSSL_ERR_get_error(), -WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E));
#endif /* WOLFSSL_HAVE_ERROR_QUEUE && OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

#ifndef NO_BIO

static int test_wolfSSL_ERR_print_errors(void)
{
    EXPECT_DECLS;
#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
    defined(DEBUG_WOLFSSL) && !defined(NO_ERROR_STRINGS)
    BIO* bio = NULL;
    char buf[1024];

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ERR_clear_error(); /* clear out any error nodes */
    ERR_put_error(0,SYS_F_ACCEPT, -173, "ssl.c", 0);
    /* Choosing -600 as an unused errno. */
    ERR_put_error(0,SYS_F_BIND, -600, "asn.c", 100);

    ERR_print_errors(bio);
    ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 56);
    ExpectIntEQ(XSTRNCMP(
        "error:173:wolfSSL library:Bad function argument:ssl.c:0",
        buf, 55), 0);
    ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 57);
    ExpectIntEQ(XSTRNCMP(
        "error:600:wolfSSL library:unknown error number:asn.c:100",
        buf, 56), 0);
    ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 1);
    ExpectIntEQ(buf[0], '\0');
    ExpectIntEQ(ERR_get_error_line(NULL, NULL), 0);

    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
    defined(DEBUG_WOLFSSL)
static int test_wolfSSL_error_cb(const char *str, size_t len, void *u)
{
    if (u != NULL) {
        wolfSSL_BIO_write((BIO*)u, str, (int)len);
    }
    return 0;
}
#endif

static int test_wolfSSL_ERR_print_errors_cb(void)
{
    EXPECT_DECLS;
#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
    defined(DEBUG_WOLFSSL)
    BIO* bio = NULL;
    char buf[1024];

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ERR_clear_error(); /* clear out any error nodes */
    ERR_put_error(0,SYS_F_ACCEPT, -173, "ssl.c", 0);
    ERR_put_error(0,SYS_F_BIND, -275, "asn.c", 100);

    ERR_print_errors_cb(test_wolfSSL_error_cb, bio);
    ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 108);
    ExpectIntEQ(XSTRNCMP(
        "wolfSSL error occurred, error = 173 line:0 file:ssl.c",
        buf, 53), 0);
    ExpectIntEQ(XSTRNCMP(
         "wolfSSL error occurred, error = 275 line:100 file:asn.c",
         buf + 53, 55), 0);
    ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 0);

    BIO_free(bio);
#endif

    return EXPECT_RESULT();
}
/*
 * Testing WOLFSSL_ERROR_MSG
 */
static int test_WOLFSSL_ERROR_MSG(void)
{
    int res = TEST_SKIPPED;
#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) ||\
    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
    const char* msg = TEST_STRING;

    WOLFSSL_ERROR_MSG(msg);

    res = TEST_SUCCESS;
#endif
    return res;
} /* End test_WOLFSSL_ERROR_MSG */
/*
 * Testing wc_ERR_remove_state
 */
static int test_wc_ERR_remove_state(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
    wc_ERR_remove_state();

    res = TEST_SUCCESS;
#endif
    return res;
} /* End test_wc_ERR_remove_state */
/*
 * Testing wc_ERR_print_errors_fp
 */
static int test_wc_ERR_print_errors_fp(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)) && \
    (!defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM))
    long sz;
    XFILE fp = XBADFILE;

    WOLFSSL_ERROR(WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectTrue((fp = XFOPEN("./tests/test-log-dump-to-file.txt", "ar")) !=
        XBADFILE);
    wc_ERR_print_errors_fp(fp);
#if defined(DEBUG_WOLFSSL)
    ExpectTrue(XFSEEK(fp, 0, XSEEK_END) == 0);
    #ifdef NO_ERROR_QUEUE
        ExpectIntEQ(sz = XFTELL(fp), 0);
    #else
        ExpectIntNE(sz = XFTELL(fp), 0);
    #endif
#endif
    if (fp != XBADFILE)
        XFCLOSE(fp);
    (void)sz;
#endif
    return EXPECT_RESULT();
} /* End test_wc_ERR_print_errors_fp */
#ifdef DEBUG_WOLFSSL
static void Logging_cb(const int logLevel, const char *const logMessage)
{
    (void)logLevel;
    (void)logMessage;
}
#endif
/*
 * Testing wolfSSL_GetLoggingCb
 */
static int test_wolfSSL_GetLoggingCb(void)
{
    EXPECT_DECLS;
#ifdef DEBUG_WOLFSSL
    /* Testing without wolfSSL_SetLoggingCb() */
    ExpectNull(wolfSSL_GetLoggingCb());
    /* Testing with wolfSSL_SetLoggingCb() */
    ExpectIntEQ(wolfSSL_SetLoggingCb(Logging_cb), 0);
    ExpectNotNull(wolfSSL_GetLoggingCb());
    ExpectIntEQ(wolfSSL_SetLoggingCb(NULL), 0);
#endif
    ExpectNull(wolfSSL_GetLoggingCb());

    return EXPECT_RESULT();
} /* End test_wolfSSL_GetLoggingCb */

#endif /* !NO_BIO */

static int test_wolfSSL_MD4(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_MD4)
    MD4_CTX md4;
    unsigned char out[16]; /* MD4_DIGEST_SIZE */
    const char* msg = "12345678901234567890123456789012345678901234567890123456"
                      "789012345678901234567890";
    const char* test = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19\x9c\x3e\x7b\x16\x4f"
                       "\xcc\x05\x36";
    int msgSz = (int)XSTRLEN(msg);


    XMEMSET(out, 0, sizeof(out));
    MD4_Init(&md4);
    MD4_Update(&md4, (const void*)msg, (word32)msgSz);
    MD4_Final(out, &md4);
    ExpectIntEQ(XMEMCMP(out, test, sizeof(out)), 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_MD5(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_MD5)
    byte input1[] = "";
    byte input2[] = "message digest";
    byte hash[WC_MD5_DIGEST_SIZE];
    unsigned char output1[] =
        "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e";
    unsigned char output2[] =
        "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61\xd0";
    WOLFSSL_MD5_CTX md5;

    XMEMSET(&md5, 0, sizeof(md5));

    /* Test cases for illegal parameters */
    ExpectIntEQ(MD5_Init(NULL), 0);
    ExpectIntEQ(MD5_Init(&md5), 1);
    ExpectIntEQ(MD5_Update(NULL, input1, 0), 0);
    ExpectIntEQ(MD5_Update(NULL, NULL, 0), 0);
    ExpectIntEQ(MD5_Update(&md5, NULL, 1), 0);
    ExpectIntEQ(MD5_Final(NULL, &md5), 0);
    ExpectIntEQ(MD5_Final(hash, NULL), 0);
    ExpectIntEQ(MD5_Final(NULL, NULL), 0);

    /* Init MD5 CTX */
    ExpectIntEQ(wolfSSL_MD5_Init(&md5), 1);
    ExpectIntEQ(wolfSSL_MD5_Update(&md5, input1, XSTRLEN((const char*)&input1)),
        1);
    ExpectIntEQ(wolfSSL_MD5_Final(hash, &md5), 1);
    ExpectIntEQ(XMEMCMP(&hash, output1, WC_MD5_DIGEST_SIZE), 0);

    /* Init MD5 CTX */
    ExpectIntEQ(wolfSSL_MD5_Init(&md5), 1);
    ExpectIntEQ(wolfSSL_MD5_Update(&md5, input2,
        (int)XSTRLEN((const char*)input2)), 1);
    ExpectIntEQ(wolfSSL_MD5_Final(hash, &md5), 1);
    ExpectIntEQ(XMEMCMP(&hash, output2, WC_MD5_DIGEST_SIZE), 0);
#if !defined(NO_OLD_NAMES) && \
  (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)))
    ExpectPtrNE(MD5(NULL, 1, (byte*)&hash), &hash);
    ExpectPtrEq(MD5(input1, 0, (byte*)&hash), &hash);
    ExpectPtrNE(MD5(input1, 1, NULL), NULL);
    ExpectPtrNE(MD5(NULL, 0, NULL), NULL);

    ExpectPtrEq(MD5(input1, (int)XSTRLEN((const char*)&input1), (byte*)&hash),
        &hash);
    ExpectIntEQ(XMEMCMP(&hash, output1, WC_MD5_DIGEST_SIZE), 0);

    ExpectPtrEq(MD5(input2, (int)XSTRLEN((const char*)&input2), (byte*)&hash),
        &hash);
    ExpectIntEQ(XMEMCMP(&hash, output2, WC_MD5_DIGEST_SIZE), 0);
    {
        byte data[] = "Data to be hashed.";
        XMEMSET(hash, 0, WC_MD5_DIGEST_SIZE);

        ExpectNotNull(MD5(data, sizeof(data), NULL));
        ExpectNotNull(MD5(data, sizeof(data), hash));
        ExpectNotNull(MD5(NULL, 0, hash));
        ExpectNull(MD5(NULL, sizeof(data), hash));
    }
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_MD5_Transform(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_MD5)
    byte input1[] = "";
    byte input2[] = "abc";
    byte local[WC_MD5_BLOCK_SIZE];
    word32 sLen = 0;
#ifdef BIG_ENDIAN_ORDER
    unsigned char output1[] =
        "\x03\x1f\x1d\xac\x6e\xa5\x8e\xd0\x1f\xab\x67\xb7\x74\x31\x77\x91";
    unsigned char output2[] =
        "\xef\xd3\x79\x8d\x67\x17\x25\x90\xa4\x13\x79\xc7\xe3\xa7\x7b\xbc";
#else
    unsigned char output1[] =
        "\xac\x1d\x1f\x03\xd0\x8e\xa5\x6e\xb7\x67\xab\x1f\x91\x77\x31\x74";
    unsigned char output2[] =
        "\x8d\x79\xd3\xef\x90\x25\x17\x67\xc7\x79\x13\xa4\xbc\x7b\xa7\xe3";
#endif

    union {
        wc_Md5 native;
        MD5_CTX compat;
    } md5;

    XMEMSET(&md5.compat, 0, sizeof(md5.compat));
    XMEMSET(&local, 0, sizeof(local));

    /* sanity check */
    ExpectIntEQ(MD5_Transform(NULL, NULL), 0);
    ExpectIntEQ(MD5_Transform(NULL, (const byte*)&input1), 0);
    ExpectIntEQ(MD5_Transform(&md5.compat, NULL), 0);
    ExpectIntEQ(wc_Md5Transform(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Md5Transform(NULL, (const byte*)&input1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Md5Transform(&md5.native, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Init MD5 CTX */
    ExpectIntEQ(wolfSSL_MD5_Init(&md5.compat), 1);
    /* Do Transform*/
    sLen = (word32)XSTRLEN((char*)input1);
    XMEMCPY(local, input1, sLen);
    ExpectIntEQ(MD5_Transform(&md5.compat, (const byte*)&local[0]), 1);

    ExpectIntEQ(XMEMCMP(md5.native.digest, output1, WC_MD5_DIGEST_SIZE), 0);

    /* Init MD5 CTX */
    ExpectIntEQ(MD5_Init(&md5.compat), 1);
    sLen = (word32)XSTRLEN((char*)input2);
    XMEMSET(local, 0, WC_MD5_BLOCK_SIZE);
    XMEMCPY(local, input2, sLen);
    ExpectIntEQ(MD5_Transform(&md5.compat, (const byte*)&local[0]), 1);
    ExpectIntEQ(XMEMCMP(md5.native.digest, output2, WC_MD5_DIGEST_SIZE), 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SHA(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(HAVE_SELFTEST)
    #if !defined(NO_SHA) && defined(NO_OLD_SHA_NAMES) && \
        (!defined(HAVE_FIPS) || \
        (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2))
    {
        const unsigned char in[] = "abc";
        unsigned char expected[] = "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
                                   "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D";
        unsigned char out[WC_SHA_DIGEST_SIZE];
        unsigned char* p = NULL;
        WOLFSSL_SHA_CTX sha;

        XMEMSET(out, 0, WC_SHA_DIGEST_SIZE);
        ExpectNotNull(SHA1(in, XSTRLEN((char*)in), out));
        ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0);

        /* SHA interface test */
        XMEMSET(out, 0, WC_SHA_DIGEST_SIZE);

        ExpectNull(SHA(NULL, XSTRLEN((char*)in), out));
        ExpectNotNull(SHA(in, 0, out));
        ExpectNotNull(SHA(in, XSTRLEN((char*)in), NULL));
        ExpectNotNull(SHA(NULL, 0, out));
        ExpectNotNull(SHA(NULL, 0, NULL));

        ExpectNotNull(SHA(in, XSTRLEN((char*)in), out));
        ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0);
        ExpectNotNull(p = SHA(in, XSTRLEN((char*)in), NULL));
        ExpectIntEQ(XMEMCMP(p, expected, WC_SHA_DIGEST_SIZE), 0);

        ExpectIntEQ(wolfSSL_SHA_Init(&sha), 1);
        ExpectIntEQ(wolfSSL_SHA_Update(&sha, in, XSTRLEN((char*)in)), 1);
        ExpectIntEQ(wolfSSL_SHA_Final(out, &sha), 1);
        ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0);

        ExpectIntEQ(wolfSSL_SHA1_Init(&sha), 1);
        ExpectIntEQ(wolfSSL_SHA1_Update(&sha, in, XSTRLEN((char*)in)), 1);
        ExpectIntEQ(wolfSSL_SHA1_Final(out, &sha), 1);
        ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0);
    }
    #endif

    #if !defined(NO_SHA256)
    {
        const unsigned char in[] = "abc";
        unsigned char expected[] =
            "\xBA\x78\x16\xBF\x8F\x01\xCF\xEA\x41\x41\x40\xDE\x5D\xAE\x22"
            "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00"
            "\x15\xAD";
        unsigned char out[WC_SHA256_DIGEST_SIZE];
        unsigned char* p = NULL;

        XMEMSET(out, 0, WC_SHA256_DIGEST_SIZE);
#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS)
        ExpectNotNull(SHA256(in, XSTRLEN((char*)in), out));
#else
        ExpectNotNull(wolfSSL_SHA256(in, XSTRLEN((char*)in), out));
#endif
        ExpectIntEQ(XMEMCMP(out, expected, WC_SHA256_DIGEST_SIZE), 0);
#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS)
        ExpectNotNull(p = SHA256(in, XSTRLEN((char*)in), NULL));
#else
        ExpectNotNull(p = wolfSSL_SHA256(in, XSTRLEN((char*)in), NULL));
#endif
        ExpectIntEQ(XMEMCMP(p, expected, WC_SHA256_DIGEST_SIZE), 0);
    }
    #endif

    #if defined(WOLFSSL_SHA384)
    {
        const unsigned char in[] = "abc";
        unsigned char expected[] =
            "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50"
            "\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff"
            "\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34"
            "\xc8\x25\xa7";
        unsigned char out[WC_SHA384_DIGEST_SIZE];
        unsigned char* p = NULL;

        XMEMSET(out, 0, WC_SHA384_DIGEST_SIZE);
#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS)
        ExpectNotNull(SHA384(in, XSTRLEN((char*)in), out));
#else
        ExpectNotNull(wolfSSL_SHA384(in, XSTRLEN((char*)in), out));
#endif
        ExpectIntEQ(XMEMCMP(out, expected, WC_SHA384_DIGEST_SIZE), 0);
#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS)
        ExpectNotNull(p = SHA384(in, XSTRLEN((char*)in), NULL));
#else
        ExpectNotNull(p = wolfSSL_SHA384(in, XSTRLEN((char*)in), NULL));
#endif
        ExpectIntEQ(XMEMCMP(p, expected, WC_SHA384_DIGEST_SIZE), 0);
    }
    #endif

    #if defined(WOLFSSL_SHA512)
    {
        const unsigned char in[] = "abc";
        unsigned char expected[] =
            "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41"
            "\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55"
            "\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3"
            "\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f"
            "\xa5\x4c\xa4\x9f";
        unsigned char out[WC_SHA512_DIGEST_SIZE];
        unsigned char* p = NULL;

        XMEMSET(out, 0, WC_SHA512_DIGEST_SIZE);
#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS)
        ExpectNotNull(SHA512(in, XSTRLEN((char*)in), out));
#else
        ExpectNotNull(wolfSSL_SHA512(in, XSTRLEN((char*)in), out));
#endif
        ExpectIntEQ(XMEMCMP(out, expected, WC_SHA512_DIGEST_SIZE), 0);
#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS)
        ExpectNotNull(p = SHA512(in, XSTRLEN((char*)in), NULL));
#else
        ExpectNotNull(p = wolfSSL_SHA512(in, XSTRLEN((char*)in), NULL));
#endif
        ExpectIntEQ(XMEMCMP(p, expected, WC_SHA512_DIGEST_SIZE), 0);
    }
    #endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SHA_Transform(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SHA)
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
    byte input1[] = "";
    byte input2[] = "abc";
    byte local[WC_SHA_BLOCK_SIZE];
    word32 sLen = 0;
#ifdef BIG_ENDIAN_ORDER
    unsigned char output1[] =
        "\x92\xb4\x04\xe5\x56\x58\x8c\xed\x6c\x1a\xcd\x4e\xbf\x05\x3f\x68"
        "\x09\xf7\x3a\x93";
    unsigned char output2[] =
        "\x97\xb2\x74\x8b\x4f\x5b\xbc\xca\x5b\xc0\xe6\xea\x2d\x40\xb4\xa0"
        "\x7c\x6e\x08\xb8";
#else
    unsigned char output1[] =
        "\xe5\x04\xb4\x92\xed\x8c\x58\x56\x4e\xcd\x1a\x6c\x68\x3f\x05\xbf"
        "\x93\x3a\xf7\x09";
    unsigned char output2[] =
        "\x8b\x74\xb2\x97\xca\xbc\x5b\x4f\xea\xe6\xc0\x5b\xa0\xb4\x40\x2d"
        "\xb8\x08\x6e\x7c";
#endif

    union {
        wc_Sha native;
        SHA_CTX compat;
    } sha;
    union {
        wc_Sha native;
        SHA_CTX compat;
    } sha1;

    XMEMSET(&sha.compat, 0, sizeof(sha.compat));
    XMEMSET(&local, 0, sizeof(local));

    /* sanity check */
    ExpectIntEQ(SHA_Transform(NULL, NULL), 0);
    ExpectIntEQ(SHA_Transform(NULL, (const byte*)&input1), 0);
    ExpectIntEQ(SHA_Transform(&sha.compat, NULL), 0);
    ExpectIntEQ(SHA1_Transform(NULL, NULL), 0);
    ExpectIntEQ(SHA1_Transform(NULL, (const byte*)&input1), 0);
    ExpectIntEQ(SHA1_Transform(&sha.compat, NULL), 0);
    ExpectIntEQ(wc_ShaTransform(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ShaTransform(NULL, (const byte*)&input1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_ShaTransform(&sha.native, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Init SHA CTX */
    ExpectIntEQ(SHA_Init(&sha.compat), 1);
    /* Do Transform*/
    sLen = (word32)XSTRLEN((char*)input1);
    XMEMCPY(local, input1, sLen);
    ExpectIntEQ(SHA_Transform(&sha.compat, (const byte*)&local[0]), 1);
    ExpectIntEQ(XMEMCMP(sha.native.digest, output1, WC_SHA_DIGEST_SIZE), 0);
    ExpectIntEQ(SHA_Final(local, &sha.compat), 1); /* frees resources */

    /* Init SHA CTX */
    ExpectIntEQ(SHA_Init(&sha.compat), 1);
    sLen = (word32)XSTRLEN((char*)input2);
    XMEMSET(local, 0, WC_SHA_BLOCK_SIZE);
    XMEMCPY(local, input2, sLen);
    ExpectIntEQ(SHA_Transform(&sha.compat, (const byte*)&local[0]), 1);
    ExpectIntEQ(XMEMCMP(sha.native.digest, output2, WC_SHA_DIGEST_SIZE), 0);
    ExpectIntEQ(SHA_Final(local, &sha.compat), 1); /* frees resources */

    /* SHA1 */
    XMEMSET(local, 0, WC_SHA_BLOCK_SIZE);
    /* Init SHA CTX */
    ExpectIntEQ(SHA1_Init(&sha1.compat), 1);
    /* Do Transform*/
    sLen = (word32)XSTRLEN((char*)input1);
    XMEMCPY(local, input1, sLen);
    ExpectIntEQ(SHA1_Transform(&sha1.compat, (const byte*)&local[0]), 1);
    ExpectIntEQ(XMEMCMP(sha1.native.digest, output1, WC_SHA_DIGEST_SIZE), 0);
    ExpectIntEQ(SHA1_Final(local, &sha1.compat), 1); /* frees resources */

    /* Init SHA CTX */
    ExpectIntEQ(SHA1_Init(&sha1.compat), 1);
    sLen = (word32)XSTRLEN((char*)input2);
    XMEMSET(local, 0, WC_SHA_BLOCK_SIZE);
    XMEMCPY(local, input2, sLen);
    ExpectIntEQ(SHA1_Transform(&sha1.compat, (const byte*)&local[0]), 1);
    ExpectIntEQ(XMEMCMP(sha1.native.digest, output2, WC_SHA_DIGEST_SIZE), 0);
    ExpectIntEQ(SHA_Final(local, &sha1.compat), 1); /* frees resources */
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SHA224(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA224) && \
    !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2))
    unsigned char input[] =
        "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
    unsigned char output[] =
         "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01"
         "\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25";
    size_t inLen;
    byte hash[WC_SHA224_DIGEST_SIZE];
    unsigned char* p = NULL;

    inLen  = XSTRLEN((char*)input);

    XMEMSET(hash, 0, WC_SHA224_DIGEST_SIZE);

    ExpectNull(SHA224(NULL, inLen, hash));
    ExpectNotNull(SHA224(input, 0, hash));
    ExpectNotNull(SHA224(input, inLen, NULL));
    ExpectNotNull(SHA224(NULL, 0, hash));
    ExpectNotNull(SHA224(NULL, 0, NULL));

    ExpectNotNull(SHA224(input, inLen, hash));
    ExpectIntEQ(XMEMCMP(hash, output, WC_SHA224_DIGEST_SIZE), 0);
    ExpectNotNull(p = SHA224(input, inLen, NULL));
    ExpectIntEQ(XMEMCMP(p, output, WC_SHA224_DIGEST_SIZE), 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SHA256(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SHA256) && \
    defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
    unsigned char input[] =
        "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
    unsigned char output[] =
        "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60"
        "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB"
        "\x06\xC1";
    size_t inLen;
    byte hash[WC_SHA256_DIGEST_SIZE];

    inLen  = XSTRLEN((char*)input);

    XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE);
    ExpectNotNull(SHA256(input, inLen, hash));
    ExpectIntEQ(XMEMCMP(hash, output, WC_SHA256_DIGEST_SIZE), 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SHA256_Transform(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SHA256)
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \
        !defined(WOLFSSL_DEVCRYPTO_HASH) && !defined(WOLFSSL_AFALG_HASH) && \
        !defined(WOLFSSL_KCAPI_HASH)
    byte input1[] = "";
    byte input2[] = "abc";
    byte local[WC_SHA256_BLOCK_SIZE];
    word32 sLen = 0;
#ifdef BIG_ENDIAN_ORDER
    unsigned char output1[] =
        "\xda\x56\x98\xbe\x17\xb9\xb4\x69\x62\x33\x57\x99\x77\x9f\xbe\xca"
        "\x8c\xe5\xd4\x91\xc0\xd2\x62\x43\xba\xfe\xf9\xea\x18\x37\xa9\xd8";
    unsigned char output2[] =
        "\x1d\x4e\xd4\x67\x67\x7c\x61\x67\x44\x10\x76\x26\x78\x10\xff\xb8"
        "\x40\xc8\x9a\x39\x73\x16\x60\x8c\xa6\x61\xd6\x05\x91\xf2\x8c\x35";
#else
    unsigned char output1[] =
        "\xbe\x98\x56\xda\x69\xb4\xb9\x17\x99\x57\x33\x62\xca\xbe\x9f\x77"
        "\x91\xd4\xe5\x8c\x43\x62\xd2\xc0\xea\xf9\xfe\xba\xd8\xa9\x37\x18";
    unsigned char output2[] =
        "\x67\xd4\x4e\x1d\x67\x61\x7c\x67\x26\x76\x10\x44\xb8\xff\x10\x78"
        "\x39\x9a\xc8\x40\x8c\x60\x16\x73\x05\xd6\x61\xa6\x35\x8c\xf2\x91";
#endif
    union {
        wc_Sha256 native;
        SHA256_CTX compat;
    } sha256;

    XMEMSET(&sha256.compat, 0, sizeof(sha256.compat));
    XMEMSET(&local, 0, sizeof(local));

    /* sanity check */
    ExpectIntEQ(SHA256_Transform(NULL, NULL), 0);
    ExpectIntEQ(SHA256_Transform(NULL, (const byte*)&input1), 0);
    ExpectIntEQ(SHA256_Transform(&sha256.compat, NULL), 0);
    ExpectIntEQ(wc_Sha256Transform(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256Transform(NULL, (const byte*)&input1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha256Transform(&sha256.native, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Init SHA256 CTX */
    ExpectIntEQ(SHA256_Init(&sha256.compat), 1);
    /* Do Transform*/
    sLen = (word32)XSTRLEN((char*)input1);
    XMEMCPY(local, input1, sLen);
    ExpectIntEQ(SHA256_Transform(&sha256.compat, (const byte*)&local[0]), 1);
    ExpectIntEQ(XMEMCMP(sha256.native.digest, output1, WC_SHA256_DIGEST_SIZE),
        0);
    ExpectIntEQ(SHA256_Final(local, &sha256.compat), 1); /* frees resources */

    /* Init SHA256 CTX */
    ExpectIntEQ(SHA256_Init(&sha256.compat), 1);
    sLen = (word32)XSTRLEN((char*)input2);
    XMEMSET(local, 0, WC_SHA256_BLOCK_SIZE);
    XMEMCPY(local, input2, sLen);
    ExpectIntEQ(SHA256_Transform(&sha256.compat, (const byte*)&local[0]), 1);
    ExpectIntEQ(XMEMCMP(sha256.native.digest, output2, WC_SHA256_DIGEST_SIZE),
        0);
    ExpectIntEQ(SHA256_Final(local, &sha256.compat), 1); /* frees resources */
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SHA512_Transform(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA512)
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \
        !defined(WOLFSSL_KCAPI_HASH)
    byte input1[] = "";
    byte input2[] = "abc";
    byte local[WC_SHA512_BLOCK_SIZE];
    word32 sLen = 0;
#ifdef BIG_ENDIAN_ORDER
    unsigned char output1[] =
        "\xcf\x78\x81\xd5\x77\x4a\xcb\xe8\x53\x33\x62\xe0\xfb\xc7\x80\x70"
        "\x02\x67\x63\x9d\x87\x46\x0e\xda\x30\x86\xcb\x40\xe8\x59\x31\xb0"
        "\x71\x7d\xc9\x52\x88\xa0\x23\xa3\x96\xba\xb2\xc1\x4c\xe0\xb5\xe0"
        "\x6f\xc4\xfe\x04\xea\xe3\x3e\x0b\x91\xf4\xd8\x0c\xbd\x66\x8b\xee";
   unsigned char output2[] =
        "\x11\x10\x93\x4e\xeb\xa0\xcc\x0d\xfd\x33\x43\x9c\xfb\x04\xc8\x21"
        "\xa9\xb4\x26\x3d\xca\xab\x31\x41\xe2\xc6\xaa\xaf\xe1\x67\xd7\xab"
        "\x31\x8f\x2e\x54\x2c\xba\x4e\x83\xbe\x88\xec\x9d\x8f\x2b\x38\x98"
        "\x14\xd2\x4e\x9d\x53\x8b\x5e\x4d\xde\x68\x6c\x69\xaf\x20\x96\xf0";
#else
    unsigned char output1[] =
        "\xe8\xcb\x4a\x77\xd5\x81\x78\xcf\x70\x80\xc7\xfb\xe0\x62\x33\x53"
        "\xda\x0e\x46\x87\x9d\x63\x67\x02\xb0\x31\x59\xe8\x40\xcb\x86\x30"
        "\xa3\x23\xa0\x88\x52\xc9\x7d\x71\xe0\xb5\xe0\x4c\xc1\xb2\xba\x96"
        "\x0b\x3e\xe3\xea\x04\xfe\xc4\x6f\xee\x8b\x66\xbd\x0c\xd8\xf4\x91";
   unsigned char output2[] =
        "\x0d\xcc\xa0\xeb\x4e\x93\x10\x11\x21\xc8\x04\xfb\x9c\x43\x33\xfd"
        "\x41\x31\xab\xca\x3d\x26\xb4\xa9\xab\xd7\x67\xe1\xaf\xaa\xc6\xe2"
        "\x83\x4e\xba\x2c\x54\x2e\x8f\x31\x98\x38\x2b\x8f\x9d\xec\x88\xbe"
        "\x4d\x5e\x8b\x53\x9d\x4e\xd2\x14\xf0\x96\x20\xaf\x69\x6c\x68\xde";
#endif
    union {
        wc_Sha512 native;
        SHA512_CTX compat;
    } sha512;

    XMEMSET(&sha512.compat, 0, sizeof(sha512.compat));
    XMEMSET(&local, 0, sizeof(local));

    /* sanity check */
    ExpectIntEQ(SHA512_Transform(NULL, NULL), 0);
    ExpectIntEQ(SHA512_Transform(NULL, (const byte*)&input1), 0);
    ExpectIntEQ(SHA512_Transform(&sha512.compat, NULL), 0);
    ExpectIntEQ(wc_Sha512Transform(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512Transform(NULL, (const byte*)&input1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512Transform(&sha512.native, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Init SHA512 CTX */
    ExpectIntEQ(wolfSSL_SHA512_Init(&sha512.compat), 1);

    /* Do Transform*/
    sLen = (word32)XSTRLEN((char*)input1);
    XMEMCPY(local, input1, sLen);
    ExpectIntEQ(SHA512_Transform(&sha512.compat, (const byte*)&local[0]), 1);
    ExpectIntEQ(XMEMCMP(sha512.native.digest, output1,
                                                    WC_SHA512_DIGEST_SIZE), 0);
    ExpectIntEQ(SHA512_Final(local, &sha512.compat), 1); /* frees resources */

    /* Init SHA512 CTX */
    ExpectIntEQ(SHA512_Init(&sha512.compat), 1);
    sLen = (word32)XSTRLEN((char*)input2);
    XMEMSET(local, 0, WC_SHA512_BLOCK_SIZE);
    XMEMCPY(local, input2, sLen);
    ExpectIntEQ(SHA512_Transform(&sha512.compat, (const byte*)&local[0]), 1);
    ExpectIntEQ(XMEMCMP(sha512.native.digest, output2,
                                                    WC_SHA512_DIGEST_SIZE), 0);
    ExpectIntEQ(SHA512_Final(local, &sha512.compat), 1); /* frees resources */

    (void)input1;
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SHA512_224_Transform(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA512) && \
    !defined(WOLFSSL_NOSHA512_224)
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \
        !defined(WOLFSSL_KCAPI_HASH)
    byte input1[] = "";
    byte input2[] = "abc";
    byte local[WC_SHA512_BLOCK_SIZE];
    word32 sLen = 0;
    unsigned char output1[] =
        "\x94\x24\x66\xd4\x60\x3a\xeb\x23\x1d\xa8\x69\x31\x3c\xd2\xde\x11"
        "\x48\x0f\x4a\x5a\xdf\x3a\x8d\x87\xcf\xcd\xbf\xa5\x03\x21\x50\xf1"
        "\x8a\x0d\x0f\x0d\x3c\x07\xba\x52\xe0\xaa\x3c\xbb\xf1\xd3\x3f\xca"
        "\x12\xa7\x61\xf8\x47\xda\x0d\x1b\x79\xc2\x65\x13\x92\xc1\x9c\xa5";
   unsigned char output2[] =
        "\x51\x28\xe7\x0b\xca\x1e\xbc\x5f\xd7\x34\x0b\x48\x30\xd7\xc2\x75"
        "\x6d\x8d\x48\x2c\x1f\xc7\x9e\x2b\x20\x5e\xbb\x0f\x0e\x4d\xb7\x61"
        "\x31\x76\x33\xa0\xb4\x3d\x5f\x93\xc1\x73\xac\xf7\x21\xff\x69\x17"
        "\xce\x66\xe5\x1e\x31\xe7\xf3\x22\x0f\x0b\x34\xd7\x5a\x57\xeb\xbf";
    union {
        wc_Sha512 native;
        SHA512_CTX compat;
    } sha512;

#ifdef BIG_ENDIAN_ORDER
    ByteReverseWords64((word64*)output1, (word64*)output1, sizeof(output1));
    ByteReverseWords64((word64*)output2, (word64*)output2, sizeof(output2));
#endif

    XMEMSET(&sha512.compat, 0, sizeof(sha512.compat));
    XMEMSET(&local, 0, sizeof(local));

    /* sanity check */
    ExpectIntEQ(SHA512_224_Transform(NULL, NULL), 0);
    ExpectIntEQ(SHA512_224_Transform(NULL, (const byte*)&input1), 0);
    ExpectIntEQ(SHA512_224_Transform(&sha512.compat, NULL), 0);
    ExpectIntEQ(wc_Sha512_224Transform(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_224Transform(NULL, (const byte*)&input1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_224Transform(&sha512.native, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Init SHA512 CTX */
    ExpectIntEQ(wolfSSL_SHA512_224_Init(&sha512.compat), 1);

    /* Do Transform*/
    sLen = (word32)XSTRLEN((char*)input1);
    XMEMCPY(local, input1, sLen);
    ExpectIntEQ(SHA512_224_Transform(&sha512.compat, (const byte*)&local[0]),
        1);
    ExpectIntEQ(XMEMCMP(sha512.native.digest, output1,
        WC_SHA512_DIGEST_SIZE), 0);
    /* frees resources */
    ExpectIntEQ(SHA512_224_Final(local, &sha512.compat), 1);

    /* Init SHA512 CTX */
    ExpectIntEQ(SHA512_224_Init(&sha512.compat), 1);
    sLen = (word32)XSTRLEN((char*)input2);
    XMEMSET(local, 0, WC_SHA512_BLOCK_SIZE);
    XMEMCPY(local, input2, sLen);
    ExpectIntEQ(SHA512_224_Transform(&sha512.compat, (const byte*)&local[0]),
        1);
    ExpectIntEQ(XMEMCMP(sha512.native.digest, output2,
        WC_SHA512_DIGEST_SIZE), 0);
    /* frees resources */
    ExpectIntEQ(SHA512_224_Final(local, &sha512.compat), 1);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SHA512_256_Transform(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA512) && \
    !defined(WOLFSSL_NOSHA512_256)
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \
        !defined(WOLFSSL_KCAPI_HASH)
    byte input1[] = "";
    byte input2[] = "abc";
    byte local[WC_SHA512_BLOCK_SIZE];
    word32 sLen = 0;
    unsigned char output1[] =
        "\xf8\x37\x37\x5a\xd7\x2e\x56\xec\xe2\x51\xa8\x31\x3a\xa0\x63\x2b"
        "\x7e\x7c\x64\xcc\xd9\xff\x2b\x6b\xeb\xc3\xd4\x4d\x7f\x8a\x3a\xb5"
        "\x61\x85\x0b\x37\x30\x9f\x3b\x08\x5e\x7b\xd3\xbc\x6d\x00\x61\xc0"
        "\x65\x9a\xd7\x73\xda\x40\xbe\xc1\xe5\x2f\xc6\x5d\xb7\x9f\xbe\x60";
   unsigned char output2[] =
        "\x22\xad\xc0\x30\xee\xd4\x6a\xef\x13\xee\x5a\x95\x8b\x1f\xb7\xb6"
        "\xb6\xba\xc0\x44\xb8\x18\x3b\xf0\xf6\x4b\x70\x9f\x03\xba\x64\xa1"
        "\xe1\xe3\x45\x15\x91\x7d\xcb\x0b\x9a\xf0\xd2\x8e\x47\x8b\x37\x78"
        "\x91\x41\xa6\xc4\xb0\x29\x8f\x8b\xdd\x78\x5c\xf2\x73\x3f\x21\x31";
    union {
        wc_Sha512 native;
        SHA512_CTX compat;
    } sha512;

#ifdef BIG_ENDIAN_ORDER
    ByteReverseWords64((word64*)output1, (word64*)output1, sizeof(output1));
    ByteReverseWords64((word64*)output2, (word64*)output2, sizeof(output2));
#endif

    XMEMSET(&sha512.compat, 0, sizeof(sha512.compat));
    XMEMSET(&local, 0, sizeof(local));

    /* sanity check */
    ExpectIntEQ(SHA512_256_Transform(NULL, NULL), 0);
    ExpectIntEQ(SHA512_256_Transform(NULL, (const byte*)&input1), 0);
    ExpectIntEQ(SHA512_256_Transform(&sha512.compat, NULL), 0);
    ExpectIntEQ(wc_Sha512_256Transform(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_256Transform(NULL, (const byte*)&input1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Sha512_256Transform(&sha512.native, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* Init SHA512 CTX */
    ExpectIntEQ(wolfSSL_SHA512_256_Init(&sha512.compat), 1);

    /* Do Transform*/
    sLen = (word32)XSTRLEN((char*)input1);
    XMEMCPY(local, input1, sLen);
    ExpectIntEQ(SHA512_256_Transform(&sha512.compat, (const byte*)&local[0]),
        1);
    ExpectIntEQ(XMEMCMP(sha512.native.digest, output1,
        WC_SHA512_DIGEST_SIZE), 0);
    /* frees resources */
    ExpectIntEQ(SHA512_256_Final(local, &sha512.compat), 1);

    /* Init SHA512 CTX */
    ExpectIntEQ(SHA512_256_Init(&sha512.compat), 1);
    sLen = (word32)XSTRLEN((char*)input2);
    XMEMSET(local, 0, WC_SHA512_BLOCK_SIZE);
    XMEMCPY(local, input2, sLen);
    ExpectIntEQ(SHA512_256_Transform(&sha512.compat, (const byte*)&local[0]),
        1);
    ExpectIntEQ(XMEMCMP(sha512.native.digest, output2,
        WC_SHA512_DIGEST_SIZE), 0);
    /* frees resources */
    ExpectIntEQ(SHA512_256_Final(local, &sha512.compat), 1);
#endif
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC)
/* helper function for test_wolfSSL_HMAC_CTX, digest size is expected to be a
 * buffer of 64 bytes.
 *
 * returns the size of the digest buffer on success and a negative value on
 * failure.
 */
static int test_HMAC_CTX_helper(const EVP_MD* type, unsigned char* digest,
    int* sz)
{
    EXPECT_DECLS;
    HMAC_CTX ctx1;
    HMAC_CTX ctx2;

    unsigned char key[] = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
                          "\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
    unsigned char long_key[] =
        "0123456789012345678901234567890123456789"
        "0123456789012345678901234567890123456789"
        "0123456789012345678901234567890123456789"
        "0123456789012345678901234567890123456789";

    unsigned char msg[] = "message to hash";
    unsigned int  digestSz = 64;
    int keySz = sizeof(key);
    int long_keySz = sizeof(long_key);
    int msgSz = sizeof(msg);

    unsigned char digest2[64];
    unsigned int digestSz2 = 64;

    HMAC_CTX_init(&ctx1);

    ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS);

    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS);
    HMAC_CTX_cleanup(&ctx1);

    ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz2), SSL_SUCCESS);
    HMAC_CTX_cleanup(&ctx2);

    ExpectIntEQ(digestSz, digestSz2);
    ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0);

    /* test HMAC_Init with NULL key */

    /* init after copy */
    HMAC_CTX_init(&ctx1);
    ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS);

    ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS);
    HMAC_CTX_cleanup(&ctx1);

    ExpectIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS);
    HMAC_CTX_cleanup(&ctx2);

    ExpectIntEQ(digestSz, digestSz2);
    ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0);

    /* long key */
    HMAC_CTX_init(&ctx1);
    ExpectIntEQ(HMAC_Init(&ctx1, (const void*)long_key, long_keySz, type),
        SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS);

    ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS);
    HMAC_CTX_cleanup(&ctx1);

    ExpectIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS);
    HMAC_CTX_cleanup(&ctx2);

    ExpectIntEQ(digestSz, digestSz2);
    ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0);

    /* init before copy */
    HMAC_CTX_init(&ctx1);
    ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS);
    ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS);

    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS);
    HMAC_CTX_cleanup(&ctx1);

    ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
    ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS);
    HMAC_CTX_cleanup(&ctx2);

    ExpectIntEQ(digestSz, digestSz2);
    ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0);

    *sz = (int)digestSz;
    return EXPECT_RESULT();
}
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_HMAC) */

static int test_wolfSSL_HMAC_CTX(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC)
    unsigned char digest[64];
    int digestSz;
    WOLFSSL_HMAC_CTX* hmac_ctx = NULL;
    WOLFSSL_HMAC_CTX ctx1;
    WOLFSSL_HMAC_CTX ctx2;

    ExpectNotNull(hmac_ctx = wolfSSL_HMAC_CTX_new());
    ExpectIntEQ(wolfSSL_HMAC_CTX_Init(NULL), 1);
    ExpectIntEQ(wolfSSL_HMAC_CTX_Init(hmac_ctx), 1);
    wolfSSL_HMAC_CTX_free(NULL);
    wolfSSL_HMAC_CTX_free(hmac_ctx);

    XMEMSET(&ctx2, 0, sizeof(WOLFSSL_HMAC_CTX));
    ExpectIntEQ(HMAC_CTX_init(NULL), 1);
    ExpectIntEQ(HMAC_CTX_init(&ctx2), 1);
    ExpectIntEQ(HMAC_CTX_copy(NULL, NULL), 0);
    ExpectIntEQ(HMAC_CTX_copy(NULL, &ctx2), 0);
    ExpectIntEQ(HMAC_CTX_copy(&ctx2, NULL), 0);
#if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && \
    ((! defined(HAVE_FIPS_VERSION)) || \
     defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION <= 2)))
    /* Copy object that hasn't had a digest set - MD5. */
    ExpectIntEQ(HMAC_CTX_copy(&ctx1, &ctx2), 1);
#else
    /* Copy object that hasn't had a digest set. */
    ExpectIntEQ(HMAC_CTX_copy(&ctx1, &ctx2), 0);
#endif
    HMAC_CTX_cleanup(NULL);
    HMAC_CTX_cleanup(&ctx2);

    ExpectNull(HMAC_CTX_get_md(NULL));

    #ifndef NO_SHA
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha1(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 20);
    ExpectIntEQ(XMEMCMP("\xD9\x68\x77\x23\x70\xFB\x53\x70\x53\xBA\x0E\xDC\xDA"
                          "\xBF\x03\x98\x31\x19\xB2\xCC", digest, digestSz), 0);
    #endif /* !NO_SHA */
    #ifdef WOLFSSL_SHA224
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha224(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 28);
    ExpectIntEQ(XMEMCMP("\x57\xFD\xF4\xE1\x2D\xB0\x79\xD7\x4B\x25\x7E\xB1\x95"
                          "\x9C\x11\xAC\x2D\x1E\x78\x94\x4F\x3A\x0F\xED\xF8\xAD"
                          "\x02\x0E", digest, digestSz), 0);
    #endif /* WOLFSSL_SHA224 */
    #ifndef NO_SHA256
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha256(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 32);
    ExpectIntEQ(XMEMCMP("\x13\xAB\x76\x91\x0C\x37\x86\x8D\xB3\x7E\x30\x0C\xFC"
                          "\xB0\x2E\x8E\x4A\xD7\xD4\x25\xCC\x3A\xA9\x0F\xA2\xF2"
                          "\x47\x1E\x62\x6F\x5D\xF2", digest, digestSz), 0);
    #endif /* !NO_SHA256 */

    #ifdef WOLFSSL_SHA384
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha384(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 48);
    ExpectIntEQ(XMEMCMP("\x9E\xCB\x07\x0C\x11\x76\x3F\x23\xC3\x25\x0E\xC4\xB7"
                          "\x28\x77\x95\x99\xD5\x9D\x7A\xBB\x1A\x9F\xB7\xFD\x25"
                          "\xC9\x72\x47\x9F\x8F\x86\x76\xD6\x20\x57\x87\xB7\xE7"
                          "\xCD\xFB\xC2\xCC\x9F\x2B\xC5\x41\xAB",
                          digest, digestSz), 0);
    #endif /* WOLFSSL_SHA384 */
    #ifdef WOLFSSL_SHA512
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha512(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 64);
    ExpectIntEQ(XMEMCMP("\xD4\x21\x0C\x8B\x60\x6F\xF4\xBF\x07\x2F\x26\xCC\xAD"
                          "\xBC\x06\x0B\x34\x78\x8B\x4F\xD6\xC0\x42\xF1\x33\x10"
                          "\x6C\x4F\x1E\x55\x59\xDD\x2A\x9F\x15\x88\x62\xF8\x60"
                          "\xA3\x99\x91\xE2\x08\x7B\xF7\x95\x3A\xB0\x92\x48\x60"
                          "\x88\x8B\x5B\xB8\x5F\xE9\xB6\xB1\x96\xE3\xB5\xF0",
                          digest, digestSz), 0);
    #endif /* WOLFSSL_SHA512 */

#ifdef WOLFSSL_SHA3
    #ifndef WOLFSSL_NOSHA3_224
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_224(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 28);
    ExpectIntEQ(XMEMCMP("\xdc\x53\x25\x3f\xc0\x9d\x2b\x0c\x7f\x59\x11\x17\x08"
                        "\x5c\xe8\x43\x31\x01\x5a\xb3\xe3\x08\x37\x71\x26\x0b"
                        "\x29\x0f", digest, digestSz), 0);
    #endif
    #ifndef WOLFSSL_NOSHA3_256
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_256(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 32);
    ExpectIntEQ(XMEMCMP("\x0f\x00\x89\x82\x15\xce\xd6\x45\x01\x83\xce\xc8\x35"
                        "\xab\x71\x07\xc9\xfe\x61\x22\x38\xf9\x09\xad\x35\x65"
                        "\x43\x77\x24\xd4\x1e\xf4", digest, digestSz), 0);
    #endif
    #ifndef WOLFSSL_NOSHA3_384
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_384(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 48);
    ExpectIntEQ(XMEMCMP("\x0f\x6a\xc0\xfb\xc3\xf2\x80\xb1\xb4\x04\xb6\xc8\x45"
                        "\x23\x3b\xb4\xbe\xc6\xea\x85\x07\xca\x8c\x71\xbb\x6e"
                        "\x79\xf6\xf9\x2b\x98\xf5\xef\x11\x39\xd4\x5d\xd3\xca"
                        "\xc0\xe6\x81\xf7\x73\xf9\x85\x5d\x4f",
                          digest, digestSz), 0);
    #endif
    #ifndef WOLFSSL_NOSHA3_512
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_512(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 64);
    ExpectIntEQ(XMEMCMP("\x3e\x77\xe3\x59\x42\x89\xed\xc3\xa4\x26\x3d\xa4\x75"
                        "\xd2\x84\x8c\xb2\xf3\x25\x04\x47\x61\xce\x1c\x42\x86"
                        "\xcd\xf4\x56\xaa\x2f\x84\xb1\x3b\x18\xed\xe6\xd6\x48"
                        "\x15\xb0\x29\xc5\x9d\x32\xef\xdd\x3e\x09\xf6\xed\x9e"
                        "\x70\xbc\x1c\x63\xf7\x3b\x3e\xe1\xdc\x84\x9c\x1c",
                          digest, digestSz), 0);
    #endif
#endif

    #if !defined(NO_MD5) && (!defined(HAVE_FIPS_VERSION) || \
        HAVE_FIPS_VERSION <= 2)
    ExpectIntEQ((test_HMAC_CTX_helper(EVP_md5(), digest, &digestSz)),
        TEST_SUCCESS);
    ExpectIntEQ(digestSz, 16);
    ExpectIntEQ(XMEMCMP("\xB7\x27\xC4\x41\xE5\x2E\x62\xBA\x54\xED\x72\x70\x9F"
                          "\xE4\x98\xDD", digest, digestSz), 0);
    #endif /* !NO_MD5 */
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && (!defined(NO_SHA256) || \
    defined(WOLFSSL_SHA224) || defined(WOLFSSL_SHA384) || \
    defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA3))
static int test_openssl_hmac(const WOLFSSL_EVP_MD* md, int md_len)
{
    EXPECT_DECLS;
    static const unsigned char key[] = "simple test key";
    HMAC_CTX* hmac = NULL;
    ENGINE* e = NULL;
    unsigned char hash[WC_MAX_DIGEST_SIZE];
    unsigned int len;

    ExpectNotNull(hmac = HMAC_CTX_new());
    HMAC_CTX_init(hmac);
#if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && \
    ((! defined(HAVE_FIPS_VERSION)) || \
     defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION <= 2)))
    /* Get size on object that hasn't had a digest set - MD5. */
    ExpectIntEQ(HMAC_size(hmac), 16);
    ExpectIntEQ(HMAC_Init(hmac, NULL, 0, NULL), 1);
    ExpectIntEQ(HMAC_Init(hmac, (void*)key, (int)sizeof(key), NULL), 1);
    ExpectIntEQ(HMAC_Init(hmac, NULL, 0, md), 1);
#else
    ExpectIntEQ(HMAC_size(hmac), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(HMAC_Init(hmac, NULL, 0, NULL), 0);
    ExpectIntEQ(HMAC_Init(hmac, (void*)key, (int)sizeof(key), NULL), 0);
    ExpectIntEQ(HMAC_Init(hmac, NULL, 0, md), 0);
#endif
    ExpectIntEQ(HMAC_Init_ex(NULL, (void*)key, (int)sizeof(key), md, e), 0);
    ExpectIntEQ(HMAC_Init_ex(hmac, (void*)key, (int)sizeof(key), md, e), 1);

    /* re-using test key as data to hash */
    ExpectIntEQ(HMAC_Update(NULL, key, (int)sizeof(key)), 0);
    ExpectIntEQ(HMAC_Update(hmac, key, (int)sizeof(key)), 1);
    ExpectIntEQ(HMAC_Update(hmac, key, 0), 1);
    ExpectIntEQ(HMAC_Update(hmac, NULL, 0), 1);
    ExpectIntEQ(HMAC_Update(hmac, NULL, (int)sizeof(key)), 1);
    ExpectIntEQ(HMAC_Final(NULL, NULL, &len), 0);
    ExpectIntEQ(HMAC_Final(hmac, NULL, &len), 0);
    ExpectIntEQ(HMAC_Final(NULL, hash, &len), 0);
    ExpectIntEQ(HMAC_Final(hmac, hash, &len), 1);
    ExpectIntEQ(HMAC_Final(hmac, hash, NULL), 1);
    ExpectIntEQ(len, md_len);
    ExpectIntEQ(HMAC_size(NULL), 0);
    ExpectIntEQ(HMAC_size(hmac), md_len);
    ExpectStrEQ(HMAC_CTX_get_md(hmac), md);

    HMAC_cleanup(NULL);
    HMAC_cleanup(hmac);
    HMAC_CTX_free(hmac);

    len = 0;
    ExpectNull(HMAC(NULL, key, (int)sizeof(key), NULL, 0, hash, &len));
    ExpectNull(HMAC(md, NULL, (int)sizeof(key), NULL, 0, hash, &len));
    ExpectNull(HMAC(md, key, (int)sizeof(key), NULL, 0, NULL, &len));
    ExpectNotNull(HMAC(md, key, (int)sizeof(key), NULL, 0, hash, &len));
    ExpectIntEQ(len, md_len);
    ExpectNotNull(HMAC(md, key, (int)sizeof(key), NULL, 0, hash, NULL));
    /* With data. */
    ExpectNotNull(HMAC(md, key, (int)sizeof(key), key, (int)sizeof(key), hash,
        &len));
    /* With NULL data. */
    ExpectNull(HMAC(md, key, (int)sizeof(key), NULL, (int)sizeof(key), hash,
        &len));
    /* With zero length data. */
    ExpectNotNull(HMAC(md, key, (int)sizeof(key), key, 0, hash, &len));

    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_HMAC(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && (!defined(NO_SHA256) || \
    defined(WOLFSSL_SHA224) || defined(WOLFSSL_SHA384) || \
    defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA3))
#ifndef NO_SHA256
    ExpectIntEQ(test_openssl_hmac(EVP_sha256(), (int)WC_SHA256_DIGEST_SIZE),
        TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA224
    ExpectIntEQ(test_openssl_hmac(EVP_sha224(), (int)WC_SHA224_DIGEST_SIZE),
        TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA384
    ExpectIntEQ(test_openssl_hmac(EVP_sha384(), (int)WC_SHA384_DIGEST_SIZE),
        TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA512
    ExpectIntEQ(test_openssl_hmac(EVP_sha512(), (int)WC_SHA512_DIGEST_SIZE),
        TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA3
    #ifndef WOLFSSL_NOSHA3_224
        ExpectIntEQ(test_openssl_hmac(EVP_sha3_224(),
             (int)WC_SHA3_224_DIGEST_SIZE), TEST_SUCCESS);
    #endif
    #ifndef WOLFSSL_NOSHA3_256
        ExpectIntEQ(test_openssl_hmac(EVP_sha3_256(),
             (int)WC_SHA3_256_DIGEST_SIZE), TEST_SUCCESS);
    #endif
    #ifndef WOLFSSL_NOSHA3_384
        ExpectIntEQ(test_openssl_hmac(EVP_sha3_384(),
             (int)WC_SHA3_384_DIGEST_SIZE), TEST_SUCCESS);
    #endif
    #ifndef WOLFSSL_NOSHA3_512
        ExpectIntEQ(test_openssl_hmac(EVP_sha3_512(),
             (int)WC_SHA3_512_DIGEST_SIZE), TEST_SUCCESS);
    #endif
#endif
#ifndef NO_SHA
    ExpectIntEQ(test_openssl_hmac(EVP_sha1(), (int)WC_SHA_DIGEST_SIZE),
        TEST_SUCCESS);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CMAC(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_AES_DIRECT)
    int i;
    byte key[AES_256_KEY_SIZE];
    CMAC_CTX* cmacCtx = NULL;
    byte out[AES_BLOCK_SIZE];
    size_t outLen = AES_BLOCK_SIZE;

    for (i=0; i < AES_256_KEY_SIZE; ++i) {
        key[i] = i;
    }
    ExpectNotNull(cmacCtx = CMAC_CTX_new());
    /* Check CMAC_CTX_get0_cipher_ctx; return value not used. */
    ExpectNotNull(CMAC_CTX_get0_cipher_ctx(cmacCtx));
    ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(),
        NULL), 1);
    /* re-using test key as data to hash */
    ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), 1);
    ExpectIntEQ(CMAC_Update(cmacCtx, NULL, 0), 1);
    ExpectIntEQ(CMAC_Final(cmacCtx, out, &outLen), 1);
    ExpectIntEQ(outLen, AES_BLOCK_SIZE);

    /* No Update works. */
    ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(),
        NULL), 1);
    ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1);

    ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(),
        NULL), 1);
    /* Test parameters with CMAC_Update. */
    ExpectIntEQ(CMAC_Update(NULL, NULL, 0), 0);
    ExpectIntEQ(CMAC_Update(NULL, key, 0), 0);
    ExpectIntEQ(CMAC_Update(NULL, NULL, AES_128_KEY_SIZE), 0);
    ExpectIntEQ(CMAC_Update(NULL, key, AES_128_KEY_SIZE), 0);
    ExpectIntEQ(CMAC_Update(cmacCtx, key, 0), 1);
    ExpectIntEQ(CMAC_Update(cmacCtx, NULL, 0), 1);
    ExpectIntEQ(CMAC_Update(cmacCtx, NULL, AES_128_KEY_SIZE), 1);
    /* Test parameters with CMAC_Final. */
    ExpectIntEQ(CMAC_Final(NULL, NULL, NULL), 0);
    ExpectIntEQ(CMAC_Final(NULL, out, NULL), 0);
    ExpectIntEQ(CMAC_Final(NULL, NULL, &outLen), 0);
    ExpectIntEQ(CMAC_Final(NULL, out, &outLen), 0);
    ExpectIntEQ(CMAC_Final(cmacCtx, NULL, NULL), 1);
    ExpectIntEQ(CMAC_Final(cmacCtx, NULL, &outLen), 1);
    ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1);
    CMAC_CTX_free(cmacCtx);

    /* Test parameters with CMAC Init. */
    cmacCtx = NULL;
    ExpectNotNull(cmacCtx = CMAC_CTX_new());
    ExpectNotNull(CMAC_CTX_get0_cipher_ctx(cmacCtx));
    ExpectIntEQ(CMAC_Init(NULL, NULL, 0, NULL, NULL), 0);
    ExpectIntEQ(CMAC_Init(NULL, key, AES_192_KEY_SIZE, EVP_aes_192_cbc(),
        NULL), 0);
    ExpectIntEQ(CMAC_Init(cmacCtx, NULL, AES_192_KEY_SIZE, EVP_aes_192_cbc(),
        NULL), 0);
    /* give a key too small for the cipher, verify we get failure */
    ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_192_cbc(),
        NULL), 0);
    ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_192_KEY_SIZE, NULL, NULL), 0);
    #if defined(HAVE_AESGCM) && defined(WOLFSSL_AES_128)
    /* Only AES-CBC supported. */
    ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_gcm(),
        NULL), 0);
    #endif
    CMAC_CTX_free(cmacCtx);

    ExpectNull(CMAC_CTX_get0_cipher_ctx(NULL));
    cmacCtx = NULL;
    ExpectNotNull(cmacCtx = CMAC_CTX_new());
    /* No Init. */
    ExpectIntEQ(CMAC_Final(cmacCtx, out, &outLen), 0);
    CMAC_CTX_free(cmacCtx);

    /* Test AES-256-CBC */
    cmacCtx = NULL;
    ExpectNotNull(cmacCtx = CMAC_CTX_new());
    ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_256_KEY_SIZE, EVP_aes_256_cbc(),
        NULL), 1);
    ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), 1);
    ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1);
    CMAC_CTX_free(cmacCtx);

    /* Test AES-192-CBC */
    cmacCtx = NULL;
    ExpectNotNull(cmacCtx = CMAC_CTX_new());
    ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_192_KEY_SIZE, EVP_aes_192_cbc(),
        NULL), 1);
    ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), 1);
    ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1);
    CMAC_CTX_free(cmacCtx);

    cmacCtx = NULL;
    ExpectNotNull(cmacCtx = CMAC_CTX_new());
    CMAC_CTX_free(cmacCtx);
#endif /* WOLFSSL_CMAC && OPENSSL_EXTRA && WOLFSSL_AES_DIRECT */
    return EXPECT_RESULT();
}

static int test_wolfSSL_DES(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DES3)
    const_DES_cblock myDes;
    DES_cblock iv;
    DES_key_schedule key;
    word32 i = 0;
    DES_LONG dl = 0;
    unsigned char msg[] = "hello wolfssl";
    unsigned char weakKey[][8] = {
        { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
        { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
        { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
        { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }
    };
    unsigned char semiWeakKey[][8] = {
        { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
        { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
        { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
        { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
        { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
        { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
        { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
        { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
        { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
        { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
        { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
        { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
    };

    DES_check_key(1);
    DES_set_key(&myDes, &key);

    /* check, check of odd parity */
    XMEMSET(myDes, 4, sizeof(const_DES_cblock));
    myDes[0] = 6; /* set even parity */
    XMEMSET(key, 5, sizeof(DES_key_schedule));
    ExpectIntEQ(DES_set_key_checked(&myDes, &key), -1);
    ExpectIntNE(key[0], myDes[0]); /* should not have copied over key */
    ExpectIntEQ(DES_set_key_checked(NULL, NULL), -2);
    ExpectIntEQ(DES_set_key_checked(&myDes, NULL), -2);
    ExpectIntEQ(DES_set_key_checked(NULL, &key), -2);

    /* set odd parity for success case */
    DES_set_odd_parity(&myDes);
    ExpectIntEQ(DES_check_key_parity(&myDes), 1);
    fprintf(stderr, "%02x %02x %02x %02x", myDes[0], myDes[1], myDes[2],
        myDes[3]);
    ExpectIntEQ(DES_set_key_checked(&myDes, &key), 0);
    for (i = 0; i < sizeof(DES_key_schedule); i++) {
        ExpectIntEQ(key[i], myDes[i]);
    }
    ExpectIntEQ(DES_is_weak_key(&myDes), 0);

    /* check weak key */
    XMEMSET(myDes, 1, sizeof(const_DES_cblock));
    XMEMSET(key, 5, sizeof(DES_key_schedule));
    ExpectIntEQ(DES_set_key_checked(&myDes, &key), -2);
    ExpectIntNE(key[0], myDes[0]); /* should not have copied over key */

    DES_set_key_unchecked(NULL, NULL);
    DES_set_key_unchecked(&myDes, NULL);
    DES_set_key_unchecked(NULL, &key);
    /* compare arrays, should be the same */
    /* now do unchecked copy of a weak key over */
    DES_set_key_unchecked(&myDes, &key);
    /* compare arrays, should be the same */
    for (i = 0; i < sizeof(DES_key_schedule); i++) {
        ExpectIntEQ(key[i], myDes[i]);
    }
    ExpectIntEQ(DES_is_weak_key(&myDes), 1);

    myDes[7] = 2;
    ExpectIntEQ(DES_set_key_checked(&myDes, &key), 0);
    ExpectIntEQ(DES_is_weak_key(&myDes), 0);
    ExpectIntEQ(DES_is_weak_key(NULL), 1);

    /* Test all weak keys. */
    for (i = 0; i < sizeof(weakKey) / sizeof(*weakKey); i++) {
        ExpectIntEQ(DES_set_key_checked(&weakKey[i], &key), -2);
    }
    /* Test all semi-weak keys. */
    for (i = 0; i < sizeof(semiWeakKey) / sizeof(*semiWeakKey); i++) {
        ExpectIntEQ(DES_set_key_checked(&semiWeakKey[i], &key), -2);
    }

    /* check DES_key_sched API */
    XMEMSET(key, 1, sizeof(DES_key_schedule));
    ExpectIntEQ(DES_key_sched(&myDes, NULL), 0);
    ExpectIntEQ(DES_key_sched(NULL, &key),   0);
    ExpectIntEQ(DES_key_sched(&myDes, &key), 0);
    /* compare arrays, should be the same */
    for (i = 0; i < sizeof(DES_key_schedule); i++) {
        ExpectIntEQ(key[i], myDes[i]);
    }


    ExpectIntEQ((DES_cbc_cksum(NULL, NULL, 0, NULL, NULL)), 0);
    ExpectIntEQ((DES_cbc_cksum(msg, NULL, 0, NULL, NULL)), 0);
    ExpectIntEQ((DES_cbc_cksum(NULL, &key, 0, NULL, NULL)), 0);
    ExpectIntEQ((DES_cbc_cksum(NULL, NULL, 0, &myDes, NULL)), 0);
    ExpectIntEQ((DES_cbc_cksum(NULL, NULL, 0, NULL, &iv)), 0);
    ExpectIntEQ((DES_cbc_cksum(NULL, &key, sizeof(msg), &myDes, &iv)), 0);
    ExpectIntEQ((DES_cbc_cksum(msg, NULL, sizeof(msg), &myDes, &iv)), 0);
    ExpectIntEQ((DES_cbc_cksum(msg, &key, sizeof(msg), NULL, &iv)), 0);
    ExpectIntEQ((DES_cbc_cksum(msg, &key, sizeof(msg), &myDes, NULL)), 0);
    /* DES_cbc_cksum should return the last 4 of the last 8 bytes after
     * DES_cbc_encrypt on the input */
    XMEMSET(iv, 0, sizeof(DES_cblock));
    XMEMSET(myDes, 5, sizeof(DES_key_schedule));
    ExpectIntGT((dl = DES_cbc_cksum(msg, &key, sizeof(msg), &myDes, &iv)), 0);
    ExpectIntEQ(dl, 480052723);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_DES_ncbc(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DES3)
    const_DES_cblock myDes;
    DES_cblock iv = {1};
    DES_key_schedule key = {0};
    unsigned char msg[] = "hello wolfssl";
    unsigned char out[DES_BLOCK_SIZE * 2] = {0};
    unsigned char pln[DES_BLOCK_SIZE * 2] = {0};

    unsigned char exp[]  = {0x31, 0x98, 0x2F, 0x3A, 0x55, 0xBF, 0xD8, 0xC4};
    unsigned char exp2[] = {0xC7, 0x45, 0x8B, 0x28, 0x10, 0x53, 0xE0, 0x58};

    /* partial block test */
    DES_set_key(&key, &myDes);
    DES_ncbc_encrypt(msg, out, 3, &myDes, &iv, DES_ENCRYPT);
    ExpectIntEQ(XMEMCMP(exp, out, DES_BLOCK_SIZE), 0);
    ExpectIntEQ(XMEMCMP(exp, iv, DES_BLOCK_SIZE), 0);

    DES_set_key(&key, &myDes);
    XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE);
    *((byte*)&iv) = 1;
    DES_ncbc_encrypt(out, pln, 3, &myDes, &iv, DES_DECRYPT);
    ExpectIntEQ(XMEMCMP(msg, pln, 3), 0);
    ExpectIntEQ(XMEMCMP(exp, iv, DES_BLOCK_SIZE), 0);

    /* full block test */
    DES_set_key(&key, &myDes);
    XMEMSET(pln, 0, DES_BLOCK_SIZE);
    XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE);
    *((byte*)&iv) = 1;
    DES_ncbc_encrypt(msg, out, 8, &myDes, &iv, DES_ENCRYPT);
    ExpectIntEQ(XMEMCMP(exp2, out, DES_BLOCK_SIZE), 0);
    ExpectIntEQ(XMEMCMP(exp2, iv, DES_BLOCK_SIZE), 0);

    DES_set_key(&key, &myDes);
    XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE);
    *((byte*)&iv) = 1;
    DES_ncbc_encrypt(out, pln, 8, &myDes, &iv, DES_DECRYPT);
    ExpectIntEQ(XMEMCMP(msg, pln, 8), 0);
    ExpectIntEQ(XMEMCMP(exp2, iv, DES_BLOCK_SIZE), 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DES_ecb_encrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) && defined(WOLFSSL_DES_ECB)
    WOLFSSL_DES_cblock input1, input2, output1, output2, back1, back2;
    WOLFSSL_DES_key_schedule key;

    XMEMCPY(key, "12345678", sizeof(WOLFSSL_DES_key_schedule));
    XMEMCPY(input1, "Iamhuman", sizeof(WOLFSSL_DES_cblock));
    XMEMCPY(input2, "Whoisit?", sizeof(WOLFSSL_DES_cblock));
    XMEMSET(output1, 0, sizeof(WOLFSSL_DES_cblock));
    XMEMSET(output2, 0, sizeof(WOLFSSL_DES_cblock));
    XMEMSET(back1, 0, sizeof(WOLFSSL_DES_cblock));
    XMEMSET(back2, 0, sizeof(WOLFSSL_DES_cblock));

    wolfSSL_DES_ecb_encrypt(NULL, NULL, NULL, DES_ENCRYPT);
    wolfSSL_DES_ecb_encrypt(&input1, NULL, NULL, DES_ENCRYPT);
    wolfSSL_DES_ecb_encrypt(NULL, &output1, NULL, DES_ENCRYPT);
    wolfSSL_DES_ecb_encrypt(NULL, NULL, &key, DES_ENCRYPT);
    wolfSSL_DES_ecb_encrypt(&input1, &output1, NULL, DES_ENCRYPT);
    wolfSSL_DES_ecb_encrypt(&input1, NULL, &key, DES_ENCRYPT);
    wolfSSL_DES_ecb_encrypt(NULL, &output1, &key, DES_ENCRYPT);

    /* Encrypt messages */
    wolfSSL_DES_ecb_encrypt(&input1, &output1, &key, DES_ENCRYPT);
    wolfSSL_DES_ecb_encrypt(&input2, &output2, &key, DES_ENCRYPT);

    {
        /* Decrypt messages */
        int ret1 = 0;
        int ret2 = 0;
        wolfSSL_DES_ecb_encrypt(&output1, &back1, &key, DES_DECRYPT);
        ExpectIntEQ(ret1 = XMEMCMP((unsigned char *)back1,
            (unsigned char *)input1, sizeof(WOLFSSL_DES_cblock)), 0);
        wolfSSL_DES_ecb_encrypt(&output2, &back2, &key, DES_DECRYPT);
        ExpectIntEQ(ret2 = XMEMCMP((unsigned char *)back2,
            (unsigned char *)input2, sizeof(WOLFSSL_DES_cblock)), 0);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DES_ede3_cbc_encrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DES3)
    unsigned char input1[8], input2[8];
    unsigned char output1[8], output2[8];
    unsigned char back1[8], back2[8];
    WOLFSSL_DES_cblock iv1, iv2;
    WOLFSSL_DES_key_schedule key1, key2, key3;
    int i;

    XMEMCPY(key1, "12345678", sizeof(WOLFSSL_DES_key_schedule));
    XMEMCPY(key2, "23456781", sizeof(WOLFSSL_DES_key_schedule));
    XMEMCPY(key3, "34567823", sizeof(WOLFSSL_DES_key_schedule));
    XMEMCPY(input1, "Iamhuman", sizeof(input1));
    XMEMCPY(input2, "Whoisit?", sizeof(input2));

    XMEMSET(output1, 0, sizeof(output1));
    XMEMSET(output2, 0, sizeof(output2));
    XMEMSET(back1, 0, sizeof(back1));
    XMEMSET(back2, 0, sizeof(back2));

    XMEMCPY(iv1, "87654321", sizeof(WOLFSSL_DES_cblock));
    XMEMCPY(iv2, "98765432", sizeof(WOLFSSL_DES_cblock));
    /* Encrypt messages */
    wolfSSL_DES_ede3_cbc_encrypt(input1, output1, 8, &key1, &key2, &key3, &iv1,
        DES_ENCRYPT);
    wolfSSL_DES_ede3_cbc_encrypt(input2, output2, 8, &key1, &key2, &key3, &iv2,
        DES_ENCRYPT);

    {
        XMEMCPY(iv1, "87654321", sizeof(WOLFSSL_DES_cblock));
        XMEMCPY(iv2, "98765432", sizeof(WOLFSSL_DES_cblock));
        /* Decrypt messages */
        wolfSSL_DES_ede3_cbc_encrypt(output1, back1, 8, &key1, &key2, &key3,
            &iv1, DES_DECRYPT);
        ExpectIntEQ(XMEMCMP(back1, input1, sizeof(input1)), 0);
        wolfSSL_DES_ede3_cbc_encrypt(output2, back2, 8, &key1, &key2, &key3,
            &iv2, DES_DECRYPT);
        ExpectIntEQ(XMEMCMP(back2, input2, sizeof(input2)), 0);
    }

    for (i = 0; i < 8; i++) {
        XMEMSET(output1, 0, sizeof(output1));
        XMEMSET(output2, 0, sizeof(output2));
        XMEMSET(back1, 0, sizeof(back1));
        XMEMSET(back2, 0, sizeof(back2));

        XMEMCPY(iv1, "87654321", sizeof(WOLFSSL_DES_cblock));
        XMEMCPY(iv2, "98765432", sizeof(WOLFSSL_DES_cblock));
        /* Encrypt partial messages */
        wolfSSL_DES_ede3_cbc_encrypt(input1, output1, i, &key1, &key2, &key3,
            &iv1, DES_ENCRYPT);
        wolfSSL_DES_ede3_cbc_encrypt(input2, output2, i, &key1, &key2, &key3,
            &iv2, DES_ENCRYPT);

        {
            XMEMCPY(iv1, "87654321", sizeof(WOLFSSL_DES_cblock));
            XMEMCPY(iv2, "98765432", sizeof(WOLFSSL_DES_cblock));
            /* Decrypt messages */
            wolfSSL_DES_ede3_cbc_encrypt(output1, back1, i, &key1, &key2,
                &key3, &iv1, DES_DECRYPT);
            ExpectIntEQ(XMEMCMP(back1, input1, i), 0);
            wolfSSL_DES_ede3_cbc_encrypt(output2, back2, i, &key1, &key2,
                &key3, &iv2, DES_DECRYPT);
            ExpectIntEQ(XMEMCMP(back2, input2, i), 0);
        }
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_AES_encrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AES_ECB) \
        && !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API)
    AES_KEY enc;
    AES_KEY dec;
    const byte msg[] = {
        0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
        0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a
    };
    const byte exp[] = {
        0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
        0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8,
    };
    const byte key[] = {
        0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
        0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
        0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
        0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
    };
    byte eout[sizeof(msg)];
    byte dout[sizeof(msg)];

    ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &enc), 0);
    ExpectIntEQ(AES_set_decrypt_key(key, sizeof(key)*8, &dec), 0);

    wolfSSL_AES_encrypt(NULL, NULL, NULL);
    wolfSSL_AES_encrypt(msg, NULL, NULL);
    wolfSSL_AES_encrypt(NULL, eout, NULL);
    wolfSSL_AES_encrypt(NULL, NULL, &enc);
    wolfSSL_AES_encrypt(msg, eout, NULL);
    wolfSSL_AES_encrypt(msg, NULL, &enc);
    wolfSSL_AES_encrypt(NULL, eout, &enc);

    wolfSSL_AES_decrypt(NULL, NULL, NULL);
    wolfSSL_AES_decrypt(eout, NULL, NULL);
    wolfSSL_AES_decrypt(NULL, dout, NULL);
    wolfSSL_AES_decrypt(NULL, NULL, &dec);
    wolfSSL_AES_decrypt(eout, dout, NULL);
    wolfSSL_AES_decrypt(eout, NULL, &dec);
    wolfSSL_AES_decrypt(NULL, dout, &dec);

    wolfSSL_AES_encrypt(msg, eout, &enc);
    ExpectIntEQ(XMEMCMP(eout, exp, AES_BLOCK_SIZE), 0);
    wolfSSL_AES_decrypt(eout, dout, &dec);
    ExpectIntEQ(XMEMCMP(dout, msg, AES_BLOCK_SIZE), 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_AES_ecb_encrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AES_ECB) \
        && !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API)
    AES_KEY aes;
    const byte msg[] =
    {
      0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
      0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a
    };

    const byte verify[] =
    {
        0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c,
        0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8
    };

    const byte key[] =
    {
      0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,
      0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,
      0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,
      0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4
    };


    byte out[AES_BLOCK_SIZE];

    ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aes), 0);
    XMEMSET(out, 0, AES_BLOCK_SIZE);
    AES_ecb_encrypt(msg, out, &aes, AES_ENCRYPT);
    ExpectIntEQ(XMEMCMP(out, verify, AES_BLOCK_SIZE), 0);

#ifdef HAVE_AES_DECRYPT
    ExpectIntEQ(AES_set_decrypt_key(key, sizeof(key)*8, &aes), 0);
    XMEMSET(out, 0, AES_BLOCK_SIZE);
    AES_ecb_encrypt(verify, out, &aes, AES_DECRYPT);
    ExpectIntEQ(XMEMCMP(out, msg, AES_BLOCK_SIZE), 0);
#endif

    /* test bad arguments */
    AES_ecb_encrypt(NULL, out, &aes, AES_DECRYPT);
    AES_ecb_encrypt(verify, NULL, &aes, AES_DECRYPT);
    AES_ecb_encrypt(verify, out, NULL, AES_DECRYPT);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_AES_cbc_encrypt(void)
{
    EXPECT_DECLS;
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) && \
        !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API)
    AES_KEY aes;
    AES_KEY* aesN = NULL;
    size_t len = 0;
    size_t lenB = 0;
    int keySz0 = 0;
    int keySzN = -1;
    byte out[AES_BLOCK_SIZE] = {0};
    byte* outN = NULL;

    /* Test vectors retrieved from:
     *   <begin URL>
     *       https://csrc.nist.gov/
     *       CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/
     *       documents/aes/KAT_AES.zip
     *   </end URL>
     */
    const byte* pt128N  = NULL;
    byte* key128N       = NULL;
    byte* iv128N        = NULL;
    byte iv128tmp[AES_BLOCK_SIZE] = {0};

    const byte pt128[]  = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };

    const byte ct128[]  = { 0x87,0x85,0xb1,0xa7,0x5b,0x0f,0x3b,0xd9,
                            0x58,0xdc,0xd0,0xe2,0x93,0x18,0xc5,0x21 };

    const byte iv128[]  = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };

    byte key128[]       = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                            0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00 };


    len = sizeof(pt128);

    #define STRESS_T(a, b, c, d, e, f, g, h, i) \
            wolfSSL_AES_cbc_encrypt(a, b, c, d, e, f); \
            ExpectIntNE(XMEMCMP(b, g, h), i)

    #define RESET_IV(x, y) XMEMCPY(x, y, AES_BLOCK_SIZE)

    /* Stressing wolfSSL_AES_cbc_encrypt() */
    STRESS_T(pt128N, out, len, &aes, iv128tmp, 1, ct128, AES_BLOCK_SIZE, 0);
    STRESS_T(pt128, out, len, &aes, iv128N, 1, ct128, AES_BLOCK_SIZE, 0);

    wolfSSL_AES_cbc_encrypt(pt128, outN, len, &aes, iv128tmp, AES_ENCRYPT);
    ExpectIntNE(XMEMCMP(out, ct128, AES_BLOCK_SIZE), 0);
    wolfSSL_AES_cbc_encrypt(pt128, out, len, aesN, iv128tmp, AES_ENCRYPT);
    ExpectIntNE(XMEMCMP(out, ct128, AES_BLOCK_SIZE), 0);

    STRESS_T(pt128, out, lenB, &aes, iv128tmp, 1, ct128, AES_BLOCK_SIZE, 0);

    /* Stressing wolfSSL_AES_set_encrypt_key */
    ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128N, sizeof(key128)*8, &aes),0);
    ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128, sizeof(key128)*8, aesN),0);
    ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128, keySz0, &aes), 0);
    ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128, keySzN, &aes), 0);

    /* Stressing wolfSSL_AES_set_decrypt_key */
    ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128N, sizeof(key128)*8, &aes),0);
    ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128N, sizeof(key128)*8, aesN),0);
    ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128, keySz0, &aes), 0);
    ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128, keySzN, &aes), 0);

  #ifdef WOLFSSL_AES_128

    /* wolfSSL_AES_cbc_encrypt() 128-bit */
    XMEMSET(out, 0, AES_BLOCK_SIZE);
    RESET_IV(iv128tmp, iv128);

    ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key128, sizeof(key128)*8, &aes), 0);
    wolfSSL_AES_cbc_encrypt(pt128, out, len, &aes, iv128tmp, AES_ENCRYPT);
    ExpectIntEQ(XMEMCMP(out, ct128, AES_BLOCK_SIZE), 0);
    wc_AesFree((Aes*)&aes);

    #ifdef HAVE_AES_DECRYPT

    /* wolfSSL_AES_cbc_encrypt() 128-bit in decrypt mode */
    XMEMSET(out, 0, AES_BLOCK_SIZE);
    RESET_IV(iv128tmp, iv128);
    len = sizeof(ct128);

    ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key128, sizeof(key128)*8, &aes), 0);
    wolfSSL_AES_cbc_encrypt(ct128, out, len, &aes, iv128tmp, AES_DECRYPT);
    ExpectIntEQ(XMEMCMP(out, pt128, AES_BLOCK_SIZE), 0);
    wc_AesFree((Aes*)&aes);

    #endif

  #endif /* WOLFSSL_AES_128 */
  #ifdef WOLFSSL_AES_192
  {
    /* Test vectors from NIST Special Publication 800-38A, 2001 Edition
     * Appendix F.2.3  */

    byte iv192tmp[AES_BLOCK_SIZE] = {0};

    const byte pt192[]  = { 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
                            0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a };

    const byte ct192[]  = { 0x4f,0x02,0x1d,0xb2,0x43,0xbc,0x63,0x3d,
                            0x71,0x78,0x18,0x3a,0x9f,0xa0,0x71,0xe8 };

    const byte iv192[]  = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
                            0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F };

    byte key192[]       = { 0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52,
                            0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5,
                            0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b };

    len = sizeof(pt192);

    /* wolfSSL_AES_cbc_encrypt() 192-bit */
    XMEMSET(out, 0, AES_BLOCK_SIZE);
    RESET_IV(iv192tmp, iv192);

    ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key192, sizeof(key192)*8, &aes), 0);
    wolfSSL_AES_cbc_encrypt(pt192, out, len, &aes, iv192tmp, AES_ENCRYPT);
    ExpectIntEQ(XMEMCMP(out, ct192, AES_BLOCK_SIZE), 0);
    wc_AesFree((Aes*)&aes);

    #ifdef HAVE_AES_DECRYPT

    /* wolfSSL_AES_cbc_encrypt() 192-bit in decrypt mode */
    len = sizeof(ct192);
    RESET_IV(iv192tmp, iv192);
    XMEMSET(out, 0, AES_BLOCK_SIZE);

    ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key192, sizeof(key192)*8, &aes), 0);
    wolfSSL_AES_cbc_encrypt(ct192, out, len, &aes, iv192tmp, AES_DECRYPT);
    ExpectIntEQ(XMEMCMP(out, pt192, AES_BLOCK_SIZE), 0);
    wc_AesFree((Aes*)&aes);

    #endif
  }
  #endif /* WOLFSSL_AES_192 */
  #ifdef WOLFSSL_AES_256
  {
    /* Test vectors from NIST Special Publication 800-38A, 2001 Edition,
     * Appendix F.2.5  */
    byte iv256tmp[AES_BLOCK_SIZE] = {0};

    const byte pt256[]  = { 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
                            0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a };

    const byte ct256[]  = { 0xf5,0x8c,0x4c,0x04,0xd6,0xe5,0xf1,0xba,
                            0x77,0x9e,0xab,0xfb,0x5f,0x7b,0xfb,0xd6 };

    const byte iv256[]  = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
                            0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F };

    byte key256[]       = { 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,
                            0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,
                            0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,
                            0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 };


    len = sizeof(pt256);

    /* wolfSSL_AES_cbc_encrypt() 256-bit */
    XMEMSET(out, 0, AES_BLOCK_SIZE);
    RESET_IV(iv256tmp, iv256);

    ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key256, sizeof(key256)*8, &aes), 0);
    wolfSSL_AES_cbc_encrypt(pt256, out, len, &aes, iv256tmp, AES_ENCRYPT);
    ExpectIntEQ(XMEMCMP(out, ct256, AES_BLOCK_SIZE), 0);
    wc_AesFree((Aes*)&aes);

    #ifdef HAVE_AES_DECRYPT

    /* wolfSSL_AES_cbc_encrypt() 256-bit in decrypt mode */
    len = sizeof(ct256);
    RESET_IV(iv256tmp, iv256);
    XMEMSET(out, 0, AES_BLOCK_SIZE);

    ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key256, sizeof(key256)*8, &aes), 0);
    wolfSSL_AES_cbc_encrypt(ct256, out, len, &aes, iv256tmp, AES_DECRYPT);
    ExpectIntEQ(XMEMCMP(out, pt256, AES_BLOCK_SIZE), 0);
    wc_AesFree((Aes*)&aes);

    #endif

    #if defined(HAVE_AES_KEYWRAP) && !defined(HAVE_FIPS) && \
        !defined(HAVE_SELFTEST)
    {
    byte wrapCipher[sizeof(key256) + KEYWRAP_BLOCK_SIZE] = { 0 };
    byte wrapPlain[sizeof(key256)] = { 0 };
    byte wrapIV[KEYWRAP_BLOCK_SIZE] = { 0 };

    /* wolfSSL_AES_wrap_key() 256-bit NULL iv */
    ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key256, sizeof(key256)*8, &aes), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, wrapCipher, key256,
            15), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, wrapCipher, key256,
            sizeof(key256)), sizeof(wrapCipher));
    wc_AesFree((Aes*)&aes);

    /* wolfSSL_AES_unwrap_key() 256-bit NULL iv */
    ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key256, sizeof(key256)*8, &aes), 0);
    ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, wrapPlain, wrapCipher,
            23), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, wrapPlain, wrapCipher,
            sizeof(wrapCipher)), sizeof(wrapPlain));
    ExpectIntEQ(XMEMCMP(wrapPlain, key256, sizeof(key256)), 0);
    XMEMSET(wrapCipher, 0, sizeof(wrapCipher));
    XMEMSET(wrapPlain, 0, sizeof(wrapPlain));
    wc_AesFree((Aes*)&aes);

    /* wolfSSL_AES_wrap_key() 256-bit custom iv */
    ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key256, sizeof(key256)*8, &aes), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, wrapIV, wrapCipher, key256,
            sizeof(key256)), sizeof(wrapCipher));
    wc_AesFree((Aes*)&aes);

    /* wolfSSL_AES_unwrap_key() 256-bit custom iv */
    ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key256, sizeof(key256)*8, &aes), 0);
    ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, wrapIV, wrapPlain, wrapCipher,
            sizeof(wrapCipher)), sizeof(wrapPlain));
    ExpectIntEQ(XMEMCMP(wrapPlain, key256, sizeof(key256)), 0);
    wc_AesFree((Aes*)&aes);

    ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, NULL, NULL, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, NULL, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, wrapIV, NULL, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, NULL, wrapCipher, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, NULL, NULL, key256, 0), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, wrapIV, wrapCipher, key256, 0), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, wrapCipher, key256, 0), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, wrapIV, NULL, key256, 0), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, wrapIV, wrapCipher, NULL, 0), 0);

    ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, NULL, NULL, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, NULL, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, wrapIV, NULL, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, NULL, wrapPlain, NULL, 0), 0);
    ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, NULL, NULL, wrapCipher, 0), 0);
    ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, wrapIV, wrapPlain, wrapCipher, 0),
        0);
    ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, wrapPlain, wrapCipher, 0),
        0);
    ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, wrapIV, NULL, wrapCipher, 0), 0);
    ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, wrapIV, wrapPlain, NULL, 0), 0);
    }
    #endif /* HAVE_AES_KEYWRAP */
  }
  #endif /* WOLFSSL_AES_256 */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_AES_cfb128_encrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(WOLFSSL_AES_CFB) && \
        !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API)
    AES_KEY aesEnc;
    AES_KEY aesDec;
    const byte msg[] = {
        0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
        0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a
    };
    const byte exp[] = {
        0x16, 0xc9, 0x90, 0x6c, 0x04, 0x0c, 0xd1, 0x2f,
        0x84, 0x7b, 0x18, 0xed, 0xed, 0x6a, 0xb5, 0xfd
    };
    const byte key[] = {
        0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
        0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
        0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
        0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
    };
    const byte ivData[] = {
        0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
        0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
    };
    byte out[AES_BLOCK_SIZE];
    byte iv[AES_BLOCK_SIZE];
    word32 i;
    int num;

    ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aesEnc), 0);
    XMEMCPY(iv, ivData, sizeof(iv));
    XMEMSET(out, 0, AES_BLOCK_SIZE);
    AES_cfb128_encrypt(msg, out, sizeof(msg), &aesEnc, iv, NULL, AES_ENCRYPT);
    ExpectIntEQ(XMEMCMP(out, exp, sizeof(msg)), 0);
    ExpectIntNE(XMEMCMP(iv, ivData, sizeof(iv)), 0);

#ifdef HAVE_AES_DECRYPT
    ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aesDec), 0);
    XMEMCPY(iv, ivData, sizeof(iv));
    XMEMSET(out, 0, AES_BLOCK_SIZE);
    AES_cfb128_encrypt(exp, out, sizeof(msg), &aesDec, iv, NULL, AES_DECRYPT);
    ExpectIntEQ(XMEMCMP(out, msg, sizeof(msg)), 0);
    ExpectIntNE(XMEMCMP(iv, ivData, sizeof(iv)), 0);
#endif

    for (i = 0; EXPECT_SUCCESS() && (i <= sizeof(msg)); i++) {
        ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aesEnc), 0);
        XMEMCPY(iv, ivData, sizeof(iv));
        XMEMSET(out, 0, AES_BLOCK_SIZE);
        AES_cfb128_encrypt(msg, out, i, &aesEnc, iv, &num, AES_ENCRYPT);
        ExpectIntEQ(num, i % AES_BLOCK_SIZE);
        ExpectIntEQ(XMEMCMP(out, exp, i), 0);
        if (i == 0) {
            ExpectIntEQ(XMEMCMP(iv, ivData, sizeof(iv)), 0);
        }
        else {
            ExpectIntNE(XMEMCMP(iv, ivData, sizeof(iv)), 0);
        }

    #ifdef HAVE_AES_DECRYPT
        ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aesDec), 0);
        XMEMCPY(iv, ivData, sizeof(iv));
        XMEMSET(out, 0, AES_BLOCK_SIZE);
        AES_cfb128_encrypt(exp, out, i, &aesDec, iv, &num, AES_DECRYPT);
        ExpectIntEQ(num, i % AES_BLOCK_SIZE);
        ExpectIntEQ(XMEMCMP(out, msg, i), 0);
        if (i == 0) {
            ExpectIntEQ(XMEMCMP(iv, ivData, sizeof(iv)), 0);
        }
        else {
            ExpectIntNE(XMEMCMP(iv, ivData, sizeof(iv)), 0);
        }
    #endif
    }

    if (EXPECT_SUCCESS()) {
        /* test bad arguments */
        AES_cfb128_encrypt(NULL, NULL, 0, NULL, NULL, NULL, AES_DECRYPT);
        AES_cfb128_encrypt(msg, NULL, 0, NULL, NULL, NULL, AES_DECRYPT);
        AES_cfb128_encrypt(NULL, out, 0, NULL, NULL, NULL, AES_DECRYPT);
        AES_cfb128_encrypt(NULL, NULL, 0, &aesDec, NULL, NULL, AES_DECRYPT);
        AES_cfb128_encrypt(NULL, NULL, 0, NULL, iv, NULL, AES_DECRYPT);
        AES_cfb128_encrypt(NULL, out, 0, &aesDec, iv, NULL, AES_DECRYPT);
        AES_cfb128_encrypt(msg, NULL, 0, &aesDec, iv, NULL, AES_DECRYPT);
        AES_cfb128_encrypt(msg, out, 0, NULL, iv, NULL, AES_DECRYPT);
        AES_cfb128_encrypt(msg, out, 0, &aesDec, NULL, NULL, AES_DECRYPT);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CRYPTO_cts128(void)
{
    EXPECT_DECLS;
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) && \
    defined(HAVE_CTS) && !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API)
    byte tmp[64]; /* Largest vector size */
    /* Test vectors taken form RFC3962 Appendix B */
    const testVector vects[] = {
        {
            "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
            "\x20",
            "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
            "\x97",
            17, 17
        },
        {
            "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
            "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20",
            "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
            "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5",
            31, 31
        },
        {
            "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
            "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43",
            "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
            "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
            32, 32
        },
        {
            "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
            "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43"
            "\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c",
            "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
            "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
            "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5",
            47, 47
        },
        {
            "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
            "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43"
            "\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20",
            "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
            "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
            "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
            48, 48
        },
        {
            "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
            "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43"
            "\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20"
            "\x61\x6e\x64\x20\x77\x6f\x6e\x74\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
            "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
            "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
            "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
            "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
            64, 64
        }
    };
    byte keyBytes[AES_128_KEY_SIZE] = {
        0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
        0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69
    };
    size_t i;
    AES_KEY encKey;
    byte iv[AES_IV_SIZE]; /* All-zero IV for all cases */

    XMEMSET(tmp, 0, sizeof(tmp));

    for (i = 0; i < sizeof(vects)/sizeof(vects[0]); i++) {
        AES_KEY decKey;

        ExpectIntEQ(AES_set_encrypt_key(keyBytes, AES_128_KEY_SIZE * 8,
            &encKey), 0);
        ExpectIntEQ(AES_set_decrypt_key(keyBytes, AES_128_KEY_SIZE * 8,
            &decKey), 0);
        XMEMSET(iv, 0, sizeof(iv));
        ExpectIntEQ(CRYPTO_cts128_encrypt((const unsigned char*)vects[i].input,
            tmp, vects[i].inLen, &encKey, iv, (cbc128_f)AES_cbc_encrypt),
            vects[i].outLen);
        ExpectIntEQ(XMEMCMP(tmp, vects[i].output, vects[i].outLen), 0);
        XMEMSET(iv, 0, sizeof(iv));
        ExpectIntEQ(CRYPTO_cts128_decrypt((const unsigned char*)vects[i].output,
            tmp, vects[i].outLen, &decKey, iv, (cbc128_f)AES_cbc_encrypt),
            vects[i].inLen);
        ExpectIntEQ(XMEMCMP(tmp, vects[i].input, vects[i].inLen), 0);
    }

    ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, NULL, 17, NULL, NULL, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, NULL, 17, NULL, NULL, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, tmp, 17, NULL, NULL, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, NULL, 17, &encKey, NULL, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, NULL, 17, NULL, iv, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, NULL, 17, NULL, NULL,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, tmp, 17, &encKey, iv,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, NULL, 17, &encKey, iv,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, tmp, 17, NULL, iv,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, tmp, 17, &encKey, NULL,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, tmp, 17, &encKey, iv, NULL), 0);
    /* Length too small. */
    ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, tmp, 0, &encKey, iv,
        (cbc128_f)AES_cbc_encrypt), 0);

    ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, NULL, 17, NULL, NULL, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, NULL, 17, NULL, NULL, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, tmp, 17, NULL, NULL, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, NULL, 17, &encKey, NULL, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, NULL, 17, NULL, iv, NULL), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, NULL, 17, NULL, NULL,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, tmp, 17, &encKey, iv,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, NULL, 17, &encKey, iv,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, tmp, 17, NULL, iv,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, tmp, 17, &encKey, NULL,
        (cbc128_f)AES_cbc_encrypt), 0);
    ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, tmp, 17, &encKey, iv, NULL), 0);
    /* Length too small. */
    ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, tmp, 0, &encKey, iv,
        (cbc128_f)AES_cbc_encrypt), 0);
#endif /* !NO_AES && HAVE_AES_CBC && OPENSSL_EXTRA && HAVE_CTS */
    return EXPECT_RESULT();
}

static int test_wolfSSL_RC4(void)
{
    EXPECT_DECLS;
#if !defined(NO_RC4) && defined(OPENSSL_EXTRA)
    WOLFSSL_RC4_KEY rc4Key;
    unsigned char key[] =  {
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
    };
    unsigned char data[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    };
    unsigned char enc[sizeof(data)];
    unsigned char dec[sizeof(data)];
    word32 i;
    word32 j;

    wolfSSL_RC4_set_key(NULL, -1, NULL);
    wolfSSL_RC4_set_key(&rc4Key, -1, NULL);
    wolfSSL_RC4_set_key(NULL, 0, NULL);
    wolfSSL_RC4_set_key(NULL, -1, key);
    wolfSSL_RC4_set_key(&rc4Key, 0, NULL);
    wolfSSL_RC4_set_key(&rc4Key, -1, key);
    wolfSSL_RC4_set_key(NULL, 0, key);

    wolfSSL_RC4(NULL, 0, NULL, NULL);
    wolfSSL_RC4(&rc4Key, 0, NULL, NULL);
    wolfSSL_RC4(NULL, 0, data, NULL);
    wolfSSL_RC4(NULL, 0, NULL, enc);
    wolfSSL_RC4(&rc4Key, 0, data, NULL);
    wolfSSL_RC4(&rc4Key, 0, NULL, enc);
    wolfSSL_RC4(NULL, 0, data, enc);

    ExpectIntEQ(1, 1);
    for (i = 0; EXPECT_SUCCESS() && (i <= sizeof(key)); i++) {
        for (j = 0; EXPECT_SUCCESS() && (j <= sizeof(data)); j++) {
            XMEMSET(enc, 0, sizeof(enc));
            XMEMSET(dec, 0, sizeof(dec));

            /* Encrypt */
            wolfSSL_RC4_set_key(&rc4Key, (int)i, key);
            wolfSSL_RC4(&rc4Key, j, data, enc);
            /* Decrypt */
            wolfSSL_RC4_set_key(&rc4Key, (int)i, key);
            wolfSSL_RC4(&rc4Key, j, enc, dec);

            ExpectIntEQ(XMEMCMP(dec, data, j), 0);
        }
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OBJ(void)
{
/* Password "wolfSSL test" is only 12 (96-bit) too short for testing in FIPS
 * mode
 */
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SHA256) && !defined(NO_ASN) && \
    !defined(HAVE_FIPS) && !defined(NO_SHA) && defined(WOLFSSL_CERT_EXT) && \
    defined(WOLFSSL_CERT_GEN) && !defined(NO_BIO) && \
    !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
    ASN1_OBJECT *obj = NULL;
    ASN1_OBJECT *obj2 = NULL;
    char buf[50];

    XFILE fp = XBADFILE;
    X509 *x509 = NULL;
    X509_NAME *x509Name = NULL;
    X509_NAME_ENTRY *x509NameEntry = NULL;
    ASN1_OBJECT *asn1Name = NULL;
    int numNames = 0;
    BIO *bio = NULL;
    int nid;
    int i, j;
    const char *f[] = {
    #ifndef NO_RSA
        "./certs/ca-cert.der",
    #endif
    #ifdef HAVE_ECC
        "./certs/ca-ecc-cert.der",
        "./certs/ca-ecc384-cert.der",
    #endif
        NULL};
    ASN1_OBJECT *field_name_obj = NULL;
    int lastpos = -1;
    int tmp = -1;
    ASN1_STRING *asn1 = NULL;
    unsigned char *buf_dyn = NULL;

    ExpectIntEQ(OBJ_obj2txt(buf, (int)sizeof(buf), obj, 1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectNotNull(obj = OBJ_nid2obj(NID_any_policy));
    ExpectIntEQ(OBJ_obj2nid(obj), NID_any_policy);
    ExpectIntEQ(OBJ_obj2txt(buf, (int)sizeof(buf), obj, 1), 11);
    ExpectIntGT(OBJ_obj2txt(buf, (int)sizeof(buf), obj, 0), 0);
    ASN1_OBJECT_free(obj);
    obj = NULL;

    ExpectNotNull(obj = OBJ_nid2obj(NID_sha256));
    ExpectIntEQ(OBJ_obj2nid(obj), NID_sha256);
    ExpectIntEQ(OBJ_obj2txt(buf, (int)sizeof(buf), obj, 1), 22);
#ifdef WOLFSSL_CERT_EXT
    ExpectIntEQ(OBJ_txt2nid(buf), NID_sha256);
#endif
    ExpectIntGT(OBJ_obj2txt(buf, (int)sizeof(buf), obj, 0), 0);
    ExpectNotNull(obj2 = OBJ_dup(obj));
    ExpectIntEQ(OBJ_cmp(obj, obj2), 0);
    ASN1_OBJECT_free(obj);
    obj = NULL;
    ASN1_OBJECT_free(obj2);
    obj2 = NULL;

    for (i = 0; f[i] != NULL; i++)
    {
        ExpectTrue((fp = XFOPEN(f[i], "rb")) != XBADFILE);
        ExpectNotNull(x509 = d2i_X509_fp(fp, NULL));
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }
        ExpectNotNull(x509Name = X509_get_issuer_name(x509));
        ExpectIntNE((numNames = X509_NAME_entry_count(x509Name)), 0);

        /* Get the Common Name by using OBJ_txt2obj */
        ExpectNotNull(field_name_obj = OBJ_txt2obj("CN", 0));
        do
        {
            lastpos = tmp;
            tmp = X509_NAME_get_index_by_OBJ(x509Name, field_name_obj, lastpos);
        } while (tmp > -1);
        ExpectIntNE(lastpos, -1);
        ASN1_OBJECT_free(field_name_obj);
        field_name_obj = NULL;
        ExpectNotNull(x509NameEntry = X509_NAME_get_entry(x509Name, lastpos));
        ExpectNotNull(asn1 = X509_NAME_ENTRY_get_data(x509NameEntry));
        ExpectIntGE(ASN1_STRING_to_UTF8(&buf_dyn, asn1), 0);
        /*
         * All Common Names should be www.wolfssl.com
         * This makes testing easier as we can test for the expected value.
         */
        ExpectStrEQ((char*)buf_dyn, "www.wolfssl.com");
        OPENSSL_free(buf_dyn);
        buf_dyn = NULL;
        bio = BIO_new(BIO_s_mem());
        ExpectTrue(bio != NULL);
        for (j = 0; j < numNames; j++)
        {
            ExpectNotNull(x509NameEntry = X509_NAME_get_entry(x509Name, j));
            ExpectNotNull(asn1Name = X509_NAME_ENTRY_get_object(x509NameEntry));
            ExpectTrue((nid = OBJ_obj2nid(asn1Name)) > 0);
        }
        BIO_free(bio);
        bio = NULL;
        X509_free(x509);
        x509 = NULL;

    }

#ifdef HAVE_PKCS12
    {
        PKCS12 *p12 = NULL;
        int boolRet;
        EVP_PKEY *pkey = NULL;
        const char *p12_f[] = {
            #if !defined(NO_DES3) && !defined(NO_RSA)
            "./certs/test-servercert.p12",
            #endif
            NULL};

        for (i = 0; p12_f[i] != NULL; i++)
        {
            ExpectTrue((fp = XFOPEN(p12_f[i], "rb")) != XBADFILE);
            ExpectNotNull(p12 = d2i_PKCS12_fp(fp, NULL));
            if (fp != XBADFILE) {
                XFCLOSE(fp);
                fp = XBADFILE;
            }
            ExpectTrue((boolRet = PKCS12_parse(p12, "wolfSSL test",
                                               &pkey, &x509, NULL)) > 0);
            wc_PKCS12_free(p12);
            p12 = NULL;
            EVP_PKEY_free(pkey);
            x509Name = X509_get_issuer_name(x509);
            ExpectNotNull(x509Name);
            ExpectIntNE((numNames = X509_NAME_entry_count(x509Name)), 0);
            ExpectTrue((bio = BIO_new(BIO_s_mem())) != NULL);
            for (j = 0; j < numNames; j++)
            {
                ExpectNotNull(x509NameEntry = X509_NAME_get_entry(x509Name, j));
                ExpectNotNull(asn1Name =
                        X509_NAME_ENTRY_get_object(x509NameEntry));
                ExpectTrue((nid = OBJ_obj2nid(asn1Name)) > 0);
            }
            BIO_free(bio);
            bio = NULL;
            X509_free(x509);
            x509 = NULL;
        }
    }
#endif /* HAVE_PKCS12 */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OBJ_cmp(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SHA256)
    ASN1_OBJECT *obj = NULL;
    ASN1_OBJECT *obj2 = NULL;

    ExpectNotNull(obj = OBJ_nid2obj(NID_any_policy));
    ExpectNotNull(obj2 = OBJ_nid2obj(NID_sha256));

    ExpectIntEQ(OBJ_cmp(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(OBJ_cmp(obj, NULL), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(OBJ_cmp(NULL, obj2), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(OBJ_cmp(obj, obj2), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(OBJ_cmp(obj, obj), 0);
    ExpectIntEQ(OBJ_cmp(obj2, obj2), 0);

    ASN1_OBJECT_free(obj);
    ASN1_OBJECT_free(obj2);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OBJ_txt2nid(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
    defined(WOLFSSL_APACHE_HTTPD)
    int i;
    static const struct {
        const char* sn;
        const char* ln;
        const char* oid;
        int nid;
    } testVals[] = {
#ifdef WOLFSSL_APACHE_HTTPD
        { "tlsfeature", "TLS Feature", "1.3.6.1.5.5.7.1.24", NID_tlsfeature },
        { "id-on-dnsSRV", "SRVName", "1.3.6.1.5.5.7.8.7",
                                                             NID_id_on_dnsSRV },
        { "msUPN", "Microsoft User Principal Name",
                                         "1.3.6.1.4.1.311.20.2.3", NID_ms_upn },
#endif
        { NULL, NULL, NULL, NID_undef }
    };

    /* Invalid cases */
    ExpectIntEQ(OBJ_txt2nid(NULL), NID_undef);
    ExpectIntEQ(OBJ_txt2nid("Bad name"), NID_undef);

    /* Valid cases */
    for (i = 0; testVals[i].sn != NULL; i++) {
        ExpectIntEQ(OBJ_txt2nid(testVals[i].sn), testVals[i].nid);
        ExpectIntEQ(OBJ_txt2nid(testVals[i].ln), testVals[i].nid);
        ExpectIntEQ(OBJ_txt2nid(testVals[i].oid), testVals[i].nid);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OBJ_txt2obj(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_APACHE_HTTPD) || (defined(OPENSSL_EXTRA) && \
        defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN))
    int i;
    char buf[50];
    ASN1_OBJECT* obj = NULL;
    static const struct {
        const char* oidStr;
        const char* sn;
        const char* ln;
    } objs_list[] = {
    #if defined(WOLFSSL_APACHE_HTTPD)
        { "1.3.6.1.5.5.7.1.24", "tlsfeature", "TLS Feature" },
        { "1.3.6.1.5.5.7.8.7", "id-on-dnsSRV", "SRVName" },
    #endif
        { "2.5.29.19", "basicConstraints", "X509v3 Basic Constraints"},
        { NULL, NULL, NULL }
    };
    static const struct {
        const char* numeric;
        const char* name;
    } objs_named[] = {
        /* In dictionary but not in normal list. */
        { "1.3.6.1.5.5.7.3.8", "Time Stamping" },
        /* Made up OID. */
        { "1.3.5.7",           "1.3.5.7" },
        { NULL, NULL }
    };

    ExpectNull(obj = OBJ_txt2obj("Bad name", 0));
    ASN1_OBJECT_free(obj);
    obj = NULL;
    ExpectNull(obj = OBJ_txt2obj(NULL, 0));
    ASN1_OBJECT_free(obj);
    obj = NULL;

    for (i = 0; objs_list[i].oidStr != NULL; i++) {
        /* Test numerical value of oid (oidStr) */
        ExpectNotNull(obj = OBJ_txt2obj(objs_list[i].oidStr, 1));
        /* Convert object back to text to confirm oid is correct */
        wolfSSL_OBJ_obj2txt(buf, (int)sizeof(buf), obj, 1);
        ExpectIntEQ(XSTRNCMP(buf, objs_list[i].oidStr, (int)XSTRLEN(buf)), 0);
        ASN1_OBJECT_free(obj);
        obj = NULL;
        XMEMSET(buf, 0, sizeof(buf));

        /* Test short name (sn) */
        ExpectNull(obj = OBJ_txt2obj(objs_list[i].sn, 1));
        ExpectNotNull(obj = OBJ_txt2obj(objs_list[i].sn, 0));
        /* Convert object back to text to confirm oid is correct */
        wolfSSL_OBJ_obj2txt(buf, (int)sizeof(buf), obj, 1);
        ExpectIntEQ(XSTRNCMP(buf, objs_list[i].oidStr, (int)XSTRLEN(buf)), 0);
        ASN1_OBJECT_free(obj);
        obj = NULL;
        XMEMSET(buf, 0, sizeof(buf));

        /* Test long name (ln) - should fail when no_name = 1 */
        ExpectNull(obj = OBJ_txt2obj(objs_list[i].ln, 1));
        ExpectNotNull(obj = OBJ_txt2obj(objs_list[i].ln, 0));
        /* Convert object back to text to confirm oid is correct */
        wolfSSL_OBJ_obj2txt(buf, (int)sizeof(buf), obj, 1);
        ExpectIntEQ(XSTRNCMP(buf, objs_list[i].oidStr, (int)XSTRLEN(buf)), 0);
        ASN1_OBJECT_free(obj);
        obj = NULL;
        XMEMSET(buf, 0, sizeof(buf));
    }

    for (i = 0; objs_named[i].numeric != NULL; i++) {
        ExpectNotNull(obj = OBJ_txt2obj(objs_named[i].numeric, 1));
        wolfSSL_OBJ_obj2txt(buf, (int)sizeof(buf), obj, 0);
        ExpectIntEQ(XSTRNCMP(buf, objs_named[i].name, (int)XSTRLEN(buf)), 0);
        wolfSSL_OBJ_obj2txt(buf, (int)sizeof(buf), obj, 1);
        ExpectIntEQ(XSTRNCMP(buf, objs_named[i].numeric, (int)XSTRLEN(buf)), 0);
        ASN1_OBJECT_free(obj);
        obj = NULL;
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_write_bio_X509(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(OPENSSL_ALL) && \
    defined(WOLFSSL_AKID_NAME) && defined(WOLFSSL_CERT_EXT) && \
    defined(WOLFSSL_CERT_GEN) && !defined(NO_BIO) && !defined(NO_RSA) && \
    !defined(NO_FILESYSTEM)
    /* This test contains the hard coded expected
     * lengths. Update if necessary */
    XFILE fp = XBADFILE;
    WOLFSSL_EVP_PKEY *priv = NULL;

    BIO* input = NULL;
    BIO* output = NULL;
    X509* x509a = NULL;
    X509* x509b = NULL;

    ASN1_TIME* notBeforeA = NULL;
    ASN1_TIME* notAfterA  = NULL;
#ifndef NO_ASN_TIME
    ASN1_TIME* notBeforeB = NULL;
    ASN1_TIME* notAfterB  = NULL;
#endif
    int expectedLen;

    ExpectTrue((fp = XFOPEN("certs/server-key.pem", "rb")) != XBADFILE);
    ExpectNotNull(priv = wolfSSL_PEM_read_PrivateKey(fp, NULL, NULL, NULL));
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }

    ExpectNotNull(input = BIO_new_file("certs/test/cert-ext-multiple.pem",
        "rb"));
    ExpectIntEQ(wolfSSL_BIO_get_len(input), 2000);

    /* read PEM into X509 struct, get notBefore / notAfter to verify against */
    ExpectNotNull(PEM_read_bio_X509(input, &x509a, NULL, NULL));
    ExpectNotNull(notBeforeA = X509_get_notBefore(x509a));
    ExpectNotNull(notAfterA = X509_get_notAfter(x509a));

    /* write X509 back to PEM BIO; no need to sign as nothing changed. */
    ExpectNotNull(output = BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_X509(output, x509a), WOLFSSL_SUCCESS);
    /* compare length against expected */
    expectedLen = 2000;
    ExpectIntEQ(wolfSSL_BIO_get_len(output), expectedLen);

#ifndef NO_ASN_TIME
    /* read exported X509 PEM back into struct, sanity check on export,
     * make sure notBefore/notAfter are the same and certs are identical. */
    ExpectNotNull(PEM_read_bio_X509(output, &x509b, NULL, NULL));
    ExpectNotNull(notBeforeB = X509_get_notBefore(x509b));
    ExpectNotNull(notAfterB = X509_get_notAfter(x509b));
    ExpectIntEQ(ASN1_TIME_compare(notBeforeA, notBeforeB), 0);
    ExpectIntEQ(ASN1_TIME_compare(notAfterA, notAfterB), 0);
    ExpectIntEQ(0, wolfSSL_X509_cmp(x509a, x509b));
    X509_free(x509b);
    x509b = NULL;
#endif

    /* Reset output buffer */
    BIO_free(output);
    output = NULL;
    ExpectNotNull(output = BIO_new(wolfSSL_BIO_s_mem()));

    /* Test forcing the AKID to be generated just from KeyIdentifier */
    if (EXPECT_SUCCESS() && x509a->authKeyIdSrc != NULL) {
        XMEMMOVE(x509a->authKeyIdSrc, x509a->authKeyId, x509a->authKeyIdSz);
        x509a->authKeyId = x509a->authKeyIdSrc;
        x509a->authKeyIdSrc = NULL;
        x509a->authKeyIdSrcSz = 0;
    }

    /* Resign to re-generate the der */
    ExpectIntGT(wolfSSL_X509_sign(x509a, priv, EVP_sha256()), 0);

    ExpectIntEQ(PEM_write_bio_X509(output, x509a), WOLFSSL_SUCCESS);

    /* Check that we generate a smaller output since the AKID will
     * only contain the KeyIdentifier without any additional
     * information */

    /* Here we copy the validity struct from the original */
    expectedLen = 1688;
    ExpectIntEQ(wolfSSL_BIO_get_len(output), expectedLen);

    /* Reset buffers and x509 */
    BIO_free(input);
    input = NULL;
    BIO_free(output);
    output = NULL;
    X509_free(x509a);
    x509a = NULL;

    /* test CA and basicConstSet values are encoded when
     * the cert is a CA */
    ExpectNotNull(input = BIO_new_file("certs/server-cert.pem", "rb"));

    /* read PEM into X509 struct */
    ExpectNotNull(PEM_read_bio_X509(input, &x509a, NULL, NULL));

    /* write X509 back to PEM BIO; no need to sign as nothing changed */
    ExpectNotNull(output = BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_X509(output, x509a), WOLFSSL_SUCCESS);

    /* read exported X509 PEM back into struct, ensure isCa and basicConstSet
     * values are maintained and certs are identical.*/
    ExpectNotNull(PEM_read_bio_X509(output, &x509b, NULL, NULL));
    ExpectIntEQ(x509b->isCa, 1);
    ExpectIntEQ(x509b->basicConstSet, 1);
    ExpectIntEQ(0, wolfSSL_X509_cmp(x509a, x509b));

    X509_free(x509a);
    x509a = NULL;
    X509_free(x509b);
    x509b = NULL;
    BIO_free(input);
    input = NULL;
    BIO_free(output);
    output = NULL;

    /* test CA and basicConstSet values are encoded when
     * the cert is not CA */
    ExpectNotNull(input = BIO_new_file("certs/client-uri-cert.pem", "rb"));

    /* read PEM into X509 struct */
    ExpectNotNull(PEM_read_bio_X509(input, &x509a, NULL, NULL));

    /* write X509 back to PEM BIO; no need to sign as nothing changed */
    ExpectNotNull(output = BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_X509(output, x509a), WOLFSSL_SUCCESS);

    /* read exported X509 PEM back into struct, ensure isCa and
     * basicConstSet values are maintained and certs are identical */
    ExpectNotNull(PEM_read_bio_X509(output, &x509b, NULL, NULL));
    ExpectIntEQ(x509b->isCa, 0);
    ExpectIntEQ(x509b->basicConstSet, 1);
    ExpectIntEQ(0, wolfSSL_X509_cmp(x509a, x509b));

    wolfSSL_EVP_PKEY_free(priv);
    X509_free(x509a);
    X509_free(x509b);
    BIO_free(input);
    BIO_free(output);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_NAME_ENTRY(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA) && defined(WOLFSSL_CERT_GEN)
    X509*      x509 = NULL;
#ifndef NO_BIO
    BIO*       bio = NULL;
#endif
    X509_NAME* nm = NULL;
    X509_NAME_ENTRY* entry = NULL;
    unsigned char cn[] = "another name to add";
#ifdef OPENSSL_ALL
    int i;
    int names_len = 0;
#endif

    ExpectNotNull(x509 =
            wolfSSL_X509_load_certificate_file(cliCertFile, SSL_FILETYPE_PEM));
#ifndef NO_BIO
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio_X509_AUX(bio, x509), SSL_SUCCESS);
#endif

#ifdef WOLFSSL_CERT_REQ
    {
        X509_REQ* req = NULL;
#ifndef NO_BIO
        BIO*      bReq = NULL;
#endif

        ExpectNotNull(req =
            wolfSSL_X509_load_certificate_file(cliCertFile, SSL_FILETYPE_PEM));
#ifndef NO_BIO
        ExpectNotNull(bReq = BIO_new(BIO_s_mem()));
        ExpectIntEQ(PEM_write_bio_X509_REQ(bReq, req), SSL_SUCCESS);

        BIO_free(bReq);
#endif
        X509_free(req);
    }
#endif

    ExpectNotNull(nm = X509_get_subject_name(x509));

    /* Test add entry */
    ExpectNotNull(entry = X509_NAME_ENTRY_create_by_NID(NULL, NID_commonName,
                0x0c, cn, (int)sizeof(cn)));
    ExpectIntEQ(X509_NAME_add_entry(nm, entry, -1, 0), SSL_SUCCESS);

#ifdef WOLFSSL_CERT_EXT
    ExpectIntEQ(X509_NAME_add_entry_by_txt(nm, "emailAddress", MBSTRING_UTF8,
                                           (byte*)"support@wolfssl.com", 19, -1,
                                           1), WOLFSSL_SUCCESS);
#endif
    X509_NAME_ENTRY_free(entry);
    entry = NULL;

#ifdef WOLFSSL_CERT_REQ
    {
        unsigned char srv_pkcs9p[] = "Server";
        unsigned char fvrtDrnk[] = "tequila";
        unsigned char* der = NULL;
        char* subject = NULL;
        ExpectIntEQ(X509_NAME_add_entry_by_NID(nm, NID_pkcs9_contentType,
            MBSTRING_ASC, srv_pkcs9p, -1, -1, 0), SSL_SUCCESS);

        ExpectIntEQ(X509_NAME_add_entry_by_NID(nm, NID_favouriteDrink,
            MBSTRING_ASC, fvrtDrnk, -1, -1, 0), SSL_SUCCESS);

        ExpectIntGT(wolfSSL_i2d_X509_NAME(nm, &der), 0);
        ExpectNotNull(der);

        ExpectNotNull(subject = X509_NAME_oneline(nm, 0, 0));
        ExpectNotNull(XSTRSTR(subject, "favouriteDrink=tequila"));
        ExpectNotNull(XSTRSTR(subject, "contentType=Server"));
    #ifdef DEBUG_WOLFSSL
        if (subject != NULL) {
            fprintf(stderr, "\n\t%s\n", subject);
        }
    #endif
        XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
        XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
    }
#endif

    /* Test add entry by text */
    ExpectNotNull(entry = X509_NAME_ENTRY_create_by_txt(NULL, "commonName",
                0x0c, cn, (int)sizeof(cn)));
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) \
    || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX)
    ExpectNull(X509_NAME_ENTRY_create_by_txt(&entry, "unknown",
                V_ASN1_UTF8STRING, cn, (int)sizeof(cn)));
    #endif
    ExpectIntEQ(X509_NAME_add_entry(nm, entry, -1, 0), SSL_SUCCESS);
    X509_NAME_ENTRY_free(entry);
    entry = NULL;

    /* Test add entry by NID */
    ExpectIntEQ(X509_NAME_add_entry_by_NID(nm, NID_commonName, MBSTRING_UTF8,
                                       cn, -1, -1, 0), SSL_SUCCESS);

#ifdef OPENSSL_ALL
    /* stack of name entry */
    ExpectIntGT((names_len = sk_X509_NAME_ENTRY_num(nm->entries)), 0);
    for (i = 0; i < names_len; i++) {
        ExpectNotNull(entry = sk_X509_NAME_ENTRY_value(nm->entries, i));
    }
#endif

#ifndef NO_BIO
    BIO_free(bio);
#endif
    X509_free(x509); /* free's nm */
#endif
    return EXPECT_RESULT();
}

/* Note the lack of wolfSSL_ prefix...this is a compatibility layer test. */
static int test_GENERAL_NAME_set0_othername(void) {
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
    defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ALT_NAMES) && \
    defined(WOLFSSL_CERT_EXT) && !defined(NO_FILESYSTEM) && \
    defined(WOLFSSL_FPKI) && !defined(NO_RSA)
    /* ./configure --enable-opensslall --enable-certgen --enable-certreq
     *  --enable-certext --enable-debug 'CPPFLAGS=-DWOLFSSL_CUSTOM_OID
     *  -DWOLFSSL_ALT_NAMES  -DWOLFSSL_FPKI' */
    const char * cert_fname = "./certs/server-cert.der";
    const char * key_fname = "./certs/server-key.der";
    X509* x509 = NULL;
    GENERAL_NAME* gn = NULL;
    GENERAL_NAMES* gns = NULL;
    ASN1_OBJECT* upn_oid = NULL;
    ASN1_UTF8STRING *utf8str = NULL;
    ASN1_TYPE *value = NULL;
    X509_EXTENSION * ext = NULL;

    byte* pt = NULL;
    byte der[4096];
    int derSz = 0;
    EVP_PKEY* priv = NULL;
    XFILE f = XBADFILE;

    ExpectTrue((f = XFOPEN(cert_fname, "rb")) != XBADFILE);
    ExpectNotNull(x509 = d2i_X509_fp(f, NULL));
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    ExpectNotNull(gn = GENERAL_NAME_new());
    ExpectNotNull(upn_oid = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.3", 1));
    ExpectNotNull(utf8str = ASN1_UTF8STRING_new());
    ExpectIntEQ(ASN1_STRING_set(utf8str, "othername@wolfssl.com", -1), 1);
    ExpectNotNull(value = ASN1_TYPE_new());
    ASN1_TYPE_set(value, V_ASN1_UTF8STRING, utf8str);
    if ((value == NULL) || (value->value.ptr != (char*)utf8str)) {
        wolfSSL_ASN1_STRING_free(utf8str);
    }
    ExpectIntEQ(GENERAL_NAME_set0_othername(gn, upn_oid, value), 1);
    if (EXPECT_FAIL()) {
        ASN1_TYPE_free(value);
    }
    ExpectNotNull(gns = sk_GENERAL_NAME_new(NULL));
    ExpectIntEQ(sk_GENERAL_NAME_push(gns, gn), 1);
    if (EXPECT_FAIL()) {
        GENERAL_NAME_free(gn);
        gn = NULL;
    }
    ExpectNotNull(ext = X509V3_EXT_i2d(NID_subject_alt_name, 0, gns));
    ExpectIntEQ(X509_add_ext(x509, ext, -1), 1);
    ExpectTrue((f = XFOPEN(key_fname, "rb")) != XBADFILE);
    ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), f), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    pt = der;
    ExpectNotNull(priv = d2i_PrivateKey(EVP_PKEY_RSA, NULL,
        (const unsigned char**)&pt, derSz));
    ExpectIntGT(X509_sign(x509, priv, EVP_sha256()), 0);
    sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
    gns = NULL;
    ExpectNotNull(gns = (GENERAL_NAMES*)X509_get_ext_d2i(x509,
        NID_subject_alt_name, NULL, NULL));

    ExpectIntEQ(sk_GENERAL_NAME_num(gns), 3);

    ExpectNotNull(gn = sk_GENERAL_NAME_value(gns, 2));
    ExpectIntEQ(gn->type, 0);

    sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);

    ASN1_OBJECT_free(upn_oid);
    X509_EXTENSION_free(ext);
    X509_free(x509);
    EVP_PKEY_free(priv);
#endif
    return EXPECT_RESULT();
}

/* Note the lack of wolfSSL_ prefix...this is a compatibility layer test. */
static int test_othername_and_SID_ext(void) {
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
    defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ALT_NAMES) && \
    defined(WOLFSSL_CERT_EXT) && !defined(NO_FILESYSTEM) && \
    defined(WOLFSSL_FPKI) && defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_RSA)
    /* ./configure --enable-opensslall --enable-certgen --enable-certreq
     *  --enable-certext --enable-debug 'CPPFLAGS=-DWOLFSSL_CUSTOM_OID
     *  -DWOLFSSL_ALT_NAMES  -DWOLFSSL_FPKI' */
    const char* csr_fname = "./certs/csr.signed.der";
    const char* key_fname = "./certs/server-key.der";

    byte der[4096];
    int derSz = 0;
    X509_REQ* x509 = NULL;
    STACK_OF(X509_EXTENSION) *exts = NULL;

    X509_EXTENSION * san_ext = NULL;
    X509_EXTENSION * ext = NULL;
    GENERAL_NAME* gn = NULL;
    GENERAL_NAMES* gns = NULL;
    ASN1_OBJECT* upn_oid = NULL;
    ASN1_UTF8STRING *utf8str = NULL;
    ASN1_TYPE *value = NULL;
    ASN1_STRING *extval = NULL;

    /* SID extension. SID data format explained here:
     * https://blog.qdsecurity.se/2022/05/27/manually-injecting-a-sid-in-a-certificate/
     */
    byte SidExtension[] = {
    48, 64, 160, 62, 6,  10, 43, 6,  1,  4,  1,  130, 55, 25, 2,  1,  160,
    48, 4,  46,  83, 45, 49, 45, 53, 45, 50, 49, 45,  50, 56, 52, 51, 57,
    48, 55, 52,  49, 56, 45, 51, 57, 50, 54, 50, 55,  55, 52, 50, 49, 45,
    51, 56, 49,  53, 57, 57, 51, 57, 55, 50, 45, 52,  54, 48, 49};

    byte expectedAltName[] = {
    0x30, 0x27, 0xA0, 0x25, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82,
    0x37, 0x14, 0x02, 0x03, 0xA0, 0x17, 0x0C, 0x15, 0x6F, 0x74, 0x68, 0x65,
    0x72, 0x6E, 0x61, 0x6D, 0x65, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73,
    0x6C, 0x2E, 0x63, 0x6F, 0x6D};

    X509_EXTENSION *sid_ext = NULL;
    ASN1_OBJECT* sid_oid = NULL;
    ASN1_OCTET_STRING *sid_data = NULL;

    ASN1_OBJECT* alt_names_oid = NULL;

    EVP_PKEY* priv = NULL;
    XFILE f = XBADFILE;
    byte* pt = NULL;
    BIO* bio = NULL;

    ExpectTrue((f = XFOPEN(csr_fname, "rb")) != XBADFILE);
    ExpectNotNull(x509 = d2i_X509_REQ_fp(f, NULL));
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    ExpectIntEQ(X509_REQ_set_version(x509, 2), 1);
    ExpectNotNull(gn = GENERAL_NAME_new());
    ExpectNotNull(upn_oid = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.3", 1));
    ExpectNotNull(utf8str = ASN1_UTF8STRING_new());
    ExpectIntEQ(ASN1_STRING_set(utf8str, "othername@wolfssl.com", -1), 1);
    ExpectNotNull(value = ASN1_TYPE_new());
    ASN1_TYPE_set(value, V_ASN1_UTF8STRING, utf8str);
    if (EXPECT_FAIL()) {
        ASN1_UTF8STRING_free(utf8str);
    }
    ExpectIntEQ(GENERAL_NAME_set0_othername(gn, upn_oid, value), 1);
    if (EXPECT_FAIL()) {
        ASN1_TYPE_free(value);
        GENERAL_NAME_free(gn);
        gn = NULL;
    }
    ExpectNotNull(gns = sk_GENERAL_NAME_new(NULL));
    ExpectIntEQ(sk_GENERAL_NAME_push(gns, gn), 1);
    if (EXPECT_FAIL()) {
        GENERAL_NAME_free(gn);
    }
    ExpectNotNull(san_ext = X509V3_EXT_i2d(NID_subject_alt_name, 0, gns));
    ExpectNotNull(sid_oid = OBJ_txt2obj("1.3.6.1.4.1.311.25.2", 1));
    ExpectNotNull(sid_data = ASN1_OCTET_STRING_new());
    ASN1_OCTET_STRING_set(sid_data, SidExtension, sizeof(SidExtension));
    ExpectNotNull(sid_ext = X509_EXTENSION_create_by_OBJ(NULL, sid_oid, 0,
                                                         sid_data));
    ExpectNotNull(exts = sk_X509_EXTENSION_new_null());
    /* Ensure an empty stack doesn't raise an error. */
    ExpectIntEQ(X509_REQ_add_extensions(x509, exts), 1);
    ExpectIntEQ(sk_X509_EXTENSION_push(exts, san_ext), 1);
    if (EXPECT_FAIL()) {
        X509_EXTENSION_free(san_ext);
    }
    ExpectIntEQ(sk_X509_EXTENSION_push(exts, sid_ext), 2);
    if (EXPECT_FAIL()) {
        X509_EXTENSION_free(sid_ext);
    }
    ExpectIntEQ(X509_REQ_add_extensions(x509, exts), 1);
    ExpectTrue((f = XFOPEN(key_fname, "rb")) != XBADFILE);
    ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);
    pt = der;
    ExpectNotNull(priv = d2i_PrivateKey(EVP_PKEY_RSA, NULL,
                                        (const unsigned char**)&pt, derSz));
    ExpectIntGT(X509_REQ_sign(x509, priv, EVP_sha256()), 0);
    pt = der;
    ExpectIntGT(derSz = i2d_X509_REQ(x509, &pt), 0);
    X509_REQ_free(x509);
    x509 = NULL;
    pt = der;
    ExpectNotNull(d2i_X509_REQ_INFO(&x509, (const unsigned char**)&pt, derSz));
    sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
    gns = NULL;
    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
    exts = NULL;
    ASN1_OBJECT_free(upn_oid);
    ASN1_OBJECT_free(sid_oid);
    sid_oid = NULL;
    ASN1_OCTET_STRING_free(sid_data);
    X509_REQ_free(x509);
    EVP_PKEY_free(priv);

    /* At this point everything used to generate what is in der is cleaned up.
     * We now read back from der to confirm the extensions were inserted
     * correctly. */
    bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
    ExpectNotNull(bio);

    ExpectIntEQ(BIO_write(bio, der, derSz), derSz); /* d2i consumes BIO */
    ExpectNotNull(d2i_X509_REQ_bio(bio, &x509));
    ExpectNotNull(x509);
    BIO_free(bio);
    ExpectNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(
        x509));
    ExpectIntEQ(sk_X509_EXTENSION_num(exts), 2);

    /* Check the SID extension. */
    ExpectNotNull(sid_oid = OBJ_txt2obj("1.3.6.1.4.1.311.25.2", 1));
    ExpectNotNull(ext = sk_X509_EXTENSION_value(exts,
            X509_get_ext_by_OBJ(x509, sid_oid, -1)));
    ExpectNotNull(extval = X509_EXTENSION_get_data(ext));
    ExpectIntEQ(extval->length, sizeof(SidExtension));
    ExpectIntEQ(XMEMCMP(SidExtension, extval->data, sizeof(SidExtension)), 0);
    ASN1_OBJECT_free(sid_oid);

    /* Check the AltNames extension. */
    ExpectNotNull(alt_names_oid = OBJ_txt2obj("subjectAltName", 0));
    ExpectNotNull(ext = sk_X509_EXTENSION_value(exts,
            X509_get_ext_by_OBJ(x509, alt_names_oid, -1)));
    ExpectNotNull(extval = X509_EXTENSION_get_data(ext));
    ExpectIntEQ(extval->length, sizeof(expectedAltName));
    ExpectIntEQ(XMEMCMP(expectedAltName, extval->data, sizeof(expectedAltName)),
                0);
    ASN1_OBJECT_free(alt_names_oid);

    /* Cleanup */
    ExpectNotNull(gns = (GENERAL_NAMES*)X509_get_ext_d2i(x509,
        NID_subject_alt_name, NULL, NULL));
    ExpectIntEQ(sk_GENERAL_NAME_num(gns), 1);
    ExpectNotNull(gn = sk_GENERAL_NAME_value(gns, 0));
    ExpectIntEQ(gn->type, 0);

    sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);

    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
    X509_REQ_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_set_name(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
    X509* x509 = NULL;
    X509_NAME* name = NULL;

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
                                           (byte*)"wolfssl.com", 11, 0, 1),
                WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
                                           (byte*)"support@wolfssl.com", 19, -1,
                                           1), WOLFSSL_SUCCESS);
    ExpectNotNull(x509 = X509_new());

    ExpectIntEQ(X509_set_subject_name(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_set_subject_name(x509, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_set_subject_name(NULL, name), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);

    ExpectIntEQ(X509_set_issuer_name(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_set_issuer_name(x509, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_set_issuer_name(NULL, name), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);

    X509_free(x509);
    X509_NAME_free(name);
#endif /* OPENSSL_ALL && !NO_CERTS */
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_set_notAfter(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) \
    && !defined(NO_ASN_TIME) && !defined(USER_TIME) && \
    !defined(TIME_OVERRIDES) && !defined(NO_CERTS) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) &&\
    !defined(TIME_T_NOT_64BIT) && !defined(NO_64BIT) && !defined(NO_BIO)
    /* Generalized time will overflow time_t if not long */
    X509* x = NULL;
    BIO*  bio = NULL;
    ASN1_TIME *asn_time = NULL;
    ASN1_TIME *time_check = NULL;
    const int year = 365*24*60*60;
    const int day  = 24*60*60;
    const int hour = 60*60;
    const int mini = 60;
    int offset_day;
    unsigned char buf[25];
    time_t t;

    /*
     * Setup asn_time. APACHE HTTPD uses time(NULL)
     */
    t = (time_t)107 * year + 31 * day + 34 * hour + 30 * mini + 7 * day;
    offset_day = 7;
    /*
     * Free these.
     */
    asn_time = wolfSSL_ASN1_TIME_adj(NULL, t, offset_day, 0);
    ExpectNotNull(asn_time);
    ExpectNotNull(x = X509_new());
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    /*
     * Tests
     */
    ExpectTrue(wolfSSL_X509_set_notAfter(x, asn_time));
    /* time_check is simply (ANS1_TIME*)x->notAfter */
    ExpectNotNull(time_check = X509_get_notAfter(x));
    /* ANS1_TIME_check validates by checking if argument can be parsed */
    ExpectIntEQ(ASN1_TIME_check(time_check), WOLFSSL_SUCCESS);
    /* Convert to human readable format and compare to intended date */
    ExpectIntEQ(ASN1_TIME_print(bio, time_check), 1);
    ExpectIntEQ(BIO_read(bio, buf, sizeof(buf)), 24);
    ExpectIntEQ(XMEMCMP(buf, "Jan 20 10:30:00 2077 GMT", sizeof(buf) - 1), 0);

    ExpectFalse(wolfSSL_X509_set_notAfter(NULL, NULL));
    ExpectFalse(wolfSSL_X509_set_notAfter(x, NULL));
    ExpectFalse(wolfSSL_X509_set_notAfter(NULL, asn_time));

    /*
     * Cleanup
     */
    XFREE(asn_time, NULL, DYNAMIC_TYPE_OPENSSL);
    X509_free(x);
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_set_notBefore(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) \
    && !defined(NO_ASN_TIME) && !defined(USER_TIME) && \
    !defined(TIME_OVERRIDES) && !defined(NO_CERTS) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && !defined(NO_BIO)
    X509* x = NULL;
    BIO*  bio = NULL;
    ASN1_TIME *asn_time = NULL;
    ASN1_TIME *time_check = NULL;
    const int year = 365*24*60*60;
    const int day  = 24*60*60;
    const int hour = 60*60;
    const int mini = 60;
    int offset_day;
    unsigned char buf[25];
    time_t t;

    /*
     * Setup asn_time. APACHE HTTPD uses time(NULL)
     */
    t = (time_t)49 * year + 125 * day + 20 * hour + 30 * mini + 7 * day;
    offset_day = 7;

    /*
     * Free these.
     */
    asn_time = wolfSSL_ASN1_TIME_adj(NULL, t, offset_day, 0);
    ExpectNotNull(asn_time);
    ExpectNotNull(x = X509_new());
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(ASN1_TIME_check(asn_time), WOLFSSL_SUCCESS);

    /*
     * Main Tests
     */
    ExpectTrue(wolfSSL_X509_set_notBefore(x, asn_time));
    /* time_check == (ANS1_TIME*)x->notBefore */
    ExpectNotNull(time_check = X509_get_notBefore(x));
    /* ANS1_TIME_check validates by checking if argument can be parsed */
    ExpectIntEQ(ASN1_TIME_check(time_check), WOLFSSL_SUCCESS);
    /* Convert to human readable format and compare to intended date */
    ExpectIntEQ(ASN1_TIME_print(bio, time_check), 1);
    ExpectIntEQ(BIO_read(bio, buf, sizeof(buf)), 24);
    ExpectIntEQ(XMEMCMP(buf, "May  8 20:30:00 2019 GMT", sizeof(buf) - 1), 0);

    ExpectFalse(wolfSSL_X509_set_notBefore(NULL, NULL));
    ExpectFalse(wolfSSL_X509_set_notBefore(x, NULL));
    ExpectFalse(wolfSSL_X509_set_notBefore(NULL, asn_time));

    /*
     * Cleanup
     */
    XFREE(asn_time, NULL, DYNAMIC_TYPE_OPENSSL);
    X509_free(x);
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_set_version(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && \
    !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
    X509* x509 = NULL;
    long v = 2L;
    long maxInt = INT_MAX;

    ExpectNotNull(x509 = X509_new());
    /* These should pass. */
    ExpectTrue(wolfSSL_X509_set_version(x509, v));
    ExpectIntEQ(v, wolfSSL_X509_get_version(x509));
    /* Fail Case: When v(long) is greater than x509->version(int). */
    v = maxInt+1;
    ExpectFalse(wolfSSL_X509_set_version(x509, v));

    ExpectFalse(wolfSSL_X509_set_version(NULL, 2L));
    ExpectFalse(wolfSSL_X509_set_version(NULL, maxInt+1));

    /* Cleanup */
    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

#ifndef NO_BIO

static int test_wolfSSL_BIO_gets(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    BIO* bio = NULL;
    BIO* bio2 = NULL;
    char msg[] = "\nhello wolfSSL\n security plus\t---...**adf\na...b.c";
    char emp[] = "";
    char bio_buffer[20];
    int bufferSz = 20;
#ifdef OPENSSL_ALL
    BUF_MEM* emp_bm = NULL;
    BUF_MEM* msg_bm = NULL;
#endif

    /* try with bad args */
    ExpectNull(bio = BIO_new_mem_buf(NULL, sizeof(msg)));
#ifdef OPENSSL_ALL
    ExpectIntEQ(BIO_set_mem_buf(bio, NULL, BIO_NOCLOSE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    /* try with real msg */
    ExpectNotNull(bio = BIO_new_mem_buf((void*)msg, -1));
    XMEMSET(bio_buffer, 0, bufferSz);
    ExpectNotNull(BIO_push(bio, BIO_new(BIO_s_bio())));
    ExpectNull(bio2 = BIO_find_type(bio, BIO_TYPE_FILE));
    ExpectNotNull(bio2 = BIO_find_type(bio, BIO_TYPE_BIO));
    ExpectFalse(bio2 != BIO_next(bio));

    /* make buffer filled with no terminating characters */
    XMEMSET(bio_buffer, 1, bufferSz);

    /* BIO_gets reads a line of data */
    ExpectIntEQ(BIO_gets(bio, bio_buffer, -3), 0);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 1);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 14);
    ExpectStrEQ(bio_buffer, "hello wolfSSL\n");
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 19);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 8);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, -1), 0);

#ifdef OPENSSL_ALL
    /* test setting the mem_buf manually */
    BIO_free(bio);
    ExpectNotNull(bio = BIO_new_mem_buf((void*)msg, -1));
    ExpectNotNull(emp_bm = BUF_MEM_new());
    ExpectNotNull(msg_bm = BUF_MEM_new());
    ExpectIntEQ(BUF_MEM_grow(msg_bm, sizeof(msg)), sizeof(msg));
    if (EXPECT_SUCCESS()) {
        XFREE(msg_bm->data, NULL, DYNAMIC_TYPE_OPENSSL);
        msg_bm->data = NULL;
    }
    /* emp size is 1 for terminator */
    ExpectIntEQ(BUF_MEM_grow(emp_bm, sizeof(emp)), sizeof(emp));
    if (EXPECT_SUCCESS()) {
        XFREE(emp_bm->data, NULL, DYNAMIC_TYPE_OPENSSL);
        emp_bm->data = emp;
        msg_bm->data = msg;
    }
    ExpectIntEQ(BIO_set_mem_buf(bio, emp_bm, BIO_CLOSE), WOLFSSL_SUCCESS);

    /* check reading an empty string */
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 1); /* just terminator */
    ExpectStrEQ(emp, bio_buffer);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 0); /* Nothing to read */

    /* BIO_gets reads a line of data */
    ExpectIntEQ(BIO_set_mem_buf(bio, msg_bm, BIO_NOCLOSE), WOLFSSL_SUCCESS);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, -3), 0);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 1);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 14);
    ExpectStrEQ(bio_buffer, "hello wolfSSL\n");
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 19);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 8);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, -1), 0);

    if (EXPECT_SUCCESS())
        emp_bm->data = NULL;
    BUF_MEM_free(emp_bm);
    if (EXPECT_SUCCESS())
        msg_bm->data = NULL;
    BUF_MEM_free(msg_bm);
#endif

    /* check not null terminated string */
    BIO_free(bio);
    bio = NULL;
    msg[0] = 0x33;
    msg[1] = 0x33;
    msg[2] = 0x33;
    ExpectNotNull(bio = BIO_new_mem_buf((void*)msg, 3));
    ExpectIntEQ(BIO_gets(bio, bio_buffer, 3), 2);
    ExpectIntEQ(bio_buffer[0], msg[0]);
    ExpectIntEQ(bio_buffer[1], msg[1]);
    ExpectIntNE(bio_buffer[2], msg[2]);

    BIO_free(bio);
    bio = NULL;
    msg[3]    = 0x33;
    bio_buffer[3] = 0x33;
    ExpectNotNull(bio = BIO_new_mem_buf((void*)msg, 3));
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 3);
    ExpectIntEQ(bio_buffer[0], msg[0]);
    ExpectIntEQ(bio_buffer[1], msg[1]);
    ExpectIntEQ(bio_buffer[2], msg[2]);
    ExpectIntNE(bio_buffer[3], 0x33); /* make sure null terminator was set */

    /* check reading an empty string */
    BIO_free(bio);
    bio = NULL;
    ExpectNotNull(bio = BIO_new_mem_buf((void*)emp, sizeof(emp)));
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 1); /* just terminator */
    ExpectStrEQ(emp, bio_buffer);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 0); /* Nothing to read */

    /* check error cases */
    BIO_free(bio);
    bio = NULL;
    ExpectIntEQ(BIO_gets(NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(BIO_gets(bio, bio_buffer, 2), 0); /* nothing to read */

#if !defined(NO_FILESYSTEM)
    {
        BIO*  f_bio = NULL;
        XFILE f = XBADFILE;

        ExpectNotNull(f_bio = BIO_new(BIO_s_file()));
        ExpectIntLE(BIO_gets(f_bio, bio_buffer, bufferSz), 0);

        ExpectTrue((f = XFOPEN(svrCertFile, "rb")) != XBADFILE);
        ExpectIntEQ((int)BIO_set_fp(f_bio, f, BIO_CLOSE), SSL_SUCCESS);
        if (EXPECT_FAIL() && (f != XBADFILE)) {
            XFCLOSE(f);
        }
        ExpectIntGT(BIO_gets(f_bio, bio_buffer, bufferSz), 0);

        BIO_free(f_bio);
        f_bio = NULL;
    }
#endif /* NO_FILESYSTEM */

    BIO_free(bio);
    bio = NULL;
    BIO_free(bio2);
    bio2 = NULL;

    /* try with type BIO */
    XMEMCPY(msg, "\nhello wolfSSL\n security plus\t---...**adf\na...b.c",
        sizeof(msg));
    ExpectNotNull(bio = BIO_new(BIO_s_bio()));
    ExpectIntEQ(BIO_gets(bio, bio_buffer, 2), 0); /* nothing to read */
    ExpectNotNull(bio2 = BIO_new(BIO_s_bio()));

    ExpectIntEQ(BIO_set_write_buf_size(bio, 10),           SSL_SUCCESS);
    ExpectIntEQ(BIO_set_write_buf_size(bio2, sizeof(msg)), SSL_SUCCESS);
    ExpectIntEQ(BIO_make_bio_pair(bio, bio2),              SSL_SUCCESS);

    ExpectIntEQ(BIO_write(bio2, msg, sizeof(msg)), sizeof(msg));
    ExpectIntEQ(BIO_gets(bio, bio_buffer, -3), 0);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 1);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 14);
    ExpectStrEQ(bio_buffer, "hello wolfSSL\n");
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 19);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 8);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, -1), 0);

    BIO_free(bio);
    bio = NULL;
    BIO_free(bio2);
    bio2 = NULL;

    /* check reading an empty string */
    ExpectNotNull(bio = BIO_new(BIO_s_bio()));
    ExpectIntEQ(BIO_set_write_buf_size(bio, sizeof(emp)), SSL_SUCCESS);
    ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 0); /* Nothing to read */
    ExpectStrEQ(emp, bio_buffer);

    BIO_free(bio);
    bio = NULL;
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_BIO_puts(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    BIO* bio = NULL;
    char input[] = "hello\0world\n.....ok\n\0";
    char output[128];

    XMEMSET(output, 0, sizeof(output));
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(BIO_puts(bio, input), 5);
    ExpectIntEQ(BIO_pending(bio), 5);
    ExpectIntEQ(BIO_puts(bio, input + 6), 14);
    ExpectIntEQ(BIO_pending(bio), 19);
    ExpectIntEQ(BIO_gets(bio, output, sizeof(output)), 11);
    ExpectStrEQ(output, "helloworld\n");
    ExpectIntEQ(BIO_pending(bio), 8);
    ExpectIntEQ(BIO_gets(bio, output, sizeof(output)), 8);
    ExpectStrEQ(output, ".....ok\n");
    ExpectIntEQ(BIO_pending(bio), 0);
    ExpectIntEQ(BIO_puts(bio, ""), -1);

    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BIO_dump(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    BIO* bio;
    static const unsigned char data[] = {
        0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE,
        0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
        0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x55, 0xBF, 0xF4,
        0x0F, 0x44, 0x50, 0x9A, 0x3D, 0xCE, 0x9B, 0xB7, 0xF0, 0xC5,
        0x4D, 0xF5, 0x70, 0x7B, 0xD4, 0xEC, 0x24, 0x8E, 0x19, 0x80,
        0xEC, 0x5A, 0x4C, 0xA2, 0x24, 0x03, 0x62, 0x2C, 0x9B, 0xDA,
        0xEF, 0xA2, 0x35, 0x12, 0x43, 0x84, 0x76, 0x16, 0xC6, 0x56,
        0x95, 0x06, 0xCC, 0x01, 0xA9, 0xBD, 0xF6, 0x75, 0x1A, 0x42,
        0xF7, 0xBD, 0xA9, 0xB2, 0x36, 0x22, 0x5F, 0xC7, 0x5D, 0x7F,
        0xB4
    };
    /* Generated with OpenSSL. */
    static const char expected[] =
"0000 - 30 59 30 13 06 07 2a 86-48 ce 3d 02 01 06 08 2a   0Y0...*.H.=....*\n"
"0010 - 86 48 ce 3d 03 01 07 03-42 00 04 55 bf f4 0f 44   .H.=....B..U...D\n"
"0020 - 50 9a 3d ce 9b b7 f0 c5-4d f5 70 7b d4 ec 24 8e   P.=.....M.p{..$.\n"
"0030 - 19 80 ec 5a 4c a2 24 03-62 2c 9b da ef a2 35 12   ...ZL.$.b,....5.\n"
"0040 - 43 84 76 16 c6 56 95 06-cc 01 a9 bd f6 75 1a 42   C.v..V.......u.B\n"
"0050 - f7 bd a9 b2 36 22 5f c7-5d 7f b4                  ....6\"_.]..\n";
    static const char expectedAll[] =
"0000 - 00 01 02 03 04 05 06 07-08 09 0a 0b 0c 0d 0e 0f   ................\n"
"0010 - 10 11 12 13 14 15 16 17-18 19 1a 1b 1c 1d 1e 1f   ................\n"
"0020 - 20 21 22 23 24 25 26 27-28 29 2a 2b 2c 2d 2e 2f    !\"#$%&'()*+,-./\n"
"0030 - 30 31 32 33 34 35 36 37-38 39 3a 3b 3c 3d 3e 3f   0123456789:;<=>?\n"
"0040 - 40 41 42 43 44 45 46 47-48 49 4a 4b 4c 4d 4e 4f   @ABCDEFGHIJKLMNO\n"
"0050 - 50 51 52 53 54 55 56 57-58 59 5a 5b 5c 5d 5e 5f   PQRSTUVWXYZ[\\]^_\n"
"0060 - 60 61 62 63 64 65 66 67-68 69 6a 6b 6c 6d 6e 6f   `abcdefghijklmno\n"
"0070 - 70 71 72 73 74 75 76 77-78 79 7a 7b 7c 7d 7e 7f   pqrstuvwxyz{|}~.\n"
"0080 - 80 81 82 83 84 85 86 87-88 89 8a 8b 8c 8d 8e 8f   ................\n"
"0090 - 90 91 92 93 94 95 96 97-98 99 9a 9b 9c 9d 9e 9f   ................\n"
"00a0 - a0 a1 a2 a3 a4 a5 a6 a7-a8 a9 aa ab ac ad ae af   ................\n"
"00b0 - b0 b1 b2 b3 b4 b5 b6 b7-b8 b9 ba bb bc bd be bf   ................\n"
"00c0 - c0 c1 c2 c3 c4 c5 c6 c7-c8 c9 ca cb cc cd ce cf   ................\n"
"00d0 - d0 d1 d2 d3 d4 d5 d6 d7-d8 d9 da db dc dd de df   ................\n"
"00e0 - e0 e1 e2 e3 e4 e5 e6 e7-e8 e9 ea eb ec ed ee ef   ................\n"
"00f0 - f0 f1 f2 f3 f4 f5 f6 f7-f8 f9 fa fb fc fd fe ff   ................\n";
    char output[16 * 80];
    int i;

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));

    /* Example key dumped. */
    ExpectIntEQ(BIO_dump(bio, (const char*)data, (int)sizeof(data)),
        sizeof(expected) - 1);
    ExpectIntEQ(BIO_read(bio, output, sizeof(output)), sizeof(expected) - 1);
    ExpectIntEQ(XMEMCMP(output, expected, sizeof(expected) - 1), 0);

    /* Try every possible value for a character. */
    for (i = 0; i < 256; i++)
       output[i] = i;
    ExpectIntEQ(BIO_dump(bio, output, 256), sizeof(expectedAll) - 1);
    ExpectIntEQ(BIO_read(bio, output, sizeof(output)), sizeof(expectedAll) - 1);
    ExpectIntEQ(XMEMCMP(output, expectedAll, sizeof(expectedAll) - 1), 0);

    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(USE_WOLFSSL_IO)
static int forceWantRead(WOLFSSL *ssl, char *buf, int sz, void *ctx)
{
    (void)ssl;
    (void)buf;
    (void)sz;
    (void)ctx;
    return WOLFSSL_CBIO_ERR_WANT_READ;
}
#endif

static int test_wolfSSL_BIO_should_retry(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(USE_WOLFSSL_IO)
    tcp_ready ready;
    func_args server_args;
    THREAD_TYPE serverThread;
    SOCKET_T sockfd = 0;
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;
    char msg[64] = "hello wolfssl!";
    char reply[1024];
    int  msgSz = (int)XSTRLEN(msg);
    int  ret;
    BIO* bio = NULL;

    XMEMSET(&server_args, 0, sizeof(func_args));
#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    StartTCP();
    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    server_args.signal = &ready;
    start_thread(test_server_nofail, &server_args, &serverThread);
    wait_tcp_ready(&server_args);


    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#ifdef OPENSSL_COMPATIBLE_DEFAULTS
    ExpectIntEQ(wolfSSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY), 0);
#endif
    ExpectIntEQ(WOLFSSL_SUCCESS,
            wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0));
    ExpectIntEQ(WOLFSSL_SUCCESS,
          wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM));
    ExpectIntEQ(WOLFSSL_SUCCESS,
            wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));
    tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL);

    /* force retry */
    ExpectNotNull(bio = wolfSSL_BIO_new_ssl(ctx, 1));
    ExpectIntEQ(BIO_get_ssl(bio, &ssl), 1);
    ExpectNotNull(ssl);
    ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
    wolfSSL_SSLSetIORecv(ssl, forceWantRead);
    if (EXPECT_FAIL()) {
        wolfSSL_free(ssl);
        ssl = NULL;
    }

    ExpectIntLE(BIO_write(bio, msg, msgSz), 0);
    ExpectIntNE(BIO_should_retry(bio), 0);
    ExpectIntEQ(BIO_should_read(bio), 0);
    ExpectIntEQ(BIO_should_write(bio), 0);


    /* now perform successful connection */
    wolfSSL_SSLSetIORecv(ssl, EmbedReceive);
    ExpectIntEQ(BIO_write(bio, msg, msgSz), msgSz);
    ExpectIntNE(BIO_read(bio, reply, sizeof(reply)), 0);
    ret = wolfSSL_get_error(ssl, -1);
    if (ret == WOLFSSL_ERROR_WANT_READ || ret == WOLFSSL_ERROR_WANT_WRITE) {
        ExpectIntNE(BIO_should_retry(bio), 0);

        if (ret == WOLFSSL_ERROR_WANT_READ)
            ExpectIntEQ(BIO_should_read(bio), 1);
        else
            ExpectIntEQ(BIO_should_read(bio), 0);

        if (ret == WOLFSSL_ERROR_WANT_WRITE)
            ExpectIntEQ(BIO_should_write(bio), 1);
        else
            ExpectIntEQ(BIO_should_write(bio), 0);
    }
    else {
        ExpectIntEQ(BIO_should_retry(bio), 0);
        ExpectIntEQ(BIO_should_read(bio), 0);
        ExpectIntEQ(BIO_should_write(bio), 0);
    }
    ExpectIntEQ(XMEMCMP(reply, "I hear you fa shizzle!",
                XSTRLEN("I hear you fa shizzle!")), 0);
    BIO_free(bio);
    wolfSSL_CTX_free(ctx);

    CloseSocket(sockfd);

    join_thread(serverThread);
    FreeTcpReady(&ready);

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BIO_connect(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
            defined(HAVE_HTTP_CLIENT) && !defined(NO_WOLFSSL_CLIENT)
    tcp_ready ready;
    func_args server_args;
    THREAD_TYPE serverThread;
    BIO *tcpBio = NULL;
    BIO *sslBio = NULL;
    SSL_CTX* ctx = NULL;
    SSL *ssl = NULL;
    SSL *sslPtr;
    char msg[] = "hello wolfssl!";
    char reply[30];
    char buff[10] = {0};

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectIntEQ(WOLFSSL_SUCCESS,
            wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0));
    ExpectIntEQ(WOLFSSL_SUCCESS,
          wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM));
    ExpectIntEQ(WOLFSSL_SUCCESS,
            wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));

    /* Setup server */
    XMEMSET(&server_args, 0, sizeof(func_args));
    StartTCP();
    InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif
    server_args.signal = &ready;
    start_thread(test_server_nofail, &server_args, &serverThread);
    wait_tcp_ready(&server_args);
    ExpectIntGT(XSNPRINTF(buff, sizeof(buff), "%d", ready.port), 0);

    /* Start the test proper */
    /* Setup the TCP BIO */
    ExpectNotNull(tcpBio = BIO_new_connect(wolfSSLIP));
    ExpectIntEQ(BIO_set_conn_port(tcpBio, buff), 1);
    /* Setup the SSL object */
    ExpectNotNull(ssl = SSL_new(ctx));
    SSL_set_connect_state(ssl);
    /* Setup the SSL BIO */
    ExpectNotNull(sslBio = BIO_new(BIO_f_ssl()));
    ExpectIntEQ(BIO_set_ssl(sslBio, ssl, BIO_CLOSE), 1);
    if (EXPECT_FAIL()) {
        wolfSSL_free(ssl);
    }
    /* Verify that BIO_get_ssl works. */
    ExpectIntEQ(BIO_get_ssl(sslBio, &sslPtr), 1);
    ExpectPtrEq(ssl, sslPtr);
    /* Link BIO's so that sslBio uses tcpBio for IO */
    ExpectPtrEq(BIO_push(sslBio, tcpBio), sslBio);
    /* Do TCP connect */
    ExpectIntEQ(BIO_do_connect(sslBio), 1);
    /* Do TLS handshake */
    ExpectIntEQ(BIO_do_handshake(sslBio), 1);
    /* Test writing */
    ExpectIntEQ(BIO_write(sslBio, msg, sizeof(msg)), sizeof(msg));
    /* Expect length of default wolfSSL reply */
    ExpectIntEQ(BIO_read(sslBio, reply, sizeof(reply)), 23);

    /* Clean it all up */
    BIO_free_all(sslBio);
    /* Server clean up */
    join_thread(serverThread);
    FreeTcpReady(&ready);

    /* Run the same test, but use BIO_new_ssl_connect and set the IP and port
     * after. */
    XMEMSET(&server_args, 0, sizeof(func_args));
    StartTCP();
    InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif
    server_args.signal = &ready;
    start_thread(test_server_nofail, &server_args, &serverThread);
    wait_tcp_ready(&server_args);
    ExpectIntGT(XSNPRINTF(buff, sizeof(buff), "%d", ready.port), 0);

    ExpectNotNull(sslBio = BIO_new_ssl_connect(ctx));
    ExpectIntEQ(BIO_set_conn_hostname(sslBio, (char*)wolfSSLIP), 1);
    ExpectIntEQ(BIO_set_conn_port(sslBio, buff), 1);
    ExpectIntEQ(BIO_do_connect(sslBio), 1);
    ExpectIntEQ(BIO_do_handshake(sslBio), 1);
    ExpectIntEQ(BIO_write(sslBio, msg, sizeof(msg)), sizeof(msg));
    ExpectIntEQ(BIO_read(sslBio, reply, sizeof(reply)), 23);
    /* Attempt to close the TLS connection gracefully. */
    BIO_ssl_shutdown(sslBio);

    BIO_free_all(sslBio);
    join_thread(serverThread);
    FreeTcpReady(&ready);

    SSL_CTX_free(ctx);

#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_BIO_tls(void)
{
    EXPECT_DECLS;
#if !defined(NO_BIO) && defined(OPENSSL_EXTRA) && !defined(NO_WOLFSSL_CLIENT)
    SSL_CTX* ctx = NULL;
    SSL *ssl = NULL;
    BIO *readBio = NULL;
    BIO *writeBio = NULL;
    int ret;
    int err = 0;

    ExpectNotNull(ctx = SSL_CTX_new(SSLv23_method()));
    ExpectNotNull(ssl = SSL_new(ctx));

    ExpectNotNull(readBio = BIO_new(BIO_s_mem()));
    ExpectNotNull(writeBio = BIO_new(BIO_s_mem()));
    /* Qt reads data from write-bio,
     * then writes the read data into plain packet.
     * Qt reads data from plain packet,
     * then writes the read data into read-bio.
     */
    SSL_set_bio(ssl, readBio, writeBio);

    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = SSL_connect(ssl);
        err = SSL_get_error(ssl, 0);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    ExpectIntEQ(ret, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    /* in this use case, should return WANT READ
     * so that Qt will read the data from plain packet for next state.
     */
    ExpectIntEQ(err, SSL_ERROR_WANT_READ);

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_BIO_datagram(void)
{
    EXPECT_DECLS;
#if !defined(NO_BIO) && defined(WOLFSSL_DTLS) && defined(WOLFSSL_HAVE_BIO_ADDR) && defined(OPENSSL_EXTRA)
    int ret;
    SOCKET_T fd1 = SOCKET_INVALID, fd2 = SOCKET_INVALID;
    WOLFSSL_BIO *bio1 = NULL, *bio2 = NULL;
    WOLFSSL_BIO_ADDR *bio_addr1 = NULL, *bio_addr2 = NULL;
    SOCKADDR_IN sin1, sin2;
    socklen_t slen;
    static const char test_msg[] = "I am a datagram, short and stout.";
    char test_msg_recvd[sizeof(test_msg) + 10];
#ifdef USE_WINDOWS_API
    static const DWORD timeout = 250; /* ms */
#else
    static const struct timeval timeout = { 0, 250000 };
#endif

    StartTCP();

    if (EXPECT_SUCCESS()) {
        fd1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        ExpectIntNE(fd1, SOCKET_INVALID);
    }
    if (EXPECT_SUCCESS()) {
        fd2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        ExpectIntNE(fd2, SOCKET_INVALID);
    }

    if (EXPECT_SUCCESS()) {
        bio1 = wolfSSL_BIO_new_dgram(fd1, 1 /* closeF */);
        ExpectNotNull(bio1);
    }

    if (EXPECT_SUCCESS()) {
        bio2 = wolfSSL_BIO_new_dgram(fd2, 1 /* closeF */);
        ExpectNotNull(bio2);
    }

    if (EXPECT_SUCCESS()) {
        sin1.sin_family = AF_INET;
        sin1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
        sin1.sin_port = 0;
        slen = (socklen_t)sizeof(sin1);
        ExpectIntEQ(bind(fd1, (const struct sockaddr *)&sin1, slen), 0);
        ExpectIntEQ(setsockopt(fd1, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)), 0);
        ExpectIntEQ(getsockname(fd1, (struct sockaddr *)&sin1, &slen), 0);
    }

    if (EXPECT_SUCCESS()) {
        sin2.sin_family = AF_INET;
        sin2.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
        sin2.sin_port = 0;
        slen = (socklen_t)sizeof(sin2);
        ExpectIntEQ(bind(fd2, (const struct sockaddr *)&sin2, slen), 0);
        ExpectIntEQ(setsockopt(fd2, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)), 0);
        ExpectIntEQ(getsockname(fd2, (struct sockaddr *)&sin2, &slen), 0);
    }

    if (EXPECT_SUCCESS()) {
        bio_addr1 = wolfSSL_BIO_ADDR_new();
        ExpectNotNull(bio_addr1);
    }

    if (EXPECT_SUCCESS()) {
        bio_addr2 = wolfSSL_BIO_ADDR_new();
        ExpectNotNull(bio_addr2);
    }

    if (EXPECT_SUCCESS()) {
        /* for OpenSSL compatibility, direct copying of sockaddrs into BIO_ADDRs must work right. */
        XMEMCPY(&bio_addr2->sa_in, &sin2, sizeof(sin2));
        ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio1, BIO_CTRL_DGRAM_SET_PEER, 0, bio_addr2), WOLFSSL_SUCCESS);
        wolfSSL_BIO_ADDR_clear(bio_addr2);
    }

    test_msg_recvd[0] = 0;
    ExpectIntEQ(wolfSSL_BIO_write(bio1, test_msg, sizeof(test_msg)), (int)sizeof(test_msg));
    ExpectIntEQ(wolfSSL_BIO_read(bio2, test_msg_recvd, sizeof(test_msg_recvd)), (int)sizeof(test_msg));
    ExpectIntEQ(XMEMCMP(test_msg_recvd, test_msg, sizeof(test_msg)), 0);

#ifdef WOLFSSL_BIO_HAVE_FLOW_STATS
    ExpectIntEQ(wolfSSL_BIO_number_written(bio1), sizeof(test_msg));
    ExpectIntEQ(wolfSSL_BIO_number_read(bio2), sizeof(test_msg));
#endif

    /* bio2 should now have bio1's addr stored as its peer_addr, because the
     * BIOs aren't "connected" yet.  use it to send a reply.
     */

    test_msg_recvd[0] = 0;
    ExpectIntEQ(wolfSSL_BIO_write(bio2, test_msg, sizeof(test_msg)), (int)sizeof(test_msg));
    ExpectIntEQ(wolfSSL_BIO_read(bio1, test_msg_recvd, sizeof(test_msg_recvd)), (int)sizeof(test_msg));
    ExpectIntEQ(XMEMCMP(test_msg_recvd, test_msg, sizeof(test_msg)), 0);

    ExpectIntEQ(wolfSSL_BIO_read(bio1, test_msg_recvd, sizeof(test_msg_recvd)), WOLFSSL_BIO_ERROR);
    ExpectIntNE(BIO_should_retry(bio1), 0);

    ExpectIntEQ(wolfSSL_BIO_read(bio2, test_msg_recvd, sizeof(test_msg_recvd)), WOLFSSL_BIO_ERROR);
    ExpectIntNE(BIO_should_retry(bio2), 0);

    /* now "connect" the sockets. */

    ExpectIntEQ(connect(fd1, (const struct sockaddr *)&sin2, (socklen_t)sizeof(sin2)), 0);
    ExpectIntEQ(connect(fd2, (const struct sockaddr *)&sin1, (socklen_t)sizeof(sin1)), 0);

    if (EXPECT_SUCCESS()) {
        XMEMCPY(&bio_addr2->sa_in, &sin2, sizeof(sin2));
        ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio1, BIO_CTRL_DGRAM_SET_CONNECTED, 0, bio_addr2), WOLFSSL_SUCCESS);
        wolfSSL_BIO_ADDR_clear(bio_addr2);
    }

    if (EXPECT_SUCCESS()) {
        XMEMCPY(&bio_addr1->sa_in, &sin1, sizeof(sin1));
        ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio2, BIO_CTRL_DGRAM_SET_CONNECTED, 0, bio_addr1), WOLFSSL_SUCCESS);
        wolfSSL_BIO_ADDR_clear(bio_addr1);
    }

    test_msg_recvd[0] = 0;
    ExpectIntEQ(wolfSSL_BIO_write(bio2, test_msg, sizeof(test_msg)), (int)sizeof(test_msg));
    ExpectIntEQ(wolfSSL_BIO_read(bio1, test_msg_recvd, sizeof(test_msg_recvd)), (int)sizeof(test_msg));
    ExpectIntEQ(XMEMCMP(test_msg_recvd, test_msg, sizeof(test_msg)), 0);

    test_msg_recvd[0] = 0;
    ExpectIntEQ(wolfSSL_BIO_write(bio1, test_msg, sizeof(test_msg)), (int)sizeof(test_msg));
    ExpectIntEQ(wolfSSL_BIO_read(bio2, test_msg_recvd, sizeof(test_msg_recvd)), (int)sizeof(test_msg));
    ExpectIntEQ(XMEMCMP(test_msg_recvd, test_msg, sizeof(test_msg)), 0);

#ifdef __linux__
    /* now "disconnect" the sockets and attempt transmits expected to fail. */

    sin1.sin_family = AF_UNSPEC;
    ExpectIntEQ(connect(fd1, (const struct sockaddr *)&sin1, (socklen_t)sizeof(sin1)), 0);
    ExpectIntEQ(connect(fd2, (const struct sockaddr *)&sin1, (socklen_t)sizeof(sin1)), 0);
    sin1.sin_family = AF_INET;

    ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio1, BIO_CTRL_DGRAM_SET_CONNECTED, 0, NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio2, BIO_CTRL_DGRAM_SET_CONNECTED, 0, NULL), WOLFSSL_SUCCESS);

    if (EXPECT_SUCCESS()) {
        sin2.sin_addr.s_addr = htonl(0xc0a8c0a8); /* 192.168.192.168 -- invalid for loopback interface. */
        XMEMCPY(&bio_addr2->sa_in, &sin2, sizeof(sin2));
        ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio1, BIO_CTRL_DGRAM_SET_PEER, 0, bio_addr2), WOLFSSL_SUCCESS);
        wolfSSL_BIO_ADDR_clear(bio_addr2);
    }

    test_msg_recvd[0] = 0;
    errno = 0;
    ExpectIntEQ(wolfSSL_BIO_write(bio1, test_msg, sizeof(test_msg)), -1);
    ExpectTrue((errno == EINVAL) || (errno == ENETUNREACH));

#endif /* __linux__ */


    if (bio1) {
        ret = wolfSSL_BIO_free(bio1);
        ExpectIntEQ(ret, WOLFSSL_SUCCESS);
    } else if (fd1 != SOCKET_INVALID)
        CloseSocket(fd1);
    if (bio2) {
        ret = wolfSSL_BIO_free(bio2);
        ExpectIntEQ(ret, WOLFSSL_SUCCESS);
    } else if (fd2 != SOCKET_INVALID)
        CloseSocket(fd2);
    if (bio_addr1)
        wolfSSL_BIO_ADDR_free(bio_addr1);
    if (bio_addr2)
        wolfSSL_BIO_ADDR_free(bio_addr2);

#endif /* !NO_BIO && WOLFSSL_DTLS && WOLFSSL_HAVE_BIO_ADDR && OPENSSL_EXTRA */

    return EXPECT_RESULT();
}


#if defined(OPENSSL_ALL) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
    defined(HAVE_HTTP_CLIENT)
static THREAD_RETURN WOLFSSL_THREAD test_wolfSSL_BIO_accept_client(void* args)
{
    BIO* clientBio;
    SSL* sslClient;
    SSL_CTX* ctx;
    char connectAddr[20]; /* IP + port */;

    (void)args;

    AssertIntGT(snprintf(connectAddr, sizeof(connectAddr), "%s:%d", wolfSSLIP, wolfSSLPort), 0);
    AssertNotNull(clientBio = BIO_new_connect(connectAddr));
    AssertIntEQ(BIO_do_connect(clientBio), 1);
    AssertNotNull(ctx = SSL_CTX_new(SSLv23_method()));
    AssertNotNull(sslClient = SSL_new(ctx));
    AssertIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0), WOLFSSL_SUCCESS);
    SSL_set_bio(sslClient, clientBio, clientBio);
    AssertIntEQ(SSL_connect(sslClient), 1);

    SSL_free(sslClient);
    SSL_CTX_free(ctx);

#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

    WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif

static int test_wolfSSL_BIO_accept(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
    defined(HAVE_HTTP_CLIENT)
    BIO* serverBindBio = NULL;
    BIO* serverAcceptBio = NULL;
    SSL* sslServer = NULL;
    SSL_CTX* ctx = NULL;
    func_args args;
    THREAD_TYPE thread;
    char port[10]; /* 10 bytes should be enough to store the string
                    * representation of the port */

    ExpectIntGT(snprintf(port, sizeof(port), "%d", wolfSSLPort), 0);
    ExpectNotNull(serverBindBio = BIO_new_accept(port));

    /* First BIO_do_accept binds the port */
    ExpectIntEQ(BIO_do_accept(serverBindBio), 1);

    XMEMSET(&args, 0, sizeof(func_args));
    start_thread(test_wolfSSL_BIO_accept_client, &args, &thread);

    ExpectIntEQ(BIO_do_accept(serverBindBio), 1);
    /* Let's plug it into SSL to test */
    ExpectNotNull(ctx = SSL_CTX_new(SSLv23_method()));
    ExpectIntEQ(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
        SSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
        SSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectNotNull(sslServer = SSL_new(ctx));
    ExpectNotNull(serverAcceptBio = BIO_pop(serverBindBio));
    SSL_set_bio(sslServer, serverAcceptBio, serverAcceptBio);
    ExpectIntEQ(SSL_accept(sslServer), 1);

    join_thread(thread);

    BIO_free(serverBindBio);
    SSL_free(sslServer);
    SSL_CTX_free(ctx);

#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BIO_write(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_ENCODE)
    BIO* bio = NULL;
    BIO* bio64 = NULL;
    BIO* bio_mem = NULL;
    BIO* ptr = NULL;
    int  sz;
    char msg[] = "conversion test";
    char out[40];
    char expected[] = "Y29udmVyc2lvbiB0ZXN0AA==\n";
    void* bufPtr = NULL;
    BUF_MEM* buf = NULL;

    ExpectNotNull(bio64 = BIO_new(BIO_f_base64()));
    ExpectNotNull(bio   = BIO_push(bio64, BIO_new(BIO_s_mem())));
    if (EXPECT_FAIL()) {
        BIO_free(bio64);
    }

    /* now should convert to base64 then write to memory */
    ExpectIntEQ(BIO_write(bio, msg, sizeof(msg)), sizeof(msg));
    BIO_flush(bio);

    /* test BIO chain */
    ExpectIntEQ(SSL_SUCCESS, (int)BIO_get_mem_ptr(bio, &buf));
    ExpectNotNull(buf);
    ExpectIntEQ(buf->length, 25);
    ExpectIntEQ(BIO_get_mem_data(bio, &bufPtr), 25);
    ExpectPtrEq(buf->data, bufPtr);

    ExpectNotNull(ptr = BIO_find_type(bio, BIO_TYPE_MEM));
    sz = sizeof(out);
    XMEMSET(out, 0, sz);
    ExpectIntEQ((sz = BIO_read(ptr, out, sz)), 25);
    ExpectIntEQ(XMEMCMP(out, expected, sz), 0);

    /* write then read should return the same message */
    ExpectIntEQ(BIO_write(bio, msg, sizeof(msg)), sizeof(msg));
    sz = sizeof(out);
    XMEMSET(out, 0, sz);
    ExpectIntEQ(BIO_read(bio, out, sz), 16);
    ExpectIntEQ(XMEMCMP(out, msg, sizeof(msg)), 0);

    /* now try encoding with no line ending */
    BIO_set_flags(bio64, BIO_FLAGS_BASE64_NO_NL);
#ifdef HAVE_EX_DATA
    BIO_set_ex_data(bio64, 0, (void*) "data");
    ExpectIntEQ(strcmp((const char*)BIO_get_ex_data(bio64, 0), "data"), 0);
#endif
    ExpectIntEQ(BIO_write(bio, msg, sizeof(msg)), sizeof(msg));
    BIO_flush(bio);
    sz = sizeof(out);
    XMEMSET(out, 0, sz);
    ExpectIntEQ((sz = BIO_read(ptr, out, sz)), 24);
    ExpectIntEQ(XMEMCMP(out, expected, sz), 0);

    BIO_free_all(bio); /* frees bio64 also */
    bio = NULL;

    /* test with more than one bio64 in list */
    ExpectNotNull(bio64 = BIO_new(BIO_f_base64()));
    ExpectNotNull(bio   = BIO_push(BIO_new(BIO_f_base64()), bio64));
    if (EXPECT_FAIL()) {
        BIO_free(bio64);
        bio64 = NULL;
    }
    ExpectNotNull(bio_mem = BIO_new(BIO_s_mem()));
    ExpectNotNull(BIO_push(bio64, bio_mem));
    if (EXPECT_FAIL()) {
        BIO_free(bio_mem);
    }

    /* now should convert to base64 when stored and then decode with read */
    ExpectIntEQ(BIO_write(bio, msg, sizeof(msg)), 25);
    BIO_flush(bio);
    sz = sizeof(out);
    XMEMSET(out, 0, sz);
    ExpectIntEQ((sz = BIO_read(bio, out, sz)), 16);
    ExpectIntEQ(XMEMCMP(out, msg, sz), 0);
    BIO_clear_flags(bio64, ~0);
    BIO_set_retry_read(bio);
    BIO_free_all(bio); /* frees bio64s also */
    bio = NULL;

    ExpectNotNull(bio = BIO_new_mem_buf(out, 0));
    ExpectIntEQ(BIO_write(bio, msg, sizeof(msg)), sizeof(msg));
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_BIO_printf(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL)
    BIO* bio = NULL;
    int  sz = 7;
    char msg[] = "TLS 1.3 for the world";
    char out[60];
    char expected[] = "TLS 1.3 for the world : sz = 7";

    XMEMSET(out, 0, sizeof(out));
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(BIO_printf(bio, "%s : sz = %d", msg, sz), 30);
    ExpectIntEQ(BIO_printf(NULL, ""), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(BIO_read(bio, out, sizeof(out)), 30);
    ExpectIntEQ(XSTRNCMP(out, expected, sizeof(expected)), 0);
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BIO_f_md(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_SHA256)
    BIO* bio = NULL;
    BIO* mem = NULL;
    char msg[] = "message to hash";
    char out[60];
    EVP_MD_CTX* ctx = NULL;
    const unsigned char testKey[] =
    {
        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
        0x0b, 0x0b, 0x0b, 0x0b
    };
    const char testData[] = "Hi There";
    const unsigned char testResult[] =
    {
        0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
        0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
        0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
        0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7
    };
    const unsigned char expectedHash[] =
    {
       0x66, 0x49, 0x3C, 0xE8, 0x8A, 0x57, 0xB0, 0x60,
       0xDC, 0x55, 0x7D, 0xFC, 0x1F, 0xA5, 0xE5, 0x07,
       0x70, 0x5A, 0xF6, 0xD7, 0xC4, 0x1F, 0x1A, 0xE4,
       0x2D, 0xA6, 0xFD, 0xD1, 0x29, 0x7D, 0x60, 0x0D
    };
    const unsigned char emptyHash[] =
    {
        0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14,
        0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
        0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C,
        0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
    };
    unsigned char check[sizeof(testResult) + 1];
    size_t checkSz = -1;
    EVP_PKEY* key = NULL;

    XMEMSET(out, 0, sizeof(out));
    ExpectNotNull(bio = BIO_new(BIO_f_md()));
    ExpectNotNull(mem = BIO_new(BIO_s_mem()));

    ExpectIntEQ(BIO_get_md_ctx(bio, &ctx), 1);
    ExpectIntEQ(EVP_DigestInit(ctx, EVP_sha256()), 1);

    /* should not be able to write/read yet since just digest wrapper and no
     * data is passing through the bio */
    ExpectIntEQ(BIO_write(bio, msg, 0), 0);
    ExpectIntEQ(BIO_pending(bio), 0);
    ExpectIntEQ(BIO_read(bio, out, sizeof(out)), 0);
    ExpectIntEQ(BIO_gets(bio, out, 3), 0);
    ExpectIntEQ(BIO_gets(bio, out, sizeof(out)), 32);
    ExpectIntEQ(XMEMCMP(emptyHash, out, 32), 0);
    BIO_reset(bio);

    /* append BIO mem to bio in order to read/write */
    ExpectNotNull(bio = BIO_push(bio, mem));

    XMEMSET(out, 0, sizeof(out));
    ExpectIntEQ(BIO_write(mem, msg, sizeof(msg)), 16);
    ExpectIntEQ(BIO_pending(bio), 16);

    /* this just reads the message and does not hash it (gets calls final) */
    ExpectIntEQ(BIO_read(bio, out, sizeof(out)), 16);
    ExpectIntEQ(XMEMCMP(out, msg, sizeof(msg)), 0);

    /* create a message digest using BIO */
    XMEMSET(out, 0, sizeof(out));
    ExpectIntEQ(BIO_write(bio, msg, sizeof(msg)), 16);
    ExpectIntEQ(BIO_pending(mem), 16);
    ExpectIntEQ(BIO_pending(bio), 16);
    ExpectIntEQ(BIO_gets(bio, out, sizeof(out)), 32);
    ExpectIntEQ(XMEMCMP(expectedHash, out, 32), 0);
    BIO_free(bio);
    bio = NULL;
    BIO_free(mem);
    mem = NULL;

    /* test with HMAC */
    XMEMSET(out, 0, sizeof(out));
    ExpectNotNull(bio = BIO_new(BIO_f_md()));
    ExpectNotNull(mem = BIO_new(BIO_s_mem()));
    BIO_get_md_ctx(bio, &ctx);
    ExpectNotNull(key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, testKey,
        (int)sizeof(testKey)));
    EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, key);
    ExpectNotNull(bio = BIO_push(bio, mem));
    BIO_write(bio, testData, (int)strlen(testData));
    ExpectIntEQ(EVP_DigestSignFinal(ctx, NULL, &checkSz), 1);
    ExpectIntEQ(EVP_DigestSignFinal(ctx, check, &checkSz), 1);

    ExpectIntEQ(XMEMCMP(check, testResult, sizeof(testResult)), 0);

    EVP_PKEY_free(key);
    BIO_free(bio);
    BIO_free(mem);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BIO_up_ref(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
    BIO* bio = NULL;

    ExpectNotNull(bio = BIO_new(BIO_f_md()));
    ExpectIntEQ(BIO_up_ref(NULL), 0);
    ExpectIntEQ(BIO_up_ref(bio), 1);
    BIO_free(bio);
    ExpectIntEQ(BIO_up_ref(bio), 1);
    BIO_free(bio);
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_BIO_reset(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
    BIO* bio = NULL;
    byte buf[16];

    ExpectNotNull(bio = BIO_new_mem_buf("secure your data",
        (word32)XSTRLEN("secure your data")));
    ExpectIntEQ(BIO_read(bio, buf, 6), 6);
    ExpectIntEQ(XMEMCMP(buf, "secure", 6), 0);
    XMEMSET(buf, 0, 16);
    ExpectIntEQ(BIO_read(bio, buf, 16), 10);
    ExpectIntEQ(XMEMCMP(buf, " your data", 10), 0);
    /* You cannot write to MEM BIO with read-only mode. */
    ExpectIntEQ(BIO_write(bio, "WriteToReadonly", 15), 0);
    ExpectIntEQ(BIO_read(bio, buf, 16), -1);
    XMEMSET(buf, 0, 16);
    ExpectIntEQ(BIO_reset(bio), 1);
    ExpectIntEQ(BIO_read(bio, buf, 16), 16);
    ExpectIntEQ(XMEMCMP(buf, "secure your data", 16), 0);
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}
#endif /* !NO_BIO */

#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)

/* test that the callback arg is correct */
static int certCbArg = 0;

static int certCb(WOLFSSL* ssl, void* arg)
{
    if (ssl == NULL || arg != &certCbArg)
        return 0;
    if (wolfSSL_is_server(ssl)) {
        if (wolfSSL_use_certificate_file(ssl, svrCertFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
            return 0;
        if (wolfSSL_use_PrivateKey_file(ssl, svrKeyFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
            return 0;
    }
    else {
        if (wolfSSL_use_certificate_file(ssl, cliCertFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
            return 0;
        if (wolfSSL_use_PrivateKey_file(ssl, cliKeyFile,
                WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
            return 0;
    }
    return 1;
}

static int certSetupCb(WOLFSSL_CTX* ctx)
{
    SSL_CTX_set_cert_cb(ctx, certCb, &certCbArg);
    return TEST_SUCCESS;
}

/**
 * This is only done because test_wolfSSL_client_server_nofail_memio has no way
 * to stop certificate and key loading
 */
static int certClearCb(WOLFSSL* ssl)
{
    /* Clear the loaded certs to force the callbacks to set them up */
    SSL_certs_clear(ssl);
    return TEST_SUCCESS;
}

#endif

static int test_wolfSSL_cert_cb(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    test_ssl_cbf func_cb_client;
    test_ssl_cbf func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

    func_cb_client.ctx_ready = certSetupCb;
    func_cb_client.ssl_ready = certClearCb;
    func_cb_server.ctx_ready = certSetupCb;
    func_cb_server.ssl_ready = certClearCb;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
        &func_cb_server, NULL), TEST_SUCCESS);
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)

static const char* test_wolfSSL_cert_cb_dyn_ciphers_client_cipher = NULL;
static const char* test_wolfSSL_cert_cb_dyn_ciphers_client_sigalgs = NULL;
static int test_wolfSSL_cert_cb_dyn_ciphers_client_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx,
        test_wolfSSL_cert_cb_dyn_ciphers_client_cipher), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
        test_wolfSSL_cert_cb_dyn_ciphers_client_sigalgs), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

static int test_wolfSSL_cert_cb_dyn_ciphers_certCB(WOLFSSL* ssl, void* arg)
{
    const byte* suites = NULL;
    word16 suiteSz = 0;
    const byte* hashSigAlgo = NULL;
    word16 hashSigAlgoSz = 0;
    word16 idx = 0;
    int haveRSA = 0;
    int haveECC = 0;

    (void)arg;

    if (wolfSSL_get_client_suites_sigalgs(ssl, &suites, &suiteSz, &hashSigAlgo,
            &hashSigAlgoSz) != WOLFSSL_SUCCESS)
        return 0;
    if (suites == NULL || suiteSz == 0 || hashSigAlgo == NULL ||
            hashSigAlgoSz == 0)
        return 0;

    for (idx = 0; idx < suiteSz; idx += 2) {
        WOLFSSL_CIPHERSUITE_INFO info =
                wolfSSL_get_ciphersuite_info(suites[idx], suites[idx+1]);

        if (info.rsaAuth)
            haveRSA = 1;
        else if (info.eccAuth)
            haveECC = 1;
    }

    if (hashSigAlgoSz > 0) {
        /* sigalgs extension takes precedence over ciphersuites */
        haveRSA = 0;
        haveECC = 0;
    }
    for (idx = 0; idx < hashSigAlgoSz; idx += 2) {
        int hashAlgo = 0;
        int sigAlgo = 0;

        if (wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1],
                &hashAlgo, &sigAlgo) != 0)
            return 0;

        if (sigAlgo == RSAk || sigAlgo == RSAPSSk)
            haveRSA = 1;
        else if (sigAlgo == ECDSAk)
            haveECC = 1;
    }

    if (haveRSA) {
        if (wolfSSL_use_certificate_file(ssl, svrCertFile, WOLFSSL_FILETYPE_PEM)
                != WOLFSSL_SUCCESS)
            return 0;
        if (wolfSSL_use_PrivateKey_file(ssl, svrKeyFile, WOLFSSL_FILETYPE_PEM)
                != WOLFSSL_SUCCESS)
            return 0;
    }
    else if (haveECC) {
        if (wolfSSL_use_certificate_file(ssl, eccCertFile, WOLFSSL_FILETYPE_PEM)
                != WOLFSSL_SUCCESS)
            return 0;
        if (wolfSSL_use_PrivateKey_file(ssl, eccKeyFile, WOLFSSL_FILETYPE_PEM)
                != WOLFSSL_SUCCESS)
            return 0;
    }

    return 1;
}

static int test_wolfSSL_cert_cb_dyn_ciphers_server_ctx_ready(WOLFSSL_CTX* ctx)
{
    SSL_CTX_set_cert_cb(ctx, test_wolfSSL_cert_cb_dyn_ciphers_certCB, NULL);
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
    return TEST_SUCCESS;
}

#endif

/* Testing dynamic ciphers offered by client */
static int test_wolfSSL_cert_cb_dyn_ciphers(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    test_ssl_cbf func_cb_client;
    test_ssl_cbf func_cb_server;
    struct {
        method_provider client_meth;
        const char* client_ciphers;
        const char* client_sigalgs;
        const char* client_ca;
        method_provider server_meth;
    } test_params[] = {
#if !defined(NO_SHA256) && defined(HAVE_AESGCM)
#ifdef WOLFSSL_TLS13
#if !defined(NO_RSA) && defined(WC_RSA_PSS)
        {wolfTLSv1_3_client_method,
                "TLS13-AES256-GCM-SHA384:TLS13-AES128-GCM-SHA256",
                "RSA-PSS+SHA256", caCertFile, wolfTLSv1_3_server_method},
#endif
#ifdef HAVE_ECC
        {wolfTLSv1_3_client_method,
                "TLS13-AES256-GCM-SHA384:TLS13-AES128-GCM-SHA256",
                "ECDSA+SHA256", caEccCertFile, wolfTLSv1_3_server_method},
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
#if !defined(NO_RSA) && defined(WC_RSA_PSS) && !defined(NO_DH)
        {wolfTLSv1_2_client_method,
                "DHE-RSA-AES128-GCM-SHA256",
                "RSA-PSS+SHA256", caCertFile, wolfTLSv1_2_server_method},
#endif
#ifdef HAVE_ECC
        {wolfTLSv1_2_client_method,
                "ECDHE-ECDSA-AES128-GCM-SHA256",
                "ECDSA+SHA256", caEccCertFile, wolfTLSv1_2_server_method},
#endif
#endif
#endif
    };
    size_t i;
    size_t testCount = sizeof(test_params)/sizeof(*test_params);

    if (testCount > 0) {
        for (i = 0; i < testCount; i++) {
            printf("\tTesting %s ciphers with %s sigalgs\n",
                    test_params[i].client_ciphers,
                    test_params[i].client_sigalgs);

            XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
            XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

            test_wolfSSL_cert_cb_dyn_ciphers_client_cipher =
                    test_params[i].client_ciphers;
            test_wolfSSL_cert_cb_dyn_ciphers_client_sigalgs =
                    test_params[i].client_sigalgs;
            func_cb_client.method = test_params[i].client_meth;
            func_cb_client.caPemFile = test_params[i].client_ca;
            func_cb_client.ctx_ready =
                    test_wolfSSL_cert_cb_dyn_ciphers_client_ctx_ready;

            func_cb_server.ctx_ready =
                    test_wolfSSL_cert_cb_dyn_ciphers_server_ctx_ready;
            func_cb_server.ssl_ready = certClearCb; /* Reuse from prev test */
            func_cb_server.method = test_params[i].server_meth;

            ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
                &func_cb_server, NULL), TEST_SUCCESS);
        }
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ciphersuite_auth(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
    WOLFSSL_CIPHERSUITE_INFO info;

    (void)info;

#ifndef WOLFSSL_NO_TLS12
#ifdef HAVE_CHACHA
    info = wolfSSL_get_ciphersuite_info(CHACHA_BYTE,
            TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256);
    ExpectIntEQ(info.rsaAuth, 1);
    ExpectIntEQ(info.eccAuth, 0);
    ExpectIntEQ(info.eccStatic, 0);
    ExpectIntEQ(info.psk, 0);

    info = wolfSSL_get_ciphersuite_info(CHACHA_BYTE,
            TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256);
    ExpectIntEQ(info.rsaAuth, 0);
    ExpectIntEQ(info.eccAuth, 1);
    ExpectIntEQ(info.eccStatic, 0);
    ExpectIntEQ(info.psk, 0);

    info = wolfSSL_get_ciphersuite_info(CHACHA_BYTE,
            TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256);
    ExpectIntEQ(info.rsaAuth, 0);
    ExpectIntEQ(info.eccAuth, 0);
    ExpectIntEQ(info.eccStatic, 0);
    ExpectIntEQ(info.psk, 1);
#endif
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
#ifndef NO_RSA
    info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
            TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
    ExpectIntEQ(info.rsaAuth, 1);
    ExpectIntEQ(info.eccAuth, 0);
    ExpectIntEQ(info.eccStatic, 0);
    ExpectIntEQ(info.psk, 0);

    info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
            TLS_ECDH_RSA_WITH_AES_128_CBC_SHA);
    ExpectIntEQ(info.rsaAuth, 1);
    ExpectIntEQ(info.eccAuth, 0);
    ExpectIntEQ(info.eccStatic, 1);
    ExpectIntEQ(info.psk, 0);

    info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
            TLS_ECDH_RSA_WITH_AES_256_CBC_SHA);
    ExpectIntEQ(info.rsaAuth, 1);
    ExpectIntEQ(info.eccAuth, 0);
    ExpectIntEQ(info.eccStatic, 1);
    ExpectIntEQ(info.psk, 0);
#endif
    info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
            TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
    ExpectIntEQ(info.rsaAuth, 0);
    ExpectIntEQ(info.eccAuth, 1);
    ExpectIntEQ(info.eccStatic, 0);
    ExpectIntEQ(info.psk, 0);

    info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
            TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA);
    ExpectIntEQ(info.rsaAuth, 0);
    ExpectIntEQ(info.eccAuth, 1);
    ExpectIntEQ(info.eccStatic, 1);
    ExpectIntEQ(info.psk, 0);

    info = wolfSSL_get_ciphersuite_info(ECDHE_PSK_BYTE,
            TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256);
    ExpectIntEQ(info.rsaAuth, 0);
    ExpectIntEQ(info.eccAuth, 0);
    ExpectIntEQ(info.eccStatic, 0);
    ExpectIntEQ(info.psk, 1);
#endif
#endif

#ifdef WOLFSSL_TLS13
    info = wolfSSL_get_ciphersuite_info(TLS13_BYTE,
            TLS_AES_128_GCM_SHA256);
    ExpectIntEQ(info.rsaAuth, 0);
    ExpectIntEQ(info.eccAuth, 0);
    ExpectIntEQ(info.eccStatic, 0);
    ExpectIntEQ(info.psk, 0);
#endif

#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_sigalg_info(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
    byte hashSigAlgo[WOLFSSL_MAX_SIGALGO];
    word16 len = 0;
    word16 idx = 0;
    int allSigAlgs = SIG_ECDSA | SIG_RSA | SIG_SM2 | SIG_FALCON | SIG_DILITHIUM;

    InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs, 1, 0xFFFFFFFF, &len);
    for (idx = 0; idx < len; idx += 2) {
        int hashAlgo = 0;
        int sigAlgo = 0;

        ExpectIntEQ(wolfSSL_get_sigalg_info(hashSigAlgo[idx+0],
                hashSigAlgo[idx+1], &hashAlgo, &sigAlgo), 0);

        ExpectIntNE(hashAlgo, 0);
        ExpectIntNE(sigAlgo, 0);
    }

    InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs | SIG_ANON, 1,
            0xFFFFFFFF, &len);
    for (idx = 0; idx < len; idx += 2) {
        int hashAlgo = 0;
        int sigAlgo = 0;

        ExpectIntEQ(wolfSSL_get_sigalg_info(hashSigAlgo[idx+0],
                hashSigAlgo[idx+1], &hashAlgo, &sigAlgo), 0);

        ExpectIntNE(hashAlgo, 0);
    }

#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SESSION(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_RSA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
    !defined(NO_SESSION_CACHE)
    WOLFSSL*     ssl = NULL;
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL_SESSION* sess = NULL;
    WOLFSSL_SESSION* sess_copy = NULL;
#ifdef OPENSSL_EXTRA
#ifdef HAVE_EXT_CACHE
    unsigned char* sessDer = NULL;
    unsigned char* ptr     = NULL;
    int sz = 0;
#endif
    const unsigned char context[] = "user app context";
    unsigned int contextSz = (unsigned int)sizeof(context);
#endif
    int ret = 0, err = 0;
    SOCKET_T sockfd;
    tcp_ready ready;
    func_args server_args;
    THREAD_TYPE serverThread;
    char msg[80];
    const char* sendGET = "GET";

    /* TLS v1.3 requires session tickets */
    /* CHACHA and POLY1305 required for myTicketEncCb */
#if !defined(WOLFSSL_NO_TLS12) && (!defined(WOLFSSL_TLS13) || \
    !(defined(HAVE_SESSION_TICKET) && ((defined(HAVE_CHACHA) && \
            defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))))
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
#else
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif

    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, cliCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0),
        WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ENCRYPTED_KEYS
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
#ifdef HAVE_SESSION_TICKET
    /* Use session tickets, for ticket tests below */
    ExpectIntEQ(wolfSSL_CTX_UseSessionTicket(ctx), WOLFSSL_SUCCESS);
#endif

    XMEMSET(&server_args, 0, sizeof(func_args));
#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    StartTCP();
    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    server_args.signal = &ready;
    start_thread(test_server_nofail, &server_args, &serverThread);
    wait_tcp_ready(&server_args);

    /* client connection */
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    tcp_connect(&sockfd, wolfSSLIP, ready.port, 0, 0, ssl);
    ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);

    #ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
    #endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_connect(ssl);
        err = wolfSSL_get_error(ssl, 0);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);

    #ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
    #endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_write(ssl, sendGET, (int)XSTRLEN(sendGET));
        err = wolfSSL_get_error(ssl, 0);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    ExpectIntEQ(ret, (int)XSTRLEN(sendGET));

    #ifdef WOLFSSL_ASYNC_CRYPT
    err = 0; /* Reset error */
    #endif
    do {
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
            ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
            if (ret < 0) { break; } else if (ret == 0) { continue; }
        }
    #endif
        ret = wolfSSL_read(ssl, msg, sizeof(msg));
        err = wolfSSL_get_error(ssl, 0);
    } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
    ExpectIntEQ(ret, 23);

    ExpectPtrNE((sess = wolfSSL_get1_session(ssl)), NULL); /* ref count 1 */
    ExpectPtrNE((sess_copy = wolfSSL_get1_session(ssl)), NULL); /* ref count 2 */
    ExpectIntEQ(wolfSSL_SessionIsSetup(sess), 1);
#ifdef HAVE_EXT_CACHE
    ExpectPtrEq(sess, sess_copy); /* they should be the same pointer but without
                                   * HAVE_EXT_CACHE we get new objects each time */
#endif
    wolfSSL_SESSION_free(sess_copy); sess_copy = NULL;
    wolfSSL_SESSION_free(sess);      sess = NULL; /* free session ref */

    sess = wolfSSL_get_session(ssl);

#ifdef OPENSSL_EXTRA
    ExpectIntEQ(SSL_SESSION_is_resumable(NULL), 0);
    ExpectIntEQ(SSL_SESSION_is_resumable(sess), 1);

    ExpectIntEQ(wolfSSL_SESSION_has_ticket(NULL), 0);
    ExpectIntEQ(wolfSSL_SESSION_get_ticket_lifetime_hint(NULL), 0);
    #ifdef HAVE_SESSION_TICKET
    ExpectIntEQ(wolfSSL_SESSION_has_ticket(sess), 1);
    ExpectIntEQ(wolfSSL_SESSION_get_ticket_lifetime_hint(sess),
                SESSION_TICKET_HINT_DEFAULT);
    #else
    ExpectIntEQ(wolfSSL_SESSION_has_ticket(sess), 0);
    #endif
#else
    (void)sess;
#endif /* OPENSSL_EXTRA */

    /* Retain copy of the session for later testing */
    ExpectNotNull(sess = wolfSSL_get1_session(ssl));

    wolfSSL_shutdown(ssl);
    wolfSSL_free(ssl); ssl = NULL;

    CloseSocket(sockfd);

    join_thread(serverThread);

    FreeTcpReady(&ready);

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
    {
        X509 *x509 = NULL;
        char buf[30];
        int  bufSz = 0;

        ExpectNotNull(x509 = SSL_SESSION_get0_peer(sess));
        ExpectIntGT((bufSz = X509_NAME_get_text_by_NID(
            X509_get_subject_name(x509), NID_organizationalUnitName, buf,
            sizeof(buf))), 0);
        ExpectIntNE((bufSz == 7 || bufSz == 16), 0); /* should be one of these*/
        if (bufSz == 7) {
            ExpectIntEQ(XMEMCMP(buf, "Support", bufSz), 0);
        }
        if (bufSz == 16) {
            ExpectIntEQ(XMEMCMP(buf, "Programming-2048", bufSz), 0);
        }
    }
#endif

#ifdef HAVE_EXT_CACHE
    ExpectNotNull(sess_copy = wolfSSL_SESSION_dup(sess));
    wolfSSL_SESSION_free(sess_copy); sess_copy = NULL;
    sess_copy = NULL;
#endif

#if defined(OPENSSL_EXTRA) && defined(HAVE_EXT_CACHE)
    /* get session from DER and update the timeout */
    ExpectIntEQ(wolfSSL_i2d_SSL_SESSION(NULL, &sessDer), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntGT((sz = wolfSSL_i2d_SSL_SESSION(sess, &sessDer)), 0);
    wolfSSL_SESSION_free(sess); sess = NULL;
    sess = NULL;
    ptr = sessDer;
    ExpectNull(sess = wolfSSL_d2i_SSL_SESSION(NULL, NULL, sz));
    ExpectNotNull(sess = wolfSSL_d2i_SSL_SESSION(NULL,
                (const unsigned char**)&ptr, sz));
    XFREE(sessDer, NULL, DYNAMIC_TYPE_OPENSSL);
    sessDer = NULL;

    ExpectIntGT(wolfSSL_SESSION_get_time(sess), 0);
    ExpectIntEQ(wolfSSL_SSL_SESSION_set_timeout(sess, 500), SSL_SUCCESS);
#endif

    /* successful set session test */
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    ExpectIntEQ(wolfSSL_set_session(ssl, sess), WOLFSSL_SUCCESS);

#ifdef HAVE_SESSION_TICKET
    /* Test set/get session ticket */
    {
        const char* ticket = "This is a session ticket";
        char buf[64] = {0};
        word32 bufSz = (word32)sizeof(buf);

        ExpectIntEQ(SSL_SUCCESS,
            wolfSSL_set_SessionTicket(ssl, (byte *)ticket,
                (word32)XSTRLEN(ticket)));
        ExpectIntEQ(SSL_SUCCESS,
            wolfSSL_get_SessionTicket(ssl, (byte *)buf, &bufSz));
        ExpectStrEQ(ticket, buf);
    }
#endif

#ifdef OPENSSL_EXTRA
    /* session timeout case */
    /* make the session to be expired */
    ExpectIntEQ(SSL_SESSION_set_timeout(sess,1), SSL_SUCCESS);
    XSLEEP_MS(1200);

    /* SSL_set_session should reject specified session but return success
     * if WOLFSSL_ERROR_CODE_OPENSSL macro is defined for OpenSSL compatibility.
     */
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
    ExpectIntEQ(wolfSSL_set_session(ssl,sess), SSL_SUCCESS);
#else
    ExpectIntEQ(wolfSSL_set_session(ssl,sess), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
    ExpectIntEQ(wolfSSL_SSL_SESSION_set_timeout(sess, 500), SSL_SUCCESS);

#ifdef WOLFSSL_SESSION_ID_CTX
    /* fail case with miss match session context IDs (use compatibility API) */
    ExpectIntEQ(SSL_set_session_id_context(ssl, context, contextSz),
            SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_set_session(ssl, sess), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    wolfSSL_free(ssl); ssl = NULL;

    ExpectIntEQ(SSL_CTX_set_session_id_context(NULL, context, contextSz),
            WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CTX_set_session_id_context(ctx, context, contextSz),
            SSL_SUCCESS);
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    ExpectIntEQ(wolfSSL_set_session(ssl, sess), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#endif /* OPENSSL_EXTRA */

    wolfSSL_free(ssl);
    wolfSSL_SESSION_free(sess);
    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_RSA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
    !defined(NO_SESSION_CACHE) && defined(OPENSSL_EXTRA) && \
    !defined(WOLFSSL_NO_TLS12)
static WOLFSSL_SESSION* test_wolfSSL_SESSION_expire_sess = NULL;

static void test_wolfSSL_SESSION_expire_downgrade_ctx_ready(WOLFSSL_CTX* ctx)
{
    #ifdef WOLFSSL_ERROR_CODE_OPENSSL
    /* returns previous timeout value */
    AssertIntEQ(wolfSSL_CTX_set_timeout(ctx, 1), 500);
    #else
    AssertIntEQ(wolfSSL_CTX_set_timeout(ctx, 1), WOLFSSL_SUCCESS);
    #endif
}


/* set the session to timeout in a second */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_ready(WOLFSSL* ssl)
{
    AssertIntEQ(wolfSSL_set_timeout(ssl, 2), 1);
}


/* store the client side session from the first successful connection */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_result(WOLFSSL* ssl)
{
    AssertPtrNE((test_wolfSSL_SESSION_expire_sess = wolfSSL_get1_session(ssl)),
        NULL); /* ref count 1 */
}


/* wait till session is expired then set it in the WOLFSSL struct for use */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_ready_wait(WOLFSSL* ssl)
{
    AssertIntEQ(wolfSSL_set_timeout(ssl, 1), 1);
    AssertIntEQ(wolfSSL_set_session(ssl, test_wolfSSL_SESSION_expire_sess),
        WOLFSSL_SUCCESS);
    XSLEEP_MS(2000); /* wait 2 seconds for session to expire */
}


/* set expired session in the WOLFSSL struct for use */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_ready_set(WOLFSSL* ssl)
{
    XSLEEP_MS(1200); /* wait a second for session to expire */

    /* set the expired session, call to set session fails but continuing on
       after failure should be handled here */
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL)
    AssertIntEQ(wolfSSL_set_session(ssl, test_wolfSSL_SESSION_expire_sess),
        WOLFSSL_SUCCESS);
#else
    AssertIntNE(wolfSSL_set_session(ssl, test_wolfSSL_SESSION_expire_sess),
        WOLFSSL_SUCCESS);
#endif
}


/* check that the expired session was not reused */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_result_reuse(WOLFSSL* ssl)
{
    /* since the session has expired it should not have been reused */
    AssertIntEQ(wolfSSL_session_reused(ssl), 0);
}
#endif

static int test_wolfSSL_SESSION_expire_downgrade(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_RSA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
    !defined(NO_SESSION_CACHE) && defined(OPENSSL_EXTRA) && \
    !defined(WOLFSSL_NO_TLS12)

    WOLFSSL_CTX* ctx = NULL;
    callback_functions server_cbf, client_cbf;

    XMEMSET(&server_cbf, 0, sizeof(callback_functions));
    XMEMSET(&client_cbf, 0, sizeof(callback_functions));

    /* force server side to use TLS 1.2 */
    server_cbf.ctx = ctx;
    server_cbf.method = wolfTLSv1_2_server_method;

    client_cbf.method = wolfSSLv23_client_method;
    server_cbf.ctx_ready = test_wolfSSL_SESSION_expire_downgrade_ctx_ready;
    client_cbf.ssl_ready = test_wolfSSL_SESSION_expire_downgrade_ssl_ready;
    client_cbf.on_result = test_wolfSSL_SESSION_expire_downgrade_ssl_result;

    test_wolfSSL_client_server_nofail(&client_cbf, &server_cbf);
    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);

    /* set the previously created session and wait till expired */
    server_cbf.ctx = ctx;

    client_cbf.method = wolfSSLv23_client_method;
    server_cbf.ctx_ready = test_wolfSSL_SESSION_expire_downgrade_ctx_ready;
    client_cbf.ssl_ready = test_wolfSSL_SESSION_expire_downgrade_ssl_ready_wait;
    client_cbf.on_result =
        test_wolfSSL_SESSION_expire_downgrade_ssl_result_reuse;

    test_wolfSSL_client_server_nofail(&client_cbf, &server_cbf);
    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);

    /* set the previously created expired session */
    server_cbf.ctx = ctx;

    client_cbf.method = wolfSSLv23_client_method;
    server_cbf.ctx_ready = test_wolfSSL_SESSION_expire_downgrade_ctx_ready;
    client_cbf.ssl_ready = test_wolfSSL_SESSION_expire_downgrade_ssl_ready_set;
    client_cbf.on_result =
        test_wolfSSL_SESSION_expire_downgrade_ssl_result_reuse;

    test_wolfSSL_client_server_nofail(&client_cbf, &server_cbf);
    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);

    wolfSSL_SESSION_free(test_wolfSSL_SESSION_expire_sess);
    wolfSSL_CTX_free(ctx);

#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(HAVE_EX_DATA) && !defined(NO_SESSION_CACHE)
#ifdef WOLFSSL_ATOMIC_OPS
    typedef wolfSSL_Atomic_Int SessRemCounter_t;
#else
    typedef int SessRemCounter_t;
#endif
static SessRemCounter_t clientSessRemCountMalloc;
static SessRemCounter_t serverSessRemCountMalloc;
static SessRemCounter_t clientSessRemCountFree;
static SessRemCounter_t serverSessRemCountFree;

static WOLFSSL_CTX* serverSessCtx = NULL;
static WOLFSSL_SESSION* serverSess = NULL;
#if (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) || \
        !defined(NO_SESSION_CACHE_REF)
static WOLFSSL_CTX* clientSessCtx = NULL;
static WOLFSSL_SESSION* clientSess = NULL;
#endif
static int serverSessRemIdx = 3;
static int sessRemCtx_Server = WOLFSSL_SERVER_END;
static int sessRemCtx_Client = WOLFSSL_CLIENT_END;

static void SessRemCtxCb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
{
    int* side;

    (void)ctx;

    side = (int*)SSL_SESSION_get_ex_data(sess, serverSessRemIdx);
    if (side != NULL) {
        if (*side == WOLFSSL_CLIENT_END)
            (void)wolfSSL_Atomic_Int_FetchAdd(&clientSessRemCountFree, 1);
        else
            (void)wolfSSL_Atomic_Int_FetchAdd(&serverSessRemCountFree, 1);

        SSL_SESSION_set_ex_data(sess, serverSessRemIdx, NULL);
    }
}

static int SessRemCtxSetupCb(WOLFSSL_CTX* ctx)
{
    SSL_CTX_sess_set_remove_cb(ctx, SessRemCtxCb);
#if defined(WOLFSSL_TLS13) && !defined(HAVE_SESSION_TICKET) && \
        !defined(NO_SESSION_CACHE_REF)
    {
        EXPECT_DECLS;
        /* Allow downgrade, set min version, and disable TLS 1.3.
         * Do this because without NO_SESSION_CACHE_REF we will want to return a
         * reference to the session cache. But with WOLFSSL_TLS13 and without
         * HAVE_SESSION_TICKET we won't have a session ID to be able to place
         * the session in the cache. In this case we need to downgrade to
         * previous versions to just use the legacy session ID field. */
        ExpectIntEQ(SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION),
            SSL_SUCCESS);
        ExpectIntEQ(SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION),
            SSL_SUCCESS);
        return EXPECT_RESULT();
    }
#else
    return TEST_SUCCESS;
#endif
}

static int SessRemSslSetupCb(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    int* side;

    if (SSL_is_server(ssl)) {
        side = &sessRemCtx_Server;
        (void)wolfSSL_Atomic_Int_FetchAdd(&serverSessRemCountMalloc, 1);
        ExpectNotNull(serverSess = SSL_get1_session(ssl));
        ExpectIntEQ(SSL_CTX_up_ref(serverSessCtx = SSL_get_SSL_CTX(ssl)),
                SSL_SUCCESS);
    }
    else {
        side = &sessRemCtx_Client;
        (void)wolfSSL_Atomic_Int_FetchAdd(&clientSessRemCountMalloc, 1);
    #if (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) || \
        !defined(NO_SESSION_CACHE_REF)
        ExpectNotNull(clientSess = SSL_get1_session(ssl));
        ExpectIntEQ(SSL_CTX_up_ref(clientSessCtx = SSL_get_SSL_CTX(ssl)),
                SSL_SUCCESS);
#endif
    }
    ExpectIntEQ(SSL_SESSION_set_ex_data(SSL_get_session(ssl),
        serverSessRemIdx, side), SSL_SUCCESS);

    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_CTX_sess_set_remove_cb(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(HAVE_EX_DATA) && !defined(NO_SESSION_CACHE)
    /* Check that the remove callback gets called for external data in a
     * session object */
    test_ssl_cbf func_cb;

    wolfSSL_Atomic_Int_Init(&clientSessRemCountMalloc, 0);
    wolfSSL_Atomic_Int_Init(&serverSessRemCountMalloc, 0);
    wolfSSL_Atomic_Int_Init(&clientSessRemCountFree, 0);
    wolfSSL_Atomic_Int_Init(&serverSessRemCountFree, 0);

    XMEMSET(&func_cb, 0, sizeof(func_cb));
    func_cb.ctx_ready = SessRemCtxSetupCb;
    func_cb.on_result = SessRemSslSetupCb;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb, &func_cb,
        NULL), TEST_SUCCESS);

    /* Both should have been allocated */
    ExpectIntEQ(clientSessRemCountMalloc, 1);
    ExpectIntEQ(serverSessRemCountMalloc, 1);

    /* This should not be called yet. Session wasn't evicted from cache yet. */
    ExpectIntEQ(clientSessRemCountFree, 0);
#if (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) || \
        !defined(NO_SESSION_CACHE_REF)
    /* Force a cache lookup */
    ExpectNotNull(SSL_SESSION_get_ex_data(clientSess, serverSessRemIdx));
    /* Force a cache update */
    ExpectNotNull(SSL_SESSION_set_ex_data(clientSess, serverSessRemIdx - 1, 0));
    /* This should set the timeout to 0 and call the remove callback from within
     * the session cache. */
    ExpectIntEQ(SSL_CTX_remove_session(clientSessCtx, clientSess), 0);
    ExpectNull(SSL_SESSION_get_ex_data(clientSess, serverSessRemIdx));
    ExpectIntEQ(clientSessRemCountFree, 1);
#endif
    /* Server session is in the cache so ex_data isn't free'd with the SSL
     * object */
    ExpectIntEQ(serverSessRemCountFree, 0);
    /* Force a cache lookup */
    ExpectNotNull(SSL_SESSION_get_ex_data(serverSess, serverSessRemIdx));
    /* Force a cache update */
    ExpectNotNull(SSL_SESSION_set_ex_data(serverSess, serverSessRemIdx - 1, 0));
    /* This should set the timeout to 0 and call the remove callback from within
     * the session cache. */
    ExpectIntEQ(SSL_CTX_remove_session(serverSessCtx, serverSess), 0);
    ExpectNull(SSL_SESSION_get_ex_data(serverSess, serverSessRemIdx));
    ExpectIntEQ(serverSessRemCountFree, 1);
    /* Need to free the references that we kept */
    SSL_CTX_free(serverSessCtx);
    SSL_SESSION_free(serverSess);
#if (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) || \
        !defined(NO_SESSION_CACHE_REF)
    SSL_CTX_free(clientSessCtx);
    SSL_SESSION_free(clientSess);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_ticket_keys(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
    !defined(NO_WOLFSSL_SERVER)
    WOLFSSL_CTX* ctx = NULL;
    byte keys[WOLFSSL_TICKET_KEYS_SZ];

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

    ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, NULL, 0),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, NULL, 0),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, keys, 0),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, keys, 0),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, NULL, sizeof(keys)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, NULL, sizeof(keys)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, keys, sizeof(keys)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, NULL, 0),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, NULL, 0),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, keys, 0),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, keys, 0),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, NULL, sizeof(keys)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, NULL, sizeof(keys)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, keys, sizeof(keys)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, keys, sizeof(keys)),
                WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, keys, sizeof(keys)),
                WOLFSSL_SUCCESS);

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

#ifndef NO_BIO

static int test_wolfSSL_d2i_PUBKEY(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    BIO* bio = NULL;
    EVP_PKEY* pkey = NULL;

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectNull(d2i_PUBKEY_bio(NULL, NULL));

#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA)
    /* RSA PUBKEY test */
    ExpectIntGT(BIO_write(bio, client_keypub_der_2048,
        sizeof_client_keypub_der_2048), 0);
    ExpectNotNull(pkey = d2i_PUBKEY_bio(bio, NULL));
    EVP_PKEY_free(pkey);
    pkey = NULL;
#endif

#if defined(USE_CERT_BUFFERS_256) && defined(HAVE_ECC)
    /* ECC PUBKEY test */
    ExpectIntGT(BIO_write(bio, ecc_clikeypub_der_256,
        sizeof_ecc_clikeypub_der_256), 0);
    ExpectNotNull(pkey = d2i_PUBKEY_bio(bio, NULL));
    EVP_PKEY_free(pkey);
    pkey = NULL;
#endif

#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_DSA)
    /* DSA PUBKEY test */
    ExpectIntGT(BIO_write(bio, dsa_pub_key_der_2048,
        sizeof_dsa_pub_key_der_2048), 0);
    ExpectNotNull(pkey = d2i_PUBKEY_bio(bio, NULL));
    EVP_PKEY_free(pkey);
    pkey = NULL;
#endif

#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_DH) && \
defined(OPENSSL_EXTRA) && defined(WOLFSSL_DH_EXTRA)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
            (HAVE_FIPS_VERSION > 2))
    /* DH PUBKEY test */
    ExpectIntGT(BIO_write(bio, dh_pub_key_der_2048,
        sizeof_dh_pub_key_der_2048), 0);
    ExpectNotNull(pkey = d2i_PUBKEY_bio(bio, NULL));
    EVP_PKEY_free(pkey);
    pkey = NULL;
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /*  USE_CERT_BUFFERS_2048 && !NO_DH &&  && OPENSSL_EXTRA */

    BIO_free(bio);

    (void)pkey;
#endif

    return EXPECT_RESULT();
}

#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA)
static int test_wolfSSL_d2i_PrivateKeys_bio(void)
{
    EXPECT_DECLS;
    BIO*      bio = NULL;
    EVP_PKEY* pkey  = NULL;
    WOLFSSL_CTX* ctx = NULL;

#if defined(WOLFSSL_KEY_GEN)
    unsigned char buff[4096];
    unsigned char* bufPtr = buff;
#endif

    /* test creating new EVP_PKEY with bad arg */
    ExpectNull((pkey = d2i_PrivateKey_bio(NULL, NULL)));

    /* test loading RSA key using BIO */
#if !defined(NO_RSA) && !defined(NO_FILESYSTEM)
    {
        XFILE file = XBADFILE;
        const char* fname = "./certs/server-key.der";
        size_t sz = 0;
        byte* buf = NULL;

        ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
        ExpectTrue(XFSEEK(file, 0, XSEEK_END) == 0);
        ExpectTrue((sz = XFTELL(file)) != 0);
        ExpectTrue(XFSEEK(file, 0, XSEEK_SET) == 0);
        ExpectNotNull(buf = (byte*)XMALLOC(sz, HEAP_HINT, DYNAMIC_TYPE_FILE));
        ExpectIntEQ(XFREAD(buf, 1, sz, file), sz);
        if (file != XBADFILE) {
            XFCLOSE(file);
        }

        /* Test using BIO new mem and loading DER private key */
        ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
        ExpectNotNull((pkey = d2i_PrivateKey_bio(bio, NULL)));
        XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_FILE);
        BIO_free(bio);
        bio = NULL;
        EVP_PKEY_free(pkey);
        pkey  = NULL;
    }
#endif

    /* test loading ECC key using BIO */
#if defined(HAVE_ECC) && !defined(NO_FILESYSTEM)
    {
        XFILE file = XBADFILE;
        const char* fname = "./certs/ecc-key.der";
        size_t sz = 0;
        byte* buf = NULL;

        ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
        ExpectTrue(XFSEEK(file, 0, XSEEK_END) == 0);
        ExpectTrue((sz = XFTELL(file)) != 0);
        ExpectTrue(XFSEEK(file, 0, XSEEK_SET) == 0);
        ExpectNotNull(buf = (byte*)XMALLOC(sz, HEAP_HINT, DYNAMIC_TYPE_FILE));
        ExpectIntEQ(XFREAD(buf, 1, sz, file), sz);
        if (file != XBADFILE)
            XFCLOSE(file);

        /* Test using BIO new mem and loading DER private key */
        ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
        ExpectNotNull((pkey = d2i_PrivateKey_bio(bio, NULL)));
        XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_FILE);
        BIO_free(bio);
        bio = NULL;
        EVP_PKEY_free(pkey);
        pkey = NULL;
    }
#endif

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
#ifndef NO_WOLFSSL_SERVER
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif

#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
    {
        RSA* rsa = NULL;
        /* Tests bad parameters */
        ExpectNull(d2i_RSAPrivateKey_bio(NULL, NULL));

        /* RSA not set yet, expecting to fail*/
        rsa = wolfSSL_RSA_new();
        ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, rsa), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
        wolfSSL_RSA_free(rsa);
        rsa = NULL;

#if defined(USE_CERT_BUFFERS_2048) && defined(WOLFSSL_KEY_GEN)
        /* set RSA using bio*/
        ExpectIntGT(BIO_write(bio, client_key_der_2048,
                    sizeof_client_key_der_2048), 0);
        ExpectNotNull(d2i_RSAPrivateKey_bio(bio, &rsa));
        ExpectNotNull(rsa);

        /* Tests bad parameters */
        ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(NULL, rsa), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

        ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, rsa), WOLFSSL_SUCCESS);

        /* i2d RSAprivate key tests */
        ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
        ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, NULL), 1192);
        ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, &bufPtr),
                                               sizeof_client_key_der_2048);
        bufPtr -= sizeof_client_key_der_2048;
        ExpectIntEQ(XMEMCMP(bufPtr, client_key_der_2048,
                            sizeof_client_key_der_2048), 0);
        bufPtr = NULL;
        ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, &bufPtr),
                                               sizeof_client_key_der_2048);
        ExpectNotNull(bufPtr);
        ExpectIntEQ(XMEMCMP(bufPtr, client_key_der_2048,
                            sizeof_client_key_der_2048), 0);
        XFREE(bufPtr, NULL, DYNAMIC_TYPE_OPENSSL);

        RSA_free(rsa);
        rsa = NULL;
        ExpectIntGT(BIO_write(bio, client_key_der_2048,
                    sizeof_client_key_der_2048), 0);
        ExpectNotNull(d2i_RSA_PUBKEY_bio(bio, &rsa));
        (void)BIO_reset(bio);

        RSA_free(rsa);
        rsa = RSA_new();
        ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, NULL), 0);
#endif /* USE_CERT_BUFFERS_2048 WOLFSSL_KEY_GEN */
        RSA_free(rsa);
    }
#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
    SSL_CTX_free(ctx);
    ctx = NULL;
    BIO_free(bio);
    bio = NULL;

    return EXPECT_RESULT();
}
#endif /* OPENSSL_ALL || (WOLFSSL_ASIO && !NO_RSA) */

#endif /* !NO_BIO */


static int test_wolfSSL_sk_GENERAL_NAME(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_RSA)
    X509* x509 = NULL;
    GENERAL_NAME* gn = NULL;
    unsigned char buf[4096];
    const unsigned char* bufPt = NULL;
    int bytes = 0;
    int i;
    int j;
    XFILE f = XBADFILE;
    STACK_OF(GENERAL_NAME)* sk = NULL;

    ExpectTrue((f = XFOPEN(cliCertDerFileExt, "rb")) != XBADFILE);
    ExpectIntGT((bytes = (int)XFREAD(buf, 1, sizeof(buf), f)), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    for (j = 0; j < 2; ++j) {
        bufPt = buf;
        ExpectNotNull(x509 = d2i_X509(NULL, &bufPt, bytes));

        ExpectNotNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509,
                    NID_subject_alt_name, NULL, NULL));

        ExpectIntEQ(sk_GENERAL_NAME_num(sk), 1);
        for (i = 0; i < sk_GENERAL_NAME_num(sk); i++) {
            ExpectNotNull(gn = sk_GENERAL_NAME_value(sk, i));

            if (gn != NULL) {
                switch (gn->type) {
                case GEN_DNS:
                    fprintf(stderr, "found type GEN_DNS\n");
                    break;
                case GEN_EMAIL:
                    fprintf(stderr, "found type GEN_EMAIL\n");
                    break;
                case GEN_URI:
                    fprintf(stderr, "found type GEN_URI\n");
                    break;
                }
            }
        }
        X509_free(x509);
        x509 = NULL;
        if (j == 0) {
            sk_GENERAL_NAME_pop_free(sk, GENERAL_NAME_free);
        }
        else {
            /*
             * We had a bug where GENERAL_NAMES_free didn't free all the memory
             * it was supposed to. This is a regression test for that bug.
             */
            GENERAL_NAMES_free(sk);
        }
        sk = NULL;
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_GENERAL_NAME_print(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_BIO) && !defined(NO_RSA)
    X509* x509 = NULL;
    GENERAL_NAME* gn = NULL;
    unsigned char buf[4096];
    const unsigned char* bufPt = NULL;
    int bytes = 0;
    XFILE f = XBADFILE;
    STACK_OF(GENERAL_NAME)* sk = NULL;
    BIO* out = NULL;
    unsigned char outbuf[128];

    X509_EXTENSION* ext = NULL;
    AUTHORITY_INFO_ACCESS* aia = NULL;
    ACCESS_DESCRIPTION* ad = NULL;
    ASN1_IA5STRING *dnsname = NULL;

    const unsigned char v4Addr[] = {192,168,53,1};
    const unsigned char v6Addr[] =
                            {0x20, 0x21, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x77, 0x77};
    const unsigned char email[]  =
                             {'i', 'n', 'f', 'o', '@', 'w', 'o', 'l',
                              'f', 's', 's', 'l', '.', 'c', 'o', 'm'};

    const char* dnsStr   = "DNS:example.com";
    const char* uriStr   = "URI:http://127.0.0.1:22220";
    const char* v4addStr = "IP Address:192.168.53.1";
    const char* v6addStr = "IP Address:2021:DB8:0:0:0:FF00:42:7777";
    const char* emailStr = "email:info@wolfssl.com";
    const char* othrStr  = "othername:<unsupported>";
    const char* x400Str  = "X400Name:<unsupported>";
    const char* ediStr   = "EdiPartyName:<unsupported>";

    /* BIO to output */
    ExpectNotNull(out = BIO_new(BIO_s_mem()));

    /* test for NULL param */
    gn = NULL;

    ExpectIntEQ(GENERAL_NAME_print(NULL, NULL), 0);
    ExpectIntEQ(GENERAL_NAME_print(NULL, gn), 0);
    ExpectIntEQ(GENERAL_NAME_print(out, NULL), 0);


    /* test for GEN_DNS */
    ExpectTrue((f = XFOPEN(cliCertDerFileExt, "rb")) != XBADFILE);
    ExpectIntGT((bytes = (int)XFREAD(buf, 1, sizeof(buf), f)), 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    bufPt = buf;
    ExpectNotNull(x509 = d2i_X509(NULL, &bufPt, bytes));
    ExpectNotNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509,
                NID_subject_alt_name, NULL, NULL));

    ExpectNotNull(gn = sk_GENERAL_NAME_value(sk, 0));
    ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);

    XMEMSET(outbuf, 0, sizeof(outbuf));
    ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
    ExpectIntEQ(XSTRNCMP((const char*)outbuf, dnsStr, XSTRLEN(dnsStr)), 0);

    sk_GENERAL_NAME_pop_free(sk, GENERAL_NAME_free);
    gn = NULL;
    sk = NULL;
    X509_free(x509);
    x509 = NULL;

    /* Lets test for setting as well. */
    ExpectNotNull(gn = GENERAL_NAME_new());
    ExpectNotNull(dnsname = ASN1_IA5STRING_new());
    ExpectIntEQ(ASN1_STRING_set(dnsname, "example.com", -1), 1);
    GENERAL_NAME_set0_value(gn, GEN_DNS, dnsname);
    dnsname = NULL;
    ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
    XMEMSET(outbuf, 0, sizeof(outbuf));
    ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
    ExpectIntEQ(XSTRNCMP((const char*)outbuf, dnsStr, XSTRLEN(dnsStr)), 0);
    GENERAL_NAME_free(gn);

    /* test for GEN_URI */

    ExpectTrue((f = XFOPEN("./certs/ocsp/root-ca-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL));
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, 4));
    ExpectNotNull(aia = (WOLFSSL_AUTHORITY_INFO_ACCESS*)wolfSSL_X509V3_EXT_d2i(
        ext));
    ExpectNotNull(ad = (WOLFSSL_ACCESS_DESCRIPTION *)wolfSSL_sk_value(aia, 0));

    if (ad != NULL) {
        gn = ad->location;
    }
    ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
    gn = NULL;

    XMEMSET(outbuf,0,sizeof(outbuf));
    ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
    ExpectIntEQ(XSTRNCMP((const char*)outbuf, uriStr, XSTRLEN(uriStr)), 0);

    wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
    aia = NULL;
    aia = (AUTHORITY_INFO_ACCESS*)wolfSSL_X509V3_EXT_d2i(ext);
    ExpectNotNull(aia);
    AUTHORITY_INFO_ACCESS_pop_free(aia, NULL);
    aia = NULL;
    X509_free(x509);
    x509 = NULL;

    /* test for GEN_IPADD */

    /* ip v4 address */
    ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
    if (gn != NULL) {
        gn->type = GEN_IPADD;
        if (gn->d.iPAddress != NULL) {
            gn->d.iPAddress->length = sizeof(v4Addr);
        }
    }
    ExpectIntEQ(wolfSSL_ASN1_STRING_set(gn->d.iPAddress, v4Addr,
        sizeof(v4Addr)), 1);

    ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
    XMEMSET(outbuf,0,sizeof(outbuf));
    ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
    ExpectIntEQ(XSTRNCMP((const char*)outbuf, v4addStr, XSTRLEN(v4addStr)), 0);

    GENERAL_NAME_free(gn);
    gn = NULL;

    /* ip v6 address */

    ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
    if (gn != NULL) {
        gn->type = GEN_IPADD;
        if (gn->d.iPAddress != NULL) {
            gn->d.iPAddress->length = sizeof(v6Addr);
        }
    }
    ExpectIntEQ(wolfSSL_ASN1_STRING_set(gn->d.iPAddress, v6Addr,
        sizeof(v6Addr)), 1);

    ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
    XMEMSET(outbuf,0,sizeof(outbuf));
    ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
    ExpectIntEQ(XSTRNCMP((const char*)outbuf, v6addStr, XSTRLEN(v6addStr)), 0);

    GENERAL_NAME_free(gn);
    gn = NULL;

    /* test for GEN_EMAIL */

    ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
    if (gn != NULL) {
        gn->type = GEN_EMAIL;
        if (gn->d.rfc822Name != NULL) {
            gn->d.rfc822Name->length = sizeof(email);
        }
    }
    ExpectIntEQ(wolfSSL_ASN1_STRING_set(gn->d.rfc822Name, email, sizeof(email)),
        1);

    ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
    XMEMSET(outbuf,0,sizeof(outbuf));
    ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
    ExpectIntEQ(XSTRNCMP((const char*)outbuf, emailStr, XSTRLEN(emailStr)), 0);

    GENERAL_NAME_free(gn);
    gn = NULL;

    /* test for  GEN_OTHERNAME */

    ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
    if (gn != NULL) {
        gn->type = GEN_OTHERNAME;
    }

    ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
    XMEMSET(outbuf,0,sizeof(outbuf));
    ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
    ExpectIntEQ(XSTRNCMP((const char*)outbuf, othrStr, XSTRLEN(othrStr)), 0);

    GENERAL_NAME_free(gn);
    gn = NULL;

    /* test for  GEN_X400 */

    ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
    if (gn != NULL) {
        gn->type = GEN_X400;
    }

    ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
    XMEMSET(outbuf,0,sizeof(outbuf));
    ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
    ExpectIntEQ(XSTRNCMP((const char*)outbuf, x400Str, XSTRLEN(x400Str)), 0);

    /* Restore to GEN_IA5 (default) to avoid memory leak. */
    if (gn != NULL) {
        gn->type = GEN_IA5;
    }
    GENERAL_NAME_free(gn);
    gn = NULL;

    /* test for GEN_EDIPARTY */

    ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
    if (gn != NULL) {
        gn->type = GEN_EDIPARTY;
    }

    ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
    XMEMSET(outbuf,0,sizeof(outbuf));
    ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
    ExpectIntEQ(XSTRNCMP((const char*)outbuf, ediStr, XSTRLEN(ediStr)), 0);

    /* Restore to GEN_IA5 (default) to avoid memory leak. */
    if (gn != NULL) {
        gn->type = GEN_IA5;
    }
    GENERAL_NAME_free(gn);
    gn = NULL;

    BIO_free(out);
#endif /* OPENSSL_ALL */
    return EXPECT_RESULT();
}

static int test_wolfSSL_sk_DIST_POINT(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
    !defined(NO_RSA)
    X509* x509 = NULL;
    unsigned char buf[4096];
    const unsigned char* bufPt;
    int bytes = 0;
    int i = 0;
    int j = 0;
    XFILE f = XBADFILE;
    DIST_POINT* dp = NULL;
    DIST_POINT_NAME* dpn = NULL;
    GENERAL_NAME* gn = NULL;
    ASN1_IA5STRING* uri = NULL;
    STACK_OF(DIST_POINT)* dps = NULL;
    STACK_OF(GENERAL_NAME)* gns = NULL;
    const char cliCertDerCrlDistPoint[] = "./certs/client-crl-dist.der";

    ExpectTrue((f = XFOPEN(cliCertDerCrlDistPoint, "rb")) != XBADFILE);
    ExpectIntGT((bytes = (int)XFREAD(buf, 1, sizeof(buf), f)), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    bufPt = buf;
    ExpectNotNull(x509 = d2i_X509(NULL, &bufPt, bytes));

    ExpectNotNull(dps = (STACK_OF(DIST_POINT)*)X509_get_ext_d2i(x509,
        NID_crl_distribution_points, NULL, NULL));

    ExpectIntEQ(sk_DIST_POINT_num(dps), 1);
    for (i = 0; i < sk_DIST_POINT_num(dps); i++) {
        ExpectNotNull(dp = sk_DIST_POINT_value(dps, i));
        ExpectNotNull(dpn = dp->distpoint);

        /* this should be type 0, fullname */
        ExpectIntEQ(dpn->type, 0);

        ExpectNotNull(gns = dp->distpoint->name.fullname);
        ExpectIntEQ(sk_GENERAL_NAME_num(gns), 1);

        for (j = 0; j < sk_GENERAL_NAME_num(gns); j++) {
            ExpectNotNull(gn = sk_GENERAL_NAME_value(gns, j));
            ExpectIntEQ(gn->type, GEN_URI);
            ExpectNotNull(uri = gn->d.uniformResourceIdentifier);
            ExpectNotNull(uri->data);
            ExpectIntGT(uri->length, 0);
        }
    }

    X509_free(x509);
    CRL_DIST_POINTS_free(dps);
#endif
    return EXPECT_RESULT();
}



static int test_wolfSSL_verify_mode(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA)
    WOLFSSL*     ssl = NULL;
    WOLFSSL_CTX* ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));

    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_CTX_get_verify_mode(ctx));
    SSL_free(ssl);
    ssl = NULL;

    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_CTX_get_verify_mode(ctx));
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_PEER);

    wolfSSL_set_verify(ssl, SSL_VERIFY_NONE, 0);
    ExpectIntEQ(SSL_CTX_get_verify_mode(ctx), SSL_VERIFY_PEER);
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_NONE);

    SSL_free(ssl);
    ssl = NULL;

    wolfSSL_CTX_set_verify(ctx,
        WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_CTX_get_verify_mode(ctx));
    ExpectIntEQ(SSL_get_verify_mode(ssl),
        WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT);

    wolfSSL_set_verify(ssl, SSL_VERIFY_PEER, 0);
    ExpectIntEQ(SSL_CTX_get_verify_mode(ctx),
        WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT);
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_PEER);

    wolfSSL_set_verify(ssl, SSL_VERIFY_NONE, 0);
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_NONE);

    wolfSSL_set_verify(ssl, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_FAIL_IF_NO_PEER_CERT);

    wolfSSL_set_verify(ssl, SSL_VERIFY_FAIL_EXCEPT_PSK, 0);
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_FAIL_EXCEPT_PSK);

#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
    wolfSSL_set_verify(ssl, SSL_VERIFY_POST_HANDSHAKE, 0);
    ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_POST_HANDSHAKE);
#endif

    ExpectIntEQ(SSL_CTX_get_verify_mode(ctx),
        WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT);

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_verify_depth(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL*     ssl = NULL;
    WOLFSSL_CTX* ctx = NULL;
    long         depth = 0;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectIntGT((depth = SSL_CTX_get_verify_depth(ctx)), 0);

    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectIntEQ(SSL_get_verify_depth(ssl), SSL_CTX_get_verify_depth(ctx));
    SSL_free(ssl);
    ssl = NULL;

    SSL_CTX_set_verify_depth(ctx, -1);
    ExpectIntEQ(depth, SSL_CTX_get_verify_depth(ctx));

    SSL_CTX_set_verify_depth(ctx, 2);
    ExpectIntEQ(2, SSL_CTX_get_verify_depth(ctx));
    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectIntEQ(2, SSL_get_verify_depth(ssl));

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_verify_result(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
    defined(OPENSSL_ALL)) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL*     ssl = NULL;
    WOLFSSL_CTX* ctx = NULL;
    long         result = 0xDEADBEEF;

    ExpectIntEQ(WC_NO_ERR_TRACE(WOLFSSL_FAILURE), wolfSSL_get_verify_result(ssl));

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ssl = SSL_new(ctx));

    wolfSSL_set_verify_result(ssl, result);
    ExpectIntEQ(result, wolfSSL_get_verify_result(ssl));

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_WOLFSSL_CLIENT)
static void sslMsgCb(int w, int version, int type, const void* buf,
        size_t sz, SSL* ssl, void* arg)
{
    int i;
    unsigned char* pt = (unsigned char*)buf;

    fprintf(stderr, "%s %d bytes of version %d , type %d : ",
            (w)?"Writing":"Reading", (int)sz, version, type);
    for (i = 0; i < (int)sz; i++) fprintf(stderr, "%02X", pt[i]);
    fprintf(stderr, "\n");
    (void)ssl;
    (void)arg;
}
#endif /* OPENSSL_EXTRA */

static int test_wolfSSL_msg_callback(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL*     ssl = NULL;
    WOLFSSL_CTX* ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectIntEQ(SSL_set_msg_callback(ssl, NULL), SSL_SUCCESS);
    ExpectIntEQ(SSL_set_msg_callback(ssl, &sslMsgCb), SSL_SUCCESS);
    ExpectIntEQ(SSL_set_msg_callback(NULL, &sslMsgCb), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

/* test_EVP_Cipher_extra, Extra-test on EVP_CipherUpdate/Final. see also test.c */
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) &&\
    (!defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128))
static void binary_dump(void *ptr, int size)
{
    #ifdef WOLFSSL_EVP_PRINT
    int i = 0;
    unsigned char *p = (unsigned char *) ptr;

    fprintf(stderr, "{");
    while ((p != NULL) && (i < size)) {
        if ((i % 8) == 0) {
            fprintf(stderr, "\n");
            fprintf(stderr, "    ");
        }
        fprintf(stderr, "0x%02x, ", p[i]);
        i++;
    }
    fprintf(stderr, "\n};\n");
    #else
    (void) ptr;
    (void) size;
    #endif
}

static int last_val = 0x0f;

static int check_result(unsigned char *data, int len)
{
    int i;

    for ( ; len; ) {
            last_val = (last_val + 1) % 16;
            for (i = 0; i < 16; len--, i++, data++)
                    if (*data != last_val) {
                            return -1;
                    }
    }
    return 0;
}

static int r_offset;
static int w_offset;

static void init_offset(void)
{
    r_offset = 0;
    w_offset = 0;
}
static void get_record(unsigned char *data, unsigned char *buf, int len)
{
    XMEMCPY(buf, data+r_offset, len);
    r_offset += len;
}

static void set_record(unsigned char *data, unsigned char *buf, int len)
{
    XMEMCPY(data+w_offset, buf, len);
    w_offset += len;
}

static void set_plain(unsigned char *plain, int rec)
{
    int i, j;
    unsigned char *p = plain;

    #define BLOCKSZ 16

    for (i=0; i<(rec/BLOCKSZ); i++) {
        for (j=0; j<BLOCKSZ; j++)
            *p++ = (i % 16);
    }
}
#endif

static int test_wolfSSL_EVP_Cipher_extra(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) &&\
    (!defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128))
    /* aes128-cbc, keylen=16, ivlen=16 */
    byte aes128_cbc_key[] = {
        0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,
        0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,
    };

    byte aes128_cbc_iv[] = {
        0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
        0x99, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
    };

    /* teset data size table */
    int test_drive1[] = {8, 3, 5, 512, 8, 3, 8, 512, 0};
    int test_drive2[] = {8, 3, 8, 512, 0};
    int test_drive3[] = {512, 512, 504, 512, 512, 8, 512, 0};

    int *test_drive[] = {test_drive1, test_drive2, test_drive3, NULL};
    int test_drive_len[100];

    int ret = 0;
    EVP_CIPHER_CTX *evp = NULL;

    int ilen = 0;
    int klen = 0;
    int i, j;

    const EVP_CIPHER *type;
    byte *iv;
    byte *key;
    int ivlen;
    int keylen;

    #define RECORDS 16
    #define BUFFSZ  512
    byte plain [BUFFSZ * RECORDS];
    byte cipher[BUFFSZ * RECORDS];

    byte inb[BUFFSZ];
    byte outb[BUFFSZ+16];
    int outl = 0;
    int inl;

    iv = aes128_cbc_iv;
    ivlen = sizeof(aes128_cbc_iv);
    key = aes128_cbc_key;
    keylen = sizeof(aes128_cbc_key);
    type = EVP_aes_128_cbc();

    set_plain(plain, BUFFSZ * RECORDS);

    SSL_library_init();

    ExpectNotNull(evp = EVP_CIPHER_CTX_new());
    ExpectIntNE((ret = EVP_CipherInit(evp, type, NULL, iv, 0)), 0);

    ExpectIntEQ(EVP_CIPHER_CTX_nid(evp), NID_aes_128_cbc);

    klen = EVP_CIPHER_CTX_key_length(evp);
    if (klen > 0 && keylen != klen) {
        ExpectIntNE(EVP_CIPHER_CTX_set_key_length(evp, keylen), 0);
    }
    ilen = EVP_CIPHER_CTX_iv_length(evp);
    if (ilen > 0 && ivlen != ilen) {
        ExpectIntNE(EVP_CIPHER_CTX_set_iv_length(evp, ivlen), 0);
    }

    ExpectIntNE((ret = EVP_CipherInit(evp, NULL, key, iv, 1)), 0);

    for (j = 0; j<RECORDS; j++)
    {
        inl = BUFFSZ;
        get_record(plain, inb, inl);
        ExpectIntNE((ret = EVP_CipherUpdate(evp, outb, &outl, inb, inl)), 0);
        set_record(cipher, outb, outl);
    }

    for (i = 0; test_drive[i]; i++) {

        ExpectIntNE((ret = EVP_CipherInit(evp, NULL, key, iv, 1)), 0);

        init_offset();
        test_drive_len[i] = 0;

        for (j = 0; test_drive[i][j]; j++)
        {
            inl = test_drive[i][j];
            test_drive_len[i] += inl;

            get_record(plain, inb, inl);
            ExpectIntNE((ret = EVP_EncryptUpdate(evp, outb, &outl, inb, inl)),
                0);
            /* output to cipher buffer, so that following Dec test can detect
               if any error */
            set_record(cipher, outb, outl);
        }

        EVP_CipherFinal(evp, outb, &outl);

        if (outl > 0)
            set_record(cipher, outb, outl);
    }

    for (i = 0; test_drive[i]; i++) {
        last_val = 0x0f;

        ExpectIntNE((ret = EVP_CipherInit(evp, NULL, key, iv, 0)), 0);

        init_offset();

        for (j = 0; test_drive[i][j]; j++) {
            inl = test_drive[i][j];
            get_record(cipher, inb, inl);

            ExpectIntNE((ret = EVP_DecryptUpdate(evp, outb, &outl, inb, inl)),
                0);

            binary_dump(outb, outl);
            ExpectIntEQ((ret = check_result(outb, outl)), 0);
            ExpectFalse(outl > ((inl/16+1)*16) && outl > 16);
        }

        ret = EVP_CipherFinal(evp, outb, &outl);

        binary_dump(outb, outl);

        ret = (((test_drive_len[i] % 16) != 0) && (ret == 0)) ||
                 (((test_drive_len[i] % 16) == 0) && (ret == 1));
        ExpectTrue(ret);
    }

    ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(evp), WOLFSSL_SUCCESS);

    EVP_CIPHER_CTX_free(evp);
    evp = NULL;

    /* Do an extra test to verify correct behavior with empty input. */

    ExpectNotNull(evp = EVP_CIPHER_CTX_new());
    ExpectIntNE((ret = EVP_CipherInit(evp, type, NULL, iv, 0)), 0);

    ExpectIntEQ(EVP_CIPHER_CTX_nid(evp), NID_aes_128_cbc);

    klen = EVP_CIPHER_CTX_key_length(evp);
    if (klen > 0 && keylen != klen) {
        ExpectIntNE(EVP_CIPHER_CTX_set_key_length(evp, keylen), 0);
    }
    ilen = EVP_CIPHER_CTX_iv_length(evp);
    if (ilen > 0 && ivlen != ilen) {
        ExpectIntNE(EVP_CIPHER_CTX_set_iv_length(evp, ivlen), 0);
    }

    ExpectIntNE((ret = EVP_CipherInit(evp, NULL, key, iv, 1)), 0);

    /* outl should be set to 0 after passing NULL, 0 for input args. */
    outl = -1;
    ExpectIntNE((ret = EVP_CipherUpdate(evp, outb, &outl, NULL, 0)), 0);
    ExpectIntEQ(outl, 0);

    EVP_CIPHER_CTX_free(evp);
#endif /* test_EVP_Cipher */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_read_DHparams(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && \
    !defined(NO_FILESYSTEM)
    DH* dh = NULL;
    XFILE fp = XBADFILE;
    unsigned char derOut[300];
    unsigned char* derOutBuf = derOut;
    int derOutSz = 0;

    unsigned char derExpected[300];
    int derExpectedSz = 0;

    XMEMSET(derOut, 0, sizeof(derOut));
    XMEMSET(derExpected, 0, sizeof(derExpected));

    /* open DH param file, read into DH struct */
    ExpectTrue((fp = XFOPEN(dhParamFile, "rb")) != XBADFILE);

    /* bad args */
    ExpectNull(dh = PEM_read_DHparams(NULL, &dh, NULL, NULL));
    ExpectNull(dh = PEM_read_DHparams(NULL, NULL, NULL, NULL));

    /* good args */
    ExpectNotNull(dh = PEM_read_DHparams(fp, &dh, NULL, NULL));
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }

    /* read in certs/dh2048.der for comparison against exported params */
    ExpectTrue((fp = XFOPEN("./certs/dh2048.der", "rb")) != XBADFILE);
    ExpectIntGT(derExpectedSz = (int)XFREAD(derExpected, 1, sizeof(derExpected),
        fp), 0);
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }

    /* export DH back to DER and compare */
    derOutSz = wolfSSL_i2d_DHparams(dh, &derOutBuf);
    ExpectIntEQ(derOutSz, derExpectedSz);
    ExpectIntEQ(XMEMCMP(derOut, derExpected, derOutSz), 0);

    DH_free(dh);
    dh = NULL;

    /* Test parsing with X9.42 header */
    ExpectTrue((fp = XFOPEN("./certs/x942dh2048.pem", "rb")) != XBADFILE);
    ExpectNotNull(dh = PEM_read_DHparams(fp, &dh, NULL, NULL));
    if (fp != XBADFILE)
        XFCLOSE(fp);

    DH_free(dh);
    dh = NULL;
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_X509_get_serialNumber(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA)
    ASN1_INTEGER* a = NULL;
    BIGNUM* bn = NULL;
    X509*   x509 = NULL;
    char *serialHex = NULL;
    byte serial[3];
    int  serialSz;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(svrCertFile,
        SSL_FILETYPE_PEM));
    ExpectNotNull(a = X509_get_serialNumber(x509));

    /* check on value of ASN1 Integer */
    ExpectNotNull(bn = ASN1_INTEGER_to_BN(a, NULL));
    a = NULL;

    /* test setting serial number and then retrieving it */
    ExpectNotNull(a = ASN1_INTEGER_new());
    ExpectIntEQ(ASN1_INTEGER_set(a, 3), 1);
    ExpectIntEQ(X509_set_serialNumber(x509, a), WOLFSSL_SUCCESS);
    serialSz = sizeof(serial);
    ExpectIntEQ(wolfSSL_X509_get_serial_number(x509, serial, &serialSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(serialSz, 1);
    ExpectIntEQ(serial[0], 3);
    ASN1_INTEGER_free(a);
    a = NULL;

    /* test setting serial number with 0's in it */
    serial[0] = 0x01;
    serial[1] = 0x00;
    serial[2] = 0x02;

    ExpectNotNull(a = wolfSSL_ASN1_INTEGER_new());
    if (a != NULL) {
        a->data[0] = ASN_INTEGER;
        a->data[1] = sizeof(serial);
        XMEMCPY(&a->data[2], serial, sizeof(serial));
        a->length = sizeof(serial) + 2;
    }
    ExpectIntEQ(X509_set_serialNumber(x509, a), WOLFSSL_SUCCESS);

    XMEMSET(serial, 0, sizeof(serial));
    serialSz = sizeof(serial);
    ExpectIntEQ(wolfSSL_X509_get_serial_number(x509, serial, &serialSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(serialSz, 3);
    ExpectIntEQ(serial[0], 0x01);
    ExpectIntEQ(serial[1], 0x00);
    ExpectIntEQ(serial[2], 0x02);
    ASN1_INTEGER_free(a);
    a = NULL;

    X509_free(x509); /* free's a */

    ExpectNotNull(serialHex = BN_bn2hex(bn));
#ifndef WC_DISABLE_RADIX_ZERO_PAD
    ExpectStrEQ(serialHex, "01");
#else
    ExpectStrEQ(serialHex, "1");
#endif
    OPENSSL_free(serialHex);
    ExpectIntEQ(BN_get_word(bn), 1);
    BN_free(bn);

    /* hard test free'ing with dynamic buffer to make sure there is no leaks */
    ExpectNotNull(a = ASN1_INTEGER_new());
    if (a != NULL) {
        ExpectNotNull(a->data = (unsigned char*)XMALLOC(100, NULL,
            DYNAMIC_TYPE_OPENSSL));
        a->isDynamic = 1;
        ASN1_INTEGER_free(a);
    }
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_OpenSSL_add_all_algorithms(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    ExpectIntEQ(wolfSSL_add_all_algorithms(), WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_OpenSSL_add_all_algorithms_noconf(), WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_OpenSSL_add_all_algorithms_conf(), WOLFSSL_SUCCESS);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OPENSSL_hexstr2buf(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    #define MAX_HEXSTR_BUFSZ 9
    #define NUM_CASES        5
    struct Output {
        const unsigned char buffer[MAX_HEXSTR_BUFSZ];
        long ret;
    };
    int i;
    int j;

    const char* inputs[NUM_CASES] = {
        "aabcd1357e",
        "01:12:23:34:a5:b6:c7:d8:e9",
        ":01:02",
        "012",
        ":ab:ac:d"
    };
    struct Output expectedOutputs[NUM_CASES] = {
        {{0xaa, 0xbc, 0xd1, 0x35, 0x7e}, 5},
        {{0x01, 0x12, 0x23, 0x34, 0xa5, 0xb6, 0xc7, 0xd8, 0xe9}, 9},
        {{0x01, 0x02}, 2},
        {{0x00}, 0},
        {{0x00}, 0}
    };
    long len = 0;
    unsigned char* returnedBuf = NULL;

    for (i = 0; i < NUM_CASES && !EXPECT_FAIL(); ++i) {
        returnedBuf = wolfSSL_OPENSSL_hexstr2buf(inputs[i], &len);
        if (returnedBuf == NULL) {
            ExpectIntEQ(expectedOutputs[i].ret, 0);
            continue;
        }

        ExpectIntEQ(expectedOutputs[i].ret, len);

        for (j = 0; j < len; ++j) {
            ExpectIntEQ(expectedOutputs[i].buffer[j], returnedBuf[j]);
        }
        OPENSSL_free(returnedBuf);
        returnedBuf = NULL;
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_CA_num(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
    defined(HAVE_ECC) && !defined(NO_RSA)
    WOLFSSL_X509_STORE *store = NULL;
    WOLFSSL_X509 *x509_1 = NULL;
    WOLFSSL_X509 *x509_2 = NULL;
    int ca_num = 0;

    ExpectNotNull(store = wolfSSL_X509_STORE_new());
    ExpectNotNull(x509_1 = wolfSSL_X509_load_certificate_file(svrCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ(wolfSSL_X509_STORE_add_cert(store, x509_1), 1);
    ExpectIntEQ(ca_num = wolfSSL_X509_CA_num(store), 1);

    ExpectNotNull(x509_2 = wolfSSL_X509_load_certificate_file(eccCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ(wolfSSL_X509_STORE_add_cert(store, x509_2), 1);
    ExpectIntEQ(ca_num = wolfSSL_X509_CA_num(store), 2);

    wolfSSL_X509_free(x509_1);
    wolfSSL_X509_free(x509_2);
    wolfSSL_X509_STORE_free(store);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_check_ca(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
    WOLFSSL_X509 *x509 = NULL;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(svrCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ(wolfSSL_X509_check_ca(x509), 1);
    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_check_ip_asc(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
    WOLFSSL_X509 *x509 = NULL;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
        WOLFSSL_FILETYPE_PEM));
#if 0
    /* TODO: add cert gen for testing positive case */
    ExpectIntEQ(wolfSSL_X509_check_ip_asc(x509, "127.0.0.1", 0), 1);
#endif
    ExpectIntEQ(wolfSSL_X509_check_ip_asc(x509, "0.0.0.0", 0), 0);
    ExpectIntEQ(wolfSSL_X509_check_ip_asc(x509, NULL, 0), 0);
    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_make_cert(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && !defined(NO_ASN_TIME) && defined(WOLFSSL_CERT_GEN) && \
    defined(WOLFSSL_CERT_EXT)
    int      ret = 0;
    Cert     cert;
    CertName name;
    RsaKey   key;
    WC_RNG   rng;
    byte     der[FOURK_BUF];
    word32   idx = 0;
    const byte mySerial[8] = {1,2,3,4,5,6,7,8};

#ifdef OPENSSL_EXTRA
    const unsigned char* pt = NULL;
    int                  certSz = 0;
    X509*                x509 = NULL;
    X509_NAME*           x509name = NULL;
    X509_NAME_ENTRY*     entry = NULL;
    ASN1_STRING*         entryValue = NULL;
#endif

    XMEMSET(&name, 0, sizeof(CertName));

    /* set up cert name */
    XMEMCPY(name.country, "US", sizeof("US"));
    name.countryEnc = CTC_PRINTABLE;
    XMEMCPY(name.state, "Oregon", sizeof("Oregon"));
    name.stateEnc = CTC_UTF8;
    XMEMCPY(name.locality, "Portland", sizeof("Portland"));
    name.localityEnc = CTC_UTF8;
    XMEMCPY(name.sur, "Test", sizeof("Test"));
    name.surEnc = CTC_UTF8;
    XMEMCPY(name.org, "wolfSSL", sizeof("wolfSSL"));
    name.orgEnc = CTC_UTF8;
    XMEMCPY(name.unit, "Development", sizeof("Development"));
    name.unitEnc = CTC_UTF8;
    XMEMCPY(name.commonName, "www.wolfssl.com", sizeof("www.wolfssl.com"));
    name.commonNameEnc = CTC_UTF8;
    XMEMCPY(name.serialDev, "wolfSSL12345", sizeof("wolfSSL12345"));
    name.serialDevEnc = CTC_PRINTABLE;
    XMEMCPY(name.userId, "TestUserID", sizeof("TestUserID"));
    name.userIdEnc = CTC_PRINTABLE;
#ifdef WOLFSSL_MULTI_ATTRIB
    #if CTC_MAX_ATTRIB > 2
    {
        NameAttrib* n;
        n = &name.name[0];
        n->id   = ASN_DOMAIN_COMPONENT;
        n->type = CTC_UTF8;
        n->sz   = sizeof("com");
        XMEMCPY(n->value, "com", sizeof("com"));

        n = &name.name[1];
        n->id   = ASN_DOMAIN_COMPONENT;
        n->type = CTC_UTF8;
        n->sz   = sizeof("wolfssl");
        XMEMCPY(n->value, "wolfssl", sizeof("wolfssl"));
    }
    #endif
#endif /* WOLFSSL_MULTI_ATTRIB */

    ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
#ifndef HAVE_FIPS
    ExpectIntEQ(wc_InitRng_ex(&rng, HEAP_HINT, testDevId), 0);
#else
    ExpectIntEQ(wc_InitRng(&rng), 0);
#endif

    /* load test RSA key */
    idx = 0;
#if defined(USE_CERT_BUFFERS_1024)
    ExpectIntEQ(wc_RsaPrivateKeyDecode(server_key_der_1024, &idx, &key,
                sizeof_server_key_der_1024), 0);
#elif defined(USE_CERT_BUFFERS_2048)
    ExpectIntEQ(wc_RsaPrivateKeyDecode(server_key_der_2048, &idx, &key,
                sizeof_server_key_der_2048), 0);
#else
    /* error case, no RSA key loaded, happens later */
    (void)idx;
#endif

    XMEMSET(&cert, 0 , sizeof(Cert));
    ExpectIntEQ(wc_InitCert(&cert), 0);

    XMEMCPY(&cert.subject, &name, sizeof(CertName));
    XMEMCPY(cert.serial, mySerial, sizeof(mySerial));
    cert.serialSz = (int)sizeof(mySerial);
    cert.isCA     = 1;
#ifndef NO_SHA256
    cert.sigType = CTC_SHA256wRSA;
#else
    cert.sigType = CTC_SHAwRSA;
#endif

    /* add SKID from the Public Key */
    ExpectIntEQ(wc_SetSubjectKeyIdFromPublicKey(&cert, &key, NULL), 0);

    /* add AKID from the Public Key */
    ExpectIntEQ(wc_SetAuthKeyIdFromPublicKey(&cert, &key, NULL), 0);

    ret = 0;
    do {
#if defined(WOLFSSL_ASYNC_CRYPT)
        ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
#endif
        if (ret >= 0) {
            ret = wc_MakeSelfCert(&cert, der, FOURK_BUF, &key, &rng);
        }
    } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
    ExpectIntGT(ret, 0);

#ifdef OPENSSL_EXTRA
    /* der holds a certificate with DC's now check X509 parsing of it */
    certSz = ret;
    pt = der;
    ExpectNotNull(x509 = d2i_X509(NULL, &pt, certSz));
    ExpectNotNull(x509name = X509_get_subject_name(x509));
#ifdef WOLFSSL_MULTI_ATTRIB
    ExpectIntEQ((idx = X509_NAME_get_index_by_NID(x509name, NID_domainComponent,
                    -1)), 5);
    ExpectIntEQ((idx = X509_NAME_get_index_by_NID(x509name, NID_domainComponent,
                    (int)idx)), 6);
    ExpectIntEQ((idx = X509_NAME_get_index_by_NID(x509name, NID_domainComponent,
                    (int)idx)), -1);
#endif /* WOLFSSL_MULTI_ATTRIB */

    /* compare DN at index 0 */
    ExpectNotNull(entry = X509_NAME_get_entry(x509name, 0));
    ExpectNotNull(entryValue = X509_NAME_ENTRY_get_data(entry));
    ExpectIntEQ(ASN1_STRING_length(entryValue), 2);
    ExpectStrEQ((const char*)ASN1_STRING_data(entryValue), "US");

#ifndef WOLFSSL_MULTI_ATTRIB
    /* compare Serial Number */
    ExpectIntEQ((idx = X509_NAME_get_index_by_NID(x509name, NID_serialNumber,
                    -1)), 7);
    ExpectNotNull(entry = X509_NAME_get_entry(x509name, idx));
    ExpectNotNull(entryValue = X509_NAME_ENTRY_get_data(entry));
    ExpectIntEQ(ASN1_STRING_length(entryValue), XSTRLEN("wolfSSL12345"));
    ExpectStrEQ((const char*)ASN1_STRING_data(entryValue), "wolfSSL12345");
#endif

#ifdef WOLFSSL_MULTI_ATTRIB
    /* get first and second DC and compare result */
    ExpectIntEQ((idx = X509_NAME_get_index_by_NID(x509name, NID_domainComponent,
                    -1)), 5);
    ExpectNotNull(entry = X509_NAME_get_entry(x509name, (int)idx));
    ExpectNotNull(entryValue = X509_NAME_ENTRY_get_data(entry));
    ExpectStrEQ((const char *)ASN1_STRING_data(entryValue), "com");

    ExpectIntEQ((idx = X509_NAME_get_index_by_NID(x509name, NID_domainComponent,
                   (int)idx)), 6);
    ExpectNotNull(entry = X509_NAME_get_entry(x509name, (int)idx));
    ExpectNotNull(entryValue = X509_NAME_ENTRY_get_data(entry));
    ExpectStrEQ((const char *)ASN1_STRING_data(entryValue), "wolfssl");
#endif /* WOLFSSL_MULTI_ATTRIB */

    /* try invalid index locations for regression test and sanity check */
    ExpectNull(entry = X509_NAME_get_entry(x509name, 11));
    ExpectNull(entry = X509_NAME_get_entry(x509name, 20));

    X509_free(x509);
#endif /* OPENSSL_EXTRA */

    wc_FreeRsaKey(&key);
    wc_FreeRng(&rng);
#endif
    return EXPECT_RESULT();
}

static int test_x509_get_key_id(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    X509 *x509 = NULL;
    const ASN1_STRING* str = NULL;
    byte* keyId = NULL;

    ExpectNotNull(x509 = X509_load_certificate_file(cliCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(str = X509_get0_subject_key_id(x509));
    ExpectNotNull(keyId = wolfSSL_X509_get_subjectKeyID(x509, NULL, NULL));
    ExpectBufEQ(keyId, ASN1_STRING_data((ASN1_STRING*)str),
            ASN1_STRING_length(str));

    X509_free(x509);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_X509_get_version(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    WOLFSSL_X509 *x509 = NULL;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(svrCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ((int)wolfSSL_X509_get_version(x509), 2);
    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_ALL)
static int test_wolfSSL_sk_CIPHER_description(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA)
    const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION;
    int i;
    int numCiphers = 0;
    const SSL_METHOD *method = NULL;
    const SSL_CIPHER *cipher = NULL;
    STACK_OF(SSL_CIPHER) *supportedCiphers = NULL;
    SSL_CTX *ctx = NULL;
    SSL *ssl = NULL;
    char buf[256];
    char test_str[9] = "0000000";
    const char badStr[] = "unknown";
    const char certPath[] = "./certs/client-cert.pem";
    XMEMSET(buf, 0, sizeof(buf));

    ExpectNotNull(method = TLSv1_2_client_method());
    ExpectNotNull(ctx = SSL_CTX_new(method));
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
    SSL_CTX_set_verify_depth(ctx, 4);
    SSL_CTX_set_options(ctx, flags);
    ExpectIntEQ(SSL_CTX_load_verify_locations(ctx, certPath, NULL),
                WOLFSSL_SUCCESS);

    ExpectNotNull(ssl = SSL_new(ctx));
    /* SSL_get_ciphers returns a stack of all configured ciphers
     * A flag, getCipherAtOffset, is set to later have SSL_CIPHER_description
     */
    ExpectNotNull(supportedCiphers = SSL_get_ciphers(ssl));

    /* loop through the amount of supportedCiphers */
    numCiphers = sk_num(supportedCiphers);
    for (i = 0; i < numCiphers; ++i) {
        int j;
        /* sk_value increments "sk->data.cipher->cipherOffset".
         * wolfSSL_sk_CIPHER_description sets the description for
         * the cipher based on the provided offset.
         */
        if ((cipher = (const WOLFSSL_CIPHER*)sk_value(supportedCiphers, i))) {
            SSL_CIPHER_description(cipher, buf, sizeof(buf));
        }

        /* Search cipher description string for "unknown" descriptor */
        for (j = 0; j < (int)XSTRLEN(buf); j++) {
            int k = 0;
            while ((k < (int)XSTRLEN(badStr)) && (buf[j] == badStr[k])) {
                test_str[k] = badStr[k];
                j++;
                k++;
            }
        }
        /* Fail if test_str == badStr == "unknown" */
        ExpectStrNE(test_str,badStr);
    }
    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_get_ciphers_compat(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA)
    const SSL_METHOD *method = NULL;
    const char certPath[] = "./certs/client-cert.pem";
    STACK_OF(SSL_CIPHER) *supportedCiphers = NULL;
    SSL_CTX *ctx = NULL;
    WOLFSSL *ssl = NULL;
    const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION;

    ExpectNotNull(method = SSLv23_client_method());
    ExpectNotNull(ctx = SSL_CTX_new(method));
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
    SSL_CTX_set_verify_depth(ctx, 4);
    SSL_CTX_set_options(ctx, flags);
    ExpectIntEQ(SSL_CTX_load_verify_locations(ctx, certPath, NULL),
                WOLFSSL_SUCCESS);

    ExpectNotNull(ssl = SSL_new(ctx));

    /* Test Bad NULL input */
    ExpectNull(supportedCiphers = SSL_get_ciphers(NULL));
    /* Test for Good input */
    ExpectNotNull(supportedCiphers = SSL_get_ciphers(ssl));
    /* Further usage of SSL_get_ciphers/wolfSSL_get_ciphers_compat is
     * tested in test_wolfSSL_sk_CIPHER_description according to Qt usage */

    SSL_free(ssl);
    SSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_PUBKEY_get(void)
{
    EXPECT_DECLS;
    WOLFSSL_X509_PUBKEY pubkey;
    WOLFSSL_X509_PUBKEY* key;
    WOLFSSL_EVP_PKEY evpkey ;
    WOLFSSL_EVP_PKEY* evpPkey;
    WOLFSSL_EVP_PKEY* retEvpPkey;

    XMEMSET(&pubkey, 0, sizeof(WOLFSSL_X509_PUBKEY));
    XMEMSET(&evpkey, 0, sizeof(WOLFSSL_EVP_PKEY));

    key = &pubkey;
    evpPkey = &evpkey;

    evpPkey->type = WOLFSSL_SUCCESS;
    key->pkey = evpPkey;

    ExpectNotNull(retEvpPkey = wolfSSL_X509_PUBKEY_get(key));
    ExpectIntEQ(retEvpPkey->type, WOLFSSL_SUCCESS);

    ExpectNull(retEvpPkey = wolfSSL_X509_PUBKEY_get(NULL));

    key->pkey = NULL;
    ExpectNull(retEvpPkey = wolfSSL_X509_PUBKEY_get(key));

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_set1_get1_DSA(void)
{
    EXPECT_DECLS;
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
    DSA       *dsa  = NULL;
    DSA       *setDsa  = NULL;
    EVP_PKEY  *pkey = NULL;
    EVP_PKEY  *set1Pkey = NULL;

    SHA_CTX sha;
    byte    signature[DSA_SIG_SIZE];
    byte    hash[WC_SHA_DIGEST_SIZE];
    word32  bytes;
    int     answer;
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* dsaKeyDer = dsa_key_der_1024;
    int dsaKeySz  = sizeof_dsa_key_der_1024;
    byte    tmp[ONEK_BUF];

    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMCPY(tmp, dsaKeyDer , dsaKeySz);
    bytes = dsaKeySz;
#elif defined(USE_CERT_BUFFERS_2048)
    const unsigned char* dsaKeyDer = dsa_key_der_2048;
    int dsaKeySz  = sizeof_dsa_key_der_2048;
    byte    tmp[TWOK_BUF];

    XMEMSET(tmp, 0, sizeof(tmp));
    XMEMCPY(tmp, dsaKeyDer , dsaKeySz);
    bytes = (word32)dsaKeySz;
#else
    byte    tmp[TWOK_BUF];
    const unsigned char* dsaKeyDer = (const unsigned char*)tmp;
    int dsaKeySz;
    XFILE fp = XBADFILE;

    XMEMSET(tmp, 0, sizeof(tmp));
    ExpectTrue((fp = XFOPEN("./certs/dsa2048.der", "rb")) != XBADFILE);
    ExpectIntGT(dsaKeySz = bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), fp), 0);
    if (fp != XBADFILE)
        XFCLOSE(fp);
#endif /* END USE_CERT_BUFFERS_1024 */

    /* Create hash to later Sign and Verify */
    ExpectIntEQ(SHA1_Init(&sha), WOLFSSL_SUCCESS);
    ExpectIntEQ(SHA1_Update(&sha, tmp, bytes), WOLFSSL_SUCCESS);
    ExpectIntEQ(SHA1_Final(hash,&sha), WOLFSSL_SUCCESS);

    /* Initialize pkey with der format dsa key */
    ExpectNotNull(d2i_PrivateKey(EVP_PKEY_DSA, &pkey, &dsaKeyDer,
        (long)dsaKeySz));

    /* Test wolfSSL_EVP_PKEY_get1_DSA */
    /* Should Fail: NULL argument */
    ExpectNull(dsa = EVP_PKEY_get0_DSA(NULL));
    ExpectNull(dsa = EVP_PKEY_get1_DSA(NULL));
    /* Should Pass: Initialized pkey argument */
    ExpectNotNull(dsa = EVP_PKEY_get0_DSA(pkey));
    ExpectNotNull(dsa = EVP_PKEY_get1_DSA(pkey));

#ifdef USE_CERT_BUFFERS_1024
    ExpectIntEQ(DSA_bits(dsa), 1024);
#else
    ExpectIntEQ(DSA_bits(dsa), 2048);
#endif

    /* Sign */
    ExpectIntEQ(wolfSSL_DSA_do_sign(hash, signature, dsa), WOLFSSL_SUCCESS);
    /* Verify. */
    ExpectIntEQ(wolfSSL_DSA_do_verify(hash, signature, dsa, &answer),
                WOLFSSL_SUCCESS);

    /* Test wolfSSL_EVP_PKEY_set1_DSA */
    /* Should Fail: set1Pkey not initialized */
    ExpectIntNE(EVP_PKEY_set1_DSA(set1Pkey, dsa), WOLFSSL_SUCCESS);

    /* Initialize set1Pkey */
    set1Pkey = EVP_PKEY_new();

    /* Should Fail Verify: setDsa not initialized from set1Pkey */
    ExpectIntNE(wolfSSL_DSA_do_verify(hash,signature,setDsa,&answer),
                WOLFSSL_SUCCESS);

    /* Should Pass: set dsa into set1Pkey */
    ExpectIntEQ(EVP_PKEY_set1_DSA(set1Pkey, dsa), WOLFSSL_SUCCESS);

    DSA_free(dsa);
    DSA_free(setDsa);
    EVP_PKEY_free(pkey);
    EVP_PKEY_free(set1Pkey);
#endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
    return EXPECT_RESULT();
} /* END test_EVP_PKEY_set1_get1_DSA */

static int test_wolfSSL_DSA_generate_parameters(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_FIPS)
    DSA *dsa = NULL;

    ExpectNotNull(dsa = DSA_generate_parameters(2048, NULL, 0, NULL, NULL, NULL,
        NULL));
    DSA_free(dsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DSA_SIG(void)
{
    EXPECT_DECLS;
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_FIPS)
    DSA          *dsa      = NULL;
    DSA          *dsa2     = NULL;
    DSA_SIG      *sig      = NULL;
    const BIGNUM *p        = NULL;
    const BIGNUM *q        = NULL;
    const BIGNUM *g        = NULL;
    const BIGNUM *pub      = NULL;
    const BIGNUM *priv     = NULL;
    BIGNUM       *dup_p    = NULL;
    BIGNUM       *dup_q    = NULL;
    BIGNUM       *dup_g    = NULL;
    BIGNUM       *dup_pub  = NULL;
    BIGNUM       *dup_priv = NULL;
    const byte digest[WC_SHA_DIGEST_SIZE] = {0};

    ExpectNotNull(dsa = DSA_new());
    ExpectIntEQ(DSA_generate_parameters_ex(dsa, 2048, NULL, 0, NULL, NULL,
         NULL), 1);
    ExpectIntEQ(DSA_generate_key(dsa), 1);
    DSA_get0_pqg(dsa, &p, &q, &g);
    DSA_get0_key(dsa, &pub, &priv);
    ExpectNotNull(dup_p    = BN_dup(p));
    ExpectNotNull(dup_q    = BN_dup(q));
    ExpectNotNull(dup_g    = BN_dup(g));
    ExpectNotNull(dup_pub  = BN_dup(pub));
    ExpectNotNull(dup_priv = BN_dup(priv));

    ExpectNotNull(sig = DSA_do_sign(digest, sizeof(digest), dsa));
    ExpectNotNull(dsa2 = DSA_new());
    ExpectIntEQ(DSA_set0_pqg(dsa2, dup_p, dup_q, dup_g), 1);
    if (EXPECT_FAIL()) {
        BN_free(dup_p);
        BN_free(dup_q);
        BN_free(dup_g);
    }
    ExpectIntEQ(DSA_set0_key(dsa2, dup_pub, dup_priv), 1);
    if (EXPECT_FAIL()) {
        BN_free(dup_pub);
        BN_free(dup_priv);
    }
    ExpectIntEQ(DSA_do_verify(digest, sizeof(digest), sig, dsa2), 1);

    DSA_free(dsa);
    DSA_free(dsa2);
    DSA_SIG_free(sig);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_set1_get1_EC_KEY (void)
{
    EXPECT_DECLS;
#ifdef HAVE_ECC
    WOLFSSL_EC_KEY* ecKey  = NULL;
    WOLFSSL_EC_KEY* ecGet1  = NULL;
    EVP_PKEY* pkey = NULL;

    ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());

    /* Test wolfSSL_EVP_PKEY_set1_EC_KEY */
    ExpectIntEQ(wolfSSL_EVP_PKEY_set1_EC_KEY(NULL, ecKey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_set1_EC_KEY(pkey, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Should fail since ecKey is empty */
    ExpectIntEQ(wolfSSL_EVP_PKEY_set1_EC_KEY(pkey, ecKey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1);
    ExpectIntEQ(wolfSSL_EVP_PKEY_set1_EC_KEY(pkey, ecKey), WOLFSSL_SUCCESS);

    /* Test wolfSSL_EVP_PKEY_get1_EC_KEY */
    ExpectNull(wolfSSL_EVP_PKEY_get1_EC_KEY(NULL));
    ExpectNotNull(ecGet1 = wolfSSL_EVP_PKEY_get1_EC_KEY(pkey));

    wolfSSL_EC_KEY_free(ecKey);
    wolfSSL_EC_KEY_free(ecGet1);
    EVP_PKEY_free(pkey);
#endif /* HAVE_ECC */
    return EXPECT_RESULT();
} /* END test_EVP_PKEY_set1_get1_EC_KEY */

static int test_wolfSSL_EVP_PKEY_set1_get1_DH (void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENSSH)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
    DH       *dh    = NULL;
    DH       *setDh = NULL;
    EVP_PKEY *pkey  = NULL;

    XFILE f = XBADFILE;
    unsigned char buf[4096];
    const unsigned char* pt = buf;
    const char* dh2048 = "./certs/dh2048.der";
    long len = 0;
    int code = -1;

    XMEMSET(buf, 0, sizeof(buf));

    ExpectTrue((f = XFOPEN(dh2048, "rb")) != XBADFILE);
    ExpectTrue((len = (long)XFREAD(buf, 1, sizeof(buf), f)) > 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    /* Load dh2048.der into DH with internal format */
    ExpectNotNull(setDh = wolfSSL_d2i_DHparams(NULL, &pt, len));

    ExpectIntEQ(wolfSSL_DH_check(setDh, &code), WOLFSSL_SUCCESS);
    ExpectIntEQ(code, 0);
    code = -1;

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());

    /* Set DH into PKEY */
    ExpectIntEQ(wolfSSL_EVP_PKEY_set1_DH(pkey, setDh), WOLFSSL_SUCCESS);

    /* Get DH from PKEY */
    ExpectNotNull(dh = wolfSSL_EVP_PKEY_get1_DH(pkey));

    ExpectIntEQ(wolfSSL_DH_check(dh, &code), WOLFSSL_SUCCESS);
    ExpectIntEQ(code, 0);

    EVP_PKEY_free(pkey);
    DH_free(setDh);
    setDh = NULL;
    DH_free(dh);
    dh = NULL;
#endif /* !NO_DH && WOLFSSL_DH_EXTRA && !NO_FILESYSTEM */
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /* OPENSSL_ALL || WOLFSSL_QT || WOLFSSL_OPENSSH */
    return EXPECT_RESULT();
} /* END test_EVP_PKEY_set1_get1_DH */

static int test_wolfSSL_CTX_ctrl(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
    !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    char caFile[] = "./certs/client-ca.pem";
    char clientFile[] = "./certs/client-cert.pem";
    SSL_CTX* ctx = NULL;
    X509* x509 = NULL;
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
    byte buf[6000];
    char file[] = "./certs/dsaparams.pem";
    XFILE f = XBADFILE;
    int  bytes = 0;
    BIO* bio = NULL;
    DSA* dsa = NULL;
    DH*  dh = NULL;
#endif
#ifdef HAVE_ECC
    WOLFSSL_EC_KEY* ecKey = NULL;
#endif

    ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(caFile,
         WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), WOLFSSL_SUCCESS);
    if (EXPECT_FAIL()) {
        wolfSSL_X509_free(x509);
    }

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(clientFile,
         WOLFSSL_FILETYPE_PEM));

#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
    /* Initialize DH */
    ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectNotNull(bio = BIO_new_mem_buf((void*)buf, bytes));

    ExpectNotNull(dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL));

    ExpectNotNull(dh = wolfSSL_DSA_dup_DH(dsa));
#endif
#ifdef HAVE_ECC
    /* Initialize WOLFSSL_EC_KEY */
    ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1);
#endif

    /* additional test of getting EVP_PKEY key size from X509
     * Do not run with user RSA because wolfSSL_RSA_size is not currently
     * allowed with user RSA */
    {
        EVP_PKEY* pkey = NULL;
#if defined(HAVE_ECC)
        X509* ecX509 = NULL;
#endif /* HAVE_ECC */

        ExpectNotNull(pkey = X509_get_pubkey(x509));
        /* current RSA key is 2048 bit (256 bytes) */
        ExpectIntEQ(EVP_PKEY_size(pkey), 256);

        EVP_PKEY_free(pkey);
        pkey = NULL;

#if defined(HAVE_ECC)
#if defined(USE_CERT_BUFFERS_256)
        ExpectNotNull(ecX509 = wolfSSL_X509_load_certificate_buffer(
            cliecc_cert_der_256, sizeof_cliecc_cert_der_256,
            SSL_FILETYPE_ASN1));
#else
        ExpectNotNull(ecX509 = wolfSSL_X509_load_certificate_file(
            cliEccCertFile, SSL_FILETYPE_PEM));
#endif
        ExpectNotNull(pkey = X509_get_pubkey(ecX509));
        /* current ECC key is 256 bit (32 bytes) */
        ExpectIntEQ(EVP_PKEY_size(pkey), 32);

        X509_free(ecX509);
        EVP_PKEY_free(pkey);
#endif /* HAVE_ECC */
    }

    /* Tests should fail with passed in NULL pointer */
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#if !defined(NO_DH) && !defined(NO_DSA)
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#ifdef HAVE_ECC
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH, 0, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif

    /* Test with SSL_CTRL_EXTRA_CHAIN_CERT
     * wolfSSL_CTX_ctrl should succesffuly call SSL_CTX_add_extra_chain_cert
     */
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509),
        SSL_SUCCESS);
    if (EXPECT_FAIL()) {
        wolfSSL_X509_free(x509);
    }

    /* Test with SSL_CTRL_OPTIONS
     * wolfSSL_CTX_ctrl should succesffuly call SSL_CTX_set_options
     */
    ExpectTrue(wolfSSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, SSL_OP_NO_TLSv1,
        NULL) == SSL_OP_NO_TLSv1);
    ExpectTrue(SSL_CTX_get_options(ctx) == SSL_OP_NO_TLSv1);

    /* Test with SSL_CTRL_SET_TMP_DH
     * wolfSSL_CTX_ctrl should succesffuly call wolfSSL_SSL_CTX_set_tmp_dh
     */
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, dh),
        SSL_SUCCESS);
#endif

    /* Test with SSL_CTRL_SET_TMP_ECDH
     * wolfSSL_CTX_ctrl should succesffuly call wolfSSL_SSL_CTX_set_tmp_ecdh
     */
#ifdef HAVE_ECC
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH, 0, ecKey),
        SSL_SUCCESS);
#endif

#ifdef WOLFSSL_ENCRYPTED_KEYS
    ExpectNull(SSL_CTX_get_default_passwd_cb(ctx));
    ExpectNull(SSL_CTX_get_default_passwd_cb_userdata(ctx));
#endif

    /* Test for min/max proto */
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION,
        0, NULL), SSL_SUCCESS);
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION,
        TLS1_2_VERSION, NULL), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_2_VERSION);
#endif
#ifdef WOLFSSL_TLS13
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION,
        0, NULL), SSL_SUCCESS);

    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION,
        TLS1_3_VERSION, NULL), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_get_max_proto_version(ctx), TLS1_3_VERSION);
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION,
        TLS1_2_VERSION, NULL), SSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_get_max_proto_version(ctx), TLS1_2_VERSION);
#endif
#endif
    /* Cleanup and Pass */
#if !defined(NO_DH) && !defined(NO_DSA)
#ifndef NO_BIO
    BIO_free(bio);
    DSA_free(dsa);
    DH_free(dh);
    dh = NULL;
#endif
#endif
#ifdef HAVE_ECC
    wolfSSL_EC_KEY_free(ecKey);
#endif
    SSL_CTX_free(ctx);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
        * !defined(NO_FILESYSTEM) && !defined(NO_RSA) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_assign(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) || !defined(NO_DSA) || defined(HAVE_ECC)
    int type;
    WOLFSSL_EVP_PKEY* pkey = NULL;
#ifndef NO_RSA
    WOLFSSL_RSA* rsa = NULL;
#endif
#ifndef NO_DSA
    WOLFSSL_DSA* dsa = NULL;
#endif
#ifdef HAVE_ECC
    WOLFSSL_EC_KEY* ecKey = NULL;
#endif

#ifndef NO_RSA
    type = EVP_PKEY_RSA;
    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectNotNull(rsa = wolfSSL_RSA_new());
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(NULL, type, rsa),  WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, type, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, -1, rsa),    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, type, rsa),  WOLFSSL_SUCCESS);
    if (EXPECT_FAIL()) {
        wolfSSL_RSA_free(rsa);
    }
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
#endif /* NO_RSA */

#ifndef NO_DSA
    type = EVP_PKEY_DSA;
    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectNotNull(dsa = wolfSSL_DSA_new());
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(NULL, type, dsa),  WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, type, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, -1, dsa),    WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, type, dsa),  WOLFSSL_SUCCESS);
    if (EXPECT_FAIL()) {
        wolfSSL_DSA_free(dsa);
    }
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
#endif /* NO_DSA */

#ifdef HAVE_ECC
    type = EVP_PKEY_EC;
    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(NULL, type, ecKey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, type, NULL),  WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, -1, ecKey),   WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, type, ecKey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1);
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign(pkey, type, ecKey), WOLFSSL_SUCCESS);
    if (EXPECT_FAIL()) {
        wolfSSL_EC_KEY_free(ecKey);
    }
    wolfSSL_EVP_PKEY_free(pkey);
    pkey = NULL;
#endif /* HAVE_ECC */
#endif /* !NO_RSA || !NO_DSA || HAVE_ECC */
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_assign_DH(void)
{
    EXPECT_DECLS;
#if !defined(NO_DH) && \
 !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
    XFILE                   f = XBADFILE;
    unsigned char           buf[4096];
    const unsigned char*    pt = buf;
    const char*             params1 = "./certs/dh2048.der";
    long                    len = 0;
    WOLFSSL_DH*             dh = NULL;
    WOLFSSL_EVP_PKEY*       pkey = NULL;
    XMEMSET(buf, 0, sizeof(buf));

    /* Load DH parameters DER. */
    ExpectTrue((f = XFOPEN(params1, "rb")) != XBADFILE);
    ExpectTrue((len = (long)XFREAD(buf, 1, sizeof(buf), f)) > 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectNotNull(dh = wolfSSL_d2i_DHparams(NULL, &pt, len));
    ExpectIntEQ(DH_generate_key(dh), WOLFSSL_SUCCESS);

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());

    /* Bad cases */
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign_DH(NULL, dh), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign_DH(pkey, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign_DH(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* Good case */
    ExpectIntEQ(wolfSSL_EVP_PKEY_assign_DH(pkey, dh), WOLFSSL_SUCCESS);
    if (EXPECT_FAIL()) {
        wolfSSL_DH_free(dh);
    }

    EVP_PKEY_free(pkey);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_base_id(void)
{
    EXPECT_DECLS;
    WOLFSSL_EVP_PKEY* pkey = NULL;

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());

    ExpectIntEQ(wolfSSL_EVP_PKEY_base_id(NULL), NID_undef);

    ExpectIntEQ(wolfSSL_EVP_PKEY_base_id(pkey), EVP_PKEY_RSA);

    EVP_PKEY_free(pkey);

    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_PKEY_id(void)
{
    EXPECT_DECLS;
    WOLFSSL_EVP_PKEY* pkey = NULL;

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());

    ExpectIntEQ(wolfSSL_EVP_PKEY_id(NULL), 0);

    ExpectIntEQ(wolfSSL_EVP_PKEY_id(pkey), EVP_PKEY_RSA);

    EVP_PKEY_free(pkey);

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_paramgen(void)
{
    EXPECT_DECLS;
    /* ECC check taken from ecc.c. It is the condition that defines ECC256 */
#if defined(OPENSSL_ALL) && !defined(NO_ECC_SECP) && \
    ((!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && \
            ECC_MIN_KEY_SZ <= 256)
    EVP_PKEY_CTX* ctx = NULL;
    EVP_PKEY*     pkey = NULL;

    /* Test error conditions. */
    ExpectIntEQ(EVP_PKEY_paramgen(NULL, &pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectNotNull(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL));
    ExpectIntEQ(EVP_PKEY_paramgen(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

#ifndef NO_RSA
    EVP_PKEY_CTX_free(ctx);
    /* Parameter generation for RSA not supported yet. */
    ExpectNotNull(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL));
    ExpectIntEQ(EVP_PKEY_paramgen(ctx, &pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif

#ifdef HAVE_ECC
    EVP_PKEY_CTX_free(ctx);
    ExpectNotNull(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL));
    ExpectIntEQ(EVP_PKEY_paramgen_init(ctx), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx,
        NID_X9_62_prime256v1), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_paramgen(ctx, &pkey), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_CTX_set_ec_param_enc(ctx, OPENSSL_EC_NAMED_CURVE),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_keygen_init(ctx), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_keygen(ctx, &pkey), WOLFSSL_SUCCESS);
#endif

    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_keygen(void)
{
    EXPECT_DECLS;
    WOLFSSL_EVP_PKEY* pkey = NULL;
    EVP_PKEY_CTX*     ctx = NULL;
#if !defined(NO_DH) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
    WOLFSSL_EVP_PKEY* params = NULL;
    DH* dh = NULL;
    const BIGNUM* pubkey = NULL;
    const BIGNUM* privkey = NULL;
    ASN1_INTEGER* asn1int = NULL;
    unsigned int length = 0;
    byte* derBuffer = NULL;
#endif

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));

    /* Bad cases */
    ExpectIntEQ(wolfSSL_EVP_PKEY_keygen(NULL, &pkey), 0);
    ExpectIntEQ(wolfSSL_EVP_PKEY_keygen(ctx, NULL), 0);
    ExpectIntEQ(wolfSSL_EVP_PKEY_keygen(NULL, NULL), 0);

    /* Good case */
    ExpectIntEQ(wolfSSL_EVP_PKEY_keygen(ctx, &pkey), 0);

    EVP_PKEY_CTX_free(ctx);
    ctx = NULL;
    EVP_PKEY_free(pkey);
    pkey = NULL;

#if !defined(NO_DH) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
    /* Test DH keygen */
    {
        ExpectNotNull(params = wolfSSL_EVP_PKEY_new());
        ExpectNotNull(dh = DH_get_2048_256());
        ExpectIntEQ(EVP_PKEY_set1_DH(params, dh), WOLFSSL_SUCCESS);
        ExpectNotNull(ctx = EVP_PKEY_CTX_new(params, NULL));
        ExpectIntEQ(EVP_PKEY_keygen_init(ctx), WOLFSSL_SUCCESS);
        ExpectIntEQ(EVP_PKEY_keygen(ctx, &pkey), WOLFSSL_SUCCESS);

        DH_free(dh);
        dh = NULL;
        EVP_PKEY_CTX_free(ctx);
        EVP_PKEY_free(params);

        /* try exporting generated key to DER, to verify */
        ExpectNotNull(dh = EVP_PKEY_get1_DH(pkey));
        DH_get0_key(dh, &pubkey, &privkey);
        ExpectNotNull(pubkey);
        ExpectNotNull(privkey);
        ExpectNotNull(asn1int = BN_to_ASN1_INTEGER(pubkey, NULL));
        ExpectIntGT((length = i2d_ASN1_INTEGER(asn1int, &derBuffer)), 0);

        ASN1_INTEGER_free(asn1int);
        DH_free(dh);
        dh = NULL;
        XFREE(derBuffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);

        EVP_PKEY_free(pkey);
    }
#endif

    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_PKEY_keygen_init(void)
{
    EXPECT_DECLS;
    WOLFSSL_EVP_PKEY*   pkey = NULL;
    EVP_PKEY_CTX        *ctx = NULL;

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));

    ExpectIntEQ(wolfSSL_EVP_PKEY_keygen_init(ctx), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EVP_PKEY_keygen_init(NULL), WOLFSSL_SUCCESS);

    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey);

    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_PKEY_missing_parameters(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_WOLFSSL_STUB)
    WOLFSSL_EVP_PKEY* pkey = NULL;

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());

    ExpectIntEQ(wolfSSL_EVP_PKEY_missing_parameters(pkey), 0);
    ExpectIntEQ(wolfSSL_EVP_PKEY_missing_parameters(NULL), 0);

    EVP_PKEY_free(pkey);
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_PKEY_copy_parameters(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DH) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_SELFTEST) && (defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
    defined(WOLFSSL_OPENSSH)) && defined(WOLFSSL_DH_EXTRA) && \
    !defined(NO_FILESYSTEM)
    WOLFSSL_EVP_PKEY* params = NULL;
    WOLFSSL_EVP_PKEY* copy = NULL;
    DH* dh = NULL;
    BIGNUM* p1;
    BIGNUM* g1;
    BIGNUM* q1;
    BIGNUM* p2;
    BIGNUM* g2;
    BIGNUM* q2;

    /* create DH with DH_get_2048_256 params */
    ExpectNotNull(params = wolfSSL_EVP_PKEY_new());
    ExpectNotNull(dh = DH_get_2048_256());
    ExpectIntEQ(EVP_PKEY_set1_DH(params, dh), WOLFSSL_SUCCESS);
    DH_get0_pqg(dh, (const BIGNUM**)&p1,
                    (const BIGNUM**)&q1,
                    (const BIGNUM**)&g1);
    DH_free(dh);
    dh = NULL;

    /* create DH with random generated DH params */
    ExpectNotNull(copy = wolfSSL_EVP_PKEY_new());
    ExpectNotNull(dh = DH_generate_parameters(2048, 2, NULL, NULL));
    ExpectIntEQ(EVP_PKEY_set1_DH(copy, dh), WOLFSSL_SUCCESS);
    DH_free(dh);
    dh = NULL;

    ExpectIntEQ(EVP_PKEY_copy_parameters(copy, params), WOLFSSL_SUCCESS);
    ExpectNotNull(dh = EVP_PKEY_get1_DH(copy));
    ExpectNotNull(dh->p);
    ExpectNotNull(dh->g);
    ExpectNotNull(dh->q);
    DH_get0_pqg(dh, (const BIGNUM**)&p2,
                    (const BIGNUM**)&q2,
                    (const BIGNUM**)&g2);

    ExpectIntEQ(BN_cmp(p1, p2), 0);
    ExpectIntEQ(BN_cmp(q1, q2), 0);
    ExpectIntEQ(BN_cmp(g1, g2), 0);

    DH_free(dh);
    dh = NULL;
    EVP_PKEY_free(copy);
    EVP_PKEY_free(params);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits(void)
{
    EXPECT_DECLS;
    WOLFSSL_EVP_PKEY*   pkey = NULL;
    EVP_PKEY_CTX*       ctx = NULL;
    int                 bits = 2048;

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));

    ExpectIntEQ(wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits),
        WOLFSSL_SUCCESS);

    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey);

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_CIPHER_CTX_iv_length(void)
{
    EXPECT_DECLS;
    /* This is large enough to be used for all key sizes */
    byte key[AES_256_KEY_SIZE] = {0};
    byte iv[AES_BLOCK_SIZE] = {0};
    int i;
    int nids[] = {
    #ifdef HAVE_AES_CBC
         NID_aes_128_cbc,
    #endif
    #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
    #ifdef HAVE_AESGCM
         NID_aes_128_gcm,
    #endif
    #endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION > 2 */
    #ifdef WOLFSSL_AES_COUNTER
         NID_aes_128_ctr,
    #endif
    #ifndef NO_DES3
         NID_des_cbc,
         NID_des_ede3_cbc,
    #endif
    };
    int iv_lengths[] = {
    #ifdef HAVE_AES_CBC
         AES_BLOCK_SIZE,
    #endif
    #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
    #ifdef HAVE_AESGCM
         GCM_NONCE_MID_SZ,
    #endif
    #endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION > 2 */
    #ifdef WOLFSSL_AES_COUNTER
         AES_BLOCK_SIZE,
    #endif
    #ifndef NO_DES3
         DES_BLOCK_SIZE,
         DES_BLOCK_SIZE,
    #endif
    };
    int nidsLen = (sizeof(nids)/sizeof(int));

    for (i = 0; i < nidsLen; i++) {
        const EVP_CIPHER* init = wolfSSL_EVP_get_cipherbynid(nids[i]);
        EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
        wolfSSL_EVP_CIPHER_CTX_init(ctx);

        ExpectIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_iv_length(ctx), iv_lengths[i]);

        EVP_CIPHER_CTX_free(ctx);
    }

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_CIPHER_CTX_key_length(void)
{
    EXPECT_DECLS;
    byte key[AES_256_KEY_SIZE] = {0};
    byte iv[AES_BLOCK_SIZE] = {0};
    int i;
    int nids[] = {
    #ifdef HAVE_AES_CBC
         NID_aes_128_cbc,
         NID_aes_256_cbc,
    #endif
    #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
    #ifdef HAVE_AESGCM
         NID_aes_128_gcm,
         NID_aes_256_gcm,
    #endif
    #endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION > 2 */
    #ifdef WOLFSSL_AES_COUNTER
         NID_aes_128_ctr,
         NID_aes_256_ctr,
    #endif
    #ifndef NO_DES3
         NID_des_cbc,
         NID_des_ede3_cbc,
    #endif
    };
    int key_lengths[] = {
    #ifdef HAVE_AES_CBC
        AES_128_KEY_SIZE,
        AES_256_KEY_SIZE,
    #endif
    #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
    #ifdef HAVE_AESGCM
        AES_128_KEY_SIZE,
        AES_256_KEY_SIZE,
    #endif
    #endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION > 2 */
    #ifdef WOLFSSL_AES_COUNTER
        AES_128_KEY_SIZE,
        AES_256_KEY_SIZE,
    #endif
    #ifndef NO_DES3
         DES_KEY_SIZE,
         DES3_KEY_SIZE,
    #endif
    };
    int nidsLen = (sizeof(nids)/sizeof(int));

    for (i = 0; i < nidsLen; i++) {
        const EVP_CIPHER *init = wolfSSL_EVP_get_cipherbynid(nids[i]);
        EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
        wolfSSL_EVP_CIPHER_CTX_init(ctx);

        ExpectIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_key_length(ctx), key_lengths[i]);

        ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, key_lengths[i]),
            WOLFSSL_SUCCESS);

        EVP_CIPHER_CTX_free(ctx);
    }

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_CIPHER_CTX_set_iv(void)
{
    EXPECT_DECLS;
#if defined(HAVE_AESGCM) && !defined(NO_DES3)
    int ivLen, keyLen;
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
#ifdef HAVE_AESGCM
    byte key[AES_128_KEY_SIZE] = {0};
    byte iv[AES_BLOCK_SIZE] = {0};
    const EVP_CIPHER *init = EVP_aes_128_gcm();
#else
    byte key[DES3_KEY_SIZE] = {0};
    byte iv[DES_BLOCK_SIZE] = {0};
    const EVP_CIPHER *init = EVP_des_ede3_cbc();
#endif

    wolfSSL_EVP_CIPHER_CTX_init(ctx);
    ExpectIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS);

    ivLen = wolfSSL_EVP_CIPHER_CTX_iv_length(ctx);
    keyLen = wolfSSL_EVP_CIPHER_CTX_key_length(ctx);

    /* Bad cases */
    ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_set_iv(NULL, iv, ivLen),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, NULL, ivLen),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, iv, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_set_iv(NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, iv, keyLen),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* Good case */
    ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, iv, ivLen), 1);

    EVP_CIPHER_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_CTX_new_id(void)
{
    EXPECT_DECLS;
    WOLFSSL_ENGINE* e = NULL;
    int id = 0;
    EVP_PKEY_CTX *ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_EVP_PKEY_CTX_new_id(id, e));

    EVP_PKEY_CTX_free(ctx);

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_rc4(void)
{
    EXPECT_DECLS;
#if !defined(NO_RC4)
    ExpectNotNull(wolfSSL_EVP_rc4());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_enc_null(void)
{
    EXPECT_DECLS;
    ExpectNotNull(wolfSSL_EVP_enc_null());
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_rc2_cbc(void)

{
    EXPECT_DECLS;
#if defined(WOLFSSL_QT) && !defined(NO_WOLFSSL_STUB)
    ExpectNull(wolfSSL_EVP_rc2_cbc());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_mdc2(void)
{
    EXPECT_DECLS;
#if !defined(NO_WOLFSSL_STUB)
    ExpectNull(wolfSSL_EVP_mdc2());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_md4(void)
{
    EXPECT_DECLS;
#if !defined(NO_MD4)
    ExpectNotNull(wolfSSL_EVP_md4());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_aes_256_gcm(void)
{
    EXPECT_DECLS;
#ifdef HAVE_AESGCM
    ExpectNotNull(wolfSSL_EVP_aes_256_gcm());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_aes_192_gcm(void)
{
    EXPECT_DECLS;
#ifdef HAVE_AESGCM
    ExpectNotNull(wolfSSL_EVP_aes_192_gcm());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_aes_256_ccm(void)
{
    EXPECT_DECLS;
#ifdef HAVE_AESCCM
    ExpectNotNull(wolfSSL_EVP_aes_256_ccm());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_aes_192_ccm(void)
{
    EXPECT_DECLS;
#ifdef HAVE_AESCCM
    ExpectNotNull(wolfSSL_EVP_aes_192_ccm());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_aes_128_ccm(void)
{
    EXPECT_DECLS;
#ifdef HAVE_AESCCM
    ExpectNotNull(wolfSSL_EVP_aes_128_ccm());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_ripemd160(void)
{
    EXPECT_DECLS;
#if !defined(NO_WOLFSSL_STUB)
    ExpectNull(wolfSSL_EVP_ripemd160());
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_get_digestbynid(void)
{
    EXPECT_DECLS;

#ifndef NO_MD5
    ExpectNotNull(wolfSSL_EVP_get_digestbynid(NID_md5));
#endif
#ifndef NO_SHA
    ExpectNotNull(wolfSSL_EVP_get_digestbynid(NID_sha1));
#endif
#ifndef NO_SHA256
    ExpectNotNull(wolfSSL_EVP_get_digestbynid(NID_sha256));
#endif
    ExpectNull(wolfSSL_EVP_get_digestbynid(0));

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_MD_nid(void)
{
    EXPECT_DECLS;

#ifndef NO_MD5
    ExpectIntEQ(EVP_MD_nid(EVP_md5()), NID_md5);
#endif
#ifndef NO_SHA
    ExpectIntEQ(EVP_MD_nid(EVP_sha1()), NID_sha1);
#endif
#ifndef NO_SHA256
    ExpectIntEQ(EVP_MD_nid(EVP_sha256()), NID_sha256);
#endif
    ExpectIntEQ(EVP_MD_nid(NULL), NID_undef);

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_get0_EC_KEY(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC)
    WOLFSSL_EVP_PKEY* pkey = NULL;

    ExpectNull(EVP_PKEY_get0_EC_KEY(NULL));

    ExpectNotNull(pkey = EVP_PKEY_new());
    ExpectNull(EVP_PKEY_get0_EC_KEY(pkey));
    EVP_PKEY_free(pkey);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_X_STATE(void)
{
    EXPECT_DECLS;
#if !defined(NO_DES3) && !defined(NO_RC4)
    byte key[DES3_KEY_SIZE] = {0};
    byte iv[DES_IV_SIZE] = {0};
    EVP_CIPHER_CTX *ctx = NULL;
    const EVP_CIPHER *init = NULL;

    /* Bad test cases */
    ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
    ExpectNotNull(init = EVP_des_ede3_cbc());

    wolfSSL_EVP_CIPHER_CTX_init(ctx);
    ExpectIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS);

    ExpectNull(wolfSSL_EVP_X_STATE(NULL));
    ExpectNull(wolfSSL_EVP_X_STATE(ctx));
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* Good test case */
    ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
    ExpectNotNull(init = wolfSSL_EVP_rc4());

    wolfSSL_EVP_CIPHER_CTX_init(ctx);
    ExpectIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS);

    ExpectNotNull(wolfSSL_EVP_X_STATE(ctx));
    EVP_CIPHER_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_X_STATE_LEN(void)
{
    EXPECT_DECLS;
#if !defined(NO_DES3) && !defined(NO_RC4)
    byte key[DES3_KEY_SIZE] = {0};
    byte iv[DES_IV_SIZE] = {0};
    EVP_CIPHER_CTX *ctx = NULL;
    const EVP_CIPHER *init = NULL;

    /* Bad test cases */
    ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
    ExpectNotNull(init = EVP_des_ede3_cbc());

    wolfSSL_EVP_CIPHER_CTX_init(ctx);
    ExpectIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_EVP_X_STATE_LEN(NULL), 0);
    ExpectIntEQ(wolfSSL_EVP_X_STATE_LEN(ctx), 0);
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* Good test case */
    ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
    ExpectNotNull(init = wolfSSL_EVP_rc4());

    wolfSSL_EVP_CIPHER_CTX_init(ctx);
    ExpectIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_EVP_X_STATE_LEN(ctx), sizeof(Arc4));
    EVP_CIPHER_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_CIPHER_block_size(void)
{
    EXPECT_DECLS;
#if defined(HAVE_AES_CBC) || defined(HAVE_AESGCM) || \
    defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AES_ECB) || \
    defined(WOLFSSL_AES_OFB) || !defined(NO_RC4) || \
    (defined(HAVE_CHACHA) && defined(HAVE_POLY1305))

#ifdef HAVE_AES_CBC
    #ifdef WOLFSSL_AES_128
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_128_cbc()), AES_BLOCK_SIZE);
    #endif
    #ifdef WOLFSSL_AES_192
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_192_cbc()), AES_BLOCK_SIZE);
    #endif
    #ifdef WOLFSSL_AES_256
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_256_cbc()), AES_BLOCK_SIZE);
    #endif
#endif

#ifdef HAVE_AESGCM
    #ifdef WOLFSSL_AES_128
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_128_gcm()), 1);
    #endif
    #ifdef WOLFSSL_AES_192
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_192_gcm()), 1);
    #endif
    #ifdef WOLFSSL_AES_256
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_256_gcm()), 1);
    #endif
#endif

#ifdef HAVE_AESCCM
    #ifdef WOLFSSL_AES_128
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_128_ccm()), 1);
    #endif
    #ifdef WOLFSSL_AES_192
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_192_ccm()), 1);
    #endif
    #ifdef WOLFSSL_AES_256
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_256_ccm()), 1);
    #endif
#endif

#ifdef WOLFSSL_AES_COUNTER
    #ifdef WOLFSSL_AES_128
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_128_ctr()), 1);
    #endif
    #ifdef WOLFSSL_AES_192
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_192_ctr()), 1);
    #endif
    #ifdef WOLFSSL_AES_256
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_256_ctr()), 1);
    #endif
#endif

#ifdef HAVE_AES_ECB
    #ifdef WOLFSSL_AES_128
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_128_ecb()), AES_BLOCK_SIZE);
    #endif
    #ifdef WOLFSSL_AES_192
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_192_ecb()), AES_BLOCK_SIZE);
    #endif
    #ifdef WOLFSSL_AES_256
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_256_ecb()), AES_BLOCK_SIZE);
    #endif
#endif

#ifdef WOLFSSL_AES_OFB
    #ifdef WOLFSSL_AES_128
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_128_ofb()), 1);
    #endif
    #ifdef WOLFSSL_AES_192
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_192_ofb()), 1);
    #endif
    #ifdef WOLFSSL_AES_256
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_aes_256_ofb()), 1);
    #endif
#endif

#ifndef NO_RC4
    ExpectIntEQ(EVP_CIPHER_block_size(wolfSSL_EVP_rc4()), 1);
#endif

#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
    ExpectIntEQ(EVP_CIPHER_block_size(wolfSSL_EVP_chacha20_poly1305()), 1);
#endif
#endif

#ifdef WOLFSSL_SM4_ECB
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_ecb()), SM4_BLOCK_SIZE);
#endif
#ifdef WOLFSSL_SM4_CBC
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_cbc()), SM4_BLOCK_SIZE);
#endif
#ifdef WOLFSSL_SM4_CTR
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_ctr()), 1);
#endif
#ifdef WOLFSSL_SM4_GCM
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_gcm()), 1);
#endif
#ifdef WOLFSSL_SM4_CCM
    ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_ccm()), 1);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_CIPHER_iv_length(void)
{
    EXPECT_DECLS;
    int nids[] = {
    #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
    #ifdef WOLFSSL_AES_128
        NID_aes_128_cbc,
    #endif
    #ifdef WOLFSSL_AES_192
        NID_aes_192_cbc,
    #endif
    #ifdef WOLFSSL_AES_256
        NID_aes_256_cbc,
    #endif
    #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
    #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
    #ifdef HAVE_AESGCM
        #ifdef WOLFSSL_AES_128
            NID_aes_128_gcm,
        #endif
        #ifdef WOLFSSL_AES_192
            NID_aes_192_gcm,
        #endif
        #ifdef WOLFSSL_AES_256
            NID_aes_256_gcm,
        #endif
    #endif /* HAVE_AESGCM */
    #endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION > 2 */
    #ifdef WOLFSSL_AES_COUNTER
    #ifdef WOLFSSL_AES_128
         NID_aes_128_ctr,
    #endif
    #ifdef WOLFSSL_AES_192
        NID_aes_192_ctr,
    #endif
    #ifdef WOLFSSL_AES_256
        NID_aes_256_ctr,
    #endif
    #endif
    #ifndef NO_DES3
         NID_des_cbc,
         NID_des_ede3_cbc,
    #endif
    #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
         NID_chacha20_poly1305,
    #endif
    };
    int iv_lengths[] = {
    #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
    #ifdef WOLFSSL_AES_128
            AES_BLOCK_SIZE,
    #endif
    #ifdef WOLFSSL_AES_192
            AES_BLOCK_SIZE,
    #endif
    #ifdef WOLFSSL_AES_256
            AES_BLOCK_SIZE,
    #endif
    #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
    #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
    #ifdef HAVE_AESGCM
        #ifdef WOLFSSL_AES_128
            GCM_NONCE_MID_SZ,
        #endif
        #ifdef WOLFSSL_AES_192
            GCM_NONCE_MID_SZ,
        #endif
        #ifdef WOLFSSL_AES_256
            GCM_NONCE_MID_SZ,
        #endif
    #endif /* HAVE_AESGCM */
    #endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION > 2 */
    #ifdef WOLFSSL_AES_COUNTER
    #ifdef WOLFSSL_AES_128
            AES_BLOCK_SIZE,
    #endif
    #ifdef WOLFSSL_AES_192
            AES_BLOCK_SIZE,
    #endif
    #ifdef WOLFSSL_AES_256
            AES_BLOCK_SIZE,
    #endif
    #endif
    #ifndef NO_DES3
            DES_BLOCK_SIZE,
            DES_BLOCK_SIZE,
    #endif
    #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
            CHACHA20_POLY1305_AEAD_IV_SIZE,
    #endif
    };
    int i;
    int nidsLen = (sizeof(nids)/sizeof(int));

    for (i = 0; i < nidsLen; i++) {
        const EVP_CIPHER *c = EVP_get_cipherbynid(nids[i]);
        ExpectIntEQ(EVP_CIPHER_iv_length(c), iv_lengths[i]);
    }

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_SignInit_ex(void)
{
    EXPECT_DECLS;
    WOLFSSL_EVP_MD_CTX mdCtx;
    WOLFSSL_ENGINE*    e = 0;
    const EVP_MD*      md = EVP_sha256();

    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_SignInit_ex(&mdCtx, md, e), WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_DigestFinal_ex(void)
{
    EXPECT_DECLS;
#if !defined(NO_SHA256)
    WOLFSSL_EVP_MD_CTX mdCtx;
    unsigned int       s = 0;
    unsigned char      md[WC_SHA256_DIGEST_SIZE];
    unsigned char      md2[WC_SHA256_DIGEST_SIZE];

    /* Bad Case */
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
    (HAVE_FIPS_VERSION > 2))
    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestFinal_ex(&mdCtx, md, &s), 0);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

#else
    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestFinal_ex(&mdCtx, md, &s), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), WOLFSSL_SUCCESS);

#endif

    /* Good Case */
    wolfSSL_EVP_MD_CTX_init(&mdCtx);
    ExpectIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, EVP_sha256()), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EVP_DigestFinal_ex(&mdCtx, md2, &s), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), WOLFSSL_SUCCESS);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_QT_EVP_PKEY_CTX_free(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    EVP_PKEY*     pkey = NULL;
    EVP_PKEY_CTX* ctx = NULL;

    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));

#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
    /* void */
    EVP_PKEY_CTX_free(ctx);
#else
    /* int */
    ExpectIntEQ(EVP_PKEY_CTX_free(ctx), WOLFSSL_SUCCESS);
#endif

    EVP_PKEY_free(pkey);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_param_check(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)

    DH       *dh    = NULL;
    DH       *setDh = NULL;
    EVP_PKEY *pkey  = NULL;
    EVP_PKEY_CTX*   ctx = NULL;

    FILE* f = NULL;
    unsigned char buf[512];
    const unsigned char* pt = buf;
    const char* dh2048 = "./certs/dh2048.der";
    long len = 0;
    int code = -1;

    XMEMSET(buf, 0, sizeof(buf));

    ExpectTrue((f = XFOPEN(dh2048, "rb")) != XBADFILE);
    ExpectTrue((len = (long)XFREAD(buf, 1, sizeof(buf), f)) > 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    /* Load dh2048.der into DH with internal format */
    ExpectNotNull(setDh = d2i_DHparams(NULL, &pt, len));
    ExpectIntEQ(DH_check(setDh, &code), WOLFSSL_SUCCESS);
    ExpectIntEQ(code, 0);
    code = -1;

    pkey = wolfSSL_EVP_PKEY_new();
    /* Set DH into PKEY */
    ExpectIntEQ(EVP_PKEY_set1_DH(pkey, setDh), WOLFSSL_SUCCESS);
    /* create ctx from pkey */
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));
    ExpectIntEQ(EVP_PKEY_param_check(ctx), 1/* valid */);

    /* TODO: more invalid cases */
    ExpectIntEQ(EVP_PKEY_param_check(NULL), 0);

    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey);
    DH_free(setDh);
    setDh = NULL;
    DH_free(dh);
    dh = NULL;
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_BytesToKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
    byte                key[AES_BLOCK_SIZE] = {0};
    byte                iv[AES_BLOCK_SIZE] = {0};
    int                 count = 0;
    const               EVP_MD* md = EVP_sha256();
    const EVP_CIPHER    *type;
    const unsigned char *salt = (unsigned char *)"salt1234";
    int                 sz = 5;
    const byte data[] = {
        0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
        0x72,0x6c,0x64
    };

    type = wolfSSL_EVP_get_cipherbynid(NID_aes_128_cbc);

    /* Bad cases */
    ExpectIntEQ(EVP_BytesToKey(NULL, md, salt, data, sz, count, key, iv),
                 0);
    ExpectIntEQ(EVP_BytesToKey(type, md, salt, NULL, sz, count, key, iv),
                16);
    md = "2";
    ExpectIntEQ(EVP_BytesToKey(type, md, salt, data, sz, count, key, iv),
                 WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* Good case */
    md = EVP_sha256();
    ExpectIntEQ(EVP_BytesToKey(type, md, salt, data, sz, count, key, iv),
                 16);
#endif
    return EXPECT_RESULT();
}

static int test_evp_cipher_aes_gcm(void)
{
    EXPECT_DECLS;
#if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && \
    !defined(HAVE_SELFTEST)) || (defined(HAVE_FIPS_VERSION) && \
    (HAVE_FIPS_VERSION >= 2)))
    /*
     * This test checks data at various points in the encrypt/decrypt process
     * against known values produced using the same test with OpenSSL. This
     * interop testing is critical for verifying the correctness of our
     * EVP_Cipher implementation with AES-GCM. Specifically, this test exercises
     * a flow supported by OpenSSL that uses the control command
     * EVP_CTRL_GCM_IV_GEN to increment the IV between cipher operations without
     * the need to call EVP_CipherInit. OpenSSH uses this flow, for example. We
     * had a bug with OpenSSH where wolfSSL OpenSSH servers could only talk to
     * wolfSSL OpenSSH clients because there was a bug in this flow that
     * happened to "cancel out" if both sides of the connection had the bug.
     */
    enum {
        NUM_ENCRYPTIONS = 3,
        AAD_SIZE = 4
    };
    byte plainText1[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
        0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
    };
    byte plainText2[] = {
        0x42, 0x49, 0x3b, 0x27, 0x03, 0x35, 0x59, 0x14, 0x41, 0x47, 0x37, 0x14,
        0x0e, 0x34, 0x0d, 0x28, 0x63, 0x09, 0x0a, 0x5b, 0x22, 0x57, 0x42, 0x22,
        0x0f, 0x5c, 0x1e, 0x53, 0x45, 0x15, 0x62, 0x08, 0x60, 0x43, 0x50, 0x2c
    };
    byte plainText3[] = {
        0x36, 0x0d, 0x2b, 0x09, 0x4a, 0x56, 0x3b, 0x4c, 0x21, 0x22, 0x58, 0x0e,
        0x5b, 0x57, 0x10
    };
    byte* plainTexts[NUM_ENCRYPTIONS] = {
        plainText1,
        plainText2,
        plainText3
    };
    const int plainTextSzs[NUM_ENCRYPTIONS] = {
        sizeof(plainText1),
        sizeof(plainText2),
        sizeof(plainText3)
    };
    byte aad1[AAD_SIZE] = {
        0x00, 0x00, 0x00, 0x01
    };
    byte aad2[AAD_SIZE] = {
        0x00, 0x00, 0x00, 0x10
    };
    byte aad3[AAD_SIZE] = {
        0x00, 0x00, 0x01, 0x00
    };
    byte* aads[NUM_ENCRYPTIONS] = {
        aad1,
        aad2,
        aad3
    };
    const byte iv[GCM_NONCE_MID_SZ] = {
        0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF
    };
    byte currentIv[GCM_NONCE_MID_SZ];
    const byte key[] = {
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
        0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
        0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
    };
    const byte expIvs[NUM_ENCRYPTIONS][GCM_NONCE_MID_SZ] = {
        {
            0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE,
            0xEF
        },
        {
            0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE,
            0xF0
        },
        {
            0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE,
            0xF1
        }
    };
    const byte expTags[NUM_ENCRYPTIONS][AES_BLOCK_SIZE] = {
        {
            0x65, 0x4F, 0xF7, 0xA0, 0xBB, 0x7B, 0x90, 0xB7, 0x9C, 0xC8, 0x14,
            0x3D, 0x32, 0x18, 0x34, 0xA9
        },
        {
            0x50, 0x3A, 0x13, 0x8D, 0x91, 0x1D, 0xEC, 0xBB, 0xBA, 0x5B, 0x57,
            0xA2, 0xFD, 0x2D, 0x6B, 0x7F
        },
        {
            0x3B, 0xED, 0x18, 0x9C, 0xB3, 0xE3, 0x61, 0x1E, 0x11, 0xEB, 0x13,
            0x5B, 0xEC, 0x52, 0x49, 0x32,
        }
    };

    const byte expCipherText1[] = {
        0xCB, 0x93, 0x4F, 0xC8, 0x22, 0xE2, 0xC0, 0x35, 0xAA, 0x6B, 0x41, 0x15,
        0x17, 0x30, 0x2F, 0x97, 0x20, 0x74, 0x39, 0x28, 0xF8, 0xEB, 0xC5, 0x51,
        0x7B, 0xD9, 0x8A, 0x36, 0xB8, 0xDA, 0x24, 0x80, 0xE7, 0x9E, 0x09, 0xDE
    };
    const byte expCipherText2[] = {
        0xF9, 0x32, 0xE1, 0x87, 0x37, 0x0F, 0x04, 0xC1, 0xB5, 0x59, 0xF0, 0x45,
        0x3A, 0x0D, 0xA0, 0x26, 0xFF, 0xA6, 0x8D, 0x38, 0xFE, 0xB8, 0xE5, 0xC2,
        0x2A, 0x98, 0x4A, 0x54, 0x8F, 0x1F, 0xD6, 0x13, 0x03, 0xB2, 0x1B, 0xC0
    };
    const byte expCipherText3[] = {
        0xD0, 0x37, 0x59, 0x1C, 0x2F, 0x85, 0x39, 0x4D, 0xED, 0xC2, 0x32, 0x5B,
        0x80, 0x5E, 0x6B,
    };
    const byte* expCipherTexts[NUM_ENCRYPTIONS] = {
        expCipherText1,
        expCipherText2,
        expCipherText3
    };
    byte* cipherText = NULL;
    byte* calcPlainText = NULL;
    byte tag[AES_BLOCK_SIZE];
    EVP_CIPHER_CTX* encCtx = NULL;
    EVP_CIPHER_CTX* decCtx = NULL;
    int i, j, outl;

    /****************************************************/
    for (i = 0; i < 3; ++i) {
        ExpectNotNull(encCtx = EVP_CIPHER_CTX_new());
        ExpectNotNull(decCtx = EVP_CIPHER_CTX_new());

        /* First iteration, set key before IV. */
        if (i == 0) {
            ExpectIntEQ(EVP_CipherInit(encCtx, EVP_aes_256_gcm(), key, NULL, 1),
                        SSL_SUCCESS);

            /*
             * The call to EVP_CipherInit below (with NULL key) should clear the
             * authIvGenEnable flag set by EVP_CTRL_GCM_SET_IV_FIXED. As such, a
             * subsequent EVP_CTRL_GCM_IV_GEN should fail. This matches OpenSSL
             * behavior.
             */
            ExpectIntEQ(EVP_CIPHER_CTX_ctrl(encCtx, EVP_CTRL_GCM_SET_IV_FIXED, -1,
                    (void*)iv), SSL_SUCCESS);
            ExpectIntEQ(EVP_CipherInit(encCtx, NULL, NULL, iv, 1),
                        SSL_SUCCESS);
            ExpectIntEQ(EVP_CIPHER_CTX_ctrl(encCtx, EVP_CTRL_GCM_IV_GEN, -1,
                        currentIv), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

            ExpectIntEQ(EVP_CipherInit(decCtx, EVP_aes_256_gcm(), key, NULL, 0),
                        SSL_SUCCESS);
            ExpectIntEQ(EVP_CipherInit(decCtx, NULL, NULL, iv, 0),
                        SSL_SUCCESS);
        }
        /* Second iteration, IV before key. */
        else {
            ExpectIntEQ(EVP_CipherInit(encCtx, EVP_aes_256_gcm(), NULL, iv, 1),
                        SSL_SUCCESS);
            ExpectIntEQ(EVP_CipherInit(encCtx, NULL, key, NULL, 1),
                        SSL_SUCCESS);
            ExpectIntEQ(EVP_CipherInit(decCtx, EVP_aes_256_gcm(), NULL, iv, 0),
                        SSL_SUCCESS);
            ExpectIntEQ(EVP_CipherInit(decCtx, NULL, key, NULL, 0),
                        SSL_SUCCESS);
        }

        /*
         * EVP_CTRL_GCM_IV_GEN should fail if EVP_CTRL_GCM_SET_IV_FIXED hasn't
         * been issued first.
         */
        ExpectIntEQ(EVP_CIPHER_CTX_ctrl(encCtx, EVP_CTRL_GCM_IV_GEN, -1,
                        currentIv), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

        ExpectIntEQ(EVP_CIPHER_CTX_ctrl(encCtx, EVP_CTRL_GCM_SET_IV_FIXED, -1,
                    (void*)iv), SSL_SUCCESS);
        ExpectIntEQ(EVP_CIPHER_CTX_ctrl(decCtx, EVP_CTRL_GCM_SET_IV_FIXED, -1,
                    (void*)iv), SSL_SUCCESS);

        for (j = 0; j < NUM_ENCRYPTIONS; ++j) {
            /*************** Encrypt ***************/
            ExpectIntEQ(EVP_CIPHER_CTX_ctrl(encCtx, EVP_CTRL_GCM_IV_GEN, -1,
                        currentIv), SSL_SUCCESS);
            /* Check current IV against expected. */
            ExpectIntEQ(XMEMCMP(currentIv, expIvs[j], GCM_NONCE_MID_SZ), 0);

            /* Add AAD. */
            if (i == 2) {
                /* Test streaming API. */
                ExpectIntEQ(EVP_CipherUpdate(encCtx, NULL, &outl, aads[j],
                                             AAD_SIZE), SSL_SUCCESS);
            }
            else {
                ExpectIntEQ(EVP_Cipher(encCtx, NULL, aads[j], AAD_SIZE),
                                       AAD_SIZE);
            }

            ExpectNotNull(cipherText = (byte*)XMALLOC(plainTextSzs[j], NULL,
                          DYNAMIC_TYPE_TMP_BUFFER));

            /* Encrypt plaintext. */
            if (i == 2) {
                ExpectIntEQ(EVP_CipherUpdate(encCtx, cipherText, &outl,
                                             plainTexts[j], plainTextSzs[j]),
                            SSL_SUCCESS);
            }
            else {
                ExpectIntEQ(EVP_Cipher(encCtx, cipherText, plainTexts[j],
                            plainTextSzs[j]), plainTextSzs[j]);
            }

            if (i == 2) {
                ExpectIntEQ(EVP_CipherFinal(encCtx, cipherText, &outl),
                            SSL_SUCCESS);
            }
            else {
                /*
                 * Calling EVP_Cipher with NULL input and output for AES-GCM is
                 * akin to calling EVP_CipherFinal.
                 */
                ExpectIntGE(EVP_Cipher(encCtx, NULL, NULL, 0), 0);
            }

            /* Check ciphertext against expected. */
            ExpectIntEQ(XMEMCMP(cipherText, expCipherTexts[j], plainTextSzs[j]),
                        0);

            /* Get and check tag against expected. */
            ExpectIntEQ(EVP_CIPHER_CTX_ctrl(encCtx, EVP_CTRL_GCM_GET_TAG,
                        sizeof(tag), tag), SSL_SUCCESS);
            ExpectIntEQ(XMEMCMP(tag, expTags[j], sizeof(tag)), 0);

            /*************** Decrypt ***************/
            ExpectIntEQ(EVP_CIPHER_CTX_ctrl(decCtx, EVP_CTRL_GCM_IV_GEN, -1,
                        currentIv), SSL_SUCCESS);
            /* Check current IV against expected. */
            ExpectIntEQ(XMEMCMP(currentIv, expIvs[j], GCM_NONCE_MID_SZ), 0);

            /* Add AAD. */
            if (i == 2) {
                /* Test streaming API. */
                ExpectIntEQ(EVP_CipherUpdate(decCtx, NULL, &outl, aads[j],
                                             AAD_SIZE), SSL_SUCCESS);
            }
            else {
                ExpectIntEQ(EVP_Cipher(decCtx, NULL, aads[j], AAD_SIZE),
                            AAD_SIZE);
            }

            /* Set expected tag. */
            ExpectIntEQ(EVP_CIPHER_CTX_ctrl(decCtx, EVP_CTRL_GCM_SET_TAG,
                        sizeof(tag), tag), SSL_SUCCESS);

            /* Decrypt ciphertext. */
            ExpectNotNull(calcPlainText = (byte*)XMALLOC(plainTextSzs[j], NULL,
                          DYNAMIC_TYPE_TMP_BUFFER));
            if (i == 2) {
                ExpectIntEQ(EVP_CipherUpdate(decCtx, calcPlainText, &outl,
                                             cipherText, plainTextSzs[j]),
                            SSL_SUCCESS);
            }
            else {
                /* This first EVP_Cipher call will check the tag, too. */
                ExpectIntEQ(EVP_Cipher(decCtx, calcPlainText, cipherText,
                        plainTextSzs[j]), plainTextSzs[j]);
            }

            if (i == 2) {
                ExpectIntEQ(EVP_CipherFinal(decCtx, calcPlainText, &outl),
                            SSL_SUCCESS);
            }
            else {
                ExpectIntGE(EVP_Cipher(decCtx, NULL, NULL, 0), 0);
            }

            /* Check plaintext against expected. */
            ExpectIntEQ(XMEMCMP(calcPlainText, plainTexts[j], plainTextSzs[j]),
                        0);

            XFREE(cipherText, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            cipherText = NULL;
            XFREE(calcPlainText, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            calcPlainText = NULL;
        }

        EVP_CIPHER_CTX_free(encCtx);
        encCtx = NULL;
        EVP_CIPHER_CTX_free(decCtx);
        decCtx = NULL;
    }
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_OBJ_ln(void)
{
    EXPECT_DECLS;
    const int nid_set[] = {
            NID_commonName,
            NID_serialNumber,
            NID_countryName,
            NID_localityName,
            NID_stateOrProvinceName,
            NID_organizationName,
            NID_organizationalUnitName,
            NID_domainComponent,
            NID_businessCategory,
            NID_jurisdictionCountryName,
            NID_jurisdictionStateOrProvinceName,
            NID_emailAddress
    };
    const char* ln_set[] = {
            "commonName",
            "serialNumber",
            "countryName",
            "localityName",
            "stateOrProvinceName",
            "organizationName",
            "organizationalUnitName",
            "domainComponent",
            "businessCategory",
            "jurisdictionCountryName",
            "jurisdictionStateOrProvinceName",
            "emailAddress",
    };
    size_t i = 0, maxIdx = sizeof(ln_set)/sizeof(char*);

    ExpectIntEQ(OBJ_ln2nid(NULL), NID_undef);

#ifdef HAVE_ECC
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    {
        EC_builtin_curve r[27];
        size_t nCurves = sizeof(r) / sizeof(r[0]);
        nCurves = EC_get_builtin_curves(r, nCurves);

        for (i = 0; i < nCurves; i++) {
            /* skip ECC_CURVE_INVALID */
            if (r[i].nid != ECC_CURVE_INVALID) {
                ExpectIntEQ(OBJ_ln2nid(r[i].comment), r[i].nid);
                ExpectStrEQ(OBJ_nid2ln(r[i].nid), r[i].comment);
            }
        }
    }
#endif
#endif

    for (i = 0; i < maxIdx; i++) {
        ExpectIntEQ(OBJ_ln2nid(ln_set[i]), nid_set[i]);
        ExpectStrEQ(OBJ_nid2ln(nid_set[i]), ln_set[i]);
    }

    return EXPECT_RESULT();
}

static int test_wolfSSL_OBJ_sn(void)
{
    EXPECT_DECLS;
    int i = 0, maxIdx = 7;
    const int nid_set[] = {NID_commonName,NID_countryName,NID_localityName,
                           NID_stateOrProvinceName,NID_organizationName,
                           NID_organizationalUnitName,NID_emailAddress};
    const char* sn_open_set[] = {"CN","C","L","ST","O","OU","emailAddress"};
    const char* sn_wolf_set[] = {WOLFSSL_COMMON_NAME,WOLFSSL_COUNTRY_NAME,
                                WOLFSSL_LOCALITY_NAME, WOLFSSL_STATE_NAME,
                                WOLFSSL_ORG_NAME, WOLFSSL_ORGUNIT_NAME,
                                WOLFSSL_EMAIL_ADDR};

    ExpectIntEQ(wolfSSL_OBJ_sn2nid(NULL), NID_undef);
    for (i = 0; i < maxIdx; i++) {
        ExpectIntEQ(wolfSSL_OBJ_sn2nid(sn_wolf_set[i]), nid_set[i]);
        ExpectStrEQ(wolfSSL_OBJ_nid2sn(nid_set[i]), sn_open_set[i]);
    }

    return EXPECT_RESULT();
}

#if !defined(NO_BIO)
static word32 TXT_DB_hash(const WOLFSSL_STRING *s)
{
    return (word32)lh_strhash(s[3]);
}

static int TXT_DB_cmp(const WOLFSSL_STRING *a, const WOLFSSL_STRING *b)
{
    return XSTRCMP(a[3], b[3]);
}
#endif

static int test_wolfSSL_TXT_DB(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_BIO)
    BIO *bio = NULL;
    TXT_DB *db = NULL;
    const int columns = 6;
    const char *fields[6] = {
        "V",
        "320926161116Z",
        "",
        "12BD",
        "unknown",
        "/CN=rsa doe",
    };
    char** fields_copy = NULL;

    /* Test read */
    ExpectNotNull(bio = BIO_new(BIO_s_file()));
    ExpectIntGT(BIO_read_filename(bio, "./tests/TXT_DB.txt"), 0);
    ExpectNotNull(db = TXT_DB_read(bio, columns));
    ExpectNotNull(fields_copy = (char**)XMALLOC(sizeof(fields), NULL,
        DYNAMIC_TYPE_OPENSSL));
    if (fields_copy != NULL) {
        XMEMCPY(fields_copy, fields, sizeof(fields));
    }
    ExpectIntEQ(TXT_DB_insert(db, fields_copy), 1);
    if (EXPECT_FAIL()) {
        XFREE(fields_copy, NULL, DYNAMIC_TYPE_OPENSSL);
    }
    BIO_free(bio);
    bio = NULL;

    /* Test write */
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(TXT_DB_write(bio, db), 1484);
    BIO_free(bio);

    /* Test index */
    ExpectIntEQ(TXT_DB_create_index(db, 3, NULL,
        (wolf_sk_hash_cb)(long unsigned int)TXT_DB_hash,
        (wolf_lh_compare_cb)TXT_DB_cmp), 1);
    ExpectNotNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));
    fields[3] = "12DA";
    ExpectNotNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));
    fields[3] = "FFFF";
    ExpectNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));
    fields[3] = "";
    ExpectNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));

    TXT_DB_free(db);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_NCONF(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_BIO)
    const char* confFile = "./tests/NCONF_test.cnf";
    CONF* conf = NULL;
    long eline = 0;
    long num = 0;

    ExpectNotNull(conf = NCONF_new(NULL));

    ExpectIntEQ(NCONF_load(conf, confFile, &eline), 1);
    ExpectIntEQ(NCONF_get_number(conf, NULL, "port", &num), 1);
    ExpectIntEQ(num, 1234);
    ExpectIntEQ(NCONF_get_number(conf, "section2", "port", &num), 1);
    ExpectIntEQ(num, 4321);
    ExpectStrEQ(NCONF_get_string(conf, NULL, "dir"), "./test-dir");
    ExpectStrEQ(NCONF_get_string(conf, "section1", "file1_copy"),
        "./test-dir/file1");
    ExpectStrEQ(NCONF_get_string(conf, "section2", "file_list"),
        "./test-dir/file1:./test-dir/file2:./section1:file2");

    NCONF_free(conf);
#endif
    return EXPECT_RESULT();
}
#endif /* OPENSSL_ALL */

static int test_wolfSSL_X509V3_EXT_get(void) {
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_ALL) && !defined(NO_RSA)
    XFILE f = XBADFILE;
    int numOfExt =0;
    int extNid = 0;
    int i = 0;
    WOLFSSL_X509* x509 = NULL;
    WOLFSSL_X509_EXTENSION* ext = NULL;
    const WOLFSSL_v3_ext_method* method = NULL;

    ExpectTrue((f = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL));
    if (f != XBADFILE)
        XFCLOSE(f);

    /* wolfSSL_X509V3_EXT_get() return struct and nid test */
    ExpectIntEQ((numOfExt = wolfSSL_X509_get_ext_count(x509)), 5);
    for (i = 0; i < numOfExt; i++) {
        ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, i));
        ExpectIntNE((extNid = ext->obj->nid), NID_undef);
        ExpectNotNull(method = wolfSSL_X509V3_EXT_get(ext));
        ExpectIntEQ(method->ext_nid, extNid);
    }

    /* wolfSSL_X509V3_EXT_get() NULL argument test */
    ExpectNull(method = wolfSSL_X509V3_EXT_get(NULL));

    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509V3_EXT_nconf(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_ALL
    const char *ext_names[] = {
        "subjectKeyIdentifier",
        "authorityKeyIdentifier",
        "subjectAltName",
        "keyUsage",
        "extendedKeyUsage",
    };
    size_t ext_names_count = sizeof(ext_names)/sizeof(*ext_names);
    int ext_nids[] = {
        NID_subject_key_identifier,
        NID_authority_key_identifier,
        NID_subject_alt_name,
        NID_key_usage,
        NID_ext_key_usage,
    };
    size_t ext_nids_count = sizeof(ext_nids)/sizeof(*ext_nids);
    const char *ext_values[] = {
        "hash",
        "hash",
        "DNS:example.com, IP:127.0.0.1",
        "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,"
            "keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly",
        "serverAuth,clientAuth,codeSigning,emailProtection,timeStamping,"
            "OCSPSigning",
    };
    size_t i;
    X509_EXTENSION* ext = NULL;
    X509* x509 = NULL;
    unsigned int keyUsageFlags;
    unsigned int extKeyUsageFlags;

    ExpectNotNull(x509 = X509_new());

    /* keyUsage / extKeyUsage should match string above */
    keyUsageFlags = KU_DIGITAL_SIGNATURE
                  | KU_NON_REPUDIATION
                  | KU_KEY_ENCIPHERMENT
                  | KU_DATA_ENCIPHERMENT
                  | KU_KEY_AGREEMENT
                  | KU_KEY_CERT_SIGN
                  | KU_CRL_SIGN
                  | KU_ENCIPHER_ONLY
                  | KU_DECIPHER_ONLY;
    extKeyUsageFlags = XKU_SSL_CLIENT
                     | XKU_SSL_SERVER
                     | XKU_CODE_SIGN
                     | XKU_SMIME
                     | XKU_TIMESTAMP
                     | XKU_OCSP_SIGN;

    for (i = 0; i < ext_names_count; i++) {
        ExpectNotNull(ext = X509V3_EXT_nconf(NULL, NULL, ext_names[i],
            ext_values[i]));
        X509_EXTENSION_free(ext);
        ext = NULL;
    }

    for (i = 0; i < ext_nids_count; i++) {
        ExpectNotNull(ext = X509V3_EXT_nconf_nid(NULL, NULL, ext_nids[i],
            ext_values[i]));
        X509_EXTENSION_free(ext);
        ext = NULL;
    }

    /* Test adding extension to X509 */
    for (i = 0; i < ext_nids_count; i++) {
        ExpectNotNull(ext = X509V3_EXT_nconf(NULL, NULL, ext_names[i],
            ext_values[i]));
        ExpectIntEQ(X509_add_ext(x509, ext, -1), WOLFSSL_SUCCESS);

        if (ext_nids[i] == NID_key_usage) {
            ExpectIntEQ(X509_get_key_usage(x509), keyUsageFlags);
        }
        else if (ext_nids[i] == NID_ext_key_usage) {
            ExpectIntEQ(X509_get_extended_key_usage(x509), extKeyUsageFlags);
        }
        X509_EXTENSION_free(ext);
        ext = NULL;
    }
    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509V3_EXT(void) {
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_ALL) && !defined(NO_RSA)
    XFILE f = XBADFILE;
    int numOfExt = 0, nid = 0, i = 0, expected, actual = 0;
    char* str = NULL;
    unsigned char* data = NULL;
    const WOLFSSL_v3_ext_method* method = NULL;
    WOLFSSL_X509* x509 = NULL;
    WOLFSSL_X509_EXTENSION* ext = NULL;
    WOLFSSL_X509_EXTENSION* ext2 = NULL;
    WOLFSSL_ASN1_OBJECT *obj = NULL;
    WOLFSSL_ASN1_OBJECT *adObj = NULL;
    WOLFSSL_ASN1_STRING* asn1str = NULL;
    WOLFSSL_AUTHORITY_KEYID* aKeyId = NULL;
    WOLFSSL_AUTHORITY_INFO_ACCESS* aia = NULL;
    WOLFSSL_BASIC_CONSTRAINTS* bc = NULL;
    WOLFSSL_ACCESS_DESCRIPTION* ad = NULL;
    WOLFSSL_GENERAL_NAME* gn = NULL;

    /* Check NULL argument */
    ExpectNull(wolfSSL_X509V3_EXT_d2i(NULL));

    /* Using OCSP cert with X509V3 extensions */
    ExpectTrue((f = XFOPEN("./certs/ocsp/root-ca-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL));
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectIntEQ((numOfExt = wolfSSL_X509_get_ext_count(x509)), 5);

    /* Basic Constraints */
    ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, i));
    ExpectNotNull(obj = wolfSSL_X509_EXTENSION_get_object(ext));
    ExpectIntEQ((nid = wolfSSL_OBJ_obj2nid(obj)), NID_basic_constraints);
    ExpectNotNull(bc = (WOLFSSL_BASIC_CONSTRAINTS*)wolfSSL_X509V3_EXT_d2i(ext));

    ExpectIntEQ(bc->ca, 1);
    ExpectNull(bc->pathlen);
    wolfSSL_BASIC_CONSTRAINTS_free(bc);
    bc = NULL;
    i++;

    /* Subject Key Identifier */
    ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, i));
    ExpectNotNull(obj = wolfSSL_X509_EXTENSION_get_object(ext));
    ExpectIntEQ((nid = wolfSSL_OBJ_obj2nid(obj)), NID_subject_key_identifier);

    ExpectNotNull(asn1str = (WOLFSSL_ASN1_STRING*)wolfSSL_X509V3_EXT_d2i(ext));
    ExpectNotNull(ext2 = wolfSSL_X509V3_EXT_i2d(NID_subject_key_identifier, 0,
        asn1str));
    X509_EXTENSION_free(ext2);
    ext2 = NULL;
    ExpectNotNull(method = wolfSSL_X509V3_EXT_get(ext));
    ExpectNotNull(method->i2s);
    ExpectNotNull(str = method->i2s((WOLFSSL_v3_ext_method*)method, asn1str));
    wolfSSL_ASN1_STRING_free(asn1str);
    asn1str = NULL;
    if (str != NULL) {
        actual = strcmp(str,
            "73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21");
    }
    ExpectIntEQ(actual, 0);
    XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    str = NULL;
    i++;

    /* Authority Key Identifier */
    ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, i));
    ExpectNotNull(obj = wolfSSL_X509_EXTENSION_get_object(ext));
    ExpectIntEQ((nid = wolfSSL_OBJ_obj2nid(obj)), NID_authority_key_identifier);

    ExpectNotNull(aKeyId = (WOLFSSL_AUTHORITY_KEYID*)wolfSSL_X509V3_EXT_d2i(
        ext));
    ExpectNotNull(method = wolfSSL_X509V3_EXT_get(ext));
    ExpectNotNull(asn1str = aKeyId->keyid);
    ExpectNotNull(str = wolfSSL_i2s_ASN1_STRING((WOLFSSL_v3_ext_method*)method,
        asn1str));
    asn1str = NULL;
    if (str != NULL) {
        actual = strcmp(str,
            "73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21");
    }
    ExpectIntEQ(actual, 0);
    XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    str = NULL;
    wolfSSL_AUTHORITY_KEYID_free(aKeyId);
    aKeyId = NULL;
    i++;

    /* Key Usage */
    ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, i));
    ExpectNotNull(obj = wolfSSL_X509_EXTENSION_get_object(ext));
    ExpectIntEQ((nid = wolfSSL_OBJ_obj2nid(obj)), NID_key_usage);

    ExpectNotNull(asn1str = (WOLFSSL_ASN1_STRING*)wolfSSL_X509V3_EXT_d2i(ext));
    #if defined(WOLFSSL_QT)
    ExpectNotNull(data = (unsigned char*)ASN1_STRING_get0_data(asn1str));
    #else
    ExpectNotNull(data = wolfSSL_ASN1_STRING_data(asn1str));
    #endif
    expected = KEYUSE_KEY_CERT_SIGN | KEYUSE_CRL_SIGN;
    if (data != NULL) {
    #ifdef BIG_ENDIAN_ORDER
        actual = data[1];
    #else
        actual = data[0];
    #endif
    }
    ExpectIntEQ(actual, expected);
    wolfSSL_ASN1_STRING_free(asn1str);
    asn1str = NULL;
#if 1
    i++;

    /* Authority Info Access */
    ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, i));
    ExpectNotNull(obj = wolfSSL_X509_EXTENSION_get_object(ext));
    ExpectIntEQ((nid = wolfSSL_OBJ_obj2nid(obj)), NID_info_access);
    ExpectNotNull(aia = (WOLFSSL_AUTHORITY_INFO_ACCESS*)wolfSSL_X509V3_EXT_d2i(
        ext));
#if defined(WOLFSSL_QT)
    ExpectIntEQ(OPENSSL_sk_num(aia), 1); /* Only one URI entry for this cert */
#else
    ExpectIntEQ(wolfSSL_sk_num(aia), 1); /* Only one URI entry for this cert */
#endif
    /* URI entry is an ACCESS_DESCRIPTION type */
#if defined(WOLFSSL_QT)
    ExpectNotNull(ad = (WOLFSSL_ACCESS_DESCRIPTION*)wolfSSL_sk_value(aia, 0));
#else
    ExpectNotNull(ad = (WOLFSSL_ACCESS_DESCRIPTION*)OPENSSL_sk_value(aia, 0));
#endif
    ExpectNotNull(adObj = ad->method);
    /* Make sure nid is OCSP */
    ExpectIntEQ(wolfSSL_OBJ_obj2nid(adObj), NID_ad_OCSP);

    /* GENERAL_NAME stores URI as an ASN1_STRING */
    ExpectNotNull(gn = ad->location);
    ExpectIntEQ(gn->type, GEN_URI); /* Type should always be GEN_URI */
    ExpectNotNull(asn1str = gn->d.uniformResourceIdentifier);
    ExpectIntEQ(wolfSSL_ASN1_STRING_length(asn1str), 22);
#if defined(WOLFSSL_QT)
    ExpectNotNull(str = (char*)ASN1_STRING_get0_data(asn1str));
#else
    ExpectNotNull(str = (char*)wolfSSL_ASN1_STRING_data(asn1str));
#endif
    if (str != NULL) {
         actual = strcmp(str, "http://127.0.0.1:22220");
    }
    ExpectIntEQ(actual, 0);

    wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
    aia = NULL;
#else
    (void) aia; (void) ad; (void) adObj; (void) gn;
#endif
    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_get_extension_flags(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA)
    XFILE f = XBADFILE;
    X509* x509 = NULL;
    unsigned int extFlags;
    unsigned int keyUsageFlags;
    unsigned int extKeyUsageFlags;

    /* client-int-cert.pem has the following extension flags. */
    extFlags = EXFLAG_KUSAGE | EXFLAG_XKUSAGE;
    /* and the following key usage flags. */
    keyUsageFlags = KU_DIGITAL_SIGNATURE
                  | KU_NON_REPUDIATION
                  | KU_KEY_ENCIPHERMENT;
    /* and the following extended key usage flags. */
    extKeyUsageFlags = XKU_SSL_CLIENT | XKU_SMIME;

    ExpectTrue((f = XFOPEN("./certs/intermediate/client-int-cert.pem", "rb")) !=
        XBADFILE);
    ExpectNotNull(x509 = PEM_read_X509(f, NULL, NULL, NULL));
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }
    ExpectIntEQ(X509_get_extension_flags(x509), extFlags);
    ExpectIntEQ(X509_get_key_usage(x509), keyUsageFlags);
    ExpectIntEQ(X509_get_extended_key_usage(x509), extKeyUsageFlags);
    X509_free(x509);
    x509 = NULL;

    /* client-cert-ext.pem has the following extension flags. */
    extFlags = EXFLAG_KUSAGE;
    /* and the following key usage flags. */
    keyUsageFlags = KU_DIGITAL_SIGNATURE
                  | KU_KEY_CERT_SIGN
                  | KU_CRL_SIGN;

    ExpectTrue((f = fopen("./certs/client-cert-ext.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = PEM_read_X509(f, NULL, NULL, NULL));
    if (f != XBADFILE)
        XFCLOSE(f);
    ExpectIntEQ(X509_get_extension_flags(x509), extFlags);
    ExpectIntEQ(X509_get_key_usage(x509), keyUsageFlags);
    X509_free(x509);
#endif /* OPENSSL_ALL */
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_get_ext(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_ALL) && !defined(NO_RSA)
    int ret = 0;
    XFILE f = XBADFILE;
    WOLFSSL_X509* x509 = NULL;
    WOLFSSL_X509_EXTENSION* foundExtension;

    ExpectTrue((f = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL));
    if (f != XBADFILE)
        XFCLOSE(f);
    ExpectIntEQ((ret = wolfSSL_X509_get_ext_count(x509)), 5);

    /* wolfSSL_X509_get_ext() valid input */
    ExpectNotNull(foundExtension = wolfSSL_X509_get_ext(x509, 0));

    /* wolfSSL_X509_get_ext() valid x509, idx out of bounds */
    ExpectNull(foundExtension = wolfSSL_X509_get_ext(x509, -1));
    ExpectNull(foundExtension = wolfSSL_X509_get_ext(x509, 100));

    /* wolfSSL_X509_get_ext() NULL x509, idx out of bounds */
    ExpectNull(foundExtension = wolfSSL_X509_get_ext(NULL, -1));
    ExpectNull(foundExtension = wolfSSL_X509_get_ext(NULL, 100));

    /* wolfSSL_X509_get_ext() NULL x509, valid idx */
    ExpectNull(foundExtension = wolfSSL_X509_get_ext(NULL, 0));

    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_get_ext_by_NID(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA)
    int rc = 0;
    XFILE f = XBADFILE;
    WOLFSSL_X509* x509 = NULL;
    ASN1_OBJECT* obj = NULL;

    ExpectTrue((f = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL));
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectIntGE(rc = wolfSSL_X509_get_ext_by_NID(x509, NID_basic_constraints,
        -1), 0);

    /* Start search from last location (should fail) */
    ExpectIntGE(rc = wolfSSL_X509_get_ext_by_NID(x509, NID_basic_constraints,
        rc), -1);

    ExpectIntGE(rc = wolfSSL_X509_get_ext_by_NID(x509, NID_basic_constraints,
        -2), -1);

    ExpectIntEQ(rc = wolfSSL_X509_get_ext_by_NID(NULL, NID_basic_constraints,
        -1), -1);

    ExpectIntEQ(rc = wolfSSL_X509_get_ext_by_NID(x509, NID_undef, -1), -1);

    /* NID_ext_key_usage, check also its nid and oid */
    ExpectIntGT(rc = wolfSSL_X509_get_ext_by_NID(x509, NID_ext_key_usage, -1),
        -1);
    ExpectNotNull(obj = wolfSSL_X509_EXTENSION_get_object(wolfSSL_X509_get_ext(
        x509, rc)));
    ExpectIntEQ(obj->nid, NID_ext_key_usage);
    ExpectIntEQ(obj->type, EXT_KEY_USAGE_OID);

    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_get_ext_subj_alt_name(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA)
    int rc = 0;
    XFILE f = XBADFILE;
    WOLFSSL_X509* x509 = NULL;
    WOLFSSL_X509_EXTENSION* ext = NULL;
    WOLFSSL_ASN1_STRING* sanString = NULL;
    byte* sanDer = NULL;

    const byte expectedDer[] = {
        0x30, 0x13, 0x82, 0x0b, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
        0x63, 0x6f, 0x6d, 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01};

    ExpectTrue((f = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = PEM_read_X509(f, NULL, NULL, NULL));
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectIntNE(rc = X509_get_ext_by_NID(x509, NID_subject_alt_name, -1), -1);
    ExpectNotNull(ext = X509_get_ext(x509, rc));
    ExpectNotNull(sanString = X509_EXTENSION_get_data(ext));
    ExpectIntEQ(ASN1_STRING_length(sanString), sizeof(expectedDer));
    ExpectNotNull(sanDer = ASN1_STRING_data(sanString));
    ExpectIntEQ(XMEMCMP(sanDer, expectedDer, sizeof(expectedDer)), 0);

    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_EXTENSION_new(void)
{
    EXPECT_DECLS;
#if defined (OPENSSL_ALL)
    WOLFSSL_X509_EXTENSION* ext = NULL;

    ExpectNotNull(ext = wolfSSL_X509_EXTENSION_new());
    ExpectNotNull(ext->obj = wolfSSL_ASN1_OBJECT_new());

    wolfSSL_X509_EXTENSION_free(ext);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_EXTENSION_get_object(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_ALL) && !defined(NO_RSA)
    WOLFSSL_X509* x509 = NULL;
    WOLFSSL_X509_EXTENSION* ext = NULL;
    WOLFSSL_ASN1_OBJECT* o = NULL;
    XFILE file = XBADFILE;

    ExpectTrue((file = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(file, NULL, NULL, NULL));
    if (file != XBADFILE)
        XFCLOSE(file);

    /* wolfSSL_X509_EXTENSION_get_object() testing ext idx 0 */
    ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, 0));
    ExpectNull(wolfSSL_X509_EXTENSION_get_object(NULL));
    ExpectNotNull(o = wolfSSL_X509_EXTENSION_get_object(ext));
    ExpectIntEQ(o->nid, 128);

    /* wolfSSL_X509_EXTENSION_get_object() NULL argument */
    ExpectNull(o = wolfSSL_X509_EXTENSION_get_object(NULL));

    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_EXTENSION_get_data(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_ALL) && !defined(NO_RSA)
    WOLFSSL_X509* x509 = NULL;
    WOLFSSL_X509_EXTENSION* ext = NULL;
    WOLFSSL_ASN1_STRING* str = NULL;
    XFILE file = XBADFILE;

    ExpectTrue((file = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(file, NULL, NULL, NULL));
    if (file != XBADFILE)
        XFCLOSE(file);
    ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, 0));

    ExpectNull(str = wolfSSL_X509_EXTENSION_get_data(NULL));
    ExpectNotNull(str = wolfSSL_X509_EXTENSION_get_data(ext));

    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_EXTENSION_get_critical(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_ALL) && !defined(NO_RSA)
    WOLFSSL_X509* x509 = NULL;
    WOLFSSL_X509_EXTENSION* ext = NULL;
    XFILE file = XBADFILE;
    int crit = 0;

    ExpectTrue((file = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
    ExpectNotNull(x509 = wolfSSL_PEM_read_X509(file, NULL, NULL, NULL));
    if (file != XBADFILE)
        XFCLOSE(file);
    ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, 0));

    ExpectIntEQ(crit = wolfSSL_X509_EXTENSION_get_critical(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(crit = wolfSSL_X509_EXTENSION_get_critical(ext), 0);

    wolfSSL_X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509V3_EXT_print(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_ALL) && !defined(NO_BIO) && \
    !defined(NO_RSA)

    {
        XFILE f = XBADFILE;
        WOLFSSL_X509* x509 = NULL;
        X509_EXTENSION * ext = NULL;
        int loc = 0;
        BIO *bio = NULL;

        ExpectTrue((f = XFOPEN(svrCertFile, "rb")) != XBADFILE);
        ExpectNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL));
        if (f != XBADFILE)
            fclose(f);

        ExpectNotNull(bio = wolfSSL_BIO_new(BIO_s_mem()));

        ExpectIntGT(loc = wolfSSL_X509_get_ext_by_NID(x509,
            NID_basic_constraints, -1), -1);
        ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, loc));
        ExpectIntEQ(wolfSSL_X509V3_EXT_print(bio, ext, 0, 0), WOLFSSL_SUCCESS);

        ExpectIntGT(loc = wolfSSL_X509_get_ext_by_NID(x509,
            NID_subject_key_identifier, -1), -1);
        ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, loc));
        ExpectIntEQ(wolfSSL_X509V3_EXT_print(bio, ext, 0, 0), WOLFSSL_SUCCESS);

        ExpectIntGT(loc = wolfSSL_X509_get_ext_by_NID(x509,
            NID_authority_key_identifier, -1), -1);
        ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, loc));
        ExpectIntEQ(wolfSSL_X509V3_EXT_print(bio, ext, 0, 0), WOLFSSL_SUCCESS);

        wolfSSL_BIO_free(bio);
        wolfSSL_X509_free(x509);
    }

    {
        X509 *x509 = NULL;
        BIO *bio = NULL;
        X509_EXTENSION *ext = NULL;
        unsigned int i = 0;
        unsigned int idx = 0;
        /* Some NIDs to test with */
        int nids[] = {
                /* NID_key_usage, currently X509_get_ext returns this as a bit
                 * string, which messes up X509V3_EXT_print */
                /* NID_ext_key_usage, */
                NID_subject_alt_name,
        };
        int* n = NULL;

        ExpectNotNull(bio = BIO_new_fp(stderr, BIO_NOCLOSE));

        ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFileExt,
            WOLFSSL_FILETYPE_PEM));

        ExpectIntGT(fprintf(stderr, "\nPrinting extension values:\n"), 0);

        for (i = 0, n = nids; i<(sizeof(nids)/sizeof(int)); i++, n++) {
            /* X509_get_ext_by_NID should return 3 for now. If that changes then
             * update the index */
            ExpectIntEQ((idx = X509_get_ext_by_NID(x509, *n, -1)), 3);
            ExpectNotNull(ext = X509_get_ext(x509, (int)idx));
            ExpectIntEQ(X509V3_EXT_print(bio, ext, 0, 0), 1);
            ExpectIntGT(fprintf(stderr, "\n"), 0);
        }

        BIO_free(bio);
        X509_free(x509);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_cmp(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA)
    XFILE file1 = XBADFILE;
    XFILE file2 = XBADFILE;
    WOLFSSL_X509* cert1 = NULL;
    WOLFSSL_X509* cert2 = NULL;

    ExpectTrue((file1 = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
    ExpectTrue((file2 = XFOPEN("./certs/3072/client-cert.pem", "rb")) !=
        XBADFILE);

    ExpectNotNull(cert1 = wolfSSL_PEM_read_X509(file1, NULL, NULL, NULL));
    ExpectNotNull(cert2 = wolfSSL_PEM_read_X509(file2, NULL, NULL, NULL));
    if (file1 != XBADFILE)
        fclose(file1);
    if (file2 != XBADFILE)
        fclose(file2);

    /* wolfSSL_X509_cmp() testing matching certs */
    ExpectIntEQ(0, wolfSSL_X509_cmp(cert1, cert1));

    /* wolfSSL_X509_cmp() testing mismatched certs */
    ExpectIntEQ(-1, wolfSSL_X509_cmp(cert1, cert2));

    /* wolfSSL_X509_cmp() testing NULL, valid args */
    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wolfSSL_X509_cmp(NULL, cert2));

    /* wolfSSL_X509_cmp() testing valid, NULL args */
    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wolfSSL_X509_cmp(cert1, NULL));

    /* wolfSSL_X509_cmp() testing NULL, NULL args */
    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wolfSSL_X509_cmp(NULL, NULL));

    wolfSSL_X509_free(cert1);
    wolfSSL_X509_free(cert2);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_up_ref(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL)
    EVP_PKEY* pkey;

    pkey = EVP_PKEY_new();
    ExpectNotNull(pkey);
    ExpectIntEQ(EVP_PKEY_up_ref(NULL), 0);
    ExpectIntEQ(EVP_PKEY_up_ref(pkey), 1);
    EVP_PKEY_free(pkey);
    ExpectIntEQ(EVP_PKEY_up_ref(pkey), 1);
    EVP_PKEY_free(pkey);
    EVP_PKEY_free(pkey);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_d2i_and_i2d_PublicKey(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    EVP_PKEY* pkey = NULL;
    const unsigned char* p;
    unsigned char *der = NULL;
    unsigned char *tmp = NULL;
    int derLen;

    p = client_keypub_der_2048;
    /* Check that key can be successfully decoded. */
    ExpectNotNull(pkey = wolfSSL_d2i_PublicKey(EVP_PKEY_RSA, NULL, &p,
        sizeof_client_keypub_der_2048));
    /* Check that key can be successfully encoded. */
    ExpectIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &der)), 0);
    /* Ensure that the encoded version matches the original. */
    ExpectIntEQ(derLen, sizeof_client_keypub_der_2048);
    ExpectIntEQ(XMEMCMP(der, client_keypub_der_2048, derLen), 0);

    /* Do same test except with pre-allocated buffer to ensure the der pointer
     * is advanced. */
    tmp = der;
    ExpectIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &tmp)), 0);
    ExpectIntEQ(derLen, sizeof_client_keypub_der_2048);
    ExpectIntEQ(XMEMCMP(der, client_keypub_der_2048, derLen), 0);
    ExpectTrue(der + derLen == tmp);

    XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
    EVP_PKEY_free(pkey);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_d2i_and_i2d_PublicKey_ecc(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && !defined(NO_CERTS) && \
    !defined(NO_ASN) && !defined(NO_PWDBASED)
    EVP_PKEY* pkey = NULL;
    const unsigned char* p;
    unsigned char *der = NULL;
    unsigned char *tmp = NULL;
    int derLen;
    unsigned char pub_buf[65];
    const int pub_len = 65;
    BN_CTX* ctx;
    EC_GROUP* curve = NULL;
    EC_KEY* ephemeral_key = NULL;
    const EC_POINT* h = NULL;

    /* Generate an x963 key pair and get public part into pub_buf */
    ExpectNotNull(ctx = BN_CTX_new());
    ExpectNotNull(curve = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
    ExpectNotNull(ephemeral_key = EC_KEY_new_by_curve_name(
        NID_X9_62_prime256v1));
    ExpectIntEQ(EC_KEY_generate_key(ephemeral_key), 1);
    ExpectNotNull(h = EC_KEY_get0_public_key(ephemeral_key));
    ExpectIntEQ(pub_len, EC_POINT_point2oct(curve, h,
        POINT_CONVERSION_UNCOMPRESSED, pub_buf, pub_len, ctx));
    /* Prepare the EVP_PKEY */
    ExpectNotNull(pkey = EVP_PKEY_new());

    p = pub_buf;
    /* Check that key can be successfully decoded. */
    ExpectNotNull(wolfSSL_d2i_PublicKey(EVP_PKEY_EC, &pkey, &p,
        pub_len));

    /* Check that key can be successfully encoded. */
    ExpectIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &der)), 0);
    /* Ensure that the encoded version matches the original. */
    ExpectIntEQ(derLen, pub_len);
    ExpectIntEQ(XMEMCMP(der, pub_buf, derLen), 0);

    /* Do same test except with pre-allocated buffer to ensure the der pointer
     * is advanced. */
    tmp = der;
    ExpectIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &tmp)), 0);
    ExpectIntEQ(derLen, pub_len);
    ExpectIntEQ(XMEMCMP(der, pub_buf, derLen), 0);
    ExpectTrue(der + derLen == tmp);

    XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
    EVP_PKEY_free(pkey);
    EC_KEY_free(ephemeral_key);
    EC_GROUP_free(curve);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_d2i_and_i2d_DSAparams(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DSA)
    DSA* dsa = NULL;
    byte derIn[] = {
        0x30, 0x82, 0x01, 0x1f, 0x02, 0x81, 0x81, 0x00,
        0xcd, 0xde, 0x25, 0x68, 0x80, 0x53, 0x0d, 0xe5,
        0x77, 0xd6, 0xd2, 0x90, 0x39, 0x3f, 0x90, 0xa2,
        0x3f, 0x33, 0x94, 0x6e, 0xe8, 0x4f, 0x2b, 0x63,
        0xab, 0x30, 0xab, 0x15, 0xba, 0x11, 0xea, 0x8a,
        0x5d, 0x8d, 0xcc, 0xb8, 0xd4, 0xa1, 0xd5, 0xc1,
        0x47, 0x9d, 0x5a, 0x73, 0x6a, 0x62, 0x49, 0xd1,
        0x06, 0x07, 0x67, 0xf6, 0x2f, 0xa3, 0x39, 0xbd,
        0x4e, 0x0d, 0xb4, 0xd3, 0x22, 0x23, 0x84, 0xec,
        0x93, 0x26, 0x5a, 0x49, 0xee, 0x7c, 0x89, 0x48,
        0x66, 0x4d, 0xe8, 0xe8, 0xd8, 0x50, 0xfb, 0xa5,
        0x71, 0x9f, 0x22, 0x18, 0xe5, 0xe6, 0x0b, 0x46,
        0x87, 0x66, 0xee, 0x52, 0x8f, 0x46, 0x4f, 0xb5,
        0x03, 0xce, 0xed, 0xe3, 0xbe, 0xe5, 0xb5, 0x81,
        0xd2, 0x59, 0xe9, 0xc0, 0xad, 0x4d, 0xd0, 0x4d,
        0x26, 0xf7, 0xba, 0x50, 0xe8, 0xc9, 0x8f, 0xfe,
        0x24, 0x19, 0x3d, 0x2e, 0xa7, 0x52, 0x3c, 0x6d,
        0x02, 0x15, 0x00, 0xfb, 0x47, 0xfb, 0xec, 0x81,
        0x20, 0xc8, 0x1c, 0xe9, 0x4a, 0xba, 0x04, 0x6f,
        0x19, 0x9b, 0x94, 0xee, 0x82, 0x67, 0xd3, 0x02,
        0x81, 0x81, 0x00, 0x9b, 0x95, 0xbb, 0x85, 0xc5,
        0x58, 0x4a, 0x32, 0x9c, 0xaa, 0x44, 0x85, 0xd6,
        0x68, 0xdc, 0x3e, 0x14, 0xf4, 0xce, 0x6d, 0xa3,
        0x49, 0x38, 0xea, 0xd6, 0x61, 0x48, 0x92, 0x5a,
        0x40, 0x95, 0x49, 0x38, 0xaa, 0xe1, 0x39, 0x29,
        0x68, 0x58, 0x47, 0x8a, 0x4b, 0x01, 0xe1, 0x2e,
        0x8e, 0x6c, 0x63, 0x6f, 0x40, 0xca, 0x50, 0x3f,
        0x8c, 0x0b, 0x99, 0xe4, 0x72, 0x42, 0xb8, 0xb1,
        0xc2, 0x26, 0x48, 0xf1, 0x9c, 0x83, 0xc6, 0x37,
        0x2e, 0x5a, 0xae, 0x11, 0x09, 0xd9, 0xf3, 0xad,
        0x1f, 0x6f, 0xad, 0xad, 0x50, 0xe3, 0x78, 0x32,
        0xe6, 0xde, 0x8e, 0xaa, 0xbf, 0xd1, 0x00, 0x9f,
        0xb3, 0x02, 0x12, 0x19, 0xa2, 0x15, 0xec, 0x14,
        0x18, 0x5c, 0x0e, 0x26, 0xce, 0xf9, 0xae, 0xcc,
        0x7b, 0xb5, 0xd1, 0x26, 0xfc, 0x85, 0xfe, 0x14,
        0x93, 0xb6, 0x9d, 0x7d, 0x76, 0xe3, 0x35, 0x97,
        0x1e, 0xde, 0xc4
    };
    int derInLen = sizeof(derIn);
    byte* derOut = NULL;
    int derOutLen;
    byte* p = derIn;

    /* Check that params can be successfully decoded. */
    ExpectNotNull(dsa = d2i_DSAparams(NULL, (const byte**)&p, derInLen));
    /* Check that params can be successfully encoded. */
    ExpectIntGE((derOutLen = i2d_DSAparams(dsa, &derOut)), 0);
    /* Ensure that the encoded version matches the original. */
    ExpectIntEQ(derInLen, derOutLen);
    ExpectIntEQ(XMEMCMP(derIn, derOut, derInLen), 0);

    XFREE(derOut, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
    DSA_free(dsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2d_PrivateKey(void)
{
    EXPECT_DECLS;
#if (!defined(NO_RSA) || defined(HAVE_ECC)) && defined(OPENSSL_EXTRA) && \
    !defined(NO_ASN) && !defined(NO_PWDBASED)

#if !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048)
    {
        EVP_PKEY* pkey = NULL;
        const unsigned char* server_key =
            (const unsigned char*)server_key_der_2048;
        unsigned char buf[FOURK_BUF];
        unsigned char* pt = NULL;
        int bufSz = 0;

        ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &server_key,
            (long)sizeof_server_key_der_2048));
        ExpectIntEQ(i2d_PrivateKey(pkey, NULL), 1193);
        pt = buf;
        ExpectIntEQ((bufSz = i2d_PrivateKey(pkey, &pt)), 1193);
        ExpectIntNE((pt - buf), 0);
        ExpectIntEQ(XMEMCMP(buf, server_key_der_2048, bufSz), 0);
        EVP_PKEY_free(pkey);
    }
#endif
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
    {
        EVP_PKEY* pkey = NULL;
        const unsigned char* client_key =
            (const unsigned char*)ecc_clikey_der_256;
        unsigned char buf[FOURK_BUF];
        unsigned char* pt = NULL;
        int bufSz = 0;

        ExpectNotNull((pkey = d2i_PrivateKey(EVP_PKEY_EC, NULL, &client_key,
            (long)sizeof_ecc_clikey_der_256)));
        ExpectIntEQ(i2d_PrivateKey(pkey, NULL), 121);
        pt = buf;
        ExpectIntEQ((bufSz = i2d_PrivateKey(pkey, &pt)), 121);
        ExpectIntNE((pt - buf), 0);
        ExpectIntEQ(XMEMCMP(buf, ecc_clikey_der_256, bufSz), 0);
        EVP_PKEY_free(pkey);
    }
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OCSP_id_get0_info(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && \
    defined(HAVE_OCSP) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    X509* cert = NULL;
    X509* issuer = NULL;
    OCSP_CERTID* id = NULL;
    OCSP_CERTID* id2 = NULL;

    ASN1_STRING* name = NULL;
    ASN1_OBJECT* pmd  = NULL;
    ASN1_STRING* keyHash = NULL;
    ASN1_INTEGER* serial = NULL;
    ASN1_INTEGER* x509Int = NULL;

    ExpectNotNull(cert = wolfSSL_X509_load_certificate_file(svrCertFile,
        SSL_FILETYPE_PEM));
    ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caCertFile,
        SSL_FILETYPE_PEM));

    ExpectNotNull(id = OCSP_cert_to_id(NULL, cert, issuer));
    ExpectNotNull(id2 = OCSP_cert_to_id(NULL, cert, issuer));

    ExpectIntEQ(OCSP_id_get0_info(NULL, NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(OCSP_id_get0_info(NULL, NULL, NULL, NULL, id), 1);

    /* name, pmd, keyHash not supported yet, expect failure if not NULL */
    ExpectIntEQ(OCSP_id_get0_info(&name, NULL, NULL, NULL, id), 0);
    ExpectIntEQ(OCSP_id_get0_info(NULL, &pmd, NULL, NULL, id), 0);
    ExpectIntEQ(OCSP_id_get0_info(NULL, NULL, &keyHash, NULL, id), 0);

    ExpectIntEQ(OCSP_id_get0_info(NULL, NULL, NULL, &serial, id), 1);
    ExpectNotNull(serial);

    /* compare serial number to one in cert, should be equal */
    ExpectNotNull(x509Int = X509_get_serialNumber(cert));
    ExpectIntEQ(x509Int->length, serial->length);
    ExpectIntEQ(XMEMCMP(x509Int->data, serial->data, serial->length), 0);

    /* test OCSP_id_cmp */
    ExpectIntNE(OCSP_id_cmp(NULL, NULL), 0);
    ExpectIntNE(OCSP_id_cmp(id, NULL), 0);
    ExpectIntNE(OCSP_id_cmp(NULL, id2), 0);
    ExpectIntEQ(OCSP_id_cmp(id, id2), 0);
    if (id != NULL) {
        id->issuerHash[0] = ~id->issuerHash[0];
    }
    ExpectIntNE(OCSP_id_cmp(id, id2), 0);

    OCSP_CERTID_free(id);
    OCSP_CERTID_free(id2);
    X509_free(cert); /* free's x509Int */
    X509_free(issuer);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2d_OCSP_CERTID(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && defined(HAVE_OCSP)
    WOLFSSL_OCSP_CERTID certId;
    byte* targetBuffer = NULL;
    byte* p;
    /* OCSP CertID bytes taken from PCAP */
    byte rawCertId[] = {
        0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
        0x00, 0x04, 0x14, 0x80, 0x51, 0x06, 0x01, 0x32, 0xad, 0x9a, 0xc2, 0x7d,
        0x51, 0x87, 0xa0, 0xe8, 0x87, 0xfb, 0x01, 0x62, 0x01, 0x55, 0xee, 0x04,
        0x14, 0x03, 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb, 0x66, 0xf0, 0xa3,
        0xe2, 0x1b, 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55, 0x02, 0x10, 0x01,
        0xfd, 0xa3, 0xeb, 0x6e, 0xca, 0x75, 0xc8, 0x88, 0x43, 0x8b, 0x72, 0x4b,
        0xcf, 0xbc, 0x91
    };
    int ret = 0;
    int i;

    XMEMSET(&certId, 0, sizeof(WOLFSSL_OCSP_CERTID));
    certId.rawCertId = rawCertId;
    certId.rawCertIdSize = sizeof(rawCertId);

    ExpectNotNull(targetBuffer = (byte*)XMALLOC(sizeof(rawCertId), NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    p = targetBuffer;
    /* Function returns the size of the encoded data. */
    ExpectIntEQ(ret = wolfSSL_i2d_OCSP_CERTID(&certId, &p), sizeof(rawCertId));
    /* If target buffer is not null, function increments targetBuffer to point
     * just past the end of the encoded data. */
    ExpectPtrEq(p, (targetBuffer + sizeof(rawCertId)));
    for (i = 0; EXPECT_SUCCESS() && i < ret; ++i) {
        ExpectIntEQ(targetBuffer[i], rawCertId[i]);
    }
    XFREE(targetBuffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    targetBuffer = NULL;

    /* If target buffer is null, function allocates memory for a buffer and
     * copies the encoded data into it. targetBuffer then points to the start of
     * this newly allocate buffer. */
    ExpectIntEQ(ret = wolfSSL_i2d_OCSP_CERTID(&certId, &targetBuffer),
        sizeof(rawCertId));
    for (i = 0; EXPECT_SUCCESS() && i < ret; ++i) {
        ExpectIntEQ(targetBuffer[i], rawCertId[i]);
    }
    XFREE(targetBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_d2i_OCSP_CERTID(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && defined(HAVE_OCSP)
    WOLFSSL_OCSP_CERTID* certId;
    WOLFSSL_OCSP_CERTID* certIdGood;
    WOLFSSL_OCSP_CERTID* certIdBad;
    const unsigned char* rawCertIdPtr;

    const unsigned char rawCertId[] = {
        0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
        0x00, 0x04, 0x14, 0x80, 0x51, 0x06, 0x01, 0x32, 0xad, 0x9a, 0xc2, 0x7d,
        0x51, 0x87, 0xa0, 0xe8, 0x87, 0xfb, 0x01, 0x62, 0x01, 0x55, 0xee, 0x04,
        0x14, 0x03, 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb, 0x66, 0xf0, 0xa3,
        0xe2, 0x1b, 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55, 0x02, 0x10, 0x01,
        0xfd, 0xa3, 0xeb, 0x6e, 0xca, 0x75, 0xc8, 0x88, 0x43, 0x8b, 0x72, 0x4b,
        0xcf, 0xbc, 0x91
    };

    rawCertIdPtr = &rawCertId[0];

    /* If the cert ID is NULL the function should allocate it and copy the
     * data to it. */
    certId = NULL;
    ExpectNotNull(certId = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr,
        sizeof(rawCertId)));
    ExpectIntEQ(certId->rawCertIdSize, sizeof(rawCertId));
    if (certId != NULL) {
        XFREE(certId->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
        XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
    }

    /* If the cert ID is not NULL the function will just copy the data to it. */
    ExpectNotNull(certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(*certId), NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectNotNull(certId);
    ExpectNotNull(XMEMSET(certId, 0, sizeof(*certId)));

    /* Reset rawCertIdPtr since it was push forward in the previous call. */
    rawCertIdPtr = &rawCertId[0];
    ExpectNotNull(certIdGood = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr,
        sizeof(rawCertId)));
    ExpectPtrEq(certIdGood, certId);
    ExpectIntEQ(certId->rawCertIdSize, sizeof(rawCertId));
    if (certId != NULL) {
        XFREE(certId->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
        XFREE(certId, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        certId = NULL;
    }

    /* The below tests should fail when passed bad parameters. NULL should
     * always be returned. */
    ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(NULL, &rawCertIdPtr,
        sizeof(rawCertId)));
    ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(&certId, NULL,
        sizeof(rawCertId)));
    ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr, 0));
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OCSP_id_cmp(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_OCSP)
    OCSP_CERTID id1;
    OCSP_CERTID id2;

    XMEMSET(&id1, 0, sizeof(id1));
    XMEMSET(&id2, 0, sizeof(id2));
    ExpectIntEQ(OCSP_id_cmp(&id1, &id2), 0);
    ExpectIntNE(OCSP_id_cmp(NULL, NULL), 0);
    ExpectIntNE(OCSP_id_cmp(&id1, NULL), 0);
    ExpectIntNE(OCSP_id_cmp(NULL, &id2), 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OCSP_SINGLERESP_get0_id(void)
{
    EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA)
    WOLFSSL_OCSP_SINGLERESP single;
    const WOLFSSL_OCSP_CERTID* certId;

    XMEMSET(&single, 0, sizeof(single));

    certId = wolfSSL_OCSP_SINGLERESP_get0_id(&single);
    ExpectPtrEq(&single, certId);

    ExpectNull(wolfSSL_OCSP_SINGLERESP_get0_id(NULL));
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OCSP_single_get0_status(void)
{
    EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_OCSP_PARSE_STATUS)
    WOLFSSL_OCSP_SINGLERESP single;
    CertStatus certStatus;
    WOLFSSL_ASN1_TIME* thisDate;
    WOLFSSL_ASN1_TIME* nextDate;
    int ret, i;

    XMEMSET(&single,     0, sizeof(WOLFSSL_OCSP_SINGLERESP));
    XMEMSET(&certStatus, 0, sizeof(CertStatus));

    /* Fill the date fields with some dummy data. */
    for (i = 0; i < CTC_DATE_SIZE; ++i) {
        certStatus.thisDateParsed.data[i] = i;
        certStatus.nextDateParsed.data[i] = i;
    }
    certStatus.status = CERT_GOOD;
    single.status = &certStatus;

    ret = wolfSSL_OCSP_single_get0_status(&single, NULL, NULL, &thisDate,
                                          &nextDate);
    ExpectIntEQ(ret, CERT_GOOD);
    ExpectPtrEq(thisDate, &certStatus.thisDateParsed);
    ExpectPtrEq(nextDate, &certStatus.nextDateParsed);

    ExpectIntEQ(wolfSSL_OCSP_single_get0_status(NULL, NULL, NULL, NULL, NULL),
        CERT_GOOD);
    ExpectIntEQ(wolfSSL_OCSP_single_get0_status(&single, NULL, NULL, NULL,
        NULL), CERT_GOOD);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OCSP_resp_count(void)
{
    EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA)
    WOLFSSL_OCSP_BASICRESP basicResp;
    WOLFSSL_OCSP_SINGLERESP singleRespOne;
    WOLFSSL_OCSP_SINGLERESP singleRespTwo;

    XMEMSET(&basicResp,     0, sizeof(WOLFSSL_OCSP_BASICRESP));
    XMEMSET(&singleRespOne, 0, sizeof(WOLFSSL_OCSP_SINGLERESP));
    XMEMSET(&singleRespTwo, 0, sizeof(WOLFSSL_OCSP_SINGLERESP));

    ExpectIntEQ(wolfSSL_OCSP_resp_count(&basicResp), 0);
    basicResp.single = &singleRespOne;
    ExpectIntEQ(wolfSSL_OCSP_resp_count(&basicResp), 1);
    singleRespOne.next = &singleRespTwo;
    ExpectIntEQ(wolfSSL_OCSP_resp_count(&basicResp), 2);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OCSP_resp_get0(void)
{
    EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA)
    WOLFSSL_OCSP_BASICRESP basicResp;
    WOLFSSL_OCSP_SINGLERESP singleRespOne;
    WOLFSSL_OCSP_SINGLERESP singleRespTwo;

    XMEMSET(&basicResp,     0, sizeof(WOLFSSL_OCSP_BASICRESP));
    XMEMSET(&singleRespOne, 0, sizeof(WOLFSSL_OCSP_SINGLERESP));
    XMEMSET(&singleRespTwo, 0, sizeof(WOLFSSL_OCSP_SINGLERESP));

    basicResp.single = &singleRespOne;
    singleRespOne.next = &singleRespTwo;
    ExpectPtrEq(wolfSSL_OCSP_resp_get0(&basicResp, 0), &singleRespOne);
    ExpectPtrEq(wolfSSL_OCSP_resp_get0(&basicResp, 1), &singleRespTwo);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_OCSP_parse_url(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_OCSP)
#define CK_OPU_OK(u, h, po, pa, s) do { \
    char* host = NULL; \
    char* port = NULL; \
    char* path = NULL; \
    int isSsl = 0; \
    ExpectIntEQ(OCSP_parse_url(u, &host, &port, &path, &isSsl), 1); \
    ExpectStrEQ(host, h); \
    ExpectStrEQ(port, po); \
    ExpectStrEQ(path, pa); \
    ExpectIntEQ(isSsl, s); \
    XFREE(host, NULL, DYNAMIC_TYPE_OPENSSL); \
    XFREE(port, NULL, DYNAMIC_TYPE_OPENSSL); \
    XFREE(path, NULL, DYNAMIC_TYPE_OPENSSL); \
} while(0)

#define CK_OPU_FAIL(u) do { \
    char* host = NULL; \
    char* port = NULL; \
    char* path = NULL; \
    int isSsl = 0; \
    ExpectIntEQ(OCSP_parse_url(u, &host, &port, &path, &isSsl), 0); \
    XFREE(host, NULL, DYNAMIC_TYPE_OPENSSL); \
    XFREE(port, NULL, DYNAMIC_TYPE_OPENSSL); \
    XFREE(path, NULL, DYNAMIC_TYPE_OPENSSL); \
} while(0)

    CK_OPU_OK("http://localhost", "localhost", "80", "/", 0);
    CK_OPU_OK("https://wolfssl.com", "wolfssl.com", "443", "/", 1);
    CK_OPU_OK("https://www.wolfssl.com/fips-140-3-announcement-to-the-world/",
         "www.wolfssl.com", "443", "/fips-140-3-announcement-to-the-world/", 1);
    CK_OPU_OK("http://localhost:1234", "localhost", "1234", "/", 0);
    CK_OPU_OK("https://localhost:1234", "localhost", "1234", "/", 1);

    CK_OPU_FAIL("ftp://localhost");
    /* two strings to cppcheck doesn't mark it as a c++ style comment */
    CK_OPU_FAIL("http/""/localhost");
    CK_OPU_FAIL("http:/localhost");
    CK_OPU_FAIL("https://localhost/path:1234");

#undef CK_OPU_OK
#undef CK_OPU_FAIL
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) && \
    defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM) && \
    !defined(NO_ASN_TIME)
static time_t test_wolfSSL_OCSP_REQ_CTX_time_cb(time_t* t)
{
    if (t != NULL) {
        *t = 1722006780;
    }

    return 1722006780;
}
#endif

static int test_wolfSSL_OCSP_REQ_CTX(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) && \
    defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
    /* This buffer was taken from the ocsp-stapling.test test case 1. The ocsp
     * response was captured in wireshark. It contains both the http and binary
     * parts. The time test_wolfSSL_OCSP_REQ_CTX_time_cb is set exactly so that
     * the time check passes. */
    unsigned char ocspRespBin[] = {
      0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30,
      0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
      0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69,
      0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2d,
      0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
      0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68,
      0x3a, 0x20, 0x31, 0x38, 0x32, 0x31, 0x0d, 0x0a, 0x0d, 0x0a, 0x30, 0x82,
      0x07, 0x19, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x07, 0x12, 0x30, 0x82, 0x07,
      0x0e, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01,
      0x04, 0x82, 0x06, 0xff, 0x30, 0x82, 0x06, 0xfb, 0x30, 0x82, 0x01, 0x19,
      0xa1, 0x81, 0xa1, 0x30, 0x81, 0x9e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
      0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
      0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e,
      0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04,
      0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10,
      0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c,
      0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04,
      0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69,
      0x6e, 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
      0x16, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53,
      0x50, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31,
      0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
      0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c,
      0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x18, 0x0f, 0x32, 0x30,
      0x32, 0x34, 0x30, 0x37, 0x32, 0x36, 0x31, 0x35, 0x31, 0x32, 0x30, 0x35,
      0x5a, 0x30, 0x62, 0x30, 0x60, 0x30, 0x38, 0x30, 0x07, 0x06, 0x05, 0x2b,
      0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x71, 0x4d, 0x82, 0x23, 0x40, 0x59,
      0xc0, 0x96, 0xa1, 0x37, 0x43, 0xfa, 0x31, 0xdb, 0xba, 0xb1, 0x43, 0x18,
      0xda, 0x04, 0x04, 0x14, 0x83, 0xc6, 0x3a, 0x89, 0x2c, 0x81, 0xf4, 0x02,
      0xd7, 0x9d, 0x4c, 0xe2, 0x2a, 0xc0, 0x71, 0x82, 0x64, 0x44, 0xda, 0x0e,
      0x02, 0x01, 0x05, 0x80, 0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x30,
      0x37, 0x32, 0x36, 0x31, 0x35, 0x31, 0x32, 0x30, 0x35, 0x5a, 0xa0, 0x11,
      0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x30, 0x37, 0x32, 0x36, 0x31, 0x35,
      0x31, 0x33, 0x30, 0x35, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
      0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
      0x00, 0x89, 0x7a, 0xe9, 0x6b, 0x66, 0x47, 0x8e, 0x52, 0x16, 0xf9, 0x8a,
      0x5a, 0x1e, 0x7a, 0x35, 0xbb, 0x1d, 0x6c, 0xd8, 0x31, 0xbb, 0x24, 0xd2,
      0xd7, 0xa4, 0x30, 0x27, 0x06, 0x17, 0x66, 0xd1, 0xf9, 0x8d, 0x24, 0xb0,
      0x49, 0x37, 0x62, 0x13, 0x78, 0x5e, 0xa6, 0x6d, 0xea, 0xe3, 0xd0, 0x30,
      0x82, 0x7d, 0xb6, 0xf6, 0x55, 0x82, 0x11, 0xdc, 0xe7, 0x0f, 0xd6, 0x24,
      0xb4, 0x80, 0x23, 0x4f, 0xfd, 0xa7, 0x9a, 0x4b, 0xac, 0xf2, 0xd3, 0xde,
      0x42, 0x10, 0xfb, 0x4b, 0x29, 0x06, 0x02, 0x7b, 0x47, 0x36, 0x70, 0x75,
      0x45, 0x38, 0x8d, 0x3e, 0x55, 0x9c, 0xce, 0x78, 0xd8, 0x18, 0x45, 0x47,
      0x2d, 0x2a, 0x46, 0x65, 0x13, 0x93, 0x1a, 0x98, 0x90, 0xc6, 0x2d, 0xd5,
      0x05, 0x2a, 0xfc, 0xcb, 0xac, 0x53, 0x73, 0x93, 0x42, 0x4e, 0xdb, 0x17,
      0x91, 0xcb, 0xe1, 0x08, 0x03, 0xd1, 0x33, 0x57, 0x4b, 0x1d, 0xb8, 0x71,
      0x84, 0x01, 0x04, 0x47, 0x6f, 0x06, 0xfa, 0x76, 0x7d, 0xd9, 0x37, 0x64,
      0x57, 0x37, 0x3a, 0x8f, 0x4d, 0x88, 0x11, 0xa5, 0xd4, 0xaa, 0xcb, 0x49,
      0x47, 0x86, 0xdd, 0xcf, 0x46, 0xa6, 0xfa, 0x8e, 0xf2, 0x62, 0x0f, 0xc9,
      0x25, 0xf2, 0x39, 0x62, 0x3e, 0x2d, 0x35, 0xc4, 0x76, 0x7b, 0xae, 0xd5,
      0xe8, 0x85, 0xa1, 0xa6, 0x2d, 0x41, 0xd6, 0x8e, 0x3c, 0xfa, 0xdc, 0x6c,
      0x66, 0xe2, 0x61, 0xe7, 0xe5, 0x90, 0xa1, 0xfd, 0x7f, 0xdb, 0x18, 0xd0,
      0xeb, 0x6d, 0x73, 0x08, 0x5f, 0x6a, 0x65, 0x44, 0x50, 0xad, 0x38, 0x9d,
      0xb6, 0xfb, 0xbf, 0x28, 0x55, 0x84, 0x65, 0xfa, 0x0e, 0x34, 0xfc, 0x43,
      0x19, 0x80, 0x5c, 0x7d, 0x2d, 0x5b, 0xd8, 0x60, 0xec, 0x0e, 0xf9, 0x1e,
      0x6e, 0x32, 0x3f, 0x35, 0xf7, 0xec, 0x7e, 0x47, 0xba, 0xb5, 0xd2, 0xaa,
      0x5a, 0x9d, 0x07, 0x2c, 0xc5, 0xa0, 0x82, 0x04, 0xc6, 0x30, 0x82, 0x04,
      0xc2, 0x30, 0x82, 0x04, 0xbe, 0x30, 0x82, 0x03, 0xa6, 0xa0, 0x03, 0x02,
      0x01, 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
      0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x97, 0x31,
      0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
      0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57,
      0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30,
      0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74,
      0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a,
      0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30,
      0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69,
      0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06,
      0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53,
      0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30,
      0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
      0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73,
      0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34,
      0x30, 0x37, 0x32, 0x36, 0x31, 0x35, 0x31, 0x32, 0x30, 0x34, 0x5a, 0x17,
      0x0d, 0x32, 0x37, 0x30, 0x34, 0x32, 0x32, 0x31, 0x35, 0x31, 0x32, 0x30,
      0x34, 0x5a, 0x30, 0x81, 0x9e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
      0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
      0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
      0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07,
      0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30,
      0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66,
      0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
      0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e,
      0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16,
      0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53, 0x50,
      0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, 0x1f,
      0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
      0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66,
      0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30,
      0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
      0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
      0x82, 0x01, 0x01, 0x00, 0xb8, 0xba, 0x23, 0xb4, 0xf6, 0xc3, 0x7b, 0x14,
      0xc3, 0xa4, 0xf5, 0x1d, 0x61, 0xa1, 0xf5, 0x1e, 0x63, 0xb9, 0x85, 0x23,
      0x34, 0x50, 0x6d, 0xf8, 0x7c, 0xa2, 0x8a, 0x04, 0x8b, 0xd5, 0x75, 0x5c,
      0x2d, 0xf7, 0x63, 0x88, 0xd1, 0x07, 0x7a, 0xea, 0x0b, 0x45, 0x35, 0x2b,
      0xeb, 0x1f, 0xb1, 0x22, 0xb4, 0x94, 0x41, 0x38, 0xe2, 0x9d, 0x74, 0xd6,
      0x8b, 0x30, 0x22, 0x10, 0x51, 0xc5, 0xdb, 0xca, 0x3f, 0x46, 0x2b, 0xfe,
      0xe5, 0x5a, 0x3f, 0x41, 0x74, 0x67, 0x75, 0x95, 0xa9, 0x94, 0xd5, 0xc3,
      0xee, 0x42, 0xf8, 0x8d, 0xeb, 0x92, 0x95, 0xe1, 0xd9, 0x65, 0xb7, 0x43,
      0xc4, 0x18, 0xde, 0x16, 0x80, 0x90, 0xce, 0x24, 0x35, 0x21, 0xc4, 0x55,
      0xac, 0x5a, 0x51, 0xe0, 0x2e, 0x2d, 0xb3, 0x0a, 0x5a, 0x4f, 0x4a, 0x73,
      0x31, 0x50, 0xee, 0x4a, 0x16, 0xbd, 0x39, 0x8b, 0xad, 0x05, 0x48, 0x87,
      0xb1, 0x99, 0xe2, 0x10, 0xa7, 0x06, 0x72, 0x67, 0xca, 0x5c, 0xd1, 0x97,
      0xbd, 0xc8, 0xf1, 0x76, 0xf8, 0xe0, 0x4a, 0xec, 0xbc, 0x93, 0xf4, 0x66,
      0x4c, 0x28, 0x71, 0xd1, 0xd8, 0x66, 0x03, 0xb4, 0x90, 0x30, 0xbb, 0x17,
      0xb0, 0xfe, 0x97, 0xf5, 0x1e, 0xe8, 0xc7, 0x5d, 0x9b, 0x8b, 0x11, 0x19,
      0x12, 0x3c, 0xab, 0x82, 0x71, 0x78, 0xff, 0xae, 0x3f, 0x32, 0xb2, 0x08,
      0x71, 0xb2, 0x1b, 0x8c, 0x27, 0xac, 0x11, 0xb8, 0xd8, 0x43, 0x49, 0xcf,
      0xb0, 0x70, 0xb1, 0xf0, 0x8c, 0xae, 0xda, 0x24, 0x87, 0x17, 0x3b, 0xd8,
      0x04, 0x65, 0x6c, 0x00, 0x76, 0x50, 0xef, 0x15, 0x08, 0xd7, 0xb4, 0x73,
      0x68, 0x26, 0x14, 0x87, 0x95, 0xc3, 0x5f, 0x6e, 0x61, 0xb8, 0x87, 0x84,
      0xfa, 0x80, 0x1a, 0x0a, 0x8b, 0x98, 0xf3, 0xe3, 0xff, 0x4e, 0x44, 0x1c,
      0x65, 0x74, 0x7c, 0x71, 0x54, 0x65, 0xe5, 0x39, 0x02, 0x03, 0x01, 0x00,
      0x01, 0xa3, 0x82, 0x01, 0x0a, 0x30, 0x82, 0x01, 0x06, 0x30, 0x09, 0x06,
      0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03,
      0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x32, 0x67, 0xe1, 0xb1, 0x79,
      0xd2, 0x81, 0xfc, 0x9f, 0x23, 0x0c, 0x70, 0x40, 0x50, 0xb5, 0x46, 0x56,
      0xb8, 0x30, 0x36, 0x30, 0x81, 0xc4, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
      0x81, 0xbc, 0x30, 0x81, 0xb9, 0x80, 0x14, 0x73, 0xb0, 0x1c, 0xa4, 0x2f,
      0x82, 0xcb, 0xcf, 0x47, 0xa5, 0x38, 0xd7, 0xb0, 0x04, 0x82, 0x3a, 0x7e,
      0x72, 0x15, 0x21, 0xa1, 0x81, 0x9d, 0xa4, 0x81, 0x9a, 0x30, 0x81, 0x97,
      0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
      0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
      0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10,
      0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61,
      0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04,
      0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14,
      0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67,
      0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, 0x16,
      0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53,
      0x53, 0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f,
      0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
      0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66,
      0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x01, 0x63, 0x30, 0x13,
      0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b,
      0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09, 0x2a,
      0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
      0x01, 0x01, 0x00, 0x37, 0xb9, 0x66, 0xd3, 0xa1, 0x08, 0xfc, 0x37, 0x58,
      0x4e, 0xe0, 0x8c, 0xd3, 0x7f, 0xa6, 0x0f, 0x59, 0xd3, 0x14, 0xf7, 0x4b,
      0x36, 0xf7, 0x2e, 0x98, 0xeb, 0x7c, 0x03, 0x3f, 0x3a, 0xd6, 0x9c, 0xcd,
      0xb4, 0x9e, 0x8d, 0x5f, 0x92, 0xa6, 0x6f, 0x63, 0x87, 0x34, 0xe8, 0x83,
      0xfd, 0x6d, 0x34, 0x64, 0xb5, 0xf0, 0x9c, 0x71, 0x02, 0xb8, 0xf6, 0x2f,
      0x10, 0xa0, 0x92, 0x8f, 0x3f, 0x86, 0x3e, 0xe2, 0x01, 0x5a, 0x56, 0x39,
      0x0a, 0x8d, 0xb1, 0xbe, 0x03, 0xf7, 0xf8, 0xa7, 0x88, 0x46, 0xef, 0x81,
      0xa0, 0xad, 0x86, 0xc9, 0xe6, 0x23, 0x89, 0x1d, 0xa6, 0x24, 0x45, 0xf2,
      0x6a, 0x83, 0x2d, 0x8e, 0x92, 0x17, 0x1e, 0x44, 0x19, 0xfa, 0x0f, 0x47,
      0x6b, 0x8f, 0x4a, 0xa2, 0xda, 0xab, 0xd5, 0x2b, 0xcd, 0xcb, 0x14, 0xf0,
      0xb5, 0xcf, 0x7c, 0x76, 0x42, 0x32, 0x90, 0x21, 0xdc, 0xdd, 0x52, 0xfc,
      0x53, 0x7e, 0xff, 0x7f, 0xd9, 0x58, 0x6b, 0x1f, 0x73, 0xee, 0x83, 0xf4,
      0x67, 0xfa, 0x4a, 0x4f, 0x24, 0xe4, 0x2b, 0x10, 0x74, 0x89, 0x52, 0x9a,
      0xf7, 0xa4, 0xe0, 0xaf, 0xf5, 0x63, 0xd7, 0xfa, 0x0b, 0x2c, 0xc9, 0x39,
      0x5d, 0xbd, 0x44, 0x93, 0x69, 0xa4, 0x1d, 0x01, 0xe2, 0x66, 0xe7, 0xc1,
      0x11, 0x44, 0x7d, 0x0a, 0x7e, 0x5d, 0x1d, 0x26, 0xc5, 0x4a, 0x26, 0x2e,
      0xa3, 0x58, 0xc4, 0xf7, 0x10, 0xcb, 0xba, 0xe6, 0x27, 0xfc, 0xdb, 0x54,
      0xe2, 0x60, 0x08, 0xc2, 0x0e, 0x4b, 0xd4, 0xaa, 0x22, 0x23, 0x93, 0x9f,
      0xe1, 0xcb, 0x85, 0xa4, 0x41, 0x6f, 0x26, 0xa7, 0x77, 0x8a, 0xef, 0x66,
      0xd0, 0xf8, 0x33, 0xf6, 0xfd, 0x6d, 0x37, 0x7a, 0x89, 0xcc, 0x88, 0x3b,
      0x82, 0xd0, 0xa9, 0xdf, 0xf1, 0x3d, 0xdc, 0xb0, 0x06, 0x1c, 0xe4, 0x4b,
      0x57, 0xb4, 0x0c, 0x65, 0xb9, 0xb4, 0x6c
    };
    OCSP_REQ_CTX *ctx = NULL;
    OCSP_REQUEST *req = NULL;
    OCSP_CERTID *cid = NULL;
    OCSP_RESPONSE *rsp = NULL;
    BIO* bio1 = NULL;
    BIO* bio2 = NULL;
    X509* cert = NULL;
    X509 *issuer = NULL;
    X509_LOOKUP *lookup = NULL;
    X509_STORE *store = NULL;
    STACK_OF(X509_OBJECT) *str_objs = NULL;
    X509_OBJECT *x509_obj = NULL;

    ExpectNotNull(bio1 = BIO_new(BIO_s_bio()));
    ExpectNotNull(bio2 = BIO_new(BIO_s_bio()));
    ExpectIntEQ(BIO_make_bio_pair(bio1, bio2), WOLFSSL_SUCCESS);

    /* Load the leaf cert */
    ExpectNotNull(cert = wolfSSL_X509_load_certificate_file(
            "certs/ocsp/server1-cert.pem", WOLFSSL_FILETYPE_PEM));

    ExpectNotNull(store = X509_STORE_new());
    ExpectNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()));
    ExpectIntEQ(X509_LOOKUP_load_file(lookup, "certs/ocsp/server1-cert.pem",
            X509_FILETYPE_PEM), 1);
    ExpectNotNull(str_objs = X509_STORE_get0_objects(store));
    ExpectNotNull(x509_obj = X509_OBJECT_retrieve_by_subject(str_objs,
            X509_LU_X509, X509_get_issuer_name(cert)));
    ExpectNotNull(issuer = X509_OBJECT_get0_X509(x509_obj));

    ExpectNotNull(req = OCSP_REQUEST_new());
    ExpectNotNull(cid = OCSP_cert_to_id(EVP_sha1(), cert, issuer));
    ExpectNotNull(OCSP_request_add0_id(req, cid));
    ExpectIntEQ(OCSP_request_add1_nonce(req, NULL, -1), 1);

    ExpectNotNull(ctx = OCSP_sendreq_new(bio1, "/", NULL, -1));
    ExpectIntEQ(OCSP_REQ_CTX_add1_header(ctx, "Host", "127.0.0.1"), 1);
    ExpectIntEQ(OCSP_REQ_CTX_set1_req(ctx, req), 1);
    ExpectIntEQ(OCSP_sendreq_nbio(&rsp, ctx), -1);
    ExpectIntEQ(BIO_write(bio2, ocspRespBin, sizeof(ocspRespBin)),
            sizeof(ocspRespBin));
#ifndef NO_ASN_TIME
    ExpectIntEQ(wc_SetTimeCb(test_wolfSSL_OCSP_REQ_CTX_time_cb), 0);
    ExpectIntEQ(OCSP_sendreq_nbio(&rsp, ctx), 1);
    ExpectIntEQ(wc_SetTimeCb(NULL), 0);
    ExpectNotNull(rsp);
#endif

    OCSP_REQ_CTX_free(ctx);
    OCSP_REQUEST_free(req);
    OCSP_RESPONSE_free(rsp);
    BIO_free(bio1);
    BIO_free(bio2);
    X509_free(cert);
    X509_STORE_free(store);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PKEY_derive(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENSSH)
#if (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || defined(HAVE_ECC)
    EVP_PKEY_CTX *ctx = NULL;
    unsigned char *skey = NULL;
    size_t skeylen;
    EVP_PKEY *pkey = NULL;
    EVP_PKEY *peerkey = NULL;
    const unsigned char* key;

#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
    /* DH */
    key = dh_key_der_2048;
    ExpectNotNull((pkey = d2i_PrivateKey(EVP_PKEY_DH, NULL, &key,
        sizeof_dh_key_der_2048)));
    ExpectIntEQ(DH_generate_key(EVP_PKEY_get0_DH(pkey)), 1);
    key = dh_key_der_2048;
    ExpectNotNull((peerkey = d2i_PrivateKey(EVP_PKEY_DH, NULL, &key,
        sizeof_dh_key_der_2048)));
    ExpectIntEQ(DH_generate_key(EVP_PKEY_get0_DH(peerkey)), 1);
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));
    ExpectIntEQ(EVP_PKEY_derive_init(ctx), 1);
    ExpectIntEQ(EVP_PKEY_derive_set_peer(ctx, peerkey), 1);
    ExpectIntEQ(EVP_PKEY_derive(ctx, NULL, &skeylen), 1);
    ExpectNotNull(skey = (unsigned char*)XMALLOC(skeylen, NULL,
        DYNAMIC_TYPE_OPENSSL));
    ExpectIntEQ(EVP_PKEY_derive(ctx, skey, &skeylen), 1);

    EVP_PKEY_CTX_free(ctx);
    ctx = NULL;
    EVP_PKEY_free(peerkey);
    peerkey = NULL;
    EVP_PKEY_free(pkey);
    pkey = NULL;
    XFREE(skey, NULL, DYNAMIC_TYPE_OPENSSL);
    skey = NULL;
#endif

#ifdef HAVE_ECC
    /* ECDH */
    key = ecc_clikey_der_256;
    ExpectNotNull((pkey = d2i_PrivateKey(EVP_PKEY_EC, NULL, &key,
        sizeof_ecc_clikey_der_256)));
    key = ecc_clikeypub_der_256;
    ExpectNotNull((peerkey = d2i_PUBKEY(NULL, &key,
        sizeof_ecc_clikeypub_der_256)));
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));
    ExpectIntEQ(EVP_PKEY_derive_init(ctx), 1);
    ExpectIntEQ(EVP_PKEY_derive_set_peer(ctx, peerkey), 1);
    ExpectIntEQ(EVP_PKEY_derive(ctx, NULL, &skeylen), 1);
    ExpectNotNull(skey = (unsigned char*)XMALLOC(skeylen, NULL,
        DYNAMIC_TYPE_OPENSSL));
    ExpectIntEQ(EVP_PKEY_derive(ctx, skey, &skeylen), 1);

    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(peerkey);
    EVP_PKEY_free(pkey);
    XFREE(skey, NULL, DYNAMIC_TYPE_OPENSSL);
#endif /* HAVE_ECC */
#endif /* (!NO_DH && WOLFSSL_DH_EXTRA) || HAVE_ECC */
#endif /* OPENSSL_ALL || WOLFSSL_QT || WOLFSSL_OPENSSH */
    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_PBE_scrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SCRYPT) && defined(HAVE_PBKDF2) && \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 5))
#if !defined(NO_PWDBASED) &&  !defined(NO_SHA256)
    int ret;

    const char  pwd[]    = {'p','a','s','s','w','o','r','d'};
    int         pwdlen   = sizeof(pwd);
    const byte  salt[]   = {'N','a','C','l'};
    int         saltlen  = sizeof(salt);
    byte        key[80];
    word64      numOvr32 = (word64)INT32_MAX + 1;

    /* expected derived key for N:16, r:1, p:1 */
    const byte expectedKey[] = {
        0xAE, 0xC6, 0xB7, 0x48, 0x3E, 0xD2, 0x6E, 0x08, 0x80, 0x2B,
        0x41, 0xF4, 0x03, 0x20, 0x86, 0xA0, 0xE8, 0x86, 0xBE, 0x7A,
        0xC4, 0x8F, 0xCF, 0xD9, 0x2F, 0xF0, 0xCE, 0xF8, 0x10, 0x97,
        0x52, 0xF4, 0xAC, 0x74, 0xB0, 0x77, 0x26, 0x32, 0x56, 0xA6,
        0x5A, 0x99, 0x70, 0x1B, 0x7A, 0x30, 0x4D, 0x46, 0x61, 0x1C,
        0x8A, 0xA3, 0x91, 0xE7, 0x99, 0xCE, 0x10, 0xA2, 0x77, 0x53,
        0xE7, 0xE9, 0xC0, 0x9A};

    /*                                               N  r  p  mx key keylen */
    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 0, 1, 1, 0, key, 64);
    ExpectIntEQ(ret, 0); /* N must be greater than 1 */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 3, 1, 1, 0, key, 64);
    ExpectIntEQ(ret, 0); /* N must be power of 2 */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 2, 0, 1, 0, key, 64);
    ExpectIntEQ(ret, 0); /* r must be greater than 0 */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 2, 1, 0, 0, key, 64);
    ExpectIntEQ(ret, 0); /* p must be greater than 0 */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 2, 1, 1, 0, key, 0);
    ExpectIntEQ(ret, 0); /* keylen must be greater than 0 */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 2, 9, 1, 0, key, 64);
    ExpectIntEQ(ret, 0); /* r must be smaller than 9 */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 2, 1, 1, 0, NULL, 64);
    ExpectIntEQ(ret, 1); /* should succeed if key is NULL  */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 2, 1, 1, 0, key, 64);
    ExpectIntEQ(ret, 1); /* should succeed */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 2, numOvr32, 1, 0,
                                                                    key, 64);
    ExpectIntEQ(ret, 0); /* should fail since r is greater than INT32_MAC */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 2, 1, numOvr32, 0,
                                                                    key, 64);
    ExpectIntEQ(ret, 0); /* should fail since p is greater than INT32_MAC */

    ret = EVP_PBE_scrypt(pwd, pwdlen, NULL, 0, 2, 1, 1, 0, key, 64);
    ExpectIntEQ(ret, 1); /* should succeed even if salt is NULL */

    ret = EVP_PBE_scrypt(pwd, pwdlen, NULL, 4, 2, 1, 1, 0, key, 64);
    ExpectIntEQ(ret, 0); /* if salt is NULL, saltlen must be 0, otherwise fail*/

    ret = EVP_PBE_scrypt(NULL, 0, salt, saltlen, 2, 1, 1, 0, key, 64);
    ExpectIntEQ(ret, 1); /* should succeed if pwd is NULL and pwdlen is 0*/

    ret = EVP_PBE_scrypt(NULL, 4, salt, saltlen, 2, 1, 1, 0, key, 64);
    ExpectIntEQ(ret, 0); /* if pwd is NULL, pwdlen must be 0 */

    ret = EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 1, 1, 0, key, 64);
    ExpectIntEQ(ret, 1); /* should succeed even both pwd and salt are NULL */

    ret = EVP_PBE_scrypt(pwd, pwdlen, salt, saltlen, 16, 1, 1, 0, key, 64);
    ExpectIntEQ(ret, 1);

    ret = XMEMCMP(expectedKey, key, sizeof(expectedKey));
    ExpectIntEQ(ret, 0); /* derived key must be the same as expected-key */
#endif /* !NO_PWDBASED && !NO_SHA256 */
#endif /* OPENSSL_EXTRA && HAVE_SCRYPT && HAVE_PBKDF2 */
    return EXPECT_RESULT();
}

static int test_no_op_functions(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    /* this makes sure wolfSSL can compile and run these no-op functions */
    SSL_load_error_strings();
    ENGINE_load_builtin_engines();
    OpenSSL_add_all_ciphers();
    ExpectIntEQ(CRYPTO_malloc_init(), 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CRYPTO_memcmp(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    char a[] = "wolfSSL (formerly CyaSSL) is a small, fast, portable "
               "implementation of TLS/SSL for embedded devices to the cloud.";
    char b[] = "wolfSSL (formerly CyaSSL) is a small, fast, portable "
               "implementation of TLS/SSL for embedded devices to the cloud.";
    char c[] = "wolfSSL (formerly CyaSSL) is a small, fast, portable "
               "implementation of TLS/SSL for embedded devices to the cloud!";

    ExpectIntEQ(CRYPTO_memcmp(a, b, sizeof(a)), 0);
    ExpectIntNE(CRYPTO_memcmp(a, c, sizeof(a)), 0);
#endif
    return EXPECT_RESULT();
}

/*----------------------------------------------------------------------------*
 | wolfCrypt ASN
 *----------------------------------------------------------------------------*/

static int test_wc_CreateEncryptedPKCS8Key(void)
{
    EXPECT_DECLS;
#if defined(HAVE_PKCS8) && !defined(NO_PWDBASED) && defined(WOLFSSL_AES_256) \
 && !defined(NO_AES_CBC) && !defined(NO_RSA) && !defined(NO_SHA) && \
    !defined(NO_ASN_CRYPT)
    WC_RNG rng;
    byte* encKey = NULL;
    word32 encKeySz = 0;
    word32 decKeySz = 0;
    const char password[] = "Lorem ipsum dolor sit amet";
    word32 passwordSz = (word32)XSTRLEN(password);
    word32 tradIdx = 0;

    XMEMSET(&rng, 0, sizeof(WC_RNG));
    ExpectIntEQ(wc_InitRng(&rng), 0);
    PRIVATE_KEY_UNLOCK();
    /* Call with NULL for out buffer to get necessary length. */
    ExpectIntEQ(wc_CreateEncryptedPKCS8Key((byte*)server_key_der_2048,
        sizeof_server_key_der_2048, NULL, &encKeySz, password, (int)passwordSz,
        PKCS5, PBES2, AES256CBCb, NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL),
        WC_NO_ERR_TRACE(LENGTH_ONLY_E));
    ExpectNotNull(encKey = (byte*)XMALLOC(encKeySz, HEAP_HINT,
        DYNAMIC_TYPE_TMP_BUFFER));
    /* Call with the allocated out buffer. */
    ExpectIntGT(wc_CreateEncryptedPKCS8Key((byte*)server_key_der_2048,
        sizeof_server_key_der_2048, encKey, &encKeySz, password, (int)passwordSz,
        PKCS5, PBES2, AES256CBCb, NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL),
        0);
    /* Decrypt the encrypted PKCS8 key we just made. */
    ExpectIntGT((decKeySz = (word32)wc_DecryptPKCS8Key(encKey, encKeySz, password,
        (int)passwordSz)), 0);
    /* encKey now holds the decrypted key (decrypted in place). */
    ExpectIntGT(wc_GetPkcs8TraditionalOffset(encKey, &tradIdx, decKeySz), 0);
    /* Check that the decrypted key matches the key prior to encryption. */
    ExpectIntEQ(XMEMCMP(encKey + tradIdx, server_key_der_2048,
        sizeof_server_key_der_2048), 0);
    PRIVATE_KEY_LOCK();

    XFREE(encKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    wc_FreeRng(&rng);
#endif
    return EXPECT_RESULT();
}

static int test_wc_GetPkcs8TraditionalOffset(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(HAVE_PKCS8)
    int length;
    int derSz = 0;
    word32 inOutIdx;
    const char* path = "./certs/server-keyPkcs8.der";
    const char* pathAttributes = "./certs/ca-key-pkcs8-attribute.der";
    XFILE file = XBADFILE;
    byte der[2048];

    ExpectTrue((file = XFOPEN(path, "rb")) != XBADFILE);
    ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), file), 0);
    if (file != XBADFILE)
        XFCLOSE(file);
    file = XBADFILE; /* reset file to avoid warning of use after close */

    /* valid case */
    inOutIdx = 0;
    ExpectIntGT(length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx, (word32)derSz),
        0);

    /* inOutIdx > sz */
    inOutIdx = 4000;
    ExpectIntEQ(length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx, (word32)derSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* null input */
    inOutIdx = 0;
    ExpectIntEQ(length = wc_GetPkcs8TraditionalOffset(NULL, &inOutIdx, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* invalid input, fill buffer with 1's */
    XMEMSET(der, 1, sizeof(der));
    inOutIdx = 0;
    ExpectIntEQ(length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx, (word32)derSz),
        WC_NO_ERR_TRACE(ASN_PARSE_E));

    /* test parsing with attributes */
    ExpectTrue((file = XFOPEN(pathAttributes, "rb")) != XBADFILE);
    ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), file), 0);
    if (file != XBADFILE)
        XFCLOSE(file);

    inOutIdx = 0;
    ExpectIntGT(length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx,
        (word32)derSz), 0);
#endif /* NO_ASN */
    return EXPECT_RESULT();
}

static int test_wc_SetSubjectRaw(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && !defined(NO_RSA)
    const char* joiCertFile = "./certs/test/cert-ext-joi.der";
    WOLFSSL_X509* x509 = NULL;
    int peerCertSz;
    const byte* peerCertBuf = NULL;
    Cert forgedCert;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(joiCertFile,
        WOLFSSL_FILETYPE_ASN1));

    ExpectNotNull(peerCertBuf = wolfSSL_X509_get_der(x509, &peerCertSz));

    ExpectIntEQ(0, wc_InitCert(&forgedCert));

    ExpectIntEQ(0, wc_SetSubjectRaw(&forgedCert, peerCertBuf, peerCertSz));

    wolfSSL_FreeX509(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wc_GetSubjectRaw(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)
    Cert cert;
    byte *subjectRaw;

    ExpectIntEQ(0, wc_InitCert(&cert));
    ExpectIntEQ(0, wc_GetSubjectRaw(&subjectRaw, &cert));
#endif
    return EXPECT_RESULT();
}

static int test_wc_SetIssuerRaw(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && !defined(NO_RSA)
    const char* joiCertFile = "./certs/test/cert-ext-joi.der";
    WOLFSSL_X509* x509 = NULL;
    int peerCertSz;
    const byte* peerCertBuf = NULL;
    Cert forgedCert;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(joiCertFile,
        WOLFSSL_FILETYPE_ASN1));

    ExpectNotNull(peerCertBuf = wolfSSL_X509_get_der(x509, &peerCertSz));

    ExpectIntEQ(0, wc_InitCert(&forgedCert));

    ExpectIntEQ(0, wc_SetIssuerRaw(&forgedCert, peerCertBuf, peerCertSz));

    wolfSSL_FreeX509(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wc_SetIssueBuffer(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && !defined(NO_RSA)
    const char* joiCertFile = "./certs/test/cert-ext-joi.der";
    WOLFSSL_X509* x509 = NULL;
    int peerCertSz;
    const byte* peerCertBuf = NULL;
    Cert forgedCert;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(joiCertFile,
        WOLFSSL_FILETYPE_ASN1));

    ExpectNotNull(peerCertBuf = wolfSSL_X509_get_der(x509, &peerCertSz));

    ExpectIntEQ(0, wc_InitCert(&forgedCert));

    ExpectIntEQ(0, wc_SetIssuerBuffer(&forgedCert, peerCertBuf, peerCertSz));

    wolfSSL_FreeX509(x509);
#endif
    return EXPECT_RESULT();
}

/*
 * Testing wc_SetSubjectKeyId
 */
static int test_wc_SetSubjectKeyId(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && defined(HAVE_ECC)
    Cert cert;
    const char* file = "certs/ecc-client-keyPub.pem";

    ExpectIntEQ(0, wc_InitCert(&cert));
    ExpectIntEQ(0, wc_SetSubjectKeyId(&cert, file));

    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wc_SetSubjectKeyId(NULL, file));
    ExpectIntGT(0, wc_SetSubjectKeyId(&cert, "badfile.name"));
#endif
    return EXPECT_RESULT();
} /* END test_wc_SetSubjectKeyId */

/*
 * Testing wc_SetSubject
 */
static int test_wc_SetSubject(void)
{
    EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && defined(HAVE_ECC)
    Cert cert;
    const char* file = "./certs/ca-ecc-cert.pem";

    ExpectIntEQ(0, wc_InitCert(&cert));
    ExpectIntEQ(0, wc_SetSubject(&cert, file));

    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wc_SetSubject(NULL, file));
    ExpectIntGT(0, wc_SetSubject(&cert, "badfile.name"));
#endif
    return EXPECT_RESULT();
} /* END test_wc_SetSubject */


static int test_CheckCertSignature(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(WOLFSSL_SMALL_CERT_VERIFY)
    WOLFSSL_CERT_MANAGER* cm = NULL;
#if !defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
    XFILE fp = XBADFILE;
    byte  cert[4096];
    int   certSz;
#endif

    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wc_CheckCertSignature(NULL, 0, NULL, NULL));
    ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
    ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wc_CheckCertSignature(NULL, 0, NULL, cm));

#ifndef NO_RSA
#ifdef USE_CERT_BUFFERS_1024
    ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(server_cert_der_1024,
                sizeof_server_cert_der_1024, NULL, cm));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCABuffer(cm,
                ca_cert_der_1024, sizeof_ca_cert_der_1024,
                WOLFSSL_FILETYPE_ASN1));
    ExpectIntEQ(0, wc_CheckCertSignature(server_cert_der_1024,
                sizeof_server_cert_der_1024, NULL, cm));
#elif defined(USE_CERT_BUFFERS_2048)
    ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(server_cert_der_2048,
                sizeof_server_cert_der_2048, NULL, cm));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCABuffer(cm,
                ca_cert_der_2048, sizeof_ca_cert_der_2048,
                WOLFSSL_FILETYPE_ASN1));
    ExpectIntEQ(0, wc_CheckCertSignature(server_cert_der_2048,
                sizeof_server_cert_der_2048, NULL, cm));
#endif
#endif

#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
    ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(serv_ecc_der_256,
                sizeof_serv_ecc_der_256, NULL, cm));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCABuffer(cm,
                ca_ecc_cert_der_256, sizeof_ca_ecc_cert_der_256,
                WOLFSSL_FILETYPE_ASN1));
    ExpectIntEQ(0, wc_CheckCertSignature(serv_ecc_der_256, sizeof_serv_ecc_der_256,
                NULL, cm));
#endif

#if !defined(NO_FILESYSTEM)
    wolfSSL_CertManagerFree(cm);
    cm = NULL;
    ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
#ifndef NO_RSA
    ExpectTrue((fp = XFOPEN("./certs/server-cert.der", "rb")) != XBADFILE);
    ExpectIntGT((certSz = (int)XFREAD(cert, 1, sizeof(cert), fp)), 0);
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }
    ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(cert, certSz, NULL, cm));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCA(cm,
                "./certs/ca-cert.pem", NULL));
    ExpectIntEQ(0, wc_CheckCertSignature(cert, certSz, NULL, cm));
#endif
#ifdef HAVE_ECC
    ExpectTrue((fp = XFOPEN("./certs/server-ecc.der", "rb")) != XBADFILE);
    ExpectIntGT((certSz = (int)XFREAD(cert, 1, sizeof(cert), fp)), 0);
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }
    ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(cert, certSz, NULL, cm));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCA(cm,
                "./certs/ca-ecc-cert.pem", NULL));
    ExpectIntEQ(0, wc_CheckCertSignature(cert, certSz, NULL, cm));
#endif
#endif

#if !defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
    (void)fp;
    (void)cert;
    (void)certSz;
#endif

    wolfSSL_CertManagerFree(cm);
#endif
    return EXPECT_RESULT();
}

static int test_wc_ParseCert(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA)
    DecodedCert decodedCert;
    const byte* rawCert = client_cert_der_2048;
    const int rawCertSize = sizeof_client_cert_der_2048;

    wc_InitDecodedCert(&decodedCert, rawCert, rawCertSize, NULL);
    ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
#ifndef IGNORE_NAME_CONSTRAINTS
    /* check that the subjects emailAddress was not put in the alt name list */
    ExpectNotNull(decodedCert.subjectEmail);
    ExpectNull(decodedCert.altEmailNames);
#endif
    wc_FreeDecodedCert(&decodedCert);
#endif
    return EXPECT_RESULT();
}

/* Test wc_ParseCert decoding of various encodings and scenarios ensuring that
 * the API safely errors out on badly-formed ASN input.
 * NOTE: Test not compatible with released FIPS implementations!
 */
static int test_wc_ParseCert_Error(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(HAVE_SELFTEST) && \
    (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
    DecodedCert decodedCert;
    int i;

    /* Certificate data */
    const byte c0[] = { 0x30, 0x04, 0x30, 0x02, 0x02, 0x80, 0x00, 0x00};
    const byte c1[] = { 0x30, 0x04, 0x30, 0x04, 0x02, 0x80, 0x00, 0x00};
    const byte c2[] = { 0x30, 0x06, 0x30, 0x04, 0x02, 0x80, 0x00, 0x00};
    const byte c3[] = { 0x30, 0x07, 0x30, 0x05, 0x02, 0x80, 0x10, 0x00, 0x00};
    const byte c4[] = { 0x02, 0x80, 0x10, 0x00, 0x00};

    /* Test data */
    const struct testStruct {
        const byte* c;
        word32 cSz;
        const int expRet;
    } t[] = {
        {c0, sizeof(c0), WC_NO_ERR_TRACE(ASN_PARSE_E)}, /* Invalid bit-string length */
        {c1, sizeof(c1), WC_NO_ERR_TRACE(ASN_PARSE_E)}, /* Invalid bit-string length */
        {c2, sizeof(c2), WC_NO_ERR_TRACE(ASN_PARSE_E)}, /* Invalid integer length (zero) */
        {c3, sizeof(c3), WC_NO_ERR_TRACE(ASN_PARSE_E)}, /* Valid INTEGER, but buffer too short */
        {c4, sizeof(c4), WC_NO_ERR_TRACE(ASN_PARSE_E)}, /* Valid INTEGER, but not in bit-string */
    };
    const int tSz = (int)(sizeof(t) / sizeof(struct testStruct));

    for (i = 0; i < tSz; i++) {
        WOLFSSL_MSG_EX("i == %d", i);
        wc_InitDecodedCert(&decodedCert, t[i].c, t[i].cSz, NULL);
        ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), t[i].expRet);
        wc_FreeDecodedCert(&decodedCert);
    }
#endif
    return EXPECT_RESULT();
}

static int test_MakeCertWithPathLen(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME) && \
    defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC)
    const byte expectedPathLen = 7;
    Cert cert;
    DecodedCert decodedCert;
    byte der[FOURK_BUF];
    int derSize = 0;
    WC_RNG rng;
    ecc_key key;
    int ret;

    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&cert, 0, sizeof(Cert));
    XMEMSET(&decodedCert, 0, sizeof(DecodedCert));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
    ExpectIntEQ(wc_InitCert(&cert), 0);

    (void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.org, "yourOrgNameHere", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.commonName, "www.yourDomain.com",
        CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.email, "yourEmail@yourDomain.com",
        CTC_NAME_SIZE);

    cert.selfSigned = 1;
    cert.isCA       = 1;
    cert.pathLen    = expectedPathLen;
    cert.pathLenSet = 1;
    cert.sigType    = CTC_SHA256wECDSA;

#ifdef WOLFSSL_CERT_EXT
    cert.keyUsage |= KEYUSE_KEY_CERT_SIGN;
#endif

    ExpectIntGE(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
    ExpectIntGE(derSize = wc_SignCert(cert.bodySz, cert.sigType, der,
        FOURK_BUF, NULL, &key, &rng), 0);

    wc_InitDecodedCert(&decodedCert, der, (word32)derSize, NULL);
    ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
    ExpectIntEQ(decodedCert.pathLength, expectedPathLen);

    wc_FreeDecodedCert(&decodedCert);
    ret = wc_ecc_free(&key);
    ExpectIntEQ(ret, 0);
    ret = wc_FreeRng(&rng);
    ExpectIntEQ(ret, 0);
#endif
    return EXPECT_RESULT();
}

static int test_MakeCertWith0Ser(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME) && \
    defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC) && \
    defined(WOLFSSL_ASN_TEMPLATE)
    Cert cert;
    DecodedCert decodedCert;
    byte der[FOURK_BUF];
    int derSize = 0;
    WC_RNG rng;
    ecc_key key;
    int ret;

    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&cert, 0, sizeof(Cert));
    XMEMSET(&decodedCert, 0, sizeof(DecodedCert));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
    ExpectIntEQ(wc_InitCert(&cert), 0);

    (void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.org, "yourOrgNameHere", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.commonName, "www.yourDomain.com",
        CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.email, "yourEmail@yourDomain.com",
        CTC_NAME_SIZE);

    cert.selfSigned = 1;
    cert.isCA       = 1;
    cert.sigType    = CTC_SHA256wECDSA;

#ifdef WOLFSSL_CERT_EXT
    cert.keyUsage |= KEYUSE_KEY_CERT_SIGN;
#endif

    /* set serial number to 0 */
    cert.serialSz  = 1;
    cert.serial[0] = 0;

    ExpectIntGE(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
    ExpectIntGE(derSize = wc_SignCert(cert.bodySz, cert.sigType, der,
        FOURK_BUF, NULL, &key, &rng), 0);

    wc_InitDecodedCert(&decodedCert, der, (word32)derSize, NULL);

#if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_PYTHON)
    ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL),
        WC_NO_ERR_TRACE(ASN_PARSE_E));
#else
    ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
#endif

    wc_FreeDecodedCert(&decodedCert);
    ret = wc_ecc_free(&key);
    ExpectIntEQ(ret, 0);
    ret = wc_FreeRng(&rng);
    ExpectIntEQ(ret, 0);
#endif
    return EXPECT_RESULT();
}

static int test_MakeCertWithCaFalse(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_ALLOW_ENCODING_CA_FALSE) && defined(WOLFSSL_CERT_REQ) && \
    !defined(NO_ASN_TIME) && defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC)
    const byte expectedIsCa = 0;
    Cert cert;
    DecodedCert decodedCert;
    byte der[FOURK_BUF];
    int derSize = 0;
    WC_RNG rng;
    ecc_key key;
    int ret;

    XMEMSET(&rng, 0, sizeof(WC_RNG));
    XMEMSET(&key, 0, sizeof(ecc_key));
    XMEMSET(&cert, 0, sizeof(Cert));
    XMEMSET(&decodedCert, 0, sizeof(DecodedCert));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    ExpectIntEQ(wc_ecc_init(&key), 0);
    ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
    ExpectIntEQ(wc_InitCert(&cert), 0);

    (void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.org, "yourOrgNameHere", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.commonName, "www.yourDomain.com",
        CTC_NAME_SIZE);
    (void)XSTRNCPY(cert.subject.email, "yourEmail@yourDomain.com",
        CTC_NAME_SIZE);

    cert.selfSigned = 1;
    cert.isCA       = expectedIsCa;
    cert.isCaSet    = 1;
    cert.sigType    = CTC_SHA256wECDSA;

    ExpectIntGE(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
    ExpectIntGE(derSize = wc_SignCert(cert.bodySz, cert.sigType, der,
        FOURK_BUF, NULL, &key, &rng), 0);

    wc_InitDecodedCert(&decodedCert, der, derSize, NULL);
    ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
    ExpectIntEQ(decodedCert.isCA, expectedIsCa);

    wc_FreeDecodedCert(&decodedCert);
    ret = wc_ecc_free(&key);
    ExpectIntEQ(ret, 0);
    ret = wc_FreeRng(&rng);
    ExpectIntEQ(ret, 0);
#endif
    return EXPECT_RESULT();
}

/*----------------------------------------------------------------------------*
 | wolfCrypt ECC
 *----------------------------------------------------------------------------*/

static int test_wc_ecc_get_curve_size_from_name(void)
{
    EXPECT_DECLS;
#ifdef HAVE_ECC
    #if !defined(NO_ECC256) && !defined(NO_ECC_SECP)
        ExpectIntEQ(wc_ecc_get_curve_size_from_name("SECP256R1"), 32);
    #endif
    /* invalid case */
    ExpectIntEQ(wc_ecc_get_curve_size_from_name("BADCURVE"), -1);
    /* NULL input */
    ExpectIntEQ(wc_ecc_get_curve_size_from_name(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif /* HAVE_ECC */
    return EXPECT_RESULT();
}

static int test_wc_ecc_get_curve_id_from_name(void)
{
    EXPECT_DECLS;
#ifdef HAVE_ECC
    #if !defined(NO_ECC256) && !defined(NO_ECC_SECP)
        ExpectIntEQ(wc_ecc_get_curve_id_from_name("SECP256R1"),
            ECC_SECP256R1);
    #endif
    /* invalid case */
    ExpectIntEQ(wc_ecc_get_curve_id_from_name("BADCURVE"), -1);
    /* NULL input */
    ExpectIntEQ(wc_ecc_get_curve_id_from_name(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif /* HAVE_ECC */
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && \
    !defined(HAVE_SELFTEST) && \
    !(defined(HAVE_FIPS) || defined(HAVE_FIPS_VERSION))
static int test_wc_ecc_get_curve_id_from_dp_params(void)
{
    EXPECT_DECLS;
#if !defined(NO_ECC256) && !defined(NO_ECC_SECP)
    ecc_key* key;
    const ecc_set_type* params = NULL;
    int ret;
#endif
    WOLFSSL_EC_KEY *ecKey = NULL;

    #if !defined(NO_ECC256) && !defined(NO_ECC_SECP)
        ExpectIntEQ(wc_ecc_get_curve_id_from_name("SECP256R1"), ECC_SECP256R1);
        ExpectNotNull(ecKey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));

        if (EXPECT_SUCCESS()) {
            ret = EC_KEY_generate_key(ecKey);
        } else
            ret = 0;

        if (ret == 1) {
            /* normal test */
            key = (ecc_key*)ecKey->internal;
            if (key != NULL) {
                params = key->dp;
            }

            ExpectIntEQ(wc_ecc_get_curve_id_from_dp_params(params),
                ECC_SECP256R1);
        }
    #endif
    /* invalid case, NULL input*/
    ExpectIntEQ(wc_ecc_get_curve_id_from_dp_params(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    wolfSSL_EC_KEY_free(ecKey);

    return EXPECT_RESULT();
}
#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */

static int test_wc_ecc_get_curve_id_from_params(void)
{
    EXPECT_DECLS;
#ifdef HAVE_ECC
    const byte prime[] =
    {
        0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
    };

    const byte primeInvalid[] =
    {
        0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x01
    };

    const byte Af[] =
    {
        0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC
    };

    const byte Bf[] =
    {
        0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,
        0xB3,0xEB,0xBD,0x55,0x76,0x98,0x86,0xBC,
        0x65,0x1D,0x06,0xB0,0xCC,0x53,0xB0,0xF6,
        0x3B,0xCE,0x3C,0x3E,0x27,0xD2,0x60,0x4B
    };

    const byte order[] =
    {
        0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        0xBC,0xE6,0xFA,0xAD,0xA7,0x17,0x9E,0x84,
        0xF3,0xB9,0xCA,0xC2,0xFC,0x63,0x25,0x51
    };

    const byte Gx[] =
    {
        0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,
        0xF8,0xBC,0xE6,0xE5,0x63,0xA4,0x40,0xF2,
        0x77,0x03,0x7D,0x81,0x2D,0xEB,0x33,0xA0,
        0xF4,0xA1,0x39,0x45,0xD8,0x98,0xC2,0x96
    };

    const byte Gy[] =
    {
        0x4F,0xE3,0x42,0xE2,0xFE,0x1A,0x7F,0x9B,
        0x8E,0xE7,0xEB,0x4A,0x7C,0x0F,0x9E,0x16,
        0x2B,0xCE,0x33,0x57,0x6B,0x31,0x5E,0xCE,
        0xCB,0xB6,0x40,0x68,0x37,0xBF,0x51,0xF5
    };

    int cofactor = 1;
    int fieldSize = 256;

    #if !defined(NO_ECC256) && !defined(NO_ECC_SECP)
        ExpectIntEQ(wc_ecc_get_curve_id_from_params(fieldSize,
            prime, sizeof(prime), Af, sizeof(Af), Bf, sizeof(Bf),
            order, sizeof(order), Gx, sizeof(Gx), Gy, sizeof(Gy), cofactor),
            ECC_SECP256R1);
    #endif

    /* invalid case, fieldSize = 0 */
    ExpectIntEQ(wc_ecc_get_curve_id_from_params(0, prime, sizeof(prime),
        Af, sizeof(Af), Bf, sizeof(Bf), order, sizeof(order),
        Gx, sizeof(Gx), Gy, sizeof(Gy), cofactor), ECC_CURVE_INVALID);

    /* invalid case, NULL prime */
    ExpectIntEQ(wc_ecc_get_curve_id_from_params(fieldSize, NULL, sizeof(prime),
        Af, sizeof(Af), Bf, sizeof(Bf), order, sizeof(order),
        Gx, sizeof(Gx), Gy, sizeof(Gy), cofactor), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* invalid case, invalid prime */
    ExpectIntEQ(wc_ecc_get_curve_id_from_params(fieldSize,
        primeInvalid, sizeof(primeInvalid),
        Af, sizeof(Af), Bf, sizeof(Bf), order, sizeof(order),
        Gx, sizeof(Gx), Gy, sizeof(Gy), cofactor), ECC_CURVE_INVALID);
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_PKEY_encrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    WOLFSSL_RSA* rsa = NULL;
    WOLFSSL_EVP_PKEY* pkey = NULL;
    WOLFSSL_EVP_PKEY_CTX* ctx = NULL;
    const char* in = "What is easy to do is easy not to do.";
    size_t inlen = XSTRLEN(in);
    size_t outEncLen = 0;
    byte*  outEnc = NULL;
    byte*  outDec = NULL;
    size_t outDecLen = 0;
    size_t rsaKeySz = 2048/8;  /* Bytes */
#if !defined(HAVE_FIPS) && defined(WC_RSA_NO_PADDING)
    byte*  inTmp = NULL;
    byte*  outEncTmp = NULL;
    byte*  outDecTmp = NULL;
#endif

    ExpectNotNull(outEnc = (byte*)XMALLOC(rsaKeySz, HEAP_HINT,
        DYNAMIC_TYPE_TMP_BUFFER));
    if (outEnc != NULL) {
        XMEMSET(outEnc, 0, rsaKeySz);
    }
    ExpectNotNull(outDec = (byte*)XMALLOC(rsaKeySz, HEAP_HINT,
        DYNAMIC_TYPE_TMP_BUFFER));
    if (outDec != NULL) {
        XMEMSET(outDec, 0, rsaKeySz);
    }

    ExpectNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL));
    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectIntEQ(EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS);
    if (EXPECT_FAIL()) {
        RSA_free(rsa);
    }
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));
    ExpectIntEQ(EVP_PKEY_encrypt_init(ctx), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING),
        WOLFSSL_SUCCESS);

    /* Test pkey references count is decremented. pkey shouldn't be destroyed
     since ctx uses it.*/
    ExpectIntEQ(pkey->ref.count, 2);
    EVP_PKEY_free(pkey);
    ExpectIntEQ(pkey->ref.count, 1);

    /* Encrypt data */
    /* Check that we can get the required output buffer length by passing in a
     * NULL output buffer. */
    ExpectIntEQ(EVP_PKEY_encrypt(ctx, NULL, &outEncLen,
                            (const unsigned char*)in, inlen), WOLFSSL_SUCCESS);
    ExpectIntEQ(rsaKeySz, outEncLen);
    /* Now do the actual encryption. */
    ExpectIntEQ(EVP_PKEY_encrypt(ctx, outEnc, &outEncLen,
                            (const unsigned char*)in, inlen), WOLFSSL_SUCCESS);

    /* Decrypt data */
    ExpectIntEQ(EVP_PKEY_decrypt_init(ctx), WOLFSSL_SUCCESS);
    /* Check that we can get the required output buffer length by passing in a
     * NULL output buffer. */
    ExpectIntEQ(EVP_PKEY_decrypt(ctx, NULL, &outDecLen, outEnc, outEncLen),
                                 WOLFSSL_SUCCESS);
    ExpectIntEQ(rsaKeySz, outDecLen);
    /* Now do the actual decryption. */
    ExpectIntEQ(EVP_PKEY_decrypt(ctx, outDec, &outDecLen, outEnc, outEncLen),
                                 WOLFSSL_SUCCESS);

    ExpectIntEQ(XMEMCMP(in, outDec, outDecLen), 0);

#if !defined(HAVE_FIPS) && defined(WC_RSA_NO_PADDING)
    /* The input length must be the same size as the RSA key.*/
    ExpectNotNull(inTmp = (byte*)XMALLOC(rsaKeySz, HEAP_HINT,
        DYNAMIC_TYPE_TMP_BUFFER));
    if (inTmp != NULL) {
        XMEMSET(inTmp, 9, rsaKeySz);
    }
    ExpectNotNull(outEncTmp = (byte*)XMALLOC(rsaKeySz, HEAP_HINT,
        DYNAMIC_TYPE_TMP_BUFFER));
    if (outEncTmp != NULL) {
        XMEMSET(outEncTmp, 0, rsaKeySz);
    }
    ExpectNotNull(outDecTmp = (byte*)XMALLOC(rsaKeySz, HEAP_HINT,
        DYNAMIC_TYPE_TMP_BUFFER));
    if (outDecTmp != NULL) {
        XMEMSET(outDecTmp, 0, rsaKeySz);
    }
    ExpectIntEQ(EVP_PKEY_encrypt_init(ctx), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_encrypt(ctx, outEncTmp, &outEncLen, inTmp, rsaKeySz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_decrypt_init(ctx), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_decrypt(ctx, outDecTmp, &outDecLen, outEncTmp,
        outEncLen), WOLFSSL_SUCCESS);
    ExpectIntEQ(XMEMCMP(inTmp, outDecTmp, outDecLen), 0);
#endif
    EVP_PKEY_CTX_free(ctx);
    XFREE(outEnc, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(outDec, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#if !defined(HAVE_FIPS) && defined(WC_RSA_NO_PADDING)
    XFREE(inTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(outEncTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(outDecTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif
#endif
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_SELFTEST)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    #ifndef TEST_WOLFSSL_EVP_PKEY_SIGN_VERIFY
        #define TEST_WOLFSSL_EVP_PKEY_SIGN_VERIFY
    #endif
#endif
#endif
#if defined(OPENSSL_EXTRA)
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
    #ifndef TEST_WOLFSSL_EVP_PKEY_SIGN_VERIFY
        #define TEST_WOLFSSL_EVP_PKEY_SIGN_VERIFY
    #endif
#endif
#endif
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    #ifndef TEST_WOLFSSL_EVP_PKEY_SIGN_VERIFY
        #define TEST_WOLFSSL_EVP_PKEY_SIGN_VERIFY
    #endif
#endif
#endif

#ifdef TEST_WOLFSSL_EVP_PKEY_SIGN_VERIFY
static int test_wolfSSL_EVP_PKEY_sign_verify(int keyType)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_SELFTEST)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    WOLFSSL_RSA* rsa = NULL;
#endif
#endif
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
    WOLFSSL_DSA* dsa = NULL;
#endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    WOLFSSL_EC_KEY* ecKey = NULL;
#endif
#endif
    WOLFSSL_EVP_PKEY* pkey = NULL;
    WOLFSSL_EVP_PKEY_CTX* ctx = NULL;
    WOLFSSL_EVP_PKEY_CTX* ctx_verify = NULL;
    const char* in = "What is easy to do is easy not to do.";
    size_t inlen = XSTRLEN(in);
    byte hash[SHA256_DIGEST_LENGTH] = {0};
    byte zero[SHA256_DIGEST_LENGTH] = {0};
    SHA256_CTX c;
    byte*  sig = NULL;
    byte*  sigVerify = NULL;
    size_t siglen;
    size_t siglenOnlyLen;
    size_t keySz = 2048/8;  /* Bytes */

    ExpectNotNull(sig =
        (byte*)XMALLOC(keySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));
    ExpectNotNull(sigVerify =
        (byte*)XMALLOC(keySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));

    siglen = keySz;
    ExpectNotNull(XMEMSET(sig, 0, keySz));
    ExpectNotNull(XMEMSET(sigVerify, 0, keySz));

    /* Generate hash */
    SHA256_Init(&c);
    SHA256_Update(&c, in, inlen);
    SHA256_Final(hash, &c);
#ifdef WOLFSSL_SMALL_STACK_CACHE
    /* workaround for small stack cache case */
    wc_Sha256Free((wc_Sha256*)&c);
#endif

    /* Generate key */
    ExpectNotNull(pkey = EVP_PKEY_new());
    switch (keyType) {
        case EVP_PKEY_RSA:
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_SELFTEST)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
        {
            ExpectNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL));
            ExpectIntEQ(EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS);
        }
#endif
#endif
            break;
        case EVP_PKEY_DSA:
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
            ExpectNotNull(dsa = DSA_new());
            ExpectIntEQ(DSA_generate_parameters_ex(dsa, 2048,
                NULL, 0, NULL, NULL, NULL), 1);
            ExpectIntEQ(DSA_generate_key(dsa), 1);
            ExpectIntEQ(EVP_PKEY_set1_DSA(pkey, dsa), WOLFSSL_SUCCESS);
#endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
            break;
        case EVP_PKEY_EC:
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
        {
            ExpectNotNull(ecKey = EC_KEY_new());
            ExpectIntEQ(EC_KEY_generate_key(ecKey), 1);
            ExpectIntEQ(
                EVP_PKEY_assign_EC_KEY(pkey, ecKey), WOLFSSL_SUCCESS);
            if (EXPECT_FAIL()) {
                EC_KEY_free(ecKey);
            }
        }
#endif
#endif
            break;
    }
    ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));
    ExpectIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS);
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_SELFTEST)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    if (keyType == EVP_PKEY_RSA)
        ExpectIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING),
                    WOLFSSL_SUCCESS);
#endif
#endif

    /* Check returning only length */
    ExpectIntEQ(EVP_PKEY_sign(ctx, NULL, &siglenOnlyLen, hash,
        SHA256_DIGEST_LENGTH), WOLFSSL_SUCCESS);
    ExpectIntGT(siglenOnlyLen, 0);
    /* Sign data */
    ExpectIntEQ(EVP_PKEY_sign(ctx, sig, &siglen, hash,
        SHA256_DIGEST_LENGTH), WOLFSSL_SUCCESS);
    ExpectIntGE(siglenOnlyLen, siglen);

    /* Verify signature */
    ExpectNotNull(ctx_verify = EVP_PKEY_CTX_new(pkey, NULL));
    ExpectIntEQ(EVP_PKEY_verify_init(ctx_verify), WOLFSSL_SUCCESS);
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_SELFTEST)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    if (keyType == EVP_PKEY_RSA)
        ExpectIntEQ(
            EVP_PKEY_CTX_set_rsa_padding(ctx_verify, RSA_PKCS1_PADDING),
            WOLFSSL_SUCCESS);
#endif
#endif
    ExpectIntEQ(EVP_PKEY_verify(
        ctx_verify, sig, siglen, hash, SHA256_DIGEST_LENGTH),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_verify(
        ctx_verify, sig, siglen, zero, SHA256_DIGEST_LENGTH),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_SELFTEST)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    if (keyType == EVP_PKEY_RSA) {
    #if defined(WC_RSA_NO_PADDING) || defined(WC_RSA_DIRECT)
        /* Try RSA sign/verify with no padding. */
        ExpectIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS);
        ExpectIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING),
            WOLFSSL_SUCCESS);
        ExpectIntEQ(EVP_PKEY_sign(ctx, sigVerify, &siglen, sig,
            siglen), WOLFSSL_SUCCESS);
        ExpectIntGE(siglenOnlyLen, siglen);
        ExpectIntEQ(EVP_PKEY_verify_init(ctx_verify), WOLFSSL_SUCCESS);
        ExpectIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx_verify,
            RSA_NO_PADDING), WOLFSSL_SUCCESS);
        ExpectIntEQ(EVP_PKEY_verify(ctx_verify, sigVerify, siglen, sig,
            siglen), WOLFSSL_SUCCESS);
    #endif

        /* Wrong padding schemes. */
        ExpectIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS);
        ExpectIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx,
            RSA_PKCS1_OAEP_PADDING), WOLFSSL_SUCCESS);
        ExpectIntNE(EVP_PKEY_sign(ctx, sigVerify, &siglen, sig,
            siglen), WOLFSSL_SUCCESS);
        ExpectIntEQ(EVP_PKEY_verify_init(ctx_verify), WOLFSSL_SUCCESS);
        ExpectIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx_verify,
            RSA_PKCS1_OAEP_PADDING), WOLFSSL_SUCCESS);
        ExpectIntNE(EVP_PKEY_verify(ctx_verify, sigVerify, siglen, sig,
            siglen), WOLFSSL_SUCCESS);

        ExpectIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING),
            WOLFSSL_SUCCESS);
        ExpectIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx_verify,
            RSA_PKCS1_PADDING), WOLFSSL_SUCCESS);
    }
#endif
#endif

    /* error cases */
    siglen = keySz; /* Reset because sig size may vary slightly */
    ExpectIntNE(EVP_PKEY_sign_init(NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS);
    ExpectIntNE(EVP_PKEY_sign(NULL, sig, &siglen, (byte*)in, inlen),
                              WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_sign(ctx, sig, &siglen, (byte*)in, inlen),
                              WOLFSSL_SUCCESS);

    EVP_PKEY_free(pkey);
    pkey = NULL;
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
    DSA_free(dsa);
    dsa = NULL;
#endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
    EVP_PKEY_CTX_free(ctx_verify);
    ctx_verify = NULL;
    EVP_PKEY_CTX_free(ctx);
    ctx = NULL;

    XFREE(sig, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(sigVerify, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_EVP_PKEY_sign_verify_rsa(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
    !defined(HAVE_SELFTEST)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    ExpectIntEQ(test_wolfSSL_EVP_PKEY_sign_verify(EVP_PKEY_RSA), TEST_SUCCESS);
#endif
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_PKEY_sign_verify_dsa(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
    ExpectIntEQ(test_wolfSSL_EVP_PKEY_sign_verify(EVP_PKEY_DSA), TEST_SUCCESS);
#endif
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_PKEY_sign_verify_ec(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    ExpectIntEQ(test_wolfSSL_EVP_PKEY_sign_verify(EVP_PKEY_EC), TEST_SUCCESS);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_EVP_PKEY_rsa(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    WOLFSSL_RSA* rsa = NULL;
    WOLFSSL_EVP_PKEY* pkey = NULL;

    ExpectNotNull(rsa = wolfSSL_RSA_new());
    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectIntEQ(EVP_PKEY_assign_RSA(NULL, rsa), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_PKEY_assign_RSA(pkey, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS);
    if (EXPECT_FAIL()) {
        wolfSSL_RSA_free(rsa);
    }
    ExpectPtrEq(EVP_PKEY_get0_RSA(pkey), rsa);
    wolfSSL_EVP_PKEY_free(pkey);
#endif
    return EXPECT_RESULT();
}

static int test_EVP_PKEY_ec(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    WOLFSSL_EC_KEY* ecKey = NULL;
    WOLFSSL_EVP_PKEY* pkey = NULL;

    ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
    ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
    ExpectIntEQ(EVP_PKEY_assign_EC_KEY(NULL, ecKey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_PKEY_assign_EC_KEY(pkey, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Should fail since ecKey is empty */
    ExpectIntEQ(EVP_PKEY_assign_EC_KEY(pkey, ecKey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1);
    ExpectIntEQ(EVP_PKEY_assign_EC_KEY(pkey, ecKey), WOLFSSL_SUCCESS);
    if (EXPECT_FAIL()) {
        wolfSSL_EC_KEY_free(ecKey);
    }
    wolfSSL_EVP_PKEY_free(pkey);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_EVP_PKEY_cmp(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    EVP_PKEY *a = NULL;
    EVP_PKEY *b = NULL;
    const unsigned char *in;

#if !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048)
    in = client_key_der_2048;
    ExpectNotNull(a = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
        &in, (long)sizeof_client_key_der_2048));
    in = client_key_der_2048;
    ExpectNotNull(b = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
        &in, (long)sizeof_client_key_der_2048));

    /* Test success case RSA */
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
    ExpectIntEQ(EVP_PKEY_cmp(a, b), 1);
#else
    ExpectIntEQ(EVP_PKEY_cmp(a, b), 0);
#endif /* WOLFSSL_ERROR_CODE_OPENSSL */

    EVP_PKEY_free(b);
    b = NULL;
    EVP_PKEY_free(a);
    a = NULL;
#endif

#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
    in = ecc_clikey_der_256;
    ExpectNotNull(a = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL,
        &in, (long)sizeof_ecc_clikey_der_256));
    in = ecc_clikey_der_256;
    ExpectNotNull(b = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL,
        &in, (long)sizeof_ecc_clikey_der_256));

    /* Test success case ECC */
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
    ExpectIntEQ(EVP_PKEY_cmp(a, b), 1);
#else
    ExpectIntEQ(EVP_PKEY_cmp(a, b), 0);
#endif /* WOLFSSL_ERROR_CODE_OPENSSL */

    EVP_PKEY_free(b);
    b = NULL;
    EVP_PKEY_free(a);
    a = NULL;
#endif

    /* Test failure cases */
#if !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048) && \
     defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)

    in = client_key_der_2048;
    ExpectNotNull(a = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
        &in, (long)sizeof_client_key_der_2048));
    in = ecc_clikey_der_256;
    ExpectNotNull(b = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL,
        &in, (long)sizeof_ecc_clikey_der_256));

#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
    ExpectIntEQ(EVP_PKEY_cmp(a, b), -1);
#else
    ExpectIntNE(EVP_PKEY_cmp(a, b), 0);
#endif /* WOLFSSL_ERROR_CODE_OPENSSL */
    EVP_PKEY_free(b);
    b = NULL;
    EVP_PKEY_free(a);
    a = NULL;
#endif

    /* invalid or empty failure cases */
    a = EVP_PKEY_new();
    b = EVP_PKEY_new();
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
    ExpectIntEQ(EVP_PKEY_cmp(NULL, NULL), 0);
    ExpectIntEQ(EVP_PKEY_cmp(a, NULL), 0);
    ExpectIntEQ(EVP_PKEY_cmp(NULL, b), 0);
#ifdef NO_RSA
    /* Type check will fail since RSA is the default EVP key type */
    ExpectIntEQ(EVP_PKEY_cmp(a, b), -2);
#else
    ExpectIntEQ(EVP_PKEY_cmp(a, b), 0);
#endif
#else
    ExpectIntNE(EVP_PKEY_cmp(NULL, NULL), 0);
    ExpectIntNE(EVP_PKEY_cmp(a, NULL), 0);
    ExpectIntNE(EVP_PKEY_cmp(NULL, b), 0);
    ExpectIntNE(EVP_PKEY_cmp(a, b), 0);
#endif
    EVP_PKEY_free(b);
    EVP_PKEY_free(a);

    (void)in;
#endif
    return EXPECT_RESULT();
}

static int test_ERR_load_crypto_strings(void)
{
#if defined(OPENSSL_ALL)
    ERR_load_crypto_strings();
    return TEST_SUCCESS;
#else
    return TEST_SKIPPED;
#endif
}

#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
static void free_x509(X509* x)
{
    AssertIntEQ((x == (X509*)1 || x == (X509*)2), 1);
}
#endif

static int test_sk_X509(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
    {
        STACK_OF(X509)* s = NULL;

        ExpectNotNull(s = sk_X509_new_null());
        ExpectIntEQ(sk_X509_num(s), 0);
        sk_X509_pop_free(s, NULL);

        ExpectNotNull(s = sk_X509_new_null());
        ExpectIntEQ(sk_X509_num(s), 0);
        sk_X509_pop_free(s, NULL);

        ExpectNotNull(s = sk_X509_new_null());
        sk_X509_push(s, (X509*)1);
        ExpectIntEQ(sk_X509_num(s), 1);
        ExpectIntEQ((sk_X509_value(s, 0) == (X509*)1), 1);
        sk_X509_push(s, (X509*)2);
        ExpectIntEQ(sk_X509_num(s), 2);
        ExpectIntEQ((sk_X509_value(s, 0) == (X509*)2), 1);
        ExpectIntEQ((sk_X509_value(s, 1) == (X509*)1), 1);
        sk_X509_push(s, (X509*)2);
        sk_X509_pop_free(s, free_x509);
    }

    {
        /* Push a list of 10 X509s onto stack, then verify that
         * value(), push(), shift(), and pop() behave as expected. */
        STACK_OF(X509)* s = NULL;
        X509*     xList[10];
        int       i = 0;
        const int len = (sizeof(xList) / sizeof(xList[0]));

        for (i = 0; i < len; ++i) {
            xList[i] = NULL;
            ExpectNotNull(xList[i] = X509_new());
        }

        /* test push, pop, and free */
        ExpectNotNull(s = sk_X509_new_null());

        for (i = 0; i < len; ++i) {
            sk_X509_push(s, xList[i]);
            ExpectIntEQ(sk_X509_num(s), i + 1);
            ExpectIntEQ((sk_X509_value(s, 0) == xList[i]), 1);
            ExpectIntEQ((sk_X509_value(s, i) == xList[0]), 1);
        }

        /* pop returns and removes last pushed on stack, which is index 0
         * in sk_x509_value */
        for (i = 0; i < len; ++i) {
            X509 * x = sk_X509_value(s, 0);
            X509 * y = sk_X509_pop(s);
            X509 * z = xList[len - 1 - i];

            ExpectIntEQ((x == y), 1);
            ExpectIntEQ((x == z), 1);
            ExpectIntEQ(sk_X509_num(s), len - 1 - i);
        }

        sk_free(s);
        s = NULL;

        /* test push, shift, and free */
        ExpectNotNull(s = sk_X509_new_null());

        for (i = 0; i < len; ++i) {
            sk_X509_push(s, xList[i]);
            ExpectIntEQ(sk_X509_num(s), i + 1);
            ExpectIntEQ((sk_X509_value(s, 0) == xList[i]), 1);
            ExpectIntEQ((sk_X509_value(s, i) == xList[0]), 1);
        }

        /* shift returns and removes first pushed on stack, which is index i
         * in sk_x509_value() */
        for (i = 0; i < len; ++i) {
            X509 * x = sk_X509_value(s, len - 1 - i);
            X509 * y = sk_X509_shift(s);
            X509 * z = xList[i];

            ExpectIntEQ((x == y), 1);
            ExpectIntEQ((x == z), 1);
            ExpectIntEQ(sk_X509_num(s), len - 1 - i);
        }

        sk_free(s);

        for (i = 0; i < len; ++i)
            X509_free(xList[i]);
    }
#endif
    return EXPECT_RESULT();
}

static int test_sk_X509_CRL(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && defined(HAVE_CRL)
    X509_CRL* crl = NULL;
    XFILE fp = XBADFILE;
    STACK_OF(X509_CRL)* s = NULL;

    ExpectTrue((fp = XFOPEN("./certs/crl/crl.pem", "rb")) != XBADFILE);
    ExpectNotNull(crl = (X509_CRL*)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
        NULL, NULL));
    if (fp != XBADFILE)
        XFCLOSE(fp);

    ExpectNotNull(s = sk_X509_CRL_new());
    ExpectIntEQ(sk_X509_CRL_num(s), 0);
    ExpectIntEQ(sk_X509_CRL_push(s, crl), 1);
    if (EXPECT_FAIL()) {
        X509_CRL_free(crl);
    }
    ExpectIntEQ(sk_X509_CRL_num(s), 1);
    ExpectPtrEq(sk_X509_CRL_value(s, 0), crl);
    sk_X509_CRL_free(s);
#endif
    return EXPECT_RESULT();
}

static int test_X509_get_signature_nid(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    X509*   x509 = NULL;

    ExpectIntEQ(X509_get_signature_nid(NULL), 0);
    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(svrCertFile,
        SSL_FILETYPE_PEM));
    ExpectIntEQ(X509_get_signature_nid(x509), NID_sha256WithRSAEncryption);
    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_X509_REQ(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && !defined(NO_BIO)
    X509_NAME* name = NULL;
#ifndef NO_RSA
    X509_NAME* subject = NULL;
#endif
#if !defined(NO_RSA) || defined(HAVE_ECC)
    X509_REQ* req = NULL;
    EVP_PKEY* priv = NULL;
    EVP_PKEY* pub = NULL;
    unsigned char* der = NULL;
    int len;
#endif
#ifndef NO_RSA
    EVP_MD_CTX *mctx = NULL;
    EVP_PKEY_CTX *pkctx = NULL;
    #ifdef USE_CERT_BUFFERS_1024
    const unsigned char* rsaPriv = (const unsigned char*)client_key_der_1024;
    const unsigned char* rsaPub = (unsigned char*)client_keypub_der_1024;
    #elif defined(USE_CERT_BUFFERS_2048)
    const unsigned char* rsaPriv = (const unsigned char*)client_key_der_2048;
    const unsigned char* rsaPub = (unsigned char*)client_keypub_der_2048;
    #endif
#endif
#ifdef HAVE_ECC
    const unsigned char* ecPriv = (const unsigned char*)ecc_clikey_der_256;
    const unsigned char* ecPub = (unsigned char*)ecc_clikeypub_der_256;
#endif

    ExpectNotNull(name = X509_NAME_new());
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
        (byte*)"wolfssl.com", 11, 0, 1), WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
        (byte*)"support@wolfssl.com", 19, -1, 1), WOLFSSL_SUCCESS);

#ifndef NO_RSA
    ExpectNotNull(priv = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &rsaPriv,
        (long)sizeof_client_key_der_2048));
    ExpectNotNull(pub = d2i_PUBKEY(NULL, &rsaPub,
        (long)sizeof_client_keypub_der_2048));
    ExpectNotNull(req = X509_REQ_new());
    ExpectIntEQ(X509_REQ_set_subject_name(NULL, name), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_REQ_set_subject_name(req, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_REQ_set_subject_name(req, name), WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_REQ_set_pubkey(NULL, pub), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_REQ_set_pubkey(req, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_REQ_set_pubkey(req, pub), WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_REQ_sign(NULL, priv, EVP_sha256()), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_REQ_sign(req, NULL, EVP_sha256()), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_REQ_sign(req, priv, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_REQ_sign(req, priv, EVP_sha256()), WOLFSSL_SUCCESS);
    len = i2d_X509_REQ(req, &der);
    DEBUG_WRITE_DER(der, len, "req.der");
#ifdef USE_CERT_BUFFERS_1024
    ExpectIntEQ(len, 381);
#else
    ExpectIntEQ(len, 643);
#endif
    XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
    der = NULL;

    mctx = EVP_MD_CTX_new();
    ExpectIntEQ(EVP_DigestSignInit(mctx, &pkctx, EVP_sha256(), NULL, priv),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_REQ_sign_ctx(req, mctx), WOLFSSL_SUCCESS);

    EVP_MD_CTX_free(mctx);
    mctx = NULL;
    X509_REQ_free(NULL);
    X509_REQ_free(req);
    req = NULL;

    /* Test getting the subject from a newly created X509_REQ */
    ExpectNotNull(req = X509_REQ_new());
    ExpectNotNull(subject = X509_REQ_get_subject_name(req));
    ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_commonName,
        MBSTRING_UTF8, (unsigned char*)"www.wolfssl.com", -1, -1, 0), 1);
    ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_countryName,
        MBSTRING_UTF8, (unsigned char*)"US", -1, -1, 0), 1);
    ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_localityName,
        MBSTRING_UTF8, (unsigned char*)"Bozeman", -1, -1, 0), 1);
    ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_stateOrProvinceName,
        MBSTRING_UTF8, (unsigned char*)"Montana", -1, -1, 0), 1);
    ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_organizationName,
        MBSTRING_UTF8, (unsigned char*)"wolfSSL", -1, -1, 0), 1);
    ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_organizationalUnitName,
        MBSTRING_UTF8, (unsigned char*)"Testing", -1, -1, 0), 1);
    ExpectIntEQ(X509_REQ_set_pubkey(req, pub), WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_REQ_sign(req, priv, EVP_sha256()), WOLFSSL_SUCCESS);
    len = i2d_X509_REQ(req, &der);
    DEBUG_WRITE_DER(der, len, "req2.der");
#ifdef USE_CERT_BUFFERS_1024
    ExpectIntEQ(len, 435);
#else
    ExpectIntEQ(len, 696);
#endif
    XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
    der = NULL;

    EVP_PKEY_free(pub);
    pub = NULL;
    EVP_PKEY_free(priv);
    priv = NULL;
    X509_REQ_free(req);
    req = NULL;
#endif
#ifdef HAVE_ECC
    ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL, &ecPriv,
        sizeof_ecc_clikey_der_256));
    ExpectNotNull(pub = wolfSSL_d2i_PUBKEY(NULL, &ecPub,
        sizeof_ecc_clikeypub_der_256));
    ExpectNotNull(req = X509_REQ_new());
    ExpectIntEQ(X509_REQ_set_subject_name(req, name), WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_REQ_set_pubkey(req, pub), WOLFSSL_SUCCESS);
    ExpectIntEQ(X509_REQ_sign(req, priv, EVP_sha256()), WOLFSSL_SUCCESS);
    /* Signature is random and may be shorter or longer. */
    ExpectIntGE((len = i2d_X509_REQ(req, &der)), 245);
    ExpectIntLE(len, 253);
    XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
    X509_REQ_free(req);
    EVP_PKEY_free(pub);
    EVP_PKEY_free(priv);

#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif /* HAVE_ECC */

    X509_NAME_free(name);
#endif
    return EXPECT_RESULT();
}

static int test_wolfssl_PKCS7(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7) && !defined(NO_BIO) && \
    !defined(NO_RSA)
    PKCS7* pkcs7 = NULL;
    byte   data[FOURK_BUF];
    word32 len = sizeof(data);
    const byte*  p = data;
    byte   content[] = "Test data to encode.";
#if !defined(NO_RSA) & defined(USE_CERT_BUFFERS_2048)
    BIO*   bio = NULL;
    byte   key[sizeof(client_key_der_2048)];
    word32 keySz = (word32)sizeof(key);
    byte*  out = NULL;
#endif

    ExpectIntGT((len = (word32)CreatePKCS7SignedData(data, (int)len, content,
        (word32)sizeof(content), 0, 0, 0, RSA_TYPE)), 0);

    ExpectNull(pkcs7 = d2i_PKCS7(NULL, NULL, (int)len));
    ExpectNull(pkcs7 = d2i_PKCS7(NULL, &p, 0));
    ExpectNotNull(pkcs7 = d2i_PKCS7(NULL, &p, (int)len));
    ExpectIntEQ(wolfSSL_PKCS7_verify(NULL, NULL, NULL, NULL, NULL,
        PKCS7_NOVERIFY), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    PKCS7_free(pkcs7);
    pkcs7 = NULL;

    /* fail case, without PKCS7_NOVERIFY */
    p = data;
    ExpectNotNull(pkcs7 = d2i_PKCS7(NULL, &p, (int)len));
    ExpectIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, NULL, NULL,
        0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    PKCS7_free(pkcs7);
    pkcs7 = NULL;

    /* success case, with PKCS7_NOVERIFY */
    p = data;
    ExpectNotNull(pkcs7 = d2i_PKCS7(NULL, &p, (int)len));
    ExpectIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, NULL, NULL,
        PKCS7_NOVERIFY), WOLFSSL_SUCCESS);

#if !defined(NO_RSA) & defined(USE_CERT_BUFFERS_2048)
    /* test i2d */
    XMEMCPY(key, client_key_der_2048, keySz);
    if (pkcs7 != NULL) {
        pkcs7->privateKey = key;
        pkcs7->privateKeySz = (word32)sizeof(key);
        pkcs7->encryptOID = RSAk;
    #ifdef NO_SHA
        pkcs7->hashOID = SHA256h;
    #else
        pkcs7->hashOID = SHAh;
    #endif
    }
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(i2d_PKCS7_bio(bio, pkcs7), 1);
#ifndef NO_ASN_TIME
    ExpectIntEQ(i2d_PKCS7(pkcs7, &out), 655);
#else
    ExpectIntEQ(i2d_PKCS7(pkcs7, &out), 625);
#endif
    XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    BIO_free(bio);
#endif

    PKCS7_free(NULL);
    PKCS7_free(pkcs7);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PKCS7_sign(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7) && !defined(NO_BIO) && \
    !defined(NO_FILESYSTEM) && !defined(NO_RSA)

    PKCS7* p7 = NULL;
    PKCS7* p7Ver = NULL;
    byte* out = NULL;
    byte* tmpPtr = NULL;
    int outLen = 0;
    int flags = 0;
    byte data[] = "Test data to encode.";

    const char* cert = "./certs/server-cert.pem";
    const char* key  = "./certs/server-key.pem";
    const char* ca   = "./certs/ca-cert.pem";

    WOLFSSL_BIO* certBio = NULL;
    WOLFSSL_BIO* keyBio = NULL;
    WOLFSSL_BIO* caBio = NULL;
    WOLFSSL_BIO* inBio = NULL;
    X509* signCert = NULL;
    EVP_PKEY* signKey = NULL;
    X509* caCert = NULL;
    X509_STORE* store = NULL;
#ifndef NO_PKCS7_STREAM
    int z;
    int ret;
#endif /* !NO_PKCS7_STREAM */

    /* read signer cert/key into BIO */
    ExpectNotNull(certBio = BIO_new_file(cert, "r"));
    ExpectNotNull(keyBio = BIO_new_file(key, "r"));
    ExpectNotNull(signCert = PEM_read_bio_X509(certBio, NULL, 0, NULL));
    ExpectNotNull(signKey = PEM_read_bio_PrivateKey(keyBio, NULL, 0, NULL));

    /* read CA cert into store (for verify) */
    ExpectNotNull(caBio = BIO_new_file(ca, "r"));
    ExpectNotNull(caCert = PEM_read_bio_X509(caBio, NULL, 0, NULL));
    ExpectNotNull(store = X509_STORE_new());
    ExpectIntEQ(X509_STORE_add_cert(store, caCert), 1);

    /* data to be signed into BIO */
    ExpectNotNull(inBio = BIO_new(BIO_s_mem()));
    ExpectIntGT(BIO_write(inBio, data, sizeof(data)), 0);

    /* PKCS7_sign, bad args: signer NULL */
    ExpectNull(p7 = PKCS7_sign(NULL, signKey, NULL, inBio, 0));
    /* PKCS7_sign, bad args: signer key NULL */
    ExpectNull(p7 = PKCS7_sign(signCert, NULL, NULL, inBio, 0));
    /* PKCS7_sign, bad args: in data NULL without PKCS7_STREAM */
    ExpectNull(p7 = PKCS7_sign(signCert, signKey, NULL, NULL, 0));
    /* PKCS7_sign, bad args: PKCS7_NOCERTS flag not supported */
    ExpectNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, PKCS7_NOCERTS));
    /* PKCS7_sign, bad args: PKCS7_PARTIAL flag not supported */
    ExpectNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, PKCS7_PARTIAL));

    /* TEST SUCCESS: Not detached, not streaming, not MIME */
    {
        flags = PKCS7_BINARY;
        ExpectNotNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, flags));
        ExpectIntGT((outLen = i2d_PKCS7(p7, &out)), 0);

        /* verify with d2i_PKCS7 */
        tmpPtr = out;
        ExpectNotNull(p7Ver = d2i_PKCS7(NULL, (const byte**)&tmpPtr, outLen));
        ExpectIntEQ(PKCS7_verify(p7Ver, NULL, store, NULL, NULL, flags), 1);
        PKCS7_free(p7Ver);
        p7Ver = NULL;

        /* verify with wc_PKCS7_VerifySignedData */
        ExpectNotNull(p7Ver = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_Init(p7Ver, HEAP_HINT, INVALID_DEVID), 0);
        ExpectIntEQ(wc_PKCS7_VerifySignedData(p7Ver, out, (word32)outLen), 0);

    #ifndef NO_PKCS7_STREAM
        /* verify with wc_PKCS7_VerifySignedData streaming */
        wc_PKCS7_Free(p7Ver);
        p7Ver = NULL;
        ExpectNotNull(p7Ver = wc_PKCS7_New(HEAP_HINT, testDevId));
        ExpectIntEQ(wc_PKCS7_Init(p7Ver, HEAP_HINT, INVALID_DEVID), 0);
        /* test for streaming */
        ret = -1;
        for (z = 0; z < outLen && ret != 0; z++) {
            ret = wc_PKCS7_VerifySignedData(p7Ver, out + z, 1);
            if (ret < 0){
                ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
            }
        }
        ExpectIntEQ(ret, 0);
    #endif /* !NO_PKCS7_STREAM */

        /* compare the signer found to expected signer */
        ExpectIntNE(p7Ver->verifyCertSz, 0);
        tmpPtr = NULL;
        ExpectIntEQ(i2d_X509(signCert, &tmpPtr), p7Ver->verifyCertSz);
        ExpectIntEQ(XMEMCMP(tmpPtr, p7Ver->verifyCert, p7Ver->verifyCertSz), 0);
        XFREE(tmpPtr, NULL, DYNAMIC_TYPE_OPENSSL);
        tmpPtr = NULL;

        wc_PKCS7_Free(p7Ver);
        p7Ver = NULL;

        ExpectNotNull(out);
        XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        out = NULL;
        PKCS7_free(p7);
        p7 = NULL;
    }

    /* TEST SUCCESS: Not detached, streaming, not MIME. Also bad arg
     * tests for PKCS7_final() while we have a PKCS7 pointer to use */
    {
        /* re-populate input BIO, may have been consumed */
        BIO_free(inBio);
        inBio = NULL;
        ExpectNotNull(inBio = BIO_new(BIO_s_mem()));
        ExpectIntGT(BIO_write(inBio, data, sizeof(data)), 0);

        flags = PKCS7_BINARY | PKCS7_STREAM;
        ExpectNotNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, flags));
        ExpectIntEQ(PKCS7_final(p7, inBio, flags), 1);
        ExpectIntGT((outLen = i2d_PKCS7(p7, &out)), 0);

        /* PKCS7_final, bad args: PKCS7 null */
        ExpectIntEQ(PKCS7_final(NULL, inBio, 0), 0);
        /* PKCS7_final, bad args: PKCS7 null */
        ExpectIntEQ(PKCS7_final(p7, NULL, 0), 0);

        tmpPtr = out;
        ExpectNotNull(p7Ver = d2i_PKCS7(NULL, (const byte**)&tmpPtr, outLen));
        ExpectIntEQ(PKCS7_verify(p7Ver, NULL, store, NULL, NULL, flags), 1);
        PKCS7_free(p7Ver);
        p7Ver = NULL;

        ExpectNotNull(out);
        XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        out = NULL;
        PKCS7_free(p7);
        p7 = NULL;
    }

    /* TEST SUCCESS: Detached, not streaming, not MIME */
    {
        /* re-populate input BIO, may have been consumed */
        BIO_free(inBio);
        inBio = NULL;
        ExpectNotNull(inBio = BIO_new(BIO_s_mem()));
        ExpectIntGT(BIO_write(inBio, data, sizeof(data)), 0);

        flags = PKCS7_BINARY | PKCS7_DETACHED;
        ExpectNotNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, flags));
        ExpectIntGT((outLen = i2d_PKCS7(p7, &out)), 0);

        /* verify with wolfCrypt, d2i_PKCS7 does not support detached content */
        ExpectNotNull(p7Ver = wc_PKCS7_New(HEAP_HINT, testDevId));
        if (p7Ver != NULL) {
            p7Ver->content = data;
            p7Ver->contentSz = sizeof(data);
        }
        ExpectIntEQ(wc_PKCS7_VerifySignedData(p7Ver, out, (word32)outLen), 0);
        wc_PKCS7_Free(p7Ver);
        p7Ver = NULL;

    #ifndef NO_PKCS7_STREAM
        /* verify with wc_PKCS7_VerifySignedData streaming */
        ExpectNotNull(p7Ver = wc_PKCS7_New(HEAP_HINT, testDevId));
        if (p7Ver != NULL) {
            p7Ver->content = data;
            p7Ver->contentSz = sizeof(data);
        }
        /* test for streaming */
        ret = -1;
        for (z = 0; z < outLen && ret != 0; z++) {
            ret = wc_PKCS7_VerifySignedData(p7Ver, out + z, 1);
            if (ret < 0){
                ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
            }
        }
        ExpectIntEQ(ret, 0);
        wc_PKCS7_Free(p7Ver);
        p7Ver = NULL;
    #endif /* !NO_PKCS7_STREAM */

        /* verify expected failure (NULL return) from d2i_PKCS7, it does not
         * yet support detached content */
        tmpPtr = out;
        ExpectNull(p7Ver = d2i_PKCS7(NULL, (const byte**)&tmpPtr, outLen));
        PKCS7_free(p7Ver);
        p7Ver = NULL;

        ExpectNotNull(out);
        XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        out = NULL;
        PKCS7_free(p7);
        p7 = NULL;
    }

    /* TEST SUCCESS: Detached, streaming, not MIME */
    {
        /* re-populate input BIO, may have been consumed */
        BIO_free(inBio);
        inBio = NULL;
        ExpectNotNull(inBio = BIO_new(BIO_s_mem()));
        ExpectIntGT(BIO_write(inBio, data, sizeof(data)), 0);

        flags = PKCS7_BINARY | PKCS7_DETACHED | PKCS7_STREAM;
        ExpectNotNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, flags));
        ExpectIntEQ(PKCS7_final(p7, inBio, flags), 1);
        ExpectIntGT((outLen = i2d_PKCS7(p7, &out)), 0);

        /* verify with wolfCrypt, d2i_PKCS7 does not support detached content */
        ExpectNotNull(p7Ver = wc_PKCS7_New(HEAP_HINT, testDevId));
        if (p7Ver != NULL) {
            p7Ver->content = data;
            p7Ver->contentSz = sizeof(data);
        }
        ExpectIntEQ(wc_PKCS7_VerifySignedData(p7Ver, out, (word32)outLen), 0);
        wc_PKCS7_Free(p7Ver);
        p7Ver = NULL;

        ExpectNotNull(out);

    #ifndef NO_PKCS7_STREAM
        /* verify with wc_PKCS7_VerifySignedData streaming */
        ExpectNotNull(p7Ver = wc_PKCS7_New(HEAP_HINT, testDevId));
        if (p7Ver != NULL) {
            p7Ver->content = data;
            p7Ver->contentSz = sizeof(data);
        }
        /* test for streaming */
        ret = -1;
        for (z = 0; z < outLen && ret != 0; z++) {
            ret = wc_PKCS7_VerifySignedData(p7Ver, out + z, 1);
            if (ret < 0){
                ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
            }
        }
        ExpectIntEQ(ret, 0);
        ExpectNotNull(out);
        wc_PKCS7_Free(p7Ver);
        p7Ver = NULL;
    #endif /* !NO_PKCS7_STREAM */

        XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        PKCS7_free(p7);
        p7 = NULL;
    }

    X509_STORE_free(store);
    X509_free(caCert);
    X509_free(signCert);
    EVP_PKEY_free(signKey);
    BIO_free(inBio);
    BIO_free(keyBio);
    BIO_free(certBio);
    BIO_free(caBio);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PKCS7_SIGNED_new(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7)
    PKCS7_SIGNED* pkcs7 = NULL;

    ExpectNotNull(pkcs7 = PKCS7_SIGNED_new());
    ExpectIntEQ(pkcs7->contentOID, SIGNED_DATA);

    PKCS7_SIGNED_free(pkcs7);
#endif
    return EXPECT_RESULT();
}

#ifndef NO_BIO
static int test_wolfSSL_PEM_write_bio_PKCS7(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM)
    PKCS7* pkcs7 = NULL;
    BIO* bio = NULL;
    const byte* cert_buf = NULL;
    int ret = 0;
    WC_RNG rng;
    const byte data[] = { /* Hello World */
        0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
        0x72,0x6c,0x64
    };
#ifndef NO_RSA
    #if defined(USE_CERT_BUFFERS_2048)
        byte        key[sizeof(client_key_der_2048)];
        byte        cert[sizeof(client_cert_der_2048)];
        word32      keySz = (word32)sizeof(key);
        word32      certSz = (word32)sizeof(cert);
        XMEMSET(key, 0, keySz);
        XMEMSET(cert, 0, certSz);
        XMEMCPY(key, client_key_der_2048, keySz);
        XMEMCPY(cert, client_cert_der_2048, certSz);
    #elif defined(USE_CERT_BUFFERS_1024)
        byte        key[sizeof_client_key_der_1024];
        byte        cert[sizeof(sizeof_client_cert_der_1024)];
        word32      keySz = (word32)sizeof(key);
        word32      certSz = (word32)sizeof(cert);
        XMEMSET(key, 0, keySz);
        XMEMSET(cert, 0, certSz);
        XMEMCPY(key, client_key_der_1024, keySz);
        XMEMCPY(cert, client_cert_der_1024, certSz);
    #else
        unsigned char   cert[ONEK_BUF];
        unsigned char   key[ONEK_BUF];
        XFILE           fp = XBADFILE;
        int             certSz;
        int             keySz;

        ExpectTrue((fp = XFOPEN("./certs/1024/client-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, sizeof_client_cert_der_1024,
            fp), 0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }

        ExpectTrue((fp = XFOPEN("./certs/1024/client-key.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(keySz = (int)XFREAD(key, 1, sizeof_client_key_der_1024, fp),
            0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }
    #endif
#elif defined(HAVE_ECC)
    #if defined(USE_CERT_BUFFERS_256)
        unsigned char    cert[sizeof(cliecc_cert_der_256)];
        unsigned char    key[sizeof(ecc_clikey_der_256)];
        int              certSz = (int)sizeof(cert);
        int              keySz = (int)sizeof(key);
        XMEMSET(cert, 0, certSz);
        XMEMSET(key, 0, keySz);
        XMEMCPY(cert, cliecc_cert_der_256, sizeof_cliecc_cert_der_256);
        XMEMCPY(key, ecc_clikey_der_256, sizeof_ecc_clikey_der_256);
    #else
        unsigned char   cert[ONEK_BUF];
        unsigned char   key[ONEK_BUF];
        XFILE           fp = XBADFILE;
        int             certSz, keySz;

        ExpectTrue((fp = XFOPEN("./certs/client-ecc-cert.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(certSz = (int)XFREAD(cert, 1, sizeof_cliecc_cert_der_256,
            fp), 0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }

        ExpectTrue((fp = XFOPEN("./certs/client-ecc-key.der", "rb")) !=
            XBADFILE);
        ExpectIntGT(keySz = (int)XFREAD(key, 1, sizeof_ecc_clikey_der_256, fp),
            0);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }
    #endif
#else
    #error PKCS7 requires ECC or RSA
#endif

    ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
    /* initialize with DER encoded cert */
    ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)cert, (word32)certSz), 0);

    /* init rng */
    XMEMSET(&rng, 0, sizeof(WC_RNG));
    ExpectIntEQ(wc_InitRng(&rng), 0);

    if (pkcs7 != NULL) {
        pkcs7->rng = &rng;
        pkcs7->content   = (byte*)data; /* not used for ex */
        pkcs7->contentSz = (word32)sizeof(data);
        pkcs7->contentOID = SIGNED_DATA;
        pkcs7->privateKey = key;
        pkcs7->privateKeySz = (word32)sizeof(key);
        pkcs7->encryptOID = RSAk;
    #ifdef NO_SHA
        pkcs7->hashOID = SHA256h;
    #else
        pkcs7->hashOID = SHAh;
    #endif
        pkcs7->signedAttribs   = NULL;
        pkcs7->signedAttribsSz = 0;
    }

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    /* Write PKCS#7 PEM to BIO, the function converts the DER to PEM cert*/
    ExpectIntEQ(PEM_write_bio_PKCS7(bio, pkcs7), WOLFSSL_SUCCESS);

    /* Read PKCS#7 PEM from BIO */
    ret = wolfSSL_BIO_get_mem_data(bio, &cert_buf);
    ExpectIntGE(ret, 0);

    BIO_free(bio);
    wc_PKCS7_Free(pkcs7);
    wc_FreeRng(&rng);
#endif
    return EXPECT_RESULT();
}

#ifdef HAVE_SMIME
/* // NOLINTBEGIN(clang-analyzer-unix.Stream) */
static int test_wolfSSL_SMIME_read_PKCS7(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA)
    PKCS7* pkcs7 = NULL;
    BIO* bio = NULL;
    BIO* bcont = NULL;
    BIO* out = NULL;
    const byte* outBuf = NULL;
    int outBufLen = 0;
    static const char contTypeText[] = "Content-Type: text/plain\r\n\r\n";
    XFILE smimeTestFile = XBADFILE;

    ExpectTrue((smimeTestFile = XFOPEN("./certs/test/smime-test.p7s", "r")) !=
        XBADFILE);

    /* smime-test.p7s */
    bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
    ExpectNotNull(bio);
    ExpectIntEQ(wolfSSL_BIO_set_fp(bio, smimeTestFile, BIO_CLOSE), SSL_SUCCESS);
    pkcs7 = wolfSSL_SMIME_read_PKCS7(bio, &bcont);
    ExpectNotNull(pkcs7);
    ExpectIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, bcont, NULL,
        PKCS7_NOVERIFY), SSL_SUCCESS);
    if (smimeTestFile != XBADFILE) {
        XFCLOSE(smimeTestFile);
        smimeTestFile = XBADFILE;
    }
    if (bcont) BIO_free(bcont);
    bcont = NULL;
    wolfSSL_PKCS7_free(pkcs7);
    pkcs7 = NULL;

    /* smime-test-multipart.p7s */
    smimeTestFile = XFOPEN("./certs/test/smime-test-multipart.p7s", "r");
    ExpectFalse(smimeTestFile == XBADFILE);
    ExpectIntEQ(wolfSSL_BIO_set_fp(bio, smimeTestFile, BIO_CLOSE), SSL_SUCCESS);
    pkcs7 = wolfSSL_SMIME_read_PKCS7(bio, &bcont);
    ExpectNotNull(pkcs7);
    ExpectIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, bcont, NULL,
        PKCS7_NOVERIFY), SSL_SUCCESS);
    if (smimeTestFile != XBADFILE) {
        XFCLOSE(smimeTestFile);
        smimeTestFile = XBADFILE;
    }
    if (bcont) BIO_free(bcont);
    bcont = NULL;
    wolfSSL_PKCS7_free(pkcs7);
    pkcs7 = NULL;

    /* smime-test-multipart-badsig.p7s */
    smimeTestFile = XFOPEN("./certs/test/smime-test-multipart-badsig.p7s", "r");
    ExpectFalse(smimeTestFile == XBADFILE);
    ExpectIntEQ(wolfSSL_BIO_set_fp(bio, smimeTestFile, BIO_CLOSE), SSL_SUCCESS);
    pkcs7 = wolfSSL_SMIME_read_PKCS7(bio, &bcont);
    ExpectNotNull(pkcs7); /* can read in the unverified smime bundle */
    ExpectIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, bcont, NULL,
        PKCS7_NOVERIFY), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    if (smimeTestFile != XBADFILE) {
        XFCLOSE(smimeTestFile);
        smimeTestFile = XBADFILE;
    }
    if (bcont) BIO_free(bcont);
    bcont = NULL;
    wolfSSL_PKCS7_free(pkcs7);
    pkcs7 = NULL;

    /* smime-test-canon.p7s */
    smimeTestFile = XFOPEN("./certs/test/smime-test-canon.p7s", "r");
    ExpectFalse(smimeTestFile == XBADFILE);
    ExpectIntEQ(wolfSSL_BIO_set_fp(bio, smimeTestFile, BIO_CLOSE), SSL_SUCCESS);
    pkcs7 = wolfSSL_SMIME_read_PKCS7(bio, &bcont);
    ExpectNotNull(pkcs7);
    ExpectIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, bcont, NULL,
        PKCS7_NOVERIFY), SSL_SUCCESS);
    if (smimeTestFile != XBADFILE) {
        XFCLOSE(smimeTestFile);
        smimeTestFile = XBADFILE;
    }
    if (bcont) BIO_free(bcont);
    bcont = NULL;
    wolfSSL_PKCS7_free(pkcs7);
    pkcs7 = NULL;

    /* Test PKCS7_TEXT, PKCS7_verify() should remove Content-Type: text/plain */
    smimeTestFile = XFOPEN("./certs/test/smime-test-canon.p7s", "r");
    ExpectFalse(smimeTestFile == XBADFILE);
    ExpectIntEQ(wolfSSL_BIO_set_fp(bio, smimeTestFile, BIO_CLOSE), SSL_SUCCESS);
    pkcs7 = wolfSSL_SMIME_read_PKCS7(bio, &bcont);
    ExpectNotNull(pkcs7);
    out = wolfSSL_BIO_new(BIO_s_mem());
    ExpectNotNull(out);
    ExpectIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, bcont, out,
        PKCS7_NOVERIFY | PKCS7_TEXT), SSL_SUCCESS);
    ExpectIntGT((outBufLen = BIO_get_mem_data(out, &outBuf)), 0);
    /* Content-Type should not show up at beginning of output buffer */
    ExpectIntGT(outBufLen, XSTRLEN(contTypeText));
    ExpectIntGT(XMEMCMP(outBuf, contTypeText, XSTRLEN(contTypeText)), 0);

    BIO_free(out);
    BIO_free(bio);
    if (bcont) BIO_free(bcont);
    wolfSSL_PKCS7_free(pkcs7);
#endif
    return EXPECT_RESULT();
}
/* // NOLINTEND(clang-analyzer-unix.Stream) */

static int test_wolfSSL_SMIME_write_PKCS7(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7) && !defined(NO_RSA)
    PKCS7* p7 = NULL;
    PKCS7* p7Ver = NULL;
    int flags = 0;
    byte data[] = "Test data to encode.";

    const char* cert = "./certs/server-cert.pem";
    const char* key  = "./certs/server-key.pem";
    const char* ca   = "./certs/ca-cert.pem";

    WOLFSSL_BIO* certBio = NULL;
    WOLFSSL_BIO* keyBio  = NULL;
    WOLFSSL_BIO* caBio   = NULL;
    WOLFSSL_BIO* inBio   = NULL;
    WOLFSSL_BIO* outBio  = NULL;
    WOLFSSL_BIO* content = NULL;
    X509* signCert = NULL;
    EVP_PKEY* signKey = NULL;
    X509* caCert = NULL;
    X509_STORE* store = NULL;

    /* read signer cert/key into BIO */
    ExpectNotNull(certBio = BIO_new_file(cert, "r"));
    ExpectNotNull(keyBio = BIO_new_file(key, "r"));
    ExpectNotNull(signCert = PEM_read_bio_X509(certBio, NULL, 0, NULL));
    ExpectNotNull(signKey = PEM_read_bio_PrivateKey(keyBio, NULL, 0, NULL));

    /* read CA cert into store (for verify) */
    ExpectNotNull(caBio = BIO_new_file(ca, "r"));
    ExpectNotNull(caCert = PEM_read_bio_X509(caBio, NULL, 0, NULL));
    ExpectNotNull(store = X509_STORE_new());
    ExpectIntEQ(X509_STORE_add_cert(store, caCert), 1);


    /* generate and verify SMIME: not detached */
    {
        ExpectNotNull(inBio = BIO_new(BIO_s_mem()));
        ExpectIntGT(BIO_write(inBio, data, sizeof(data)), 0);

        flags = PKCS7_STREAM;
        ExpectNotNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, flags));
        ExpectNotNull(outBio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(SMIME_write_PKCS7(outBio, p7, inBio, flags), 1);

        /* bad arg: out NULL */
        ExpectIntEQ(SMIME_write_PKCS7(NULL, p7, inBio, flags), 0);
        /* bad arg: pkcs7 NULL */
        ExpectIntEQ(SMIME_write_PKCS7(outBio, NULL, inBio, flags), 0);

        ExpectNotNull(p7Ver = SMIME_read_PKCS7(outBio, &content));
        ExpectIntEQ(PKCS7_verify(p7Ver, NULL, store, NULL, NULL, flags), 1);

        BIO_free(content);
        content = NULL;
        BIO_free(inBio);
        inBio = NULL;
        BIO_free(outBio);
        outBio = NULL;
        PKCS7_free(p7Ver);
        p7Ver = NULL;
        PKCS7_free(p7);
        p7 = NULL;
    }

    /* generate and verify SMIME: not detached, add Content-Type */
    {
        ExpectNotNull(inBio = BIO_new(BIO_s_mem()));
        ExpectIntGT(BIO_write(inBio, data, sizeof(data)), 0);

        flags = PKCS7_STREAM | PKCS7_TEXT;
        ExpectNotNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, flags));
        ExpectNotNull(outBio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(SMIME_write_PKCS7(outBio, p7, inBio, flags), 1);

        ExpectNotNull(p7Ver = SMIME_read_PKCS7(outBio, &content));
        ExpectIntEQ(PKCS7_verify(p7Ver, NULL, store, NULL, NULL, flags), 1);

        BIO_free(content);
        content = NULL;
        BIO_free(inBio);
        inBio = NULL;
        BIO_free(outBio);
        outBio = NULL;
        PKCS7_free(p7Ver);
        p7Ver = NULL;
        PKCS7_free(p7);
        p7 = NULL;
    }

    /* generate and verify SMIME: detached */
    {
        ExpectNotNull(inBio = BIO_new(BIO_s_mem()));
        ExpectIntGT(BIO_write(inBio, data, sizeof(data)), 0);

        flags = PKCS7_DETACHED | PKCS7_STREAM;
        ExpectNotNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, flags));
        ExpectNotNull(outBio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(SMIME_write_PKCS7(outBio, p7, inBio, flags), 1);

        ExpectNotNull(p7Ver = SMIME_read_PKCS7(outBio, &content));
        ExpectIntEQ(PKCS7_verify(p7Ver, NULL, store, content, NULL, flags), 1);

        BIO_free(content);
        content = NULL;
        BIO_free(inBio);
        inBio = NULL;
        BIO_free(outBio);
        outBio = NULL;
        PKCS7_free(p7Ver);
        p7Ver = NULL;
        PKCS7_free(p7);
        p7 = NULL;
    }

    /* generate and verify SMIME: PKCS7_TEXT to add Content-Type header */
    {
        ExpectNotNull(inBio = BIO_new(BIO_s_mem()));
        ExpectIntGT(BIO_write(inBio, data, sizeof(data)), 0);

        flags = PKCS7_STREAM | PKCS7_DETACHED | PKCS7_TEXT;
        ExpectNotNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, flags));
        ExpectNotNull(outBio = BIO_new(BIO_s_mem()));
        ExpectIntEQ(SMIME_write_PKCS7(outBio, p7, inBio, flags), 1);

        ExpectNotNull(p7Ver = SMIME_read_PKCS7(outBio, &content));
        ExpectIntEQ(PKCS7_verify(p7Ver, NULL, store, content, NULL, flags), 1);

        BIO_free(content);
        content = NULL;
        BIO_free(inBio);
        inBio = NULL;
        BIO_free(outBio);
        outBio = NULL;
        PKCS7_free(p7Ver);
        p7Ver = NULL;
        PKCS7_free(p7);
        p7 = NULL;
    }

    X509_STORE_free(store);
    X509_free(caCert);
    X509_free(signCert);
    EVP_PKEY_free(signKey);
    BIO_free(keyBio);
    BIO_free(certBio);
    BIO_free(caBio);
#endif
    return EXPECT_RESULT();
}
#endif /* HAVE_SMIME */
#endif /* !NO_BIO */

/* Test of X509 store use outside of SSL context w/ CRL lookup (ALWAYS
 * returns 0) */
static int test_X509_STORE_No_SSL_CTX(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
    (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
    !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)  && \
    (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
    defined(HAVE_CRL) && !defined(NO_RSA)

    X509_STORE *     store = NULL;
    X509_STORE_CTX * storeCtx = NULL;
    X509_CRL *       crl = NULL;
    X509 *           ca = NULL;
    X509 *           cert = NULL;
    const char       cliCrlPem[] = "./certs/crl/cliCrl.pem";
    const char       srvCert[] = "./certs/server-cert.pem";
    const char       caCert[] = "./certs/ca-cert.pem";
    const char       caDir[] = "./certs/crl/hash_pem";
    XFILE            fp = XBADFILE;
    X509_LOOKUP *    lookup = NULL;

    ExpectNotNull(store = (X509_STORE *)X509_STORE_new());

    /* Set up store with CA */
    ExpectNotNull((ca = wolfSSL_X509_load_certificate_file(caCert,
        SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_add_cert(store, ca), SSL_SUCCESS);

    /* Add CRL lookup directory to store
     * NOTE: test uses ./certs/crl/hash_pem/0fdb2da4.r0, which is a copy
     * of crl.pem */
    ExpectNotNull((lookup = X509_STORE_add_lookup(store,
        X509_LOOKUP_hash_dir())));
    ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, caDir,
        X509_FILETYPE_PEM, NULL), SSL_SUCCESS);

    ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK),
        SSL_SUCCESS);

    /* Add CRL to store NOT containing the verified certificate, which
     * forces use of the CRL lookup directory */
    ExpectTrue((fp = XFOPEN(cliCrlPem, "rb")) != XBADFILE);
    ExpectNotNull(crl = (X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
        NULL, NULL));
    if (fp != XBADFILE)
        XFCLOSE(fp);
    ExpectIntEQ(X509_STORE_add_crl(store, crl), SSL_SUCCESS);

    /* Create verification context outside of an SSL session */
    ExpectNotNull((storeCtx = X509_STORE_CTX_new()));
    ExpectNotNull((cert = wolfSSL_X509_load_certificate_file(srvCert,
        SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_CTX_init(storeCtx, store, cert, NULL), SSL_SUCCESS);

    /* Perform verification, which should NOT indicate CRL missing due to the
     * store CM's X509 store pointer being NULL */
    ExpectIntNE(X509_verify_cert(storeCtx), WC_NO_ERR_TRACE(CRL_MISSING));

    X509_CRL_free(crl);
    X509_STORE_free(store);
    X509_STORE_CTX_free(storeCtx);
    X509_free(cert);
    X509_free(ca);
#endif
    return EXPECT_RESULT();
}

/* Test of X509 store use outside of SSL context w/ CRL lookup, but
 * with X509_LOOKUP_add_dir and X509_FILETYPE_ASN1. */
static int test_X509_LOOKUP_add_dir(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
    (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
    !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)  && \
    (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
    defined(HAVE_CRL) && !defined(NO_RSA)

    X509_STORE *     store = NULL;
    X509_STORE_CTX * storeCtx = NULL;
    X509_CRL *       crl = NULL;
    X509 *           ca = NULL;
    X509 *           cert = NULL;
    const char       cliCrlPem[] = "./certs/crl/cliCrl.pem";
    const char       srvCert[] = "./certs/server-cert.pem";
    const char       caCert[] = "./certs/ca-cert.pem";
    const char       caDir[] = "./certs/crl/hash_der";
    XFILE            fp = XBADFILE;
    X509_LOOKUP *    lookup = NULL;

    ExpectNotNull(store = (X509_STORE *)X509_STORE_new());

    /* Set up store with CA */
    ExpectNotNull((ca = wolfSSL_X509_load_certificate_file(caCert,
        SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_add_cert(store, ca), SSL_SUCCESS);

    /* Add CRL lookup directory to store.
     * Test uses ./certs/crl/hash_der/0fdb2da4.r0, which is a copy
     * of crl.der */
    ExpectNotNull((lookup = X509_STORE_add_lookup(store,
        X509_LOOKUP_hash_dir())));

    ExpectIntEQ(X509_LOOKUP_add_dir(lookup, caDir, X509_FILETYPE_ASN1),
        SSL_SUCCESS);

    ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK),
        SSL_SUCCESS);

    /* Add CRL to store NOT containing the verified certificate, which
     * forces use of the CRL lookup directory */
    ExpectTrue((fp = XFOPEN(cliCrlPem, "rb")) != XBADFILE);
    ExpectNotNull(crl = (X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
        NULL, NULL));
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }
    ExpectIntEQ(X509_STORE_add_crl(store, crl), SSL_SUCCESS);

    /* Create verification context outside of an SSL session */
    ExpectNotNull((storeCtx = X509_STORE_CTX_new()));
    ExpectNotNull((cert = wolfSSL_X509_load_certificate_file(srvCert,
        SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_CTX_init(storeCtx, store, cert, NULL), SSL_SUCCESS);

    /* Perform verification, which should NOT return CRL missing */
    ExpectIntNE(X509_verify_cert(storeCtx), WC_NO_ERR_TRACE(CRL_MISSING));

    X509_CRL_free(crl);
    crl = NULL;
    X509_STORE_free(store);
    store = NULL;
    X509_STORE_CTX_free(storeCtx);
    storeCtx = NULL;
    X509_free(cert);
    cert = NULL;
    X509_free(ca);
    ca = NULL;

    /* Now repeat the same, but look for X509_FILETYPE_PEM.
     * We should get CRL_MISSING at the end, because the lookup
     * dir has only ASN1 CRLs. */

    ExpectNotNull(store = (X509_STORE *)X509_STORE_new());

    ExpectNotNull((ca = wolfSSL_X509_load_certificate_file(caCert,
        SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_add_cert(store, ca), SSL_SUCCESS);

    ExpectNotNull((lookup = X509_STORE_add_lookup(store,
        X509_LOOKUP_hash_dir())));

    ExpectIntEQ(X509_LOOKUP_add_dir(lookup, caDir, X509_FILETYPE_PEM),
        SSL_SUCCESS);

    ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK),
        SSL_SUCCESS);

    ExpectTrue((fp = XFOPEN(cliCrlPem, "rb")) != XBADFILE);
    ExpectNotNull(crl = (X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
        NULL, NULL));
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }
    ExpectIntEQ(X509_STORE_add_crl(store, crl), SSL_SUCCESS);

    ExpectNotNull((storeCtx = X509_STORE_CTX_new()));
    ExpectNotNull((cert = wolfSSL_X509_load_certificate_file(srvCert,
        SSL_FILETYPE_PEM)));
    ExpectIntEQ(X509_STORE_CTX_init(storeCtx, store, cert, NULL), SSL_SUCCESS);

    /* Now we SHOULD get CRL_MISSING, because we looked for PEM
     * in dir containing only ASN1/DER. */
    ExpectIntEQ(X509_verify_cert(storeCtx), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(X509_STORE_CTX_get_error(storeCtx),
            X509_V_ERR_UNABLE_TO_GET_CRL);

    X509_CRL_free(crl);
    X509_STORE_free(store);
    X509_STORE_CTX_free(storeCtx);
    X509_free(cert);
    X509_free(ca);
#endif
    return EXPECT_RESULT();
}



/*----------------------------------------------------------------------------*
 | Certificate Failure Checks
 *----------------------------------------------------------------------------*/
#if !defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
                   !defined(WOLFSSL_NO_CLIENT_AUTH)) && !defined(NO_FILESYSTEM)
#if !defined(NO_RSA) || defined(HAVE_ECC)
/* Use the Cert Manager(CM) API to generate the error ASN_SIG_CONFIRM_E */
static int verify_sig_cm(const char* ca, byte* cert_buf, size_t cert_sz,
    int type)
{
    int ret;
    WOLFSSL_CERT_MANAGER* cm = NULL;

    switch (type) {
        case TESTING_RSA:
        #ifdef NO_RSA
            fprintf(stderr, "RSA disabled, skipping test\n");
            return ASN_SIG_CONFIRM_E;
        #else
            break;
        #endif
        case TESTING_ECC:
        #ifndef HAVE_ECC
            fprintf(stderr, "ECC disabled, skipping test\n");
            return ASN_SIG_CONFIRM_E;
        #else
            break;
        #endif
        default:
            fprintf(stderr, "Bad function argument\n");
            return BAD_FUNC_ARG;
    }
    cm = wolfSSL_CertManagerNew();
    if (cm == NULL) {
        fprintf(stderr, "wolfSSL_CertManagerNew failed\n");
        return -1;
    }

#ifndef NO_FILESYSTEM
    ret = wolfSSL_CertManagerLoadCA(cm, ca, 0);
    if (ret != WOLFSSL_SUCCESS) {
        fprintf(stderr, "wolfSSL_CertManagerLoadCA failed\n");
        wolfSSL_CertManagerFree(cm);
        return ret;
    }
#else
    (void)ca;
#endif

    ret = wolfSSL_CertManagerVerifyBuffer(cm, cert_buf, (long int)cert_sz,
        WOLFSSL_FILETYPE_ASN1);
    /* Let ExpectIntEQ handle return code */

    wolfSSL_CertManagerFree(cm);

    return ret;
}
#endif

#if !defined(NO_FILESYSTEM)
static int test_RsaSigFailure_cm(void)
{
    EXPECT_DECLS;
#ifndef NO_RSA
    const char* ca_cert = "./certs/ca-cert.pem";
    const char* server_cert = "./certs/server-cert.der";
    byte* cert_buf = NULL;
    size_t cert_sz = 0;

    ExpectIntEQ(load_file(server_cert, &cert_buf, &cert_sz), 0);
    if ((cert_buf != NULL) && (cert_sz > 0)) {
        /* corrupt DER - invert last byte, which is signature */
        cert_buf[cert_sz-1] = ~cert_buf[cert_sz-1];
        /* test bad cert */
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
        ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_RSA),
           WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#elif defined(NO_ASN_CRYPT)
        /* RSA verify is not called when ASN crypt support is disabled */
        ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_RSA),
           WOLFSSL_SUCCESS);
#else
        ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_RSA),
           WC_NO_ERR_TRACE(ASN_SIG_CONFIRM_E));
#endif
    }

    /* load_file() uses malloc. */
    if (cert_buf != NULL) {
        free(cert_buf);
    }
#endif /* !NO_RSA */
    return EXPECT_RESULT();
}

static int test_EccSigFailure_cm(void)
{
    EXPECT_DECLS;
#ifdef HAVE_ECC
    /* self-signed ECC cert, so use server cert as CA */
    const char* ca_cert = "./certs/ca-ecc-cert.pem";
    const char* server_cert = "./certs/server-ecc.der";
    byte* cert_buf = NULL;
    size_t cert_sz = 0;

    ExpectIntEQ(load_file(server_cert, &cert_buf, &cert_sz), 0);
    if (cert_buf != NULL && cert_sz > 0) {
        /* corrupt DER - invert last byte, which is signature */
        cert_buf[cert_sz-1] = ~cert_buf[cert_sz-1];

        /* test bad cert */
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
        ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_ECC),
           WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#elif defined(NO_ASN_CRYPT)
        /* ECC verify is not called when ASN crypt support is disabled */
        ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_ECC),
           WOLFSSL_SUCCESS);
#else
        ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_ECC),
           WC_NO_ERR_TRACE(ASN_SIG_CONFIRM_E));
#endif
    }

    /* load_file() uses malloc. */
    if (cert_buf != NULL) {
        free(cert_buf);
    }
#ifdef FP_ECC
    wc_ecc_fp_free();
#endif
#endif /* HAVE_ECC */
    return EXPECT_RESULT();
}

#endif /* !NO_FILESYSTEM */
#endif /* NO_CERTS */

#ifdef WOLFSSL_TLS13
#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
#ifdef WC_SHA384_DIGEST_SIZE
    static byte fixedKey[WC_SHA384_DIGEST_SIZE] = { 0, };
#else
    static byte fixedKey[WC_SHA256_DIGEST_SIZE] = { 0, };
#endif
#endif
#ifdef WOLFSSL_EARLY_DATA
static const char earlyData[] = "Early Data";
static       char earlyDataBuffer[1];
#endif

static int test_tls13_apis(void)
{
    EXPECT_DECLS;
    int          ret;
#ifndef WOLFSSL_NO_TLS12
#ifndef NO_WOLFSSL_CLIENT
    WOLFSSL_CTX* clientTls12Ctx = NULL;
    WOLFSSL*     clientTls12Ssl = NULL;
#endif
#ifndef NO_WOLFSSL_SERVER
    WOLFSSL_CTX* serverTls12Ctx = NULL;
    WOLFSSL*     serverTls12Ssl = NULL;
#endif
#endif
#ifndef NO_WOLFSSL_CLIENT
    WOLFSSL_CTX* clientCtx = NULL;
    WOLFSSL*     clientSsl = NULL;
#endif
#ifndef NO_WOLFSSL_SERVER
    WOLFSSL_CTX* serverCtx = NULL;
    WOLFSSL*     serverSsl = NULL;
#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM)
    const char*  ourCert = svrCertFile;
    const char*  ourKey  = svrKeyFile;
#endif
#endif
    int          required;
#ifdef WOLFSSL_EARLY_DATA
    int          outSz;
#endif
#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
    int          groups[2] = { WOLFSSL_ECC_SECP256R1,
#ifdef WOLFSSL_HAVE_KYBER
    #ifndef WOLFSSL_NO_KYBER512
                               WOLFSSL_KYBER_LEVEL1
    #elif !defined(WOLFSSL_NO_KYBER768)
                               WOLFSSL_KYBER_LEVEL3
    #else
                               WOLFSSL_KYBER_LEVEL5
    #endif
#else
                               WOLFSSL_ECC_SECP256R1
#endif
                             };
#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT)
    int          bad_groups[2] = { 0xDEAD, 0xBEEF };
#endif /* !NO_WOLFSSL_SERVER || !NO_WOLFSSL_CLIENT */
    int          numGroups = 2;
#endif
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
    char         groupList[] =
#ifdef HAVE_CURVE25519
            "X25519:"
#endif
#ifdef HAVE_CURVE448
            "X448:"
#endif
#ifndef NO_ECC_SECP
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
            "P-521:secp521r1:"
#endif
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
            "P-384:secp384r1:"
#endif
#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
            "P-256:secp256r1"
#if defined(WOLFSSL_HAVE_KYBER)
    #ifndef WOLFSSL_NO_KYBER512
            ":P256_KYBER_LEVEL1"
    #elif !defined(WOLFSSL_NO_KYBER768)
            ":P256_KYBER_LEVEL3"
    #else
            ":P256_KYBER_LEVEL5"
    #endif
#endif
#endif
#endif /* !defined(NO_ECC_SECP) */
#if defined(WOLFSSL_HAVE_KYBER)
    #ifndef WOLFSSL_NO_KYBER512
            ":KYBER_LEVEL1"
    #elif !defined(WOLFSSL_NO_KYBER768)
            ":KYBER_LEVEL3"
    #else
            ":KYBER_LEVEL5"
    #endif
#endif
            "";
#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */
#if defined(WOLFSSL_HAVE_KYBER)
    int kyberLevel;
#endif

    (void)ret;

#ifndef WOLFSSL_NO_TLS12
#ifndef NO_WOLFSSL_CLIENT
    clientTls12Ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
    clientTls12Ssl = wolfSSL_new(clientTls12Ctx);
#endif
#ifndef NO_WOLFSSL_SERVER
    serverTls12Ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM)
    wolfSSL_CTX_use_certificate_chain_file(serverTls12Ctx, ourCert);
    wolfSSL_CTX_use_PrivateKey_file(serverTls12Ctx, ourKey,
        WOLFSSL_FILETYPE_PEM);
#endif
    serverTls12Ssl = wolfSSL_new(serverTls12Ctx);
#endif
#endif

#ifndef NO_WOLFSSL_CLIENT
    clientCtx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
    clientSsl = wolfSSL_new(clientCtx);
#endif
#ifndef NO_WOLFSSL_SERVER
    serverCtx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM)
    wolfSSL_CTX_use_certificate_chain_file(serverCtx, ourCert);
    wolfSSL_CTX_use_PrivateKey_file(serverCtx, ourKey, WOLFSSL_FILETYPE_PEM);
#endif
    serverSsl = wolfSSL_new(serverCtx);
    ExpectNotNull(serverSsl);
#endif

#ifdef WOLFSSL_SEND_HRR_COOKIE
    ExpectIntEQ(wolfSSL_send_hrr_cookie(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_send_hrr_cookie(clientSsl, NULL, 0), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_SERVER
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_send_hrr_cookie(serverTls12Ssl, NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    ExpectIntEQ(wolfSSL_send_hrr_cookie(serverSsl, NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_send_hrr_cookie(serverSsl, fixedKey, sizeof(fixedKey)),
        WOLFSSL_SUCCESS);
#endif
#endif

#ifdef HAVE_SUPPORTED_CURVES
#ifdef HAVE_ECC
    ExpectIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_ECC_SECP256R1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_SERVER
    do {
        ret = wolfSSL_UseKeyShare(serverSsl, WOLFSSL_ECC_SECP256R1);
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
            wolfSSL_AsyncPoll(serverSsl, WOLF_POLL_FLAG_CHECK_HW);
    #endif
    }
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    do {
        ret = wolfSSL_UseKeyShare(clientTls12Ssl, WOLFSSL_ECC_SECP256R1);
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
            wolfSSL_AsyncPoll(clientTls12Ssl, WOLF_POLL_FLAG_CHECK_HW);
    #endif
    }
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);
#endif
    do {
        ret = wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_SECP256R1);
    #ifdef WOLFSSL_ASYNC_CRYPT
        if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
            wolfSSL_AsyncPoll(clientSsl, WOLF_POLL_FLAG_CHECK_HW);
    #endif
    }
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);
#endif
#elif defined(HAVE_CURVE25519)
    ExpectIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_ECC_X25519), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_UseKeyShare(serverSsl, WOLFSSL_ECC_X25519),
        WOLFSSL_SUCCESS);
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_UseKeyShare(clientTls12Ssl, WOLFSSL_ECC_X25519),
        WOLFSSL_SUCCESS);
#endif
    ExpectIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_X25519),
        WOLFSSL_SUCCESS);
#endif
#elif defined(HAVE_CURVE448)
    ExpectIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_ECC_X448), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_UseKeyShare(serverSsl, WOLFSSL_ECC_X448),
        WOLFSSL_SUCCESS);
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_UseKeyShare(clientTls12Ssl, WOLFSSL_ECC_X448),
        WOLFSSL_SUCCESS);
#endif
    ExpectIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_X448),
        WOLFSSL_SUCCESS);
#endif
#else
    ExpectIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_ECC_SECP256R1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_UseKeyShare(clientTls12Ssl, WOLFSSL_ECC_SECP256R1),
        WC_NO_ERR_TRACE(NOT_COMPILED_IN));
#endif
    ExpectIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_SECP256R1),
        WC_NO_ERR_TRACE(NOT_COMPILED_IN));
#endif
#endif

#if defined(WOLFSSL_HAVE_KYBER)
#ifndef WOLFSSL_NO_KYBER768
    kyberLevel = WOLFSSL_KYBER_LEVEL3;
#elif !defined(WOLFSSL_NO_KYBER1024)
    kyberLevel = WOLFSSL_KYBER_LEVEL5;
#else
    kyberLevel = WOLFSSL_KYBER_LEVEL1;
#endif
    ExpectIntEQ(wolfSSL_UseKeyShare(NULL, kyberLevel), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_UseKeyShare(serverSsl, kyberLevel),
        WOLFSSL_SUCCESS);
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_UseKeyShare(clientTls12Ssl, kyberLevel),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_UseKeyShare(clientSsl, kyberLevel),
        WOLFSSL_SUCCESS);
#endif
#endif

    ExpectIntEQ(wolfSSL_NoKeyShares(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_NoKeyShares(serverSsl), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_NoKeyShares(clientTls12Ssl), WOLFSSL_SUCCESS);
#endif
    ExpectIntEQ(wolfSSL_NoKeyShares(clientSsl), WOLFSSL_SUCCESS);
#endif
#endif /* HAVE_SUPPORTED_CURVES */

    ExpectIntEQ(wolfSSL_CTX_no_ticket_TLSv13(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_CTX_no_ticket_TLSv13(clientCtx), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_SERVER
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_CTX_no_ticket_TLSv13(serverTls12Ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_CTX_no_ticket_TLSv13(serverCtx), 0);
#endif

    ExpectIntEQ(wolfSSL_no_ticket_TLSv13(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_no_ticket_TLSv13(clientSsl), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_SERVER
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_no_ticket_TLSv13(serverTls12Ssl), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_no_ticket_TLSv13(serverSsl), 0);
#endif

    ExpectIntEQ(wolfSSL_CTX_no_dhe_psk(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_CTX_no_dhe_psk(clientTls12Ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_CTX_no_dhe_psk(clientCtx), 0);
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_CTX_no_dhe_psk(serverCtx), 0);
#endif

    ExpectIntEQ(wolfSSL_no_dhe_psk(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_no_dhe_psk(clientTls12Ssl), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_no_dhe_psk(clientSsl), 0);
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_no_dhe_psk(serverSsl), 0);
#endif

    ExpectIntEQ(wolfSSL_update_keys(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_update_keys(clientTls12Ssl), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_update_keys(clientSsl), WC_NO_ERR_TRACE(BUILD_MSG_ERROR));
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_update_keys(serverSsl), WC_NO_ERR_TRACE(BUILD_MSG_ERROR));
#endif

    ExpectIntEQ(wolfSSL_key_update_response(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_key_update_response(NULL, &required), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_key_update_response(clientTls12Ssl, &required),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_key_update_response(clientSsl, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_key_update_response(serverSsl, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

#if !defined(NO_CERTS) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
    ExpectIntEQ(wolfSSL_CTX_allow_post_handshake_auth(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_CTX_allow_post_handshake_auth(serverCtx), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_CTX_allow_post_handshake_auth(clientTls12Ctx),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_CTX_allow_post_handshake_auth(clientCtx), 0);
#endif

    ExpectIntEQ(wolfSSL_allow_post_handshake_auth(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_allow_post_handshake_auth(serverSsl), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_allow_post_handshake_auth(clientTls12Ssl),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_allow_post_handshake_auth(clientSsl), 0);
#endif

    ExpectIntEQ(wolfSSL_request_certificate(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_request_certificate(clientSsl), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_SERVER
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_request_certificate(serverTls12Ssl),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_request_certificate(serverSsl), WC_NO_ERR_TRACE(NOT_READY_ERROR));
#endif
#endif

#ifdef HAVE_ECC
#ifndef WOLFSSL_NO_SERVER_GROUPS_EXT
    ExpectIntEQ(wolfSSL_preferred_group(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_preferred_group(serverSsl), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_preferred_group(clientTls12Ssl), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_preferred_group(clientSsl), WC_NO_ERR_TRACE(NOT_READY_ERROR));
#endif
#endif

#ifdef HAVE_SUPPORTED_CURVES
    ExpectIntEQ(wolfSSL_CTX_set_groups(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_CTX_set_groups(clientCtx, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_CTX_set_groups(NULL, groups, numGroups), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_CTX_set_groups(clientTls12Ctx, groups, numGroups),
        WOLFSSL_SUCCESS);
#endif
    ExpectIntEQ(wolfSSL_CTX_set_groups(clientCtx, groups,
        WOLFSSL_MAX_GROUP_COUNT + 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_set_groups(clientCtx, groups, numGroups),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_set_groups(clientCtx, bad_groups, numGroups),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_CTX_set_groups(serverCtx, groups, numGroups),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_set_groups(serverCtx, bad_groups, numGroups),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

    ExpectIntEQ(wolfSSL_set_groups(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_set_groups(clientSsl, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_set_groups(NULL, groups, numGroups), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_set_groups(clientTls12Ssl, groups, numGroups),
        WOLFSSL_SUCCESS);
#endif
    ExpectIntEQ(wolfSSL_set_groups(clientSsl, groups,
        WOLFSSL_MAX_GROUP_COUNT + 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_set_groups(clientSsl, groups, numGroups),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_set_groups(clientSsl, bad_groups, numGroups),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_set_groups(serverSsl, groups, numGroups),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_set_groups(serverSsl, bad_groups, numGroups),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

#ifdef OPENSSL_EXTRA
    ExpectIntEQ(wolfSSL_CTX_set1_groups_list(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_CTX_set1_groups_list(clientCtx, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
    ExpectIntEQ(wolfSSL_CTX_set1_groups_list(NULL, groupList),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_CTX_set1_groups_list(clientTls12Ctx, groupList),
        WOLFSSL_SUCCESS);
#endif
    ExpectIntEQ(wolfSSL_CTX_set1_groups_list(clientCtx, groupList),
        WOLFSSL_SUCCESS);
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_CTX_set1_groups_list(serverCtx, groupList),
        WOLFSSL_SUCCESS);
#endif

    ExpectIntEQ(wolfSSL_set1_groups_list(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_set1_groups_list(clientSsl, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
    ExpectIntEQ(wolfSSL_set1_groups_list(NULL, groupList), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_set1_groups_list(clientTls12Ssl, groupList),
        WOLFSSL_SUCCESS);
#endif
    ExpectIntEQ(wolfSSL_set1_groups_list(clientSsl, groupList),
        WOLFSSL_SUCCESS);
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_set1_groups_list(serverSsl, groupList),
        WOLFSSL_SUCCESS);
#endif
#endif /* OPENSSL_EXTRA */
#endif /* HAVE_SUPPORTED_CURVES */
#endif /* HAVE_ECC */

#ifdef WOLFSSL_EARLY_DATA
#ifndef OPENSSL_EXTRA
    ExpectIntEQ(wolfSSL_CTX_set_max_early_data(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_get_max_early_data(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#else
    ExpectIntEQ(SSL_CTX_set_max_early_data(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(SSL_CTX_get_max_early_data(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef OPENSSL_EXTRA
    ExpectIntEQ(wolfSSL_CTX_set_max_early_data(clientCtx, 0), WC_NO_ERR_TRACE(SIDE_ERROR));
    ExpectIntEQ(wolfSSL_CTX_get_max_early_data(clientCtx), WC_NO_ERR_TRACE(SIDE_ERROR));
#else
    ExpectIntEQ(SSL_CTX_set_max_early_data(clientCtx, 0), WC_NO_ERR_TRACE(SIDE_ERROR));
    ExpectIntEQ(SSL_CTX_get_max_early_data(clientCtx), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#endif
#ifndef NO_WOLFSSL_SERVER
#ifndef WOLFSSL_NO_TLS12
#ifndef OPENSSL_EXTRA
    ExpectIntEQ(wolfSSL_CTX_set_max_early_data(serverTls12Ctx, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_get_max_early_data(serverTls12Ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#else
    ExpectIntEQ(SSL_CTX_set_max_early_data(serverTls12Ctx, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(SSL_CTX_get_max_early_data(serverTls12Ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#endif
#ifndef OPENSSL_EXTRA
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
    ExpectIntEQ(wolfSSL_CTX_set_max_early_data(serverCtx, 32),
        WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(wolfSSL_CTX_set_max_early_data(serverCtx, 32), 0);
#endif
    ExpectIntEQ(wolfSSL_CTX_get_max_early_data(serverCtx), 32);
#else
    ExpectIntEQ(SSL_CTX_set_max_early_data(serverCtx, 32), 1);
    ExpectIntEQ(SSL_CTX_get_max_early_data(serverCtx), 32);
#endif
#endif

#ifndef OPENSSL_EXTRA
    ExpectIntEQ(wolfSSL_set_max_early_data(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_get_max_early_data(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#else
    ExpectIntEQ(SSL_set_max_early_data(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(SSL_get_max_early_data(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef OPENSSL_EXTRA
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
    ExpectIntEQ(wolfSSL_set_max_early_data(clientSsl, 17), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(wolfSSL_set_max_early_data(clientSsl, 17), 0);
#endif
    ExpectIntEQ(wolfSSL_get_max_early_data(clientSsl), 17);
#else
    ExpectIntEQ(SSL_set_max_early_data(clientSsl, 17), WOLFSSL_SUCCESS);
    ExpectIntEQ(SSL_get_max_early_data(clientSsl), 17);
#endif
#endif
#ifndef NO_WOLFSSL_SERVER
#ifndef WOLFSSL_NO_TLS12
#ifndef OPENSSL_EXTRA
    ExpectIntEQ(wolfSSL_set_max_early_data(serverTls12Ssl, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_get_max_early_data(serverTls12Ssl), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#else
    ExpectIntEQ(SSL_set_max_early_data(serverTls12Ssl, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(SSL_get_max_early_data(serverTls12Ssl), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#endif
#ifndef OPENSSL_EXTRA
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
    ExpectIntEQ(wolfSSL_set_max_early_data(serverSsl, 16), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(wolfSSL_set_max_early_data(serverSsl, 16), 0);
#endif
    ExpectIntEQ(wolfSSL_get_max_early_data(serverSsl), 16);
#else
    ExpectIntEQ(SSL_set_max_early_data(serverSsl, 16), 1);
    ExpectIntEQ(SSL_get_max_early_data(serverSsl), 16);
#endif
#endif


    ExpectIntEQ(wolfSSL_write_early_data(NULL, earlyData, sizeof(earlyData),
        &outSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_write_early_data(clientSsl, NULL, sizeof(earlyData),
        &outSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_write_early_data(clientSsl, earlyData, -1, &outSz),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_write_early_data(clientSsl, earlyData,
        sizeof(earlyData), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_write_early_data(serverSsl, earlyData,
        sizeof(earlyData), &outSz), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_write_early_data(clientTls12Ssl, earlyData,
        sizeof(earlyData), &outSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_write_early_data(clientSsl, earlyData,
        sizeof(earlyData), &outSz), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#endif

    ExpectIntEQ(wolfSSL_read_early_data(NULL, earlyDataBuffer,
        sizeof(earlyDataBuffer), &outSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_SERVER
    ExpectIntEQ(wolfSSL_read_early_data(serverSsl, NULL,
        sizeof(earlyDataBuffer), &outSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_read_early_data(serverSsl, earlyDataBuffer, -1,
        &outSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_read_early_data(serverSsl, earlyDataBuffer,
        sizeof(earlyDataBuffer), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef NO_WOLFSSL_CLIENT
    ExpectIntEQ(wolfSSL_read_early_data(clientSsl, earlyDataBuffer,
        sizeof(earlyDataBuffer), &outSz), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
#ifndef NO_WOLFSSL_SERVER
#ifndef WOLFSSL_NO_TLS12
    ExpectIntEQ(wolfSSL_read_early_data(serverTls12Ssl, earlyDataBuffer,
        sizeof(earlyDataBuffer), &outSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
    ExpectIntEQ(wolfSSL_read_early_data(serverSsl, earlyDataBuffer,
        sizeof(earlyDataBuffer), &outSz), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#endif
#endif

#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_EARLY_DATA)
    ExpectIntLT(SSL_get_early_data_status(NULL), 0);
#endif


#ifndef NO_WOLFSSL_SERVER
    wolfSSL_free(serverSsl);
    wolfSSL_CTX_free(serverCtx);
#endif
#ifndef NO_WOLFSSL_CLIENT
    wolfSSL_free(clientSsl);
    wolfSSL_CTX_free(clientCtx);
#endif

#ifndef WOLFSSL_NO_TLS12
#ifndef NO_WOLFSSL_SERVER
    wolfSSL_free(serverTls12Ssl);
    wolfSSL_CTX_free(serverTls12Ctx);
#endif
#ifndef NO_WOLFSSL_CLIENT
    wolfSSL_free(clientTls12Ssl);
    wolfSSL_CTX_free(clientTls12Ctx);
#endif
#endif

    return EXPECT_RESULT();
}

#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) && \
    defined(HAVE_ECC) && defined(BUILD_TLS_AES_128_GCM_SHA256) && \
    defined(BUILD_TLS_AES_256_GCM_SHA384)
/* Called when writing. */
static int CsSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
    (void)ssl;
    (void)buf;
    (void)sz;
    (void)ctx;

    /* Force error return from wolfSSL_accept_TLSv13(). */
    return WANT_WRITE;
}
/* Called when reading. */
static int CsRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
    WOLFSSL_BUFFER_INFO* msg = (WOLFSSL_BUFFER_INFO*)ctx;
    int len = (int)msg->length;

    (void)ssl;
    (void)sz;

    /* Pass back as much of message as will fit in buffer. */
    if (len > sz)
        len = sz;
    XMEMCPY(buf, msg->buffer, len);
    /* Move over returned data. */
    msg->buffer += len;
    msg->length -= len;

    /* Amount actually copied. */
    return len;
}
#endif

static int test_tls13_cipher_suites(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) && \
    defined(HAVE_ECC) && defined(BUILD_TLS_AES_128_GCM_SHA256) && \
    defined(BUILD_TLS_AES_256_GCM_SHA384)
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL *ssl = NULL;
    int i;
    byte clientHello[] = {
        0x16, 0x03, 0x03, 0x01, 0x9b, 0x01, 0x00, 0x01,
        0x97, 0x03, 0x03, 0xf4, 0x65, 0xbd, 0x22, 0xfe,
        0x6e, 0xab, 0x66, 0xdd, 0xcf, 0xe9, 0x65, 0x55,
        0xe8, 0xdf, 0xc3, 0x8e, 0x4b, 0x00, 0xbc, 0xf8,
        0x23, 0x57, 0x1b, 0xa0, 0xc8, 0xa9, 0xe2, 0x8c,
        0x91, 0x6e, 0xf9, 0x20, 0xf7, 0x5c, 0xc5, 0x5b,
        0x75, 0x8c, 0x47, 0x0a, 0x0e, 0xc4, 0x1a, 0xda,
        0xef, 0x75, 0xe5, 0x21, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
        /* Cipher suites: 0x13, 0x01 = TLS13-AES128-GCM-SHA256, twice. */
                                            0x13, 0x01,
        0x13, 0x01, 0x01, 0x00, 0x01, 0x4a, 0x00, 0x2d,
        0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x33, 0x00,
        0x47, 0x00, 0x45, 0x00, 0x17, 0x00, 0x41, 0x04,
        0x90, 0xfc, 0xe2, 0x97, 0x05, 0x7c, 0xb5, 0x23,
        0x5d, 0x5f, 0x5b, 0xcd, 0x0c, 0x1e, 0xe0, 0xe9,
        0xab, 0x38, 0x6b, 0x1e, 0x20, 0x5c, 0x1c, 0x90,
        0x2a, 0x9e, 0x68, 0x8e, 0x70, 0x05, 0x10, 0xa8,
        0x02, 0x1b, 0xf9, 0x5c, 0xef, 0xc9, 0xaf, 0xca,
        0x1a, 0x3b, 0x16, 0x8b, 0xe4, 0x1b, 0x3c, 0x15,
        0xb8, 0x0d, 0xbd, 0xaf, 0x62, 0x8d, 0xa7, 0x13,
        0xa0, 0x7c, 0xe0, 0x59, 0x0c, 0x4f, 0x8a, 0x6d,
        0x00, 0x2b, 0x00, 0x03, 0x02, 0x03, 0x04, 0x00,
        0x0d, 0x00, 0x20, 0x00, 0x1e, 0x06, 0x03, 0x05,
        0x03, 0x04, 0x03, 0x02, 0x03, 0x08, 0x06, 0x08,
        0x0b, 0x08, 0x05, 0x08, 0x0a, 0x08, 0x04, 0x08,
        0x09, 0x06, 0x01, 0x05, 0x01, 0x04, 0x01, 0x03,
        0x01, 0x02, 0x01, 0x00, 0x0a, 0x00, 0x04, 0x00,
        0x02, 0x00, 0x17, 0x00, 0x16, 0x00, 0x00, 0x00,
        0x23, 0x00, 0x00, 0x00, 0x29, 0x00, 0xb9, 0x00,
        0x94, 0x00, 0x8e, 0x0f, 0x12, 0xfa, 0x84, 0x1f,
        0x76, 0x94, 0xd7, 0x09, 0x5e, 0xad, 0x08, 0x51,
        0xb6, 0x80, 0x28, 0x31, 0x8b, 0xfd, 0xc6, 0xbd,
        0x9e, 0xf5, 0x3b, 0x4d, 0x02, 0xbe, 0x1d, 0x73,
        0xea, 0x13, 0x68, 0x00, 0x4c, 0xfd, 0x3d, 0x48,
        0x51, 0xf9, 0x06, 0xbb, 0x92, 0xed, 0x42, 0x9f,
        0x7f, 0x2c, 0x73, 0x9f, 0xd9, 0xb4, 0xef, 0x05,
        0x26, 0x5b, 0x60, 0x5c, 0x0a, 0xfc, 0xa3, 0xbd,
        0x2d, 0x2d, 0x8b, 0xf9, 0xaa, 0x5c, 0x96, 0x3a,
        0xf2, 0xec, 0xfa, 0xe5, 0x57, 0x2e, 0x87, 0xbe,
        0x27, 0xc5, 0x3d, 0x4f, 0x5d, 0xdd, 0xde, 0x1c,
        0x1b, 0xb3, 0xcc, 0x27, 0x27, 0x57, 0x5a, 0xd9,
        0xea, 0x99, 0x27, 0x23, 0xa6, 0x0e, 0xea, 0x9c,
        0x0d, 0x85, 0xcb, 0x72, 0xeb, 0xd7, 0x93, 0xe3,
        0xfe, 0xf7, 0x5c, 0xc5, 0x5b, 0x75, 0x8c, 0x47,
        0x0a, 0x0e, 0xc4, 0x1a, 0xda, 0xef, 0x75, 0xe5,
        0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0xfb, 0x92, 0xce, 0xaa, 0x00, 0x21, 0x20,
        0xcb, 0x73, 0x25, 0x80, 0x46, 0x78, 0x4f, 0xe5,
        0x34, 0xf6, 0x91, 0x13, 0x7f, 0xc8, 0x8d, 0xdc,
        0x81, 0x04, 0xb7, 0x0d, 0x49, 0x85, 0x2e, 0x12,
        0x7a, 0x07, 0x23, 0xe9, 0x13, 0xa4, 0x6d, 0x8c
    };
    WOLFSSL_BUFFER_INFO msg;
    /* Offset into ClientHello message data of first cipher suite. */
    const int csOff = 78;
    /* Server cipher list. */
    const char* serverCs = "TLS13-AES256-GCM-SHA384:TLS13-AES128-GCM-SHA256";
    /* Suite list with duplicates. */
    const char* dupCs = "TLS13-AES128-GCM-SHA256:"
                        "TLS13-AES128-GCM-SHA256:"
                        "TLS13-AES256-GCM-SHA384:"
                        "TLS13-AES256-GCM-SHA384:"
                        "TLS13-AES128-GCM-SHA256";
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
    const byte dupCsBytes[] = { TLS13_BYTE, TLS_AES_256_GCM_SHA384,
                                TLS13_BYTE, TLS_AES_256_GCM_SHA384,
                                TLS13_BYTE, TLS_AES_128_GCM_SHA256,
                                TLS13_BYTE, TLS_AES_128_GCM_SHA256,
                                TLS13_BYTE, TLS_AES_256_GCM_SHA384 };
#endif

    /* Set up wolfSSL context. */
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile,
        WOLFSSL_FILETYPE_PEM));
    /* Read from 'msg'. */
    wolfSSL_SetIORecv(ctx, CsRecv);
    /* No where to send to - dummy sender. */
    wolfSSL_SetIOSend(ctx, CsSend);

    /* Test cipher suite list with many copies of a cipher suite. */
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    msg.buffer = clientHello;
    msg.length = (unsigned int)sizeof(clientHello);
    wolfSSL_SetIOReadCtx(ssl, &msg);
    /* Force server to have as many occurrences of same cipher suite as
     * possible. */
    if (ssl != NULL) {
        Suites* suites = (Suites*)WOLFSSL_SUITES(ssl);
        suites->suiteSz = WOLFSSL_MAX_SUITE_SZ;
        for (i = 0; i < suites->suiteSz; i += 2) {
            suites->suites[i + 0] = TLS13_BYTE;
            suites->suites[i + 1] = TLS_AES_128_GCM_SHA256;
        }
    }
    /* Test multiple occurrences of same cipher suite. */
    ExpectIntEQ(wolfSSL_accept_TLSv13(ssl), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    wolfSSL_free(ssl);
    ssl = NULL;

    /* Set client order opposite to server order:
     *   TLS13-AES128-GCM-SHA256:TLS13-AES256-GCM-SHA384 */
    clientHello[csOff + 0] = TLS13_BYTE;
    clientHello[csOff + 1] = TLS_AES_128_GCM_SHA256;
    clientHello[csOff + 2] = TLS13_BYTE;
    clientHello[csOff + 3] = TLS_AES_256_GCM_SHA384;

    /* Test server order negotiation. */
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    msg.buffer = clientHello;
    msg.length = (unsigned int)sizeof(clientHello);
    wolfSSL_SetIOReadCtx(ssl, &msg);
    /* Server order: TLS13-AES256-GCM-SHA384:TLS13-AES128-GCM-SHA256 */
    ExpectIntEQ(wolfSSL_set_cipher_list(ssl, serverCs), WOLFSSL_SUCCESS);
    /* Negotiate cipher suites in server order: TLS13-AES256-GCM-SHA384 */
    ExpectIntEQ(wolfSSL_accept_TLSv13(ssl), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    /* Check refined order - server order. */
    ExpectIntEQ(ssl->suites->suiteSz, 4);
    ExpectIntEQ(ssl->suites->suites[0], TLS13_BYTE);
    ExpectIntEQ(ssl->suites->suites[1], TLS_AES_256_GCM_SHA384);
    ExpectIntEQ(ssl->suites->suites[2], TLS13_BYTE);
    ExpectIntEQ(ssl->suites->suites[3], TLS_AES_128_GCM_SHA256);
    wolfSSL_free(ssl);
    ssl = NULL;

    /* Test client order negotiation. */
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    msg.buffer = clientHello;
    msg.length = (unsigned int)sizeof(clientHello);
    wolfSSL_SetIOReadCtx(ssl, &msg);
    /* Server order: TLS13-AES256-GCM-SHA384:TLS13-AES128-GCM-SHA256 */
    ExpectIntEQ(wolfSSL_set_cipher_list(ssl, serverCs), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_UseClientSuites(ssl), 0);
    /* Negotiate cipher suites in client order: TLS13-AES128-GCM-SHA256 */
    ExpectIntEQ(wolfSSL_accept_TLSv13(ssl), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    /* Check refined order - client order. */
    ExpectIntEQ(ssl->suites->suiteSz, 4);
    ExpectIntEQ(ssl->suites->suites[0], TLS13_BYTE);
    ExpectIntEQ(ssl->suites->suites[1], TLS_AES_128_GCM_SHA256);
    ExpectIntEQ(ssl->suites->suites[2], TLS13_BYTE);
    ExpectIntEQ(ssl->suites->suites[3], TLS_AES_256_GCM_SHA384);
    wolfSSL_free(ssl);
    ssl = NULL;

    /* Check duplicate detection is working. */
    ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx, dupCs), WOLFSSL_SUCCESS);
    ExpectIntEQ(ctx->suites->suiteSz, 4);
    ExpectIntEQ(ctx->suites->suites[0], TLS13_BYTE);
    ExpectIntEQ(ctx->suites->suites[1], TLS_AES_128_GCM_SHA256);
    ExpectIntEQ(ctx->suites->suites[2], TLS13_BYTE);
    ExpectIntEQ(ctx->suites->suites[3], TLS_AES_256_GCM_SHA384);

#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
    ExpectIntEQ(wolfSSL_CTX_set_cipher_list_bytes(ctx, dupCsBytes,
        sizeof(dupCsBytes)), WOLFSSL_SUCCESS);
    ExpectIntEQ(ctx->suites->suiteSz, 4);
    ExpectIntEQ(ctx->suites->suites[0], TLS13_BYTE);
    ExpectIntEQ(ctx->suites->suites[1], TLS_AES_256_GCM_SHA384);
    ExpectIntEQ(ctx->suites->suites[2], TLS13_BYTE);
    ExpectIntEQ(ctx->suites->suites[3], TLS_AES_128_GCM_SHA256);
#endif

    wolfSSL_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

#endif

#if defined(HAVE_PK_CALLBACKS) && !defined(WOLFSSL_NO_TLS12)
#if !defined(NO_FILESYSTEM) && !defined(NO_DH) && \
        !defined(NO_AES) && defined(HAVE_AES_CBC) && \
         defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int my_DhCallback(WOLFSSL* ssl, struct DhKey* key,
        const unsigned char* priv, unsigned int privSz,
        const unsigned char* pubKeyDer, unsigned int pubKeySz,
        unsigned char* out, unsigned int* outlen,
        void* ctx)
{
    int result;
    /* Test fail when context associated with WOLFSSL is NULL */
    if (ctx == NULL) {
        return -1;
    }

    (void)ssl;
    /* return 0 on success */
    PRIVATE_KEY_UNLOCK();
    result = wc_DhAgree(key, out, outlen, priv, privSz, pubKeyDer, pubKeySz);
    PRIVATE_KEY_LOCK();
    return result;
}

static int test_dh_ctx_setup(WOLFSSL_CTX* ctx) {
    EXPECT_DECLS;
    wolfSSL_CTX_SetDhAgreeCb(ctx, my_DhCallback);
#if defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
    ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx, "DHE-RSA-AES128-SHA256"),
            WOLFSSL_SUCCESS);
#endif
#if defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
    ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx, "DHE-RSA-AES256-SHA256"),
            WOLFSSL_SUCCESS);
#endif
    return EXPECT_RESULT();
}

static int test_dh_ssl_setup(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    static int dh_test_ctx = 1;
    int ret;

    wolfSSL_SetDhAgreeCtx(ssl, &dh_test_ctx);
    ExpectIntEQ(*((int*)wolfSSL_GetDhAgreeCtx(ssl)), dh_test_ctx);
    ret = wolfSSL_SetTmpDH_file(ssl, dhParamFile, WOLFSSL_FILETYPE_PEM);
    if (ret != WOLFSSL_SUCCESS && ret != WC_NO_ERR_TRACE(SIDE_ERROR)) {
        ExpectIntEQ(ret, WOLFSSL_SUCCESS);
    }
    return EXPECT_RESULT();
}

static int test_dh_ssl_setup_fail(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    int ret;

    wolfSSL_SetDhAgreeCtx(ssl, NULL);
    ExpectNull(wolfSSL_GetDhAgreeCtx(ssl));
    ret = wolfSSL_SetTmpDH_file(ssl, dhParamFile, WOLFSSL_FILETYPE_PEM);
    if (ret != WOLFSSL_SUCCESS && ret != WC_NO_ERR_TRACE(SIDE_ERROR)) {
        ExpectIntEQ(ret, WOLFSSL_SUCCESS);
    }
    return EXPECT_RESULT();
}
#endif

static int test_DhCallbacks(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_DH) && \
        !defined(NO_AES) && defined(HAVE_AES_CBC) && \
         defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL     *ssl = NULL;
    int  test;
    test_ssl_cbf func_cb_client;
    test_ssl_cbf func_cb_server;

    /* Test that DH callback APIs work. */
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectIntEQ(wolfSSL_CTX_set_cipher_list(NULL, "NONE"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    wolfSSL_CTX_SetDhAgreeCb(ctx, &my_DhCallback);
    /* load client ca cert */
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0),
            WOLFSSL_SUCCESS);
    /* test with NULL arguments */
    wolfSSL_SetDhAgreeCtx(NULL, &test);
    ExpectNull(wolfSSL_GetDhAgreeCtx(NULL));
    /* test success case */
    test = 1;
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    wolfSSL_SetDhAgreeCtx(ssl, &test);
    ExpectIntEQ(*((int*)wolfSSL_GetDhAgreeCtx(ssl)), test);
    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);


    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

    /* set callbacks to use DH functions */
    func_cb_client.ctx_ready = &test_dh_ctx_setup;
    func_cb_client.ssl_ready = &test_dh_ssl_setup;
    func_cb_client.method = wolfTLSv1_2_client_method;

    func_cb_server.ctx_ready = &test_dh_ctx_setup;
    func_cb_server.ssl_ready = &test_dh_ssl_setup;
    func_cb_server.method = wolfTLSv1_2_server_method;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
        &func_cb_server, NULL), TEST_SUCCESS);

    /* Test fail */
    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

    /* set callbacks to use DH functions */
    func_cb_client.ctx_ready = &test_dh_ctx_setup;
    func_cb_client.ssl_ready = &test_dh_ssl_setup_fail;
    func_cb_client.method = wolfTLSv1_2_client_method;

    func_cb_server.ctx_ready = &test_dh_ctx_setup;
    func_cb_server.ssl_ready = &test_dh_ssl_setup_fail;
    func_cb_server.method = wolfTLSv1_2_server_method;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
        &func_cb_server, NULL), -1001);
#endif
    return EXPECT_RESULT();
}
#endif /* HAVE_PK_CALLBACKS */

#ifdef HAVE_HASHDRBG

#ifdef TEST_RESEED_INTERVAL
static int test_wc_RNG_GenerateBlock_Reseed(void)
{
    EXPECT_DECLS;
    int i;
    WC_RNG rng;
    byte key[32];

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    for (i = 0; i < WC_RESEED_INTERVAL + 10; i++) {
        ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0);
    }
    DoExpectIntEQ(wc_FreeRng(&rng), 0);

    return EXPECT_RESULT();
}
#endif /* TEST_RESEED_INTERVAL */

static int test_wc_RNG_GenerateBlock(void)
{
    EXPECT_DECLS;
    int i;
    WC_RNG rng;
    byte key[32];

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRng(&rng), 0);
    for (i = 0; i < 10; i++) {
        ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0);
    }
    DoExpectIntEQ(wc_FreeRng(&rng), 0);

    return EXPECT_RESULT();
}

#endif /* HAVE_HASHDRBG */

/*
 * Testing get_rand_digit
 */
static int test_get_rand_digit(void)
{
    EXPECT_DECLS;
#if !defined(WC_NO_RNG) && defined(WOLFSSL_PUBLIC_MP)
    WC_RNG   rng;
    mp_digit d;

    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectIntEQ(get_rand_digit(&rng, &d), 0);
    ExpectIntEQ(get_rand_digit(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(get_rand_digit(NULL, &d), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(get_rand_digit(&rng, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* End test_get_rand_digit*/

/*
 * Testing get_digit_count
 */
static int test_get_digit_count(void)
{
    EXPECT_DECLS;
#if !defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_PUBLIC_MP)
    mp_int a;

    XMEMSET(&a, 0, sizeof(mp_int));

    ExpectIntEQ(mp_init(&a), 0);

    ExpectIntEQ(get_digit_count(NULL), 0);
    ExpectIntEQ(get_digit_count(&a), 0);

    mp_clear(&a);
#endif
    return EXPECT_RESULT();
} /* End test_get_digit_count*/

/*
 * Testing mp_cond_copy
 */
static int test_mp_cond_copy(void)
{
    EXPECT_DECLS;
#if (defined(HAVE_ECC) || defined(WOLFSSL_MP_COND_COPY)) && \
    defined(WOLFSSL_PUBLIC_MP)
    mp_int a;
    mp_int b;
    int    copy = 0;

    XMEMSET(&a, 0, sizeof(mp_int));
    XMEMSET(&b, 0, sizeof(mp_int));

    ExpectIntEQ(mp_init(&a), MP_OKAY);
    ExpectIntEQ(mp_init(&b), MP_OKAY);

    ExpectIntEQ(mp_cond_copy(NULL, copy, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(mp_cond_copy(NULL, copy, &b), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(mp_cond_copy(&a, copy, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(mp_cond_copy(&a, copy, &b), 0);

    mp_clear(&a);
    mp_clear(&b);
#endif
    return EXPECT_RESULT();
} /* End test_mp_cond_copy*/

/*
 * Testing mp_rand
 */
static int test_mp_rand(void)
{
    EXPECT_DECLS;
#if defined(WC_RSA_BLINDING) && defined(WOLFSSL_PUBLIC_MP)
    mp_int a;
    WC_RNG rng;
    int    digits = 1;

    XMEMSET(&a, 0, sizeof(mp_int));
    XMEMSET(&rng, 0, sizeof(WC_RNG));

    ExpectIntEQ(mp_init(&a), MP_OKAY);
    ExpectIntEQ(wc_InitRng(&rng), 0);

    ExpectIntEQ(mp_rand(&a, digits, NULL), WC_NO_ERR_TRACE(MISSING_RNG_E));
    ExpectIntEQ(mp_rand(NULL, digits, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(mp_rand(&a, 0, &rng), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(mp_rand(&a, digits, &rng), 0);

    mp_clear(&a);
    DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* End test_mp_rand*/

/*
 * Testing get_digit
 */
static int test_get_digit(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_PUBLIC_MP)
    mp_int a;
    int    n = 0;

    XMEMSET(&a, 0, sizeof(mp_int));

    ExpectIntEQ(mp_init(&a), MP_OKAY);
    ExpectIntEQ(get_digit(NULL, n), 0);
    ExpectIntEQ(get_digit(&a, n), 0);

    mp_clear(&a);
#endif
    return EXPECT_RESULT();
} /* End test_get_digit*/

/*
 * Testing wc_export_int
 */
static int test_wc_export_int(void)
{
    EXPECT_DECLS;
#if (defined(HAVE_ECC) || defined(WOLFSSL_EXPORT_INT)) && \
    defined(WOLFSSL_PUBLIC_MP)
    mp_int mp;
    byte   buf[32];
    word32 keySz = (word32)sizeof(buf);
    word32 len = (word32)sizeof(buf);

    XMEMSET(&mp, 0, sizeof(mp_int));

    ExpectIntEQ(mp_init(&mp), MP_OKAY);
    ExpectIntEQ(mp_set(&mp, 1234), 0);

    ExpectIntEQ(wc_export_int(NULL, buf, &len, keySz, WC_TYPE_UNSIGNED_BIN),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    len = sizeof(buf)-1;
    ExpectIntEQ(wc_export_int(&mp, buf, &len, keySz, WC_TYPE_UNSIGNED_BIN),
        WC_NO_ERR_TRACE(BUFFER_E));
    len = sizeof(buf);
    ExpectIntEQ(wc_export_int(&mp, buf, &len, keySz, WC_TYPE_UNSIGNED_BIN), 0);
    len = 4; /* test input too small */
    ExpectIntEQ(wc_export_int(&mp, buf, &len, 0, WC_TYPE_HEX_STR), WC_NO_ERR_TRACE(BUFFER_E));
    len = sizeof(buf);
    ExpectIntEQ(wc_export_int(&mp, buf, &len, 0, WC_TYPE_HEX_STR), 0);
    /* hex version of 1234 is 04D2 and should be 4 digits + 1 null */
    ExpectIntEQ(len, 5);

    mp_clear(&mp);
#endif
    return EXPECT_RESULT();

} /* End test_wc_export_int*/

static int test_wc_InitRngNonce(void)
{
    EXPECT_DECLS;
#if !defined(WC_NO_RNG) && !defined(HAVE_SELFTEST) && \
    (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
     HAVE_FIPS_VERSION >= 2))
    WC_RNG rng;
    byte   nonce[] = "\x0D\x74\xDB\x42\xA9\x10\x77\xDE"
                     "\x45\xAC\x13\x7A\xE1\x48\xAF\x16";
    word32 nonceSz = sizeof(nonce);

    ExpectIntEQ(wc_InitRngNonce(&rng, nonce, nonceSz), 0);
    ExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* End test_wc_InitRngNonce*/

/*
 * Testing wc_InitRngNonce_ex
 */
static int test_wc_InitRngNonce_ex(void)
{
    EXPECT_DECLS;
#if !defined(WC_NO_RNG) && !defined(HAVE_SELFTEST) && \
    (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
     HAVE_FIPS_VERSION >= 2))
    WC_RNG rng;
    byte   nonce[] = "\x0D\x74\xDB\x42\xA9\x10\x77\xDE"
                     "\x45\xAC\x13\x7A\xE1\x48\xAF\x16";
    word32 nonceSz = sizeof(nonce);

    ExpectIntEQ(wc_InitRngNonce_ex(&rng, nonce, nonceSz, HEAP_HINT, testDevId),
        0);
    ExpectIntEQ(wc_FreeRng(&rng), 0);
#endif
    return EXPECT_RESULT();
} /* End test_wc_InitRngNonce_ex */



static int test_wolfSSL_X509_CRL(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
    X509_CRL *crl = NULL;
    char pem[][100] = {
        "./certs/crl/crl.pem",
        "./certs/crl/crl2.pem",
        "./certs/crl/caEccCrl.pem",
        "./certs/crl/eccCliCRL.pem",
        "./certs/crl/eccSrvCRL.pem",
        ""
    };
#ifndef NO_BIO
    BIO *bio = NULL;
#endif

#ifdef HAVE_TEST_d2i_X509_CRL_fp
    char der[][100] = {
        "./certs/crl/crl.der",
        "./certs/crl/crl2.der",
        ""};
#endif

    XFILE fp = XBADFILE;
    int i;

    for (i = 0; pem[i][0] != '\0'; i++)
    {
        ExpectTrue((fp = XFOPEN(pem[i], "rb")) != XBADFILE);
        ExpectNotNull(crl = (X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
            NULL, NULL));
        ExpectNotNull(crl);
        X509_CRL_free(crl);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }
        ExpectTrue((fp = XFOPEN(pem[i], "rb")) != XBADFILE);
        ExpectNotNull((X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)&crl, NULL,
            NULL));
        if (EXPECT_FAIL()) {
            crl = NULL;
        }
        ExpectNotNull(crl);
        X509_CRL_free(crl);
        crl = NULL;
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }
    }

#ifndef NO_BIO
    for (i = 0; pem[i][0] != '\0'; i++)
    {
        ExpectNotNull(bio = BIO_new_file(pem[i], "rb"));
        ExpectNotNull(crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL));
        X509_CRL_free(crl);
        crl = NULL;
        BIO_free(bio);
        bio = NULL;
    }
#endif

#ifdef HAVE_TEST_d2i_X509_CRL_fp
    for (i = 0; der[i][0] != '\0'; i++) {
        ExpectTrue((fp = XFOPEN(der[i], "rb")) != XBADFILE);
        ExpectTrue((fp != XBADFILE));
        ExpectNotNull(crl = (X509_CRL *)d2i_X509_CRL_fp((fp, X509_CRL **)NULL));
        ExpectNotNull(crl);
        X509_CRL_free(crl);
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }
        fp = XFOPEN(der[i], "rb");
        ExpectTrue((fp != XBADFILE));
        ExpectNotNull((X509_CRL *)d2i_X509_CRL_fp(fp, (X509_CRL **)&crl));
        if (EXPECT_FAIL()) {
            crl = NULL;
        }
        ExpectNotNull(crl);
        X509_CRL_free(crl);
        crl = NULL;
        if (fp != XBADFILE) {
            XFCLOSE(fp);
            fp = XBADFILE;
        }
    }
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_load_crl_file(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) && !defined(NO_FILESYSTEM) && \
    !defined(NO_STDIO_FILESYSTEM) && !defined(NO_RSA) && !defined(NO_BIO) && \
    !defined(WOLFSSL_CRL_ALLOW_MISSING_CDP)
    int i;
    char pem[][100] = {
        "./certs/crl/crl.pem",
        "./certs/crl/crl2.pem",
        "./certs/crl/caEccCrl.pem",
        "./certs/crl/eccCliCRL.pem",
        "./certs/crl/eccSrvCRL.pem",
    #ifdef WC_RSA_PSS
        "./certs/crl/crl_rsapss.pem",
    #endif
        ""
    };
    char der[][100] = {
        "./certs/crl/crl.der",
        "./certs/crl/crl2.der",
        ""
    };
    WOLFSSL_X509_STORE*  store = NULL;
    WOLFSSL_X509_LOOKUP* lookup = NULL;

    ExpectNotNull(store = wolfSSL_X509_STORE_new());
    ExpectNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()));

    ExpectIntEQ(X509_LOOKUP_load_file(lookup, "certs/ca-cert.pem",
        X509_FILETYPE_PEM), 1);
#ifdef WC_RSA_PSS
    ExpectIntEQ(X509_LOOKUP_load_file(lookup, "certs/rsapss/ca-rsapss.pem",
        X509_FILETYPE_PEM), 1);
#endif
    ExpectIntEQ(X509_LOOKUP_load_file(lookup, "certs/server-revoked-cert.pem",
        X509_FILETYPE_PEM), 1);
    if (store) {
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm, svrCertFile,
            WOLFSSL_FILETYPE_PEM), 1);
        /* since store hasn't yet known the revoked cert*/
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm,
            "certs/server-revoked-cert.pem", WOLFSSL_FILETYPE_PEM), 1);
    }

    for (i = 0; pem[i][0] != '\0'; i++) {
        ExpectIntEQ(X509_load_crl_file(lookup, pem[i], WOLFSSL_FILETYPE_PEM),
            1);
    }

    if (store) {
        /* since store knows crl list */
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm,
            "certs/server-revoked-cert.pem", WOLFSSL_FILETYPE_PEM),
            WC_NO_ERR_TRACE(CRL_CERT_REVOKED));
#ifdef WC_RSA_PSS
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm,
            "certs/rsapss/server-rsapss-cert.pem", WOLFSSL_FILETYPE_PEM),
            WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
#endif
    }
    /* once feeing store */
    X509_STORE_free(store);
    store = NULL;

    ExpectNotNull(store = wolfSSL_X509_STORE_new());
    ExpectNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()));

    ExpectIntEQ(X509_LOOKUP_load_file(lookup, "certs/ca-cert.pem",
        X509_FILETYPE_PEM), 1);
    ExpectIntEQ(X509_LOOKUP_load_file(lookup, "certs/server-revoked-cert.pem",
        X509_FILETYPE_PEM), 1);
    if (store) {
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm, svrCertFile,
            WOLFSSL_FILETYPE_PEM), 1);
        /* since store hasn't yet known the revoked cert*/
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm,
            "certs/server-revoked-cert.pem", WOLFSSL_FILETYPE_PEM), 1);
    }

    for (i = 0; der[i][0] != '\0'; i++) {
        ExpectIntEQ(X509_load_crl_file(lookup, der[i], WOLFSSL_FILETYPE_ASN1),
            1);
    }

    if (store) {
        /* since store knows crl list */
        ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm,
            "certs/server-revoked-cert.pem", WOLFSSL_FILETYPE_PEM),
            WC_NO_ERR_TRACE(CRL_CERT_REVOKED));
    }

    /* test for incorrect parameter */
    ExpectIntEQ(X509_load_crl_file(NULL, pem[0], 0), 0);
    ExpectIntEQ(X509_load_crl_file(lookup, NULL, 0), 0);
    ExpectIntEQ(X509_load_crl_file(NULL, NULL, 0), 0);

    X509_STORE_free(store);
    store = NULL;
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2d_X509(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA)
    const unsigned char* cert_buf = server_cert_der_2048;
    unsigned char* out = NULL;
    unsigned char* tmp = NULL;
    X509* cert = NULL;

    ExpectNotNull(d2i_X509(&cert, &cert_buf, sizeof_server_cert_der_2048));
    /* Pointer should be advanced */
    ExpectPtrGT(cert_buf, server_cert_der_2048);
    ExpectIntGT(i2d_X509(cert, &out), 0);
    ExpectNotNull(out);
    tmp = out;
    ExpectIntGT(i2d_X509(cert, &tmp), 0);
    ExpectPtrGT(tmp, out);

    if (out != NULL)
        XFREE(out, NULL, DYNAMIC_TYPE_OPENSSL);
    X509_free(cert);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_d2i_X509_REQ(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_RSA) && !defined(NO_BIO) && \
    (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
    !defined(WOLFSSL_SP_MATH)
    /* ./certs/csr.signed.der, ./certs/csr.ext.der, and ./certs/csr.attr.der
     * were generated by libest
     * ./certs/csr.attr.der contains sample attributes
     * ./certs/csr.ext.der contains sample extensions */
    const char* csrFile = "./certs/csr.signed.der";
    const char* csrPopFile = "./certs/csr.attr.der";
    const char* csrExtFile = "./certs/csr.ext.der";
    /* ./certs/csr.dsa.pem is generated using
     * openssl req -newkey dsa:certs/dsaparams.pem \
     *     -keyout certs/csr.dsa.key.pem -keyform PEM -out certs/csr.dsa.pem \
     *     -outform PEM
     * with the passphrase "wolfSSL"
     */
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
    const char* csrDsaFile = "./certs/csr.dsa.pem";
    XFILE f = XBADFILE;
#endif
    BIO* bio = NULL;
    X509* req = NULL;
    EVP_PKEY *pub_key = NULL;

    {
        ExpectNotNull(bio = BIO_new_file(csrFile, "rb"));
        ExpectNotNull(d2i_X509_REQ_bio(bio, &req));

        /*
         * Extract the public key from the CSR
         */
        ExpectNotNull(pub_key = X509_REQ_get_pubkey(req));

        /*
         * Verify the signature in the CSR
         */
        ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);

        X509_free(req);
        req = NULL;
        BIO_free(bio);
        bio = NULL;
        EVP_PKEY_free(pub_key);
        pub_key = NULL;
    }
    {
#ifdef OPENSSL_ALL
        X509_ATTRIBUTE* attr = NULL;
        ASN1_TYPE *at = NULL;
#endif
        ExpectNotNull(bio = BIO_new_file(csrPopFile, "rb"));
        ExpectNotNull(d2i_X509_REQ_bio(bio, &req));

        /*
         * Extract the public key from the CSR
         */
        ExpectNotNull(pub_key = X509_REQ_get_pubkey(req));

        /*
         * Verify the signature in the CSR
         */
        ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);

#ifdef OPENSSL_ALL
        /*
         * Obtain the challenge password from the CSR
         */
        ExpectIntEQ(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword,
            -1), 1);
        ExpectNotNull(attr = X509_REQ_get_attr(req, 1));
        ExpectNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0));
        ExpectNotNull(at->value.asn1_string);
        ExpectStrEQ((char*)ASN1_STRING_data(at->value.asn1_string),
            "2xIE+qqp/rhyTXP+");
        ExpectIntEQ(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), -1);
#endif

        X509_free(req);
        req = NULL;
        BIO_free(bio);
        bio = NULL;
        EVP_PKEY_free(pub_key);
        pub_key = NULL;
    }
    {
#ifdef OPENSSL_ALL
        X509_ATTRIBUTE* attr = NULL;
        ASN1_TYPE *at = NULL;
        STACK_OF(X509_EXTENSION) *exts = NULL;
#endif
        ExpectNotNull(bio = BIO_new_file(csrExtFile, "rb"));
        /* This CSR contains an Extension Request attribute so
         * we test extension parsing in a CSR attribute here. */
        ExpectNotNull(d2i_X509_REQ_bio(bio, &req));

        /*
         * Extract the public key from the CSR
         */
        ExpectNotNull(pub_key = X509_REQ_get_pubkey(req));

        /*
         * Verify the signature in the CSR
         */
        ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);

#ifdef OPENSSL_ALL
        ExpectNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(
            req));
        ExpectIntEQ(sk_X509_EXTENSION_num(exts), 2);
        sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        /*
         * Obtain the challenge password from the CSR
         */
        ExpectIntEQ(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword,
            -1), 0);
        ExpectNotNull(attr = X509_REQ_get_attr(req, 0));
        ExpectNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0));
        ExpectNotNull(at->value.asn1_string);
        ExpectStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "IGCu/xNL4/0/wOgo");
        ExpectIntGE(X509_get_ext_by_NID(req, NID_key_usage, -1), 0);
        ExpectIntGE(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), 0);
#endif

        X509_free(req);
        req = NULL;
        BIO_free(bio);
        bio = NULL;
        EVP_PKEY_free(pub_key);
        pub_key = NULL;
    }
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
    {
        ExpectNotNull(bio = BIO_new_file(csrDsaFile, "rb"));
        ExpectNotNull(PEM_read_bio_X509_REQ(bio, &req, NULL, NULL));

        /*
         * Extract the public key from the CSR
         */
        ExpectNotNull(pub_key = X509_REQ_get_pubkey(req));

        /*
         * Verify the signature in the CSR
         */
        ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);

        X509_free(req);
        req = NULL;
        BIO_free(bio);

        /* Run the same test, but with a file pointer instead of a BIO.
         * (PEM_read_X509_REQ)*/
        ExpectTrue((f = XFOPEN(csrDsaFile, "rb")) != XBADFILE);
        ExpectNotNull(PEM_read_X509_REQ(f, &req, NULL, NULL));
        ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);

        X509_free(req);
        EVP_PKEY_free(pub_key);
    }
#endif /* !NO_DSA && !HAVE_SELFTEST */
#endif /* WOLFSSL_CERT_REQ && (OPENSSL_ALL || OPENSSL_EXTRA) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_read_X509(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) && !defined(NO_FILESYSTEM) && \
    !defined(NO_RSA)
    X509 *x509 = NULL;
    XFILE fp = XBADFILE;

    ExpectTrue((fp = XFOPEN(svrCertFile, "rb")) != XBADFILE);
    ExpectNotNull(x509 = (X509 *)PEM_read_X509(fp, (X509 **)NULL, NULL, NULL));
    X509_free(x509);
    if (fp != XBADFILE)
        XFCLOSE(fp);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_read(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_BIO)
    const char* filename = "./certs/server-keyEnc.pem";
    XFILE fp = XBADFILE;
    char* name = NULL;
    char* header = NULL;
    byte* data = NULL;
    long len;
    EVP_CIPHER_INFO cipher;
    WOLFSSL_BIO* bio = NULL;
    byte* fileData = NULL;
    size_t fileDataSz = 0;
    byte* out;

    ExpectNotNull(bio = BIO_new_file(filename, "rb"));
    ExpectIntEQ(PEM_read_bio(bio, NULL, &header, &data, &len), 0);
    ExpectIntEQ(PEM_read_bio(bio, &name, NULL, &data, &len), 0);
    ExpectIntEQ(PEM_read_bio(bio, &name, &header, NULL, &len), 0);
    ExpectIntEQ(PEM_read_bio(bio, &name, &header, &data, NULL), 0);

    ExpectIntEQ(PEM_read_bio(bio, &name, &header, &data, &len), 1);
    ExpectIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
    ExpectIntGT(XSTRLEN(header), 0);
    ExpectIntGT(len, 0);
    XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    name = NULL;
    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    header = NULL;
    XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    data = NULL;
    BIO_free(bio);
    bio = NULL;

    ExpectTrue((fp = XFOPEN(filename, "rb")) != XBADFILE);

    /* Fail cases. */
    ExpectIntEQ(PEM_read(fp, NULL, &header, &data, &len), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_read(fp, &name, NULL, &data, &len), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_read(fp, &name, &header, NULL, &len), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_read(fp, &name, &header, &data, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(PEM_read(fp, &name, &header, &data, &len), WOLFSSL_SUCCESS);

    ExpectIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
    ExpectIntGT(XSTRLEN(header), 0);
    ExpectIntGT(len, 0);

    ExpectIntEQ(XFSEEK(fp, 0, SEEK_END), 0);
    ExpectIntGT((fileDataSz = XFTELL(fp)), 0);
    ExpectIntEQ(XFSEEK(fp, 0, SEEK_SET), 0);
    ExpectNotNull(fileData = (unsigned char*)XMALLOC(fileDataSz, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(XFREAD(fileData, 1, fileDataSz, fp), fileDataSz);
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }

    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));

    /* Fail cases. */
    ExpectIntEQ(PEM_write_bio(NULL, name, header, data, len), 0);
    ExpectIntEQ(PEM_write_bio(bio, NULL, header, data, len), 0);
    ExpectIntEQ(PEM_write_bio(bio, name, NULL, data, len), 0);
    ExpectIntEQ(PEM_write_bio(bio, name, header, NULL, len), 0);

    ExpectIntEQ(PEM_write_bio(bio, name, header, data, len), fileDataSz);
    ExpectIntEQ(wolfSSL_BIO_get_mem_data(bio, &out), fileDataSz);
    ExpectIntEQ(XMEMCMP(out, fileData, fileDataSz), 0);

    /* Fail cases. */
    ExpectIntEQ(PEM_write(XBADFILE, name, header, data, len), 0);
    ExpectIntEQ(PEM_write(stderr, NULL, header, data, len), 0);
    ExpectIntEQ(PEM_write(stderr, name, NULL, data, len), 0);
    ExpectIntEQ(PEM_write(stderr, name, header, NULL, len), 0);
    /* Pass case */
    ExpectIntEQ(PEM_write(stderr, name, header, data, len), fileDataSz);

    XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    name = NULL;
    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    header = NULL;
    XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    data = NULL;
    /* Read out of a fixed buffer BIO - forces malloc in PEM_read_bio. */
    ExpectIntEQ(PEM_read_bio(bio, &name, &header, &data, &len), 1);
    ExpectIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
    ExpectIntGT(XSTRLEN(header), 0);
    ExpectIntGT(len, 0);

    /* Fail cases. */
    ExpectIntEQ(PEM_get_EVP_CIPHER_INFO(NULL, &cipher), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_get_EVP_CIPHER_INFO(header, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_get_EVP_CIPHER_INFO((char*)"", &cipher), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

#ifndef NO_DES3
    ExpectIntEQ(PEM_get_EVP_CIPHER_INFO(header, &cipher), WOLFSSL_SUCCESS);
#endif

    /* Fail cases. */
    ExpectIntEQ(PEM_do_header(NULL, data, &len, PasswordCallBack,
        (void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_do_header(&cipher, NULL, &len, PasswordCallBack,
        (void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_do_header(&cipher, data, NULL, PasswordCallBack,
        (void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(PEM_do_header(&cipher, data, &len, NULL,
        (void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(PEM_do_header(&cipher, data, &len, NoPasswordCallBack,
                              (void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#if !defined(NO_DES3) && !defined(NO_MD5)
    ExpectIntEQ(PEM_do_header(&cipher, data, &len, PasswordCallBack,
                              (void*)"yassl123"), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(PEM_do_header(&cipher, data, &len, PasswordCallBack,
                              (void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif

    BIO_free(bio);
    bio = NULL;
    XFREE(fileData, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    fileData = NULL;
    XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    name = NULL;
    header = NULL;
    data = NULL;
    ExpectTrue((fp = XFOPEN(svrKeyFile, "rb")) != XBADFILE);
    ExpectIntEQ(PEM_read(fp, &name, &header, &data, &len), WOLFSSL_SUCCESS);
    ExpectIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
    ExpectIntEQ(XSTRLEN(header), 0);
    ExpectIntGT(len, 0);

    ExpectIntEQ(XFSEEK(fp, 0, SEEK_END), 0);
    ExpectIntGT((fileDataSz = XFTELL(fp)), 0);
    ExpectIntEQ(XFSEEK(fp, 0, SEEK_SET), 0);
    ExpectNotNull(fileData = (unsigned char*)XMALLOC(fileDataSz, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntEQ(XFREAD(fileData, 1, fileDataSz, fp), fileDataSz);
    if (fp != XBADFILE)
        XFCLOSE(fp);

    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
    ExpectIntEQ(PEM_write_bio(bio, name, header, data, len), fileDataSz);
    ExpectIntEQ(wolfSSL_BIO_get_mem_data(bio, &out), fileDataSz);
    ExpectIntEQ(XMEMCMP(out, fileData, fileDataSz), 0);

    BIO_free(bio);
    XFREE(fileData, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wolfssl_EVP_aes_gcm_AAD_2_parts(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \
    !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
    const byte iv[12] = { 0 };
    const byte key[16] = { 0 };
    const byte cleartext[16] = { 0 };
    const byte aad[] = {
        0x01, 0x10, 0x00, 0x2a, 0x08, 0x00, 0x04, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
        0x00, 0x00, 0xdc, 0x4d, 0xad, 0x6b, 0x06, 0x93,
        0x4f
    };
    byte out1Part[16];
    byte outTag1Part[16];
    byte out2Part[16];
    byte outTag2Part[16];
    byte decryptBuf[16];
    int len = 0;
    int tlen;
    EVP_CIPHER_CTX* ctx = NULL;

    /* ENCRYPT */
    /* Send AAD and data in 1 part */
    ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
    tlen = 0;
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL),
                1);
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), 1);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad, sizeof(aad)), 1);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, out1Part, &len, cleartext,
                                  sizeof(cleartext)), 1);
    tlen += len;
    ExpectIntEQ(EVP_EncryptFinal_ex(ctx, out1Part, &len), 1);
    tlen += len;
    ExpectIntEQ(tlen, sizeof(cleartext));
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16,
                                    outTag1Part), 1);
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* DECRYPT */
    /* Send AAD and data in 1 part */
    ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
    tlen = 0;
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL),
                1);
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), 1);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad, sizeof(aad)), 1);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptBuf, &len, out1Part,
                                  sizeof(cleartext)), 1);
    tlen += len;
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16,
                                    outTag1Part), 1);
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptBuf, &len), 1);
    tlen += len;
    ExpectIntEQ(tlen, sizeof(cleartext));
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    ExpectIntEQ(XMEMCMP(decryptBuf, cleartext, len), 0);

    /* ENCRYPT */
    /* Send AAD and data in 2 parts */
    ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
    tlen = 0;
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL),
                1);
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), 1);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad, 1), 1);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad + 1, sizeof(aad) - 1),
                1);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, out2Part, &len, cleartext, 1), 1);
    tlen += len;
    ExpectIntEQ(EVP_EncryptUpdate(ctx, out2Part + tlen, &len, cleartext + 1,
                                  sizeof(cleartext) - 1), 1);
    tlen += len;
    ExpectIntEQ(EVP_EncryptFinal_ex(ctx, out2Part + tlen, &len), 1);
    tlen += len;
    ExpectIntEQ(tlen, sizeof(cleartext));
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16,
                                    outTag2Part), 1);

    ExpectIntEQ(XMEMCMP(out1Part, out2Part, sizeof(out1Part)), 0);
    ExpectIntEQ(XMEMCMP(outTag1Part, outTag2Part, sizeof(outTag1Part)), 0);
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* DECRYPT */
    /* Send AAD and data in 2 parts */
    ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
    tlen = 0;
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL),
                1);
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), 1);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad, 1), 1);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad + 1, sizeof(aad) - 1),
                1);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptBuf, &len, out1Part, 1), 1);
    tlen += len;
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptBuf + tlen, &len, out1Part + 1,
                                  sizeof(cleartext) - 1), 1);
    tlen += len;
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16,
                                    outTag1Part), 1);
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptBuf + tlen, &len), 1);
    tlen += len;
    ExpectIntEQ(tlen, sizeof(cleartext));

    ExpectIntEQ(XMEMCMP(decryptBuf, cleartext, len), 0);

    /* Test AAD reuse */
    EVP_CIPHER_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfssl_EVP_aes_gcm_zeroLen(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \
    !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
    /* Zero length plain text */
    byte key[] = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    }; /* align */
    byte iv[]  = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    }; /* align */
    byte plaintxt[1];
    int ivSz  = 12;
    int plaintxtSz = 0;
    unsigned char tag[16];
    unsigned char tag_kat[] = {
        0x53,0x0f,0x8a,0xfb,0xc7,0x45,0x36,0xb9,
        0xa9,0x63,0xb4,0xf1,0xc4,0xcb,0x73,0x8b
    };

    byte ciphertxt[AES_BLOCK_SIZE * 4] = {0};
    byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0};
    int ciphertxtSz = 0;
    int decryptedtxtSz = 0;
    int len = 0;

    EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new();

    ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_aes_256_gcm(), NULL, key, iv));
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
    ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt,
        plaintxtSz));
    ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len));
    ciphertxtSz += len;
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_GET_TAG, 16, tag));
    ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en));

    ExpectIntEQ(0, ciphertxtSz);
    ExpectIntEQ(0, XMEMCMP(tag, tag_kat, sizeof(tag)));

    EVP_CIPHER_CTX_init(de);
    ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_aes_256_gcm(), NULL, key, iv));
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
    ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len));
    decryptedtxtSz = len;
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_TAG, 16, tag));
    ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len));
    decryptedtxtSz += len;
    ExpectIntEQ(0, decryptedtxtSz);

    EVP_CIPHER_CTX_free(en);
    EVP_CIPHER_CTX_free(de);
#endif
    return EXPECT_RESULT();
}

static int test_wolfssl_EVP_aes_gcm(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \
    !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
    /* A 256 bit key, AES_128 will use the first 128 bit*/
    byte *key = (byte*)"01234567890123456789012345678901";
    /* A 128 bit IV */
    byte *iv = (byte*)"0123456789012345";
    int ivSz = AES_BLOCK_SIZE;
    /* Message to be encrypted */
    byte *plaintxt = (byte*)"for things to change you have to change";
    /* Additional non-confidential data */
    byte *aad = (byte*)"Don't spend major time on minor things.";

    unsigned char tag[AES_BLOCK_SIZE] = {0};
    int plaintxtSz = (int)XSTRLEN((char*)plaintxt);
    int aadSz = (int)XSTRLEN((char*)aad);
    byte ciphertxt[AES_BLOCK_SIZE * 4] = {0};
    byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0};
    int ciphertxtSz = 0;
    int decryptedtxtSz = 0;
    int len = 0;
    int i = 0;
    EVP_CIPHER_CTX en[2];
    EVP_CIPHER_CTX de[2];

    for (i = 0; i < 2; i++) {
        EVP_CIPHER_CTX_init(&en[i]);
        if (i == 0) {
            /* Default uses 96-bits IV length */
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_128_gcm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_192_gcm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_256_gcm(), NULL,
                key, iv));
#endif
        }
        else {
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_128_gcm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_192_gcm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_256_gcm(), NULL,
                NULL, NULL));
#endif
             /* non-default must to set the IV length first */
            ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN,
                ivSz, NULL));
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv));
        }
        ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt,
            plaintxtSz));
        ciphertxtSz = len;
        ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len));
        ciphertxtSz += len;
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_GET_TAG,
            AES_BLOCK_SIZE, tag));
        ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1);

        EVP_CIPHER_CTX_init(&de[i]);
        if (i == 0) {
            /* Default uses 96-bits IV length */
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL,
                key, iv));
#endif
        }
        else {
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL,
                NULL, NULL));
#endif
            /* non-default must to set the IV length first */
            ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN,
                ivSz, NULL));
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv));

        }
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt,
            ciphertxtSz));
        decryptedtxtSz = len;
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG,
            AES_BLOCK_SIZE, tag));
        ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        decryptedtxtSz += len;
        ExpectIntEQ(ciphertxtSz, decryptedtxtSz);
        ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz));

        /* modify tag*/
        if (i == 0) {
            /* Default uses 96-bits IV length */
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL,
                key, iv));
#endif
        }
        else {
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL,
                NULL, NULL));
#endif
            /* non-default must to set the IV length first */
            ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN,
                ivSz, NULL));
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv));

        }
        tag[AES_BLOCK_SIZE-1]+=0xBB;
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG,
            AES_BLOCK_SIZE, tag));
        /* fail due to wrong tag */
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt,
            ciphertxtSz));
        ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        ExpectIntEQ(0, len);

        ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1);
    }
#endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESGCM */
    return EXPECT_RESULT();
}

static int test_wolfssl_EVP_aria_gcm(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ARIA) && \
    !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)

    /* A 256 bit key, AES_128 will use the first 128 bit*/
    byte *key = (byte*)"01234567890123456789012345678901";
    /* A 128 bit IV */
    byte *iv = (byte*)"0123456789012345";
    int ivSz = ARIA_BLOCK_SIZE;
    /* Message to be encrypted */
    const int plaintxtSz = 40;
    byte plaintxt[WC_ARIA_GCM_GET_CIPHERTEXT_SIZE(plaintxtSz)];
    XMEMCPY(plaintxt,"for things to change you have to change",plaintxtSz);
    /* Additional non-confidential data */
    byte *aad = (byte*)"Don't spend major time on minor things.";

    unsigned char tag[ARIA_BLOCK_SIZE] = {0};
    int aadSz = (int)XSTRLEN((char*)aad);
    byte ciphertxt[WC_ARIA_GCM_GET_CIPHERTEXT_SIZE(plaintxtSz)];
    byte decryptedtxt[plaintxtSz];
    int ciphertxtSz = 0;
    int decryptedtxtSz = 0;
    int len = 0;
    int i = 0;
    #define TEST_ARIA_GCM_COUNT 6
    EVP_CIPHER_CTX en[TEST_ARIA_GCM_COUNT];
    EVP_CIPHER_CTX de[TEST_ARIA_GCM_COUNT];

    for (i = 0; i < TEST_ARIA_GCM_COUNT; i++) {

        EVP_CIPHER_CTX_init(&en[i]);
        switch (i) {
            case 0:
                /* Default uses 96-bits IV length */
                AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_128_gcm(), NULL, key, iv));
                break;
            case 1:
                /* Default uses 96-bits IV length */
                AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_192_gcm(), NULL, key, iv));
                break;
            case 2:
                /* Default uses 96-bits IV length */
                AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_256_gcm(), NULL, key, iv));
                break;
            case 3:
                AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_128_gcm(), NULL, NULL, NULL));
                /* non-default must to set the IV length first */
                AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
                AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv));
                break;
            case 4:
                AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_192_gcm(), NULL, NULL, NULL));
                /* non-default must to set the IV length first */
                AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
                AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv));
                break;
            case 5:
                AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_256_gcm(), NULL, NULL, NULL));
                /* non-default must to set the IV length first */
                AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
                AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv));
                break;
        }
        XMEMSET(ciphertxt,0,sizeof(ciphertxt));
        AssertIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz));
        AssertIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt, plaintxtSz));
        ciphertxtSz = len;
        AssertIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len));
        AssertIntNE(0, XMEMCMP(plaintxt, ciphertxt, plaintxtSz));
        ciphertxtSz += len;
        AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_GET_TAG, ARIA_BLOCK_SIZE, tag));
        AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1);

        EVP_CIPHER_CTX_init(&de[i]);
        switch (i) {
            case 0:
                /* Default uses 96-bits IV length */
                AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_128_gcm(), NULL, key, iv));
                break;
            case 1:
                /* Default uses 96-bits IV length */
                AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_192_gcm(), NULL, key, iv));
                break;
            case 2:
                /* Default uses 96-bits IV length */
                AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_256_gcm(), NULL, key, iv));
                break;
            case 3:
                AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_128_gcm(), NULL, NULL, NULL));
                /* non-default must to set the IV length first */
                AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
                AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv));
                break;
            case 4:
                AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_192_gcm(), NULL, NULL, NULL));
                /* non-default must to set the IV length first */
                AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
                AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv));
                break;
            case 5:
                AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_256_gcm(), NULL, NULL, NULL));
                /* non-default must to set the IV length first */
                AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
                AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv));
                break;
        }
        XMEMSET(decryptedtxt,0,sizeof(decryptedtxt));
        AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz));
        decryptedtxtSz = len;
        AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, ARIA_BLOCK_SIZE, tag));
        AssertIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        decryptedtxtSz += len;
        AssertIntEQ(plaintxtSz, decryptedtxtSz);
        AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz));

        XMEMSET(decryptedtxt,0,sizeof(decryptedtxt));
        /* modify tag*/
        tag[AES_BLOCK_SIZE-1]+=0xBB;
        AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, ARIA_BLOCK_SIZE, tag));
        /* fail due to wrong tag */
        AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz));
        AssertIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        AssertIntEQ(0, len);
        AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1);
    }

    res = TEST_RES_CHECK(1);
#endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESGCM */
    return res;
}

static int test_wolfssl_EVP_aes_ccm_zeroLen(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESCCM) && \
    !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
    /* Zero length plain text */
    byte key[] = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    }; /* align */
    byte iv[]  = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    }; /* align */
    byte plaintxt[1];
    int ivSz  = 12;
    int plaintxtSz = 0;
    unsigned char tag[16];

    byte ciphertxt[AES_BLOCK_SIZE * 4] = {0};
    byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0};
    int ciphertxtSz = 0;
    int decryptedtxtSz = 0;
    int len = 0;

    EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new();

    ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_aes_256_ccm(), NULL, key, iv));
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL));
    ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt,
                                     plaintxtSz));
    ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len));
    ciphertxtSz += len;
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_GET_TAG, 16, tag));
    ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en));

    ExpectIntEQ(0, ciphertxtSz);

    EVP_CIPHER_CTX_init(de);
    ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_aes_256_ccm(), NULL, key, iv));
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL));
    ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len));
    decryptedtxtSz = len;
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_TAG, 16, tag));
    ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len));
    decryptedtxtSz += len;
    ExpectIntEQ(0, decryptedtxtSz);

    EVP_CIPHER_CTX_free(en);
    EVP_CIPHER_CTX_free(de);
#endif
    return EXPECT_RESULT();
}

static int test_wolfssl_EVP_aes_ccm(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESCCM) && \
    !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
    /* A 256 bit key, AES_128 will use the first 128 bit*/
    byte *key = (byte*)"01234567890123456789012345678901";
    /* A 128 bit IV */
    byte *iv = (byte*)"0123456789012";
    int ivSz = (int)XSTRLEN((char*)iv);
    /* Message to be encrypted */
    byte *plaintxt = (byte*)"for things to change you have to change";
    /* Additional non-confidential data */
    byte *aad = (byte*)"Don't spend major time on minor things.";

    unsigned char tag[AES_BLOCK_SIZE] = {0};
    int plaintxtSz = (int)XSTRLEN((char*)plaintxt);
    int aadSz = (int)XSTRLEN((char*)aad);
    byte ciphertxt[AES_BLOCK_SIZE * 4] = {0};
    byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0};
    int ciphertxtSz = 0;
    int decryptedtxtSz = 0;
    int len = 0;
    int i = 0;
    int ret;
    EVP_CIPHER_CTX en[2];
    EVP_CIPHER_CTX de[2];

    for (i = 0; i < 2; i++) {
        EVP_CIPHER_CTX_init(&en[i]);

        if (i == 0) {
            /* Default uses 96-bits IV length */
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_128_ccm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_192_ccm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_256_ccm(), NULL,
                key, iv));
#endif
        }
        else {
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_128_ccm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_192_ccm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_256_ccm(), NULL,
                NULL, NULL));
#endif
             /* non-default must to set the IV length first */
            ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_SET_IVLEN,
                ivSz, NULL));
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv));
        }
        ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt,
              plaintxtSz));
        ciphertxtSz = len;
        ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len));
        ciphertxtSz += len;
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_GET_TAG,
            AES_BLOCK_SIZE, tag));
        ret = wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]);
        ExpectIntEQ(ret, 1);

        EVP_CIPHER_CTX_init(&de[i]);
        if (i == 0) {
            /* Default uses 96-bits IV length */
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_ccm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_ccm(), NULL,
                key, iv));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_ccm(), NULL,
                key, iv));
#endif
        }
        else {
#ifdef WOLFSSL_AES_128
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_ccm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_192)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_ccm(), NULL,
                NULL, NULL));
#elif defined(WOLFSSL_AES_256)
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_ccm(), NULL,
                NULL, NULL));
#endif
            /* non-default must to set the IV length first */
            ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_IVLEN,
                ivSz, NULL));
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv));

        }
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt,
            ciphertxtSz));
        decryptedtxtSz = len;
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG,
            AES_BLOCK_SIZE, tag));
        ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        decryptedtxtSz += len;
        ExpectIntEQ(ciphertxtSz, decryptedtxtSz);
        ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz));

        /* modify tag*/
        tag[AES_BLOCK_SIZE-1]+=0xBB;
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG,
            AES_BLOCK_SIZE, tag));
        /* fail due to wrong tag */
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt,
            ciphertxtSz));
        ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        ExpectIntEQ(0, len);
        ret = wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]);
        ExpectIntEQ(ret, 1);
    }
#endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESCCM */
    return EXPECT_RESULT();
}

static int test_wolfssl_EVP_chacha20_poly1305(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
    byte key[CHACHA20_POLY1305_AEAD_KEYSIZE];
    byte iv [CHACHA20_POLY1305_AEAD_IV_SIZE];
    byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF};
    byte aad[] = {0xAA, 0XBB, 0xCC, 0xDD, 0xEE, 0xFF};
    byte cipherText[sizeof(plainText)];
    byte decryptedText[sizeof(plainText)];
    byte tag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE];
    EVP_CIPHER_CTX* ctx = NULL;
    int outSz;

    XMEMSET(key, 0, sizeof(key));
    XMEMSET(iv, 0, sizeof(iv));

    /* Encrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, NULL,
                NULL), WOLFSSL_SUCCESS);
    /* Invalid IV length. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
                CHACHA20_POLY1305_AEAD_IV_SIZE-1, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Valid IV length. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
                CHACHA20_POLY1305_AEAD_IV_SIZE, NULL), WOLFSSL_SUCCESS);
    /* Invalid tag length. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
                CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE-1, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Valid tag length. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
                CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, NULL, &outSz, aad, sizeof(aad)),
               WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(aad));
    ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText,
                sizeof(plainText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(plainText));
    ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText, &outSz), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    /* Invalid tag length. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
                CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE-1, tag), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Valid tag length. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
                CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, tag), WOLFSSL_SUCCESS);
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* Decrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, NULL,
                NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
                CHACHA20_POLY1305_AEAD_IV_SIZE, NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
                CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, tag), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, NULL, &outSz, aad, sizeof(aad)),
               WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(aad));
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
                sizeof(cipherText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(cipherText));
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz),
                WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* Test partial Inits. CipherInit() allow setting of key and iv
     * in separate calls. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_chacha20_poly1305(),
                key, NULL, 1), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 1),
                WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EVP_CipherUpdate(ctx, NULL, &outSz,
                aad, sizeof(aad)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(aad));
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
                sizeof(cipherText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(cipherText));
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz),
            WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    EVP_CIPHER_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfssl_EVP_chacha20(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_CHACHA)
    byte key[CHACHA_MAX_KEY_SZ];
    byte iv [WOLFSSL_EVP_CHACHA_IV_BYTES];
    byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF};
    byte cipherText[sizeof(plainText)];
    byte decryptedText[sizeof(plainText)];
    EVP_CIPHER_CTX* ctx = NULL;
    int outSz;

    XMEMSET(key, 0, sizeof(key));
    XMEMSET(iv, 0, sizeof(iv));
    /* Encrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_chacha20(), NULL, NULL,
                NULL), WOLFSSL_SUCCESS);
    /* Any tag length must fail - not an AEAD cipher. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
                16, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText,
                sizeof(plainText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(plainText));
    ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText, &outSz), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* Decrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_chacha20(), NULL, NULL,
                NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
                sizeof(cipherText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(cipherText));
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz),
                WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* Test partial Inits. CipherInit() allow setting of key and iv
     * in separate calls. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_chacha20(),
                key, NULL, 1), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 1),
                WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
                sizeof(cipherText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(cipherText));
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz),
            WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    EVP_CIPHER_CTX_free(ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfssl_EVP_sm4_ecb(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_ECB)
    EXPECT_DECLS;
    byte key[SM4_KEY_SIZE];
    byte plainText[SM4_BLOCK_SIZE] = {
        0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
        0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF
    };
    byte cipherText[sizeof(plainText) + SM4_BLOCK_SIZE];
    byte decryptedText[sizeof(plainText) + SM4_BLOCK_SIZE];
    EVP_CIPHER_CTX* ctx;
    int outSz;

    XMEMSET(key, 0, sizeof(key));

    /* Encrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_sm4_ecb(), NULL, NULL, NULL),
        WOLFSSL_SUCCESS);
    /* Any tag length must fail - not an AEAD cipher. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText,
        sizeof(plainText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(plainText));
    ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText + outSz, &outSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, SM4_BLOCK_SIZE);
    ExpectBufNE(cipherText, plainText, sizeof(plainText));
    EVP_CIPHER_CTX_free(ctx);

    /* Decrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_sm4_ecb(), NULL, NULL, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
        sizeof(cipherText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(plainText));
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText + outSz, &outSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    ExpectBufEQ(decryptedText, plainText, sizeof(plainText));
    EVP_CIPHER_CTX_free(ctx);

    res = EXPECT_RESULT();
#endif
    return res;
}

static int test_wolfssl_EVP_sm4_cbc(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CBC)
    EXPECT_DECLS;
    byte key[SM4_KEY_SIZE];
    byte iv[SM4_BLOCK_SIZE];
    byte plainText[SM4_BLOCK_SIZE] = {
        0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
        0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF
    };
    byte cipherText[sizeof(plainText) + SM4_BLOCK_SIZE];
    byte decryptedText[sizeof(plainText) + SM4_BLOCK_SIZE];
    EVP_CIPHER_CTX* ctx;
    int outSz;

    XMEMSET(key, 0, sizeof(key));
    XMEMSET(iv, 0, sizeof(iv));

    /* Encrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_sm4_cbc(), NULL, NULL, NULL),
        WOLFSSL_SUCCESS);
    /* Any tag length must fail - not an AEAD cipher. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText,
        sizeof(plainText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(plainText));
    ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText + outSz, &outSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, SM4_BLOCK_SIZE);
    ExpectBufNE(cipherText, plainText, sizeof(plainText));
    EVP_CIPHER_CTX_free(ctx);

    /* Decrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_sm4_cbc(), NULL, NULL, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
        sizeof(cipherText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(plainText));
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText + outSz, &outSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    ExpectBufEQ(decryptedText, plainText, sizeof(plainText));
    EVP_CIPHER_CTX_free(ctx);

    /* Test partial Inits. CipherInit() allow setting of key and iv
     * in separate calls. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_sm4_cbc(), key, NULL, 0),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 0),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
         sizeof(cipherText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(plainText));
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText + outSz, &outSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    ExpectBufEQ(decryptedText, plainText, sizeof(plainText));
    EVP_CIPHER_CTX_free(ctx);

    res = EXPECT_RESULT();
#endif
    return res;
}

static int test_wolfssl_EVP_sm4_ctr(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CTR)
    EXPECT_DECLS;
    byte key[SM4_KEY_SIZE];
    byte iv[SM4_BLOCK_SIZE];
    byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF};
    byte cipherText[sizeof(plainText)];
    byte decryptedText[sizeof(plainText)];
    EVP_CIPHER_CTX* ctx;
    int outSz;

    XMEMSET(key, 0, sizeof(key));
    XMEMSET(iv, 0, sizeof(iv));

    /* Encrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_sm4_ctr(), NULL, NULL, NULL),
        WOLFSSL_SUCCESS);
    /* Any tag length must fail - not an AEAD cipher. */
    ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, NULL),
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText,
        sizeof(plainText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(plainText));
    ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText, &outSz), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    ExpectBufNE(cipherText, plainText, sizeof(plainText));
    EVP_CIPHER_CTX_free(ctx);

    /* Decrypt. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_sm4_ctr(), NULL, NULL, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
        sizeof(cipherText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(cipherText));
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    ExpectBufEQ(decryptedText, plainText, sizeof(plainText));
    EVP_CIPHER_CTX_free(ctx);

    /* Test partial Inits. CipherInit() allow setting of key and iv
     * in separate calls. */
    ExpectNotNull((ctx = EVP_CIPHER_CTX_new()));
    ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_sm4_ctr(), key, NULL, 1),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 1),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
         sizeof(cipherText)), WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, sizeof(cipherText));
    ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(outSz, 0);
    ExpectBufEQ(decryptedText, plainText, sizeof(plainText));
    EVP_CIPHER_CTX_free(ctx);

    res = EXPECT_RESULT();
#endif
    return res;
}

static int test_wolfssl_EVP_sm4_gcm_zeroLen(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_GCM)
    /* Zero length plain text */
    EXPECT_DECLS;
    byte key[] = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    }; /* align */
    byte iv[]  = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    }; /* align */
    byte plaintxt[1];
    int ivSz  = 12;
    int plaintxtSz = 0;
    unsigned char tag[16];
    unsigned char tag_kat[16] = {
        0x23,0x2f,0x0c,0xfe,0x30,0x8b,0x49,0xea,
        0x6f,0xc8,0x82,0x29,0xb5,0xdc,0x85,0x8d
    };

    byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0};
    byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0};
    int ciphertxtSz = 0;
    int decryptedtxtSz = 0;
    int len = 0;

    EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new();

    ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_sm4_gcm(), NULL, key, iv));
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
    ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt,
        plaintxtSz));
    ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len));
    ciphertxtSz += len;
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_GET_TAG, 16, tag));
    ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en));

    ExpectIntEQ(0, ciphertxtSz);
    ExpectIntEQ(0, XMEMCMP(tag, tag_kat, sizeof(tag)));

    EVP_CIPHER_CTX_init(de);
    ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_sm4_gcm(), NULL, key, iv));
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
    ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len));
    decryptedtxtSz = len;
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_TAG, 16, tag));
    ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len));
    decryptedtxtSz += len;
    ExpectIntEQ(0, decryptedtxtSz);

    EVP_CIPHER_CTX_free(en);
    EVP_CIPHER_CTX_free(de);

    res = EXPECT_RESULT();
#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_GCM */
    return res;
}

static int test_wolfssl_EVP_sm4_gcm(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_GCM)
    EXPECT_DECLS;
    byte *key = (byte*)"0123456789012345";
    /* A 128 bit IV */
    byte *iv = (byte*)"0123456789012345";
    int ivSz = SM4_BLOCK_SIZE;
    /* Message to be encrypted */
    byte *plaintxt = (byte*)"for things to change you have to change";
    /* Additional non-confidential data */
    byte *aad = (byte*)"Don't spend major time on minor things.";

    unsigned char tag[SM4_BLOCK_SIZE] = {0};
    int plaintxtSz = (int)XSTRLEN((char*)plaintxt);
    int aadSz = (int)XSTRLEN((char*)aad);
    byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0};
    byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0};
    int ciphertxtSz = 0;
    int decryptedtxtSz = 0;
    int len = 0;
    int i = 0;
    EVP_CIPHER_CTX en[2];
    EVP_CIPHER_CTX de[2];

    for (i = 0; i < 2; i++) {
        EVP_CIPHER_CTX_init(&en[i]);

        if (i == 0) {
            /* Default uses 96-bits IV length */
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_gcm(), NULL, key,
                iv));
        }
        else {
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_gcm(), NULL, NULL,
                NULL));
             /* non-default must to set the IV length first */
            ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN,
                ivSz, NULL));
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv));
        }
        ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt,
            plaintxtSz));
        ciphertxtSz = len;
        ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len));
        ciphertxtSz += len;
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_GET_TAG,
            SM4_BLOCK_SIZE, tag));
        ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1);

        EVP_CIPHER_CTX_init(&de[i]);
        if (i == 0) {
            /* Default uses 96-bits IV length */
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_gcm(), NULL, key,
                iv));
        }
        else {
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_gcm(), NULL, NULL,
                NULL));
            /* non-default must to set the IV length first */
            ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN,
                ivSz, NULL));
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv));

        }
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt,
            ciphertxtSz));
        decryptedtxtSz = len;
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG,
            SM4_BLOCK_SIZE, tag));
        ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        decryptedtxtSz += len;
        ExpectIntEQ(ciphertxtSz, decryptedtxtSz);
        ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz));

        /* modify tag*/
        tag[SM4_BLOCK_SIZE-1]+=0xBB;
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG,
            SM4_BLOCK_SIZE, tag));
        /* fail due to wrong tag */
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt,
            ciphertxtSz));
        ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        ExpectIntEQ(0, len);
        ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1);
    }

    res = EXPECT_RESULT();
#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_GCM */
    return res;
}

static int test_wolfssl_EVP_sm4_ccm_zeroLen(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CCM)
    /* Zero length plain text */
    EXPECT_DECLS;
    byte key[] = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    }; /* align */
    byte iv[]  = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    }; /* align */
    byte plaintxt[1];
    int ivSz  = 12;
    int plaintxtSz = 0;
    unsigned char tag[16];

    byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0};
    byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0};
    int ciphertxtSz = 0;
    int decryptedtxtSz = 0;
    int len = 0;

    EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new();

    ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_sm4_ccm(), NULL, key, iv));
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL));
    ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt,
                                     plaintxtSz));
    ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len));
    ciphertxtSz += len;
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_GET_TAG, 16, tag));
    ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en));

    ExpectIntEQ(0, ciphertxtSz);

    EVP_CIPHER_CTX_init(de);
    ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_sm4_ccm(), NULL, key, iv));
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL));
    ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len));
    decryptedtxtSz = len;
    ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_TAG, 16, tag));
    ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len));
    decryptedtxtSz += len;
    ExpectIntEQ(0, decryptedtxtSz);

    EVP_CIPHER_CTX_free(en);
    EVP_CIPHER_CTX_free(de);

    res = EXPECT_RESULT();
#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_CCM */
    return res;
}

static int test_wolfssl_EVP_sm4_ccm(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CCM)
    EXPECT_DECLS;
    byte *key = (byte*)"0123456789012345";
    byte *iv = (byte*)"0123456789012";
    int ivSz = (int)XSTRLEN((char*)iv);
    /* Message to be encrypted */
    byte *plaintxt = (byte*)"for things to change you have to change";
    /* Additional non-confidential data */
    byte *aad = (byte*)"Don't spend major time on minor things.";

    unsigned char tag[SM4_BLOCK_SIZE] = {0};
    int plaintxtSz = (int)XSTRLEN((char*)plaintxt);
    int aadSz = (int)XSTRLEN((char*)aad);
    byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0};
    byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0};
    int ciphertxtSz = 0;
    int decryptedtxtSz = 0;
    int len = 0;
    int i = 0;
    EVP_CIPHER_CTX en[2];
    EVP_CIPHER_CTX de[2];

    for (i = 0; i < 2; i++) {
        EVP_CIPHER_CTX_init(&en[i]);

        if (i == 0) {
            /* Default uses 96-bits IV length */
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_ccm(), NULL, key,
                iv));
        }
        else {
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_ccm(), NULL, NULL,
                NULL));
             /* non-default must to set the IV length first */
            ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_SET_IVLEN,
                ivSz, NULL));
            ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv));
        }
        ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt,
            plaintxtSz));
        ciphertxtSz = len;
        ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len));
        ciphertxtSz += len;
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_GET_TAG,
            SM4_BLOCK_SIZE, tag));
        ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1);

        EVP_CIPHER_CTX_init(&de[i]);
        if (i == 0) {
            /* Default uses 96-bits IV length */
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_ccm(), NULL, key,
                iv));
        }
        else {
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_ccm(), NULL, NULL,
                NULL));
            /* non-default must to set the IV length first */
            ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_IVLEN,
                ivSz, NULL));
            ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv));

        }
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt,
            ciphertxtSz));
        decryptedtxtSz = len;
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG,
            SM4_BLOCK_SIZE, tag));
        ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        decryptedtxtSz += len;
        ExpectIntEQ(ciphertxtSz, decryptedtxtSz);
        ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz));

        /* modify tag*/
        tag[SM4_BLOCK_SIZE-1]+=0xBB;
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
        ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG,
            SM4_BLOCK_SIZE, tag));
        /* fail due to wrong tag */
        ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt,
            ciphertxtSz));
        ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
        ExpectIntEQ(0, len);
        ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1);
    }

    res = EXPECT_RESULT();
#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_CCM */
    return res;
}

static int test_wolfSSL_EVP_PKEY_hkdf(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_HKDF)
    EVP_PKEY_CTX* ctx = NULL;
    byte salt[]  = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    byte key[]   = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
    byte info[]  = {0X01, 0x02, 0x03, 0x04, 0x05};
    byte info2[] = {0X06, 0x07, 0x08, 0x09, 0x0A};
    byte outKey[34];
    size_t outKeySz = sizeof(outKey);
    /* These expected outputs were gathered by running the same test below using
     * OpenSSL. */
    const byte extractAndExpand[] = {
        0x8B, 0xEB, 0x90, 0xA9, 0x04, 0xFF, 0x05, 0x10, 0xE4, 0xB5, 0xB1, 0x10,
        0x31, 0x34, 0xFF, 0x07, 0x5B, 0xE3, 0xC6, 0x93, 0xD4, 0xF8, 0xC7, 0xEE,
        0x96, 0xDA, 0x78, 0x7A, 0xE2, 0x9A, 0x2D, 0x05, 0x4B, 0xF6
    };
    const byte extractOnly[] = {
        0xE7, 0x6B, 0x9E, 0x0F, 0xE4, 0x02, 0x1D, 0x62, 0xEA, 0x97, 0x74, 0x5E,
        0xF4, 0x3C, 0x65, 0x4D, 0xC1, 0x46, 0x98, 0xAA, 0x79, 0x9A, 0xCB, 0x9C,
        0xCC, 0x3E, 0x7F, 0x2A, 0x2B, 0x41, 0xA1, 0x9E
    };
    const byte expandOnly[] = {
        0xFF, 0x29, 0x29, 0x56, 0x9E, 0xA7, 0x66, 0x02, 0xDB, 0x4F, 0xDB, 0x53,
        0x7D, 0x21, 0x67, 0x52, 0xC3, 0x0E, 0xF3, 0xFC, 0x71, 0xCE, 0x67, 0x2B,
        0xEA, 0x3B, 0xE9, 0xFC, 0xDD, 0xC8, 0xCC, 0xB7, 0x42, 0x74
    };
    const byte extractAndExpandAddInfo[] = {
        0x5A, 0x74, 0x79, 0x83, 0xA3, 0xA4, 0x2E, 0xB7, 0xD4, 0x08, 0xC2, 0x6A,
        0x2F, 0xA5, 0xE3, 0x4E, 0xF1, 0xF4, 0x87, 0x3E, 0xA6, 0xC7, 0x88, 0x45,
        0xD7, 0xE2, 0x15, 0xBC, 0xB8, 0x10, 0xEF, 0x6C, 0x4D, 0x7A
    };

    ExpectNotNull((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)));
    ExpectIntEQ(EVP_PKEY_derive_init(ctx), WOLFSSL_SUCCESS);
    /* NULL ctx. */
    ExpectIntEQ(EVP_PKEY_CTX_set_hkdf_md(NULL, EVP_sha256()), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* NULL md. */
    ExpectIntEQ(EVP_PKEY_CTX_set_hkdf_md(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_sha256()), WOLFSSL_SUCCESS);
    /* NULL ctx. */
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(NULL, salt, sizeof(salt)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* NULL salt is ok. */
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, NULL, sizeof(salt)),
                WOLFSSL_SUCCESS);
    /* Salt length <= 0. */
    /* Length 0 salt is ok. */
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, -1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, sizeof(salt)),
                WOLFSSL_SUCCESS);
    /* NULL ctx. */
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(NULL, key, sizeof(key)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* NULL key. */
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, NULL, sizeof(key)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Key length <= 0 */
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, key, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, key, -1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, key, sizeof(key)),
                WOLFSSL_SUCCESS);
    /* NULL ctx. */
    ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(NULL, info, sizeof(info)),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* NULL info is ok. */
    ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, NULL, sizeof(info)),
                WOLFSSL_SUCCESS);
    /* Info length <= 0 */
    /* Length 0 info is ok. */
    ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info, -1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info, sizeof(info)),
                WOLFSSL_SUCCESS);
    /* NULL ctx. */
    ExpectIntEQ(EVP_PKEY_CTX_hkdf_mode(NULL, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY),
                WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Extract and expand (default). */
    ExpectIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS);
    ExpectIntEQ(outKeySz, sizeof(extractAndExpand));
    ExpectIntEQ(XMEMCMP(outKey, extractAndExpand, outKeySz), 0);
    /* Extract only. */
    ExpectIntEQ(EVP_PKEY_CTX_hkdf_mode(ctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY),
                WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS);
    ExpectIntEQ(outKeySz, sizeof(extractOnly));
    ExpectIntEQ(XMEMCMP(outKey, extractOnly, outKeySz), 0);
    outKeySz = sizeof(outKey);
    /* Expand only. */
    ExpectIntEQ(EVP_PKEY_CTX_hkdf_mode(ctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY),
                WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS);
    ExpectIntEQ(outKeySz, sizeof(expandOnly));
    ExpectIntEQ(XMEMCMP(outKey, expandOnly, outKeySz), 0);
    outKeySz = sizeof(outKey);
    /* Extract and expand with appended additional info. */
    ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info2, sizeof(info2)),
                WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_CTX_hkdf_mode(ctx,
                EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS);
    ExpectIntEQ(outKeySz, sizeof(extractAndExpandAddInfo));
    ExpectIntEQ(XMEMCMP(outKey, extractAndExpandAddInfo, outKeySz), 0);

    EVP_PKEY_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && HAVE_HKDF */
    return EXPECT_RESULT();
}

#ifndef NO_BIO
static int test_wolfSSL_PEM_X509_INFO_read_bio(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    BIO* bio = NULL;
    X509_INFO* info = NULL;
    STACK_OF(X509_INFO)* sk = NULL;
    char* subject = NULL;
    char exp1[] = "/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/"
                  "CN=www.wolfssl.com/emailAddress=info@wolfssl.com";
    char exp2[] = "/C=US/ST=Montana/L=Bozeman/O=wolfSSL/OU=Support/"
                  "CN=www.wolfssl.com/emailAddress=info@wolfssl.com";

    ExpectNotNull(bio = BIO_new(BIO_s_file()));
    ExpectIntGT(BIO_read_filename(bio, svrCertFile), 0);
    ExpectNotNull(sk = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL));
    ExpectIntEQ(sk_X509_INFO_num(sk), 2);

    /* using dereference to maintain testing for Apache port*/
    ExpectNotNull(info = sk_X509_INFO_pop(sk));
    ExpectNotNull(subject = X509_NAME_oneline(X509_get_subject_name(info->x509),
        0, 0));

    ExpectIntEQ(0, XSTRNCMP(subject, exp1, sizeof(exp1)));
    XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
    X509_INFO_free(info);
    info = NULL;

    ExpectNotNull(info = sk_X509_INFO_pop(sk));
    ExpectNotNull(subject = X509_NAME_oneline(X509_get_subject_name(info->x509),
        0, 0));

    ExpectIntEQ(0, XSTRNCMP(subject, exp2, sizeof(exp2)));
    XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
    X509_INFO_free(info);
    ExpectNull(info = sk_X509_INFO_pop(sk));

    sk_X509_INFO_pop_free(sk, X509_INFO_free);
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}
#endif /* !NO_BIO */

static int test_wolfSSL_X509_NAME_ENTRY_get_object(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    X509 *x509 = NULL;
    X509_NAME* name = NULL;
    int idx = 0;
    X509_NAME_ENTRY *ne = NULL;
    ASN1_OBJECT *object = NULL;

    ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(name = X509_get_subject_name(x509));
    ExpectIntGE(idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1), 0);

    ExpectNotNull(ne = X509_NAME_get_entry(name, idx));
    ExpectNotNull(object = X509_NAME_ENTRY_get_object(ne));

    X509_free(x509);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_get1_certs(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SIGNER_DER_CERT) && \
    !defined(NO_FILESYSTEM) && !defined(NO_RSA)
    X509_STORE_CTX *storeCtx = NULL;
    X509_STORE *store = NULL;
    X509 *caX509 = NULL;
    X509 *svrX509 = NULL;
    X509_NAME *subject = NULL;
    WOLF_STACK_OF(WOLFSSL_X509) *certs = NULL;

    ExpectNotNull(caX509 = X509_load_certificate_file(caCertFile,
        SSL_FILETYPE_PEM));
    ExpectNotNull((svrX509 = wolfSSL_X509_load_certificate_file(svrCertFile,
        SSL_FILETYPE_PEM)));
    ExpectNotNull(storeCtx = X509_STORE_CTX_new());
    ExpectNotNull(store = X509_STORE_new());
    ExpectNotNull(subject = X509_get_subject_name(caX509));

    /* Errors */
    ExpectNull(X509_STORE_get1_certs(storeCtx, subject));
    ExpectNull(X509_STORE_get1_certs(NULL, subject));
    ExpectNull(X509_STORE_get1_certs(storeCtx, NULL));

    ExpectIntEQ(X509_STORE_add_cert(store, caX509), SSL_SUCCESS);
    ExpectIntEQ(X509_STORE_CTX_init(storeCtx, store, caX509, NULL),
        SSL_SUCCESS);

    /* Should find the cert */
    ExpectNotNull(certs = X509_STORE_get1_certs(storeCtx, subject));
    ExpectIntEQ(1, wolfSSL_sk_X509_num(certs));

    sk_X509_pop_free(certs, NULL);
    certs = NULL;

    /* Should not find the cert */
    ExpectNotNull(subject = X509_get_subject_name(svrX509));
    ExpectNotNull(certs = X509_STORE_get1_certs(storeCtx, subject));
    ExpectIntEQ(0, wolfSSL_sk_X509_num(certs));

    sk_X509_pop_free(certs, NULL);
    certs = NULL;

    X509_STORE_free(store);
    X509_STORE_CTX_free(storeCtx);
    X509_free(svrX509);
    X509_free(caX509);
#endif /* OPENSSL_EXTRA && WOLFSSL_SIGNER_DER_CERT && !NO_FILESYSTEM */
    return EXPECT_RESULT();
}

#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(WOLFSSL_LOCAL_X509_STORE) && \
    (defined(OPENSSL_ALL) || defined(WOLFSSL_QT)) && defined(HAVE_CRL)
static int test_wolfSSL_X509_STORE_set_get_crl_provider(X509_STORE_CTX* ctx,
        X509_CRL** crl_out, X509* cert) {
    X509_CRL *crl = NULL;
    XFILE fp = XBADFILE;
    char* cert_issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
    int ret = 0;

    (void)ctx;

    if (cert_issuer == NULL)
        return 0;

    if ((fp = XFOPEN("certs/crl/crl.pem", "rb")) != XBADFILE) {
        PEM_read_X509_CRL(fp, &crl, NULL, NULL);
        XFCLOSE(fp);
        if (crl != NULL) {
            char* crl_issuer = X509_NAME_oneline(
                    X509_CRL_get_issuer(crl), NULL, 0);
            if ((crl_issuer != NULL) &&
                   (XSTRCMP(cert_issuer, crl_issuer) == 0)) {
                *crl_out = X509_CRL_dup(crl);
                if (*crl_out != NULL)
                    ret = 1;
            }
            OPENSSL_free(crl_issuer);
        }
    }

    X509_CRL_free(crl);
    OPENSSL_free(cert_issuer);
    return ret;
}

static int test_wolfSSL_X509_STORE_set_get_crl_provider2(X509_STORE_CTX* ctx,
        X509_CRL** crl_out, X509* cert) {
    (void)ctx;
    (void)cert;
    *crl_out = NULL;
    return 1;
}

#ifndef NO_WOLFSSL_STUB
static int test_wolfSSL_X509_STORE_set_get_crl_check(X509_STORE_CTX* ctx,
        X509_CRL* crl) {
    (void)ctx;
    (void)crl;
    return 1;
}
#endif

static int test_wolfSSL_X509_STORE_set_get_crl_verify(int ok,
        X509_STORE_CTX* ctx) {
    int cert_error = X509_STORE_CTX_get_error(ctx);
    X509_VERIFY_PARAM* param = X509_STORE_CTX_get0_param(ctx);
    int flags = X509_VERIFY_PARAM_get_flags(param);
    if ((flags & (X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL)) !=
            (X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL)) {
        /* Make sure the flags are set */
        return 0;
    }
    /* Ignore CRL missing error */
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
    if (cert_error == WC_NO_ERR_TRACE(CRL_MISSING))
#else
    if (cert_error == X509_V_ERR_UNABLE_TO_GET_CRL)
#endif
        return 1;
    return ok;
}

static int test_wolfSSL_X509_STORE_set_get_crl_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    X509_STORE* cert_store = NULL;

    ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL),
            WOLFSSL_SUCCESS);
    ExpectNotNull(cert_store = SSL_CTX_get_cert_store(ctx));
    X509_STORE_set_get_crl(cert_store,
            test_wolfSSL_X509_STORE_set_get_crl_provider);
#ifndef NO_WOLFSSL_STUB
    X509_STORE_set_check_crl(cert_store,
            test_wolfSSL_X509_STORE_set_get_crl_check);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_STORE_set_get_crl_ctx_ready2(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    X509_STORE* cert_store = NULL;
    X509_VERIFY_PARAM* param = NULL;

    SSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
    ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL),
            WOLFSSL_SUCCESS);
    ExpectNotNull(cert_store = SSL_CTX_get_cert_store(ctx));
    X509_STORE_set_get_crl(cert_store,
            test_wolfSSL_X509_STORE_set_get_crl_provider2);
#ifndef NO_WOLFSSL_STUB
    X509_STORE_set_check_crl(cert_store,
            test_wolfSSL_X509_STORE_set_get_crl_check);
#endif
    X509_STORE_set_verify_cb(cert_store,
            test_wolfSSL_X509_STORE_set_get_crl_verify);
    ExpectNotNull(X509_STORE_get0_param(cert_store));
    ExpectNotNull(param = X509_VERIFY_PARAM_new());
    ExpectIntEQ(X509_VERIFY_PARAM_inherit(param,
            X509_STORE_get0_param(cert_store)), 1);
    ExpectIntEQ(X509_VERIFY_PARAM_set_flags(
        param, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL), 1);
    ExpectIntEQ(X509_STORE_set1_param(cert_store, param), 1);
    ExpectIntEQ(X509_STORE_set_flags(cert_store,
            X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL), 1);


    X509_VERIFY_PARAM_free(param);
    return EXPECT_RESULT();
}
#endif

/* This test mimics the usage of the CRL provider in gRPC */
static int test_wolfSSL_X509_STORE_set_get_crl(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(WOLFSSL_LOCAL_X509_STORE) && \
    (defined(OPENSSL_ALL) || defined(WOLFSSL_QT)) && defined(HAVE_CRL)
    test_ssl_cbf func_cb_client;
    test_ssl_cbf func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

    func_cb_client.ctx_ready = test_wolfSSL_X509_STORE_set_get_crl_ctx_ready;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
        &func_cb_server, NULL), TEST_SUCCESS);

    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

    func_cb_client.ctx_ready = test_wolfSSL_X509_STORE_set_get_crl_ctx_ready2;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
        &func_cb_server, NULL), TEST_SUCCESS);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_dup_CA_list(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_ALL)
    EXPECT_DECLS;
    STACK_OF(X509_NAME) *originalStack = NULL;
    STACK_OF(X509_NAME) *copyStack = NULL;
    int originalCount = 0;
    int copyCount = 0;
    X509_NAME *name = NULL;
    int i;

    originalStack = sk_X509_NAME_new_null();
    ExpectNotNull(originalStack);

    for (i = 0; i < 3; i++) {
        name = X509_NAME_new();
        ExpectNotNull(name);
        ExpectIntEQ(sk_X509_NAME_push(originalStack, name), i+1);
        if (EXPECT_FAIL()) {
            X509_NAME_free(name);
        }
    }

    copyStack = SSL_dup_CA_list(originalStack);
    ExpectNotNull(copyStack);
    originalCount = sk_X509_NAME_num(originalStack);
    copyCount = sk_X509_NAME_num(copyStack);

    ExpectIntEQ(originalCount, copyCount);
    sk_X509_NAME_pop_free(originalStack, X509_NAME_free);
    sk_X509_NAME_pop_free(copyStack, X509_NAME_free);

    originalStack = NULL;
    copyStack = NULL;

    res = EXPECT_RESULT();
#endif /* OPENSSL_ALL */
    return res;
}

static int test_ForceZero(void)
{
    EXPECT_DECLS;
    unsigned char data[32];
    unsigned int i, j, len;

    /* Test case with 0 length */
    ForceZero(data, 0);

    /* Test ForceZero */
    for (i = 0; i < sizeof(data); i++) {
        for (len = 1; len < sizeof(data) - i; len++) {
            for (j = 0; j < sizeof(data); j++)
                data[j] = ((unsigned char)j + 1);

            ForceZero(data + i, len);

            for (j = 0; j < sizeof(data); j++) {
                if (j < i || j >= i + len) {
                    ExpectIntNE(data[j], 0x00);
                }
                else {
                    ExpectIntEQ(data[j], 0x00);
                }
            }
        }
    }

    return EXPECT_RESULT();
}

#ifndef NO_BIO

static int test_wolfSSL_X509_print(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
   !defined(NO_RSA) && defined(XSNPRINTF)
    X509 *x509 = NULL;
    BIO *bio = NULL;
#if defined(OPENSSL_ALL) && !defined(NO_WOLFSSL_DIR)
    const X509_ALGOR *cert_sig_alg = NULL;
#endif

    ExpectNotNull(x509 = X509_load_certificate_file(svrCertFile,
        WOLFSSL_FILETYPE_PEM));

    /* print to memory */
    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(X509_print(bio, x509), SSL_SUCCESS);

#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
  #if defined(WC_DISABLE_RADIX_ZERO_PAD)
     /* Will print IP address subject alt name. */
     ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3349);
  #elif defined(NO_ASN_TIME)
      /* Will print IP address subject alt name but not Validity. */
     ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3235);
  #else
      /* Will print IP address subject alt name. */
     ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3350);
  #endif
#elif defined(NO_ASN_TIME)
    /* With NO_ASN_TIME defined, X509_print skips printing Validity. */
    ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3213);
#else
    ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3328);
#endif
    BIO_free(bio);
    bio = NULL;

    ExpectNotNull(bio = BIO_new_fd(STDERR_FILENO, BIO_NOCLOSE));

#if defined(OPENSSL_ALL) && !defined(NO_WOLFSSL_DIR)
    /* Print signature */
    ExpectNotNull(cert_sig_alg = X509_get0_tbs_sigalg(x509));
    ExpectIntEQ(X509_signature_print(bio, cert_sig_alg, NULL), SSL_SUCCESS);
#endif

    /* print to stderr */
#if !defined(NO_WOLFSSL_DIR)
    ExpectIntEQ(X509_print(bio, x509), SSL_SUCCESS);
#endif
    /* print again */
    ExpectIntEQ(X509_print_fp(stderr, x509), SSL_SUCCESS);

    X509_free(x509);
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_X509_CRL_print(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && defined(HAVE_CRL)\
    && !defined(NO_FILESYSTEM) && defined(XSNPRINTF)
    X509_CRL* crl = NULL;
    BIO *bio = NULL;
    XFILE fp = XBADFILE;

    ExpectTrue((fp = XFOPEN("./certs/crl/crl.pem", "rb")) != XBADFILE);
    ExpectNotNull(crl = (X509_CRL*)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
        NULL, NULL));
    if (fp != XBADFILE)
        XFCLOSE(fp);

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(X509_CRL_print(bio, crl), SSL_SUCCESS);

    X509_CRL_free(crl);
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_BIO_get_len(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_BIO)
    BIO *bio = NULL;
    const char txt[] = "Some example text to push to the BIO.";

    ExpectIntEQ(wolfSSL_BIO_get_len(bio), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));

    ExpectIntEQ(wolfSSL_BIO_write(bio, txt, sizeof(txt)), sizeof(txt));
    ExpectIntEQ(wolfSSL_BIO_get_len(bio), sizeof(txt));
    BIO_free(bio);
    bio = NULL;

    ExpectNotNull(bio = BIO_new_fd(STDERR_FILENO, BIO_NOCLOSE));
    ExpectIntEQ(wolfSSL_BIO_get_len(bio), WC_NO_ERR_TRACE(WOLFSSL_BAD_FILE));
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

#endif /* !NO_BIO */

static int test_wolfSSL_RSA(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
    RSA* rsa = NULL;
    const BIGNUM *n = NULL;
    const BIGNUM *e = NULL;
    const BIGNUM *d = NULL;
    const BIGNUM *p = NULL;
    const BIGNUM *q = NULL;
    const BIGNUM *dmp1 = NULL;
    const BIGNUM *dmq1 = NULL;
    const BIGNUM *iqmp = NULL;

    ExpectNotNull(rsa = RSA_new());
    ExpectIntEQ(RSA_size(NULL), 0);
    ExpectIntEQ(RSA_size(rsa), 0);
    ExpectIntEQ(RSA_set0_key(rsa, NULL, NULL, NULL), 0);
    ExpectIntEQ(RSA_set0_crt_params(rsa, NULL, NULL, NULL), 0);
    ExpectIntEQ(RSA_set0_factors(rsa, NULL, NULL), 0);
#ifdef WOLFSSL_RSA_KEY_CHECK
    ExpectIntEQ(RSA_check_key(rsa), 0);
#endif

    RSA_free(rsa);
    rsa = NULL;
    ExpectNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL));
    ExpectIntEQ(RSA_size(rsa), 256);

#if (!defined(HAVE_FIPS) || FIPS_VERSION3_GT(6,0,0)) && !defined(HAVE_SELFTEST)
    {
        /* Test setting only subset of parameters */
        RSA *rsa2 = NULL;
        unsigned char hash[SHA256_DIGEST_LENGTH];
        unsigned char signature[2048/8];
        unsigned int signatureLen = 0;
        BIGNUM* n2 = NULL;
        BIGNUM* e2 = NULL;
        BIGNUM* d2 = NULL;
        BIGNUM* p2 = NULL;
        BIGNUM* q2 = NULL;
        BIGNUM* dmp12 = NULL;
        BIGNUM* dmq12 = NULL;
        BIGNUM* iqmp2 = NULL;

        XMEMSET(hash, 0, sizeof(hash));
        RSA_get0_key(rsa, &n, &e, &d);
        RSA_get0_factors(rsa, &p, &q);
        RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);

        ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature,
            &signatureLen, rsa), 1);
        /* Quick sanity check */
        ExpectIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature,
            signatureLen, rsa), 1);

        /* Verifying */
        ExpectNotNull(n2 = BN_dup(n));
        ExpectNotNull(e2 = BN_dup(e));
        ExpectNotNull(p2 = BN_dup(p));
        ExpectNotNull(q2 = BN_dup(q));
        ExpectNotNull(dmp12 = BN_dup(dmp1));
        ExpectNotNull(dmq12 = BN_dup(dmq1));
        ExpectNotNull(iqmp2 = BN_dup(iqmp));

        ExpectNotNull(rsa2 = RSA_new());
        ExpectIntEQ(RSA_set0_key(rsa2, n2, e2, NULL), 1);
        if (EXPECT_SUCCESS()) {
            n2 = NULL;
            e2 = NULL;
        }
        ExpectIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature,
            signatureLen, rsa2), 1);
        ExpectIntEQ(RSA_set0_factors(rsa2, p2, q2), 1);
        if (EXPECT_SUCCESS()) {
            p2 = NULL;
            q2 = NULL;
        }
        ExpectIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature,
            signatureLen, rsa2), 1);
        ExpectIntEQ(RSA_set0_crt_params(rsa2, dmp12, dmq12, iqmp2), 1);
        if (EXPECT_SUCCESS()) {
            dmp12 = NULL;
            dmq12 = NULL;
            iqmp2 = NULL;
        }
        ExpectIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature,
            signatureLen, rsa2), 1);
        RSA_free(rsa2);
        rsa2 = NULL;

        BN_free(iqmp2);
        iqmp2 = NULL;
        BN_free(dmq12);
        dmq12 = NULL;
        BN_free(dmp12);
        dmp12 = NULL;
        BN_free(q2);
        q2 = NULL;
        BN_free(p2);
        p2 = NULL;
        BN_free(e2);
        e2 = NULL;
        BN_free(n2);
        n2 = NULL;

        ExpectNotNull(n2 = BN_dup(n));
        ExpectNotNull(e2 = BN_dup(e));
        ExpectNotNull(d2 = BN_dup(d));
        ExpectNotNull(p2 = BN_dup(p));
        ExpectNotNull(q2 = BN_dup(q));
        ExpectNotNull(dmp12 = BN_dup(dmp1));
        ExpectNotNull(dmq12 = BN_dup(dmq1));
        ExpectNotNull(iqmp2 = BN_dup(iqmp));

        /* Signing */
        XMEMSET(signature, 0, sizeof(signature));
        ExpectNotNull(rsa2 = RSA_new());
        ExpectIntEQ(RSA_set0_key(rsa2, n2, e2, d2), 1);
        if (EXPECT_SUCCESS()) {
            n2 = NULL;
            e2 = NULL;
            d2 = NULL;
        }
#if defined(WOLFSSL_SP_MATH) && !defined(RSA_LOW_MEM)
        /* SP is not support signing without CRT parameters. */
        ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature,
            &signatureLen, rsa2), 0);
        ExpectIntEQ(RSA_set0_factors(rsa2, p2, q2), 1);
        if (EXPECT_SUCCESS()) {
            p2 = NULL;
            q2 = NULL;
        }
        ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature,
            &signatureLen, rsa2), 0);
#else
        ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature,
            &signatureLen, rsa2), 1);
        ExpectIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature,
            signatureLen, rsa), 1);
        ExpectIntEQ(RSA_set0_factors(rsa2, p2, q2), 1);
        if (EXPECT_SUCCESS()) {
            p2 = NULL;
            q2 = NULL;
        }
        XMEMSET(signature, 0, sizeof(signature));
        ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature,
            &signatureLen, rsa2), 1);
        ExpectIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature,
            signatureLen, rsa), 1);
#endif
        ExpectIntEQ(RSA_set0_crt_params(rsa2, dmp12, dmq12, iqmp2), 1);
        if (EXPECT_SUCCESS()) {
            dmp12 = NULL;
            dmq12 = NULL;
            iqmp2 = NULL;
        }
        ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature,
            &signatureLen, rsa2), 1);
        ExpectIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature,
            signatureLen, rsa), 1);
        RSA_free(rsa2);
        rsa2 = NULL;

        BN_free(iqmp2);
        BN_free(dmq12);
        BN_free(dmp12);
        BN_free(q2);
        BN_free(p2);
        BN_free(d2);
        BN_free(e2);
        BN_free(n2);
    }
#endif

#ifdef WOLFSSL_RSA_KEY_CHECK
    ExpectIntEQ(RSA_check_key(NULL), 0);
    ExpectIntEQ(RSA_check_key(rsa), 1);
#endif

    /* sanity check */
    ExpectIntEQ(RSA_bits(NULL), 0);

    /* key */
    ExpectIntEQ(RSA_bits(rsa), 2048);
    RSA_get0_key(rsa, &n, &e, &d);
    ExpectPtrEq(rsa->n, n);
    ExpectPtrEq(rsa->e, e);
    ExpectPtrEq(rsa->d, d);
    n = NULL;
    e = NULL;
    d = NULL;
    ExpectNotNull(n = BN_new());
    ExpectNotNull(e = BN_new());
    ExpectNotNull(d = BN_new());
    ExpectIntEQ(RSA_set0_key(rsa, (BIGNUM*)n, (BIGNUM*)e, (BIGNUM*)d), 1);
    if (EXPECT_FAIL()) {
        BN_free((BIGNUM*)n);
        BN_free((BIGNUM*)e);
        BN_free((BIGNUM*)d);
    }
    ExpectPtrEq(rsa->n, n);
    ExpectPtrEq(rsa->e, e);
    ExpectPtrEq(rsa->d, d);
    ExpectIntEQ(RSA_set0_key(rsa, NULL, NULL, NULL), 1);
    ExpectIntEQ(RSA_set0_key(NULL, (BIGNUM*)n, (BIGNUM*)e, (BIGNUM*)d), 0);

    /* crt_params */
    RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
    ExpectPtrEq(rsa->dmp1, dmp1);
    ExpectPtrEq(rsa->dmq1, dmq1);
    ExpectPtrEq(rsa->iqmp, iqmp);
    dmp1 = NULL;
    dmq1 = NULL;
    iqmp = NULL;
    ExpectNotNull(dmp1 = BN_new());
    ExpectNotNull(dmq1 = BN_new());
    ExpectNotNull(iqmp = BN_new());
    ExpectIntEQ(RSA_set0_crt_params(rsa, (BIGNUM*)dmp1, (BIGNUM*)dmq1,
        (BIGNUM*)iqmp), 1);
    if (EXPECT_FAIL()) {
        BN_free((BIGNUM*)dmp1);
        BN_free((BIGNUM*)dmq1);
        BN_free((BIGNUM*)iqmp);
    }
    ExpectPtrEq(rsa->dmp1, dmp1);
    ExpectPtrEq(rsa->dmq1, dmq1);
    ExpectPtrEq(rsa->iqmp, iqmp);
    ExpectIntEQ(RSA_set0_crt_params(rsa, NULL, NULL, NULL), 1);
    ExpectIntEQ(RSA_set0_crt_params(NULL, (BIGNUM*)dmp1, (BIGNUM*)dmq1,
        (BIGNUM*)iqmp), 0);
    RSA_get0_crt_params(NULL, NULL, NULL, NULL);
    RSA_get0_crt_params(rsa, NULL, NULL, NULL);
    RSA_get0_crt_params(NULL, &dmp1, &dmq1, &iqmp);
    ExpectNull(dmp1);
    ExpectNull(dmq1);
    ExpectNull(iqmp);

    /* factors */
    RSA_get0_factors(rsa, NULL, NULL);
    RSA_get0_factors(rsa, &p, &q);
    ExpectPtrEq(rsa->p, p);
    ExpectPtrEq(rsa->q, q);
    p = NULL;
    q = NULL;
    ExpectNotNull(p = BN_new());
    ExpectNotNull(q = BN_new());
    ExpectIntEQ(RSA_set0_factors(rsa, (BIGNUM*)p, (BIGNUM*)q), 1);
    if (EXPECT_FAIL()) {
        BN_free((BIGNUM*)p);
        BN_free((BIGNUM*)q);
    }
    ExpectPtrEq(rsa->p, p);
    ExpectPtrEq(rsa->q, q);
    ExpectIntEQ(RSA_set0_factors(rsa, NULL, NULL), 1);
    ExpectIntEQ(RSA_set0_factors(NULL, (BIGNUM*)p, (BIGNUM*)q), 0);
    RSA_get0_factors(NULL, NULL, NULL);
    RSA_get0_factors(NULL, &p, &q);
    ExpectNull(p);
    ExpectNull(q);

    ExpectIntEQ(BN_hex2bn(&rsa->n, "1FFFFF"), 1);
    ExpectIntEQ(RSA_bits(rsa), 21);
    RSA_free(rsa);
    rsa = NULL;

#if !defined(USE_FAST_MATH) || (FP_MAX_BITS >= (3072*2))
    ExpectNotNull(rsa = RSA_generate_key(3072, 17, NULL, NULL));
    ExpectIntEQ(RSA_size(rsa), 384);
    ExpectIntEQ(RSA_bits(rsa), 3072);
    RSA_free(rsa);
    rsa = NULL;
#endif

    /* remove for now with odd key size until adjusting rsa key size check with
       wc_MakeRsaKey()
    ExpectNotNull(rsa = RSA_generate_key(2999, 65537, NULL, NULL));
    RSA_free(rsa);
    rsa = NULL;
    */

    ExpectNull(RSA_generate_key(-1, 3, NULL, NULL));
    ExpectNull(RSA_generate_key(RSA_MIN_SIZE - 1, 3, NULL, NULL));
    ExpectNull(RSA_generate_key(RSA_MAX_SIZE + 1, 3, NULL, NULL));
    ExpectNull(RSA_generate_key(2048, 0, NULL, NULL));


#if !defined(NO_FILESYSTEM) && !defined(NO_ASN)
    {
        byte buff[FOURK_BUF];
        byte der[FOURK_BUF];
        const char PrivKeyPemFile[] = "certs/client-keyEnc.pem";

        XFILE f = XBADFILE;
        int bytes = 0;

        /* test loading encrypted RSA private pem w/o password */
        ExpectTrue((f = XFOPEN(PrivKeyPemFile, "rb")) != XBADFILE);
        ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
        if (f != XBADFILE)
            XFCLOSE(f);
        XMEMSET(der, 0, sizeof(der));
        /* test that error value is returned with no password */
        ExpectIntLT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der), ""),
            0);
    }
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_DER(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && defined(OPENSSL_EXTRA)
    RSA *rsa = NULL;
    int i;
    const unsigned char *buff = NULL;
    unsigned char *newBuff = NULL;

    struct tbl_s
    {
        const unsigned char *der;
        int sz;
    } tbl[] = {

#ifdef USE_CERT_BUFFERS_1024
        {client_key_der_1024, sizeof_client_key_der_1024},
        {server_key_der_1024, sizeof_server_key_der_1024},
#endif
#ifdef USE_CERT_BUFFERS_2048
        {client_key_der_2048, sizeof_client_key_der_2048},
        {server_key_der_2048, sizeof_server_key_der_2048},
#endif
        {NULL, 0}
    };

    /* Public Key DER */
    struct tbl_s pub[] = {
#ifdef USE_CERT_BUFFERS_1024
        {client_keypub_der_1024, sizeof_client_keypub_der_1024},
#endif
#ifdef USE_CERT_BUFFERS_2048
        {client_keypub_der_2048, sizeof_client_keypub_der_2048},
#endif
        {NULL, 0}
    };

    ExpectNull(d2i_RSAPublicKey(&rsa, NULL, pub[0].sz));
    buff = pub[0].der;
    ExpectNull(d2i_RSAPublicKey(&rsa, &buff, 1));
    ExpectNull(d2i_RSAPrivateKey(&rsa, NULL, tbl[0].sz));
    buff = tbl[0].der;
    ExpectNull(d2i_RSAPrivateKey(&rsa, &buff, 1));

    ExpectIntEQ(i2d_RSAPublicKey(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    rsa = RSA_new();
    ExpectIntEQ(i2d_RSAPublicKey(rsa, NULL), 0);
    RSA_free(rsa);
    rsa = NULL;

    for (i = 0; tbl[i].der != NULL; i++)
    {
        /* Passing in pointer results in pointer moving. */
        buff = tbl[i].der;
        ExpectNotNull(d2i_RSAPublicKey(&rsa, &buff, tbl[i].sz));
        ExpectNotNull(rsa);
        RSA_free(rsa);
        rsa = NULL;
    }
    for (i = 0; tbl[i].der != NULL; i++)
    {
        /* Passing in pointer results in pointer moving. */
        buff = tbl[i].der;
        ExpectNotNull(d2i_RSAPrivateKey(&rsa, &buff, tbl[i].sz));
        ExpectNotNull(rsa);
        RSA_free(rsa);
        rsa = NULL;
    }

    for (i = 0; pub[i].der != NULL; i++)
    {
        buff = pub[i].der;
        ExpectNotNull(d2i_RSAPublicKey(&rsa, &buff, pub[i].sz));
        ExpectNotNull(rsa);
        ExpectIntEQ(i2d_RSAPublicKey(rsa, NULL), pub[i].sz);
        newBuff = NULL;
        ExpectIntEQ(i2d_RSAPublicKey(rsa, &newBuff), pub[i].sz);
        ExpectNotNull(newBuff);
        ExpectIntEQ(XMEMCMP((void *)newBuff, (void *)pub[i].der, pub[i].sz), 0);
        XFREE((void *)newBuff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        RSA_free(rsa);
        rsa = NULL;
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_print(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
   !defined(NO_STDIO_FILESYSTEM) && \
   !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
   !defined(NO_BIO) && defined(XFPRINTF)
    BIO *bio = NULL;
    WOLFSSL_RSA* rsa = NULL;

    ExpectNotNull(bio = BIO_new_fd(STDERR_FILENO, BIO_NOCLOSE));
    ExpectNotNull(rsa = RSA_new());

    ExpectIntEQ(RSA_print(NULL, rsa, 0), -1);
    ExpectIntEQ(RSA_print_fp(XBADFILE, rsa, 0), 0);
    ExpectIntEQ(RSA_print(bio, NULL, 0), -1);
    ExpectIntEQ(RSA_print_fp(stderr, NULL, 0), 0);
    /* Some very large number of indent spaces. */
    ExpectIntEQ(RSA_print(bio, rsa, 128), -1);
    /* RSA is empty. */
    ExpectIntEQ(RSA_print(bio, rsa, 0), 0);
    ExpectIntEQ(RSA_print_fp(stderr, rsa, 0), 0);

    RSA_free(rsa);
    rsa = NULL;
    ExpectNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL));

    ExpectIntEQ(RSA_print(bio, rsa, 0), 1);
    ExpectIntEQ(RSA_print(bio, rsa, 4), 1);
    ExpectIntEQ(RSA_print(bio, rsa, -1), 1);
    ExpectIntEQ(RSA_print_fp(stderr, rsa, 0), 1);
    ExpectIntEQ(RSA_print_fp(stderr, rsa, 4), 1);
    ExpectIntEQ(RSA_print_fp(stderr, rsa, -1), 1);

    BIO_free(bio);
    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_padding_add_PKCS1_PSS(void)
{
    EXPECT_DECLS;
#ifndef NO_RSA
#if defined(OPENSSL_ALL) && defined(WC_RSA_PSS) && !defined(WC_NO_RNG)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    RSA *rsa = NULL;
    const unsigned char *derBuf = client_key_der_2048;
    unsigned char em[256] = {0}; /* len = 2048/8 */
    /* Random data simulating a hash */
    const unsigned char mHash[WC_SHA256_DIGEST_SIZE] = {
        0x28, 0x6e, 0xfd, 0xf8, 0x76, 0xc7, 0x00, 0x3d, 0x91, 0x4e, 0x59, 0xe4,
        0x8e, 0xb7, 0x40, 0x7b, 0xd1, 0x0c, 0x98, 0x4b, 0xe3, 0x3d, 0xb3, 0xeb,
        0x6f, 0x8a, 0x3c, 0x42, 0xab, 0x21, 0xad, 0x28
    };

    ExpectNotNull(d2i_RSAPrivateKey(&rsa, &derBuf, sizeof_client_key_der_2048));
    ExpectIntEQ(RSA_padding_add_PKCS1_PSS(NULL, em, mHash, EVP_sha256(),
        RSA_PSS_SALTLEN_DIGEST), 0);
    ExpectIntEQ(RSA_padding_add_PKCS1_PSS(rsa, NULL, mHash, EVP_sha256(),
        RSA_PSS_SALTLEN_DIGEST), 0);
    ExpectIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, NULL, EVP_sha256(),
        RSA_PSS_SALTLEN_DIGEST), 0);
    ExpectIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, NULL,
        RSA_PSS_SALTLEN_DIGEST), 0);
    ExpectIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(), -5), 0);

    ExpectIntEQ(RSA_verify_PKCS1_PSS(NULL, mHash, EVP_sha256(), em,
        RSA_PSS_SALTLEN_MAX_SIGN), 0);
    ExpectIntEQ(RSA_verify_PKCS1_PSS(rsa, NULL, EVP_sha256(), em,
        RSA_PSS_SALTLEN_MAX_SIGN), 0);
    ExpectIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, NULL, em,
        RSA_PSS_SALTLEN_MAX_SIGN), 0);
    ExpectIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), NULL,
        RSA_PSS_SALTLEN_MAX_SIGN), 0);
    ExpectIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em,
        RSA_PSS_SALTLEN_MAX_SIGN), 0);
    ExpectIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em, -5), 0);

    ExpectIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(),
        RSA_PSS_SALTLEN_DIGEST), 1);
    ExpectIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em,
        RSA_PSS_SALTLEN_DIGEST), 1);

    ExpectIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(),
        RSA_PSS_SALTLEN_MAX_SIGN), 1);
    ExpectIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em,
        RSA_PSS_SALTLEN_MAX_SIGN), 1);

    ExpectIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(),
        RSA_PSS_SALTLEN_MAX), 1);
    ExpectIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em,
        RSA_PSS_SALTLEN_MAX), 1);

    ExpectIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(), 10), 1);
    ExpectIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em, 10), 1);

    RSA_free(rsa);
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /* OPENSSL_ALL && WC_RSA_PSS && !WC_NO_RNG*/
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_sign_sha3(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
#if defined(OPENSSL_ALL) && defined(WC_RSA_PSS) && !defined(WC_NO_RNG)
    RSA* rsa = NULL;
    const unsigned char *derBuf = client_key_der_2048;
    unsigned char sigRet[256] = {0};
    unsigned int sigLen = sizeof(sigRet);
    /* Random data simulating a hash */
    const unsigned char mHash[WC_SHA3_256_DIGEST_SIZE] = {
        0x28, 0x6e, 0xfd, 0xf8, 0x76, 0xc7, 0x00, 0x3d, 0x91, 0x4e, 0x59, 0xe4,
        0x8e, 0xb7, 0x40, 0x7b, 0xd1, 0x0c, 0x98, 0x4b, 0xe3, 0x3d, 0xb3, 0xeb,
        0x6f, 0x8a, 0x3c, 0x42, 0xab, 0x21, 0xad, 0x28
    };

    ExpectNotNull(d2i_RSAPrivateKey(&rsa, &derBuf, sizeof_client_key_der_2048));
    ExpectIntEQ(RSA_sign(NID_sha3_256, mHash, sizeof(mHash), sigRet, &sigLen,
        rsa), 1);

    RSA_free(rsa);
#endif /* OPENSSL_ALL && WC_RSA_PSS && !WC_NO_RNG*/
#endif /* !NO_RSA && WOLFSSL_SHA3 && !WOLFSSL_NOSHA3_256*/
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_get0_key(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA *rsa = NULL;
    const BIGNUM* n = NULL;
    const BIGNUM* e = NULL;
    const BIGNUM* d = NULL;

    const unsigned char* der;
    int derSz;

#ifdef USE_CERT_BUFFERS_1024
    der = client_key_der_1024;
    derSz = sizeof_client_key_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
    der = client_key_der_2048;
    derSz = sizeof_client_key_der_2048;
#else
    der = NULL;
    derSz = 0;
#endif

    if (der != NULL) {
        RSA_get0_key(NULL, NULL, NULL, NULL);
        RSA_get0_key(rsa, NULL, NULL, NULL);
        RSA_get0_key(NULL, &n, &e, &d);
        ExpectNull(n);
        ExpectNull(e);
        ExpectNull(d);

        ExpectNotNull(d2i_RSAPrivateKey(&rsa, &der, derSz));
        ExpectNotNull(rsa);

        RSA_get0_key(rsa, NULL, NULL, NULL);
        RSA_get0_key(rsa, &n, NULL, NULL);
        ExpectNotNull(n);
        RSA_get0_key(rsa, NULL, &e, NULL);
        ExpectNotNull(e);
        RSA_get0_key(rsa, NULL, NULL, &d);
        ExpectNotNull(d);
        RSA_get0_key(rsa, &n, &e, &d);
        ExpectNotNull(n);
        ExpectNotNull(e);
        ExpectNotNull(d);

        RSA_free(rsa);
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_meth(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA *rsa = NULL;
    RSA_METHOD *rsa_meth = NULL;

#ifdef WOLFSSL_KEY_GEN
    ExpectNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL));
    RSA_free(rsa);
    rsa = NULL;
#else
    ExpectNull(rsa = RSA_generate_key(2048, 3, NULL, NULL));
#endif

    ExpectNotNull(RSA_get_default_method());

    wolfSSL_RSA_meth_free(NULL);

    ExpectNull(wolfSSL_RSA_meth_new(NULL, 0));

    ExpectNotNull(rsa_meth = RSA_meth_new("placeholder RSA method",
        RSA_METHOD_FLAG_NO_CHECK));

#ifndef NO_WOLFSSL_STUB
    ExpectIntEQ(RSA_meth_set_pub_enc(rsa_meth, NULL), 1);
    ExpectIntEQ(RSA_meth_set_pub_dec(rsa_meth, NULL), 1);
    ExpectIntEQ(RSA_meth_set_priv_enc(rsa_meth, NULL), 1);
    ExpectIntEQ(RSA_meth_set_priv_dec(rsa_meth, NULL), 1);
    ExpectIntEQ(RSA_meth_set_init(rsa_meth, NULL), 1);
    ExpectIntEQ(RSA_meth_set_finish(rsa_meth, NULL), 1);
    ExpectIntEQ(RSA_meth_set0_app_data(rsa_meth, NULL), 1);
#endif

    ExpectIntEQ(RSA_flags(NULL), 0);
    RSA_set_flags(NULL, RSA_FLAG_CACHE_PUBLIC);
    RSA_clear_flags(NULL, RSA_FLAG_CACHE_PUBLIC);
    ExpectIntEQ(RSA_test_flags(NULL, RSA_FLAG_CACHE_PUBLIC), 0);

    ExpectNotNull(rsa = RSA_new());
    /* No method set. */
    ExpectIntEQ(RSA_flags(rsa), 0);
    RSA_set_flags(rsa, RSA_FLAG_CACHE_PUBLIC);
    RSA_clear_flags(rsa, RSA_FLAG_CACHE_PUBLIC);
    ExpectIntEQ(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0);

    ExpectIntEQ(RSA_set_method(NULL, rsa_meth), 1);
    ExpectIntEQ(RSA_set_method(rsa, rsa_meth), 1);
    if (EXPECT_FAIL()) {
        wolfSSL_RSA_meth_free(rsa_meth);
    }
    ExpectNull(RSA_get_method(NULL));
    ExpectPtrEq(RSA_get_method(rsa), rsa_meth);
    ExpectIntEQ(RSA_flags(rsa), RSA_METHOD_FLAG_NO_CHECK);
    RSA_set_flags(rsa, RSA_FLAG_CACHE_PUBLIC);
    ExpectIntNE(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0);
    ExpectIntEQ(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC |
                                RSA_METHOD_FLAG_NO_CHECK);
    RSA_clear_flags(rsa, RSA_FLAG_CACHE_PUBLIC);
    ExpectIntEQ(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0);
    ExpectIntNE(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC);

    /* rsa_meth is freed here */
    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_verify(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
#ifndef NO_BIO
    XFILE fp = XBADFILE;
    RSA *pKey = NULL;
    RSA *pubKey = NULL;
    X509 *cert = NULL;
    const char *text = "Hello wolfSSL !";
    unsigned char hash[SHA256_DIGEST_LENGTH];
    unsigned char signature[2048/8];
    unsigned int signatureLength;
    byte *buf = NULL;
    BIO *bio = NULL;
    SHA256_CTX c;
    EVP_PKEY *evpPkey = NULL;
    EVP_PKEY *evpPubkey = NULL;
    size_t sz;

    /* generate hash */
    SHA256_Init(&c);
    SHA256_Update(&c, text, strlen(text));
    SHA256_Final(hash, &c);
#ifdef WOLFSSL_SMALL_STACK_CACHE
    /* workaround for small stack cache case */
    wc_Sha256Free((wc_Sha256*)&c);
#endif

    /* read privete key file */
    ExpectTrue((fp = XFOPEN(svrKeyFile, "rb")) != XBADFILE);
    ExpectIntEQ(XFSEEK(fp, 0, XSEEK_END), 0);
    ExpectTrue((sz = XFTELL(fp)) > 0);
    ExpectIntEQ(XFSEEK(fp, 0, XSEEK_SET), 0);
    ExpectNotNull(buf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE));
    ExpectIntEQ(XFREAD(buf, 1, sz, fp), sz);
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }

    /* read private key and sign hash data */
    ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
    ExpectNotNull(evpPkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL));
    ExpectNotNull(pKey = EVP_PKEY_get1_RSA(evpPkey));
    ExpectIntEQ(RSA_sign(NID_sha256, hash, SHA256_DIGEST_LENGTH,
        signature, &signatureLength, pKey), SSL_SUCCESS);

    /* read public key and verify signed data */
    ExpectTrue((fp = XFOPEN(svrCertFile,"rb")) != XBADFILE);
    ExpectNotNull(cert = PEM_read_X509(fp, 0, 0, 0 ));
    if (fp != XBADFILE)
        XFCLOSE(fp);
    ExpectNotNull(evpPubkey = X509_get_pubkey(cert));
    ExpectNotNull(pubKey = EVP_PKEY_get1_RSA(evpPubkey));
    ExpectIntEQ(RSA_verify(NID_sha256, hash, SHA256_DIGEST_LENGTH, signature,
        signatureLength, pubKey), SSL_SUCCESS);

    ExpectIntEQ(RSA_verify(NID_sha256, NULL, SHA256_DIGEST_LENGTH, NULL,
        signatureLength, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(RSA_verify(NID_sha256, NULL, SHA256_DIGEST_LENGTH, signature,
        signatureLength, pubKey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(RSA_verify(NID_sha256, hash, SHA256_DIGEST_LENGTH, NULL,
        signatureLength, pubKey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(RSA_verify(NID_sha256, hash, SHA256_DIGEST_LENGTH, signature,
        signatureLength, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));


    RSA_free(pKey);
    EVP_PKEY_free(evpPkey);
    RSA_free(pubKey);
    EVP_PKEY_free(evpPubkey);
    X509_free(cert);
    BIO_free(bio);
    XFREE(buf, NULL, DYNAMIC_TYPE_FILE);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_sign(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA *rsa;
    unsigned char hash[SHA256_DIGEST_LENGTH];
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* privDer = client_key_der_1024;
    size_t privDerSz = sizeof_client_key_der_1024;
    const unsigned char* pubDer = client_keypub_der_1024;
    size_t pubDerSz = sizeof_client_keypub_der_1024;
    unsigned char signature[1024/8];
#else
    const unsigned char* privDer = client_key_der_2048;
    size_t privDerSz = sizeof_client_key_der_2048;
    const unsigned char* pubDer = client_keypub_der_2048;
    size_t pubDerSz = sizeof_client_keypub_der_2048;
    unsigned char signature[2048/8];
#endif
    unsigned int signatureLen;
    const unsigned char* der;

    XMEMSET(hash, 0, sizeof(hash));

    der = privDer;
    rsa = NULL;
    ExpectNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz));

    /* Invalid parameters. */
    ExpectIntEQ(RSA_sign(NID_rsaEncryption, NULL, 0, NULL, NULL, NULL), 0);
    ExpectIntEQ(RSA_sign(NID_rsaEncryption, hash, sizeof(hash), signature,
        &signatureLen, rsa), 0);
    ExpectIntEQ(RSA_sign(NID_sha256, NULL, sizeof(hash), signature,
        &signatureLen, rsa), 0);
    ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), NULL,
        &signatureLen, rsa), 0);
    ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature,
        NULL, rsa), 0);
    ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature,
        &signatureLen, NULL), 0);

    ExpectIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature,
        &signatureLen, rsa), 1);

    RSA_free(rsa);
    der = pubDer;
    rsa = NULL;
    ExpectNotNull(d2i_RSAPublicKey(&rsa, &der, pubDerSz));

    ExpectIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature,
        signatureLen, rsa), 1);

    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_sign_ex(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA *rsa = NULL;
    unsigned char hash[SHA256_DIGEST_LENGTH];
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* privDer = client_key_der_1024;
    size_t privDerSz = sizeof_client_key_der_1024;
    const unsigned char* pubDer = client_keypub_der_1024;
    size_t pubDerSz = sizeof_client_keypub_der_1024;
    unsigned char signature[1024/8];
#else
    const unsigned char* privDer = client_key_der_2048;
    size_t privDerSz = sizeof_client_key_der_2048;
    const unsigned char* pubDer = client_keypub_der_2048;
    size_t pubDerSz = sizeof_client_keypub_der_2048;
    unsigned char signature[2048/8];
#endif
    unsigned int signatureLen;
    const unsigned char* der;
    unsigned char encodedHash[51];
    unsigned int encodedHashLen;
    const unsigned char expEncHash[] = {
        0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
        0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
        0x00, 0x04, 0x20,
        /* Hash data */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    };

    XMEMSET(hash, 0, sizeof(hash));

    ExpectNotNull(rsa = wolfSSL_RSA_new());
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature,
        &signatureLen, rsa, 1), 0);
    wolfSSL_RSA_free(rsa);

    der = privDer;
    rsa = NULL;
    ExpectNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz));

    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_rsaEncryption,NULL, 0, NULL, NULL, NULL,
        -1), 0);
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_rsaEncryption, hash, sizeof(hash),
        signature, &signatureLen, rsa, 1), 0);
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, NULL, sizeof(hash), signature,
        &signatureLen, rsa, 1), 0);
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), NULL,
        &signatureLen, rsa, 1), 0);
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature,
        NULL, rsa, 1), 0);
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature,
        &signatureLen, NULL, 1), 0);
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature,
        &signatureLen, rsa, -1), 0);
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, NULL, sizeof(hash), signature,
        &signatureLen, rsa, 0), 0);
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), NULL,
        &signatureLen, rsa, 0), 0);
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature,
        NULL, rsa, 0), 0);

    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature,
        &signatureLen, rsa, 1), 1);
    /* Test returning encoded hash. */
    ExpectIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), encodedHash,
        &encodedHashLen, rsa, 0), 1);
    ExpectIntEQ(encodedHashLen, sizeof(expEncHash));
    ExpectIntEQ(XMEMCMP(encodedHash, expEncHash, sizeof(expEncHash)), 0);

    RSA_free(rsa);
    der = pubDer;
    rsa = NULL;
    ExpectNotNull(d2i_RSAPublicKey(&rsa, &der, pubDerSz));

    ExpectIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature,
        signatureLen, rsa), 1);

    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}


static int test_wolfSSL_RSA_public_decrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA *rsa;
    unsigned char msg[SHA256_DIGEST_LENGTH];
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* pubDer = client_keypub_der_1024;
    size_t pubDerSz = sizeof_client_keypub_der_1024;
    unsigned char decMsg[1024/8];
    const unsigned char encMsg[] = {
        0x45, 0x8e, 0x6e, 0x7a, 0x9c, 0xe1, 0x67, 0x36,
        0x72, 0xfc, 0x9d, 0x05, 0xdf, 0xc2, 0xaf, 0x54,
        0xc5, 0x2f, 0x94, 0xb8, 0xc7, 0x82, 0x40, 0xfa,
        0xa7, 0x8c, 0xb1, 0x89, 0x40, 0xc3, 0x59, 0x5a,
        0x77, 0x08, 0x54, 0x93, 0x43, 0x7f, 0xc4, 0xb7,
        0xc4, 0x78, 0xf1, 0xf8, 0xab, 0xbf, 0xc2, 0x81,
        0x5d, 0x97, 0xea, 0x7a, 0x60, 0x90, 0x51, 0xb7,
        0x47, 0x78, 0x48, 0x1e, 0x88, 0x6b, 0x89, 0xde,
        0xce, 0x41, 0x41, 0xae, 0x49, 0xf6, 0xfd, 0x2d,
        0x2d, 0x9c, 0x70, 0x7d, 0xf9, 0xcf, 0x77, 0x5f,
        0x06, 0xc7, 0x20, 0xe3, 0x57, 0xd4, 0xd8, 0x1a,
        0x96, 0xa2, 0x39, 0xb0, 0x6e, 0x8e, 0x68, 0xf8,
        0x57, 0x7b, 0x26, 0x88, 0x17, 0xc4, 0xb7, 0xf1,
        0x59, 0xfa, 0xb6, 0x95, 0xdd, 0x1e, 0xe8, 0xd8,
        0x4e, 0xbd, 0xcd, 0x41, 0xad, 0xc7, 0xe2, 0x39,
        0xb8, 0x00, 0xca, 0xf5, 0x59, 0xdf, 0xf8, 0x43
    };
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) && \
    defined(WC_RSA_NO_PADDING)
    const unsigned char encMsgNoPad[] = {
        0x0d, 0x41, 0x5a, 0xc7, 0x60, 0xd7, 0xbe, 0xb6,
        0x42, 0xd1, 0x65, 0xb1, 0x7e, 0x59, 0x54, 0xcc,
        0x76, 0x62, 0xd0, 0x2f, 0x4d, 0xe3, 0x23, 0x62,
        0xc8, 0x14, 0xfe, 0x5e, 0xa1, 0xc7, 0x05, 0xee,
        0x9e, 0x28, 0x2e, 0xf5, 0xfd, 0xa4, 0xc0, 0x43,
        0x55, 0xa2, 0x6b, 0x6b, 0x16, 0xa7, 0x63, 0x06,
        0xa7, 0x78, 0x4f, 0xda, 0xae, 0x10, 0x6d, 0xd1,
        0x2e, 0x1d, 0xbb, 0xbc, 0xc4, 0x1d, 0x82, 0xe4,
        0xc6, 0x76, 0x77, 0xa6, 0x0a, 0xef, 0xd2, 0x89,
        0xff, 0x30, 0x85, 0x22, 0xa0, 0x68, 0x88, 0x54,
        0xa3, 0xd1, 0x92, 0xd1, 0x3f, 0x57, 0xe4, 0xc7,
        0x43, 0x5a, 0x8b, 0xb3, 0x86, 0xaf, 0xd5, 0x6d,
        0x07, 0xe1, 0xa0, 0x5f, 0xe1, 0x9a, 0x06, 0xba,
        0x56, 0xd2, 0xb0, 0x73, 0xf5, 0xb3, 0xd0, 0x5f,
        0xc0, 0xbf, 0x22, 0x4c, 0x54, 0x4e, 0x11, 0xe2,
        0xc5, 0xf8, 0x66, 0x39, 0x9d, 0x70, 0x90, 0x31
    };
#endif
#else
    const unsigned char* pubDer = client_keypub_der_2048;
    size_t pubDerSz = sizeof_client_keypub_der_2048;
    unsigned char decMsg[2048/8];
    const unsigned char encMsg[] = {
        0x16, 0x5d, 0xbb, 0x00, 0x38, 0x73, 0x01, 0x34,
        0xca, 0x59, 0xc6, 0x8b, 0x64, 0x70, 0x89, 0xf5,
        0x50, 0x2d, 0x1d, 0x69, 0x1f, 0x07, 0x1e, 0x31,
        0xae, 0x9b, 0xa6, 0x6e, 0xee, 0x80, 0xd9, 0x9e,
        0x59, 0x33, 0x70, 0x30, 0x28, 0x42, 0x7d, 0x24,
        0x36, 0x95, 0x6b, 0xf9, 0x0a, 0x23, 0xcb, 0xce,
        0x66, 0xa5, 0x07, 0x5e, 0x11, 0xa7, 0xdc, 0xfb,
        0xd9, 0xc2, 0x51, 0xf0, 0x05, 0xc9, 0x39, 0xb3,
        0xae, 0xff, 0xfb, 0xe9, 0xb1, 0x9a, 0x54, 0xac,
        0x1d, 0xca, 0x42, 0x1a, 0xfd, 0x7c, 0x97, 0xa0,
        0x60, 0x2b, 0xcd, 0xb6, 0x36, 0x33, 0xfc, 0x44,
        0x69, 0xf7, 0x2e, 0x8c, 0x3b, 0x5f, 0xb4, 0x9f,
        0xa7, 0x02, 0x8f, 0x6d, 0x6b, 0x79, 0x10, 0x32,
        0x7d, 0xf4, 0x5d, 0xa1, 0x63, 0x22, 0x59, 0xc4,
        0x44, 0x8e, 0x44, 0x24, 0x8b, 0x14, 0x9d, 0x2b,
        0xb5, 0xd3, 0xad, 0x9a, 0x87, 0x0d, 0xe7, 0x70,
        0x6d, 0xe9, 0xae, 0xaa, 0x52, 0xbf, 0x1a, 0x9b,
        0xc8, 0x3d, 0x45, 0x7c, 0xd1, 0x90, 0xe3, 0xd9,
        0x57, 0xcf, 0xc3, 0x29, 0x69, 0x05, 0x07, 0x96,
        0x2e, 0x46, 0x74, 0x0a, 0xa7, 0x76, 0x8b, 0xc0,
        0x1c, 0x04, 0x80, 0x08, 0xa0, 0x94, 0x7e, 0xbb,
        0x2d, 0x99, 0xe9, 0xab, 0x18, 0x4d, 0x48, 0x2d,
        0x94, 0x5e, 0x50, 0x21, 0x42, 0xdf, 0xf5, 0x61,
        0x42, 0x7d, 0x86, 0x5d, 0x9e, 0x89, 0xc9, 0x5b,
        0x24, 0xab, 0xa1, 0xd8, 0x20, 0x45, 0xcb, 0x81,
        0xcf, 0xc5, 0x25, 0x7d, 0x11, 0x6e, 0xbd, 0x80,
        0xac, 0xba, 0xdc, 0xef, 0xb9, 0x05, 0x9c, 0xd5,
        0xc2, 0x26, 0x57, 0x69, 0x8b, 0x08, 0x27, 0xc7,
        0xea, 0xbe, 0xaf, 0x52, 0x21, 0x95, 0x9f, 0xa0,
        0x2f, 0x2f, 0x53, 0x7c, 0x2f, 0xa3, 0x0b, 0x79,
        0x39, 0x01, 0xa3, 0x37, 0x46, 0xa8, 0xc4, 0x34,
        0x41, 0x20, 0x7c, 0x3f, 0x70, 0x9a, 0x47, 0xe8
    };
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) && \
    defined(WC_RSA_NO_PADDING)
    const unsigned char encMsgNoPad[] = {
        0x79, 0x69, 0xdc, 0x0d, 0xff, 0x09, 0xeb, 0x91,
        0xbc, 0xda, 0xe4, 0xd3, 0xcd, 0xd5, 0xd3, 0x1c,
        0xb9, 0x66, 0xa8, 0x02, 0xf3, 0x75, 0x40, 0xf1,
        0x38, 0x4a, 0x37, 0x7b, 0x19, 0xc8, 0xcd, 0xea,
        0x79, 0xa8, 0x51, 0x32, 0x00, 0x3f, 0x4c, 0xde,
        0xaa, 0xe5, 0xe2, 0x7c, 0x10, 0xcd, 0x6e, 0x00,
        0xc6, 0xc4, 0x63, 0x98, 0x58, 0x9b, 0x38, 0xca,
        0xf0, 0x5d, 0xc8, 0xf0, 0x57, 0xf6, 0x21, 0x50,
        0x3f, 0x63, 0x05, 0x9f, 0xbf, 0xb6, 0x3b, 0x50,
        0x85, 0x06, 0x34, 0x08, 0x57, 0xb9, 0x44, 0xce,
        0xe4, 0x66, 0xbf, 0x0c, 0xfe, 0x36, 0xa4, 0x5b,
        0xed, 0x2d, 0x7d, 0xed, 0xf1, 0xbd, 0xda, 0x3e,
        0x19, 0x1f, 0x99, 0xc8, 0xe4, 0xc2, 0xbb, 0xb5,
        0x6c, 0x83, 0x22, 0xd1, 0xe7, 0x57, 0xcf, 0x1b,
        0x91, 0x0c, 0xa5, 0x47, 0x06, 0x71, 0x8f, 0x93,
        0xf3, 0xad, 0xdb, 0xe3, 0xf8, 0xa0, 0x0b, 0xcd,
        0x89, 0x4e, 0xa5, 0xb5, 0x03, 0x68, 0x61, 0x89,
        0x0b, 0xe2, 0x03, 0x8b, 0x1f, 0x54, 0xae, 0x0f,
        0xfa, 0xf0, 0xb7, 0x0f, 0x8c, 0x84, 0x35, 0x13,
        0x8d, 0x65, 0x1f, 0x2c, 0xd5, 0xce, 0xc4, 0x6c,
        0x98, 0x67, 0xe4, 0x1a, 0x85, 0x67, 0x69, 0x17,
        0x17, 0x5a, 0x5d, 0xfd, 0x23, 0xdd, 0x03, 0x3f,
        0x6d, 0x7a, 0xb6, 0x8b, 0x99, 0xc0, 0xb6, 0x70,
        0x86, 0xac, 0xf6, 0x02, 0xc2, 0x28, 0x42, 0xed,
        0x06, 0xcf, 0xca, 0x3d, 0x07, 0x16, 0xf0, 0x0e,
        0x04, 0x55, 0x1e, 0x59, 0x3f, 0x32, 0xc7, 0x12,
        0xc5, 0x0d, 0x9d, 0x64, 0x7d, 0x2e, 0xd4, 0xbc,
        0x8c, 0x24, 0x42, 0x94, 0x2b, 0xf6, 0x11, 0x7f,
        0xb1, 0x1c, 0x09, 0x12, 0x6f, 0x5e, 0x2e, 0x7a,
        0xc6, 0x01, 0xe0, 0x98, 0x31, 0xb7, 0x13, 0x03,
        0xce, 0x29, 0xe1, 0xef, 0x9d, 0xdf, 0x9b, 0xa5,
        0xba, 0x0b, 0xad, 0xf2, 0xeb, 0x2f, 0xf9, 0xd1
    };
#endif
#endif
    const unsigned char* der;
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) && \
    defined(WC_RSA_NO_PADDING)
    int i;
#endif

    XMEMSET(msg, 0, sizeof(msg));

    der = pubDer;
    rsa = NULL;
    ExpectNotNull(d2i_RSAPublicKey(&rsa, &der, pubDerSz));

    ExpectIntEQ(RSA_public_decrypt(0, NULL, NULL, NULL, 0), -1);
    ExpectIntEQ(RSA_public_decrypt(-1, encMsg, decMsg, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_public_decrypt(sizeof(encMsg), NULL, decMsg, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_public_decrypt(sizeof(encMsg), encMsg, NULL, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_public_decrypt(sizeof(encMsg), encMsg, decMsg, NULL,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_public_decrypt(sizeof(encMsg), encMsg, decMsg, rsa,
        RSA_PKCS1_PSS_PADDING), -1);

    ExpectIntEQ(RSA_public_decrypt(sizeof(encMsg), encMsg, decMsg, rsa,
        RSA_PKCS1_PADDING), 32);
    ExpectIntEQ(XMEMCMP(decMsg, msg, sizeof(msg)), 0);

#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
    (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) && \
    defined(WC_RSA_NO_PADDING)
    ExpectIntEQ(RSA_public_decrypt(sizeof(encMsgNoPad), encMsgNoPad, decMsg,
        rsa, RSA_NO_PADDING), sizeof(decMsg));
    /* Zeros before actual data. */
    for (i = 0; i < (int)(sizeof(decMsg) - sizeof(msg)); i += sizeof(msg)) {
        ExpectIntEQ(XMEMCMP(decMsg + i, msg, sizeof(msg)), 0);
    }
    /* Check actual data. */
    XMEMSET(msg, 0x01, sizeof(msg));
    ExpectIntEQ(XMEMCMP(decMsg + i, msg, sizeof(msg)), 0);
#endif

    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_private_encrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA *rsa;
    unsigned char msg[SHA256_DIGEST_LENGTH];
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* privDer = client_key_der_1024;
    size_t privDerSz = sizeof_client_key_der_1024;
    unsigned char encMsg[1024/8];
    const unsigned char expEncMsg[] = {
        0x45, 0x8e, 0x6e, 0x7a, 0x9c, 0xe1, 0x67, 0x36,
        0x72, 0xfc, 0x9d, 0x05, 0xdf, 0xc2, 0xaf, 0x54,
        0xc5, 0x2f, 0x94, 0xb8, 0xc7, 0x82, 0x40, 0xfa,
        0xa7, 0x8c, 0xb1, 0x89, 0x40, 0xc3, 0x59, 0x5a,
        0x77, 0x08, 0x54, 0x93, 0x43, 0x7f, 0xc4, 0xb7,
        0xc4, 0x78, 0xf1, 0xf8, 0xab, 0xbf, 0xc2, 0x81,
        0x5d, 0x97, 0xea, 0x7a, 0x60, 0x90, 0x51, 0xb7,
        0x47, 0x78, 0x48, 0x1e, 0x88, 0x6b, 0x89, 0xde,
        0xce, 0x41, 0x41, 0xae, 0x49, 0xf6, 0xfd, 0x2d,
        0x2d, 0x9c, 0x70, 0x7d, 0xf9, 0xcf, 0x77, 0x5f,
        0x06, 0xc7, 0x20, 0xe3, 0x57, 0xd4, 0xd8, 0x1a,
        0x96, 0xa2, 0x39, 0xb0, 0x6e, 0x8e, 0x68, 0xf8,
        0x57, 0x7b, 0x26, 0x88, 0x17, 0xc4, 0xb7, 0xf1,
        0x59, 0xfa, 0xb6, 0x95, 0xdd, 0x1e, 0xe8, 0xd8,
        0x4e, 0xbd, 0xcd, 0x41, 0xad, 0xc7, 0xe2, 0x39,
        0xb8, 0x00, 0xca, 0xf5, 0x59, 0xdf, 0xf8, 0x43
    };
#ifdef WC_RSA_NO_PADDING
    const unsigned char expEncMsgNoPad[] = {
        0x0d, 0x41, 0x5a, 0xc7, 0x60, 0xd7, 0xbe, 0xb6,
        0x42, 0xd1, 0x65, 0xb1, 0x7e, 0x59, 0x54, 0xcc,
        0x76, 0x62, 0xd0, 0x2f, 0x4d, 0xe3, 0x23, 0x62,
        0xc8, 0x14, 0xfe, 0x5e, 0xa1, 0xc7, 0x05, 0xee,
        0x9e, 0x28, 0x2e, 0xf5, 0xfd, 0xa4, 0xc0, 0x43,
        0x55, 0xa2, 0x6b, 0x6b, 0x16, 0xa7, 0x63, 0x06,
        0xa7, 0x78, 0x4f, 0xda, 0xae, 0x10, 0x6d, 0xd1,
        0x2e, 0x1d, 0xbb, 0xbc, 0xc4, 0x1d, 0x82, 0xe4,
        0xc6, 0x76, 0x77, 0xa6, 0x0a, 0xef, 0xd2, 0x89,
        0xff, 0x30, 0x85, 0x22, 0xa0, 0x68, 0x88, 0x54,
        0xa3, 0xd1, 0x92, 0xd1, 0x3f, 0x57, 0xe4, 0xc7,
        0x43, 0x5a, 0x8b, 0xb3, 0x86, 0xaf, 0xd5, 0x6d,
        0x07, 0xe1, 0xa0, 0x5f, 0xe1, 0x9a, 0x06, 0xba,
        0x56, 0xd2, 0xb0, 0x73, 0xf5, 0xb3, 0xd0, 0x5f,
        0xc0, 0xbf, 0x22, 0x4c, 0x54, 0x4e, 0x11, 0xe2,
        0xc5, 0xf8, 0x66, 0x39, 0x9d, 0x70, 0x90, 0x31
    };
#endif
#else
    const unsigned char* privDer = client_key_der_2048;
    size_t privDerSz = sizeof_client_key_der_2048;
    unsigned char encMsg[2048/8];
    const unsigned char expEncMsg[] = {
        0x16, 0x5d, 0xbb, 0x00, 0x38, 0x73, 0x01, 0x34,
        0xca, 0x59, 0xc6, 0x8b, 0x64, 0x70, 0x89, 0xf5,
        0x50, 0x2d, 0x1d, 0x69, 0x1f, 0x07, 0x1e, 0x31,
        0xae, 0x9b, 0xa6, 0x6e, 0xee, 0x80, 0xd9, 0x9e,
        0x59, 0x33, 0x70, 0x30, 0x28, 0x42, 0x7d, 0x24,
        0x36, 0x95, 0x6b, 0xf9, 0x0a, 0x23, 0xcb, 0xce,
        0x66, 0xa5, 0x07, 0x5e, 0x11, 0xa7, 0xdc, 0xfb,
        0xd9, 0xc2, 0x51, 0xf0, 0x05, 0xc9, 0x39, 0xb3,
        0xae, 0xff, 0xfb, 0xe9, 0xb1, 0x9a, 0x54, 0xac,
        0x1d, 0xca, 0x42, 0x1a, 0xfd, 0x7c, 0x97, 0xa0,
        0x60, 0x2b, 0xcd, 0xb6, 0x36, 0x33, 0xfc, 0x44,
        0x69, 0xf7, 0x2e, 0x8c, 0x3b, 0x5f, 0xb4, 0x9f,
        0xa7, 0x02, 0x8f, 0x6d, 0x6b, 0x79, 0x10, 0x32,
        0x7d, 0xf4, 0x5d, 0xa1, 0x63, 0x22, 0x59, 0xc4,
        0x44, 0x8e, 0x44, 0x24, 0x8b, 0x14, 0x9d, 0x2b,
        0xb5, 0xd3, 0xad, 0x9a, 0x87, 0x0d, 0xe7, 0x70,
        0x6d, 0xe9, 0xae, 0xaa, 0x52, 0xbf, 0x1a, 0x9b,
        0xc8, 0x3d, 0x45, 0x7c, 0xd1, 0x90, 0xe3, 0xd9,
        0x57, 0xcf, 0xc3, 0x29, 0x69, 0x05, 0x07, 0x96,
        0x2e, 0x46, 0x74, 0x0a, 0xa7, 0x76, 0x8b, 0xc0,
        0x1c, 0x04, 0x80, 0x08, 0xa0, 0x94, 0x7e, 0xbb,
        0x2d, 0x99, 0xe9, 0xab, 0x18, 0x4d, 0x48, 0x2d,
        0x94, 0x5e, 0x50, 0x21, 0x42, 0xdf, 0xf5, 0x61,
        0x42, 0x7d, 0x86, 0x5d, 0x9e, 0x89, 0xc9, 0x5b,
        0x24, 0xab, 0xa1, 0xd8, 0x20, 0x45, 0xcb, 0x81,
        0xcf, 0xc5, 0x25, 0x7d, 0x11, 0x6e, 0xbd, 0x80,
        0xac, 0xba, 0xdc, 0xef, 0xb9, 0x05, 0x9c, 0xd5,
        0xc2, 0x26, 0x57, 0x69, 0x8b, 0x08, 0x27, 0xc7,
        0xea, 0xbe, 0xaf, 0x52, 0x21, 0x95, 0x9f, 0xa0,
        0x2f, 0x2f, 0x53, 0x7c, 0x2f, 0xa3, 0x0b, 0x79,
        0x39, 0x01, 0xa3, 0x37, 0x46, 0xa8, 0xc4, 0x34,
        0x41, 0x20, 0x7c, 0x3f, 0x70, 0x9a, 0x47, 0xe8
    };
#ifdef WC_RSA_NO_PADDING
    const unsigned char expEncMsgNoPad[] = {
        0x79, 0x69, 0xdc, 0x0d, 0xff, 0x09, 0xeb, 0x91,
        0xbc, 0xda, 0xe4, 0xd3, 0xcd, 0xd5, 0xd3, 0x1c,
        0xb9, 0x66, 0xa8, 0x02, 0xf3, 0x75, 0x40, 0xf1,
        0x38, 0x4a, 0x37, 0x7b, 0x19, 0xc8, 0xcd, 0xea,
        0x79, 0xa8, 0x51, 0x32, 0x00, 0x3f, 0x4c, 0xde,
        0xaa, 0xe5, 0xe2, 0x7c, 0x10, 0xcd, 0x6e, 0x00,
        0xc6, 0xc4, 0x63, 0x98, 0x58, 0x9b, 0x38, 0xca,
        0xf0, 0x5d, 0xc8, 0xf0, 0x57, 0xf6, 0x21, 0x50,
        0x3f, 0x63, 0x05, 0x9f, 0xbf, 0xb6, 0x3b, 0x50,
        0x85, 0x06, 0x34, 0x08, 0x57, 0xb9, 0x44, 0xce,
        0xe4, 0x66, 0xbf, 0x0c, 0xfe, 0x36, 0xa4, 0x5b,
        0xed, 0x2d, 0x7d, 0xed, 0xf1, 0xbd, 0xda, 0x3e,
        0x19, 0x1f, 0x99, 0xc8, 0xe4, 0xc2, 0xbb, 0xb5,
        0x6c, 0x83, 0x22, 0xd1, 0xe7, 0x57, 0xcf, 0x1b,
        0x91, 0x0c, 0xa5, 0x47, 0x06, 0x71, 0x8f, 0x93,
        0xf3, 0xad, 0xdb, 0xe3, 0xf8, 0xa0, 0x0b, 0xcd,
        0x89, 0x4e, 0xa5, 0xb5, 0x03, 0x68, 0x61, 0x89,
        0x0b, 0xe2, 0x03, 0x8b, 0x1f, 0x54, 0xae, 0x0f,
        0xfa, 0xf0, 0xb7, 0x0f, 0x8c, 0x84, 0x35, 0x13,
        0x8d, 0x65, 0x1f, 0x2c, 0xd5, 0xce, 0xc4, 0x6c,
        0x98, 0x67, 0xe4, 0x1a, 0x85, 0x67, 0x69, 0x17,
        0x17, 0x5a, 0x5d, 0xfd, 0x23, 0xdd, 0x03, 0x3f,
        0x6d, 0x7a, 0xb6, 0x8b, 0x99, 0xc0, 0xb6, 0x70,
        0x86, 0xac, 0xf6, 0x02, 0xc2, 0x28, 0x42, 0xed,
        0x06, 0xcf, 0xca, 0x3d, 0x07, 0x16, 0xf0, 0x0e,
        0x04, 0x55, 0x1e, 0x59, 0x3f, 0x32, 0xc7, 0x12,
        0xc5, 0x0d, 0x9d, 0x64, 0x7d, 0x2e, 0xd4, 0xbc,
        0x8c, 0x24, 0x42, 0x94, 0x2b, 0xf6, 0x11, 0x7f,
        0xb1, 0x1c, 0x09, 0x12, 0x6f, 0x5e, 0x2e, 0x7a,
        0xc6, 0x01, 0xe0, 0x98, 0x31, 0xb7, 0x13, 0x03,
        0xce, 0x29, 0xe1, 0xef, 0x9d, 0xdf, 0x9b, 0xa5,
        0xba, 0x0b, 0xad, 0xf2, 0xeb, 0x2f, 0xf9, 0xd1
    };
#endif
#endif
    const unsigned char* der;

    XMEMSET(msg, 0x00, sizeof(msg));

    der = privDer;
    rsa = NULL;
    ExpectNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz));

    ExpectIntEQ(RSA_private_encrypt(0, NULL, NULL, NULL, 0), -1);
    ExpectIntEQ(RSA_private_encrypt(0, msg, encMsg, rsa, RSA_PKCS1_PADDING),
        -1);
    ExpectIntEQ(RSA_private_encrypt(sizeof(msg), NULL, encMsg, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_private_encrypt(sizeof(msg), msg, NULL, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_private_encrypt(sizeof(msg), msg, encMsg, NULL,
         RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_private_encrypt(sizeof(msg), msg, encMsg, rsa,
         RSA_PKCS1_PSS_PADDING), -1);

    ExpectIntEQ(RSA_private_encrypt(sizeof(msg), msg, encMsg, rsa,
         RSA_PKCS1_PADDING), sizeof(encMsg));
    ExpectIntEQ(XMEMCMP(encMsg, expEncMsg, sizeof(expEncMsg)), 0);

#ifdef WC_RSA_NO_PADDING
    /* Non-zero message. */
    XMEMSET(msg, 0x01, sizeof(msg));
    ExpectIntEQ(RSA_private_encrypt(sizeof(msg), msg, encMsg, rsa,
         RSA_NO_PADDING), sizeof(encMsg));
    ExpectIntEQ(XMEMCMP(encMsg, expEncMsgNoPad, sizeof(expEncMsgNoPad)), 0);
#endif

    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_public_encrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA* rsa = NULL;
    const unsigned char msg[2048/8] = { 0 };
    unsigned char encMsg[2048/8];

    ExpectNotNull(rsa = RSA_new());

    ExpectIntEQ(RSA_public_encrypt(-1, msg, encMsg, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_public_encrypt(sizeof(msg), NULL, encMsg, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_public_encrypt(sizeof(msg), msg, NULL, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_public_encrypt(sizeof(msg), msg, encMsg, NULL,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_public_encrypt(sizeof(msg), msg, encMsg, rsa,
        RSA_PKCS1_PSS_PADDING), -1);
    /* Empty RSA key. */
    ExpectIntEQ(RSA_public_encrypt(sizeof(msg), msg, encMsg, rsa,
        RSA_PKCS1_PADDING), -1);

    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_private_decrypt(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA* rsa = NULL;
    unsigned char msg[2048/8];
    const unsigned char encMsg[2048/8] = { 0 };

    ExpectNotNull(rsa = RSA_new());

    ExpectIntEQ(RSA_private_decrypt(-1, encMsg, msg, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_private_decrypt(sizeof(encMsg), NULL, msg, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_private_decrypt(sizeof(encMsg), encMsg, NULL, rsa,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_private_decrypt(sizeof(encMsg), encMsg, msg, NULL,
        RSA_PKCS1_PADDING), -1);
    ExpectIntEQ(RSA_private_decrypt(sizeof(encMsg), encMsg, msg, rsa,
        RSA_PKCS1_PSS_PADDING), -1);
    /* Empty RSA key. */
    ExpectIntEQ(RSA_private_decrypt(sizeof(encMsg), encMsg, msg, rsa,
        RSA_PKCS1_PADDING), -1);

    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_GenAdd(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA *rsa;
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* privDer = client_key_der_1024;
    size_t privDerSz = sizeof_client_key_der_1024;
    const unsigned char* pubDer = client_keypub_der_1024;
    size_t pubDerSz = sizeof_client_keypub_der_1024;
#else
    const unsigned char* privDer = client_key_der_2048;
    size_t privDerSz = sizeof_client_key_der_2048;
    const unsigned char* pubDer = client_keypub_der_2048;
    size_t pubDerSz = sizeof_client_keypub_der_2048;
#endif
    const unsigned char* der;

    der = privDer;
    rsa = NULL;
    ExpectNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz));

    ExpectIntEQ(wolfSSL_RSA_GenAdd(NULL), -1);
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
    !defined(RSA_LOW_MEM)
    ExpectIntEQ(wolfSSL_RSA_GenAdd(rsa), 1);
#else
    /* dmp1 and dmq1 are not set (allocated) in this config */
    ExpectIntEQ(wolfSSL_RSA_GenAdd(rsa), -1);
#endif

    RSA_free(rsa);
    der = pubDer;
    rsa = NULL;
    ExpectNotNull(d2i_RSAPublicKey(&rsa, &der, pubDerSz));
    /* Need private values. */
    ExpectIntEQ(wolfSSL_RSA_GenAdd(rsa), -1);

    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_blinding_on(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_WOLFSSL_STUB)
    RSA *rsa;
    WOLFSSL_BN_CTX *bnCtx = NULL;
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* privDer = client_key_der_1024;
    size_t privDerSz = sizeof_client_key_der_1024;
#else
    const unsigned char* privDer = client_key_der_2048;
    size_t privDerSz = sizeof_client_key_der_2048;
#endif
    const unsigned char* der;

    der = privDer;
    rsa = NULL;
    ExpectNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz));
    ExpectNotNull(bnCtx = wolfSSL_BN_CTX_new());

    /* Does nothing so all parameters are valid. */
    ExpectIntEQ(wolfSSL_RSA_blinding_on(NULL, NULL), 1);
    ExpectIntEQ(wolfSSL_RSA_blinding_on(rsa, NULL), 1);
    ExpectIntEQ(wolfSSL_RSA_blinding_on(NULL, bnCtx), 1);
    ExpectIntEQ(wolfSSL_RSA_blinding_on(rsa, bnCtx), 1);

    wolfSSL_BN_CTX_free(bnCtx);
    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_ex_data(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(OPENSSL_EXTRA)
    RSA* rsa = NULL;
    unsigned char data[1];

    ExpectNotNull(rsa = RSA_new());

    ExpectNull(wolfSSL_RSA_get_ex_data(NULL, 0));
    ExpectNull(wolfSSL_RSA_get_ex_data(rsa, 0));
#ifdef MAX_EX_DATA
    ExpectNull(wolfSSL_RSA_get_ex_data(rsa, MAX_EX_DATA));
    ExpectIntEQ(wolfSSL_RSA_set_ex_data(rsa, MAX_EX_DATA, data), 0);
#endif
    ExpectIntEQ(wolfSSL_RSA_set_ex_data(NULL, 0, NULL), 0);
    ExpectIntEQ(wolfSSL_RSA_set_ex_data(NULL, 0, data), 0);

#ifdef HAVE_EX_DATA
    ExpectIntEQ(wolfSSL_RSA_set_ex_data(rsa, 0, NULL), 1);
    ExpectIntEQ(wolfSSL_RSA_set_ex_data(rsa, 0, data), 1);
    ExpectPtrEq(wolfSSL_RSA_get_ex_data(rsa, 0), data);
#else
    ExpectIntEQ(wolfSSL_RSA_set_ex_data(rsa, 0, NULL), 0);
    ExpectIntEQ(wolfSSL_RSA_set_ex_data(rsa, 0, data), 0);
    ExpectNull(wolfSSL_RSA_get_ex_data(rsa, 0));
#endif

    RSA_free(rsa);
#endif /* !NO_RSA && OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_RSA_LoadDer(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || \
    defined(OPENSSL_EXTRA_X509_SMALL))
    RSA *rsa = NULL;
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* privDer = client_key_der_1024;
    size_t privDerSz = sizeof_client_key_der_1024;
#else
    const unsigned char* privDer = client_key_der_2048;
    size_t privDerSz = sizeof_client_key_der_2048;
#endif

    ExpectNotNull(rsa = RSA_new());

    ExpectIntEQ(wolfSSL_RSA_LoadDer(NULL, privDer, (int)privDerSz), -1);
    ExpectIntEQ(wolfSSL_RSA_LoadDer(rsa, NULL, (int)privDerSz), -1);
    ExpectIntEQ(wolfSSL_RSA_LoadDer(rsa, privDer, 0), -1);

    ExpectIntEQ(wolfSSL_RSA_LoadDer(rsa, privDer, (int)privDerSz), 1);

    RSA_free(rsa);
#endif /* !NO_RSA && OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

/* Local API. */
static int test_wolfSSL_RSA_To_Der(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_TEST_STATIC_BUILD
#if defined(WOLFSSL_KEY_GEN) && defined(OPENSSL_EXTRA) && !defined(NO_RSA)
    RSA* rsa;
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* privDer = client_key_der_1024;
    size_t privDerSz = sizeof_client_key_der_1024;
    const unsigned char* pubDer = client_keypub_der_1024;
    size_t pubDerSz = sizeof_client_keypub_der_1024;
    unsigned char out[sizeof(client_key_der_1024)];
#else
    const unsigned char* privDer = client_key_der_2048;
    size_t privDerSz = sizeof_client_key_der_2048;
    const unsigned char* pubDer = client_keypub_der_2048;
    size_t pubDerSz = sizeof_client_keypub_der_2048;
    unsigned char out[sizeof(client_key_der_2048)];
#endif
    const unsigned char* der;
    unsigned char* outDer = NULL;

    der = privDer;
    rsa = NULL;
    ExpectNotNull(wolfSSL_d2i_RSAPrivateKey(&rsa, &der, privDerSz));

    ExpectIntEQ(wolfSSL_RSA_To_Der(NULL, &outDer, 0, HEAP_HINT), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 2, HEAP_HINT), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_RSA_To_Der(rsa, NULL, 0, HEAP_HINT), privDerSz);
    outDer = out;
    ExpectIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 0, HEAP_HINT), privDerSz);
    ExpectIntEQ(XMEMCMP(out, privDer, privDerSz), 0);
    outDer = NULL;
    ExpectIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 0, HEAP_HINT), privDerSz);
    ExpectNotNull(outDer);
    ExpectIntEQ(XMEMCMP(outDer, privDer, privDerSz), 0);
    XFREE(outDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);

    ExpectIntEQ(wolfSSL_RSA_To_Der(rsa, NULL, 1, HEAP_HINT), pubDerSz);
    outDer = out;
    ExpectIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 1, HEAP_HINT), pubDerSz);
    ExpectIntEQ(XMEMCMP(out, pubDer, pubDerSz), 0);

    RSA_free(rsa);

    ExpectNotNull(rsa = RSA_new());
    ExpectIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 0, HEAP_HINT), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 1, HEAP_HINT), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    RSA_free(rsa);

    der = pubDer;
    rsa = NULL;
    ExpectNotNull(wolfSSL_d2i_RSAPublicKey(&rsa, &der, pubDerSz));
    ExpectIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 0, HEAP_HINT), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    RSA_free(rsa);
#endif
#endif
    return EXPECT_RESULT();
}

/* wolfSSL_PEM_read_RSAPublicKey is a stub function. */
static int test_wolfSSL_PEM_read_RSAPublicKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
    XFILE file = XBADFILE;
    const char* fname = "./certs/server-keyPub.pem";
    RSA *rsa = NULL;

    ExpectNull(wolfSSL_PEM_read_RSAPublicKey(XBADFILE, NULL, NULL, NULL));

    ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
    ExpectNotNull(rsa = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL));
    ExpectIntEQ(RSA_size(rsa), 256);
    RSA_free(rsa);
    if (file != XBADFILE)
        XFCLOSE(file);
#endif
    return EXPECT_RESULT();
}

/* wolfSSL_PEM_read_RSAPublicKey is a stub function. */
static int test_wolfSSL_PEM_write_RSA_PUBKEY(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
    defined(WOLFSSL_KEY_GEN)
    RSA* rsa = NULL;

    ExpectIntEQ(wolfSSL_PEM_write_RSA_PUBKEY(XBADFILE, NULL), 0);
    ExpectIntEQ(wolfSSL_PEM_write_RSA_PUBKEY(stderr, NULL), 0);
    /* Valid but stub so returns 0. */
    ExpectIntEQ(wolfSSL_PEM_write_RSA_PUBKEY(stderr, rsa), 0);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_write_RSAPrivateKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \
    (defined(WOLFSSL_PEM_TO_DER) || \
    defined(WOLFSSL_DER_TO_PEM)) && !defined(NO_FILESYSTEM)
    RSA* rsa = NULL;
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* privDer = client_key_der_1024;
    size_t privDerSz = sizeof_client_key_der_1024;
#else
    const unsigned char* privDer = client_key_der_2048;
    size_t privDerSz = sizeof_client_key_der_2048;
#endif
    const unsigned char* der;
#ifndef NO_AES
    unsigned char passwd[] = "password";
#endif

    ExpectNotNull(rsa = RSA_new());
    ExpectIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stderr, rsa, NULL, NULL, 0,
        NULL, NULL), 0);
    RSA_free(rsa);

    der = privDer;
    rsa = NULL;
    ExpectNotNull(wolfSSL_d2i_RSAPrivateKey(&rsa, &der, privDerSz));

    ExpectIntEQ(wolfSSL_PEM_write_RSAPrivateKey(XBADFILE, rsa, NULL, NULL, 0,
        NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stderr, NULL, NULL, NULL, 0,
        NULL, NULL), 0);

    ExpectIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stderr, rsa, NULL, NULL, 0,
        NULL, NULL), 1);
#ifndef NO_AES
    ExpectIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stderr, rsa, EVP_aes_128_cbc(),
        NULL, 0, NULL, NULL), 1);
    ExpectIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stderr, rsa, EVP_aes_128_cbc(),
        passwd, sizeof(passwd) - 1, NULL, NULL), 1);
#endif
    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_write_mem_RSAPrivateKey(void)
{
    EXPECT_DECLS;
#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \
    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
    RSA* rsa = NULL;
#ifdef USE_CERT_BUFFERS_1024
    const unsigned char* privDer = client_key_der_1024;
    size_t privDerSz = sizeof_client_key_der_1024;
#else
    const unsigned char* privDer = client_key_der_2048;
    size_t privDerSz = sizeof_client_key_der_2048;
#endif
    const unsigned char* der;
#ifndef NO_AES
    unsigned char passwd[] = "password";
#endif
    unsigned char* pem = NULL;
    int plen;

    ExpectNotNull(rsa = RSA_new());
    ExpectIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, NULL, NULL, 0, &pem,
        &plen), 0);
    RSA_free(rsa);

    der = privDer;
    rsa = NULL;
    ExpectNotNull(wolfSSL_d2i_RSAPrivateKey(&rsa, &der, privDerSz));

    ExpectIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(NULL, NULL, NULL, 0, &pem,
        &plen), 0);
    ExpectIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, NULL, NULL, 0, NULL,
        &plen), 0);
    ExpectIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, NULL, NULL, 0, &pem,
        NULL), 0);

    ExpectIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, NULL, NULL, 0, &pem,
        &plen), 1);
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
    pem = NULL;
#ifndef NO_AES
    ExpectIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, EVP_aes_128_cbc(),
        NULL, 0, &pem, &plen), 1);
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
    pem = NULL;
    ExpectIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, EVP_aes_128_cbc(),
        passwd, sizeof(passwd) - 1, &pem, &plen), 1);
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
#endif

    RSA_free(rsa);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DH(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DH)
    DH *dh = NULL;
    BIGNUM* p;
    BIGNUM* q;
    BIGNUM* g;
    BIGNUM* pub = NULL;
    BIGNUM* priv = NULL;
#if defined(OPENSSL_ALL)
#if !defined(HAVE_FIPS) || \
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
    FILE* f = NULL;
    unsigned char buf[268];
    const unsigned char* pt = buf;
    long len = 0;

    dh = NULL;
    XMEMSET(buf, 0, sizeof(buf));
    /* Test 2048 bit parameters */
    ExpectTrue((f = XFOPEN("./certs/dh2048.der", "rb")) != XBADFILE);
    ExpectTrue((len = (long)XFREAD(buf, 1, sizeof(buf), f)) > 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectNotNull(dh = d2i_DHparams(NULL, &pt, len));
    ExpectNotNull(dh->p);
    ExpectNotNull(dh->g);
    ExpectTrue(pt == buf);
    ExpectIntEQ(DH_generate_key(dh), 1);

    /* first, test for expected successful key agreement. */
    if (EXPECT_SUCCESS()) {
        DH *dh2 = NULL;
        unsigned char buf2[268];
        int sz1 = 0, sz2 = 0;

        ExpectNotNull(dh2 = d2i_DHparams(NULL, &pt, len));
        ExpectIntEQ(DH_generate_key(dh2), 1);

        ExpectIntGT(sz1=DH_compute_key(buf, dh2->pub_key, dh), 0);
        ExpectIntGT(sz2=DH_compute_key(buf2, dh->pub_key, dh2), 0);
        ExpectIntEQ(sz1, sz2);
        ExpectIntEQ(XMEMCMP(buf, buf2, (size_t)sz1), 0);

        ExpectIntNE(sz1 = DH_size(dh), 0);
        ExpectIntEQ(DH_compute_key_padded(buf, dh2->pub_key, dh), sz1);
        ExpectIntEQ(DH_compute_key_padded(buf2, dh->pub_key, dh2), sz1);
        ExpectIntEQ(XMEMCMP(buf, buf2, (size_t)sz1), 0);

        if (dh2 != NULL)
            DH_free(dh2);
    }

    ExpectIntEQ(DH_generate_key(dh), 1);
    ExpectIntEQ(DH_compute_key(NULL, NULL, NULL), -1);
    ExpectNotNull(pub = BN_new());
    ExpectIntEQ(BN_set_word(pub, 1), 1);
    ExpectIntEQ(DH_compute_key(buf, NULL, NULL), -1);
    ExpectIntEQ(DH_compute_key(NULL, pub, NULL), -1);
    ExpectIntEQ(DH_compute_key(NULL, NULL, dh), -1);
    ExpectIntEQ(DH_compute_key(buf, pub, NULL), -1);
    ExpectIntEQ(DH_compute_key(buf, NULL, dh), -1);
    ExpectIntEQ(DH_compute_key(NULL, pub, dh), -1);
    ExpectIntEQ(DH_compute_key(buf, pub, dh), -1);
    BN_free(pub);
    pub = NULL;

    DH_get0_pqg(dh, (const BIGNUM**)&p,
                    (const BIGNUM**)&q,
                    (const BIGNUM**)&g);
    ExpectPtrEq(p, dh->p);
    ExpectPtrEq(q, dh->q);
    ExpectPtrEq(g, dh->g);
    DH_get0_key(NULL, (const BIGNUM**)&pub, (const BIGNUM**)&priv);
    DH_get0_key(dh, (const BIGNUM**)&pub, (const BIGNUM**)&priv);
    ExpectPtrEq(pub, dh->pub_key);
    ExpectPtrEq(priv, dh->priv_key);
    DH_get0_key(dh, (const BIGNUM**)&pub, NULL);
    ExpectPtrEq(pub, dh->pub_key);
    DH_get0_key(dh, NULL, (const BIGNUM**)&priv);
    ExpectPtrEq(priv, dh->priv_key);
    pub = NULL;
    priv = NULL;
    ExpectNotNull(pub = BN_new());
    ExpectNotNull(priv = BN_new());
    ExpectIntEQ(DH_set0_key(NULL, pub, priv), 0);
    ExpectIntEQ(DH_set0_key(dh, pub, priv), 1);
    if (EXPECT_FAIL()) {
        BN_free(pub);
        BN_free(priv);
    }
    pub = NULL;
    priv = NULL;
    ExpectNotNull(pub = BN_new());
    ExpectIntEQ(DH_set0_key(dh, pub, NULL), 1);
    if (EXPECT_FAIL()) {
        BN_free(pub);
    }
    ExpectNotNull(priv = BN_new());
    ExpectIntEQ(DH_set0_key(dh, NULL, priv), 1);
    if (EXPECT_FAIL()) {
        BN_free(priv);
    }
    ExpectPtrEq(pub, dh->pub_key);
    ExpectPtrEq(priv, dh->priv_key);
    pub = NULL;
    priv = NULL;

    DH_free(dh);
    dh = NULL;

    ExpectNotNull(dh = DH_new());
    p = NULL;
    ExpectNotNull(p = BN_new());
    ExpectIntEQ(BN_set_word(p, 1), 1);
    ExpectIntEQ(DH_compute_key(buf, p, dh), -1);
    ExpectNotNull(pub = BN_new());
    ExpectNotNull(priv = BN_new());
    ExpectIntEQ(DH_set0_key(dh, pub, priv), 1);
    if (EXPECT_FAIL()) {
        BN_free(pub);
        BN_free(priv);
    }
    pub = NULL;
    priv = NULL;
    ExpectIntEQ(DH_compute_key(buf, p, dh), -1);
    BN_free(p);
    p = NULL;
    DH_free(dh);
    dh = NULL;

#ifdef WOLFSSL_KEY_GEN
    ExpectNotNull(dh = DH_generate_parameters(2048, 2, NULL, NULL));
    ExpectIntEQ(wolfSSL_DH_generate_parameters_ex(NULL, 2048, 2, NULL), 0);
    DH_free(dh);
    dh = NULL;
#endif
#endif /* !HAVE_FIPS || (HAVE_FIPS_VERSION && HAVE_FIPS_VERSION > 2) */
#endif /* OPENSSL_ALL */

    (void)dh;
    (void)p;
    (void)q;
    (void)g;
    (void)pub;
    (void)priv;

    ExpectNotNull(dh = wolfSSL_DH_new());

    /* invalid parameters test */
    DH_get0_pqg(NULL, (const BIGNUM**)&p,
                      (const BIGNUM**)&q,
                      (const BIGNUM**)&g);

    DH_get0_pqg(dh, NULL,
                    (const BIGNUM**)&q,
                    (const BIGNUM**)&g);

    DH_get0_pqg(dh, NULL, NULL, (const BIGNUM**)&g);

    DH_get0_pqg(dh, NULL, NULL, NULL);

    DH_get0_pqg(dh, (const BIGNUM**)&p,
                    (const BIGNUM**)&q,
                    (const BIGNUM**)&g);

    ExpectPtrEq(p, NULL);
    ExpectPtrEq(q, NULL);
    ExpectPtrEq(g, NULL);
    DH_free(dh);
    dh = NULL;

#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && !defined(WOLFSSL_DH_EXTRA)) \
 || (defined(HAVE_FIPS_VERSION) && FIPS_VERSION_GT(2,0))
#if defined(OPENSSL_ALL) || \
    defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
    dh = wolfSSL_DH_new();
    ExpectNotNull(dh);
    p = wolfSSL_BN_new();
    ExpectNotNull(p);
    ExpectIntEQ(BN_set_word(p, 11), 1);
    g = wolfSSL_BN_new();
    ExpectNotNull(g);
    ExpectIntEQ(BN_set_word(g, 2), 1);
    q = wolfSSL_BN_new();
    ExpectNotNull(q);
    ExpectIntEQ(BN_set_word(q, 5), 1);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(NULL, NULL, NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, NULL, NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(NULL, p, NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(NULL, NULL, q, NULL), 0);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(NULL, NULL, NULL, g), 0);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(NULL, p, q, g), 0);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, NULL, q, g), 0);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, p, q, NULL), 0);
    /* Don't need q. */
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, p, NULL, g), 1);
    if (EXPECT_FAIL()) {
        BN_free(p);
        BN_free(g);
    }
    p = NULL;
    g = NULL;
    /* Setting again will free the p and g. */
    wolfSSL_BN_free(q);
    q = NULL;
    DH_free(dh);
    dh = NULL;

    dh = wolfSSL_DH_new();
    ExpectNotNull(dh);

    p = wolfSSL_BN_new();
    ExpectNotNull(p);
    ExpectIntEQ(BN_set_word(p, 11), 1);
    g = wolfSSL_BN_new();
    ExpectNotNull(g);
    ExpectIntEQ(BN_set_word(g, 2), 1);
    q = wolfSSL_BN_new();
    ExpectNotNull(q);
    ExpectIntEQ(BN_set_word(q, 5), 1);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, p, q, g), 1);
    /* p, q and g are now owned by dh - don't free. */
    if (EXPECT_FAIL()) {
        BN_free(p);
        BN_free(q);
        BN_free(g);
    }
    p = NULL;
    q = NULL;
    g = NULL;

    p = wolfSSL_BN_new();
    ExpectNotNull(p);
    ExpectIntEQ(BN_set_word(p, 11), 1);
    g = wolfSSL_BN_new();
    ExpectNotNull(g);
    ExpectIntEQ(BN_set_word(g, 2), 1);
    q = wolfSSL_BN_new();
    ExpectNotNull(q);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, p, NULL, NULL), 1);
    if (EXPECT_FAIL()) {
        BN_free(p);
    }
    p = NULL;
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, NULL, q, NULL), 1);
    if (EXPECT_FAIL()) {
        BN_free(q);
    }
    q = NULL;
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, NULL, NULL, g), 1);
    if (EXPECT_FAIL()) {
        BN_free(g);
    }
    g = NULL;
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, NULL, NULL, NULL), 1);
    /* p, q and g are now owned by dh - don't free. */

    DH_free(dh);
    dh = NULL;

    ExpectIntEQ(DH_generate_key(NULL), 0);
    ExpectNotNull(dh = DH_new());
    ExpectIntEQ(DH_generate_key(dh), 0);
    p = wolfSSL_BN_new();
    ExpectNotNull(p);
    ExpectIntEQ(BN_set_word(p, 0), 1);
    g = wolfSSL_BN_new();
    ExpectNotNull(g);
    ExpectIntEQ(BN_set_word(g, 2), 1);
    ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, p, NULL, g), 1);
    if (EXPECT_FAIL()) {
        BN_free(p);
        BN_free(g);
    }
    p = NULL;
    g = NULL;
    ExpectIntEQ(DH_generate_key(dh), 0);
    DH_free(dh);
    dh = NULL;
#endif
#endif

    /* Test DH_up_ref() */
    dh = wolfSSL_DH_new();
    ExpectNotNull(dh);
    ExpectIntEQ(wolfSSL_DH_up_ref(NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_DH_up_ref(dh), WOLFSSL_SUCCESS);
    DH_free(dh); /* decrease ref count */
    DH_free(dh); /* free WOLFSSL_DH */
    dh = NULL;
    q = NULL;

    ExpectNull((dh = DH_new_by_nid(NID_sha1)));
#if (defined(HAVE_PUBLIC_FFDHE) || (defined(HAVE_FIPS) && \
    FIPS_VERSION_EQ(2,0))) || (!defined(HAVE_PUBLIC_FFDHE) && \
    (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)))
#ifdef HAVE_FFDHE_2048
    ExpectNotNull((dh = DH_new_by_nid(NID_ffdhe2048)));
    DH_free(dh);
    dh = NULL;
    q = NULL;
#endif
#ifdef HAVE_FFDHE_3072
    ExpectNotNull((dh = DH_new_by_nid(NID_ffdhe3072)));
    DH_free(dh);
    dh = NULL;
    q = NULL;
#endif
#ifdef HAVE_FFDHE_4096
    ExpectNotNull((dh = DH_new_by_nid(NID_ffdhe4096)));
    DH_free(dh);
    dh = NULL;
    q = NULL;
#endif
#else
    ExpectNull((dh = DH_new_by_nid(NID_ffdhe2048)));
#endif /* (HAVE_PUBLIC_FFDHE || (HAVE_FIPS && HAVE_FIPS_VERSION == 2)) ||
        * (!HAVE_PUBLIC_FFDHE && (!HAVE_FIPS || HAVE_FIPS_VERSION > 2))*/

    ExpectIntEQ(wolfSSL_DH_size(NULL), -1);
#endif /* OPENSSL_EXTRA && !NO_DH */
    return EXPECT_RESULT();
}

static int test_wolfSSL_DH_dup(void)
{
    EXPECT_DECLS;
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) || \
    defined(OPENSSL_EXTRA)
    DH *dh = NULL;
    DH *dhDup = NULL;

    ExpectNotNull(dh = wolfSSL_DH_new());

    ExpectNull(dhDup = wolfSSL_DH_dup(NULL));
    ExpectNull(dhDup = wolfSSL_DH_dup(dh));

#if defined(OPENSSL_ALL) || \
    defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
    {
        WOLFSSL_BIGNUM* p = NULL;
        WOLFSSL_BIGNUM* g = NULL;

        ExpectNotNull(p = wolfSSL_BN_new());
        ExpectNotNull(g = wolfSSL_BN_new());
        ExpectIntEQ(wolfSSL_BN_set_word(p, 11), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_BN_set_word(g, 2), WOLFSSL_SUCCESS);

        ExpectIntEQ(wolfSSL_DH_set0_pqg(dh, p, NULL, g), 1);
        if (EXPECT_FAIL()) {
            wolfSSL_BN_free(p);
            wolfSSL_BN_free(g);
        }

        ExpectNotNull(dhDup = wolfSSL_DH_dup(dh));
        wolfSSL_DH_free(dhDup);
    }
#endif

    wolfSSL_DH_free(dh);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DH_check(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_ALL
#ifndef NO_DH
#ifndef NO_BIO
#ifndef NO_DSA
    byte buf[6000];
    char file[] = "./certs/dsaparams.pem";
    XFILE f = XBADFILE;
    int  bytes = 0;
    BIO* bio = NULL;
    DSA* dsa = NULL;
#elif !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
    static const byte dh2048[] = {
        0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01,
        0x00, 0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13,
        0xba, 0x59, 0x06, 0x3c, 0xbc, 0x30, 0xd5, 0xf5,
        0x00, 0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a,
        0xc6, 0x25, 0x27, 0x1c, 0xe8, 0xd2, 0x96, 0x53,
        0x0a, 0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84,
        0xbf, 0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1,
        0x8a, 0xc5, 0xbe, 0x72, 0x5c, 0xa7, 0xe7, 0x91,
        0xe6, 0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66,
        0x48, 0xc7, 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9,
        0x3d, 0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46, 0x3e,
        0x19, 0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d,
        0x9f, 0x2b, 0x96, 0x17, 0x39, 0x6d, 0x30, 0x8d,
        0x2a, 0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75,
        0xe6, 0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa,
        0x04, 0x83, 0x57, 0x30, 0xfb, 0xda, 0x76, 0x93,
        0x38, 0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c,
        0xe5, 0xb7, 0xc8, 0x09, 0xae, 0x6f, 0x50, 0x35,
        0x8e, 0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e,
        0x5a, 0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76,
        0xcc, 0x16, 0x30, 0xdb, 0x0c, 0xfc, 0xc5, 0x62,
        0xa7, 0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0,
        0x36, 0xf6, 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40,
        0x90, 0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3, 0x1a,
        0xc3, 0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4,
        0x48, 0x4e, 0x22, 0x73, 0x6f, 0xc3, 0x5f, 0xd4,
        0x9a, 0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90,
        0xab, 0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58,
        0x4b, 0xa6, 0xb9, 0xcd, 0x29, 0xbf, 0x68, 0x1f,
        0x08, 0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6,
        0xb6, 0x06, 0x65, 0xf7, 0xa6, 0xdc, 0x00, 0x67,
        0x6b, 0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7,
        0xfa, 0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f,
        0x93, 0x02, 0x01, 0x02
    };
    const byte* params;
#endif
    DH*  dh = NULL;
    WOLFSSL_BIGNUM* p = NULL;
    WOLFSSL_BIGNUM* g = NULL;
    WOLFSSL_BIGNUM* pTmp = NULL;
    WOLFSSL_BIGNUM* gTmp = NULL;
    int codes = -1;

#ifndef NO_DSA
    /* Initialize DH */
    ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
    ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
    if (f != XBADFILE)
        XFCLOSE(f);

    ExpectNotNull(bio = BIO_new_mem_buf((void*)buf, bytes));

    ExpectNotNull(dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL));

    ExpectNotNull(dh = wolfSSL_DSA_dup_DH(dsa));
    ExpectNotNull(dh);

    BIO_free(bio);
    DSA_free(dsa);
#elif !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
    params = dh2048;
    ExpectNotNull(dh = wolfSSL_d2i_DHparams(NULL, &params,
        (long)sizeof(dh2048)));
#else
    ExpectNotNull(dh = wolfSSL_DH_new_by_nid(NID_ffdhe2048));
#endif

    /* Test assumed to be valid dh.
     * Should return WOLFSSL_SUCCESS
     * codes should be 0
     * Invalid codes = {DH_NOT_SUITABLE_GENERATOR, DH_CHECK_P_NOT_PRIME}
     */
    ExpectIntEQ(wolfSSL_DH_check(dh, &codes), 1);
    ExpectIntEQ(codes, 0);

    /* Test NULL dh: expected BAD_FUNC_ARG */
    ExpectIntEQ(wolfSSL_DH_check(NULL, &codes), 0);

    /* Break dh prime to test if codes = DH_CHECK_P_NOT_PRIME */
    if (dh != NULL) {
        pTmp = dh->p;
        dh->p  = NULL;
    }
    ExpectIntEQ(wolfSSL_DH_check(dh, &codes), 1);
    ExpectIntEQ(wolfSSL_DH_check(dh, NULL), 0);
    ExpectIntEQ(codes, DH_CHECK_P_NOT_PRIME);
    /* set dh->p back to normal so it won't fail on next tests */
    if (dh != NULL) {
        dh->p = pTmp;
        pTmp = NULL;
    }

    /* Break dh generator to test if codes = DH_NOT_SUITABLE_GENERATOR */
    if (dh != NULL) {
        gTmp = dh->g;
        dh->g = NULL;
    }
    ExpectIntEQ(wolfSSL_DH_check(dh, &codes), 1);
    ExpectIntEQ(wolfSSL_DH_check(dh, NULL), 0);
    ExpectIntEQ(codes, DH_NOT_SUITABLE_GENERATOR);
    if (dh != NULL) {
        dh->g = gTmp;
        gTmp = NULL;
    }

    /* Cleanup */
    DH_free(dh);
    dh = NULL;

    dh = DH_new();
    ExpectNotNull(dh);
    /* Check empty DH. */
    ExpectIntEQ(wolfSSL_DH_check(dh, &codes), 1);
    ExpectIntEQ(wolfSSL_DH_check(dh, NULL), 0);
    ExpectIntEQ(codes, DH_NOT_SUITABLE_GENERATOR | DH_CHECK_P_NOT_PRIME);
    /* Check non-prime valued p. */
    ExpectNotNull(p = BN_new());
    ExpectIntEQ(BN_set_word(p, 4), 1);
    ExpectNotNull(g = BN_new());
    ExpectIntEQ(BN_set_word(g, 2), 1);
    ExpectIntEQ(DH_set0_pqg(dh, p, NULL, g), 1);
    if (EXPECT_FAIL()) {
        wolfSSL_BN_free(p);
        wolfSSL_BN_free(g);
    }
    ExpectIntEQ(wolfSSL_DH_check(dh, &codes), 1);
    ExpectIntEQ(wolfSSL_DH_check(dh, NULL), 0);
    ExpectIntEQ(codes, DH_CHECK_P_NOT_PRIME);
    DH_free(dh);
    dh = NULL;
#endif
#endif /* !NO_DH  && !NO_DSA */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DH_prime(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DH)
    WOLFSSL_BIGNUM* bn = NULL;
#if WOLFSSL_MAX_BN_BITS >= 768
    WOLFSSL_BIGNUM* bn2 = NULL;
#endif

    bn = wolfSSL_DH_768_prime(NULL);
#if WOLFSSL_MAX_BN_BITS >= 768
    ExpectNotNull(bn);
    bn2 = wolfSSL_DH_768_prime(bn);
    ExpectNotNull(bn2);
    ExpectTrue(bn == bn2);
    wolfSSL_BN_free(bn);
    bn = NULL;
#else
    ExpectNull(bn);
#endif

    bn = wolfSSL_DH_1024_prime(NULL);
#if WOLFSSL_MAX_BN_BITS >= 1024
    ExpectNotNull(bn);
    wolfSSL_BN_free(bn);
    bn = NULL;
#else
    ExpectNull(bn);
#endif
    bn = wolfSSL_DH_2048_prime(NULL);
#if WOLFSSL_MAX_BN_BITS >= 2048
    ExpectNotNull(bn);
    wolfSSL_BN_free(bn);
    bn = NULL;
#else
    ExpectNull(bn);
#endif
    bn = wolfSSL_DH_3072_prime(NULL);
#if WOLFSSL_MAX_BN_BITS >= 3072
    ExpectNotNull(bn);
    wolfSSL_BN_free(bn);
    bn = NULL;
#else
    ExpectNull(bn);
#endif
    bn = wolfSSL_DH_4096_prime(NULL);
#if WOLFSSL_MAX_BN_BITS >= 4096
    ExpectNotNull(bn);
    wolfSSL_BN_free(bn);
    bn = NULL;
#else
    ExpectNull(bn);
#endif
    bn = wolfSSL_DH_6144_prime(NULL);
#if WOLFSSL_MAX_BN_BITS >= 6144
    ExpectNotNull(bn);
    wolfSSL_BN_free(bn);
    bn = NULL;
#else
    ExpectNull(bn);
#endif
    bn = wolfSSL_DH_8192_prime(NULL);
#if WOLFSSL_MAX_BN_BITS >= 8192
    ExpectNotNull(bn);
    wolfSSL_BN_free(bn);
    bn = NULL;
#else
    ExpectNull(bn);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DH_1536_prime(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DH)
    BIGNUM* bn = NULL;
    unsigned char bits[200];
    int sz = 192; /* known binary size */
    const byte expected[] = {
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
        0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
        0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
        0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,
        0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
        0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,
        0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
        0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
        0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
        0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,
        0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
        0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,
        0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
        0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
        0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
        0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,
        0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
        0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,
        0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
        0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
        0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
        0xF1,0x74,0x6C,0x08,0xCA,0x23,0x73,0x27,
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
    };

    ExpectNotNull(bn = get_rfc3526_prime_1536(NULL));
    ExpectIntEQ(sz, BN_bn2bin((const BIGNUM*)bn, bits));
    ExpectIntEQ(0, XMEMCMP(expected, bits, sz));

    BN_free(bn);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DH_get_2048_256(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DH)
    WOLFSSL_DH* dh = NULL;
    const WOLFSSL_BIGNUM* pBn;
    const WOLFSSL_BIGNUM* gBn;
    const WOLFSSL_BIGNUM* qBn;
    const byte pExpected[] = {
        0x87, 0xA8, 0xE6, 0x1D, 0xB4, 0xB6, 0x66, 0x3C, 0xFF, 0xBB, 0xD1, 0x9C,
        0x65, 0x19, 0x59, 0x99, 0x8C, 0xEE, 0xF6, 0x08, 0x66, 0x0D, 0xD0, 0xF2,
        0x5D, 0x2C, 0xEE, 0xD4, 0x43, 0x5E, 0x3B, 0x00, 0xE0, 0x0D, 0xF8, 0xF1,
        0xD6, 0x19, 0x57, 0xD4, 0xFA, 0xF7, 0xDF, 0x45, 0x61, 0xB2, 0xAA, 0x30,
        0x16, 0xC3, 0xD9, 0x11, 0x34, 0x09, 0x6F, 0xAA, 0x3B, 0xF4, 0x29, 0x6D,
        0x83, 0x0E, 0x9A, 0x7C, 0x20, 0x9E, 0x0C, 0x64, 0x97, 0x51, 0x7A, 0xBD,
        0x5A, 0x8A, 0x9D, 0x30, 0x6B, 0xCF, 0x67, 0xED, 0x91, 0xF9, 0xE6, 0x72,
        0x5B, 0x47, 0x58, 0xC0, 0x22, 0xE0, 0xB1, 0xEF, 0x42, 0x75, 0xBF, 0x7B,
        0x6C, 0x5B, 0xFC, 0x11, 0xD4, 0x5F, 0x90, 0x88, 0xB9, 0x41, 0xF5, 0x4E,
        0xB1, 0xE5, 0x9B, 0xB8, 0xBC, 0x39, 0xA0, 0xBF, 0x12, 0x30, 0x7F, 0x5C,
        0x4F, 0xDB, 0x70, 0xC5, 0x81, 0xB2, 0x3F, 0x76, 0xB6, 0x3A, 0xCA, 0xE1,
        0xCA, 0xA6, 0xB7, 0x90, 0x2D, 0x52, 0x52, 0x67, 0x35, 0x48, 0x8A, 0x0E,
        0xF1, 0x3C, 0x6D, 0x9A, 0x51, 0xBF, 0xA4, 0xAB, 0x3A, 0xD8, 0x34, 0x77,
        0x96, 0x52, 0x4D, 0x8E, 0xF6, 0xA1, 0x67, 0xB5, 0xA4, 0x18, 0x25, 0xD9,
        0x67, 0xE1, 0x44, 0xE5, 0x14, 0x05, 0x64, 0x25, 0x1C, 0xCA, 0xCB, 0x83,
        0xE6, 0xB4, 0x86, 0xF6, 0xB3, 0xCA, 0x3F, 0x79, 0x71, 0x50, 0x60, 0x26,
        0xC0, 0xB8, 0x57, 0xF6, 0x89, 0x96, 0x28, 0x56, 0xDE, 0xD4, 0x01, 0x0A,
        0xBD, 0x0B, 0xE6, 0x21, 0xC3, 0xA3, 0x96, 0x0A, 0x54, 0xE7, 0x10, 0xC3,
        0x75, 0xF2, 0x63, 0x75, 0xD7, 0x01, 0x41, 0x03, 0xA4, 0xB5, 0x43, 0x30,
        0xC1, 0x98, 0xAF, 0x12, 0x61, 0x16, 0xD2, 0x27, 0x6E, 0x11, 0x71, 0x5F,
        0x69, 0x38, 0x77, 0xFA, 0xD7, 0xEF, 0x09, 0xCA, 0xDB, 0x09, 0x4A, 0xE9,
        0x1E, 0x1A, 0x15, 0x97
    };
    const byte gExpected[] = {
        0x3F, 0xB3, 0x2C, 0x9B, 0x73, 0x13, 0x4D, 0x0B, 0x2E, 0x77, 0x50, 0x66,
        0x60, 0xED, 0xBD, 0x48, 0x4C, 0xA7, 0xB1, 0x8F, 0x21, 0xEF, 0x20, 0x54,
        0x07, 0xF4, 0x79, 0x3A, 0x1A, 0x0B, 0xA1, 0x25, 0x10, 0xDB, 0xC1, 0x50,
        0x77, 0xBE, 0x46, 0x3F, 0xFF, 0x4F, 0xED, 0x4A, 0xAC, 0x0B, 0xB5, 0x55,
        0xBE, 0x3A, 0x6C, 0x1B, 0x0C, 0x6B, 0x47, 0xB1, 0xBC, 0x37, 0x73, 0xBF,
        0x7E, 0x8C, 0x6F, 0x62, 0x90, 0x12, 0x28, 0xF8, 0xC2, 0x8C, 0xBB, 0x18,
        0xA5, 0x5A, 0xE3, 0x13, 0x41, 0x00, 0x0A, 0x65, 0x01, 0x96, 0xF9, 0x31,
        0xC7, 0x7A, 0x57, 0xF2, 0xDD, 0xF4, 0x63, 0xE5, 0xE9, 0xEC, 0x14, 0x4B,
        0x77, 0x7D, 0xE6, 0x2A, 0xAA, 0xB8, 0xA8, 0x62, 0x8A, 0xC3, 0x76, 0xD2,
        0x82, 0xD6, 0xED, 0x38, 0x64, 0xE6, 0x79, 0x82, 0x42, 0x8E, 0xBC, 0x83,
        0x1D, 0x14, 0x34, 0x8F, 0x6F, 0x2F, 0x91, 0x93, 0xB5, 0x04, 0x5A, 0xF2,
        0x76, 0x71, 0x64, 0xE1, 0xDF, 0xC9, 0x67, 0xC1, 0xFB, 0x3F, 0x2E, 0x55,
        0xA4, 0xBD, 0x1B, 0xFF, 0xE8, 0x3B, 0x9C, 0x80, 0xD0, 0x52, 0xB9, 0x85,
        0xD1, 0x82, 0xEA, 0x0A, 0xDB, 0x2A, 0x3B, 0x73, 0x13, 0xD3, 0xFE, 0x14,
        0xC8, 0x48, 0x4B, 0x1E, 0x05, 0x25, 0x88, 0xB9, 0xB7, 0xD2, 0xBB, 0xD2,
        0xDF, 0x01, 0x61, 0x99, 0xEC, 0xD0, 0x6E, 0x15, 0x57, 0xCD, 0x09, 0x15,
        0xB3, 0x35, 0x3B, 0xBB, 0x64, 0xE0, 0xEC, 0x37, 0x7F, 0xD0, 0x28, 0x37,
        0x0D, 0xF9, 0x2B, 0x52, 0xC7, 0x89, 0x14, 0x28, 0xCD, 0xC6, 0x7E, 0xB6,
        0x18, 0x4B, 0x52, 0x3D, 0x1D, 0xB2, 0x46, 0xC3, 0x2F, 0x63, 0x07, 0x84,
        0x90, 0xF0, 0x0E, 0xF8, 0xD6, 0x47, 0xD1, 0x48, 0xD4, 0x79, 0x54, 0x51,
        0x5E, 0x23, 0x27, 0xCF, 0xEF, 0x98, 0xC5, 0x82, 0x66, 0x4B, 0x4C, 0x0F,
        0x6C, 0xC4, 0x16, 0x59
    };
    const byte qExpected[] = {
        0x8C, 0xF8, 0x36, 0x42, 0xA7, 0x09, 0xA0, 0x97, 0xB4, 0x47, 0x99, 0x76,
        0x40, 0x12, 0x9D, 0xA2, 0x99, 0xB1, 0xA4, 0x7D, 0x1E, 0xB3, 0x75, 0x0B,
        0xA3, 0x08, 0xB0, 0xFE, 0x64, 0xF5, 0xFB, 0xD3
    };
    int pSz = 0;
    int qSz = 0;
    int gSz = 0;
    byte* pReturned = NULL;
    byte* qReturned = NULL;
    byte* gReturned = NULL;

    ExpectNotNull((dh = wolfSSL_DH_get_2048_256()));
    wolfSSL_DH_get0_pqg(dh, &pBn, &qBn, &gBn);

    ExpectIntGT((pSz = wolfSSL_BN_num_bytes(pBn)), 0);
    ExpectNotNull(pReturned = (byte*)XMALLOC(pSz, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntGT((pSz = wolfSSL_BN_bn2bin(pBn, pReturned)), 0);
    ExpectIntEQ(pSz, sizeof(pExpected));
    ExpectIntEQ(XMEMCMP(pExpected, pReturned, pSz), 0);

    ExpectIntGT((qSz = wolfSSL_BN_num_bytes(qBn)), 0);
    ExpectNotNull(qReturned = (byte*)XMALLOC(qSz, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntGT((qSz = wolfSSL_BN_bn2bin(qBn, qReturned)), 0);
    ExpectIntEQ(qSz, sizeof(qExpected));
    ExpectIntEQ(XMEMCMP(qExpected, qReturned, qSz), 0);

    ExpectIntGT((gSz = wolfSSL_BN_num_bytes(gBn)), 0);
    ExpectNotNull(gReturned = (byte*)XMALLOC(gSz, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    ExpectIntGT((gSz = wolfSSL_BN_bn2bin(gBn, gReturned)), 0);
    ExpectIntEQ(gSz, sizeof(gExpected));
    ExpectIntEQ(XMEMCMP(gExpected, gReturned, gSz), 0);

    wolfSSL_DH_free(dh);
    XFREE(pReturned, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(gReturned, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(qReturned, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_write_DHparams(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_BIO) && \
    !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
    DH* dh = NULL;
    BIO* bio = NULL;
    XFILE fp = XBADFILE;
    byte pem[2048];
    int  pemSz = 0;
    const char expected[] =
        "-----BEGIN DH PARAMETERS-----\n"
        "MIIBCAKCAQEAsKEIBpwIE7pZBjy8MNX1AMFPRKfW70rGJScc6NKWUwpckd2iwpSE\n"
        "v32yRJ+b0sGKxb5yXKfnkebUn3MHhVtmSMdw+rTuAsk9mkraPcFGPhlp0RdGB6NN\n"
        "nyuWFzltMI0q85TTdc+gdebykh8acAWqBINXMPvadpM4UOgn/WPuPOW3yAmub1A1\n"
        "joTOSgDpEn5aMdcz/CETdswWMNsM/MVipzW477ewrMA29tnJRkj5QJAAKxuqbOMa\n"
        "wwsDnhvCRuRITiJzb8Nf1JrWMAdI1oyQq9T28eNI01hLprnNKb9oHwhLY4YvXGvW\n"
        "tgZl96bcAGdru8OpQYP7x/rI4h5+rwA/kwIBAg==\n"
        "-----END DH PARAMETERS-----\n";
    const char badPem[] =
        "-----BEGIN DH PARAMETERS-----\n"
        "-----END DH PARAMETERS-----\n";
    const char emptySeqPem[] =
        "-----BEGIN DH PARAMETERS-----\n"
        "MAA=\n"
        "-----END DH PARAMETERS-----\n";

    ExpectTrue((fp = XFOPEN(dhParamFile, "rb")) != XBADFILE);
    ExpectIntGT((pemSz = (int)XFREAD(pem, 1, sizeof(pem), fp)), 0);
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }

    ExpectNull(PEM_read_bio_DHparams(NULL, NULL, NULL, NULL));

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectNull(dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL));
    ExpectIntEQ(BIO_write(bio, badPem, (int)sizeof(badPem)),
        (int)sizeof(badPem));
    ExpectNull(dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectNull(dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL));
    ExpectIntEQ(BIO_write(bio, emptySeqPem, (int)sizeof(emptySeqPem)),
        (int)sizeof(emptySeqPem));
    ExpectNull(dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;

    ExpectNotNull(bio = BIO_new(BIO_s_mem()));
    ExpectIntEQ(BIO_write(bio, pem, pemSz), pemSz);
    ExpectNotNull(dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;

    ExpectNotNull(fp = XFOPEN("./test-write-dhparams.pem", "wb"));
    ExpectIntEQ(PEM_write_DHparams(fp, dh), WOLFSSL_SUCCESS);
    ExpectIntEQ(PEM_write_DHparams(fp, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    DH_free(dh);
    dh = NULL;

    dh = wolfSSL_DH_new();
    ExpectIntEQ(PEM_write_DHparams(fp, dh), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    if (fp != XBADFILE) {
        XFCLOSE(fp);
        fp = XBADFILE;
    }
    wolfSSL_DH_free(dh);
    dh = NULL;

    /* check results */
    XMEMSET(pem, 0, sizeof(pem));
    ExpectTrue((fp = XFOPEN("./test-write-dhparams.pem", "rb")) != XBADFILE);
    ExpectIntGT((pemSz = (int)XFREAD(pem, 1, sizeof(pem), fp)), 0);
    ExpectIntEQ(XMEMCMP(pem, expected, pemSz), 0);
    if (fp != XBADFILE)
        XFCLOSE(fp);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_d2i_DHparams(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_ALL
#if !defined(NO_DH) && (defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072))
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    XFILE f = XBADFILE;
    unsigned char buf[4096];
    const unsigned char* pt = buf;
#ifdef HAVE_FFDHE_2048
    const char* params1 = "./certs/dh2048.der";
#endif
#ifdef HAVE_FFDHE_3072
    const char* params2 = "./certs/dh3072.der";
#endif
    long len = 0;
    WOLFSSL_DH* dh = NULL;
    XMEMSET(buf, 0, sizeof(buf));

    /* Test 2048 bit parameters */
#ifdef HAVE_FFDHE_2048
    ExpectTrue((f = XFOPEN(params1, "rb")) != XBADFILE);
    ExpectTrue((len = (long)XFREAD(buf, 1, sizeof(buf), f)) > 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    /* Valid case */
    ExpectNotNull(dh = wolfSSL_d2i_DHparams(NULL, &pt, len));
    ExpectNotNull(dh->p);
    ExpectNotNull(dh->g);
    ExpectTrue(pt == buf);
    ExpectIntEQ(DH_set_length(NULL, BN_num_bits(dh->p)), 0);
    ExpectIntEQ(DH_set_length(dh, BN_num_bits(dh->p)), 1);
    ExpectIntEQ(DH_generate_key(dh), WOLFSSL_SUCCESS);

    /* Invalid cases */
    ExpectNull(wolfSSL_d2i_DHparams(NULL, NULL, len));
    ExpectNull(wolfSSL_d2i_DHparams(NULL, &pt, -1));
    ExpectNull(wolfSSL_d2i_DHparams(NULL, &pt, 10));

    DH_free(dh);
    dh = NULL;

    *buf = 0;
    pt = buf;
#endif /* HAVE_FFDHE_2048 */

    /* Test 3072 bit parameters */
#ifdef HAVE_FFDHE_3072
    ExpectTrue((f = XFOPEN(params2, "rb")) != XBADFILE);
    ExpectTrue((len = (long)XFREAD(buf, 1, sizeof(buf), f)) > 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    /* Valid case */
    ExpectNotNull(dh = wolfSSL_d2i_DHparams(&dh, &pt, len));
    ExpectNotNull(dh->p);
    ExpectNotNull(dh->g);
    ExpectTrue(pt != buf);
    ExpectIntEQ(DH_generate_key(dh), 1);

    /* Invalid cases */
    ExpectNull(wolfSSL_d2i_DHparams(NULL, NULL, len));
    ExpectNull(wolfSSL_d2i_DHparams(NULL, &pt, -1));

    DH_free(dh);
    dh = NULL;
#endif /* HAVE_FFDHE_3072 */

#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /* !NO_DH */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_DH_LoadDer(void)
{
    EXPECT_DECLS;
#if !defined(NO_DH) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)) && \
    defined(OPENSSL_EXTRA)
    static const byte dh2048[] = {
        0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01,
        0x00, 0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13,
        0xba, 0x59, 0x06, 0x3c, 0xbc, 0x30, 0xd5, 0xf5,
        0x00, 0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a,
        0xc6, 0x25, 0x27, 0x1c, 0xe8, 0xd2, 0x96, 0x53,
        0x0a, 0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84,
        0xbf, 0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1,
        0x8a, 0xc5, 0xbe, 0x72, 0x5c, 0xa7, 0xe7, 0x91,
        0xe6, 0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66,
        0x48, 0xc7, 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9,
        0x3d, 0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46, 0x3e,
        0x19, 0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d,
        0x9f, 0x2b, 0x96, 0x17, 0x39, 0x6d, 0x30, 0x8d,
        0x2a, 0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75,
        0xe6, 0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa,
        0x04, 0x83, 0x57, 0x30, 0xfb, 0xda, 0x76, 0x93,
        0x38, 0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c,
        0xe5, 0xb7, 0xc8, 0x09, 0xae, 0x6f, 0x50, 0x35,
        0x8e, 0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e,
        0x5a, 0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76,
        0xcc, 0x16, 0x30, 0xdb, 0x0c, 0xfc, 0xc5, 0x62,
        0xa7, 0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0,
        0x36, 0xf6, 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40,
        0x90, 0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3, 0x1a,
        0xc3, 0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4,
        0x48, 0x4e, 0x22, 0x73, 0x6f, 0xc3, 0x5f, 0xd4,
        0x9a, 0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90,
        0xab, 0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58,
        0x4b, 0xa6, 0xb9, 0xcd, 0x29, 0xbf, 0x68, 0x1f,
        0x08, 0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6,
        0xb6, 0x06, 0x65, 0xf7, 0xa6, 0xdc, 0x00, 0x67,
        0x6b, 0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7,
        0xfa, 0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f,
        0x93, 0x02, 0x01, 0x02
    };
    WOLFSSL_DH* dh = NULL;

    ExpectNotNull(dh = wolfSSL_DH_new());

    ExpectIntEQ(wolfSSL_DH_LoadDer(NULL, NULL, 0), -1);
    ExpectIntEQ(wolfSSL_DH_LoadDer(dh, NULL, 0), -1);
    ExpectIntEQ(wolfSSL_DH_LoadDer(NULL, dh2048, sizeof(dh2048)), -1);

    ExpectIntEQ(wolfSSL_DH_LoadDer(dh, dh2048, sizeof(dh2048)), 1);

    wolfSSL_DH_free(dh);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2d_DHparams(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_ALL
#if !defined(NO_DH) && (defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072))
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    XFILE f = XBADFILE;
    unsigned char buf[4096];
    const unsigned char* pt;
    unsigned char* pt2;
#ifdef HAVE_FFDHE_2048
    const char* params1 = "./certs/dh2048.der";
#endif
#ifdef HAVE_FFDHE_3072
    const char* params2 = "./certs/dh3072.der";
#endif
    long len = 0;
    WOLFSSL_DH* dh = NULL;

    /* Test 2048 bit parameters */
#ifdef HAVE_FFDHE_2048
    pt = buf;
    pt2 = buf;

    ExpectTrue((f = XFOPEN(params1, "rb")) != XBADFILE);
    ExpectTrue((len = (long)XFREAD(buf, 1, sizeof(buf), f)) > 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    /* Valid case */
    ExpectNotNull(dh = wolfSSL_d2i_DHparams(NULL, &pt, len));
    ExpectTrue(pt == buf);
    ExpectIntEQ(DH_generate_key(dh), 1);
    ExpectIntEQ(wolfSSL_i2d_DHparams(dh, &pt2), 268);

    /* Invalid case */
    ExpectIntEQ(wolfSSL_i2d_DHparams(NULL, &pt2), 0);

    /* Return length only */
    ExpectIntEQ(wolfSSL_i2d_DHparams(dh, NULL), 268);

    DH_free(dh);
    dh = NULL;

    *buf = 0;
#endif

    /* Test 3072 bit parameters */
#ifdef HAVE_FFDHE_3072
    pt = buf;
    pt2 = buf;

    ExpectTrue((f = XFOPEN(params2, "rb")) != XBADFILE);
    ExpectTrue((len = (long)XFREAD(buf, 1, sizeof(buf), f)) > 0);
    if (f != XBADFILE) {
        XFCLOSE(f);
        f = XBADFILE;
    }

    /* Valid case */
    ExpectNotNull(dh = wolfSSL_d2i_DHparams(NULL, &pt, len));
    ExpectTrue(pt == buf);
    ExpectIntEQ(DH_generate_key(dh), 1);
    ExpectIntEQ(wolfSSL_i2d_DHparams(dh, &pt2), 396);

    /* Invalid case */
    ExpectIntEQ(wolfSSL_i2d_DHparams(NULL, &pt2), 0);

    /* Return length only */
    ExpectIntEQ(wolfSSL_i2d_DHparams(dh, NULL), 396);

    DH_free(dh);
    dh = NULL;
#endif

    dh = DH_new();
    ExpectNotNull(dh);
    pt2 = buf;
    ExpectIntEQ(wolfSSL_i2d_DHparams(dh, &pt2), 0);
    DH_free(dh);
    dh = NULL;
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /* !NO_DH && (HAVE_FFDHE_2048 || HAVE_FFDHE_3072) */
#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_ECC) && !defined(OPENSSL_NO_PK)

/*----------------------------------------------------------------------------*
 | EC
 *----------------------------------------------------------------------------*/

static int test_wolfSSL_EC_GROUP(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    EC_GROUP *group = NULL;
    EC_GROUP *group2 = NULL;
    EC_GROUP *group3 = NULL;
#ifndef HAVE_ECC_BRAINPOOL
    EC_GROUP *group4 = NULL;
#endif
    WOLFSSL_BIGNUM* order = NULL;
    int group_bits;
    int i;
    static const int knownEccNids[] = {
        NID_X9_62_prime192v1,
        NID_X9_62_prime192v2,
        NID_X9_62_prime192v3,
        NID_X9_62_prime239v1,
        NID_X9_62_prime239v2,
        NID_X9_62_prime239v3,
        NID_X9_62_prime256v1,
        NID_secp112r1,
        NID_secp112r2,
        NID_secp128r1,
        NID_secp128r2,
        NID_secp160r1,
        NID_secp160r2,
        NID_secp224r1,
        NID_secp384r1,
        NID_secp521r1,
        NID_secp160k1,
        NID_secp192k1,
        NID_secp224k1,
        NID_secp256k1,
        NID_brainpoolP160r1,
        NID_brainpoolP192r1,
        NID_brainpoolP224r1,
        NID_brainpoolP256r1,
        NID_brainpoolP320r1,
        NID_brainpoolP384r1,
        NID_brainpoolP512r1,
    };
    int knowEccNidsLen = (int)(sizeof(knownEccNids) / sizeof(*knownEccNids));
    static const int knownEccEnums[] = {
        ECC_SECP192R1,
        ECC_PRIME192V2,
        ECC_PRIME192V3,
        ECC_PRIME239V1,
        ECC_PRIME239V2,
        ECC_PRIME239V3,
        ECC_SECP256R1,
        ECC_SECP112R1,
        ECC_SECP112R2,
        ECC_SECP128R1,
        ECC_SECP128R2,
        ECC_SECP160R1,
        ECC_SECP160R2,
        ECC_SECP224R1,
        ECC_SECP384R1,
        ECC_SECP521R1,
        ECC_SECP160K1,
        ECC_SECP192K1,
        ECC_SECP224K1,
        ECC_SECP256K1,
        ECC_BRAINPOOLP160R1,
        ECC_BRAINPOOLP192R1,
        ECC_BRAINPOOLP224R1,
        ECC_BRAINPOOLP256R1,
        ECC_BRAINPOOLP320R1,
        ECC_BRAINPOOLP384R1,
        ECC_BRAINPOOLP512R1,
    };
    int knowEccEnumsLen = (int)(sizeof(knownEccEnums) / sizeof(*knownEccEnums));

    ExpectNotNull(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
    ExpectNotNull(group2 = EC_GROUP_dup(group));
    ExpectNotNull(group3 = wolfSSL_EC_GROUP_new_by_curve_name(NID_secp384r1));
#ifndef HAVE_ECC_BRAINPOOL
    ExpectNotNull(group4 = wolfSSL_EC_GROUP_new_by_curve_name(
        NID_brainpoolP256r1));
#endif

    ExpectNull(EC_GROUP_dup(NULL));

    ExpectIntEQ(wolfSSL_EC_GROUP_get_curve_name(NULL), 0);
    ExpectIntEQ(wolfSSL_EC_GROUP_get_curve_name(group), NID_X9_62_prime256v1);

    ExpectIntEQ((group_bits = EC_GROUP_order_bits(NULL)), 0);
    ExpectIntEQ((group_bits = EC_GROUP_order_bits(group)), 256);
#ifndef HAVE_ECC_BRAINPOOL
    ExpectIntEQ((group_bits = EC_GROUP_order_bits(group4)), 0);
#endif

    ExpectIntEQ(wolfSSL_EC_GROUP_get_degree(NULL), 0);
    ExpectIntEQ(wolfSSL_EC_GROUP_get_degree(group), 256);

    ExpectNotNull(order = BN_new());
    ExpectIntEQ(wolfSSL_EC_GROUP_get_order(NULL, NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_EC_GROUP_get_order(group, NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_EC_GROUP_get_order(NULL, order, NULL), 0);
    ExpectIntEQ(wolfSSL_EC_GROUP_get_order(group, order, NULL), 1);
    wolfSSL_BN_free(order);

    ExpectNotNull(EC_GROUP_method_of(group));

    ExpectIntEQ(EC_METHOD_get_field_type(NULL), 0);
    ExpectIntEQ(EC_METHOD_get_field_type(EC_GROUP_method_of(group)),
        NID_X9_62_prime_field);

    ExpectIntEQ(wolfSSL_EC_GROUP_cmp(NULL, NULL, NULL), -1);
    ExpectIntEQ(wolfSSL_EC_GROUP_cmp(group, NULL, NULL), -1);
    ExpectIntEQ(wolfSSL_EC_GROUP_cmp(NULL, group, NULL), -1);
    ExpectIntEQ(wolfSSL_EC_GROUP_cmp(group, group3, NULL), 1);

#ifndef NO_WOLFSSL_STUB
    wolfSSL_EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
#endif

#ifndef HAVE_ECC_BRAINPOOL
    EC_GROUP_free(group4);
#endif
    EC_GROUP_free(group3);
    EC_GROUP_free(group2);
    EC_GROUP_free(group);

    for (i = 0; i < knowEccNidsLen; i++) {
        group = NULL;
        ExpectNotNull(group = EC_GROUP_new_by_curve_name(knownEccNids[i]));
        ExpectIntGT(wolfSSL_EC_GROUP_get_degree(group), 0);
        EC_GROUP_free(group);
    }
    for (i = 0; i < knowEccEnumsLen; i++) {
        group = NULL;
        ExpectNotNull(group = EC_GROUP_new_by_curve_name(knownEccEnums[i]));
        ExpectIntEQ(wolfSSL_EC_GROUP_get_curve_name(group), knownEccNids[i]);
        EC_GROUP_free(group);
    }
#endif
   return EXPECT_RESULT();
}

static int test_wolfSSL_PEM_read_bio_ECPKParameters(void)
{
    EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && !defined(NO_BIO)
    EC_GROUP *group = NULL;
    BIO* bio = NULL;
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \
    ECC_MIN_KEY_SZ <= 384 && !defined(NO_ECC_SECP)
    EC_GROUP *ret = NULL;
    static char ec_nc_p384[] = "-----BEGIN EC PARAMETERS-----\n"
                               "BgUrgQQAIg==\n"
                               "-----END EC PARAMETERS-----";
#endif
    static char ec_nc_bad_1[] = "-----BEGIN EC PARAMETERS-----\n"
                                "MAA=\n"
                                "-----END EC PARAMETERS-----";
    static char ec_nc_bad_2[] = "-----BEGIN EC PARAMETERS-----\n"
                                "BgA=\n"
                                "-----END EC PARAMETERS-----";
    static char ec_nc_bad_3[] = "-----BEGIN EC PARAMETERS-----\n"
                                "BgE=\n"
                                "-----END EC PARAMETERS-----";
    static char ec_nc_bad_4[] = "-----BEGIN EC PARAMETERS-----\n"
                                "BgE*\n"
                                "-----END EC PARAMETERS-----";

    /* Test that first parameter, bio, being NULL fails. */
    ExpectNull(PEM_read_bio_ECPKParameters(NULL, NULL, NULL, NULL));

    /* Test that reading named parameters works. */
    ExpectNotNull(bio = BIO_new(BIO_s_file()));
    ExpectIntEQ(BIO_read_filename(bio, eccKeyFile), WOLFSSL_SUCCESS);
    ExpectNotNull(group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL));
    ExpectIntEQ(EC_GROUP_get_curve_name(group), NID_X9_62_prime256v1);
    BIO_free(bio);
    bio = NULL;
    EC_GROUP_free(group);
    group = NULL;

#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \
    ECC_MIN_KEY_SZ <= 384 && !defined(NO_ECC_SECP)
    /* Test that reusing group works. */
    ExpectNotNull(bio = BIO_new_mem_buf((unsigned char*)ec_nc_p384,
        sizeof(ec_nc_p384)));
    ExpectNotNull(group = PEM_read_bio_ECPKParameters(bio, &group, NULL, NULL));
    ExpectIntEQ(EC_GROUP_get_curve_name(group), NID_secp384r1);
    BIO_free(bio);
    bio = NULL;
    EC_GROUP_free(group);
    group = NULL;

    /* Test that returning through group works. */
    ExpectNotNull(bio = BIO_new_mem_buf((unsigned char*)ec_nc_p384,
        sizeof(ec_nc_p384)));
    ExpectNotNull(ret = PEM_read_bio_ECPKParameters(bio, &group, NULL, NULL));
    ExpectIntEQ(group == ret, 1);
    ExpectIntEQ(EC_GROUP_get_curve_name(group), NID_secp384r1);
    BIO_free(bio);
    bio = NULL;
    EC_GROUP_free(group);
    group = NULL;
#endif

    /* Test 0x30, 0x00 (not and object id) fails. */
    ExpectNotNull(bio = BIO_new_mem_buf((unsigned char*)ec_nc_bad_1,
        sizeof(ec_nc_bad_1)));
    ExpectNull(PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;

    /* Test 0x06, 0x00 (empty object id) fails. */
    ExpectNotNull(bio = BIO_new_mem_buf((unsigned char*)ec_nc_bad_2,
        sizeof(ec_nc_bad_2)));
    ExpectNull(PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;

    /* Test 0x06, 0x01 (badly formed object id) fails. */
    ExpectNotNull(bio = BIO_new_mem_buf((unsigned char*)ec_nc_bad_3,
        sizeof(ec_nc_bad_3)));
    ExpectNull(PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL));
    BIO_free(bio);
    bio = NULL;

    /* Test invalid PEM encoding - invalid character. */
    ExpectNotNull(bio = BIO_new_mem_buf((unsigned char*)ec_nc_bad_4,
        sizeof(ec_nc_bad_4)));
    ExpectNull(PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL));
    BIO_free(bio);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_i2d_ECPKParameters(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    EC_GROUP* grp = NULL;
    unsigned char p256_oid[] = {
        0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
    };
    unsigned char *der = p256_oid;
    unsigned char out_der[sizeof(p256_oid)];

    XMEMSET(out_der, 0, sizeof(out_der));
    ExpectNotNull(d2i_ECPKParameters(&grp, (const unsigned char **)&der,
            sizeof(p256_oid)));
    der = out_der;
    ExpectIntEQ(i2d_ECPKParameters(grp, &der), sizeof(p256_oid));
    ExpectBufEQ(p256_oid, out_der, sizeof(p256_oid));
    EC_GROUP_free(grp);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_POINT(void)
{
    EXPECT_DECLS;
#if !defined(WOLFSSL_SP_MATH) && \
  (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)))

#ifdef OPENSSL_EXTRA
    BN_CTX* ctx = NULL;
    EC_GROUP* group = NULL;
#ifndef HAVE_ECC_BRAINPOOL
    EC_GROUP* group2 = NULL;
#endif
    EC_POINT* Gxy = NULL;
    EC_POINT* new_point = NULL;
    EC_POINT* set_point = NULL;
    EC_POINT* get_point = NULL;
    EC_POINT* infinity = NULL;
    BIGNUM* k = NULL;
    BIGNUM* Gx = NULL;
    BIGNUM* Gy = NULL;
    BIGNUM* Gz = NULL;
    BIGNUM* X = NULL;
    BIGNUM* Y = NULL;
    BIGNUM* set_point_bn = NULL;
    char* hexStr = NULL;

    const char* kTest = "F4F8338AFCC562C5C3F3E1E46A7EFECD"
                        "17AF381913FF7A96314EA47055EA0FD0";
    /* NISTP256R1 Gx/Gy */
    const char* kGx   = "6B17D1F2E12C4247F8BCE6E563A440F2"
                        "77037D812DEB33A0F4A13945D898C296";
    const char* kGy   = "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
                        "2BCE33576B315ECECBB6406837BF51F5";
    const char* uncompG
                      = "046B17D1F2E12C4247F8BCE6E563A440F2"
                        "77037D812DEB33A0F4A13945D898C296"
                        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
                        "2BCE33576B315ECECBB6406837BF51F5";
    const char* compG
                      = "036B17D1F2E12C4247F8BCE6E563A440F2"
                        "77037D812DEB33A0F4A13945D898C296";

#ifndef HAVE_SELFTEST
    EC_POINT *tmp = NULL;
    size_t bin_len;
    unsigned int blen = 0;
    unsigned char* buf = NULL;
    unsigned char bufInf[1] = { 0x00 };

    const unsigned char binUncompG[] = {
        0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
        0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
        0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
        0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
        0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
        0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
    };
    const unsigned char binUncompGBad[] = {
        0x09, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
        0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
        0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
        0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
        0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
        0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
    };

#ifdef HAVE_COMP_KEY
    const unsigned char binCompG[] = {
        0x03, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
        0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
        0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
    };
#endif
#endif

    ExpectNotNull(ctx = BN_CTX_new());
    ExpectNotNull(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
#ifndef HAVE_ECC_BRAINPOOL
    /* Used to make groups curve_idx == -1. */
    ExpectNotNull(group2 = EC_GROUP_new_by_curve_name(NID_brainpoolP256r1));
#endif

    ExpectNull(EC_POINT_new(NULL));
    ExpectNotNull(Gxy = EC_POINT_new(group));
    ExpectNotNull(new_point = EC_POINT_new(group));
    ExpectNotNull(set_point = EC_POINT_new(group));
    ExpectNotNull(X = BN_new());
    ExpectNotNull(Y = BN_new());
    ExpectNotNull(set_point_bn = BN_new());

    ExpectNotNull(infinity = EC_POINT_new(group));

    /* load test values */
    ExpectIntEQ(BN_hex2bn(&k,  kTest), WOLFSSL_SUCCESS);
    ExpectIntEQ(BN_hex2bn(&Gx, kGx),   WOLFSSL_SUCCESS);
    ExpectIntEQ(BN_hex2bn(&Gy, kGy),   WOLFSSL_SUCCESS);
    ExpectIntEQ(BN_hex2bn(&Gz, "1"),   WOLFSSL_SUCCESS);

    /* populate coordinates for input point */
    if (Gxy != NULL) {
        Gxy->X = Gx;
        Gxy->Y = Gy;
        Gxy->Z = Gz;
    }

    /* Test handling of NULL point. */
    EC_POINT_clear_free(NULL);

    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(NULL, NULL,
        NULL, NULL, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(group, NULL,
        NULL, NULL, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(NULL, Gxy,
        NULL, NULL, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(NULL, NULL,
        X, NULL, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(NULL, NULL,
        NULL, Y, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(NULL, Gxy,
        X, Y, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(group, NULL,
        X, Y, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(group, Gxy,
        NULL, Y, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(group, Gxy,
        X, NULL, ctx), 0);
    /* Getting point at infinity returns an error. */
    ExpectIntEQ(wolfSSL_EC_POINT_get_affine_coordinates_GFp(group, infinity,
        X, Y, ctx), 0);

#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
    !defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
    ExpectIntEQ(EC_POINT_add(NULL, NULL, NULL, NULL, ctx), 0);
    ExpectIntEQ(EC_POINT_add(group, NULL, NULL, NULL, ctx), 0);
    ExpectIntEQ(EC_POINT_add(NULL, new_point, NULL, NULL, ctx), 0);
    ExpectIntEQ(EC_POINT_add(NULL, NULL, new_point, NULL, ctx), 0);
    ExpectIntEQ(EC_POINT_add(NULL, NULL, NULL, Gxy, ctx), 0);
    ExpectIntEQ(EC_POINT_add(NULL, new_point, new_point, Gxy, ctx), 0);
    ExpectIntEQ(EC_POINT_add(group, NULL, new_point, Gxy, ctx), 0);
    ExpectIntEQ(EC_POINT_add(group, new_point, NULL, Gxy, ctx), 0);
    ExpectIntEQ(EC_POINT_add(group, new_point, new_point, NULL, ctx), 0);

    ExpectIntEQ(EC_POINT_mul(NULL, NULL, Gx, Gxy, k, ctx), 0);
    ExpectIntEQ(EC_POINT_mul(NULL, new_point, Gx, Gxy, k, ctx), 0);
    ExpectIntEQ(EC_POINT_mul(group, NULL, Gx, Gxy, k, ctx), 0);

    ExpectIntEQ(EC_POINT_add(group, new_point, new_point, Gxy, ctx), 1);
    /* perform point multiplication */
    ExpectIntEQ(EC_POINT_mul(group, new_point, Gx, Gxy, k, ctx), 1);
    ExpectIntEQ(BN_is_zero(new_point->X), 0);
    ExpectIntEQ(BN_is_zero(new_point->Y), 0);
    ExpectIntEQ(BN_is_zero(new_point->Z), 0);
    ExpectIntEQ(EC_POINT_mul(group, new_point, NULL, Gxy, k, ctx), 1);
    ExpectIntEQ(BN_is_zero(new_point->X), 0);
    ExpectIntEQ(BN_is_zero(new_point->Y), 0);
    ExpectIntEQ(BN_is_zero(new_point->Z), 0);
    ExpectIntEQ(EC_POINT_mul(group, new_point, Gx, NULL, NULL, ctx), 1);
    ExpectIntEQ(BN_is_zero(new_point->X), 0);
    ExpectIntEQ(BN_is_zero(new_point->Y), 0);
    ExpectIntEQ(BN_is_zero(new_point->Z), 0);
    ExpectIntEQ(EC_POINT_mul(group, new_point, NULL, NULL, NULL, ctx), 1);
    ExpectIntEQ(BN_is_zero(new_point->X), 1);
    ExpectIntEQ(BN_is_zero(new_point->Y), 1);
    ExpectIntEQ(BN_is_zero(new_point->Z), 1);
    /* Set point to something. */
    ExpectIntEQ(EC_POINT_add(group, new_point, Gxy, Gxy, ctx), 1);
#else
    ExpectIntEQ(EC_POINT_set_affine_coordinates_GFp(group, new_point, Gx, Gy,
        ctx), 1);
    ExpectIntEQ(BN_is_zero(new_point->X), 0);
    ExpectIntEQ(BN_is_zero(new_point->Y), 0);
    ExpectIntEQ(BN_is_zero(new_point->Z), 0);
#endif

    /* check if point X coordinate is zero */
    ExpectIntEQ(BN_is_zero(new_point->X), 0);

#if defined(USE_ECC_B_PARAM) && !defined(HAVE_SELFTEST) && \
    (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
    ExpectIntEQ(EC_POINT_is_on_curve(group, new_point, ctx), 1);
#endif

    /* extract the coordinates from point */
    ExpectIntEQ(EC_POINT_get_affine_coordinates_GFp(group, new_point, X, Y,
        ctx), WOLFSSL_SUCCESS);

    /* check if point X coordinate is zero */
    ExpectIntEQ(BN_is_zero(X), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* set the same X and Y points in another object */
    ExpectIntEQ(EC_POINT_set_affine_coordinates_GFp(group, set_point, X, Y,
        ctx), WOLFSSL_SUCCESS);

    /* compare points as they should be the same */
    ExpectIntEQ(EC_POINT_cmp(NULL, NULL, NULL, ctx), -1);
    ExpectIntEQ(EC_POINT_cmp(group, NULL, NULL, ctx), -1);
    ExpectIntEQ(EC_POINT_cmp(NULL, new_point, NULL, ctx), -1);
    ExpectIntEQ(EC_POINT_cmp(NULL, NULL, set_point, ctx), -1);
    ExpectIntEQ(EC_POINT_cmp(NULL, new_point, set_point, ctx), -1);
    ExpectIntEQ(EC_POINT_cmp(group, NULL, set_point, ctx), -1);
    ExpectIntEQ(EC_POINT_cmp(group, new_point, NULL, ctx), -1);
    ExpectIntEQ(EC_POINT_cmp(group, new_point, set_point, ctx), 0);

    /* Test copying */
    ExpectIntEQ(EC_POINT_copy(NULL, NULL), 0);
    ExpectIntEQ(EC_POINT_copy(NULL, set_point), 0);
    ExpectIntEQ(EC_POINT_copy(new_point, NULL), 0);
    ExpectIntEQ(EC_POINT_copy(new_point, set_point), 1);

    /* Test inverting */
    ExpectIntEQ(EC_POINT_invert(NULL, NULL, ctx), 0);
    ExpectIntEQ(EC_POINT_invert(NULL, new_point, ctx), 0);
    ExpectIntEQ(EC_POINT_invert(group, NULL, ctx), 0);
    ExpectIntEQ(EC_POINT_invert(group, new_point, ctx), 1);

#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
    !defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
    {
        EC_POINT* orig_point = NULL;
        ExpectNotNull(orig_point = EC_POINT_new(group));
        ExpectIntEQ(EC_POINT_add(group, orig_point, set_point, set_point, NULL),
                    1);
        /* new_point should be set_point inverted so adding it will revert
         * the point back to set_point */
        ExpectIntEQ(EC_POINT_add(group, orig_point, orig_point, new_point,
                                 NULL), 1);
        ExpectIntEQ(EC_POINT_cmp(group, orig_point, set_point, NULL), 0);
        EC_POINT_free(orig_point);
    }
#endif

    /* Test getting affine converts from projective. */
    ExpectIntEQ(EC_POINT_copy(set_point, new_point), 1);
    /* Force non-affine coordinates */
    ExpectIntEQ(BN_add(new_point->Z, (WOLFSSL_BIGNUM*)BN_value_one(),
        (WOLFSSL_BIGNUM*)BN_value_one()), 1);
    if (new_point != NULL) {
        new_point->inSet = 0;
    }
    /* extract the coordinates from point */
    ExpectIntEQ(EC_POINT_get_affine_coordinates_GFp(group, new_point, X, Y,
        ctx), WOLFSSL_SUCCESS);
    /* check if point ordinates have changed. */
    ExpectIntNE(BN_cmp(X, set_point->X), 0);
    ExpectIntNE(BN_cmp(Y, set_point->Y), 0);

    /* Test check for infinity */
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
    ExpectIntEQ(EC_POINT_is_at_infinity(NULL, NULL), 0);
    ExpectIntEQ(EC_POINT_is_at_infinity(NULL, infinity), 0);
    ExpectIntEQ(EC_POINT_is_at_infinity(group, NULL), 0);
    ExpectIntEQ(EC_POINT_is_at_infinity(group, infinity), 1);
    ExpectIntEQ(EC_POINT_is_at_infinity(group, Gxy), 0);
#else
    ExpectIntEQ(EC_POINT_is_at_infinity(group, infinity), 0);
#endif

    ExpectPtrEq(EC_POINT_point2bn(group, set_point,
        POINT_CONVERSION_UNCOMPRESSED, set_point_bn, ctx), set_point_bn);

    /* check bn2hex */
    hexStr = BN_bn2hex(k);
    ExpectStrEQ(hexStr, kTest);
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) && \
     defined(XFPRINTF)
    BN_print_fp(stderr, k);
    fprintf(stderr, "\n");
#endif
    XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC);

    hexStr = BN_bn2hex(Gx);
    ExpectStrEQ(hexStr, kGx);
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) && \
     defined(XFPRINTF)
    BN_print_fp(stderr, Gx);
    fprintf(stderr, "\n");
#endif
    XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC);

    hexStr = BN_bn2hex(Gy);
    ExpectStrEQ(hexStr, kGy);
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) && \
     defined(XFPRINTF)
    BN_print_fp(stderr, Gy);
    fprintf(stderr, "\n");
#endif
    XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC);

    /* Test point to hex */
    ExpectNull(EC_POINT_point2hex(NULL, NULL, POINT_CONVERSION_UNCOMPRESSED,
        ctx));
    ExpectNull(EC_POINT_point2hex(NULL, Gxy, POINT_CONVERSION_UNCOMPRESSED,
        ctx));
    ExpectNull(EC_POINT_point2hex(group, NULL, POINT_CONVERSION_UNCOMPRESSED,
        ctx));
#ifndef HAVE_ECC_BRAINPOOL
    /* Group not supported in wolfCrypt. */
    ExpectNull(EC_POINT_point2hex(group2, Gxy, POINT_CONVERSION_UNCOMPRESSED,
        ctx));
#endif

    hexStr = EC_POINT_point2hex(group, Gxy, POINT_CONVERSION_UNCOMPRESSED, ctx);
    ExpectNotNull(hexStr);
    ExpectStrEQ(hexStr, uncompG);
    ExpectNotNull(get_point = EC_POINT_hex2point(group, hexStr, NULL, ctx));
    ExpectIntEQ(EC_POINT_cmp(group, Gxy, get_point, ctx), 0);
    XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC);

    hexStr = EC_POINT_point2hex(group, Gxy, POINT_CONVERSION_COMPRESSED, ctx);
    ExpectNotNull(hexStr);
    ExpectStrEQ(hexStr, compG);
    #ifdef HAVE_COMP_KEY
    ExpectNotNull(get_point = EC_POINT_hex2point
                                            (group, hexStr, get_point, ctx));
    ExpectIntEQ(EC_POINT_cmp(group, Gxy, get_point, ctx), 0);
    #endif
    XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC);
    EC_POINT_free(get_point);

#ifndef HAVE_SELFTEST
    /* Test point to oct */
    ExpectIntEQ(EC_POINT_point2oct(NULL, NULL, POINT_CONVERSION_UNCOMPRESSED,
        NULL, 0, ctx), 0);
    ExpectIntEQ(EC_POINT_point2oct(NULL, Gxy, POINT_CONVERSION_UNCOMPRESSED,
        NULL, 0, ctx), 0);
    ExpectIntEQ(EC_POINT_point2oct(group, NULL, POINT_CONVERSION_UNCOMPRESSED,
        NULL, 0, ctx), 0);
    bin_len = EC_POINT_point2oct(group, Gxy, POINT_CONVERSION_UNCOMPRESSED,
        NULL, 0, ctx);
    ExpectIntEQ(bin_len, sizeof(binUncompG));
    ExpectNotNull(buf = (unsigned char*)XMALLOC(bin_len, NULL,
         DYNAMIC_TYPE_ECC));
    ExpectIntEQ(EC_POINT_point2oct(group, Gxy, POINT_CONVERSION_UNCOMPRESSED,
        buf, bin_len, ctx), bin_len);
    ExpectIntEQ(XMEMCMP(buf, binUncompG, sizeof(binUncompG)), 0);
    XFREE(buf, NULL, DYNAMIC_TYPE_ECC);

    /* Infinity (x=0, y=0) encodes as '0x00'. */
    ExpectIntEQ(EC_POINT_point2oct(group, infinity,
        POINT_CONVERSION_UNCOMPRESSED, NULL, 0, ctx), 1);
    ExpectIntEQ(EC_POINT_point2oct(group, infinity,
        POINT_CONVERSION_UNCOMPRESSED, bufInf, 0, ctx), 0);
    ExpectIntEQ(EC_POINT_point2oct(group, infinity,
        POINT_CONVERSION_UNCOMPRESSED, bufInf, 1, ctx), 1);
    ExpectIntEQ(bufInf[0], 0);

    wolfSSL_EC_POINT_dump(NULL, NULL);
    /* Test point i2d */
    ExpectIntEQ(ECPoint_i2d(NULL, NULL, NULL, &blen), 0);
    ExpectIntEQ(ECPoint_i2d(NULL, Gxy, NULL, &blen), 0);
    ExpectIntEQ(ECPoint_i2d(group, NULL, NULL, &blen), 0);
    ExpectIntEQ(ECPoint_i2d(group, Gxy, NULL, NULL), 0);
    ExpectIntEQ(ECPoint_i2d(group, Gxy, NULL, &blen), 1);
    ExpectIntEQ(blen, sizeof(binUncompG));
    ExpectNotNull(buf = (unsigned char*)XMALLOC(blen, NULL, DYNAMIC_TYPE_ECC));
    blen -= 1;
    ExpectIntEQ(ECPoint_i2d(group, Gxy, buf, &blen), 0);
    blen += 1;
    ExpectIntEQ(ECPoint_i2d(group, Gxy, buf, &blen), 1);
    ExpectIntEQ(XMEMCMP(buf, binUncompG, sizeof(binUncompG)), 0);
    XFREE(buf, NULL, DYNAMIC_TYPE_ECC);

#ifdef HAVE_COMP_KEY
    /* Test point to oct compressed */
    bin_len = EC_POINT_point2oct(group, Gxy, POINT_CONVERSION_COMPRESSED, NULL,
        0, ctx);
    ExpectIntEQ(bin_len, sizeof(binCompG));
    ExpectNotNull(buf = (unsigned char*)XMALLOC(bin_len, NULL,
        DYNAMIC_TYPE_ECC));
    ExpectIntEQ(EC_POINT_point2oct(group, Gxy, POINT_CONVERSION_COMPRESSED, buf,
        bin_len, ctx), bin_len);
    ExpectIntEQ(XMEMCMP(buf, binCompG, sizeof(binCompG)), 0);
    XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
#endif

    /* Test point BN */
    ExpectNull(wolfSSL_EC_POINT_point2bn(NULL, NULL,
        POINT_CONVERSION_UNCOMPRESSED, NULL, ctx));
    ExpectNull(wolfSSL_EC_POINT_point2bn(NULL, Gxy,
        POINT_CONVERSION_UNCOMPRESSED, NULL, ctx));
    ExpectNull(wolfSSL_EC_POINT_point2bn(group, NULL,
        POINT_CONVERSION_UNCOMPRESSED, NULL, ctx));
    ExpectNull(wolfSSL_EC_POINT_point2bn(group, Gxy, 0, NULL, ctx));

    /* Test oct to point */
    ExpectNotNull(tmp = EC_POINT_new(group));
    ExpectIntEQ(EC_POINT_oct2point(NULL, NULL, binUncompG, sizeof(binUncompG),
        ctx), 0);
    ExpectIntEQ(EC_POINT_oct2point(NULL, tmp, binUncompG, sizeof(binUncompG),
        ctx), 0);
    ExpectIntEQ(EC_POINT_oct2point(group, NULL, binUncompG, sizeof(binUncompG),
        ctx), 0);
    ExpectIntEQ(EC_POINT_oct2point(group, tmp, binUncompGBad,
        sizeof(binUncompGBad), ctx), 0);
    ExpectIntEQ(EC_POINT_oct2point(group, tmp, binUncompG, sizeof(binUncompG),
        ctx), 1);
    ExpectIntEQ(EC_POINT_cmp(group, tmp, Gxy, ctx), 0);
    EC_POINT_free(tmp);
    tmp = NULL;

    /* Test setting BN ordinates. */
    ExpectNotNull(tmp = EC_POINT_new(group));
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(NULL, NULL, NULL,
        NULL, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(group, NULL, NULL,
        NULL, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(NULL, tmp, NULL,
        NULL, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(NULL, NULL, Gx,
        NULL, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(NULL, NULL, NULL,
        Gy, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(NULL, tmp, Gx, Gy,
        ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(group, NULL, Gx, Gy,
        ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(group, tmp, NULL,
        Gy, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(group, tmp, Gx,
        NULL, ctx), 0);
    ExpectIntEQ(wolfSSL_EC_POINT_set_affine_coordinates_GFp(group, tmp, Gx, Gy,
        ctx), 1);
    EC_POINT_free(tmp);
    tmp = NULL;

    /* Test point d2i */
    ExpectNotNull(tmp = EC_POINT_new(group));
    ExpectIntEQ(ECPoint_d2i(NULL, sizeof(binUncompG), NULL, NULL), 0);
    ExpectIntEQ(ECPoint_d2i(binUncompG, sizeof(binUncompG), NULL, NULL), 0);
    ExpectIntEQ(ECPoint_d2i(NULL, sizeof(binUncompG), group, NULL), 0);
    ExpectIntEQ(ECPoint_d2i(NULL, sizeof(binUncompG), NULL, tmp), 0);
    ExpectIntEQ(ECPoint_d2i(NULL, sizeof(binUncompG), group, tmp), 0);
    ExpectIntEQ(ECPoint_d2i(binUncompG, sizeof(binUncompG), NULL, tmp), 0);
    ExpectIntEQ(ECPoint_d2i(binUncompG, sizeof(binUncompG), group, NULL), 0);
    ExpectIntEQ(ECPoint_d2i(binUncompGBad, sizeof(binUncompG), group, tmp), 0);
    ExpectIntEQ(ECPoint_d2i(binUncompG, sizeof(binUncompG), group, tmp), 1);
    ExpectIntEQ(EC_POINT_cmp(group, tmp, Gxy, ctx), 0);
    EC_POINT_free(tmp);
    tmp = NULL;

#ifdef HAVE_COMP_KEY
    /* Test oct compressed to point */
    ExpectNotNull(tmp = EC_POINT_new(group));
    ExpectIntEQ(EC_POINT_oct2point(group, tmp, binCompG, sizeof(binCompG), ctx),
        1);
    ExpectIntEQ(EC_POINT_cmp(group, tmp, Gxy, ctx), 0);
    EC_POINT_free(tmp);
    tmp = NULL;

    /* Test point d2i - compressed */
    ExpectNotNull(tmp = EC_POINT_new(group));
    ExpectIntEQ(ECPoint_d2i(binCompG, sizeof(binCompG), group, tmp), 1);
    ExpectIntEQ(EC_POINT_cmp(group, tmp, Gxy, ctx), 0);
    EC_POINT_free(tmp);
    tmp = NULL;
#endif
#endif

    /* test BN_mod_add */
    ExpectIntEQ(BN_mod_add(new_point->Z, (WOLFSSL_BIGNUM*)BN_value_one(),
        (WOLFSSL_BIGNUM*)BN_value_one(), (WOLFSSL_BIGNUM*)BN_value_one(), NULL),
        1);
    ExpectIntEQ(BN_is_zero(new_point->Z), 1);

    /* cleanup */
    BN_free(X);
    BN_free(Y);
    BN_free(k);
    BN_free(set_point_bn);
    EC_POINT_free(infinity);
    EC_POINT_free(new_point);
    EC_POINT_free(set_point);
    EC_POINT_clear_free(Gxy);
#ifndef HAVE_ECC_BRAINPOOL
    EC_GROUP_free(group2);
#endif
    EC_GROUP_free(group);
    BN_CTX_free(ctx);
#endif
#endif /* !WOLFSSL_SP_MATH && ( !HAVE_FIPS || HAVE_FIPS_VERSION > 2) */
    return EXPECT_RESULT();
}

static int test_wolfSSL_SPAKE(void)
{
    EXPECT_DECLS;

#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && !defined(WOLFSSL_ATECC508A) \
    && !defined(WOLFSSL_ATECC608A) && !defined(HAVE_SELFTEST) && \
       !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
    BIGNUM* x = NULL; /* kdc priv */
    BIGNUM* y = NULL; /* client priv */
    BIGNUM* w = NULL; /* shared value */
    byte M_bytes[] = {
        /* uncompressed */
        0x04,
        /* x */
        0x88, 0x6e, 0x2f, 0x97, 0xac, 0xe4, 0x6e, 0x55, 0xba, 0x9d, 0xd7, 0x24,
        0x25, 0x79, 0xf2, 0x99, 0x3b, 0x64, 0xe1, 0x6e, 0xf3, 0xdc, 0xab, 0x95,
        0xaf, 0xd4, 0x97, 0x33, 0x3d, 0x8f, 0xa1, 0x2f,
        /* y */
        0x5f, 0xf3, 0x55, 0x16, 0x3e, 0x43, 0xce, 0x22, 0x4e, 0x0b, 0x0e, 0x65,
        0xff, 0x02, 0xac, 0x8e, 0x5c, 0x7b, 0xe0, 0x94, 0x19, 0xc7, 0x85, 0xe0,
        0xca, 0x54, 0x7d, 0x55, 0xa1, 0x2e, 0x2d, 0x20
    };
    EC_POINT* M = NULL; /* shared value */
    byte N_bytes[] = {
        /* uncompressed */
        0x04,
        /* x */
        0xd8, 0xbb, 0xd6, 0xc6, 0x39, 0xc6, 0x29, 0x37, 0xb0, 0x4d, 0x99, 0x7f,
        0x38, 0xc3, 0x77, 0x07, 0x19, 0xc6, 0x29, 0xd7, 0x01, 0x4d, 0x49, 0xa2,
        0x4b, 0x4f, 0x98, 0xba, 0xa1, 0x29, 0x2b, 0x49,
        /* y */
        0x07, 0xd6, 0x0a, 0xa6, 0xbf, 0xad, 0xe4, 0x50, 0x08, 0xa6, 0x36, 0x33,
        0x7f, 0x51, 0x68, 0xc6, 0x4d, 0x9b, 0xd3, 0x60, 0x34, 0x80, 0x8c, 0xd5,
        0x64, 0x49, 0x0b, 0x1e, 0x65, 0x6e, 0xdb, 0xe7
    };
    EC_POINT* N = NULL; /* shared value */
    EC_POINT* T = NULL; /* kdc pub */
    EC_POINT* tmp1 = NULL; /* kdc pub */
    EC_POINT* tmp2 = NULL; /* kdc pub */
    EC_POINT* S = NULL; /* client pub */
    EC_POINT* client_secret = NULL;
    EC_POINT* kdc_secret = NULL;
    EC_GROUP* group = NULL;
    BN_CTX* bn_ctx = NULL;

    /* Values taken from a test run of Kerberos 5 */

    ExpectNotNull(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
    ExpectNotNull(bn_ctx = BN_CTX_new());

    ExpectNotNull(M = EC_POINT_new(group));
    ExpectNotNull(N = EC_POINT_new(group));
    ExpectNotNull(T = EC_POINT_new(group));
    ExpectNotNull(tmp1 = EC_POINT_new(group));
    ExpectNotNull(tmp2 = EC_POINT_new(group));
    ExpectNotNull(S = EC_POINT_new(group));
    ExpectNotNull(client_secret = EC_POINT_new(group));
    ExpectNotNull(kdc_secret = EC_POINT_new(group));
    ExpectIntEQ(BN_hex2bn(&x, "DAC3027CD692B4BDF0EDFE9B7D0E4E7"
                              "E5D8768A725EAEEA6FC68EC239A17C0"), 1);
    ExpectIntEQ(BN_hex2bn(&y, "6F6A1D394E26B1655A54B26DCE30D49"
                              "90CC47EBE08F809EF3FF7F6AEAABBB5"), 1);
    ExpectIntEQ(BN_hex2bn(&w, "1D992AB8BA851B9BA05353453D81EE9"
                              "506AB395478F0AAB647752CF117B36250"), 1);
    ExpectIntEQ(EC_POINT_oct2point(group, M, M_bytes, sizeof(M_bytes), bn_ctx),
                1);
    ExpectIntEQ(EC_POINT_oct2point(group, N, N_bytes, sizeof(N_bytes), bn_ctx),
                1);

    /* Function pattern similar to ossl_keygen and ossl_result in krb5 */

    /* kdc */
    /* T=x*P+w*M */
    /* All in one function call */
    ExpectIntEQ(EC_POINT_mul(group, T, x, M, w, bn_ctx), 1);
    /* Spread into separate calls */
    ExpectIntEQ(EC_POINT_mul(group, tmp1, x, NULL, NULL, bn_ctx), 1);
    ExpectIntEQ(EC_POINT_mul(group, tmp2, NULL, M, w, bn_ctx), 1);
    ExpectIntEQ(EC_POINT_add(group, tmp1, tmp1, tmp2, bn_ctx),
                1);
    ExpectIntEQ(EC_POINT_cmp(group, T, tmp1, bn_ctx), 0);
    /* client */
    /* S=y*P+w*N */
    /* All in one function call */
    ExpectIntEQ(EC_POINT_mul(group, S, y, N, w, bn_ctx), 1);
    /* Spread into separate calls */
    ExpectIntEQ(EC_POINT_mul(group, tmp1, y, NULL, NULL, bn_ctx), 1);
    ExpectIntEQ(EC_POINT_mul(group, tmp2, NULL, N, w, bn_ctx), 1);
    ExpectIntEQ(EC_POINT_add(group, tmp1, tmp1, tmp2, bn_ctx),
                1);
    ExpectIntEQ(EC_POINT_cmp(group, S, tmp1, bn_ctx), 0);
    /* K=y*(T-w*M) */
    ExpectIntEQ(EC_POINT_mul(group, client_secret, NULL, M, w, bn_ctx), 1);
    ExpectIntEQ(EC_POINT_invert(group, client_secret, bn_ctx), 1);
    ExpectIntEQ(EC_POINT_add(group, client_secret, T, client_secret, bn_ctx),
                1);
    ExpectIntEQ(EC_POINT_mul(group, client_secret, NULL, client_secret, y,
                             bn_ctx), 1);
    /* kdc */
    /* K=x*(S-w*N) */
    ExpectIntEQ(EC_POINT_mul(group, kdc_secret, NULL, N, w, bn_ctx), 1);
    ExpectIntEQ(EC_POINT_invert(group, kdc_secret, bn_ctx), 1);
    ExpectIntEQ(EC_POINT_add(group, kdc_secret, S, kdc_secret, bn_ctx),
                1);
    ExpectIntEQ(EC_POINT_mul(group, kdc_secret, NULL, kdc_secret, x, bn_ctx),
                1);

    /* kdc_secret == client_secret */
    ExpectIntEQ(EC_POINT_cmp(group, client_secret, kdc_secret, bn_ctx), 0);

    BN_free(x);
    BN_free(y);
    BN_free(w);
    EC_POINT_free(M);
    EC_POINT_free(N);
    EC_POINT_free(T);
    EC_POINT_free(tmp1);
    EC_POINT_free(tmp2);
    EC_POINT_free(S);
    EC_POINT_free(client_secret);
    EC_POINT_free(kdc_secret);
    EC_GROUP_free(group);
    BN_CTX_free(bn_ctx);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_KEY_generate(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    WOLFSSL_EC_KEY* key = NULL;
#ifndef HAVE_ECC_BRAINPOOL
    WOLFSSL_EC_GROUP* group = NULL;
#endif

    ExpectNotNull(key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));

    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(NULL), 0);
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(key), 1);
    wolfSSL_EC_KEY_free(key);
    key = NULL;

#ifndef HAVE_ECC_BRAINPOOL
    ExpectNotNull(group = wolfSSL_EC_GROUP_new_by_curve_name(
        NID_brainpoolP256r1));
    ExpectNotNull(key = wolfSSL_EC_KEY_new());
    ExpectIntEQ(wolfSSL_EC_KEY_set_group(key, group), 1);
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(key), 0);
    wolfSSL_EC_KEY_free(key);
    wolfSSL_EC_GROUP_free(group);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_EC_i2d(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(HAVE_FIPS)
    EC_KEY *key = NULL;
    EC_KEY *copy = NULL;
    int len = 0;
    unsigned char *buf = NULL;
    unsigned char *p = NULL;
    const unsigned char *tmp = NULL;
    const unsigned char octBad[] = {
        0x09, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
        0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
        0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
        0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
        0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
        0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
    };

    ExpectNotNull(key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
    ExpectIntEQ(EC_KEY_generate_key(key), 1);
    ExpectIntGT((len = i2d_EC_PUBKEY(key, NULL)), 0);
    ExpectNotNull(buf = (unsigned char*)XMALLOC(len, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    p = buf;
    ExpectIntEQ(i2d_EC_PUBKEY(key, &p), len);

    ExpectNull(o2i_ECPublicKey(NULL, NULL, -1));
    ExpectNull(o2i_ECPublicKey(&copy, NULL, -1));
    ExpectNull(o2i_ECPublicKey(&key, NULL, -1));
    ExpectNull(o2i_ECPublicKey(NULL, &tmp, -1));
    ExpectNull(o2i_ECPublicKey(NULL, NULL, 0));
    ExpectNull(o2i_ECPublicKey(&key, NULL, 0));
    ExpectNull(o2i_ECPublicKey(&key, &tmp, 0));
    tmp = buf;
    ExpectNull(o2i_ECPublicKey(NULL, &tmp, 0));
    ExpectNull(o2i_ECPublicKey(&copy, &tmp, 0));
    ExpectNull(o2i_ECPublicKey(NULL, &tmp, -1));
    ExpectNull(o2i_ECPublicKey(&key, &tmp, -1));

    ExpectIntEQ(i2o_ECPublicKey(NULL, NULL), 0);
    ExpectIntEQ(i2o_ECPublicKey(NULL, &buf), 0);

    tmp = buf;
    ExpectNull(d2i_ECPrivateKey(NULL, &tmp, 0));
    ExpectNull(d2i_ECPrivateKey(NULL, &tmp, 1));
    ExpectNull(d2i_ECPrivateKey(&copy, &tmp, 0));
    ExpectNull(d2i_ECPrivateKey(&copy, &tmp, 1));
    ExpectNull(d2i_ECPrivateKey(&key, &tmp, 0));

    {
        EC_KEY *pubkey = NULL;
        BIO* bio = NULL;

        ExpectNotNull(bio = BIO_new(BIO_s_mem()));
        ExpectIntGT(BIO_write(bio, buf, len), 0);
        ExpectNotNull(d2i_EC_PUBKEY_bio(bio, &pubkey));

        BIO_free(bio);
        EC_KEY_free(pubkey);
    }

    ExpectIntEQ(i2d_ECPrivateKey(NULL, &p), 0);
    ExpectIntEQ(i2d_ECPrivateKey(NULL, NULL), 0);

    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer(NULL, NULL, -1), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(NULL, NULL, -1, 0), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(key, NULL, -1, 0), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(NULL, buf, -1, 0), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(NULL, NULL, 0, 0), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(NULL, NULL, -1,
        WOLFSSL_EC_KEY_LOAD_PUBLIC), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(NULL, buf, len,
        WOLFSSL_EC_KEY_LOAD_PUBLIC), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(key, NULL, len,
        WOLFSSL_EC_KEY_LOAD_PUBLIC), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(key, buf, -1,
        WOLFSSL_EC_KEY_LOAD_PUBLIC), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(key, buf, len, 0), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(key, buf, len,
        WOLFSSL_EC_KEY_LOAD_PRIVATE), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(key, octBad, sizeof(octBad),
        WOLFSSL_EC_KEY_LOAD_PRIVATE), -1);
    ExpectIntEQ(wolfSSL_EC_KEY_LoadDer_ex(key, octBad, sizeof(octBad),
        WOLFSSL_EC_KEY_LOAD_PUBLIC), -1);

    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    buf = NULL;
    buf = NULL;

    ExpectIntGT((len = i2d_ECPrivateKey(key, NULL)), 0);
    ExpectNotNull(buf = (unsigned char*)XMALLOC(len, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    p = buf;
    ExpectIntEQ(i2d_ECPrivateKey(key, &p), len);

    p = NULL;
    ExpectIntEQ(i2d_ECPrivateKey(key, &p), len);
    XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    p = NULL;

    /* Bad point is also an invalid private key. */
    tmp = octBad;
    ExpectNull(d2i_ECPrivateKey(&copy, &tmp, sizeof(octBad)));
    tmp = buf;
    ExpectNotNull(d2i_ECPrivateKey(&copy, &tmp, len));
    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    buf = NULL;
    buf = NULL;

    ExpectIntGT((len = i2o_ECPublicKey(key, NULL)), 0);
    ExpectNotNull(buf = (unsigned char*)XMALLOC(len, NULL,
        DYNAMIC_TYPE_TMP_BUFFER));
    p = buf;
    ExpectIntGT((len = i2o_ECPublicKey(key, &p)), 0);
    p = NULL;
    ExpectIntGT((len = i2o_ECPublicKey(key, &p)), 0);
    tmp = buf;
    ExpectNotNull(o2i_ECPublicKey(&copy, &tmp, len));
    tmp = octBad;
    ExpectNull(o2i_ECPublicKey(&key, &tmp, sizeof(octBad)));

    ExpectIntEQ(EC_KEY_check_key(NULL), 0);
    ExpectIntEQ(EC_KEY_check_key(key), 1);

    XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
    XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);

    EC_KEY_free(key);
    EC_KEY_free(copy);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_curve(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    int nid = NID_secp160k1;
    const char* nid_name = NULL;

    ExpectNull(EC_curve_nid2nist(NID_sha256));

    ExpectNotNull(nid_name = EC_curve_nid2nist(nid));
    ExpectIntEQ(XMEMCMP(nid_name, "K-160", XSTRLEN("K-160")), 0);

    ExpectIntEQ(EC_curve_nist2nid("INVALID"), 0);
    ExpectIntEQ(EC_curve_nist2nid(nid_name), nid);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_KEY_dup(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
    WOLFSSL_EC_KEY* ecKey = NULL;
    WOLFSSL_EC_KEY* dupKey = NULL;
    ecc_key* srcKey = NULL;
    ecc_key* destKey = NULL;

    ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1);

    /* Valid cases */
    ExpectNotNull(dupKey = wolfSSL_EC_KEY_dup(ecKey));
    ExpectIntEQ(EC_KEY_check_key(dupKey), 1);

    /* Compare pubkey */
    if (ecKey != NULL) {
        srcKey = (ecc_key*)ecKey->internal;
    }
    if (dupKey != NULL) {
        destKey = (ecc_key*)dupKey->internal;
    }
    ExpectIntEQ(wc_ecc_cmp_point(&srcKey->pubkey, &destKey->pubkey), 0);

    /* compare EC_GROUP */
    ExpectIntEQ(wolfSSL_EC_GROUP_cmp(ecKey->group, dupKey->group, NULL), MP_EQ);

    /* compare EC_POINT */
    ExpectIntEQ(wolfSSL_EC_POINT_cmp(ecKey->group, ecKey->pub_key, \
                dupKey->pub_key, NULL), MP_EQ);

    /* compare BIGNUM */
    ExpectIntEQ(wolfSSL_BN_cmp(ecKey->priv_key, dupKey->priv_key), MP_EQ);
    wolfSSL_EC_KEY_free(dupKey);
    dupKey = NULL;

    /* Invalid cases */
    /* NULL key */
    ExpectNull(dupKey = wolfSSL_EC_KEY_dup(NULL));
    /* NULL ecc_key */
    if (ecKey != NULL) {
        wc_ecc_free((ecc_key*)ecKey->internal);
        XFREE(ecKey->internal, NULL, DYNAMIC_TYPE_ECC);
        ecKey->internal = NULL; /* Set ecc_key to NULL */
    }
    ExpectNull(dupKey = wolfSSL_EC_KEY_dup(ecKey));
    wolfSSL_EC_KEY_free(ecKey);
    ecKey = NULL;
    wolfSSL_EC_KEY_free(dupKey);
    dupKey = NULL;

    /* NULL Group */
    ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1);
    if (ecKey != NULL) {
        wolfSSL_EC_GROUP_free(ecKey->group);
        ecKey->group = NULL; /* Set group to NULL */
    }
    ExpectNull(dupKey = wolfSSL_EC_KEY_dup(ecKey));
    wolfSSL_EC_KEY_free(ecKey);
    ecKey = NULL;
    wolfSSL_EC_KEY_free(dupKey);
    dupKey = NULL;

    /* NULL public key */
    ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1);
    if (ecKey != NULL) {
        wc_ecc_del_point((ecc_point*)ecKey->pub_key->internal);
        ecKey->pub_key->internal = NULL; /* Set ecc_point to NULL */
    }

    ExpectNull(dupKey = wolfSSL_EC_KEY_dup(ecKey));
    if (ecKey != NULL) {
        wolfSSL_EC_POINT_free(ecKey->pub_key);
        ecKey->pub_key = NULL; /* Set pub_key to NULL */
    }
    ExpectNull(dupKey = wolfSSL_EC_KEY_dup(ecKey));
    wolfSSL_EC_KEY_free(ecKey);
    ecKey = NULL;
    wolfSSL_EC_KEY_free(dupKey);
    dupKey = NULL;

    /* NULL private key */
    ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1);

    if (ecKey != NULL) {
        wolfSSL_BN_free(ecKey->priv_key);
        ecKey->priv_key = NULL; /* Set priv_key to NULL */
    }
    ExpectNull(dupKey = wolfSSL_EC_KEY_dup(ecKey));

    wolfSSL_EC_KEY_free(ecKey);
    ecKey = NULL;
    wolfSSL_EC_KEY_free(dupKey);
    dupKey = NULL;

    /* Test EC_KEY_up_ref */
    ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EC_KEY_up_ref(NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_EC_KEY_up_ref(ecKey), WOLFSSL_SUCCESS);
    /* reference count doesn't follow duplicate */
    ExpectNotNull(dupKey = wolfSSL_EC_KEY_dup(ecKey));
    ExpectIntEQ(wolfSSL_EC_KEY_up_ref(dupKey), WOLFSSL_SUCCESS); /* +1 */
    ExpectIntEQ(wolfSSL_EC_KEY_up_ref(dupKey), WOLFSSL_SUCCESS); /* +2 */
    wolfSSL_EC_KEY_free(dupKey); /* 3 */
    wolfSSL_EC_KEY_free(dupKey); /* 2 */
    wolfSSL_EC_KEY_free(dupKey); /* 1, free */
    wolfSSL_EC_KEY_free(ecKey);  /* 2 */
    wolfSSL_EC_KEY_free(ecKey);  /* 1, free */
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_KEY_set_group(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(NO_ECC256) && !defined(NO_ECC_SECP) && \
    defined(OPENSSL_EXTRA)
    EC_KEY   *key    = NULL;
    EC_GROUP *group  = NULL;
    const EC_GROUP *group2 = NULL;

    ExpectNotNull(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
    ExpectNotNull(key = EC_KEY_new());

    ExpectNull(EC_KEY_get0_group(NULL));
    ExpectIntEQ(EC_KEY_set_group(NULL, NULL), 0);
    ExpectIntEQ(EC_KEY_set_group(key, NULL), 0);
    ExpectIntEQ(EC_KEY_set_group(NULL, group), 0);

    ExpectIntEQ(EC_KEY_set_group(key, group), WOLFSSL_SUCCESS);
    ExpectNotNull(group2 = EC_KEY_get0_group(key));
    ExpectIntEQ(EC_GROUP_cmp(group2, group, NULL), 0);

    EC_GROUP_free(group);
    EC_KEY_free(key);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_KEY_set_conv_form(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && defined(OPENSSL_EXTRA) && !defined(NO_BIO)
    BIO* bio = NULL;
    EC_KEY* key = NULL;

    /* Error condition: NULL key. */
    ExpectIntLT(EC_KEY_get_conv_form(NULL), 0);

    ExpectNotNull(bio = BIO_new_file("./certs/ecc-keyPub.pem", "rb"));
    ExpectNotNull(key = PEM_read_bio_EC_PUBKEY(bio, NULL, NULL, NULL));
    /* Conversion form defaults to uncompressed. */
    ExpectIntEQ(EC_KEY_get_conv_form(key), POINT_CONVERSION_UNCOMPRESSED);
#ifdef HAVE_COMP_KEY
    /* Explicitly set to compressed. */
    EC_KEY_set_conv_form(key, POINT_CONVERSION_COMPRESSED);
    ExpectIntEQ(EC_KEY_get_conv_form(key), POINT_CONVERSION_COMPRESSED);
#else
    /* Will still work just won't change anything. */
    EC_KEY_set_conv_form(key, POINT_CONVERSION_COMPRESSED);
    ExpectIntEQ(EC_KEY_get_conv_form(key), POINT_CONVERSION_UNCOMPRESSED);
    EC_KEY_set_conv_form(key, POINT_CONVERSION_UNCOMPRESSED);
    ExpectIntEQ(EC_KEY_get_conv_form(key), POINT_CONVERSION_UNCOMPRESSED);
#endif
    EC_KEY_set_conv_form(NULL, POINT_CONVERSION_UNCOMPRESSED);

    BIO_free(bio);
    EC_KEY_free(key);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_KEY_private_key(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_BIO)
    WOLFSSL_EC_KEY* key = NULL;
    WOLFSSL_BIGNUM* priv = NULL;
    WOLFSSL_BIGNUM* priv2 = NULL;
    WOLFSSL_BIGNUM* bn;

    ExpectNotNull(key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
    ExpectNotNull(priv = wolfSSL_BN_new());
    ExpectNotNull(priv2 = wolfSSL_BN_new());
    ExpectIntNE(BN_set_word(priv, 2), 0);
    ExpectIntNE(BN_set_word(priv2, 2), 0);

    ExpectNull(wolfSSL_EC_KEY_get0_private_key(NULL));
    /* No private key set. */
    ExpectNull(wolfSSL_EC_KEY_get0_private_key(key));

    ExpectIntEQ(wolfSSL_EC_KEY_set_private_key(NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_EC_KEY_set_private_key(key, NULL), 0);
    ExpectIntEQ(wolfSSL_EC_KEY_set_private_key(NULL, priv), 0);

    ExpectIntEQ(wolfSSL_EC_KEY_set_private_key(key, priv), 1);
    ExpectNotNull(bn = wolfSSL_EC_KEY_get0_private_key(key));
    ExpectPtrNE(bn, priv);
    ExpectIntEQ(wolfSSL_EC_KEY_set_private_key(key, priv2), 1);
    ExpectNotNull(bn = wolfSSL_EC_KEY_get0_private_key(key));
    ExpectPtrNE(bn, priv2);

    wolfSSL_BN_free(priv2);
    wolfSSL_BN_free(priv);
    wolfSSL_EC_KEY_free(key);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_KEY_public_key(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_BIO)
    WOLFSSL_EC_KEY* key = NULL;
    WOLFSSL_EC_POINT* pub = NULL;
    WOLFSSL_EC_POINT* point = NULL;

    ExpectNotNull(key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));

    ExpectNull(wolfSSL_EC_KEY_get0_public_key(NULL));
    ExpectNotNull(wolfSSL_EC_KEY_get0_public_key(key));

    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(key), 1);

    ExpectNotNull(pub = wolfSSL_EC_KEY_get0_public_key(key));

    ExpectIntEQ(wolfSSL_EC_KEY_set_public_key(NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_EC_KEY_set_public_key(key, NULL), 0);
    ExpectIntEQ(wolfSSL_EC_KEY_set_public_key(NULL, pub), 0);

    ExpectIntEQ(wolfSSL_EC_KEY_set_public_key(key, pub), 1);
    ExpectNotNull(point = wolfSSL_EC_KEY_get0_public_key(key));
    ExpectPtrEq(point, pub);

    wolfSSL_EC_KEY_free(key);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_KEY_print_fp(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && ((defined(HAVE_ECC224) && defined(HAVE_ECC256)) || \
    defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224 && \
    defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
    !defined(NO_STDIO_FILESYSTEM)
    EC_KEY* key = NULL;

    /* Bad file pointer. */
    ExpectIntEQ(wolfSSL_EC_KEY_print_fp(NULL, key, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* NULL key. */
    ExpectIntEQ(wolfSSL_EC_KEY_print_fp(stderr, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectNotNull((key = wolfSSL_EC_KEY_new_by_curve_name(NID_secp224r1)));
    /* Negative indent. */
    ExpectIntEQ(wolfSSL_EC_KEY_print_fp(stderr, key, -1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    ExpectIntEQ(wolfSSL_EC_KEY_print_fp(stderr, key, 4), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(key), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EC_KEY_print_fp(stderr, key, 4), WOLFSSL_SUCCESS);
    wolfSSL_EC_KEY_free(key);

    ExpectNotNull((key = wolfSSL_EC_KEY_new_by_curve_name(
        NID_X9_62_prime256v1)));
    ExpectIntEQ(wolfSSL_EC_KEY_generate_key(key), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_EC_KEY_print_fp(stderr, key, 4), WOLFSSL_SUCCESS);
    wolfSSL_EC_KEY_free(key);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_EC_get_builtin_curves(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
    EC_builtin_curve* curves = NULL;
    size_t crv_len = 0;
    size_t i = 0;

    ExpectIntGT((crv_len = EC_get_builtin_curves(NULL, 0)), 0);
    ExpectNotNull(curves = (EC_builtin_curve*)XMALLOC(
        sizeof(EC_builtin_curve) * crv_len, NULL, DYNAMIC_TYPE_TMP_BUFFER));

    ExpectIntEQ((EC_get_builtin_curves(curves, 0)), crv_len);
    ExpectIntEQ(EC_get_builtin_curves(curves, crv_len), crv_len);

    for (i = 0; EXPECT_SUCCESS() && (i < crv_len); i++) {
        if (curves[i].comment != NULL) {
            ExpectStrEQ(OBJ_nid2sn(curves[i].nid), curves[i].comment);
        }
    }

    if (crv_len > 1) {
        ExpectIntEQ(EC_get_builtin_curves(curves, crv_len - 1), crv_len - 1);
    }

    XFREE(curves, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
    return EXPECT_RESULT();
}

static int test_wolfSSL_ECDSA_SIG(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
    WOLFSSL_ECDSA_SIG* sig = NULL;
    WOLFSSL_ECDSA_SIG* sig2 = NULL;
    WOLFSSL_BIGNUM* r = NULL;
    WOLFSSL_BIGNUM* s = NULL;
    const WOLFSSL_BIGNUM* r2 = NULL;
    const WOLFSSL_BIGNUM* s2 = NULL;
    const unsigned char* cp = NULL;
    unsigned char* p = NULL;
    unsigned char outSig[8];
    unsigned char sigData[8] =
                             { 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01 };
    unsigned char sigDataBad[8] =
                             { 0x30, 0x07, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01 };

    wolfSSL_ECDSA_SIG_free(NULL);

    ExpectNotNull(sig = wolfSSL_ECDSA_SIG_new());
    ExpectNotNull(r = wolfSSL_BN_new());
    ExpectNotNull(s = wolfSSL_BN_new());
    ExpectIntEQ(wolfSSL_BN_set_word(r, 1), 1);
    ExpectIntEQ(wolfSSL_BN_set_word(s, 1), 1);

    wolfSSL_ECDSA_SIG_get0(NULL, NULL, NULL);
    wolfSSL_ECDSA_SIG_get0(NULL, &r2, NULL);
    wolfSSL_ECDSA_SIG_get0(NULL, NULL, &s2);
    wolfSSL_ECDSA_SIG_get0(NULL, &r2, &s2);
    ExpectIntEQ(wolfSSL_ECDSA_SIG_set0(NULL, NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_ECDSA_SIG_set0(sig, NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_ECDSA_SIG_set0(NULL, r, NULL), 0);
    ExpectIntEQ(wolfSSL_ECDSA_SIG_set0(NULL, NULL, s), 0);
    ExpectIntEQ(wolfSSL_ECDSA_SIG_set0(NULL, r, s), 0);
    ExpectIntEQ(wolfSSL_ECDSA_SIG_set0(sig, NULL, s), 0);
    ExpectIntEQ(wolfSSL_ECDSA_SIG_set0(sig, r, NULL), 0);

    r2 = NULL;
    s2 = NULL;
    wolfSSL_ECDSA_SIG_get0(NULL, &r2, &s2);
    ExpectNull(r2);
    ExpectNull(s2);
    ExpectIntEQ(wolfSSL_ECDSA_SIG_set0(sig, r, s), 1);
    if (EXPECT_FAIL()) {
        wolfSSL_BN_free(r);
        wolfSSL_BN_free(s);
    }
    wolfSSL_ECDSA_SIG_get0(sig, &r2, &s2);
    ExpectPtrEq(r2, r);
    ExpectPtrEq(s2, s);
    r2 = NULL;
    wolfSSL_ECDSA_SIG_get0(sig, &r2, NULL);
    ExpectPtrEq(r2, r);
    s2 = NULL;
    wolfSSL_ECDSA_SIG_get0(sig, NULL, &s2);
    ExpectPtrEq(s2, s);

    /* r and s are freed when sig is freed. */
    wolfSSL_ECDSA_SIG_free(sig);
    sig = NULL;

    ExpectNull(wolfSSL_d2i_ECDSA_SIG(NULL, NULL, sizeof(sigData)));
    cp = sigDataBad;
    ExpectNull(wolfSSL_d2i_ECDSA_SIG(NULL, &cp, sizeof(sigDataBad)));
    cp = sigData;
    ExpectNotNull((sig = wolfSSL_d2i_ECDSA_SIG(NULL, &cp, sizeof(sigData))));
    ExpectIntEQ((cp == sigData + 8), 1);
    cp = sigData;
    ExpectNull(wolfSSL_d2i_ECDSA_SIG(&sig, NULL, sizeof(sigData)));
    ExpectNotNull((sig2 = wolfSSL_d2i_ECDSA_SIG(&sig, &cp, sizeof(sigData))));
    ExpectIntEQ((sig == sig2), 1);
    cp = outSig;

    p = outSig;
    ExpectIntEQ(wolfSSL_i2d_ECDSA_SIG(NULL, &p), 0);
    ExpectIntEQ(wolfSSL_i2d_ECDSA_SIG(NULL, NULL), 0);
    ExpectIntEQ(wolfSSL_i2d_ECDSA_SIG(sig, NULL), 8);
    ExpectIntEQ(wolfSSL_i2d_ECDSA_SIG(sig, &p), sizeof(sigData));
    ExpectIntEQ((p == outSig + 8), 1);
    ExpectIntEQ(XMEMCMP(sigData, outSig, 8), 0);

    p = NULL;
    ExpectIntEQ(wolfSSL_i2d_ECDSA_SIG(sig, &p), 8);
#ifndef WOLFSSL_I2D_ECDSA_SIG_ALLOC
    ExpectNull(p);
#else
    ExpectNotNull(p);
    ExpectIntEQ(XMEMCMP(p, outSig, 8), 0);
    XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
#endif

    wolfSSL_ECDSA_SIG_free(sig);
#endif
    return EXPECT_RESULT();
}

static int test_ECDSA_size_sign(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ECC256) && !defined(NO_ECC_SECP)
    EC_KEY* key = NULL;
    ECDSA_SIG* ecdsaSig = NULL;
    int id;
    byte hash[WC_MAX_DIGEST_SIZE];
    byte hash2[WC_MAX_DIGEST_SIZE];
    byte sig[ECC_MAX_SIG_SIZE];
    unsigned int sigSz = sizeof(sig);

    XMEMSET(hash, 123, sizeof(hash));
    XMEMSET(hash2, 234, sizeof(hash2));

    id = wc_ecc_get_curve_id_from_name("SECP256R1");
    ExpectIntEQ(id, ECC_SECP256R1);

    ExpectNotNull(key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
    ExpectIntEQ(EC_KEY_generate_key(key), 1);

    ExpectIntGE(ECDSA_size(NULL), 0);

    ExpectIntEQ(ECDSA_sign(0, hash, sizeof(hash), sig, &sigSz, NULL), 0);
    ExpectIntEQ(ECDSA_sign(0, NULL, sizeof(hash), sig, &sigSz, key), 0);
    ExpectIntEQ(ECDSA_sign(0, hash, sizeof(hash), NULL, &sigSz, key), 0);
    ExpectIntEQ(ECDSA_verify(0, hash, sizeof(hash), sig, (int)sigSz, NULL), 0);
    ExpectIntEQ(ECDSA_verify(0, NULL, sizeof(hash), sig, (int)sigSz, key), 0);
    ExpectIntEQ(ECDSA_verify(0, hash, sizeof(hash), NULL, (int)sigSz, key), 0);

    ExpectIntEQ(ECDSA_sign(0, hash, sizeof(hash), sig, &sigSz, key), 1);
    ExpectIntGE(ECDSA_size(key), sigSz);
    ExpectIntEQ(ECDSA_verify(0, hash, sizeof(hash), sig, (int)sigSz, key), 1);
    ExpectIntEQ(ECDSA_verify(0, hash2, sizeof(hash2), sig, (int)sigSz, key), 0);

    ExpectNull(ECDSA_do_sign(NULL, sizeof(hash), NULL));
    ExpectNull(ECDSA_do_sign(NULL, sizeof(hash), key));
    ExpectNull(ECDSA_do_sign(hash, sizeof(hash), NULL));
    ExpectNotNull(ecdsaSig = ECDSA_do_sign(hash, sizeof(hash), key));
    ExpectIntEQ(ECDSA_do_verify(NULL, sizeof(hash), NULL, NULL), -1);
    ExpectIntEQ(ECDSA_do_verify(hash, sizeof(hash), NULL, NULL), -1);
    ExpectIntEQ(ECDSA_do_verify(NULL, sizeof(hash), ecdsaSig, NULL), -1);
    ExpectIntEQ(ECDSA_do_verify(NULL, sizeof(hash), NULL, key), -1);
    ExpectIntEQ(ECDSA_do_verify(NULL, sizeof(hash), ecdsaSig, key), -1);
    ExpectIntEQ(ECDSA_do_verify(hash, sizeof(hash), NULL, key), -1);
    ExpectIntEQ(ECDSA_do_verify(hash, sizeof(hash), ecdsaSig, NULL), -1);
    ExpectIntEQ(ECDSA_do_verify(hash, sizeof(hash), ecdsaSig, key), 1);
    ExpectIntEQ(ECDSA_do_verify(hash2, sizeof(hash2), ecdsaSig, key), 0);
    ECDSA_SIG_free(ecdsaSig);

    EC_KEY_free(key);
#endif /* OPENSSL_EXTRA && !NO_ECC256 && !NO_ECC_SECP */
    return EXPECT_RESULT();
}

static int test_ECDH_compute_key(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ECC256) && !defined(NO_ECC_SECP) && \
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
    EC_KEY* key1 = NULL;
    EC_KEY* key2 = NULL;
    EC_POINT* pub1 = NULL;
    EC_POINT* pub2 = NULL;
    byte secret1[32];
    byte secret2[32];
    int i;

    ExpectNotNull(key1 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
    ExpectIntEQ(EC_KEY_generate_key(key1), 1);
    ExpectNotNull(pub1 = wolfSSL_EC_KEY_get0_public_key(key1));
    ExpectNotNull(key2 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
    ExpectIntEQ(EC_KEY_generate_key(key2), 1);
    ExpectNotNull(pub2 = wolfSSL_EC_KEY_get0_public_key(key2));

    ExpectIntEQ(ECDH_compute_key(NULL, sizeof(secret1), NULL, NULL, NULL), 0);
    ExpectIntEQ(ECDH_compute_key(secret1, sizeof(secret1), NULL, NULL, NULL),
        0);
    ExpectIntEQ(ECDH_compute_key(NULL, sizeof(secret1), pub2, NULL, NULL), 0);
    ExpectIntEQ(ECDH_compute_key(NULL, sizeof(secret1), NULL, key1, NULL), 0);
    ExpectIntEQ(ECDH_compute_key(NULL, sizeof(secret1), pub2, key1, NULL), 0);
    ExpectIntEQ(ECDH_compute_key(secret1, sizeof(secret1), NULL, key1, NULL),
        0);
    ExpectIntEQ(ECDH_compute_key(secret1, sizeof(secret1), pub2, NULL, NULL),
        0);

    ExpectIntEQ(ECDH_compute_key(secret1, sizeof(secret1) - 16, pub2, key1,
        NULL), 0);

    ExpectIntEQ(ECDH_compute_key(secret1, sizeof(secret1), pub2, key1, NULL),
        sizeof(secret1));
    ExpectIntEQ(ECDH_compute_key(secret2, sizeof(secret2), pub1, key2, NULL),
        sizeof(secret2));

    for (i = 0; i < (int)sizeof(secret1); i++) {
        ExpectIntEQ(secret1[i], secret2[i]);
    }

    EC_KEY_free(key2);
    EC_KEY_free(key1);
#endif /* OPENSSL_EXTRA && !NO_ECC256 && !NO_ECC_SECP &&
        * !WOLF_CRYPTO_CB_ONLY_ECC */
    return EXPECT_RESULT();
}

#endif /* HAVE_ECC && !OPENSSL_NO_PK */

#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
    !defined(NO_ASN_TIME)
static int test_openssl_make_self_signed_certificate(EVP_PKEY* pkey,
        int expectedDerSz)
{
    EXPECT_DECLS;
    X509* x509 = NULL;
    BIGNUM* serial_number = NULL;
    X509_NAME* name = NULL;
    time_t epoch_off = 0;
    ASN1_INTEGER* asn1_serial_number = NULL;
    long not_before, not_after;
    int derSz;

    ExpectNotNull(x509 = X509_new());

    ExpectIntNE(X509_set_pubkey(x509, pkey), 0);

    ExpectNotNull(serial_number = BN_new());
    ExpectIntNE(BN_pseudo_rand(serial_number, 64, 0, 0), 0);
    ExpectNotNull(asn1_serial_number = X509_get_serialNumber(x509));
    ExpectNotNull(BN_to_ASN1_INTEGER(serial_number, asn1_serial_number));

    /* version 3 */
    ExpectIntNE(X509_set_version(x509, 2L), 0);

    ExpectNotNull(name = X509_NAME_new());

    ExpectIntNE(X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8,
        (unsigned char*)"www.wolfssl.com", -1, -1, 0), 0);
    ExpectIntNE(X509_NAME_add_entry_by_NID(name, NID_pkcs9_contentType,
                MBSTRING_UTF8,(unsigned char*)"Server", -1, -1, 0), 0);

    ExpectIntNE(X509_set_subject_name(x509, name), 0);
    ExpectIntNE(X509_set_issuer_name(x509, name), 0);

    not_before = (long)wc_Time(NULL);
    not_after = not_before + (365 * 24 * 60 * 60);
    ExpectNotNull(X509_time_adj(X509_get_notBefore(x509), not_before,
        &epoch_off));
    ExpectNotNull(X509_time_adj(X509_get_notAfter(x509), not_after,
        &epoch_off));

    ExpectIntNE(X509_sign(x509, pkey, EVP_sha256()), 0);

    ExpectNotNull(wolfSSL_X509_get_der(x509, &derSz));
    ExpectIntGE(derSz, expectedDerSz);

    BN_free(serial_number);
    X509_NAME_free(name);
    X509_free(x509);

    return EXPECT_RESULT();
}
#endif

static int test_openssl_generate_key_and_cert(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    int expectedDerSz;
    EVP_PKEY* pkey = NULL;
#ifdef HAVE_ECC
    EC_KEY* ec_key = NULL;
#endif
#if !defined(NO_RSA)
    int key_length = 2048;
    BIGNUM* exponent = NULL;
    RSA* rsa = NULL;

    ExpectNotNull(pkey = EVP_PKEY_new());
    ExpectNotNull(exponent = BN_new());
    ExpectNotNull(rsa = RSA_new());

    ExpectIntNE(BN_set_word(exponent, WC_RSA_EXPONENT), 0);
#ifndef WOLFSSL_KEY_GEN
    ExpectIntEQ(RSA_generate_key_ex(rsa, key_length, exponent, NULL), 0);

    #if defined(USE_CERT_BUFFERS_1024)
    ExpectIntNE(wolfSSL_RSA_LoadDer_ex(rsa, server_key_der_1024,
        sizeof_server_key_der_1024, WOLFSSL_RSA_LOAD_PRIVATE), 0);
    key_length = 1024;
    #elif defined(USE_CERT_BUFFERS_2048)
    ExpectIntNE(wolfSSL_RSA_LoadDer_ex(rsa, server_key_der_2048,
        sizeof_server_key_der_2048, WOLFSSL_RSA_LOAD_PRIVATE), 0);
    #else
    RSA_free(rsa);
    rsa = NULL;
    #endif
#else
    ExpectIntEQ(RSA_generate_key_ex(NULL, key_length, exponent, NULL), 0);
    ExpectIntEQ(RSA_generate_key_ex(rsa, 0, exponent, NULL), 0);
    ExpectIntEQ(RSA_generate_key_ex(rsa, key_length, NULL, NULL), 0);
    ExpectIntNE(RSA_generate_key_ex(rsa, key_length, exponent, NULL), 0);
#endif

    if (rsa) {
        ExpectIntNE(EVP_PKEY_assign_RSA(pkey, rsa), 0);
        if (EXPECT_FAIL()) {
            RSA_free(rsa);
        }

    #if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && \
            defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME)
        expectedDerSz = 743;
        ExpectIntEQ(test_openssl_make_self_signed_certificate(pkey,
                    expectedDerSz), TEST_SUCCESS);
    #endif
    }

    EVP_PKEY_free(pkey);
    pkey = NULL;
    BN_free(exponent);
#endif /* !NO_RSA */

#ifdef HAVE_ECC
    ExpectNotNull(pkey = EVP_PKEY_new());
    ExpectNotNull(ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));

#ifndef NO_WOLFSSL_STUB
    EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE);
#endif

    ExpectIntNE(EC_KEY_generate_key(ec_key), 0);
    ExpectIntNE(EVP_PKEY_assign_EC_KEY(pkey, ec_key), 0);
    if (EXPECT_FAIL()) {
        EC_KEY_free(ec_key);
    }

#if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && \
        defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME)
    expectedDerSz = 344;
    ExpectIntEQ(test_openssl_make_self_signed_certificate(pkey, expectedDerSz),
                TEST_SUCCESS);
#endif

    EVP_PKEY_free(pkey);
#endif /* HAVE_ECC */
    (void)pkey;
    (void)expectedDerSz;
#endif /* OPENSSL_EXTRA */

    return EXPECT_RESULT();
}

static int test_stubs_are_stubs(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_WOLFSSL_STUB) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL_CTX* ctxN = NULL;
  #ifndef NO_WOLFSSL_CLIENT
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
  #elif !defined(NO_WOLFSSL_SERVER)
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
  #endif

    #define CHECKZERO_RET(x, y, z) ExpectIntEQ((int) x(y), 0); \
                     ExpectIntEQ((int) x(z), 0)
    /* test logic, all stubs return same result regardless of ctx being NULL
     * as there are no sanity checks, it's just a stub! If at some
     * point a stub is not a stub it should begin to return BAD_FUNC_ARG
     * if invalid inputs are supplied. Test calling both
     * with and without valid inputs, if a stub functionality remains unchanged.
     */
    CHECKZERO_RET(wolfSSL_CTX_sess_accept, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_connect, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_accept_good, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_connect_good, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_accept_renegotiate, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_connect_renegotiate, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_hits, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_cb_hits, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_cache_full, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_misses, ctx, ctxN);
    CHECKZERO_RET(wolfSSL_CTX_sess_timeouts, ctx, ctxN);

    /* when implemented this should take WOLFSSL object instead, right now
     * always returns 0 */
    ExpectPtrEq(SSL_get_current_expansion(NULL), NULL);

    wolfSSL_CTX_free(ctx);
    ctx = NULL;

    ExpectStrEQ(SSL_COMP_get_name(NULL), "not supported");
    ExpectPtrEq(SSL_get_current_expansion(NULL), NULL);
#endif /* OPENSSL_EXTRA && !NO_WOLFSSL_STUB && (!NO_WOLFSSL_CLIENT ||
        * !NO_WOLFSSL_SERVER) */
    return EXPECT_RESULT();
}

static int test_CONF_modules_xxx(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA)
    CONF_modules_free();

    CONF_modules_unload(0);
    CONF_modules_unload(1);
    CONF_modules_unload(-1);

    res = TEST_SUCCESS;
#endif /* OPENSSL_EXTRA */
    return res;
}
static int test_CRYPTO_set_dynlock_xxx(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA)
    CRYPTO_set_dynlock_create_callback(
        (struct CRYPTO_dynlock_value *(*)(const char*, int))NULL);

    CRYPTO_set_dynlock_create_callback(
        (struct CRYPTO_dynlock_value *(*)(const char*, int))1);

    CRYPTO_set_dynlock_destroy_callback(
        (void (*)(struct CRYPTO_dynlock_value*, const char*, int))NULL);

    CRYPTO_set_dynlock_destroy_callback(
        (void (*)(struct CRYPTO_dynlock_value*, const char*, int))1);

    CRYPTO_set_dynlock_lock_callback(
        (void (*)(int, struct CRYPTO_dynlock_value *, const char*, int))NULL);

    CRYPTO_set_dynlock_lock_callback(
        (void (*)(int, struct CRYPTO_dynlock_value *, const char*, int))1);

    res = TEST_SUCCESS;
#endif /* OPENSSL_EXTRA */
    return res;
}
static int test_CRYPTO_THREADID_xxx(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    CRYPTO_THREADID_current((CRYPTO_THREADID*)NULL);
    CRYPTO_THREADID_current((CRYPTO_THREADID*)1);
    ExpectIntEQ(CRYPTO_THREADID_hash((const CRYPTO_THREADID*)NULL), 0);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}
static int test_ENGINE_cleanup(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA)
    ENGINE_cleanup();

    res = TEST_SUCCESS;
#endif /* OPENSSL_EXTRA */
    return res;
}

static int test_wolfSSL_CTX_LoadCRL(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CRL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \
    (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL* ssl = NULL;
    const char* badPath = "dummypath";
    const char* validPath = "./certs/crl";
    const char* validFilePath = "./certs/crl/cliCrl.pem";
    const char* issuerCert = "./certs/client-cert.pem";
    int derType = WOLFSSL_FILETYPE_ASN1;
    int pemType = WOLFSSL_FILETYPE_PEM;
#ifdef HAVE_CRL_MONITOR
    int monitor = WOLFSSL_CRL_MONITOR;
#else
    int monitor = 0;
#endif
    WOLFSSL_CERT_MANAGER* cm = NULL;

    #define FAIL_T1(x, y, z, p, d) ExpectIntEQ((int) x(y, z, p, d), \
                                       WC_NO_ERR_TRACE(BAD_FUNC_ARG))
    #define FAIL_T2(x, y, z, p, d) ExpectIntEQ((int) x(y, z, p, d), \
                                    WC_NO_ERR_TRACE(NOT_COMPILED_IN))
    #define SUCC_T(x, y, z, p, d) ExpectIntEQ((int) x(y, z, p, d), \
                                                WOLFSSL_SUCCESS)
#ifndef NO_WOLFSSL_CLIENT
    #define NEW_CTX(ctx) ExpectNotNull( \
            (ctx) = wolfSSL_CTX_new(wolfSSLv23_client_method()))
#elif !defined(NO_WOLFSSL_SERVER)
    #define NEW_CTX(ctx) ExpectNotNull( \
            (ctx) = wolfSSL_CTX_new(wolfSSLv23_server_method()))
#else
    #define NEW_CTX(ctx) return
#endif

    FAIL_T1(wolfSSL_CTX_LoadCRL, ctx, validPath, pemType, monitor);

    NEW_CTX(ctx);

#ifndef HAVE_CRL_MONITOR
    FAIL_T2(wolfSSL_CTX_LoadCRL, ctx, validPath, pemType, WOLFSSL_CRL_MONITOR);
    wolfSSL_CTX_free(ctx);
    NEW_CTX(ctx);
#endif

    SUCC_T (wolfSSL_CTX_LoadCRL, ctx, validPath, pemType, monitor);
    SUCC_T (wolfSSL_CTX_LoadCRL, ctx, badPath, pemType, monitor);
    SUCC_T (wolfSSL_CTX_LoadCRL, ctx, badPath, derType, monitor);

    wolfSSL_CTX_free(ctx);
    ctx = NULL;

    NEW_CTX(ctx);
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, issuerCert, NULL),
            WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx, validFilePath, pemType), WOLFSSL_SUCCESS);
    wolfSSL_CTX_free(ctx);
    ctx = NULL;

    NEW_CTX(ctx);
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, issuerCert, NULL),
            WOLFSSL_SUCCESS);
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    ExpectIntEQ(wolfSSL_LoadCRLFile(ssl, validFilePath, pemType), WOLFSSL_SUCCESS);
    wolfSSL_free(ssl);
    ssl = NULL;
    wolfSSL_CTX_free(ctx);
    ctx = NULL;

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, issuerCert, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, validFilePath, pemType),
        WOLFSSL_SUCCESS);
    wolfSSL_CertManagerFree(cm);
#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_CRL) && \
    !defined(WOLFSSL_CRL_ALLOW_MISSING_CDP)
static int test_multiple_crls_same_issuer_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
    ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx, "./certs/crl/crl.pem",
        WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}
#endif

static int test_multiple_crls_same_issuer(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_CRL) && \
    !defined(WOLFSSL_CRL_ALLOW_MISSING_CDP)
    test_ssl_cbf client_cbs, server_cbs;
    struct {
        const char* server_cert;
        const char* server_key;
    } test_params[] = {
        { "./certs/server-cert.pem", "./certs/server-key.pem" },
        { "./certs/server-revoked-cert.pem", "./certs/server-revoked-key.pem" }
    };
    size_t i;

    for (i = 0; i < (sizeof(test_params)/sizeof(*test_params)); i++) {
        XMEMSET(&client_cbs, 0, sizeof(client_cbs));
        XMEMSET(&server_cbs, 0, sizeof(server_cbs));

        server_cbs.certPemFile = test_params[i].server_cert;
        server_cbs.keyPemFile = test_params[i].server_key;
        client_cbs.crlPemFile = "./certs/crl/extra-crls/general-server-crl.pem";

        client_cbs.ctx_ready = test_multiple_crls_same_issuer_ctx_ready;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
            &server_cbs, NULL), -1001);
    }
#endif
    return EXPECT_RESULT();
}

static int test_SetTmpEC_DHE_Sz(void)
{
    EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(NO_WOLFSSL_CLIENT)
    WOLFSSL_CTX *ctx = NULL;
    WOLFSSL *ssl = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpEC_DHE_Sz(ctx, 32));
    ExpectNotNull(ssl = wolfSSL_new(ctx));
    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpEC_DHE_Sz(ssl, 32));

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_get0_privatekey(void)
{
    EXPECT_DECLS;
#ifdef OPENSSL_ALL
    WOLFSSL_CTX* ctx = NULL;

    (void)ctx;

#ifndef NO_RSA
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
    ExpectNull(SSL_CTX_get0_privatekey(ctx));
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
                                                WOLFSSL_FILETYPE_PEM));
    ExpectNull(SSL_CTX_get0_privatekey(ctx));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
                                               WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(SSL_CTX_get0_privatekey(ctx));
    wolfSSL_CTX_free(ctx);
    ctx = NULL;
#endif
#ifdef HAVE_ECC
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
    ExpectNull(SSL_CTX_get0_privatekey(ctx));
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCertFile,
                                                WOLFSSL_FILETYPE_PEM));
    ExpectNull(SSL_CTX_get0_privatekey(ctx));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile,
                                               WOLFSSL_FILETYPE_PEM));
    ExpectNotNull(SSL_CTX_get0_privatekey(ctx));
    wolfSSL_CTX_free(ctx);
#endif
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_dtls_set_mtu(void)
{
    EXPECT_DECLS;
#if (defined(WOLFSSL_DTLS_MTU) || defined(WOLFSSL_SCTP)) && \
    !defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_DTLS) && \
    !defined(WOLFSSL_NO_TLS12)
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;
    const char* testCertFile;
    const char* testKeyFile;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()));
#ifndef NO_RSA
        testCertFile = svrCertFile;
        testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
        testCertFile = eccCertFile;
        testKeyFile = eccKeyFile;
#endif
    if  (testCertFile != NULL && testKeyFile != NULL) {
        ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
                                                    WOLFSSL_FILETYPE_PEM));
        ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
                                                   WOLFSSL_FILETYPE_PEM));
    }
    ExpectNotNull(ssl = wolfSSL_new(ctx));

    ExpectIntEQ(wolfSSL_CTX_dtls_set_mtu(NULL, 1488), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_dtls_set_mtu(NULL, 1488), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_dtls_set_mtu(ctx, 20000), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_dtls_set_mtu(ssl, 20000), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_get_error(ssl, WC_NO_ERR_TRACE(WOLFSSL_FAILURE)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_dtls_set_mtu(ctx, 1488), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_dtls_set_mtu(ssl, 1488), WOLFSSL_SUCCESS);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
#endif

    return EXPECT_RESULT();
}

#if defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(SINGLE_THREADED) && \
    defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12)

static WC_INLINE void generateDTLSMsg(byte* out, int outSz, word32 seq,
        enum HandShakeType hsType, word16 length)
{
    size_t idx = 0;
    byte* l;

    /* record layer */
    /* handshake type */
    out[idx++] = handshake;
    /* protocol version */
    out[idx++] = 0xfe;
    out[idx++] = 0xfd; /* DTLS 1.2 */
    /* epoch 0 */
    XMEMSET(out + idx, 0, 2);
    idx += 2;
    /* sequence number */
    XMEMSET(out + idx, 0, 6);
    c32toa(seq, out + idx + 2);
    idx += 6;
    /* length in BE */
    if (length)
        c16toa(length, out + idx);
    else
        c16toa(outSz - idx - 2, out + idx);
    idx += 2;

    /* handshake layer */
    /* handshake type */
    out[idx++] = (byte)hsType;
    /* length */
    l = out + idx;
    idx += 3;
    /* message seq */
    c16toa(0, out + idx);
    idx += 2;
    /* frag offset */
    c32to24(0, out + idx);
    idx += 3;
    /* frag length */
    c32to24((word32)outSz - (word32)idx - 3, l);
    c32to24((word32)outSz - (word32)idx - 3, out + idx);
    idx += 3;
    XMEMSET(out + idx, 0, outSz - idx);
}

static void test_wolfSSL_dtls_plaintext_server(WOLFSSL* ssl)
{
    byte msg[] = "This is a msg for the client";
    byte reply[40];
    AssertIntGT(wolfSSL_read(ssl, reply, sizeof(reply)),0);
    reply[sizeof(reply) - 1] = '\0';
    fprintf(stderr, "Client message: %s\n", reply);
    AssertIntEQ(wolfSSL_write(ssl, msg, sizeof(msg)), sizeof(msg));
}

static void test_wolfSSL_dtls_plaintext_client(WOLFSSL* ssl)
{
    byte ch[50];
    int fd = wolfSSL_get_fd(ssl);
    byte msg[] = "This is a msg for the server";
    byte reply[40];

    generateDTLSMsg(ch, sizeof(ch), 20, client_hello, 0);
    /* Server should ignore this datagram */
    AssertIntEQ(send(fd, ch, sizeof(ch), 0), sizeof(ch));
    generateDTLSMsg(ch, sizeof(ch), 20, client_hello, 10000);
    /* Server should ignore this datagram */
    AssertIntEQ(send(fd, ch, sizeof(ch), 0), sizeof(ch));

    AssertIntEQ(wolfSSL_write(ssl, msg, sizeof(msg)), sizeof(msg));
    AssertIntGT(wolfSSL_read(ssl, reply, sizeof(reply)),0);
    reply[sizeof(reply) - 1] = '\0';
    fprintf(stderr, "Server response: %s\n", reply);
}

static int test_wolfSSL_dtls_plaintext(void)
{
    callback_functions func_cb_client;
    callback_functions func_cb_server;
    size_t i;
    struct test_params {
        method_provider client_meth;
        method_provider server_meth;
        ssl_callback on_result_server;
        ssl_callback on_result_client;
    } params[] = {
        {wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method,
                test_wolfSSL_dtls_plaintext_server,
                test_wolfSSL_dtls_plaintext_client},
    };

    for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
        XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
        XMEMSET(&func_cb_server, 0, sizeof(callback_functions));

        func_cb_client.doUdp = func_cb_server.doUdp = 1;
        func_cb_server.method = params[i].server_meth;
        func_cb_client.method = params[i].client_meth;
        func_cb_client.on_result = params[i].on_result_client;
        func_cb_server.on_result = params[i].on_result_server;

        test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

        if (!func_cb_client.return_code)
            return TEST_FAIL;
        if (!func_cb_server.return_code)
            return TEST_FAIL;
    }

    return TEST_RES_CHECK(1);
}
#else
static int test_wolfSSL_dtls_plaintext(void) {
    return TEST_SKIPPED;
}
#endif

#if defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(SINGLE_THREADED) && \
    defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12)

static void test_wolfSSL_dtls12_fragments_spammer(WOLFSSL* ssl)
{
    byte b[1100]; /* buffer for the messages to send */
    size_t idx = 0;
    size_t seq_offset = 0;
    size_t msg_offset = 0;
    int i;
    int fd = wolfSSL_get_fd(ssl);
    int ret = wolfSSL_connect_cert(ssl); /* This gets us past the cookie */
    word32 seq_number = 100; /* start high so server definitely reads this */
    word16 msg_number = 50; /* start high so server has to buffer this */
    AssertIntEQ(ret, 1);
    /* Now let's start spamming the peer with fragments it needs to store */
    XMEMSET(b, -1, sizeof(b));

    /* record layer */
    /* handshake type */
    b[idx++] = 22;
    /* protocol version */
    b[idx++] = 0xfe;
    b[idx++] = 0xfd; /* DTLS 1.2 */
    /* epoch 0 */
    XMEMSET(b + idx, 0, 2);
    idx += 2;
    /* sequence number */
    XMEMSET(b + idx, 0, 6);
    seq_offset = idx + 2; /* increment only the low 32 bits */
    idx += 6;
    /* static length in BE */
    c16toa(42, b + idx);
    idx += 2;

    /* handshake layer */
    /* cert type */
    b[idx++] = 11;
    /* length */
    c32to24(1000, b + idx);
    idx += 3;
    /* message seq */
    c16toa(0, b + idx);
    msg_offset = idx;
    idx += 2;
    /* frag offset */
    c32to24(500, b + idx);
    idx += 3;
    /* frag length */
    c32to24(30, b + idx);
    idx += 3;
    (void)idx; /* inhibit clang-analyzer-deadcode.DeadStores */

    for (i = 0; i < DTLS_POOL_SZ * 2 && ret > 0;
            seq_number++, msg_number++, i++) {
        struct timespec delay;
        XMEMSET(&delay, 0, sizeof(delay));
        delay.tv_nsec = 10000000; /* wait 0.01 seconds */
        c32toa(seq_number, b + seq_offset);
        c16toa(msg_number, b + msg_offset);
        ret = (int)send(fd, b, 55, 0);
        nanosleep(&delay, NULL);
    }
}

#ifdef WOLFSSL_DTLS13
static void test_wolfSSL_dtls13_fragments_spammer(WOLFSSL* ssl)
{
    const word16 sendCountMax = 100;
    byte b[150]; /* buffer for the messages to send */
    size_t idx = 0;
    size_t msg_offset = 0;
    int fd = wolfSSL_get_fd(ssl);
    word16 msg_number = 10; /* start high so server has to buffer this */
    int ret = wolfSSL_connect_cert(ssl); /* This gets us past the cookie */
    AssertIntEQ(ret, 1);
    /* Now let's start spamming the peer with fragments it needs to store */
    XMEMSET(b, -1, sizeof(b));

    /* handshake type */
    b[idx++] = 11;
    /* length */
    c32to24(10000, b + idx);
    idx += 3;
    /* message_seq */
    msg_offset = idx;
    idx += 2;
    /* fragment_offset */
    c32to24(5000, b + idx);
    idx += 3;
    /* fragment_length */
    c32to24(100, b + idx);
    idx += 3;
    /* fragment contents */
    idx += 100;

    for (; ret > 0 && msg_number < sendCountMax; msg_number++) {
        byte sendBuf[150];
        int sendSz = sizeof(sendBuf);
        struct timespec delay;
        XMEMSET(&delay, 0, sizeof(delay));
        delay.tv_nsec = 10000000; /* wait 0.01 seconds */
        c16toa(msg_number, b + msg_offset);
        sendSz = BuildTls13Message(ssl, sendBuf, sendSz, b,
            (int)idx, handshake, 0, 0, 0);
        ret = (int)send(fd, sendBuf, (size_t)sendSz, 0);
        nanosleep(&delay, NULL);
    }
}
#endif

static int test_wolfSSL_dtls_fragments(void)
{
    EXPECT_DECLS;
    callback_functions func_cb_client;
    callback_functions func_cb_server;
    size_t i;
    struct test_params {
        method_provider client_meth;
        method_provider server_meth;
        ssl_callback spammer;
    } params[] = {
#if !defined(WOLFSSL_NO_TLS12)
        {wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method,
                test_wolfSSL_dtls12_fragments_spammer},
#endif
#ifdef WOLFSSL_DTLS13
        {wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method,
                test_wolfSSL_dtls13_fragments_spammer},
#endif
    };

    for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
        XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
        XMEMSET(&func_cb_server, 0, sizeof(callback_functions));

        func_cb_client.doUdp = func_cb_server.doUdp = 1;
        func_cb_server.method = params[i].server_meth;
        func_cb_client.method = params[i].client_meth;
        func_cb_client.ssl_ready = params[i].spammer;

        test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

        ExpectFalse(func_cb_client.return_code);
        ExpectFalse(func_cb_server.return_code);

        /* The socket should be closed by the server resulting in a
         * socket error, fatal error or reading a close notify alert */
        if (func_cb_client.last_err != WC_NO_ERR_TRACE(SOCKET_ERROR_E) &&
                func_cb_client.last_err != WOLFSSL_ERROR_ZERO_RETURN &&
                func_cb_client.last_err != WC_NO_ERR_TRACE(FATAL_ERROR)) {
            ExpectIntEQ(func_cb_client.last_err, WC_NO_ERR_TRACE(SOCKET_ERROR_E));
        }
        /* Check the server returned an error indicating the msg buffer
         * was full */
        ExpectIntEQ(func_cb_server.last_err, WC_NO_ERR_TRACE(DTLS_TOO_MANY_FRAGMENTS_E));

        if (EXPECT_FAIL())
            break;
    }

    return EXPECT_RESULT();
}

static void test_wolfSSL_dtls_send_alert(WOLFSSL* ssl)
{
    int fd, ret;
    byte alert_msg[] = {
        0x15, /* alert type */
        0xfe, 0xfd, /* version */
        0x00, 0x00, /* epoch */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* seq number */
        0x00, 0x02, /* length */
        0x02, /* level: fatal */
        0x46 /* protocol version */
    };

    fd = wolfSSL_get_fd(ssl);
    ret = (int)send(fd, alert_msg, sizeof(alert_msg), 0);
    AssertIntGT(ret, 0);
}

static int _test_wolfSSL_ignore_alert_before_cookie(byte version12)
{
    callback_functions client_cbs, server_cbs;

    XMEMSET(&client_cbs, 0, sizeof(client_cbs));
    XMEMSET(&server_cbs, 0, sizeof(server_cbs));
    client_cbs.doUdp = server_cbs.doUdp = 1;
    if (version12) {
#if !defined(WOLFSSL_NO_TLS12)
        client_cbs.method = wolfDTLSv1_2_client_method;
        server_cbs.method = wolfDTLSv1_2_server_method;
#else
        return TEST_SKIPPED;
#endif
    }
    else
    {
#ifdef WOLFSSL_DTLS13
        client_cbs.method = wolfDTLSv1_3_client_method;
        server_cbs.method = wolfDTLSv1_3_server_method;
#else
        return TEST_SKIPPED;
#endif /* WOLFSSL_DTLS13 */
    }

    client_cbs.ssl_ready = test_wolfSSL_dtls_send_alert;
    test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);

    if (!client_cbs.return_code)
        return TEST_FAIL;
    if (!server_cbs.return_code)
        return TEST_FAIL;

    return TEST_SUCCESS;
}

static int test_wolfSSL_ignore_alert_before_cookie(void)
{
    int ret;
    ret =_test_wolfSSL_ignore_alert_before_cookie(0);
    if (ret != 0)
        return ret;
    ret =_test_wolfSSL_ignore_alert_before_cookie(1);
    if (ret != 0)
        return ret;
    return 0;
}

static void test_wolfSSL_send_bad_record(WOLFSSL* ssl)
{
    int ret;
    int fd;

    byte bad_msg[] = {
        0x17, /* app data  */
        0xaa, 0xfd, /* bad version */
        0x00, 0x01, /* epoch 1 */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x55, /* not seen seq number */
        0x00, 0x26, /* length: 38 bytes */
        0xae, 0x30, 0x31, 0xb1, 0xf1, 0xb9, 0x6f, 0xda, 0x17, 0x19, 0xd9, 0x57,
        0xa9, 0x9d, 0x5c, 0x51, 0x9b, 0x53, 0x63, 0xa5, 0x24, 0x70, 0xa1,
        0xae, 0xdf, 0x1c, 0xb9, 0xfc, 0xe3, 0xd7, 0x77, 0x6d, 0xb6, 0x89, 0x0f,
        0x03, 0x18, 0x72
    };

    fd = wolfSSL_get_fd(ssl);
    AssertIntGE(fd, 0);
    ret = (int)send(fd, bad_msg, sizeof(bad_msg), 0);
    AssertIntEQ(ret, sizeof(bad_msg));
    ret = wolfSSL_write(ssl, "badrecordtest", sizeof("badrecordtest"));
    AssertIntEQ(ret, sizeof("badrecordtest"));
}

static void test_wolfSSL_read_string(WOLFSSL* ssl)
{
    byte buf[100];
    int ret;

    ret = wolfSSL_read(ssl, buf, sizeof(buf));
    AssertIntGT(ret, 0);
    AssertIntEQ(strcmp((char*)buf, "badrecordtest"), 0);
}

static int _test_wolfSSL_dtls_bad_record(
    method_provider client_method, method_provider server_method)
{
    callback_functions client_cbs, server_cbs;

    XMEMSET(&client_cbs, 0, sizeof(client_cbs));
    XMEMSET(&server_cbs, 0, sizeof(server_cbs));
    client_cbs.doUdp = server_cbs.doUdp = 1;
    client_cbs.method = client_method;
    server_cbs.method = server_method;

    client_cbs.on_result = test_wolfSSL_send_bad_record;
    server_cbs.on_result = test_wolfSSL_read_string;

    test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);

    if (!client_cbs.return_code)
        return TEST_FAIL;
    if (!server_cbs.return_code)
        return TEST_FAIL;

    return TEST_SUCCESS;
}

static int test_wolfSSL_dtls_bad_record(void)
{
    int ret = TEST_SUCCESS;
#if !defined(WOLFSSL_NO_TLS12)
    ret = _test_wolfSSL_dtls_bad_record(wolfDTLSv1_2_client_method,
        wolfDTLSv1_2_server_method);
#endif
#ifdef WOLFSSL_DTLS13
    if (ret == TEST_SUCCESS) {
        ret = _test_wolfSSL_dtls_bad_record(wolfDTLSv1_3_client_method,
        wolfDTLSv1_3_server_method);
    }
#endif /* WOLFSSL_DTLS13 */
    return ret;

}

#else
static int test_wolfSSL_dtls_fragments(void) {
    return TEST_SKIPPED;
}
static int test_wolfSSL_ignore_alert_before_cookie(void) {
    return TEST_SKIPPED;
}
static int test_wolfSSL_dtls_bad_record(void) {
    return TEST_SKIPPED;
}
#endif

#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_TLS13_IGNORE_AEAD_LIMITS) && \
    !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES)
static byte test_AEAD_fail_decryption = 0;
static byte test_AEAD_seq_num = 0;
static byte test_AEAD_done = 0;

static int test_AEAD_cbiorecv(WOLFSSL *ssl, char *buf, int sz, void *ctx)
{
    int ret = (int)recv(wolfSSL_get_fd(ssl), buf, sz, 0);
    if (ret > 0) {
        if (test_AEAD_fail_decryption) {
            /* Modify the packet to trigger a decryption failure */
            buf[ret/2] ^= 0xFF;
            if (test_AEAD_fail_decryption == 1)
                test_AEAD_fail_decryption = 0;
        }
    }
    (void)ctx;
    return ret;
}

static void test_AEAD_get_limits(WOLFSSL* ssl, w64wrapper* hardLimit,
        w64wrapper* keyUpdateLimit, w64wrapper* sendLimit)
{
    if (sendLimit)
        w64Zero(sendLimit);
    switch (ssl->specs.bulk_cipher_algorithm) {
        case wolfssl_aes_gcm:
            if (sendLimit)
                *sendLimit = AEAD_AES_LIMIT;
            FALL_THROUGH;
        case wolfssl_chacha:
            if (hardLimit)
                *hardLimit = DTLS_AEAD_AES_GCM_CHACHA_FAIL_LIMIT;
            if (keyUpdateLimit)
                *keyUpdateLimit = DTLS_AEAD_AES_GCM_CHACHA_FAIL_KU_LIMIT;
            break;
        case wolfssl_aes_ccm:
            if (sendLimit)
                *sendLimit = DTLS_AEAD_AES_CCM_LIMIT;
            if (ssl->specs.aead_mac_size == AES_CCM_8_AUTH_SZ) {
                if (hardLimit)
                    *hardLimit = DTLS_AEAD_AES_CCM_8_FAIL_LIMIT;
                if (keyUpdateLimit)
                    *keyUpdateLimit = DTLS_AEAD_AES_CCM_8_FAIL_KU_LIMIT;
            }
            else {
                if (hardLimit)
                    *hardLimit = DTLS_AEAD_AES_CCM_FAIL_LIMIT;
                if (keyUpdateLimit)
                    *keyUpdateLimit = DTLS_AEAD_AES_CCM_FAIL_KU_LIMIT;
            }
            break;
        default:
            fprintf(stderr, "Unrecognized bulk cipher");
            AssertFalse(1);
            break;
    }
}

static void test_AEAD_limit_client(WOLFSSL* ssl)
{
    int ret;
    int i;
    int didReKey = 0;
    char msgBuf[20];
    w64wrapper hardLimit;
    w64wrapper keyUpdateLimit;
    w64wrapper counter;
    w64wrapper sendLimit;

    test_AEAD_get_limits(ssl, &hardLimit, &keyUpdateLimit, &sendLimit);

    w64Zero(&counter);
    AssertTrue(w64Equal(Dtls13GetEpoch(ssl, ssl->dtls13Epoch)->dropCount, counter));

    wolfSSL_SSLSetIORecv(ssl, test_AEAD_cbiorecv);

    for (i = 0; i < 10; i++) {
        /* Test some failed decryptions */
        test_AEAD_fail_decryption = 1;
        w64Increment(&counter);
        ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
        /* Should succeed since decryption failures are dropped */
        AssertIntGT(ret, 0);
        AssertTrue(w64Equal(Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount, counter));
    }

    test_AEAD_fail_decryption = 1;
    Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount = keyUpdateLimit;
    w64Increment(&Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount);
    /* 100 read calls should be enough to complete the key update */
    w64Zero(&counter);
    for (i = 0; i < 100; i++) {
        /* Key update should be sent and negotiated */
        ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
        AssertIntGT(ret, 0);
        /* Epoch after one key update is 4 */
        if (w64Equal(ssl->dtls13PeerEpoch, w64From32(0, 4)) &&
                w64Equal(Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount, counter)) {
            didReKey = 1;
            break;
        }
    }
    AssertTrue(didReKey);

    if (!w64IsZero(sendLimit)) {
        /* Test the sending limit for AEAD ciphers */
        Dtls13GetEpoch(ssl, ssl->dtls13Epoch)->nextSeqNumber = sendLimit;
        test_AEAD_seq_num = 1;
        XMEMSET(msgBuf, 0, sizeof(msgBuf));
        ret = wolfSSL_write(ssl, msgBuf, sizeof(msgBuf));
        AssertIntGT(ret, 0);
        didReKey = 0;
        w64Zero(&counter);
        /* 100 read calls should be enough to complete the key update */
        for (i = 0; i < 100; i++) {
            /* Key update should be sent and negotiated */
            ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
            AssertIntGT(ret, 0);
            /* Epoch after another key update is 5 */
            if (w64Equal(ssl->dtls13Epoch, w64From32(0, 5)) &&
                    w64Equal(Dtls13GetEpoch(ssl, ssl->dtls13Epoch)->dropCount, counter)) {
                didReKey = 1;
                break;
            }
        }
        AssertTrue(didReKey);
    }

    test_AEAD_fail_decryption = 2;
    Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount = hardLimit;
    w64Decrement(&Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount);
    /* Connection should fail with a DECRYPT_ERROR */
    ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
    AssertIntEQ(ret, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    AssertIntEQ(wolfSSL_get_error(ssl, ret), WC_NO_ERR_TRACE(DECRYPT_ERROR));

    test_AEAD_done = 1;
}

int counter = 0;
static void test_AEAD_limit_server(WOLFSSL* ssl)
{
    char msgBuf[] = "Sending data";
    int ret = WOLFSSL_SUCCESS;
    w64wrapper sendLimit;
    SOCKET_T fd = wolfSSL_get_fd(ssl);
    struct timespec delay;
    XMEMSET(&delay, 0, sizeof(delay));
    delay.tv_nsec = 100000000; /* wait 0.1 seconds */
    tcp_set_nonblocking(&fd); /* So that read doesn't block */
    wolfSSL_dtls_set_using_nonblock(ssl, 1);
    test_AEAD_get_limits(ssl, NULL, NULL, &sendLimit);
    while (!test_AEAD_done && ret > 0) {
        counter++;
        if (test_AEAD_seq_num) {
            /* We need to update the seq number so that we can understand the
             * peer. Otherwise we will incorrectly interpret the seq number. */
            Dtls13Epoch* e = Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch);
            AssertNotNull(e);
            e->nextPeerSeqNumber = sendLimit;
            test_AEAD_seq_num = 0;
        }
        (void)wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
        ret = wolfSSL_write(ssl, msgBuf, sizeof(msgBuf));
        nanosleep(&delay, NULL);
    }
}

static int test_wolfSSL_dtls_AEAD_limit(void)
{
    callback_functions func_cb_client;
    callback_functions func_cb_server;
    XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
    XMEMSET(&func_cb_server, 0, sizeof(callback_functions));

    func_cb_client.doUdp = func_cb_server.doUdp = 1;
    func_cb_server.method = wolfDTLSv1_3_server_method;
    func_cb_client.method = wolfDTLSv1_3_client_method;
    func_cb_server.on_result = test_AEAD_limit_server;
    func_cb_client.on_result = test_AEAD_limit_client;

    test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

    if (!func_cb_client.return_code)
        return TEST_FAIL;
    if (!func_cb_server.return_code)
        return TEST_FAIL;

    return TEST_SUCCESS;
}
#else
static int test_wolfSSL_dtls_AEAD_limit(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(WOLFSSL_DTLS) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(SINGLE_THREADED) && \
    !defined(DEBUG_VECTOR_REGISTER_ACCESS_FUZZING)
static void test_wolfSSL_dtls_send_ch(WOLFSSL* ssl)
{
    int fd, ret;
    byte ch_msg[] = {
        0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
        0xfa, 0x01, 0x00, 0x01, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
        0xee, 0xfe, 0xfd, 0xc0, 0xca, 0xb5, 0x6f, 0x3d, 0x23, 0xcc, 0x53, 0x9a,
        0x67, 0x17, 0x70, 0xd3, 0xfb, 0x23, 0x16, 0x9e, 0x4e, 0xd6, 0x7e, 0x29,
        0xab, 0xfa, 0x4c, 0xa5, 0x84, 0x95, 0xc3, 0xdb, 0x21, 0x9a, 0x52, 0x00,
        0x00, 0x00, 0x36, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x2c, 0xc0,
        0x2b, 0xc0, 0x30, 0xc0, 0x2f, 0x00, 0x9f, 0x00, 0x9e, 0xcc, 0xa9, 0xcc,
        0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x28, 0xc0, 0x24, 0xc0,
        0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x6b, 0x00, 0x67, 0x00,
        0x39, 0x00, 0x33, 0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0x01, 0x00, 0x01,
        0x8e, 0x00, 0x2b, 0x00, 0x03, 0x02, 0xfe, 0xfc, 0x00, 0x0d, 0x00, 0x20,
        0x00, 0x1e, 0x06, 0x03, 0x05, 0x03, 0x04, 0x03, 0x02, 0x03, 0x08, 0x06,
        0x08, 0x0b, 0x08, 0x05, 0x08, 0x0a, 0x08, 0x04, 0x08, 0x09, 0x06, 0x01,
        0x05, 0x01, 0x04, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x0a, 0x00, 0x0c,
        0x00, 0x0a, 0x00, 0x19, 0x00, 0x18, 0x00, 0x17, 0x00, 0x15, 0x01, 0x00,
        0x00, 0x16, 0x00, 0x00, 0x00, 0x33, 0x01, 0x4b, 0x01, 0x49, 0x00, 0x17,
        0x00, 0x41, 0x04, 0x96, 0xcb, 0x2e, 0x4e, 0xd9, 0x88, 0x71, 0xc7, 0xf3,
        0x1a, 0x16, 0xdd, 0x7a, 0x7c, 0xf7, 0x67, 0x8a, 0x5d, 0x9a, 0x55, 0xa6,
        0x4a, 0x90, 0xd9, 0xfb, 0xc7, 0xfb, 0xbe, 0x09, 0xa9, 0x8a, 0xb5, 0x7a,
        0xd1, 0xde, 0x83, 0x74, 0x27, 0x31, 0x1c, 0xaa, 0xae, 0xef, 0x58, 0x43,
        0x13, 0x7d, 0x15, 0x4d, 0x7f, 0x68, 0xf6, 0x8a, 0x38, 0xef, 0x0e, 0xb3,
        0xcf, 0xb8, 0x4a, 0xa9, 0xb4, 0xd7, 0xcb, 0x01, 0x00, 0x01, 0x00, 0x1d,
        0x0a, 0x22, 0x8a, 0xd1, 0x78, 0x85, 0x1e, 0x5a, 0xe1, 0x1d, 0x1e, 0xb7,
        0x2d, 0xbc, 0x5f, 0x52, 0xbc, 0x97, 0x5d, 0x8b, 0x6a, 0x8b, 0x9d, 0x1e,
        0xb1, 0xfc, 0x8a, 0xb2, 0x56, 0xcd, 0xed, 0x4b, 0xfb, 0x66, 0x3f, 0x59,
        0x3f, 0x15, 0x5d, 0x09, 0x9e, 0x2f, 0x60, 0x5b, 0x31, 0x81, 0x27, 0xf0,
        0x1c, 0xda, 0xcd, 0x48, 0x66, 0xc6, 0xbb, 0x25, 0xf0, 0x5f, 0xda, 0x4c,
        0xcf, 0x1d, 0x88, 0xc8, 0xda, 0x1b, 0x53, 0xea, 0xbd, 0xce, 0x6d, 0xf6,
        0x4a, 0x76, 0xdb, 0x75, 0x99, 0xaf, 0xcf, 0x76, 0x4a, 0xfb, 0xe3, 0xef,
        0xb2, 0xcb, 0xae, 0x4a, 0xc0, 0xe8, 0x63, 0x1f, 0xd6, 0xe8, 0xe6, 0x45,
        0xf9, 0xea, 0x0d, 0x06, 0x19, 0xfc, 0xb1, 0xfd, 0x5d, 0x92, 0x89, 0x7b,
        0xc7, 0x9f, 0x1a, 0xb3, 0x2b, 0xc7, 0xad, 0x0e, 0xfb, 0x13, 0x41, 0x83,
        0x84, 0x58, 0x3a, 0x25, 0xb9, 0x49, 0x35, 0x1c, 0x23, 0xcb, 0xd6, 0xe7,
        0xc2, 0x8c, 0x4b, 0x2a, 0x73, 0xa1, 0xdf, 0x4f, 0x73, 0x9b, 0xb3, 0xd2,
        0xb2, 0x95, 0x00, 0x3c, 0x26, 0x09, 0x89, 0x71, 0x05, 0x39, 0xc8, 0x98,
        0x8f, 0xed, 0x32, 0x15, 0x78, 0xcd, 0xd3, 0x7e, 0xfb, 0x5a, 0x78, 0x2a,
        0xdc, 0xca, 0x20, 0x09, 0xb5, 0x14, 0xf9, 0xd4, 0x58, 0xf6, 0x69, 0xf8,
        0x65, 0x9f, 0xb7, 0xe4, 0x93, 0xf1, 0xa3, 0x84, 0x7e, 0x1b, 0x23, 0x5d,
        0xea, 0x59, 0x3e, 0x4d, 0xca, 0xfd, 0xa5, 0x55, 0xdd, 0x99, 0xb5, 0x02,
        0xf8, 0x0d, 0xe5, 0xf4, 0x06, 0xb0, 0x43, 0x9e, 0x2e, 0xbf, 0x05, 0x33,
        0x65, 0x7b, 0x13, 0x8c, 0xf9, 0x16, 0x4d, 0xc5, 0x15, 0x0b, 0x40, 0x2f,
        0x66, 0x94, 0xf2, 0x43, 0x95, 0xe7, 0xa9, 0xb6, 0x39, 0x99, 0x73, 0xb3,
        0xb0, 0x06, 0xfe, 0x52, 0x9e, 0x57, 0xba, 0x75, 0xfd, 0x76, 0x7b, 0x20,
        0x31, 0x68, 0x4c
    };

    fd = wolfSSL_get_fd(ssl);
    ret = (int)send(fd, ch_msg, sizeof(ch_msg), 0);
    AssertIntGT(ret, 0);
    /* consume the HRR otherwise handshake will fail */
    ret = (int)recv(fd, ch_msg, sizeof(ch_msg), 0);
    AssertIntGT(ret, 0);
}

#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
static void test_wolfSSL_dtls_send_ch_with_invalid_cookie(WOLFSSL* ssl)
{
    int fd, ret;
    byte ch_msh_invalid_cookie[] = {
      0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
      0x4e, 0x01, 0x00, 0x02, 0x42, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
      0x42, 0xfe, 0xfd, 0x69, 0xca, 0x77, 0x60, 0x6f, 0xfc, 0xd1, 0x5b, 0x60,
      0x5d, 0xf1, 0xa6, 0x5c, 0x44, 0x71, 0xae, 0xca, 0x62, 0x19, 0x0c, 0xb6,
      0xf7, 0x2c, 0xa6, 0xd5, 0xd2, 0x99, 0x9d, 0x18, 0xae, 0xac, 0x11, 0x00,
      0x00, 0x00, 0x36, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x2c, 0xc0,
      0x2b, 0xc0, 0x30, 0xc0, 0x2f, 0x00, 0x9f, 0x00, 0x9e, 0xcc, 0xa9, 0xcc,
      0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x28, 0xc0, 0x24, 0xc0,
      0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x6b, 0x00, 0x67, 0x00,
      0x39, 0x00, 0x33, 0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0x01, 0x00, 0x01,
      0xe2, 0x00, 0x2b, 0x00, 0x03, 0x02, 0xfe, 0xfc, 0x00, 0x0d, 0x00, 0x20,
      0x00, 0x1e, 0x06, 0x03, 0x05, 0x03, 0x04, 0x03, 0x02, 0x03, 0x08, 0x06,
      0x08, 0x0b, 0x08, 0x05, 0x08, 0x0a, 0x08, 0x04, 0x08, 0x09, 0x06, 0x01,
      0x05, 0x01, 0x04, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x2c, 0x00, 0x45,
      0x00, 0x43, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x2d, 0x00,
      0x03, 0x02, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x19,
      0x00, 0x18, 0x00, 0x17, 0x00, 0x15, 0x01, 0x00, 0x00, 0x16, 0x00, 0x00,
      0x00, 0x33, 0x01, 0x4b, 0x01, 0x49, 0x00, 0x17, 0x00, 0x41, 0x04, 0x7c,
      0x5a, 0xc2, 0x5a, 0xfd, 0xcd, 0x2b, 0x08, 0xb2, 0xeb, 0x8e, 0xc0, 0x02,
      0x03, 0x9d, 0xb1, 0xc1, 0x0d, 0x7b, 0x7f, 0x46, 0x43, 0xdf, 0xf3, 0xee,
      0x2b, 0x78, 0x0e, 0x29, 0x8c, 0x42, 0x11, 0x2c, 0xde, 0xd7, 0x41, 0x0f,
      0x28, 0x94, 0x80, 0x41, 0x70, 0xc4, 0x17, 0xfd, 0x6d, 0xfa, 0xee, 0x9a,
      0xf2, 0xc4, 0x15, 0x4c, 0x5f, 0x54, 0xb6, 0x78, 0x6e, 0xf9, 0x63, 0x27,
      0x33, 0xb8, 0x7b, 0x01, 0x00, 0x01, 0x00, 0xd4, 0x46, 0x62, 0x9c, 0xbf,
      0x8f, 0x1b, 0x65, 0x9b, 0xf0, 0x29, 0x64, 0xd8, 0x50, 0x0e, 0x74, 0xf1,
      0x58, 0x10, 0xc9, 0xd9, 0x82, 0x5b, 0xd9, 0xbe, 0x14, 0xdf, 0xde, 0x86,
      0xb4, 0x2e, 0x15, 0xee, 0x4f, 0xf6, 0x74, 0x9e, 0x59, 0x11, 0x36, 0x2d,
      0xb9, 0x67, 0xaa, 0x5a, 0x09, 0x9b, 0x45, 0xf1, 0x01, 0x4c, 0x4e, 0xf6,
      0xda, 0x6a, 0xae, 0xa7, 0x73, 0x7b, 0x2e, 0xb6, 0x24, 0x89, 0x99, 0xb7,
      0x52, 0x16, 0x62, 0x0a, 0xab, 0x58, 0xf8, 0x3f, 0x10, 0x5b, 0x83, 0xfd,
      0x7b, 0x81, 0x77, 0x81, 0x8d, 0xef, 0x24, 0x56, 0x6d, 0xba, 0x49, 0xd4,
      0x8b, 0xb5, 0xa0, 0xb1, 0xc9, 0x8c, 0x32, 0x95, 0x1c, 0x5e, 0x0a, 0x4b,
      0xf6, 0x00, 0x50, 0x0a, 0x87, 0x99, 0x59, 0xcf, 0x6f, 0x9d, 0x02, 0xd0,
      0x1b, 0xa1, 0x96, 0x45, 0x28, 0x76, 0x40, 0x33, 0x28, 0xc9, 0xa1, 0xfd,
      0x46, 0xab, 0x2c, 0x9e, 0x5e, 0xc6, 0x74, 0x19, 0x9a, 0xf5, 0x9b, 0x51,
      0x11, 0x4f, 0xc8, 0xb9, 0x99, 0x6b, 0x4e, 0x3e, 0x31, 0x64, 0xb4, 0x92,
      0xf4, 0x0d, 0x41, 0x4b, 0x2c, 0x65, 0x23, 0xf7, 0x47, 0xe3, 0xa5, 0x2e,
      0xe4, 0x9c, 0x2b, 0xc9, 0x41, 0x22, 0x83, 0x8a, 0x23, 0xef, 0x29, 0x7e,
      0x4f, 0x3f, 0xa3, 0xbf, 0x73, 0x2b, 0xd7, 0xcc, 0xc8, 0xc6, 0xe9, 0xbc,
      0x01, 0xb7, 0x32, 0x63, 0xd4, 0x7e, 0x7f, 0x9a, 0xaf, 0x5f, 0x05, 0x31,
      0x53, 0xd6, 0x1f, 0xa2, 0xd0, 0xdf, 0x67, 0x56, 0xf1, 0x9c, 0x4a, 0x9d,
      0x83, 0xb4, 0xef, 0xb3, 0xf2, 0xcc, 0xf1, 0x91, 0x6c, 0x47, 0xc3, 0x8b,
      0xd0, 0x92, 0x79, 0x3d, 0xa0, 0xc0, 0x3a, 0x57, 0x26, 0x6d, 0x0a, 0xad,
      0x5f, 0xad, 0xb4, 0x74, 0x48, 0x4a, 0x51, 0xe1, 0xb5, 0x82, 0x0a, 0x4c,
      0x4f, 0x9d, 0xaf, 0xee, 0x5a, 0xa2, 0x4d, 0x4d, 0x5f, 0xe0, 0x17, 0x00,
      0x23, 0x00, 0x00
    };
    byte alert_reply[50];
    byte expected_alert_reply[] = {
        0x15, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
        0x02, 0x02, 0x2f
    };

    fd = wolfSSL_get_fd(ssl);
    ret = (int)send(fd, ch_msh_invalid_cookie, sizeof(ch_msh_invalid_cookie), 0);
    AssertIntGT(ret, 0);
    /* should reply with an illegal_parameter reply */
    ret = (int)recv(fd, alert_reply, sizeof(alert_reply), 0);
    AssertIntEQ(ret, sizeof(expected_alert_reply));
    AssertIntEQ(XMEMCMP(alert_reply, expected_alert_reply, sizeof(expected_alert_reply)), 0);
}
#endif

static word32 test_wolfSSL_dtls_stateless_HashWOLFSSL(const WOLFSSL* ssl)
{
#ifndef NO_MD5
    enum wc_HashType hashType = WC_HASH_TYPE_MD5;
#elif !defined(NO_SHA)
    enum wc_HashType hashType = WC_HASH_TYPE_SHA;
#elif !defined(NO_SHA256)
    enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
#else
    #error "We need a digest to hash the WOLFSSL object"
#endif
    byte hashBuf[WC_MAX_DIGEST_SIZE];
    wc_HashAlg hash;
    const TLSX* exts = ssl->extensions;
    WOLFSSL sslCopy; /* Use a copy to omit certain fields */
    HS_Hashes* hsHashes = ssl->hsHashes; /* Is re-allocated in
                                          * InitHandshakeHashes */

    XMEMCPY(&sslCopy, ssl, sizeof(*ssl));
    XMEMSET(hashBuf, 0, sizeof(hashBuf));

    /* Following fields are not important to compare */
    XMEMSET(sslCopy.buffers.inputBuffer.staticBuffer, 0, STATIC_BUFFER_LEN);
    sslCopy.buffers.inputBuffer.buffer = NULL;
    sslCopy.buffers.inputBuffer.bufferSize = 0;
    sslCopy.buffers.inputBuffer.dynamicFlag = 0;
    sslCopy.buffers.inputBuffer.offset = 0;
    XMEMSET(sslCopy.buffers.outputBuffer.staticBuffer, 0, STATIC_BUFFER_LEN);
    sslCopy.buffers.outputBuffer.buffer = NULL;
    sslCopy.buffers.outputBuffer.bufferSize = 0;
    sslCopy.buffers.outputBuffer.dynamicFlag = 0;
    sslCopy.buffers.outputBuffer.offset = 0;
    sslCopy.error = 0;
    sslCopy.curSize = 0;
    sslCopy.curStartIdx = 0;
    sslCopy.keys.curSeq_lo = 0;
    XMEMSET(&sslCopy.curRL, 0, sizeof(sslCopy.curRL));
#ifdef WOLFSSL_DTLS13
    XMEMSET(&sslCopy.keys.curSeq, 0, sizeof(sslCopy.keys.curSeq));
    sslCopy.dtls13FastTimeout = 0;
#endif
    sslCopy.keys.dtls_peer_handshake_number = 0;
    XMEMSET(&sslCopy.alert_history, 0, sizeof(sslCopy.alert_history));
    sslCopy.hsHashes = NULL;
#ifdef WOLFSSL_ASYNC_IO
#ifdef WOLFSSL_ASYNC_CRYPT
    sslCopy.asyncDev = NULL;
#endif
    sslCopy.async = NULL;
#endif

    AssertIntEQ(wc_HashInit(&hash, hashType), 0);
    AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)&sslCopy, sizeof(sslCopy)), 0);
    /* hash extension list */
    while (exts != NULL) {
        AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)exts, sizeof(*exts)), 0);
        exts = exts->next;
    }
    /* Hash suites */
    if (sslCopy.suites != NULL) {
        AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)sslCopy.suites,
                sizeof(struct Suites)), 0);
    }
    /* Hash hsHashes */
    AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)hsHashes,
            sizeof(*hsHashes)), 0);
    AssertIntEQ(wc_HashFinal(&hash, hashType, hashBuf), 0);
    AssertIntEQ(wc_HashFree(&hash, hashType), 0);

    return MakeWordFromHash(hashBuf);
}

static CallbackIORecv test_wolfSSL_dtls_compare_stateless_cb;
static int test_wolfSSL_dtls_compare_stateless_cb_call_once;
static int test_wolfSSL_dtls_compare_stateless_read_cb_once(WOLFSSL *ssl,
        char *buf, int sz, void *ctx)
{
    if (test_wolfSSL_dtls_compare_stateless_cb_call_once) {
        test_wolfSSL_dtls_compare_stateless_cb_call_once = 0;
        return test_wolfSSL_dtls_compare_stateless_cb(ssl, buf, sz, ctx);
    }
    else {
        return WOLFSSL_CBIO_ERR_WANT_READ;
    }
}

static void test_wolfSSL_dtls_compare_stateless(WOLFSSL* ssl)
{
    /* Compare the ssl object before and after one ClientHello msg */
    SOCKET_T fd = wolfSSL_get_fd(ssl);
    int res;
    int err;
    word32 initHash;

    test_wolfSSL_dtls_compare_stateless_cb = ssl->CBIORecv;
    test_wolfSSL_dtls_compare_stateless_cb_call_once = 1;
    wolfSSL_dtls_set_using_nonblock(ssl, 1);
    ssl->CBIORecv = test_wolfSSL_dtls_compare_stateless_read_cb_once;

    initHash = test_wolfSSL_dtls_stateless_HashWOLFSSL(ssl);
    (void)initHash;

    res = tcp_select(fd, 5);
    /* We are expecting a msg. A timeout indicates failure. */
    AssertIntEQ(res, TEST_RECV_READY);

    res = wolfSSL_accept(ssl);
    err = wolfSSL_get_error(ssl, res);
    AssertIntEQ(res, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    AssertIntEQ(err, WOLFSSL_ERROR_WANT_READ);

    AssertIntEQ(initHash, test_wolfSSL_dtls_stateless_HashWOLFSSL(ssl));

    wolfSSL_dtls_set_using_nonblock(ssl, 0);
    ssl->CBIORecv = test_wolfSSL_dtls_compare_stateless_cb;

}

#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
static void test_wolfSSL_dtls_enable_hrrcookie(WOLFSSL* ssl)
{
    int ret;
    ret = wolfSSL_send_hrr_cookie(ssl, NULL, 0);
    AssertIntEQ(ret, WOLFSSL_SUCCESS);
    test_wolfSSL_dtls_compare_stateless(ssl);
}
#endif

static int test_wolfSSL_dtls_stateless(void)
{
    callback_functions client_cbs, server_cbs;
    size_t i;
    struct {
        method_provider client_meth;
        method_provider server_meth;
        ssl_callback client_ssl_ready;
        ssl_callback server_ssl_ready;
    } test_params[] = {
#if !defined(WOLFSSL_NO_TLS12)
        {wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method,
                test_wolfSSL_dtls_send_ch, test_wolfSSL_dtls_compare_stateless},
#endif
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
        {wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method,
                test_wolfSSL_dtls_send_ch, test_wolfSSL_dtls_enable_hrrcookie},
        {wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method,
                test_wolfSSL_dtls_send_ch_with_invalid_cookie, test_wolfSSL_dtls_enable_hrrcookie},
#endif
    };

    if (0 == sizeof(test_params)){
        return TEST_SKIPPED;
    }

    for (i = 0; i < sizeof(test_params)/sizeof(*test_params); i++) {
        XMEMSET(&client_cbs, 0, sizeof(client_cbs));
        XMEMSET(&server_cbs, 0, sizeof(server_cbs));
        client_cbs.doUdp = server_cbs.doUdp = 1;
        client_cbs.method = test_params[i].client_meth;
        server_cbs.method = test_params[i].server_meth;

        client_cbs.ssl_ready = test_params[i].client_ssl_ready;
        server_cbs.ssl_ready = test_params[i].server_ssl_ready;
        test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);

        if (!client_cbs.return_code)
            return TEST_FAIL;
        if (!server_cbs.return_code)
            return TEST_FAIL;
    }

    return TEST_SUCCESS;
}
#else
static int test_wolfSSL_dtls_stateless(void)
{
    return TEST_SKIPPED;
}
#endif /* WOLFSSL_DTLS13 && WOLFSSL_SEND_HRR_COOKIE &&
        * HAVE_IO_TESTS_DEPENDENCIES && !SINGLE_THREADED */

#ifdef HAVE_CERT_CHAIN_VALIDATION
static int load_ca_into_cm(WOLFSSL_CERT_MANAGER* cm, char* certA)
{
    int ret;

    if ((ret = wolfSSL_CertManagerLoadCA(cm, certA, 0)) != WOLFSSL_SUCCESS) {
        fprintf(stderr, "loading cert %s failed\n", certA);
        fprintf(stderr, "Error: (%d): %s\n", ret,
            wolfSSL_ERR_reason_error_string((word32)ret));
        return -1;
    }

    return 0;
}

static int verify_cert_with_cm(WOLFSSL_CERT_MANAGER* cm, char* certA)
{
    int ret;
    if ((ret = wolfSSL_CertManagerVerify(cm, certA, WOLFSSL_FILETYPE_PEM))
                                                         != WOLFSSL_SUCCESS) {
        fprintf(stderr, "could not verify the cert: %s\n", certA);
        fprintf(stderr, "Error: (%d): %s\n", ret,
            wolfSSL_ERR_reason_error_string((word32)ret));
        return -1;
    }
    else {
        fprintf(stderr, "successfully verified: %s\n", certA);
    }

    return 0;
}
#define LOAD_ONE_CA(a, b, c, d)                         \
                    do {                                \
                        (a) = load_ca_into_cm(c, d);    \
                        if ((a) != 0)                   \
                            return (b);                 \
                        else                            \
                            (b)--;                      \
                    } while(0)

#define VERIFY_ONE_CERT(a, b, c, d)                     \
                    do {                                \
                        (a) = verify_cert_with_cm(c, d);\
                        if ((a) != 0)                   \
                            return (b);                 \
                        else                            \
                            (b)--;                      \
                    } while(0)

static int test_chainG(WOLFSSL_CERT_MANAGER* cm)
{
    int ret;
    int i = -1;
    /* Chain G is a valid chain per RFC 5280 section 4.2.1.9 */
    char chainGArr[9][50] = {"certs/ca-cert.pem",
                             "certs/test-pathlen/chainG-ICA7-pathlen100.pem",
                             "certs/test-pathlen/chainG-ICA6-pathlen10.pem",
                             "certs/test-pathlen/chainG-ICA5-pathlen20.pem",
                             "certs/test-pathlen/chainG-ICA4-pathlen5.pem",
                             "certs/test-pathlen/chainG-ICA3-pathlen99.pem",
                             "certs/test-pathlen/chainG-ICA2-pathlen1.pem",
                             "certs/test-pathlen/chainG-ICA1-pathlen0.pem",
                             "certs/test-pathlen/chainG-entity.pem"};

    LOAD_ONE_CA(ret, i, cm, chainGArr[0]); /* if failure, i = -1 here */
    LOAD_ONE_CA(ret, i, cm, chainGArr[1]); /* if failure, i = -2 here */
    LOAD_ONE_CA(ret, i, cm, chainGArr[2]); /* if failure, i = -3 here */
    LOAD_ONE_CA(ret, i, cm, chainGArr[3]); /* if failure, i = -4 here */
    LOAD_ONE_CA(ret, i, cm, chainGArr[4]); /* if failure, i = -5 here */
    LOAD_ONE_CA(ret, i, cm, chainGArr[5]); /* if failure, i = -6 here */
    LOAD_ONE_CA(ret, i, cm, chainGArr[6]); /* if failure, i = -7 here */
    LOAD_ONE_CA(ret, i, cm, chainGArr[7]); /* if failure, i = -8 here */
    VERIFY_ONE_CERT(ret, i, cm, chainGArr[1]); /* if failure, i = -9 here */
    VERIFY_ONE_CERT(ret, i, cm, chainGArr[2]); /* if failure, i = -10 here */
    VERIFY_ONE_CERT(ret, i, cm, chainGArr[3]); /* if failure, i = -11 here */
    VERIFY_ONE_CERT(ret, i, cm, chainGArr[4]); /* if failure, i = -12 here */
    VERIFY_ONE_CERT(ret, i, cm, chainGArr[5]); /* if failure, i = -13 here */
    VERIFY_ONE_CERT(ret, i, cm, chainGArr[6]); /* if failure, i = -14 here */
    VERIFY_ONE_CERT(ret, i, cm, chainGArr[7]); /* if failure, i = -15 here */
    VERIFY_ONE_CERT(ret, i, cm, chainGArr[8]); /* if failure, i = -16 here */

    /* test validating the entity twice, should have no effect on pathLen since
     * entity/leaf cert */
    VERIFY_ONE_CERT(ret, i, cm, chainGArr[8]); /* if failure, i = -17 here */

    return ret;
}

static int test_chainH(WOLFSSL_CERT_MANAGER* cm)
{
    int ret;
    int i = -1;
    /* Chain H is NOT a valid chain per RFC5280 section 4.2.1.9:
     * ICA4-pathlen of 2 signing ICA3-pathlen of 2 (reduce max path len to 2)
     * ICA3-pathlen of 2 signing ICA2-pathlen of 2 (reduce max path len to 1)
     * ICA2-pathlen of 2 signing ICA1-pathlen of 0 (reduce max path len to 0)
     * ICA1-pathlen of 0 signing entity (pathlen is already 0, ERROR)
     * Test should successfully verify ICA4, ICA3, ICA2 and then fail on ICA1
     */
    char chainHArr[6][50] = {"certs/ca-cert.pem",
                             "certs/test-pathlen/chainH-ICA4-pathlen2.pem",
                             "certs/test-pathlen/chainH-ICA3-pathlen2.pem",
                             "certs/test-pathlen/chainH-ICA2-pathlen2.pem",
                             "certs/test-pathlen/chainH-ICA1-pathlen0.pem",
                             "certs/test-pathlen/chainH-entity.pem"};

    LOAD_ONE_CA(ret, i, cm, chainHArr[0]); /* if failure, i = -1 here */
    LOAD_ONE_CA(ret, i, cm, chainHArr[1]); /* if failure, i = -2 here */
    LOAD_ONE_CA(ret, i, cm, chainHArr[2]); /* if failure, i = -3 here */
    LOAD_ONE_CA(ret, i, cm, chainHArr[3]); /* if failure, i = -4 here */
    LOAD_ONE_CA(ret, i, cm, chainHArr[4]); /* if failure, i = -5 here */
    VERIFY_ONE_CERT(ret, i, cm, chainHArr[1]); /* if failure, i = -6 here */
    VERIFY_ONE_CERT(ret, i, cm, chainHArr[2]); /* if failure, i = -7 here */
    VERIFY_ONE_CERT(ret, i, cm, chainHArr[3]); /* if failure, i = -8 here */
    VERIFY_ONE_CERT(ret, i, cm, chainHArr[4]); /* if failure, i = -9 here */
    VERIFY_ONE_CERT(ret, i, cm, chainHArr[5]); /* if failure, i = -10 here */

    return ret;
}

static int test_chainI(WOLFSSL_CERT_MANAGER* cm)
{
    int ret;
    int i = -1;
    /* Chain I is a valid chain per RFC5280 section 4.2.1.9:
     * ICA3-pathlen of 2 signing ICA2 without a pathlen (reduce maxPathLen to 2)
     * ICA2-no_pathlen signing ICA1-no_pathlen (reduce maxPathLen to 1)
     * ICA1-no_pathlen signing entity (reduce maxPathLen to 0)
     * Test should successfully verify ICA4, ICA3, ICA2 and then fail on ICA1
     */
    char chainIArr[5][50] = {"certs/ca-cert.pem",
                             "certs/test-pathlen/chainI-ICA3-pathlen2.pem",
                             "certs/test-pathlen/chainI-ICA2-no_pathlen.pem",
                             "certs/test-pathlen/chainI-ICA1-no_pathlen.pem",
                             "certs/test-pathlen/chainI-entity.pem"};

    LOAD_ONE_CA(ret, i, cm, chainIArr[0]); /* if failure, i = -1 here */
    LOAD_ONE_CA(ret, i, cm, chainIArr[1]); /* if failure, i = -2 here */
    LOAD_ONE_CA(ret, i, cm, chainIArr[2]); /* if failure, i = -3 here */
    LOAD_ONE_CA(ret, i, cm, chainIArr[3]); /* if failure, i = -4 here */
    VERIFY_ONE_CERT(ret, i, cm, chainIArr[1]); /* if failure, i = -5 here */
    VERIFY_ONE_CERT(ret, i, cm, chainIArr[2]); /* if failure, i = -6 here */
    VERIFY_ONE_CERT(ret, i, cm, chainIArr[3]); /* if failure, i = -7 here */
    VERIFY_ONE_CERT(ret, i, cm, chainIArr[4]); /* if failure, i = -8 here */

    return ret;
}

static int test_chainJ(WOLFSSL_CERT_MANAGER* cm)
{
    int ret;
    int i = -1;
    /* Chain J is NOT a valid chain per RFC5280 section 4.2.1.9:
     * ICA4-pathlen of 2 signing ICA3 without a pathlen (reduce maxPathLen to 2)
     * ICA3-pathlen of 2 signing ICA2 without a pathlen (reduce maxPathLen to 1)
     * ICA2-no_pathlen signing ICA1-no_pathlen (reduce maxPathLen to 0)
     * ICA1-no_pathlen signing entity (ERROR, pathlen zero and non-leaf cert)
     */
    char chainJArr[6][50] = {"certs/ca-cert.pem",
                             "certs/test-pathlen/chainJ-ICA4-pathlen2.pem",
                             "certs/test-pathlen/chainJ-ICA3-no_pathlen.pem",
                             "certs/test-pathlen/chainJ-ICA2-no_pathlen.pem",
                             "certs/test-pathlen/chainJ-ICA1-no_pathlen.pem",
                             "certs/test-pathlen/chainJ-entity.pem"};

    LOAD_ONE_CA(ret, i, cm, chainJArr[0]); /* if failure, i = -1 here */
    LOAD_ONE_CA(ret, i, cm, chainJArr[1]); /* if failure, i = -2 here */
    LOAD_ONE_CA(ret, i, cm, chainJArr[2]); /* if failure, i = -3 here */
    LOAD_ONE_CA(ret, i, cm, chainJArr[3]); /* if failure, i = -4 here */
    LOAD_ONE_CA(ret, i, cm, chainJArr[4]); /* if failure, i = -5 here */
    VERIFY_ONE_CERT(ret, i, cm, chainJArr[1]); /* if failure, i = -6 here */
    VERIFY_ONE_CERT(ret, i, cm, chainJArr[2]); /* if failure, i = -7 here */
    VERIFY_ONE_CERT(ret, i, cm, chainJArr[3]); /* if failure, i = -8 here */
    VERIFY_ONE_CERT(ret, i, cm, chainJArr[4]); /* if failure, i = -9 here */
    VERIFY_ONE_CERT(ret, i, cm, chainJArr[5]); /* if failure, i = -10 here */

    return ret;
}

static int test_various_pathlen_chains(void)
{
    EXPECT_DECLS;
    WOLFSSL_CERT_MANAGER* cm = NULL;

    /* Test chain G (large chain with varying pathLens) */
    ExpectNotNull(cm = wolfSSL_CertManagerNew());
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
    ExpectIntEQ(test_chainG(cm), -1);
#else
    ExpectIntEQ(test_chainG(cm), 0);
#endif /* NO_WOLFSSL_CLIENT && NO_WOLFSSL_SERVER */
    ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(cm), WOLFSSL_SUCCESS);
    wolfSSL_CertManagerFree(cm);
    /* end test chain G */

    /* Test chain H (5 chain with same pathLens) */
    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectIntLT(test_chainH(cm), 0);
    ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(cm), WOLFSSL_SUCCESS);
    wolfSSL_CertManagerFree(cm);

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(cm), WOLFSSL_SUCCESS);
    wolfSSL_CertManagerFree(cm);
    /* end test chain H */

    /* Test chain I (only first ICA has pathLen set and it's set to 2,
     * followed by 2 ICA's, should pass) */
    ExpectNotNull(cm = wolfSSL_CertManagerNew());
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
    ExpectIntEQ(test_chainI(cm), -1);
#else
    ExpectIntEQ(test_chainI(cm), 0);
#endif /* NO_WOLFSSL_CLIENT && NO_WOLFSSL_SERVER */
    ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(cm), WOLFSSL_SUCCESS);
    wolfSSL_CertManagerFree(cm);
    cm = NULL;

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(cm), WOLFSSL_SUCCESS);
    wolfSSL_CertManagerFree(cm);
    cm = NULL;

    /* Test chain J (Again only first ICA has pathLen set and it's set to 2,
     * this time followed by 3 ICA's, should fail */
    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectIntLT(test_chainJ(cm), 0);
    ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(cm), WOLFSSL_SUCCESS);
    wolfSSL_CertManagerFree(cm);
    cm = NULL;

    ExpectNotNull(cm = wolfSSL_CertManagerNew());
    ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(cm), WOLFSSL_SUCCESS);
    wolfSSL_CertManagerFree(cm);

    return EXPECT_RESULT();
}
#endif /* !NO_RSA && !NO_SHA && !NO_FILESYSTEM && !NO_CERTS */

#if defined(HAVE_KEYING_MATERIAL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_export_keying_material_cb(WOLFSSL_CTX *ctx, WOLFSSL *ssl)
{
    EXPECT_DECLS;
    byte ekm[100] = {0};

    (void)ctx;

    /* Success Cases */
    ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
            "Test label", XSTR_SIZEOF("Test label"), NULL, 0, 0), 1);
    ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
            "Test label", XSTR_SIZEOF("Test label"), NULL, 0, 1), 1);
    /* Use some random context */
    ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
            "Test label", XSTR_SIZEOF("Test label"), ekm, 10, 1), 1);
    /* Failure cases */
    ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
            "client finished", XSTR_SIZEOF("client finished"), NULL, 0, 0), 0);
    ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
            "server finished", XSTR_SIZEOF("server finished"), NULL, 0, 0), 0);
    ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
            "master secret", XSTR_SIZEOF("master secret"), NULL, 0, 0), 0);
    ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
            "extended master secret", XSTR_SIZEOF("extended master secret"),
            NULL, 0, 0), 0);
    ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
            "key expansion", XSTR_SIZEOF("key expansion"), NULL, 0, 0), 0);

    return EXPECT_RESULT();
}

static int test_export_keying_material_ssl_cb(WOLFSSL* ssl)
{
    wolfSSL_KeepArrays(ssl);
    return TEST_SUCCESS;
}

static int test_export_keying_material(void)
{
    EXPECT_DECLS;
    test_ssl_cbf serverCb;
    test_ssl_cbf clientCb;

    XMEMSET(&serverCb, 0, sizeof(serverCb));
    XMEMSET(&clientCb, 0, sizeof(clientCb));
    clientCb.ssl_ready = test_export_keying_material_ssl_cb;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&clientCb,
        &serverCb, test_export_keying_material_cb), TEST_SUCCESS);

    return EXPECT_RESULT();
}
#endif /* HAVE_KEYING_MATERIAL */

static int test_wolfSSL_THREADID_hash(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    CRYPTO_THREADID id;

    CRYPTO_THREADID_current(NULL);
    /* Hash result is word32. */
    ExpectTrue(CRYPTO_THREADID_hash(NULL) == 0UL);
    XMEMSET(&id, 0, sizeof(id));
    ExpectTrue(CRYPTO_THREADID_hash(&id) == 0UL);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}
static int test_wolfSSL_set_ecdh_auto(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    WOLFSSL* ssl = NULL;

    ExpectIntEQ(SSL_set_ecdh_auto(NULL,0), 1);
    ExpectIntEQ(SSL_set_ecdh_auto(NULL,1), 1);
    ExpectIntEQ(SSL_set_ecdh_auto(ssl,0), 1);
    ExpectIntEQ(SSL_set_ecdh_auto(ssl,1), 1);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_set_ecdh_auto(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    WOLFSSL_CTX* ctx = NULL;

    ExpectIntEQ(SSL_CTX_set_ecdh_auto(NULL,0), 1);
    ExpectIntEQ(SSL_CTX_set_ecdh_auto(NULL,1), 1);
    ExpectIntEQ(SSL_CTX_set_ecdh_auto(ctx,0), 1);
    ExpectIntEQ(SSL_CTX_set_ecdh_auto(ctx,1), 1);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_server_thread(void* args)
{
    EXPECT_DECLS;
    callback_functions* callbacks = NULL;
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;
    SOCKET_T     sfd = 0;
    SOCKET_T     cfd = 0;
    word16       port;
    char msg[] = "I hear you fa shizzle!";
    int  len   = (int) XSTRLEN(msg);
    char input[1024];
    int  ret = 0;
    int  err = 0;

    if (!args)
        WOLFSSL_RETURN_FROM_THREAD(0);

    ((func_args*)args)->return_code = TEST_FAIL;

    callbacks   = ((func_args*)args)->callbacks;
    ctx         = wolfSSL_CTX_new(callbacks->method());

#if defined(USE_WINDOWS_API)
    port = ((func_args*)args)->signal->port;
#else
    /* Let tcp_listen assign port */
    port = 0;
#endif

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx,
        caCertFile, 0));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_certificate_file(ctx,
        svrCertFile, WOLFSSL_FILETYPE_PEM));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_PrivateKey_file(ctx,
        svrKeyFile, WOLFSSL_FILETYPE_PEM));

#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
    ExpectIntEQ(wolfSSL_CTX_SetTmpDH_file(ctx, dhParamFile,
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#elif !defined(NO_DH)
    SetDHCtx(ctx);  /* will repick suites with DHE, higher priority than PSK */
#endif

    if (callbacks->ctx_ready)
        callbacks->ctx_ready(ctx);

    ssl = wolfSSL_new(ctx);
    ExpectNotNull(ssl);

    /* listen and accept */
    tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0, 0);
    CloseSocket(sfd);

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_set_fd(ssl, cfd));

    if (callbacks->ssl_ready)
        callbacks->ssl_ready(ssl);

    if (EXPECT_SUCCESS()) {
        do {
            err = 0; /* Reset error */
            ret = wolfSSL_accept(ssl);
            if (ret != WOLFSSL_SUCCESS) {
                err = wolfSSL_get_error(ssl, 0);
            }
        } while (ret != WOLFSSL_SUCCESS && err == WC_NO_ERR_TRACE(WC_PENDING_E));
    }

    ExpectIntEQ(ret, WOLFSSL_SUCCESS);

    /* read and write data */
    XMEMSET(input, 0, sizeof(input));

    while (EXPECT_SUCCESS()) {
        ret = wolfSSL_read(ssl, input, sizeof(input));
        if (ret > 0) {
            break;
        }
        else {
            err = wolfSSL_get_error(ssl,ret);
            if (err == WOLFSSL_ERROR_WANT_READ) {
                continue;
            }
            break;
        }
    }

    if (EXPECT_SUCCESS() && (err == WOLFSSL_ERROR_ZERO_RETURN)) {
        do {
            ret = wolfSSL_write(ssl, msg, len);
            if (ret > 0) {
                break;
            }
        } while (ret < 0);
    }

    /* bidirectional shutdown */
    while (EXPECT_SUCCESS()) {
        ret = wolfSSL_shutdown(ssl);
        ExpectIntNE(ret, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
        if (ret == WOLFSSL_SUCCESS) {
            break;
        }
    }

    if (EXPECT_SUCCESS()) {
        /* wait for the peer to disconnect the tcp connection */
        do {
            ret = wolfSSL_read(ssl, input, sizeof(input));
            err = wolfSSL_get_error(ssl, ret);
        } while (ret > 0 || err != WOLFSSL_ERROR_ZERO_RETURN);
    }

    /* detect TCP disconnect */
    ExpectIntLE(ret,WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_get_error(ssl, ret), WOLFSSL_ERROR_ZERO_RETURN);

    ((func_args*)args)->return_code = EXPECT_RESULT();

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    CloseSocket(cfd);
#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif
    WOLFSSL_RETURN_FROM_THREAD(0);
}
static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_client_thread(void* args)
{
    EXPECT_DECLS;
    callback_functions* callbacks = NULL;
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL*     ssl = NULL;
    SOCKET_T     sfd = 0;
    char msg[] = "hello wolfssl server!";
    int  len   = (int) XSTRLEN(msg);
    char input[1024];
    int  idx;
    int  ret, err;

    if (!args)
        WOLFSSL_RETURN_FROM_THREAD(0);

    ((func_args*)args)->return_code = TEST_FAIL;
    callbacks   = ((func_args*)args)->callbacks;
    ctx         = wolfSSL_CTX_new(callbacks->method());

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx,
        caCertFile, 0));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_certificate_file(ctx,
        cliCertFile, WOLFSSL_FILETYPE_PEM));

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_PrivateKey_file(ctx,
        cliKeyFile, WOLFSSL_FILETYPE_PEM));

    ExpectNotNull((ssl = wolfSSL_new(ctx)));

    tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, 0, ssl);

    ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_set_fd(ssl, sfd));

    if (EXPECT_SUCCESS()) {
        do {
            err = 0; /* Reset error */
            ret = wolfSSL_connect(ssl);
            if (ret != WOLFSSL_SUCCESS) {
                err = wolfSSL_get_error(ssl, 0);
            }
        } while (ret != WOLFSSL_SUCCESS && err == WC_NO_ERR_TRACE(WC_PENDING_E));
    }

    ExpectIntGE(wolfSSL_write(ssl, msg, len), 0);

    if (EXPECT_SUCCESS()) {
        if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) {
            input[idx] = 0;
        }
    }

    if (EXPECT_SUCCESS()) {
        ret = wolfSSL_shutdown(ssl);
        if (ret == WOLFSSL_SHUTDOWN_NOT_DONE) {
            ret = wolfSSL_shutdown(ssl);
        }
    }
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);

    ((func_args*)args)->return_code = EXPECT_RESULT();

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    CloseSocket(sfd);
#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif
    WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL &&
          HAVE_IO_TESTS_DEPENDENCIES && !WOLFSSL_NO_TLS12 */

/* This test is to check wolfSSL_read behaves as same as
 * openSSL when it is called after SSL_shutdown completes.
 */
static int test_wolfSSL_read_detect_TCP_disconnect(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
    tcp_ready ready;
    func_args client_args;
    func_args server_args;
    THREAD_TYPE serverThread;
    THREAD_TYPE clientThread;
    callback_functions server_cbf;
    callback_functions client_cbf;

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif
    StartTCP();
    InitTcpReady(&ready);

#if defined(USE_WINDOWS_API)
    /* use RNG to get random port if using windows */
    ready.port = GetRandomPort();
#endif

    XMEMSET(&client_args, 0, sizeof(func_args));
    XMEMSET(&server_args, 0, sizeof(func_args));

    XMEMSET(&server_cbf, 0, sizeof(callback_functions));
    XMEMSET(&client_cbf, 0, sizeof(callback_functions));

    server_cbf.method = wolfTLSv1_2_server_method;
    client_cbf.method = wolfTLSv1_2_client_method;

    server_args.callbacks = &server_cbf;
    client_args.callbacks = &client_cbf;

    server_args.signal = &ready;
    client_args.signal = &ready;

    start_thread(SSL_read_test_server_thread, &server_args, &serverThread);

    wait_tcp_ready(&server_args);

    start_thread(SSL_read_test_client_thread, &client_args, &clientThread);

    join_thread(clientThread);
    join_thread(serverThread);

    ExpectTrue(client_args.return_code);
    ExpectTrue(server_args.return_code);

    FreeTcpReady(&ready);
#endif
    return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_get_min_proto_version(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
    WOLFSSL_CTX *ctx = NULL;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
    ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, SSL3_VERSION),
        WOLFSSL_SUCCESS);
    #ifdef WOLFSSL_ALLOW_SSLV3
        ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), SSL3_VERSION);
    #else
        ExpectIntGT(wolfSSL_CTX_get_min_proto_version(ctx), SSL3_VERSION);
    #endif
    wolfSSL_CTX_free(ctx);
    ctx = NULL;

    #ifndef NO_OLD_TLS
    #ifdef WOLFSSL_ALLOW_TLSV10
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
    #endif
    ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, TLS1_VERSION),
        WOLFSSL_SUCCESS);
    #ifdef WOLFSSL_ALLOW_TLSV10
        ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_VERSION);
    #else
        ExpectIntGT(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_VERSION);
    #endif
    wolfSSL_CTX_free(ctx);
    ctx = NULL;
    #endif

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
    ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION),
        WOLFSSL_SUCCESS);
    #ifndef NO_OLD_TLS
        ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_1_VERSION);
    #else
        ExpectIntGT(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_1_VERSION);
    #endif
    wolfSSL_CTX_free(ctx);
    ctx = NULL;

    #ifndef WOLFSSL_NO_TLS12
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_method()));
        ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION),
            WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_2_VERSION);
        wolfSSL_CTX_free(ctx);
        ctx = NULL;
    #endif

    #ifdef WOLFSSL_TLS13
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_method()));
        ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION),
            WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_3_VERSION);
        wolfSSL_CTX_free(ctx);
        ctx = NULL;
    #endif
#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) */
    return EXPECT_RESULT();
}

#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
static int test_wolfSSL_set_SSL_CTX(void)
{
    EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) \
    && !defined(WOLFSSL_NO_TLS12) && defined(WOLFSSL_TLS13) && \
    !defined(NO_RSA)
    WOLFSSL_CTX *ctx1 = NULL;
    WOLFSSL_CTX *ctx2 = NULL;
    WOLFSSL *ssl = NULL;
    const byte *session_id1 = (const byte *)"CTX1";
    const byte *session_id2 = (const byte *)"CTX2";

    ExpectNotNull(ctx1 = wolfSSL_CTX_new(wolfTLS_server_method()));
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx1, svrCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx1, svrKeyFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx1, TLS1_2_VERSION),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx1), TLS1_2_VERSION);
    ExpectIntEQ(wolfSSL_CTX_get_max_proto_version(ctx1), TLS1_3_VERSION);
    ExpectIntEQ(wolfSSL_CTX_set_session_id_context(ctx1, session_id1, 4),
        WOLFSSL_SUCCESS);

    ExpectNotNull(ctx2 = wolfSSL_CTX_new(wolfTLS_server_method()));
    ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx2, svrCertFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx2, svrKeyFile,
        WOLFSSL_FILETYPE_PEM));
    ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx2, TLS1_2_VERSION),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(ctx2, TLS1_2_VERSION),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx2), TLS1_2_VERSION);
    ExpectIntEQ(wolfSSL_CTX_get_max_proto_version(ctx2), TLS1_2_VERSION);
    ExpectIntEQ(wolfSSL_CTX_set_session_id_context(ctx2, session_id2, 4),
        WOLFSSL_SUCCESS);

#ifdef HAVE_SESSION_TICKET
    ExpectIntEQ((wolfSSL_CTX_get_options(ctx1) & SSL_OP_NO_TICKET), 0);
    wolfSSL_CTX_set_options(ctx2, SSL_OP_NO_TICKET);
    ExpectIntNE((wolfSSL_CTX_get_options(ctx2) & SSL_OP_NO_TICKET), 0);
#endif

    ExpectNotNull(ssl = wolfSSL_new(ctx2));
    ExpectIntNE((wolfSSL_get_options(ssl) & WOLFSSL_OP_NO_TLSv1_3), 0);
#ifdef WOLFSSL_INT_H
#ifdef WOLFSSL_SESSION_ID_CTX
    ExpectIntEQ(XMEMCMP(ssl->sessionCtx, session_id2, 4), 0);
#endif
#ifdef WOLFSSL_COPY_CERT
    if (ctx2 != NULL && ctx2->certificate != NULL) {
        ExpectFalse(ssl->buffers.certificate == ctx2->certificate);
    }
    if (ctx2 != NULL && ctx2->certChain != NULL) {
        ExpectFalse(ssl->buffers.certChain == ctx2->certChain);
    }
#else
    ExpectTrue(ssl->buffers.certificate == ctx2->certificate);
    ExpectTrue(ssl->buffers.certChain == ctx2->certChain);
#endif
#endif

#ifdef HAVE_SESSION_TICKET
    ExpectIntNE((wolfSSL_get_options(ssl) & SSL_OP_NO_TICKET), 0);
#endif

    /* Set the ctx1 that has TLSv1.3 as max proto version */
    ExpectNotNull(wolfSSL_set_SSL_CTX(ssl, ctx1));

    /* MUST not change proto versions of ssl */
    ExpectIntNE((wolfSSL_get_options(ssl) & WOLFSSL_OP_NO_TLSv1_3), 0);
#ifdef HAVE_SESSION_TICKET
    /* MUST not change */
    ExpectIntNE((wolfSSL_get_options(ssl) & SSL_OP_NO_TICKET), 0);
#endif
    /* MUST change */
#ifdef WOLFSSL_INT_H
#ifdef WOLFSSL_COPY_CERT
    if (ctx1 != NULL && ctx1->certificate != NULL) {
        ExpectFalse(ssl->buffers.certificate == ctx1->certificate);
    }
    if (ctx1 != NULL && ctx1->certChain != NULL) {
        ExpectFalse(ssl->buffers.certChain == ctx1->certChain);
    }
#else
    ExpectTrue(ssl->buffers.certificate == ctx1->certificate);
    ExpectTrue(ssl->buffers.certChain == ctx1->certChain);
#endif
#ifdef WOLFSSL_SESSION_ID_CTX
    ExpectIntEQ(XMEMCMP(ssl->sessionCtx, session_id1, 4), 0);
#endif
#endif

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx1);
    wolfSSL_CTX_free(ctx2);
#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) */
    return EXPECT_RESULT();
}
#endif /* defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))) */

static int test_wolfSSL_security_level(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    SSL_CTX *ctx = NULL;

    #ifdef WOLFSSL_TLS13
        #ifdef NO_WOLFSSL_SERVER
            ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
        #else
            ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
        #endif
        SSL_CTX_set_security_level(NULL, 1);
        SSL_CTX_set_security_level(ctx, 1);
        ExpectIntEQ(SSL_CTX_get_security_level(NULL), 0);
        /* Stub so nothing happens. */
        ExpectIntEQ(SSL_CTX_get_security_level(ctx), 0);

        SSL_CTX_free(ctx);
    #else
        (void)ctx;
    #endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SSL_in_init(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_BIO)
    SSL_CTX* ctx = NULL;
    SSL*     ssl = NULL;
    const char* testCertFile;
    const char* testKeyFile;

#ifdef WOLFSSL_TLS13
    #ifdef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
    #endif
#else
    #ifdef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    #endif
#endif
#ifndef NO_RSA
    testCertFile = svrCertFile;
    testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
    testCertFile = eccCertFile;
    testKeyFile = eccKeyFile;
#else
    testCertFile = NULL;
    testKeyFile = NULL;
#endif
    if ((testCertFile != NULL) && (testKeyFile != NULL)) {
        ExpectTrue(SSL_CTX_use_certificate_file(ctx, testCertFile,
            SSL_FILETYPE_PEM));
        ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
            SSL_FILETYPE_PEM));
    }

    ExpectNotNull(ssl = SSL_new(ctx));
    ExpectIntEQ(SSL_in_init(ssl), 1);

    SSL_CTX_free(ctx);
    SSL_free(ssl);
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_set_timeout(void)
{
    EXPECT_DECLS;
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_SESSION_CACHE)
    int timeout;
    WOLFSSL_CTX* ctx = NULL;

    (void)timeout;

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
    /* in WOLFSSL_ERROR_CODE_OPENSSL macro guard,
     * wolfSSL_CTX_set_timeout returns previous timeout value on success.
     */
    ExpectIntEQ(wolfSSL_CTX_set_timeout(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* giving 0 as timeout value sets default timeout */
    timeout = wolfSSL_CTX_set_timeout(ctx, 0);
    ExpectIntEQ(wolfSSL_CTX_set_timeout(ctx, 20), timeout);
    ExpectIntEQ(wolfSSL_CTX_set_timeout(ctx, 30), 20);

#else
    ExpectIntEQ(wolfSSL_CTX_set_timeout(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wolfSSL_CTX_set_timeout(ctx, 100), 1);
    ExpectIntEQ(wolfSSL_CTX_set_timeout(ctx, 0), 1);
#endif

    wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_SERVER && !NO_SESSION_CACHE*/
    return EXPECT_RESULT();
}

static int test_wolfSSL_OpenSSL_version(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
    const char* ver;

#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
    ExpectNotNull(ver = OpenSSL_version(0));
#else
    ExpectNotNull(ver = OpenSSL_version());
#endif
    ExpectIntEQ(XMEMCMP(ver, "wolfSSL " LIBWOLFSSL_VERSION_STRING,
        XSTRLEN("wolfSSL " LIBWOLFSSL_VERSION_STRING)), 0);
#endif
    return EXPECT_RESULT();
}

static int test_CONF_CTX_CMDLINE(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL)
    SSL_CTX* ctx = NULL;
    SSL_CONF_CTX* cctx = NULL;

    ExpectNotNull(cctx = SSL_CONF_CTX_new());

    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);

    /* set flags */
    ExpectIntEQ(SSL_CONF_CTX_set_flags(cctx, WOLFSSL_CONF_FLAG_CMDLINE),
        WOLFSSL_CONF_FLAG_CMDLINE);
    ExpectIntEQ(SSL_CONF_CTX_set_flags(cctx, WOLFSSL_CONF_FLAG_CERTIFICATE),
        WOLFSSL_CONF_FLAG_CMDLINE | WOLFSSL_CONF_FLAG_CERTIFICATE);
    /* cmd invalid command */
    ExpectIntEQ(SSL_CONF_cmd(cctx, "foo", "foobar"), -2);
    ExpectIntEQ(SSL_CONF_cmd(cctx, "foo", NULL), -2);
    ExpectIntEQ(SSL_CONF_cmd(cctx, NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CONF_cmd(cctx, NULL, "foobar"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CONF_cmd(NULL, "-curves", "foobar"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* cmd Certificate and Private Key*/
    {
    #if !defined(NO_CERTS) && !defined(NO_RSA)
        const char*  ourCert = svrCertFile;
        const char*  ourKey  = svrKeyFile;

        ExpectIntEQ(SSL_CONF_cmd(cctx, "-cert", NULL), -3);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "-cert", ourCert), WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "-key", NULL), -3);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "-key", ourKey), WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
    #endif
    }

    /* cmd curves */
    {
    #if defined(HAVE_ECC)
        const char* curve = "secp256r1";

        ExpectIntEQ(SSL_CONF_cmd(cctx, "-curves", NULL), -3);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "-curves", curve), WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
    #endif
    }

    /* cmd CipherString */
    {
        char* cipher = wolfSSL_get_cipher_list(0/*top priority*/);

        ExpectIntEQ(SSL_CONF_cmd(cctx, "-cipher", NULL), -3);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "-cipher", cipher), WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
    }

    /* cmd DH parameter */
    {
    #if !defined(NO_DH) && !defined(NO_BIO)
        const char* ourdhcert = "./certs/dh2048.pem";

        ExpectIntEQ(SSL_CONF_cmd(cctx, "-dhparam", NULL), -3);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "-dhparam", ourdhcert), WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);

    #endif
    }

    SSL_CTX_free(ctx);
    SSL_CONF_CTX_free(cctx);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_CONF_CTX_FILE(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL)
    SSL_CTX* ctx = NULL;
    SSL_CONF_CTX* cctx = NULL;

    ExpectNotNull(cctx = SSL_CONF_CTX_new());
    ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);

    /* set flags */
    ExpectIntEQ(SSL_CONF_CTX_set_flags(cctx, WOLFSSL_CONF_FLAG_FILE),
        WOLFSSL_CONF_FLAG_FILE);
    ExpectIntEQ(SSL_CONF_CTX_set_flags(cctx, WOLFSSL_CONF_FLAG_CERTIFICATE),
        WOLFSSL_CONF_FLAG_FILE | WOLFSSL_CONF_FLAG_CERTIFICATE);
    /* sanity check */
    ExpectIntEQ(SSL_CONF_cmd(cctx, "foo", "foobar"), -2);
    ExpectIntEQ(SSL_CONF_cmd(cctx, "foo", NULL), -2);
    ExpectIntEQ(SSL_CONF_cmd(cctx, NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CONF_cmd(cctx, NULL, "foobar"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(SSL_CONF_cmd(NULL, "-curves", "foobar"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* cmd Certificate and Private Key*/
    {
    #if !defined(NO_CERTS) && !defined(NO_RSA)
        const char*  ourCert = svrCertFile;
        const char*  ourKey  = svrKeyFile;

        ExpectIntEQ(SSL_CONF_cmd(cctx, "Certificate", NULL), -3);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "PrivateKey", NULL), -3);

        ExpectIntEQ(SSL_CONF_cmd(cctx, "Certificate", ourCert),
            WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "PrivateKey", ourKey), WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
    #endif
    }

    /* cmd curves */
    {
    #if defined(HAVE_ECC)
        const char* curve = "secp256r1";

        ExpectIntEQ(SSL_CONF_cmd(cctx, "Curves", NULL), -3);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "Curves", curve), WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
    #endif
    }

    /* cmd CipherString */
    {
        char* cipher = wolfSSL_get_cipher_list(0/*top priority*/);

        ExpectIntEQ(SSL_CONF_cmd(cctx, "CipherString", NULL), -3);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "CipherString", cipher),
            WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
    }

    /* cmd DH parameter */
    {
    #if !defined(NO_DH) && !defined(NO_BIO) && defined(HAVE_FFDHE_3072)
        const char* ourdhcert = "./certs/dh3072.pem";

        ExpectIntEQ(SSL_CONF_cmd(cctx, "DHParameters", NULL), -3);
        ExpectIntEQ(SSL_CONF_cmd(cctx, "DHParameters", ourdhcert),
            WOLFSSL_SUCCESS);
        ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);

    #endif
    }

    SSL_CTX_free(ctx);
    SSL_CONF_CTX_free(cctx);
#endif /* OPENSSL_EXTRA */
    return EXPECT_RESULT();
}

static int test_wolfSSL_CRYPTO_get_ex_new_index(void)
{
    EXPECT_DECLS;
#ifdef HAVE_EX_DATA
    int idx1, idx2;

    /* test for unsupported class index */
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509_STORE,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(
        WOLF_CRYPTO_EX_INDEX_X509_STORE_CTX,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_DH,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_DSA,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_EC_KEY,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_RSA,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_ENGINE,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_UI,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_BIO,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_APP,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_UI_METHOD,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_DRBG,
        0,NULL, NULL, NULL, NULL ), -1);
    ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(20,
        0,NULL, NULL, NULL, NULL ), -1);

    /* test for supported class index */
    idx1 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL,
        0,NULL, NULL, NULL, NULL );
    idx2 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL,
        0,NULL, NULL, NULL, NULL );
    ExpectIntNE(idx1, -1);
    ExpectIntNE(idx2, -1);
    ExpectIntNE(idx1, idx2);

    idx1 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX,
        0,NULL, NULL, NULL, NULL );
    idx2 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX,
        0,NULL, NULL, NULL, NULL );
    ExpectIntNE(idx1, -1);
    ExpectIntNE(idx2, -1);
    ExpectIntNE(idx1, idx2);

    idx1 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509,
        0,NULL, NULL, NULL, NULL );
    idx2 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509,
        0,NULL, NULL, NULL, NULL );
    ExpectIntNE(idx1, -1);
    ExpectIntNE(idx2, -1);
    ExpectIntNE(idx1, idx2);


    idx1 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_SESSION,
        0,NULL, NULL, NULL, NULL );
    idx2 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_SESSION,
        0,NULL, NULL, NULL, NULL );
    ExpectIntNE(idx1, -1);
    ExpectIntNE(idx2, -1);
    ExpectIntNE(idx1, idx2);
#endif /* HAVE_EX_DATA */
    return EXPECT_RESULT();
}

#if defined(HAVE_EX_DATA) && defined(HAVE_EXT_CACHE) && \
    (defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
        (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
        defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
        defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))))

#define SESSION_NEW_IDX_LONG 0xDEADBEEF
#define SESSION_NEW_IDX_VAL  ((void*)0xAEADAEAD)
#define SESSION_DUP_IDX_VAL  ((void*)0xDEDEDEDE)
#define SESSION_NEW_IDX_PTR  "Testing"

static void test_wolfSSL_SESSION_get_ex_new_index_new_cb(void* p, void* ptr,
        CRYPTO_EX_DATA* a, int idx, long argValue, void* arg)
{
    AssertNotNull(p);
    AssertNull(ptr);
    AssertIntEQ(CRYPTO_set_ex_data(a, idx, SESSION_NEW_IDX_VAL), SSL_SUCCESS);
    AssertIntEQ(argValue, SESSION_NEW_IDX_LONG);
    AssertStrEQ(arg, SESSION_NEW_IDX_PTR);
}

static int test_wolfSSL_SESSION_get_ex_new_index_dup_cb(CRYPTO_EX_DATA* out,
        const CRYPTO_EX_DATA* in, void* inPtr, int idx, long argV,
        void* arg)
{
    EXPECT_DECLS;

    ExpectNotNull(out);
    ExpectNotNull(in);
    ExpectPtrEq(*(void**)inPtr, SESSION_NEW_IDX_VAL);
    ExpectPtrEq(CRYPTO_get_ex_data(in, idx), SESSION_NEW_IDX_VAL);
    ExpectPtrEq(CRYPTO_get_ex_data(out, idx), SESSION_NEW_IDX_VAL);
    ExpectIntEQ(argV, SESSION_NEW_IDX_LONG);
    ExpectStrEQ(arg, SESSION_NEW_IDX_PTR);
    *(void**)inPtr = SESSION_DUP_IDX_VAL;
    if (EXPECT_SUCCESS()) {
        return SSL_SUCCESS;
    }
    else {
        return SSL_FAILURE;
    }
}

static int test_wolfSSL_SESSION_get_ex_new_index_free_cb_called = 0;
static void test_wolfSSL_SESSION_get_ex_new_index_free_cb(void* p, void* ptr,
        CRYPTO_EX_DATA* a, int idx, long argValue, void* arg)
{
    EXPECT_DECLS;

    ExpectNotNull(p);
    ExpectNull(ptr);
    ExpectPtrNE(CRYPTO_get_ex_data(a, idx), 0);
    ExpectIntEQ(argValue, SESSION_NEW_IDX_LONG);
    ExpectStrEQ(arg, SESSION_NEW_IDX_PTR);
    if (EXPECT_SUCCESS()) {
        test_wolfSSL_SESSION_get_ex_new_index_free_cb_called++;
    }
}

static int test_wolfSSL_SESSION_get_ex_new_index(void)
{
    EXPECT_DECLS;
    int idx = SSL_SESSION_get_ex_new_index(SESSION_NEW_IDX_LONG,
                (void*)SESSION_NEW_IDX_PTR,
                test_wolfSSL_SESSION_get_ex_new_index_new_cb,
                test_wolfSSL_SESSION_get_ex_new_index_dup_cb,
                test_wolfSSL_SESSION_get_ex_new_index_free_cb);
    SSL_SESSION* s = SSL_SESSION_new();
    SSL_SESSION* d = NULL;

    ExpectNotNull(s);
    ExpectPtrEq(SSL_SESSION_get_ex_data(s, idx), SESSION_NEW_IDX_VAL);
    ExpectNotNull(d = SSL_SESSION_dup(s));
    ExpectPtrEq(SSL_SESSION_get_ex_data(d, idx), SESSION_DUP_IDX_VAL);
    SSL_SESSION_free(s);
    ExpectIntEQ(test_wolfSSL_SESSION_get_ex_new_index_free_cb_called, 1);
    SSL_SESSION_free(d);
    ExpectIntEQ(test_wolfSSL_SESSION_get_ex_new_index_free_cb_called, 2);

    crypto_ex_cb_free(crypto_ex_cb_ctx_session);
    crypto_ex_cb_ctx_session = NULL;
    return EXPECT_RESULT();
}
#else
static int test_wolfSSL_SESSION_get_ex_new_index(void)
{
    return TEST_SKIPPED;
}
#endif

static int test_wolfSSL_set_psk_use_session_callback(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_PSK)
    SSL_CTX* ctx = NULL;
    SSL*     ssl = NULL;
    const char* testCertFile;
    const char* testKeyFile;

#ifdef WOLFSSL_TLS13
    #ifdef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
    #endif
#else
    #ifdef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    #endif
#endif
#ifndef NO_RSA
    testCertFile = svrCertFile;
    testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
    testCertFile = eccCertFile;
    testKeyFile = eccKeyFile;
#else
    testCertFile = NULL;
    testKeyFile = NULL;
#endif
    if ((testCertFile != NULL) && (testKeyFile != NULL)) {
        ExpectTrue(SSL_CTX_use_certificate_file(ctx, testCertFile,
            SSL_FILETYPE_PEM));
        ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
            SSL_FILETYPE_PEM));
    }

    ExpectNotNull(ssl = SSL_new(ctx));

    SSL_set_psk_use_session_callback(ssl, my_psk_use_session_cb);

    SSL_CTX_free(ctx);
    SSL_free(ssl);
#endif
    return EXPECT_RESULT();
}

/* similar to error_test() in wolfcrypt/test/test.c, but adding error codes from
 * TLS layer.
 */
static int error_test(void)
{
    EXPECT_DECLS;
    const char* errStr;
    const char* unknownStr = wc_GetErrorString(0);

#ifdef NO_ERROR_STRINGS
    /* Ensure a valid error code's string matches an invalid code's.
     * The string is that error strings are not available.
     */
    errStr = wc_GetErrorString(OPEN_RAN_E);
    ExpectIntEQ(XSTRCMP(errStr, unknownStr), 0);
    if (EXPECT_FAIL())
        return OPEN_RAN_E;
#else
    int i;
    int j = 0;
    /* Values that are not or no longer error codes. */
    static const struct {
        int first;
        int last;
    } missing[] = {
#ifndef OPENSSL_EXTRA
        { 0, 0 },
#endif

#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
    defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
        { -11, -12 },
        { -15, -17 },
        { -19, -19 },
        { -26, -27 },
        { -30, WC_FIRST_E+1 },
#else
        { -9, WC_FIRST_E+1 },
#endif
        { -124, -124 },
        { -166, -169 },
        { -300, -300 },
        { -334, -336 },
        { -346, -349 },
        { -356, -356 },
        { -358, -358 },
        { -384, -384 },
        { -466, -499 },
        { WOLFSSL_LAST_E-1, WOLFSSL_LAST_E-1 }
    };

    /* Check that all errors have a string and it's the same through the two
     * APIs. Check that the values that are not errors map to the unknown
     * string.
     */
    for (i = 0; i >= WOLFSSL_LAST_E-1; i--) {
        int this_missing = 0;
        for (j = 0; j < (int)XELEM_CNT(missing); ++j) {
            if ((i <= missing[j].first) && (i >= missing[j].last)) {
                this_missing = 1;
                break;
            }
        }
        errStr = wolfSSL_ERR_reason_error_string((word32)i);

        if (! this_missing) {
            ExpectIntNE(XSTRCMP(errStr, unknownStr), 0);
            if (EXPECT_FAIL()) {
                return i;
            }
            ExpectTrue(XSTRLEN(errStr) < WOLFSSL_MAX_ERROR_SZ);
            if (EXPECT_FAIL()) {
                return i;
            }
        }
        else {
            j++;
            ExpectIntEQ(XSTRCMP(errStr, unknownStr), 0);
            if (EXPECT_FAIL()) {
                return i;
            }
        }
    }
#endif

    return 1;
}

static int test_wolfSSL_ERR_strings(void)
{
    EXPECT_DECLS;

#if !defined(NO_ERROR_STRINGS)
    const char* err1 = "unsupported cipher suite";
    const char* err2 = "wolfSSL PEM routines";
    const char* err  = NULL;

    (void)err;
    (void)err1;
    (void)err2;

#if defined(OPENSSL_EXTRA)
    ExpectNotNull(err = ERR_reason_error_string(WC_NO_ERR_TRACE(UNSUPPORTED_SUITE)));
    ExpectIntEQ(XSTRNCMP(err, err1, XSTRLEN(err1)), 0);

    ExpectNotNull(err = ERR_func_error_string(WC_NO_ERR_TRACE(UNSUPPORTED_SUITE)));
    ExpectIntEQ((*err == '\0'), 1);

    ExpectNotNull(err = ERR_lib_error_string(PEM_R_PROBLEMS_GETTING_PASSWORD));
    ExpectIntEQ(XSTRNCMP(err, err2, XSTRLEN(err2)), 0);
#else
    ExpectNotNull(err = wolfSSL_ERR_reason_error_string(WC_NO_ERR_TRACE((word32)UNSUPPORTED_SUITE)));
    ExpectIntEQ(XSTRNCMP(err, err1, XSTRLEN(err1)), 0);

    ExpectNotNull(err = wolfSSL_ERR_func_error_string(WC_NO_ERR_TRACE((word32)UNSUPPORTED_SUITE)));
    ExpectIntEQ((*err == '\0'), 1);

    /* The value -MIN_CODE_E+2 is PEM_R_PROBLEMS_GETTING_PASSWORD. */
    ExpectNotNull(err = wolfSSL_ERR_lib_error_string(-MIN_CODE_E+2));
    ExpectIntEQ((*err == '\0'), 1);
#endif
#endif

    ExpectIntEQ(error_test(), 1);

    return EXPECT_RESULT();
}
static int test_wolfSSL_EVP_shake128(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA3) && \
                                            defined(WOLFSSL_SHAKE128)
    const EVP_MD* md = NULL;

    ExpectNotNull(md = EVP_shake128());
    ExpectIntEQ(XSTRNCMP(md, "SHAKE128", XSTRLEN("SHAKE128")), 0);
#endif

    return EXPECT_RESULT();
}

static int test_wolfSSL_EVP_shake256(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA3) && \
                                            defined(WOLFSSL_SHAKE256)
    const EVP_MD* md = NULL;

    ExpectNotNull(md = EVP_shake256());
    ExpectIntEQ(XSTRNCMP(md, "SHAKE256", XSTRLEN("SHAKE256")), 0);
#endif

    return EXPECT_RESULT();
}

/*
 *  Testing EVP digest API with SM3
 */
static int test_wolfSSL_EVP_sm3(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM3)
    EXPECT_DECLS;
    const EVP_MD* md = NULL;
    EVP_MD_CTX* mdCtx = NULL;
    byte data[WC_SM3_BLOCK_SIZE * 4];
    byte hash[WC_SM3_DIGEST_SIZE];
    byte calcHash[WC_SM3_DIGEST_SIZE];
    byte expHash[WC_SM3_DIGEST_SIZE] = {
        0x38, 0x48, 0x15, 0xa7, 0x0e, 0xae, 0x0b, 0x27,
        0x5c, 0xde, 0x9d, 0xa5, 0xd1, 0xa4, 0x30, 0xa1,
        0xca, 0xd4, 0x54, 0x58, 0x44, 0xa2, 0x96, 0x1b,
        0xd7, 0x14, 0x80, 0x3f, 0x80, 0x1a, 0x07, 0xb6
    };
    word32 chunk;
    word32 i;
    unsigned int sz;
    int ret;

    XMEMSET(data, 0, sizeof(data));

    md = EVP_sm3();
    ExpectTrue(md != NULL);
    ExpectIntEQ(XSTRNCMP(md, "SM3", XSTRLEN("SM3")), 0);
    mdCtx = EVP_MD_CTX_new();
    ExpectTrue(mdCtx != NULL);

    /* Invalid Parameters */
    ExpectIntEQ(EVP_DigestInit(NULL, md), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    /* Valid Parameters */
    ExpectIntEQ(EVP_DigestInit(mdCtx, md), WOLFSSL_SUCCESS);

    ExpectIntEQ(EVP_DigestUpdate(NULL, NULL, 1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_DigestUpdate(mdCtx, NULL, 1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_DigestUpdate(NULL, data, 1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* Valid Parameters */
    ExpectIntEQ(EVP_DigestUpdate(mdCtx, NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, 1), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, 1), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, WC_SM3_BLOCK_SIZE),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, WC_SM3_BLOCK_SIZE - 2),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, WC_SM3_BLOCK_SIZE * 2),
        WOLFSSL_SUCCESS);
    /* Ensure too many bytes for lengths. */
    ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, WC_SM3_PAD_SIZE),
        WOLFSSL_SUCCESS);

    /* Invalid Parameters */
    ExpectIntEQ(EVP_DigestFinal(NULL, NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_DigestFinal(mdCtx, NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_DigestFinal(NULL, hash, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_DigestFinal(NULL, hash, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(EVP_DigestFinal(mdCtx, NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));

    /* Valid Parameters */
    ExpectIntEQ(EVP_DigestFinal(mdCtx, hash, NULL), WOLFSSL_SUCCESS);
    ExpectBufEQ(hash, expHash, WC_SM3_DIGEST_SIZE);

    /* Chunk tests. */
    ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, sizeof(data)), WOLFSSL_SUCCESS);
    ExpectIntEQ(EVP_DigestFinal(mdCtx, calcHash, &sz), WOLFSSL_SUCCESS);
    ExpectIntEQ(sz, WC_SM3_DIGEST_SIZE);
    for (chunk = 1; chunk <= WC_SM3_BLOCK_SIZE + 1; chunk++) {
        for (i = 0; i + chunk <= (word32)sizeof(data); i += chunk) {
            ExpectIntEQ(EVP_DigestUpdate(mdCtx, data + i, chunk),
                WOLFSSL_SUCCESS);
        }
        if (i < (word32)sizeof(data)) {
            ExpectIntEQ(EVP_DigestUpdate(mdCtx, data + i,
                (word32)sizeof(data) - i), WOLFSSL_SUCCESS);
        }
        ExpectIntEQ(EVP_DigestFinal(mdCtx, hash, NULL), WOLFSSL_SUCCESS);
        ExpectBufEQ(hash, calcHash, WC_SM3_DIGEST_SIZE);
    }

    /* Not testing when the low 32-bit length overflows. */

    ret = EVP_MD_CTX_cleanup(mdCtx);
    ExpectIntEQ(ret, WOLFSSL_SUCCESS);
    wolfSSL_EVP_MD_CTX_free(mdCtx);

    res = EXPECT_RESULT();
#endif
    return res;
}  /* END test_EVP_sm3 */

static int test_EVP_blake2(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && (defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S))
    const EVP_MD* md = NULL;
    (void)md;

#if defined(HAVE_BLAKE2)
    ExpectNotNull(md = EVP_blake2b512());
    ExpectIntEQ(XSTRNCMP(md, "BLAKE2B512", XSTRLEN("BLAKE2B512")), 0);
#endif

#if defined(HAVE_BLAKE2S)
    ExpectNotNull(md = EVP_blake2s256());
    ExpectIntEQ(XSTRNCMP(md, "BLAKE2S256", XSTRLEN("BLAKE2S256")), 0);
#endif
#endif

    return EXPECT_RESULT();
}

#if defined(OPENSSL_EXTRA)
static void list_md_fn(const EVP_MD* m, const char* from,
                       const char* to, void* arg)
{
    const char* mn;
    BIO *bio;

    (void) from;
    (void) to;
    (void) arg;
    (void) mn;
    (void) bio;

    if (!m) {
        /* alias */
        AssertNull(m);
        AssertNotNull(to);
    }
    else {
        AssertNotNull(m);
        AssertNull(to);
    }

    AssertNotNull(from);

#if !defined(NO_FILESYSTEM) && defined(DEBUG_WOLFSSL_VERBOSE)
    mn = EVP_get_digestbyname(from);
    /* print to stderr */
    AssertNotNull(arg);

    bio = BIO_new(BIO_s_file());
    BIO_set_fp(bio, arg, BIO_NOCLOSE);
    BIO_printf(bio, "Use %s message digest algorithm\n", mn);
    BIO_free(bio);
#endif
}
#endif

static int test_EVP_MD_do_all(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA)
    EVP_MD_do_all(NULL, stderr);

    EVP_MD_do_all(list_md_fn, stderr);

    res = TEST_SUCCESS;
#endif

    return res;
}

#if defined(OPENSSL_EXTRA)
static void obj_name_t(const OBJ_NAME* nm, void* arg)
{
    (void)arg;
    (void)nm;

    AssertIntGT(nm->type, OBJ_NAME_TYPE_UNDEF);

#if !defined(NO_FILESYSTEM) && defined(DEBUG_WOLFSSL_VERBOSE)
    /* print to stderr */
    AssertNotNull(arg);

    BIO *bio = BIO_new(BIO_s_file());
    BIO_set_fp(bio, arg, BIO_NOCLOSE);
    BIO_printf(bio, "%s\n", nm);
    BIO_free(bio);
#endif
}

#endif
static int test_OBJ_NAME_do_all(void)
{
    int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA)

    OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, NULL, NULL);

    OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, NULL, stderr);

    OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, obj_name_t, stderr);
    OBJ_NAME_do_all(OBJ_NAME_TYPE_PKEY_METH, obj_name_t, stderr);
    OBJ_NAME_do_all(OBJ_NAME_TYPE_COMP_METH, obj_name_t, stderr);
    OBJ_NAME_do_all(OBJ_NAME_TYPE_NUM, obj_name_t, stderr);
    OBJ_NAME_do_all(OBJ_NAME_TYPE_UNDEF, obj_name_t, stderr);
    OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, obj_name_t, stderr);
    OBJ_NAME_do_all(-1, obj_name_t, stderr);

    res = TEST_SUCCESS;
#endif

    return res;
}

static int test_SSL_CIPHER_get_xxx(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
       !defined(NO_FILESYSTEM)
    const SSL_CIPHER* cipher = NULL;
    STACK_OF(SSL_CIPHER) *supportedCiphers = NULL;
    int i, numCiphers = 0;
    SSL_CTX* ctx = NULL;
    SSL*     ssl = NULL;
    const char* testCertFile;
    const char* testKeyFile;
    char buf[256] = {0};

    const char* cipher_id = NULL;
    int   expect_nid1 = NID_undef;
    int   expect_nid2 = NID_undef;
    int   expect_nid3 = NID_undef;
    int   expect_nid4 = NID_undef;
    int   expect_nid5 = 0;

    const char* cipher_id2 = NULL;
    int   expect_nid21 = NID_undef;
    int   expect_nid22 = NID_undef;
    int   expect_nid23 = NID_undef;
    int   expect_nid24 = NID_undef;
    int   expect_nid25 = 0;

    (void)cipher;
    (void)supportedCiphers;
    (void)i;
    (void)numCiphers;
    (void)ctx;
    (void)ssl;
    (void)testCertFile;
    (void)testKeyFile;

#if defined(WOLFSSL_TLS13)
    cipher_id = "TLS13-AES128-GCM-SHA256";
    expect_nid1 = NID_auth_rsa;
    expect_nid2 = NID_aes_128_gcm;
    expect_nid3 = NID_sha256;
    expect_nid4 = NID_kx_any;
    expect_nid5 = 1;

    #if !defined(WOLFSSL_NO_TLS12)
    cipher_id2 = "ECDHE-RSA-AES256-GCM-SHA384";
    expect_nid21 = NID_auth_rsa;
    expect_nid22 = NID_aes_256_gcm;
    expect_nid23 = NID_sha384;
    expect_nid24 = NID_kx_ecdhe;
    expect_nid25 = 1;
    #endif
#endif

    #ifdef NO_WOLFSSL_SERVER
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
    #else
        ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
    #endif

    if (cipher_id) {
    #ifndef NO_RSA
        testCertFile = svrCertFile;
        testKeyFile = svrKeyFile;
    #elif defined(HAVE_ECC)
        testCertFile = eccCertFile;
        testKeyFile = eccKeyFile;
    #else
        testCertFile = NULL;
        testKeyFile = NULL;
    #endif
        if  (testCertFile != NULL && testKeyFile != NULL) {
            ExpectTrue(SSL_CTX_use_certificate_file(ctx, testCertFile,
                                                    SSL_FILETYPE_PEM));
            ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
                                                    SSL_FILETYPE_PEM));
        }

        ExpectNotNull(ssl = SSL_new(ctx));
        ExpectIntEQ(SSL_in_init(ssl), 1);

        supportedCiphers = SSL_get_ciphers(ssl);
        numCiphers = sk_num(supportedCiphers);

        for (i = 0; i < numCiphers; ++i) {

            if ((cipher = (const WOLFSSL_CIPHER*)sk_value(supportedCiphers, i))) {
                SSL_CIPHER_description(cipher, buf, sizeof(buf));
            }

            if (XMEMCMP(cipher_id, buf, XSTRLEN(cipher_id)) == 0) {
                break;
            }
        }
        /* test case for */
        if (i != numCiphers) {
            ExpectIntEQ(wolfSSL_CIPHER_get_auth_nid(cipher), expect_nid1);
            ExpectIntEQ(wolfSSL_CIPHER_get_cipher_nid(cipher), expect_nid2);
            ExpectIntEQ(wolfSSL_CIPHER_get_digest_nid(cipher), expect_nid3);
            ExpectIntEQ(wolfSSL_CIPHER_get_kx_nid(cipher), expect_nid4);
            ExpectIntEQ(wolfSSL_CIPHER_is_aead(cipher), expect_nid5);
        }

        if (cipher_id2) {

            for (i = 0; i < numCiphers; ++i) {

                if ((cipher = (const WOLFSSL_CIPHER*)sk_value(supportedCiphers, i))) {
                    SSL_CIPHER_description(cipher, buf, sizeof(buf));
                }

                if (XMEMCMP(cipher_id2, buf, XSTRLEN(cipher_id2)) == 0) {
                    break;
                }
            }
            /* test case for */
            if (i != numCiphers) {
                ExpectIntEQ(wolfSSL_CIPHER_get_auth_nid(cipher), expect_nid21);
                ExpectIntEQ(wolfSSL_CIPHER_get_cipher_nid(cipher), expect_nid22);
                ExpectIntEQ(wolfSSL_CIPHER_get_digest_nid(cipher), expect_nid23);
                ExpectIntEQ(wolfSSL_CIPHER_get_kx_nid(cipher), expect_nid24);
                ExpectIntEQ(wolfSSL_CIPHER_is_aead(cipher), expect_nid25);
            }
        }
    }

    SSL_CTX_free(ctx);
    SSL_free(ssl);
#endif

    return EXPECT_RESULT();
}

#if defined(WOLF_CRYPTO_CB) && defined(HAVE_IO_TESTS_DEPENDENCIES)

static int load_pem_key_file_as_der(const char* privKeyFile, DerBuffer** pDer,
    int* keyFormat)
{
    int ret;
    byte* key_buf = NULL;
    size_t key_sz = 0;
    EncryptedInfo encInfo;

    XMEMSET(&encInfo, 0, sizeof(encInfo));

    ret = load_file(privKeyFile, &key_buf, &key_sz);
    if (ret == 0) {
        ret = wc_PemToDer(key_buf, key_sz, PRIVATEKEY_TYPE, pDer,
            NULL, &encInfo, keyFormat);
    }

    if (key_buf != NULL) {
        free(key_buf); key_buf = NULL;
    }
    (void)encInfo; /* not used in this test */

#ifdef DEBUG_WOLFSSL
    fprintf(stderr, "%s (%d): Loading PEM %s (len %d) to DER (len %d)\n",
        (ret == 0) ? "Success" : "Failure", ret, privKeyFile, (int)key_sz,
        (*pDer)->length);
#endif

    return ret;
}
static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
{
    int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
    const char* privKeyFile = (const char*)ctx;
    DerBuffer* pDer = NULL;
    int keyFormat = 0;

    if (info->algo_type == WC_ALGO_TYPE_PK) {
    #ifdef DEBUG_WOLFSSL
        fprintf(stderr, "test_CryptoCb_Func: Pk Type %d\n", info->pk.type);
    #endif

    #ifndef NO_RSA
        if (info->pk.type == WC_PK_TYPE_RSA) {
            switch (info->pk.rsa.type) {
                case RSA_PUBLIC_ENCRYPT:
                case RSA_PUBLIC_DECRYPT:
                    /* perform software based RSA public op */
                    ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); /* fallback to software */
                    break;
                case RSA_PRIVATE_ENCRYPT:
                case RSA_PRIVATE_DECRYPT:
                {
                    RsaKey key;

                    /* perform software based RSA private op */
                #ifdef DEBUG_WOLFSSL
                    fprintf(stderr, "test_CryptoCb_Func: RSA Priv\n");
                #endif

                    ret = load_pem_key_file_as_der(privKeyFile, &pDer,
                        &keyFormat);
                    if (ret != 0) {
                        return ret;
                    }
                    ret = wc_InitRsaKey(&key, HEAP_HINT);
                    if (ret == 0) {
                        word32 keyIdx = 0;
                        /* load RSA private key and perform private transform */
                        ret = wc_RsaPrivateKeyDecode(pDer->buffer, &keyIdx,
                            &key, pDer->length);
                        if (ret == 0) {
                            ret = wc_RsaFunction(
                                info->pk.rsa.in, info->pk.rsa.inLen,
                                info->pk.rsa.out, info->pk.rsa.outLen,
                                info->pk.rsa.type, &key, info->pk.rsa.rng);
                        }
                        else {
                            /* if decode fails, then fall-back to software based crypto */
                            fprintf(stderr, "test_CryptoCb_Func: RSA private "
                                "key decode failed %d, falling back to "
                                "software\n", ret);
                            ret = CRYPTOCB_UNAVAILABLE;
                        }
                        wc_FreeRsaKey(&key);
                    }
                    wc_FreeDer(&pDer); pDer = NULL;
                    break;
                }
            }
        #ifdef DEBUG_WOLFSSL
            fprintf(stderr, "test_CryptoCb_Func: RSA Type %d, Ret %d, Out %d\n",
                info->pk.rsa.type, ret, *info->pk.rsa.outLen);
        #endif
        }
        #ifdef WOLF_CRYPTO_CB_RSA_PAD
        else if (info->pk.type == WC_PK_TYPE_RSA_PKCS ||
                 info->pk.type == WC_PK_TYPE_RSA_PSS  ||
                 info->pk.type == WC_PK_TYPE_RSA_OAEP) {
            RsaKey key;

            if (info->pk.rsa.type == RSA_PUBLIC_ENCRYPT ||
                info->pk.rsa.type == RSA_PUBLIC_DECRYPT) {
                /* Have all public key ops fall back to SW */
                return CRYPTOCB_UNAVAILABLE;
            }

            if (info->pk.rsa.padding == NULL) {
                return BAD_FUNC_ARG;
            }

            /* Initialize key */
            ret = load_pem_key_file_as_der(privKeyFile, &pDer,
                &keyFormat);
            if (ret != 0) {
                return ret;
            }

            ret = wc_InitRsaKey(&key, HEAP_HINT);
            if (ret == 0) {
                word32 keyIdx = 0;
                /* load RSA private key and perform private transform */
                ret = wc_RsaPrivateKeyDecode(pDer->buffer, &keyIdx,
                    &key, pDer->length);
            }
            /* Perform RSA operation */
            if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_PKCS)) {
            #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
                ret = wc_RsaSSL_Sign(info->pk.rsa.in, info->pk.rsa.inLen,
                    info->pk.rsa.out, *info->pk.rsa.outLen, &key,
                    info->pk.rsa.rng);
            #else
                ret = CRYPTOCB_UNAVAILABLE;
            #endif
            }
            if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_PSS)) {
            #ifdef WC_RSA_PSS
                ret = wc_RsaPSS_Sign_ex(info->pk.rsa.in, info->pk.rsa.inLen,
                    info->pk.rsa.out, *info->pk.rsa.outLen,
                    info->pk.rsa.padding->hash, info->pk.rsa.padding->mgf,
                    info->pk.rsa.padding->saltLen, &key, info->pk.rsa.rng);
            #else
                ret = CRYPTOCB_UNAVAILABLE;
            #endif
            }
            if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_OAEP)) {
            #if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING)
                ret = wc_RsaPrivateDecrypt_ex(
                    info->pk.rsa.in, info->pk.rsa.inLen,
                    info->pk.rsa.out, *info->pk.rsa.outLen,
                    &key, WC_RSA_OAEP_PAD, info->pk.rsa.padding->hash,
                    info->pk.rsa.padding->mgf, info->pk.rsa.padding->label,
                    info->pk.rsa.padding->labelSz);
            #else
                ret = CRYPTOCB_UNAVAILABLE;
            #endif
            }

            if (ret > 0) {
                *info->pk.rsa.outLen = ret;
            }

            wc_FreeRsaKey(&key);
            wc_FreeDer(&pDer); pDer = NULL;
        }
        #endif /* ifdef WOLF_CRYPTO_CB_RSA_PAD */
    #endif /* !NO_RSA */
    #ifdef HAVE_ECC
        if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) {
            /* mark this key as ephemeral */
            if (info->pk.eckg.key != NULL) {
                XSTRNCPY(info->pk.eckg.key->label, "ephemeral",
                    sizeof(info->pk.eckg.key->label));
                info->pk.eckg.key->labelLen = (int)XSTRLEN(info->pk.eckg.key->label);
            }
        }
        else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
            ecc_key key;

            /* perform software based ECC sign */
        #ifdef DEBUG_WOLFSSL
            fprintf(stderr, "test_CryptoCb_Func: ECC Sign\n");
        #endif

            if (info->pk.eccsign.key != NULL &&
                XSTRCMP(info->pk.eccsign.key->label, "ephemeral") == 0) {
                /* this is an empheral key */
            #ifdef DEBUG_WOLFSSL
                fprintf(stderr, "test_CryptoCb_Func: skipping signing op on "
                    "ephemeral key\n");
            #endif
                return CRYPTOCB_UNAVAILABLE;
            }

            ret = load_pem_key_file_as_der(privKeyFile, &pDer, &keyFormat);
            if (ret != 0) {
                return ret;
            }

            ret = wc_ecc_init(&key);
            if (ret == 0) {
                word32 keyIdx = 0;
                /* load ECC private key and perform private transform */
                ret = wc_EccPrivateKeyDecode(pDer->buffer, &keyIdx,
                    &key, pDer->length);
                if (ret == 0) {
                    ret = wc_ecc_sign_hash(
                        info->pk.eccsign.in, info->pk.eccsign.inlen,
                        info->pk.eccsign.out, info->pk.eccsign.outlen,
                        info->pk.eccsign.rng, &key);
                }
                else {
                    /* if decode fails, then fall-back to software based crypto */
                    fprintf(stderr, "test_CryptoCb_Func: ECC private key "
                        "decode failed %d, falling back to software\n", ret);
                    ret = CRYPTOCB_UNAVAILABLE;
                }
                wc_ecc_free(&key);
            }
            wc_FreeDer(&pDer); pDer = NULL;

        #ifdef DEBUG_WOLFSSL
            fprintf(stderr, "test_CryptoCb_Func: ECC Ret %d, Out %d\n",
                ret, *info->pk.eccsign.outlen);
        #endif
        }
    #endif /* HAVE_ECC */
    #ifdef HAVE_ED25519
        if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) {
            ed25519_key key;

            /* perform software based ED25519 sign */
        #ifdef DEBUG_WOLFSSL
            fprintf(stderr, "test_CryptoCb_Func: ED25519 Sign\n");
        #endif

            ret = load_pem_key_file_as_der(privKeyFile, &pDer, &keyFormat);
            if (ret != 0) {
                return ret;
            }
            ret = wc_ed25519_init(&key);
            if (ret == 0) {
                word32 keyIdx = 0;
                /* load ED25519 private key and perform private transform */
                ret = wc_Ed25519PrivateKeyDecode(pDer->buffer, &keyIdx,
                    &key, pDer->length);
                if (ret == 0) {
                    /* calculate public key */
                    ret = wc_ed25519_make_public(&key, key.p, ED25519_PUB_KEY_SIZE);
                    if (ret == 0) {
                        key.pubKeySet = 1;
                        ret = wc_ed25519_sign_msg_ex(
                            info->pk.ed25519sign.in, info->pk.ed25519sign.inLen,
                            info->pk.ed25519sign.out, info->pk.ed25519sign.outLen,
                            &key, info->pk.ed25519sign.type,
                            info->pk.ed25519sign.context,
                            info->pk.ed25519sign.contextLen);
                    }
                }
                else {
                    /* if decode fails, then fall-back to software based crypto */
                    fprintf(stderr, "test_CryptoCb_Func: ED25519 private key "
                        "decode failed %d, falling back to software\n", ret);
                    ret = CRYPTOCB_UNAVAILABLE;
                }
                wc_ed25519_free(&key);
            }
            wc_FreeDer(&pDer); pDer = NULL;

        #ifdef DEBUG_WOLFSSL
            fprintf(stderr, "test_CryptoCb_Func: ED25519 Ret %d, Out %d\n",
                ret, *info->pk.ed25519sign.outLen);
        #endif
        }
    #endif /* HAVE_ED25519 */
    }
    (void)thisDevId;
    (void)keyFormat;

    return ret;
}

/* tlsVer: WOLFSSL_TLSV1_2 or WOLFSSL_TLSV1_3 */
static int test_wc_CryptoCb_TLS(int tlsVer,
    const char* cliCaPemFile, const char* cliCertPemFile,
    const char* cliPrivKeyPemFile, const char* cliPubKeyPemFile,
    const char* svrCaPemFile, const char* svrCertPemFile,
    const char* svrPrivKeyPemFile, const char* svrPubKeyPemFile)
{
    EXPECT_DECLS;
    callback_functions client_cbf;
    callback_functions server_cbf;

    XMEMSET(&client_cbf, 0, sizeof(client_cbf));
    XMEMSET(&server_cbf, 0, sizeof(server_cbf));

    if (tlsVer == WOLFSSL_TLSV1_3) {
    #ifdef WOLFSSL_TLS13
        server_cbf.method = wolfTLSv1_3_server_method;
        client_cbf.method = wolfTLSv1_3_client_method;
    #endif
    }
    else if (tlsVer == WOLFSSL_TLSV1_2) {
    #ifndef WOLFSSL_NO_TLS12
        server_cbf.method = wolfTLSv1_2_server_method;
        client_cbf.method = wolfTLSv1_2_client_method;
    #endif
    }
    else if (tlsVer == WOLFSSL_TLSV1_1) {
    #ifndef NO_OLD_TLS
        server_cbf.method = wolfTLSv1_1_server_method;
        client_cbf.method = wolfTLSv1_1_client_method;
    #endif
    }
    else if (tlsVer == WOLFSSL_TLSV1) {
    #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
        server_cbf.method = wolfTLSv1_server_method;
        client_cbf.method = wolfTLSv1_client_method;
    #endif
    }
    else if (tlsVer == WOLFSSL_SSLV3) {
    #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) && \
         defined(WOLFSSL_STATIC_RSA)
        server_cbf.method = wolfSSLv3_server_method;
        client_cbf.method = wolfSSLv3_client_method;
    #endif
    }
    else if (tlsVer == WOLFSSL_DTLSV1_2) {
    #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12)
        server_cbf.method = wolfDTLSv1_2_server_method;
        client_cbf.method = wolfDTLSv1_2_client_method;
    #endif
    }
    else if (tlsVer == WOLFSSL_DTLSV1) {
    #if defined(WOLFSSL_DTLS) && !defined(NO_OLD_TLS)
        server_cbf.method = wolfDTLSv1_server_method;
        client_cbf.method = wolfDTLSv1_client_method;
    #endif
    }

    if (server_cbf.method == NULL) {
        /* not enabled */
        return TEST_SUCCESS;
    }

    /* Setup the keys for the TLS test */
    client_cbf.certPemFile = cliCertPemFile;
    client_cbf.keyPemFile = cliPubKeyPemFile;
    client_cbf.caPemFile = cliCaPemFile;

    server_cbf.certPemFile = svrCertPemFile;
    server_cbf.keyPemFile = svrPubKeyPemFile;
    server_cbf.caPemFile = svrCaPemFile;

    /* Setup a crypto callback with pointer to private key file for testing */
    client_cbf.devId = 1;
    wc_CryptoCb_RegisterDevice(client_cbf.devId, test_CryptoCb_Func,
        (void*)cliPrivKeyPemFile);
    server_cbf.devId = 2;
    wc_CryptoCb_RegisterDevice(server_cbf.devId, test_CryptoCb_Func,
        (void*)svrPrivKeyPemFile);

    /* Perform TLS server and client test */
    /* First test is at WOLFSSL_CTX level */
    test_wolfSSL_client_server(&client_cbf, &server_cbf);
    /* Check for success */
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);

    if (EXPECT_SUCCESS()) {
        /* Second test is a WOLFSSL object level */
        client_cbf.loadToSSL = 1; server_cbf.loadToSSL = 1;
        test_wolfSSL_client_server(&client_cbf, &server_cbf);
    }

    /* Check for success */
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);

    /* Un register the devId's */
    wc_CryptoCb_UnRegisterDevice(client_cbf.devId);
    client_cbf.devId = INVALID_DEVID;
    wc_CryptoCb_UnRegisterDevice(server_cbf.devId);
    server_cbf.devId = INVALID_DEVID;

    return EXPECT_RESULT();
}
#endif /* WOLF_CRYPTO_CB && HAVE_IO_TESTS_DEPENDENCIES */

static int test_wc_CryptoCb(void)
{
    EXPECT_DECLS;
#ifdef WOLF_CRYPTO_CB
    /* TODO: Add crypto callback API tests */

#ifdef HAVE_IO_TESTS_DEPENDENCIES
    #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
    int tlsVer;
    #endif

    #ifndef NO_RSA
    for (tlsVer = WOLFSSL_SSLV3; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) {
        ExpectIntEQ(test_wc_CryptoCb_TLS(tlsVer,
            svrCertFile, cliCertFile, cliKeyFile, cliKeyPubFile,
            cliCertFile, svrCertFile, svrKeyFile, svrKeyPubFile),
            TEST_SUCCESS);
    }
    #endif
    #ifdef HAVE_ECC
    for (tlsVer = WOLFSSL_TLSV1; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) {
        ExpectIntEQ(test_wc_CryptoCb_TLS(tlsVer,
            caEccCertFile,  cliEccCertFile, cliEccKeyFile, cliEccKeyPubFile,
            cliEccCertFile, eccCertFile,    eccKeyFile,    eccKeyPubFile),
            TEST_SUCCESS);
    }
    #endif
    #ifdef HAVE_ED25519
    for (tlsVer = WOLFSSL_TLSV1_2; tlsVer <= WOLFSSL_DTLSV1_2; tlsVer++) {
        if (tlsVer == WOLFSSL_DTLSV1) continue;
        ExpectIntEQ(test_wc_CryptoCb_TLS(tlsVer,
            caEdCertFile,  cliEdCertFile, cliEdKeyFile, cliEdKeyPubFile,
            cliEdCertFile, edCertFile,    edKeyFile,    edKeyPubFile),
            TEST_SUCCESS);
    }
    #endif
#endif /* HAVE_IO_TESTS_DEPENDENCIES */
#endif /* WOLF_CRYPTO_CB */
    return EXPECT_RESULT();
}

#if defined(WOLFSSL_STATIC_MEMORY) && defined(HAVE_IO_TESTS_DEPENDENCIES)

/* tlsVer: Example: WOLFSSL_TLSV1_2 or WOLFSSL_TLSV1_3 */
static int test_wolfSSL_CTX_StaticMemory_TLS(int tlsVer,
    const char* cliCaPemFile, const char* cliCertPemFile,
    const char* cliPrivKeyPemFile,
    const char* svrCaPemFile, const char* svrCertPemFile,
    const char* svrPrivKeyPemFile,
    byte* cliMem, word32 cliMemSz, byte* svrMem, word32 svrMemSz)
{
    EXPECT_DECLS;
    callback_functions client_cbf;
    callback_functions server_cbf;

    XMEMSET(&client_cbf, 0, sizeof(client_cbf));
    XMEMSET(&server_cbf, 0, sizeof(server_cbf));

    if (tlsVer == WOLFSSL_TLSV1_3) {
    #ifdef WOLFSSL_TLS13
        server_cbf.method_ex = wolfTLSv1_3_server_method_ex;
        client_cbf.method_ex = wolfTLSv1_3_client_method_ex;
    #endif
    }
    else if (tlsVer == WOLFSSL_TLSV1_2) {
    #ifndef WOLFSSL_NO_TLS12
        server_cbf.method_ex = wolfTLSv1_2_server_method_ex;
        client_cbf.method_ex = wolfTLSv1_2_client_method_ex;
    #endif
    }
    else if (tlsVer == WOLFSSL_TLSV1_1) {
    #ifndef NO_OLD_TLS
        server_cbf.method_ex = wolfTLSv1_1_server_method_ex;
        client_cbf.method_ex = wolfTLSv1_1_client_method_ex;
    #endif
    }
    else if (tlsVer == WOLFSSL_TLSV1) {
    #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
        server_cbf.method_ex = wolfTLSv1_server_method_ex;
        client_cbf.method_ex = wolfTLSv1_client_method_ex;
    #endif
    }
    else if (tlsVer == WOLFSSL_SSLV3) {
    #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) && \
         defined(WOLFSSL_STATIC_RSA)
        server_cbf.method_ex = wolfSSLv3_server_method_ex;
        client_cbf.method_ex = wolfSSLv3_client_method_ex;
    #endif
    }
    else if (tlsVer == WOLFSSL_DTLSV1_2) {
    #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12)
        server_cbf.method_ex = wolfDTLSv1_2_server_method_ex;
        client_cbf.method_ex = wolfDTLSv1_2_client_method_ex;
    #endif
    }
    else if (tlsVer == WOLFSSL_DTLSV1) {
    #if defined(WOLFSSL_DTLS) && !defined(NO_OLD_TLS)
        server_cbf.method_ex = wolfDTLSv1_server_method_ex;
        client_cbf.method_ex = wolfDTLSv1_client_method_ex;
    #endif
    }

    if (server_cbf.method_ex == NULL) {
        /* not enabled */
        return TEST_SUCCESS;
    }

    /* Setup the keys for the TLS test */
    client_cbf.certPemFile = cliCertPemFile;
    client_cbf.keyPemFile = cliPrivKeyPemFile;
    client_cbf.caPemFile = cliCaPemFile;

    server_cbf.certPemFile = svrCertPemFile;
    server_cbf.keyPemFile = svrPrivKeyPemFile;
    server_cbf.caPemFile = svrCaPemFile;

    client_cbf.mem = cliMem;
    client_cbf.memSz = cliMemSz;
    server_cbf.mem = svrMem;
    server_cbf.memSz = svrMemSz;

    client_cbf.devId = INVALID_DEVID;
    server_cbf.devId = INVALID_DEVID;

    /* Perform TLS server and client test */
    /* First test is at WOLFSSL_CTX level */
    test_wolfSSL_client_server(&client_cbf, &server_cbf);
    /* Check for success */
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);

    if (EXPECT_SUCCESS()) {
       /* Second test is a WOLFSSL object level */
       client_cbf.loadToSSL = 1; server_cbf.loadToSSL = 1;
       test_wolfSSL_client_server(&client_cbf, &server_cbf);
    }

    /* Check for success */
    ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
    ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);

    return EXPECT_RESULT();
}
#endif /* WOLFSSL_STATIC_MEMORY && HAVE_IO_TESTS_DEPENDENCIES */

#if defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFCRYPT_ONLY)
static int test_wolfSSL_CTX_StaticMemory_SSL(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    WOLFSSL *ssl1 = NULL, *ssl2 = NULL, *ssl3 = NULL;
    WOLFSSL_MEM_STATS mem_stats;
    WOLFSSL_MEM_CONN_STATS ssl_stats;

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA)
    ExpectIntEQ(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
        WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
        WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif

    ExpectNotNull((ssl1 = wolfSSL_new(ctx)));
    ExpectNotNull((ssl2 = wolfSSL_new(ctx)));

#ifndef WOLFSSL_STATIC_MEMORY_LEAN
    /* this should fail because kMaxCtxClients == 2 */
    ExpectNull((ssl3 = wolfSSL_new(ctx)));
#else
    (void)ssl3;
#endif

    if (wolfSSL_is_static_memory(ssl1, &ssl_stats) == 1) {
    #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_STATIC_MEMORY_LEAN)
        wolfSSL_PrintStatsConn(&ssl_stats);
    #endif
        (void)ssl_stats;
    }

    /* display collected statistics */
    if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) == 1) {
    #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_STATIC_MEMORY_LEAN)
        wolfSSL_PrintStats(&mem_stats);
    #endif
        (void)mem_stats;
    }

    wolfSSL_free(ssl1);
    wolfSSL_free(ssl2);

    return EXPECT_RESULT();
}
#endif /* WOLFSSL_STATIC_MEMORY && !WOLFCRYPT_ONLY */

static int test_wolfSSL_CTX_StaticMemory(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFCRYPT_ONLY)
    wolfSSL_method_func method_func;
    WOLFSSL_CTX* ctx;
    const int kMaxCtxClients = 2;
    #ifdef HAVE_IO_TESTS_DEPENDENCIES
    #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
    int tlsVer;
    byte cliMem[TEST_TLS_STATIC_MEMSZ];
    #endif
    #endif
    byte svrMem[TEST_TLS_STATIC_MEMSZ];

#ifndef NO_WOLFSSL_SERVER
    #ifndef WOLFSSL_NO_TLS12
        method_func = wolfTLSv1_2_server_method_ex;
    #else
        method_func = wolfTLSv1_3_server_method_ex;
    #endif
#else
    #ifndef WOLFSSL_NO_TLS12
        method_func = wolfTLSv1_2_client_method_ex;
    #else
        method_func = wolfTLSv1_3_client_method_ex;
    #endif
#endif

    /* Test creating CTX directly from static memory pool */
    ctx = NULL;
    ExpectIntEQ(wolfSSL_CTX_load_static_memory(&ctx, method_func, svrMem,
        sizeof(svrMem), 0, kMaxCtxClients), WOLFSSL_SUCCESS);
    ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_SSL(ctx), TEST_SUCCESS);
    wolfSSL_CTX_free(ctx);
    ctx = NULL;

    /* Test for heap allocated CTX, then assigning static pool to it */
    ExpectNotNull(ctx = wolfSSL_CTX_new(method_func(NULL)));
    ExpectIntEQ(wolfSSL_CTX_load_static_memory(&ctx, NULL, svrMem,
        sizeof(svrMem), 0, kMaxCtxClients), WOLFSSL_SUCCESS);
    ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_SSL(ctx), TEST_SUCCESS);
    wolfSSL_CTX_free(ctx);

    /* TLS Level Tests using static memory */
#ifdef HAVE_IO_TESTS_DEPENDENCIES
    #ifndef NO_RSA
    for (tlsVer = WOLFSSL_SSLV3; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) {
        ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_TLS(tlsVer,
            svrCertFile, cliCertFile, cliKeyFile,
            cliCertFile, svrCertFile, svrKeyFile,
            cliMem, (word32)sizeof(cliMem), svrMem, (word32)sizeof(svrMem)),
            TEST_SUCCESS);
    }
    #endif
    #ifdef HAVE_ECC
    for (tlsVer = WOLFSSL_TLSV1; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) {
        ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_TLS(tlsVer,
            caEccCertFile,  cliEccCertFile, cliEccKeyFile,
            cliEccCertFile, eccCertFile,    eccKeyFile,
            cliMem, (word32)sizeof(cliMem), svrMem, (word32)sizeof(svrMem)),
            TEST_SUCCESS);
    }
    #endif
    #ifdef HAVE_ED25519
    for (tlsVer = WOLFSSL_TLSV1_2; tlsVer <= WOLFSSL_DTLSV1_2; tlsVer++) {
        if (tlsVer == WOLFSSL_DTLSV1) continue;
        ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_TLS(tlsVer,
            caEdCertFile,  cliEdCertFile, cliEdKeyFile,
            cliEdCertFile, edCertFile,    edKeyFile,
            cliMem, (word32)sizeof(cliMem), svrMem, (word32)sizeof(svrMem)),
            TEST_SUCCESS);
    }
    #endif
#endif /* HAVE_IO_TESTS_DEPENDENCIES */
#endif /* WOLFSSL_STATIC_MEMORY && !WOLFCRYPT_ONLY */
    return EXPECT_RESULT();
}

static int test_openssl_FIPS_drbg(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(WC_NO_RNG) && defined(HAVE_HASHDRBG)
    DRBG_CTX* dctx = NULL;
    byte data1[32], data2[32], zeroData[32];
    byte testSeed[16];
    size_t dlen = sizeof(data1);
    int i;

    XMEMSET(data1, 0, dlen);
    XMEMSET(data2, 0, dlen);
    XMEMSET(zeroData, 0, sizeof(zeroData));
    for (i = 0; i < (int)sizeof(testSeed); i++) {
        testSeed[i] = (byte)i;
    }

    ExpectNotNull(dctx = FIPS_get_default_drbg());
    ExpectIntEQ(FIPS_drbg_init(dctx, 0, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(FIPS_drbg_set_callbacks(dctx, NULL, NULL, 20, NULL, NULL),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(FIPS_drbg_instantiate(dctx, NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(FIPS_drbg_generate(dctx, data1, dlen, 0, NULL, 0),
        WOLFSSL_SUCCESS);
    ExpectIntNE(XMEMCMP(data1, zeroData, dlen), 0);
    ExpectIntEQ(FIPS_drbg_reseed(dctx, testSeed, sizeof(testSeed)),
        WOLFSSL_SUCCESS);
    ExpectIntEQ(FIPS_drbg_generate(dctx, data2, dlen, 0, NULL, 0),
        WOLFSSL_SUCCESS);
    ExpectIntNE(XMEMCMP(data1, zeroData, dlen), 0);
    ExpectIntNE(XMEMCMP(data1, data2, dlen), 0);
    ExpectIntEQ(FIPS_drbg_uninstantiate(dctx), WOLFSSL_SUCCESS);
#ifndef HAVE_GLOBAL_RNG
    /* gets freed by wolfSSL_Cleanup() when HAVE_GLOBAL_RNG defined */
    wolfSSL_FIPS_drbg_free(dctx);
#endif
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_FIPS_mode(void)
{
    EXPECT_DECLS;
#if defined(OPENSSL_ALL)
#ifdef HAVE_FIPS
    ExpectIntEQ(wolfSSL_FIPS_mode(), 1);
    ExpectIntEQ(wolfSSL_FIPS_mode_set(0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
    ExpectIntEQ(wolfSSL_FIPS_mode_set(1), WOLFSSL_SUCCESS);
#else
    ExpectIntEQ(wolfSSL_FIPS_mode(), 0);
    ExpectIntEQ(wolfSSL_FIPS_mode_set(0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_FIPS_mode_set(1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#endif
    return EXPECT_RESULT();
}

#ifdef WOLFSSL_DTLS

/* Prints out the current window */
static void DUW_TEST_print_window_binary(word32 h, word32 l, word32* w) {
#ifdef WOLFSSL_DEBUG_DTLS_WINDOW
    int i;
    for (i = WOLFSSL_DTLS_WINDOW_WORDS - 1; i >= 0; i--) {
        word32 b = w[i];
        int j;
        /* Prints out a 32 bit binary number in big endian order */
        for (j = 0; j < 32; j++, b <<= 1) {
            if (b & (((word32)1) << 31))
                fprintf(stderr, "1");
            else
                fprintf(stderr, "0");
        }
        fprintf(stderr, " ");
    }
    fprintf(stderr, "cur_hi %u cur_lo %u\n", h, l);
#else
    (void)h;
    (void)l;
    (void)w;
#endif
}

/* a - cur_hi
 * b - cur_lo
 * c - next_hi
 * d - next_lo
 * e - window
 * f - expected next_hi
 * g - expected next_lo
 * h - expected window[1]
 * i - expected window[0]
 */
#define DUW_TEST(a,b,c,d,e,f,g,h,i) do { \
    ExpectIntEQ(wolfSSL_DtlsUpdateWindow((a), (b), &(c), &(d), (e)), 1); \
    DUW_TEST_print_window_binary((a), (b), (e)); \
    ExpectIntEQ((c), (f)); \
    ExpectIntEQ((d), (g)); \
    ExpectIntEQ((e)[1], (h)); \
    ExpectIntEQ((e)[0], (i)); \
} while (0)

static int test_wolfSSL_DtlsUpdateWindow(void)
{
    EXPECT_DECLS;
    word32 window[WOLFSSL_DTLS_WINDOW_WORDS];
    word32 next_lo = 0;
    word16 next_hi = 0;

#ifdef WOLFSSL_DEBUG_DTLS_WINDOW
    fprintf(stderr, "\n");
#endif

    XMEMSET(window, 0, sizeof window);
    DUW_TEST(0, 0, next_hi, next_lo, window, 0, 1, 0, 0x01);
    DUW_TEST(0, 1, next_hi, next_lo, window, 0, 2, 0, 0x03);
    DUW_TEST(0, 5, next_hi, next_lo, window, 0, 6, 0, 0x31);
    DUW_TEST(0, 4, next_hi, next_lo, window, 0, 6, 0, 0x33);
    DUW_TEST(0, 100, next_hi, next_lo, window, 0, 101, 0, 0x01);
    DUW_TEST(0, 101, next_hi, next_lo, window, 0, 102, 0, 0x03);
    DUW_TEST(0, 133, next_hi, next_lo, window, 0, 134, 0x03, 0x01);
    DUW_TEST(0, 200, next_hi, next_lo, window, 0, 201, 0, 0x01);
    DUW_TEST(0, 264, next_hi, next_lo, window, 0, 265, 0, 0x01);
    DUW_TEST(0, 0xFFFFFFFF, next_hi, next_lo, window, 1, 0, 0, 0x01);
    DUW_TEST(0, 0xFFFFFFFD, next_hi, next_lo, window, 1, 0, 0, 0x05);
    DUW_TEST(0, 0xFFFFFFFE, next_hi, next_lo, window, 1, 0, 0, 0x07);
    DUW_TEST(1, 3, next_hi, next_lo, window, 1, 4, 0, 0x71);
    DUW_TEST(1, 0, next_hi, next_lo, window, 1, 4, 0, 0x79);
    DUW_TEST(1, 0xFFFFFFFF, next_hi, next_lo, window, 2, 0, 0, 0x01);
    DUW_TEST(2, 3, next_hi, next_lo, window, 2, 4, 0, 0x11);
    DUW_TEST(2, 0, next_hi, next_lo, window, 2, 4, 0, 0x19);
    DUW_TEST(2, 25, next_hi, next_lo, window, 2, 26, 0, 0x6400001);
    DUW_TEST(2, 27, next_hi, next_lo, window, 2, 28, 0, 0x19000005);
    DUW_TEST(2, 29, next_hi, next_lo, window, 2, 30, 0, 0x64000015);
    DUW_TEST(2, 33, next_hi, next_lo, window, 2, 34, 6, 0x40000151);
    DUW_TEST(2, 60, next_hi, next_lo, window, 2, 61, 0x3200000A, 0x88000001);
    DUW_TEST(1, 0xFFFFFFF0, next_hi, next_lo, window, 2, 61, 0x3200000A, 0x88000001);
    DUW_TEST(2, 0xFFFFFFFD, next_hi, next_lo, window, 2, 0xFFFFFFFE, 0, 0x01);
    DUW_TEST(3, 1, next_hi, next_lo, window, 3, 2, 0, 0x11);
    DUW_TEST(99, 66, next_hi, next_lo, window, 99, 67, 0, 0x01);
    DUW_TEST(50, 66, next_hi, next_lo, window, 99, 67, 0, 0x01);
    DUW_TEST(100, 68, next_hi, next_lo, window, 100, 69, 0, 0x01);
    DUW_TEST(99, 50, next_hi, next_lo, window, 100, 69, 0, 0x01);
    DUW_TEST(99, 0xFFFFFFFF, next_hi, next_lo, window, 100, 69, 0, 0x01);
    DUW_TEST(150, 0xFFFFFFFF, next_hi, next_lo, window, 151, 0, 0, 0x01);
    DUW_TEST(152, 0xFFFFFFFF, next_hi, next_lo, window, 153, 0, 0, 0x01);

    return EXPECT_RESULT();
}
#endif /* WOLFSSL_DTLS */

#ifdef WOLFSSL_DTLS
static int DFB_TEST(WOLFSSL* ssl, word32 seq, word32 len, word32 f_offset,
        word32 f_len, word32 f_count, byte ready, word32 bytesReceived)
{
    DtlsMsg* cur;
    static byte msg[100];
    static byte msgInit = 0;

    if (!msgInit) {
        int i;
        for (i = 0; i < 100; i++)
            msg[i] = i + 1;
        msgInit = 1;
    }

    /* Sanitize test parameters */
    if (len > sizeof(msg))
        return -1;
    if (f_offset + f_len > sizeof(msg))
        return -1;

    DtlsMsgStore(ssl, 0, seq, msg + f_offset, len, certificate, f_offset, f_len, NULL);

    if (ssl->dtls_rx_msg_list == NULL)
        return -100;

    if ((cur = DtlsMsgFind(ssl->dtls_rx_msg_list, 0, seq)) == NULL)
        return -200;
    if (cur->fragBucketListCount != f_count)
        return -300;
    if (cur->ready != ready)
        return -400;
    if (cur->bytesReceived != bytesReceived)
        return -500;
    if (ready) {
        if (cur->fragBucketList != NULL)
            return -600;
        if (XMEMCMP(cur->fullMsg, msg, cur->sz) != 0)
            return -700;
    }
    else {
        DtlsFragBucket* fb;
        if (cur->fragBucketList == NULL)
            return -800;
        for (fb = cur->fragBucketList; fb != NULL; fb = fb->m.m.next) {
            if (XMEMCMP(fb->buf, msg + fb->m.m.offset, fb->m.m.sz) != 0)
                return -900;
        }
    }
    return 0;
}

static int test_wolfSSL_DTLS_fragment_buckets(void)
{
    EXPECT_DECLS;
    WOLFSSL ssl[1];

    XMEMSET(ssl, 0, sizeof(*ssl));

    ExpectIntEQ(DFB_TEST(ssl, 0, 100, 0, 100, 0, 1, 100), 0); /*  0-100 */

    ExpectIntEQ(DFB_TEST(ssl, 1, 100,  0, 20, 1, 0,  20), 0); /*  0-20  */
    ExpectIntEQ(DFB_TEST(ssl, 1, 100, 20, 20, 1, 0,  40), 0); /* 20-40  */
    ExpectIntEQ(DFB_TEST(ssl, 1, 100, 40, 20, 1, 0,  60), 0); /* 40-60  */
    ExpectIntEQ(DFB_TEST(ssl, 1, 100, 60, 20, 1, 0,  80), 0); /* 60-80  */
    ExpectIntEQ(DFB_TEST(ssl, 1, 100, 80, 20, 0, 1, 100), 0); /* 80-100 */

    /* Test all permutations of 3 regions */
    /* 1 2 3 */
    ExpectIntEQ(DFB_TEST(ssl, 2, 100,  0, 30, 1, 0,  30), 0); /*  0-30  */
    ExpectIntEQ(DFB_TEST(ssl, 2, 100, 30, 30, 1, 0,  60), 0); /* 30-60  */
    ExpectIntEQ(DFB_TEST(ssl, 2, 100, 60, 40, 0, 1, 100), 0); /* 60-100 */
    /* 1 3 2 */
    ExpectIntEQ(DFB_TEST(ssl, 3, 100,  0, 30, 1, 0,  30), 0); /*  0-30  */
    ExpectIntEQ(DFB_TEST(ssl, 3, 100, 60, 40, 2, 0,  70), 0); /* 60-100 */
    ExpectIntEQ(DFB_TEST(ssl, 3, 100, 30, 30, 0, 1, 100), 0); /* 30-60  */
    /* 2 1 3 */
    ExpectIntEQ(DFB_TEST(ssl, 4, 100, 30, 30, 1, 0,  30), 0); /* 30-60  */
    ExpectIntEQ(DFB_TEST(ssl, 4, 100,  0, 30, 1, 0,  60), 0); /*  0-30  */
    ExpectIntEQ(DFB_TEST(ssl, 4, 100, 60, 40, 0, 1, 100), 0); /* 60-100 */
    /* 2 3 1 */
    ExpectIntEQ(DFB_TEST(ssl, 5, 100, 30, 30, 1, 0,  30), 0); /* 30-60  */
    ExpectIntEQ(DFB_TEST(ssl, 5, 100, 60, 40, 1, 0,  70), 0); /* 60-100 */
    ExpectIntEQ(DFB_TEST(ssl, 5, 100,  0, 30, 0, 1, 100), 0); /*  0-30  */
    /* 3 1 2 */
    ExpectIntEQ(DFB_TEST(ssl, 6, 100, 60, 40, 1, 0,  40), 0); /* 60-100 */
    ExpectIntEQ(DFB_TEST(ssl, 6, 100,  0, 30, 2, 0,  70), 0); /*  0-30  */
    ExpectIntEQ(DFB_TEST(ssl, 6, 100, 30, 30, 0, 1, 100), 0); /* 30-60  */
    /* 3 2 1 */
    ExpectIntEQ(DFB_TEST(ssl, 7, 100, 60, 40, 1, 0,  40), 0); /* 60-100 */
    ExpectIntEQ(DFB_TEST(ssl, 7, 100, 30, 30, 1, 0,  70), 0); /* 30-60  */
    ExpectIntEQ(DFB_TEST(ssl, 7, 100,  0, 30, 0, 1, 100), 0); /*  0-30  */

    /* Test overlapping regions */
    ExpectIntEQ(DFB_TEST(ssl, 8, 100,  0, 30, 1, 0,  30), 0); /*  0-30  */
    ExpectIntEQ(DFB_TEST(ssl, 8, 100, 20, 10, 1, 0,  30), 0); /* 20-30  */
    ExpectIntEQ(DFB_TEST(ssl, 8, 100, 70, 10, 2, 0,  40), 0); /* 70-80  */
    ExpectIntEQ(DFB_TEST(ssl, 8, 100, 20, 30, 2, 0,  60), 0); /* 20-50  */
    ExpectIntEQ(DFB_TEST(ssl, 8, 100, 40, 60, 0, 1, 100), 0); /* 40-100 */

    /* Test overlapping multiple regions */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100,  0, 20, 1, 0,  20), 0); /*  0-20  */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100, 30,  5, 2, 0,  25), 0); /* 30-35  */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100, 40,  5, 3, 0,  30), 0); /* 40-45  */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100, 50,  5, 4, 0,  35), 0); /* 50-55  */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100, 60,  5, 5, 0,  40), 0); /* 60-65  */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100, 70,  5, 6, 0,  45), 0); /* 70-75  */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100, 30, 25, 4, 0,  55), 0); /* 30-55  */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100, 55, 15, 2, 0,  65), 0); /* 55-70  */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100, 75, 25, 2, 0,  90), 0); /* 75-100 */
    ExpectIntEQ(DFB_TEST(ssl, 9, 100, 10, 25, 0, 1, 100), 0); /* 10-35 */

    ExpectIntEQ(DFB_TEST(ssl, 10, 100,  0, 20, 1, 0,  20), 0); /*  0-20  */
    ExpectIntEQ(DFB_TEST(ssl, 10, 100, 30, 20, 2, 0,  40), 0); /* 30-50  */
    ExpectIntEQ(DFB_TEST(ssl, 10, 100,  0, 40, 1, 0,  50), 0); /*  0-40  */
    ExpectIntEQ(DFB_TEST(ssl, 10, 100, 50, 50, 0, 1, 100), 0); /* 10-35 */

    DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
    ssl->dtls_rx_msg_list = NULL;
    ssl->dtls_rx_msg_list_sz = 0;

    return EXPECT_RESULT();
}

#endif


#if !defined(NO_FILESYSTEM) && \
     defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
     defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)

static int test_wolfSSL_dtls_stateless2(void)
{
    EXPECT_DECLS;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_c2 = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
    ExpectNotNull(ssl_c2 = wolfSSL_new(ctx_c));
    wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
    wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
    /* send CH */
    ExpectTrue((wolfSSL_connect(ssl_c2) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_c2->error == WC_NO_ERR_TRACE(WANT_READ)));
    ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
    ExpectIntNE(test_ctx.c_len, 0);
    /* consume HRR */
    test_ctx.c_len = 0;
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    wolfSSL_free(ssl_c2);
    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
    return EXPECT_RESULT();
}

#ifdef HAVE_MAX_FRAGMENT
static int test_wolfSSL_dtls_stateless_maxfrag(void)
{
    EXPECT_DECLS;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_c2 = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    word16 max_fragment = 0;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
    ExpectNotNull(ssl_s);
    ExpectNotNull(ssl_c2 = wolfSSL_new(ctx_c));
    ExpectIntEQ(wolfSSL_UseMaxFragment(ssl_c2, WOLFSSL_MFL_2_8),
        WOLFSSL_SUCCESS);
    wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
    wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
    if (EXPECT_SUCCESS()) {
        max_fragment = ssl_s->max_fragment;
    }
    /* send CH */
    ExpectTrue((wolfSSL_connect(ssl_c2) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_c2->error == WC_NO_ERR_TRACE(WANT_READ)));
    ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
    /* CH without cookie shouldn't change state */
    ExpectIntEQ(ssl_s->max_fragment, max_fragment);
    ExpectIntNE(test_ctx.c_len, 0);

    /* consume HRR from buffer */
    test_ctx.c_len = 0;
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    wolfSSL_free(ssl_c2);
    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
    return EXPECT_RESULT();
}
#endif /* HAVE_MAX_FRAGMENT */

#if defined(WOLFSSL_DTLS_NO_HVR_ON_RESUME)
#define ROUNDS_WITH_HVR 4
#define ROUNDS_WITHOUT_HVR 2
#define HANDSHAKE_TYPE_OFFSET DTLS_RECORD_HEADER_SZ
static int buf_is_hvr(const byte *data, int len)
{
    if (len < DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ)
        return 0;
    return data[HANDSHAKE_TYPE_OFFSET] == hello_verify_request;
}

static int _test_wolfSSL_dtls_stateless_resume(byte useticket, byte bad)
{
    EXPECT_DECLS;
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    WOLFSSL_SESSION *sess = NULL;
    int round_trips;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
        &ssl_s, wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
#ifdef HAVE_SESSION_TICKET
    if (useticket) {
        ExpectIntEQ(wolfSSL_UseSessionTicket(ssl_c), WOLFSSL_SUCCESS);
    }
#endif
    round_trips = ROUNDS_WITH_HVR;
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, round_trips,
        &round_trips), 0);
    ExpectIntEQ(round_trips, ROUNDS_WITH_HVR);
    ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
    wolfSSL_shutdown(ssl_c);
    wolfSSL_shutdown(ssl_s);
    wolfSSL_free(ssl_c);
    ssl_c = NULL;
    wolfSSL_free(ssl_s);
    ssl_s = NULL;

    test_ctx.c_len = test_ctx.s_len = 0;
    /* make resumption invalid */
    if (bad && (sess != NULL)) {
        if (useticket) {
#ifdef HAVE_SESSION_TICKET
            if (sess->ticket != NULL) {
                sess->ticket[0] = !sess->ticket[0];
            }
#endif /* HAVE_SESSION_TICKET */
        }
        else {
            sess->sessionID[0] = !sess->sessionID[0];
        }
    }
    ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
    ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
    wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
    wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
    wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
    wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
    ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
    ExpectTrue((wolfSSL_connect(ssl_c) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));
    ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
    ExpectFalse(bad && !buf_is_hvr(test_ctx.c_buff, test_ctx.c_len));
    ExpectFalse(!bad && buf_is_hvr(test_ctx.c_buff, test_ctx.c_len));
    if (!useticket) {
        ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, &round_trips), 0);
        ExpectFalse(bad && round_trips != ROUNDS_WITH_HVR - 1);
        ExpectFalse(!bad && round_trips != ROUNDS_WITHOUT_HVR - 1);
    }
    wolfSSL_SESSION_free(sess);
    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
    return EXPECT_RESULT();
}

static int test_wolfSSL_dtls_stateless_resume(void)
{
    EXPECT_DECLS;
#ifdef HAVE_SESSION_TICKET
    ExpectIntEQ(_test_wolfSSL_dtls_stateless_resume(1, 0), TEST_SUCCESS);
    ExpectIntEQ(_test_wolfSSL_dtls_stateless_resume(1, 1), TEST_SUCCESS);
#endif /* HAVE_SESION_TICKET */
    ExpectIntEQ(_test_wolfSSL_dtls_stateless_resume(0, 0), TEST_SUCCESS);
    ExpectIntEQ(_test_wolfSSL_dtls_stateless_resume(0, 1), TEST_SUCCESS);
    return EXPECT_RESULT();
}
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */

#if !defined(NO_OLD_TLS)
static int test_wolfSSL_dtls_stateless_downgrade(void)
{
    EXPECT_DECLS;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_c2 = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_c2 = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
    ExpectIntEQ(wolfSSL_CTX_SetMinVersion(ctx_s, WOLFSSL_DTLSV1),
        WOLFSSL_SUCCESS);
    ExpectNotNull(ctx_c2 = wolfSSL_CTX_new(wolfDTLSv1_client_method()));
    wolfSSL_SetIORecv(ctx_c2, test_memio_read_cb);
    wolfSSL_SetIOSend(ctx_c2, test_memio_write_cb);
    ExpectNotNull(ssl_c2 = wolfSSL_new(ctx_c2));
    wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
    wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
    /* send CH */
    ExpectTrue((wolfSSL_connect(ssl_c2) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_c2->error == WC_NO_ERR_TRACE(WANT_READ)));
    ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
    ExpectIntNE(test_ctx.c_len, 0);
    /* consume HRR */
    test_ctx.c_len = 0;
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    wolfSSL_free(ssl_c2);
    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_c2);
    wolfSSL_CTX_free(ctx_s);

    return EXPECT_RESULT();
}
#endif /* !defined(NO_OLD_TLS) */

#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
    !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)*/

#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
    !defined(NO_OLD_TLS) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
static int test_WOLFSSL_dtls_version_alert(void)
{
    EXPECT_DECLS;
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_2_client_method, wolfDTLSv1_server_method), 0);

    /* client hello */
    ExpectTrue((wolfSSL_connect(ssl_c) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));
    /* hrr */
    ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
    /* client hello 1 */
    ExpectTrue((wolfSSL_connect(ssl_c) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));
    /* server hello */
    ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
    /* should fail */
    ExpectTrue((wolfSSL_connect(ssl_c) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_c->error == WC_NO_ERR_TRACE(VERSION_ERROR)));
    /* shuould fail */
    ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_s->error == WC_NO_ERR_TRACE(VERSION_ERROR) || ssl_s->error == WC_NO_ERR_TRACE(FATAL_ERROR)));

    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);

    return EXPECT_RESULT();
}
#else
static int test_WOLFSSL_dtls_version_alert(void)
{
    return TEST_SKIPPED;
}
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) &&
        * !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) &&
        * !defined(NO_OLD_TLS) && !defined(NO_RSA)
        */


#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && defined(HAVE_SESSION_TICKET)       \
    && defined(WOLFSSL_TLS13) &&                                               \
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))\
    && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
static int send_new_session_ticket(WOLFSSL *ssl, byte nonceLength, byte filler)
{
    struct test_memio_ctx *test_ctx;
    byte buf[2048];
    int idx, sz;
    word32 tmp;
    int ret;

    idx = 5; /* space for record header */

    buf[idx] = session_ticket; /* type */
    idx++;

    tmp = OPAQUE32_LEN +
        OPAQUE32_LEN +
        OPAQUE8_LEN + nonceLength +
        OPAQUE16_LEN + OPAQUE8_LEN + OPAQUE16_LEN;
    c32to24(tmp, buf + idx);
    idx += OPAQUE24_LEN;

    c32toa((word32)12345, buf+idx); /* lifetime */
    idx += OPAQUE32_LEN;
    c32toa((word32)12345, buf+idx); /* add */
    idx += OPAQUE32_LEN;
    buf[idx] = nonceLength; /* nonce length */
    idx++;
    XMEMSET(&buf[idx], filler, nonceLength); /* nonce */
    idx += nonceLength;
    tmp = 1; /* ticket len */
    c16toa((word16)tmp, buf+idx);
    idx += 2;
    buf[idx] = 0xFF; /* ticket */
    idx++;
    tmp = 0; /* ext len */
    c16toa((word16)tmp, buf+idx);
    idx += 2;

    sz = BuildTls13Message(ssl, buf, 2048, buf+5, idx - 5,
        handshake, 0, 0, 0);
    AssertIntGT(sz, 0);
    test_ctx = (struct test_memio_ctx*)wolfSSL_GetIOWriteCtx(ssl);
    AssertNotNull(test_ctx);
    ret = test_memio_write_cb(ssl, (char*)buf, sz, test_ctx);
    return !(ret == sz);
}

static int test_ticket_nonce_check(WOLFSSL_SESSION *sess, byte len)
{
    int ret = 0;

    if ((sess == NULL) || (sess->ticketNonce.len != len)) {
        ret = -1;
    }
    else {
        int i;
        for (i = 0; i < len; i++) {
            if (sess->ticketNonce.data[i] != len) {
                ret = -1;
                break;
            }
        }
    }

    return ret;
}

static int test_ticket_nonce_malloc_do(WOLFSSL *ssl_s, WOLFSSL *ssl_c, byte len)
{
    EXPECT_DECLS;
    char *buf[1024];

    ExpectIntEQ(send_new_session_ticket(ssl_s, len, len), 0);
    ExpectTrue((wolfSSL_recv(ssl_c, buf, 1024, 0) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
        (ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));

    ExpectIntEQ(test_ticket_nonce_check(ssl_c->session, len), 0);

    return EXPECT_RESULT();
}

static int test_ticket_nonce_cache(WOLFSSL *ssl_s, WOLFSSL *ssl_c, byte len)
{
    EXPECT_DECLS;
    WOLFSSL_SESSION *sess = NULL;
    WOLFSSL_SESSION *cached = NULL;
    WOLFSSL_CTX *ctx = ssl_c->ctx;

    ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, len), TEST_SUCCESS);
    ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));

    ExpectIntEQ(AddSessionToCache(ctx, sess, sess->sessionID, sess->sessionIDSz,
        NULL, ssl_c->options.side, 1,NULL), 0);

    ExpectNotNull(cached = wolfSSL_SESSION_new());

    ExpectIntEQ(wolfSSL_GetSessionFromCache(ssl_c, cached), WOLFSSL_SUCCESS);

    ExpectIntEQ(test_ticket_nonce_check(cached, len), 0);

    wolfSSL_SESSION_free(cached);
    wolfSSL_SESSION_free(sess);

    return EXPECT_RESULT();
}

static int test_ticket_nonce_malloc(void)
{
    EXPECT_DECLS;
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    byte small;
    byte medium;
    byte big;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);

    /* will send ticket manually */
    ExpectIntEQ(wolfSSL_no_ticket_TLSv13(ssl_s), 0);

    wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, 0);
    wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, 0);

    while (EXPECT_SUCCESS() && (ssl_c->options.handShakeDone == 0) &&
            (ssl_s->options.handShakeDone == 0)) {
        ExpectTrue((wolfSSL_connect(ssl_c) == WOLFSSL_SUCCESS) ||
            (ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));

        ExpectTrue((wolfSSL_accept(ssl_s) == WOLFSSL_SUCCESS) ||
            (ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
    }

    small = TLS13_TICKET_NONCE_STATIC_SZ;
#if TLS13_TICKET_NONCE_STATIC_SZ + 20 <= 255
    medium = small + 20;
#else
    medium = 255;
#endif
#if TLS13_TICKET_NONCE_STATIC_SZ + 20 + 20 <= 255
    big = small + 20;
#else
    big = 255;
#endif

    ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, small), TEST_SUCCESS);
    ExpectPtrEq(ssl_c->session->ticketNonce.data,
         ssl_c->session->ticketNonce.dataStatic);
    ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, medium),
        TEST_SUCCESS);
    ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, big), TEST_SUCCESS);
    ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, medium),
        TEST_SUCCESS);
    ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, small), TEST_SUCCESS);
    ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, small), TEST_SUCCESS);
    ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, medium), TEST_SUCCESS);
    ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, big), TEST_SUCCESS);
    ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, medium), TEST_SUCCESS);
    ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, small), TEST_SUCCESS);

    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);

    return EXPECT_RESULT();
}

#endif /* WOLFSSL_TICKET_NONCE_MALLOC */

#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_TLS12) && \
    !defined(WOLFSSL_TICKET_DECRYPT_NO_CREATE) &&                 \
    !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
    !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && !defined(NO_RSA) && \
    defined(HAVE_ECC) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)

static int test_ticket_ret_create(void)
{
    EXPECT_DECLS;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    byte ticket[SESSION_TICKET_LEN];
    struct test_memio_ctx test_ctx;
    WOLFSSL_SESSION *sess = NULL;
    word16 ticketLen = 0;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
    wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, 0);
    wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, 0);
    ExpectIntEQ(wolfSSL_CTX_UseSessionTicket(ctx_c), WOLFSSL_SUCCESS);

    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
    ExpectIntLE(sess->ticketLen, SESSION_TICKET_LEN);
    if (sess != NULL) {
        ticketLen = sess->ticketLen;
        XMEMCPY(ticket, sess->ticket, sess->ticketLen);
    }
    wolfSSL_free(ssl_c);
    ssl_c = NULL;
    wolfSSL_free(ssl_s);
    ssl_s = NULL;

    ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
    wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
    wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
    ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
    wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
    wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);

    ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
    ExpectIntLE(ssl_c->session->ticketLen, SESSION_TICKET_LEN);
    ExpectIntEQ(ssl_c->session->ticketLen, ticketLen);
    ExpectTrue(XMEMCMP(ssl_c->session->ticket, ticket, ticketLen) != 0);

    wolfSSL_SESSION_free(sess);
    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);

    return EXPECT_RESULT();
}
#else
static int test_ticket_ret_create(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
    defined(HAVE_SESSION_TICKET) && defined(OPENSSL_EXTRA) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_AESGCM) && \
    !defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \
    defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
static void test_ticket_and_psk_mixing_on_result(WOLFSSL* ssl)
{
    int ret;
    WOLFSSL_SESSION* session = NULL;

    AssertIntEQ(wolfSSL_get_current_cipher_suite(ssl), 0x1301);
    if (!wolfSSL_is_server(ssl)) {
        session = wolfSSL_SESSION_dup(wolfSSL_get_session(ssl));
        AssertNotNull(session);
    }
    do {
        ret = wolfSSL_shutdown(ssl);
    } while (ret == WOLFSSL_SHUTDOWN_NOT_DONE);
    AssertIntEQ(wolfSSL_clear(ssl), WOLFSSL_SUCCESS);
    wolfSSL_set_psk_callback_ctx(ssl, (void*)"TLS13-AES256-GCM-SHA384");
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
    /* OpenSSL considers PSK to be verified. We error out with NO_PEER_CERT. */
    wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_NONE, NULL);
#endif

    if (!wolfSSL_is_server(ssl)) {
        /* client */
        AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:"
                "TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS);
        wolfSSL_set_session(ssl, session);
        wolfSSL_SESSION_free(session);
        wolfSSL_set_psk_client_tls13_callback(ssl, my_psk_client_tls13_cb);
        AssertIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
    }
    else {
        /* server */
        /* Different ciphersuite so that the ticket will be invalidated based on
         * the ciphersuite */
        AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384"),
            WOLFSSL_SUCCESS);
        wolfSSL_set_psk_server_tls13_callback(ssl, my_psk_server_tls13_cb);
        AssertIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
    }
}

static void test_ticket_and_psk_mixing_ssl_ready(WOLFSSL* ssl)
{
    AssertIntEQ(wolfSSL_UseSessionTicket(ssl), WOLFSSL_SUCCESS);
    AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES128-GCM-SHA256"),
        WOLFSSL_SUCCESS);
}

static int test_ticket_and_psk_mixing(void)
{
    EXPECT_DECLS;
    /* Test mixing tickets and regular PSK */
    callback_functions client_cbs, server_cbs;

    XMEMSET(&client_cbs, 0, sizeof(client_cbs));
    XMEMSET(&server_cbs, 0, sizeof(server_cbs));

    client_cbs.method = wolfTLSv1_3_client_method;
    server_cbs.method = wolfTLSv1_3_server_method;

    client_cbs.ssl_ready = test_ticket_and_psk_mixing_ssl_ready;

    client_cbs.on_result = test_ticket_and_psk_mixing_on_result;
    server_cbs.on_result = test_ticket_and_psk_mixing_on_result;

    test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);

    ExpectIntEQ(client_cbs.return_code, TEST_SUCCESS);
    ExpectIntEQ(server_cbs.return_code, TEST_SUCCESS);

    return EXPECT_RESULT();
}
#else
static int test_ticket_and_psk_mixing(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && defined(HAVE_SESSION_TICKET) \
    && defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
    defined(HAVE_AESGCM) && !defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \
    defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
static int test_prioritize_psk_cb_called = FALSE;

static unsigned int test_prioritize_psk_cb(WOLFSSL* ssl,
        const char* identity, unsigned char* key, unsigned int key_max_len,
        const char** ciphersuite)
{
    test_prioritize_psk_cb_called = TRUE;
    return my_psk_server_tls13_cb(ssl, identity, key, key_max_len, ciphersuite);
}

static void test_prioritize_psk_on_result(WOLFSSL* ssl)
{
    int ret;
    WOLFSSL_SESSION* session = NULL;
    AssertIntEQ(wolfSSL_get_current_cipher_suite(ssl), 0x1301);
    if (!wolfSSL_is_server(ssl)) {
        session = wolfSSL_SESSION_dup(wolfSSL_get_session(ssl));
        AssertNotNull(session);
    }
    do {
        ret = wolfSSL_shutdown(ssl);
    } while (ret == WOLFSSL_SHUTDOWN_NOT_DONE);
    AssertIntEQ(wolfSSL_clear(ssl), WOLFSSL_SUCCESS);
    wolfSSL_set_psk_callback_ctx(ssl, (void*)"TLS13-AES256-GCM-SHA384");
    /* Previous connection was made with TLS13-AES128-GCM-SHA256. Order is
     * important. */
    AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:"
            "TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS);
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
    /* OpenSSL considers PSK to be verified. We error out with NO_PEER_CERT. */
    wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_NONE, NULL);
#endif

    if (!wolfSSL_is_server(ssl)) {
        /* client */
        wolfSSL_set_psk_client_tls13_callback(ssl, my_psk_client_tls13_cb);
        wolfSSL_set_session(ssl, session);
        wolfSSL_SESSION_free(session);
        AssertIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
    }
    else {
        /* server */
        wolfSSL_set_psk_server_tls13_callback(ssl, test_prioritize_psk_cb);
        AssertIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_PRIORITIZE_PSK
        /* The ticket should be first tried with all ciphersuites and chosen */
        AssertFalse(test_prioritize_psk_cb_called);
#else
        /* Ciphersuites should be tried with each PSK. This triggers the PSK
         * callback that sets this var. */
        AssertTrue(test_prioritize_psk_cb_called);
#endif
    }
}

static void test_prioritize_psk_ssl_ready(WOLFSSL* ssl)
{
    if (!wolfSSL_is_server(ssl))
        AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES128-GCM-SHA256"),
                WOLFSSL_SUCCESS);
    else
        AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:"
                "TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS);
}

static int test_prioritize_psk(void)
{
    EXPECT_DECLS;
    /* We always send the ticket first. With WOLFSSL_PRIORITIZE_PSK the order
     * of the PSK's will be followed instead of the ciphersuite. */
    callback_functions client_cbs, server_cbs;

    XMEMSET(&client_cbs, 0, sizeof(client_cbs));
    XMEMSET(&server_cbs, 0, sizeof(server_cbs));

    client_cbs.method = wolfTLSv1_3_client_method;
    server_cbs.method = wolfTLSv1_3_server_method;

    client_cbs.ssl_ready = test_prioritize_psk_ssl_ready;
    server_cbs.ssl_ready = test_prioritize_psk_ssl_ready;

    client_cbs.on_result = test_prioritize_psk_on_result;
    server_cbs.on_result = test_prioritize_psk_on_result;

    test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);

    ExpectIntEQ(client_cbs.return_code, TEST_SUCCESS);
    ExpectIntEQ(server_cbs.return_code, TEST_SUCCESS);

    return EXPECT_RESULT();
}
#else
static int test_prioritize_psk(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(WOLFSSL_TLS13) && defined(OPENSSL_EXTRA) && \
    defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_AESGCM) && \
    !defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \
    !defined(WOLFSSL_NO_TLS12)
static int test_wolfSSL_CTX_set_ciphersuites_ctx_ready_server(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectTrue(SSL_CTX_set_cipher_list(ctx, "DEFAULT"));
    /* Set TLS 1.3 specific suite */
    ExpectTrue(SSL_CTX_set_ciphersuites(ctx, "TLS13-AES128-GCM-SHA256"));
    return EXPECT_RESULT();
}

static int test_wolfSSL_CTX_set_ciphersuites(void)
{
    EXPECT_DECLS;
    /* Test using SSL_CTX_set_cipher_list and SSL_CTX_set_ciphersuites and then
     * do a 1.2 connection. */
    test_ssl_cbf client_cbs, server_cbs;

    XMEMSET(&client_cbs, 0, sizeof(client_cbs));
    XMEMSET(&server_cbs, 0, sizeof(server_cbs));

    client_cbs.method = wolfTLSv1_2_client_method;
    server_cbs.method = wolfTLS_server_method; /* Allow downgrade */

    server_cbs.ctx_ready = test_wolfSSL_CTX_set_ciphersuites_ctx_ready_server;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
        &server_cbs, NULL), TEST_SUCCESS);

    return EXPECT_RESULT();
}
#else
static int test_wolfSSL_CTX_set_ciphersuites(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(HAVE_CRL) && defined(WOLFSSL_CHECK_ALERT_ON_ERR) && \
        defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CRL_CERT_REVOKED_alert_ctx_ready(WOLFSSL_CTX* ctx)
{
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
    return TEST_SUCCESS;
}

static int test_wolfSSL_CRL_CERT_REVOKED_alert_on_cleanup(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    WOLFSSL_ALERT_HISTORY h;
    ExpectIntEQ(wolfSSL_get_alert_history(ssl, &h), WOLFSSL_SUCCESS);
    ExpectIntEQ(h.last_rx.level, alert_fatal);
    ExpectIntEQ(h.last_rx.code, certificate_revoked);
    return EXPECT_RESULT();
}

static int test_wolfSSL_CRL_CERT_REVOKED_alert(void)
{
    EXPECT_DECLS;
    test_ssl_cbf client_cbs, server_cbs;

    XMEMSET(&client_cbs, 0, sizeof(client_cbs));
    XMEMSET(&server_cbs, 0, sizeof(server_cbs));

    server_cbs.certPemFile = "./certs/server-revoked-cert.pem";
    server_cbs.keyPemFile = "./certs/server-revoked-key.pem";
    client_cbs.crlPemFile = "./certs/crl/crl.revoked";

    client_cbs.ctx_ready = test_wolfSSL_CRL_CERT_REVOKED_alert_ctx_ready;
    server_cbs.on_cleanup = test_wolfSSL_CRL_CERT_REVOKED_alert_on_cleanup;

    ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
        &server_cbs, NULL), -1001);

    return EXPECT_RESULT();
}
#else
static int test_wolfSSL_CRL_CERT_REVOKED_alert(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) \
    && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_AESGCM) && \
    !defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \
    defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) && \
    !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)

static WOLFSSL_CTX* test_TLS_13_ticket_different_ciphers_ctx = NULL;
static WOLFSSL_SESSION* test_TLS_13_ticket_different_ciphers_session = NULL;
static int test_TLS_13_ticket_different_ciphers_run = 0;

static int test_TLS_13_ticket_different_ciphers_ssl_ready(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    switch (test_TLS_13_ticket_different_ciphers_run) {
        case 0:
            /* First run */
            ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES128-GCM-SHA256"),
                WOLFSSL_SUCCESS);
            if (wolfSSL_is_server(ssl)) {
                ExpectNotNull(test_TLS_13_ticket_different_ciphers_ctx =
                    wolfSSL_get_SSL_CTX(ssl));
                ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_up_ref(
                    test_TLS_13_ticket_different_ciphers_ctx));
            }
            break;
        case 1:
            /* Second run */
            ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:"
                                                     "TLS13-AES128-GCM-SHA256"),
                            WOLFSSL_SUCCESS);
            if (!wolfSSL_is_server(ssl)) {
                ExpectIntEQ(wolfSSL_set_session(ssl,
                    test_TLS_13_ticket_different_ciphers_session),
                    WOLFSSL_SUCCESS);
            }
            break;
        default:
            /* Bad state? */
            Fail(("Should not enter here"), ("Should not enter here"));
    }

    return EXPECT_RESULT();
}

static int test_TLS_13_ticket_different_ciphers_on_result(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    switch (test_TLS_13_ticket_different_ciphers_run) {
        case 0:
            /* First run */
            ExpectNotNull(test_TLS_13_ticket_different_ciphers_session =
                    wolfSSL_get1_session(ssl));
            break;
        case 1:
            /* Second run */
            ExpectTrue(wolfSSL_session_reused(ssl));
            break;
        default:
            /* Bad state? */
            Fail(("Should not enter here"), ("Should not enter here"));
    }
    return EXPECT_RESULT();
}

static int test_TLS_13_ticket_different_ciphers(void)
{
    EXPECT_DECLS;
    /* Check that we handle the connection when the ticket doesn't match
     * the first ciphersuite. */
    test_ssl_cbf client_cbs, server_cbs;
    struct test_params {
        method_provider client_meth;
        method_provider server_meth;
        int doUdp;
    } params[] = {
#ifdef WOLFSSL_DTLS13
        /* Test that the stateless code handles sessions correctly */
        {wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, 1},
#endif
        {wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, 0},
    };
    size_t i;

    for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
        XMEMSET(&client_cbs, 0, sizeof(client_cbs));
        XMEMSET(&server_cbs, 0, sizeof(server_cbs));

        test_TLS_13_ticket_different_ciphers_run = 0;

        client_cbs.doUdp = server_cbs.doUdp = params[i].doUdp;

        client_cbs.method = params[i].client_meth;
        server_cbs.method = params[i].server_meth;

        client_cbs.ssl_ready = test_TLS_13_ticket_different_ciphers_ssl_ready;
        server_cbs.ssl_ready = test_TLS_13_ticket_different_ciphers_ssl_ready;

        client_cbs.on_result = test_TLS_13_ticket_different_ciphers_on_result;

        server_cbs.ticNoInit = 1;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
            &server_cbs, NULL), TEST_SUCCESS);

        test_TLS_13_ticket_different_ciphers_run++;

        server_cbs.ctx = test_TLS_13_ticket_different_ciphers_ctx;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
            &server_cbs, NULL), TEST_SUCCESS);

        wolfSSL_SESSION_free(test_TLS_13_ticket_different_ciphers_session);
        test_TLS_13_ticket_different_ciphers_session = NULL;
        wolfSSL_CTX_free(test_TLS_13_ticket_different_ciphers_ctx);
        test_TLS_13_ticket_different_ciphers_ctx = NULL;
    }

    return EXPECT_RESULT();
}
#else
static int test_TLS_13_ticket_different_ciphers(void)
{
    return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_EXTRA_ALERTS) && !defined(WOLFSSL_NO_TLS12) &&             \
    defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)

#define TEST_WRONG_CS_CLIENT "DHE-RSA-AES128-SHA"
/* AKA TLS_DHE_RSA_WITH_AES_128_CBC_SHA */

byte test_extra_alerts_wrong_cs_sh[] = {
  0x16, 0x03, 0x03, 0x00, 0x56, 0x02, 0x00, 0x00, 0x52, 0x03, 0x03, 0xef,
  0x0c, 0x30, 0x98, 0xa2, 0xac, 0xfa, 0x68, 0xe9, 0x3e, 0xaa, 0x5c, 0xcf,
  0xa7, 0x42, 0x72, 0xaf, 0xa0, 0xe8, 0x39, 0x2b, 0x3e, 0x81, 0xa7, 0x7a,
  0xa5, 0x62, 0x8a, 0x0e, 0x41, 0xba, 0xda, 0x20, 0x18, 0x9f, 0xe1, 0x8c,
  0x1d, 0xc0, 0x37, 0x9c, 0xf4, 0x90, 0x5d, 0x8d, 0xa0, 0x79, 0xa7, 0x4b,
  0xa8, 0x79, 0xdf, 0xcd, 0x8d, 0xf5, 0xb5, 0x50, 0x5f, 0xf1, 0xdb, 0x4d,
  0xbb, 0x07, 0x54, 0x1c,
  0x00, 0x02, /* TLS_RSA_WITH_NULL_SHA */
  0x00, 0x00, 0x0a, 0x00, 0x0b, 0x00,
  0x02, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00
};

static int test_extra_alerts_wrong_cs(void)
{
    EXPECT_DECLS;
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_ALERT_HISTORY h;
    WOLFSSL *ssl_c = NULL;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
        wolfTLSv1_2_client_method, NULL), 0);

    ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, TEST_WRONG_CS_CLIENT),
        WOLFSSL_SUCCESS);

    /* CH */
    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    /* consume CH */
    test_ctx.s_len = 0;
    /* inject SH */
    XMEMCPY(test_ctx.c_buff, test_extra_alerts_wrong_cs_sh,
        sizeof(test_extra_alerts_wrong_cs_sh));
    test_ctx.c_len = sizeof(test_extra_alerts_wrong_cs_sh);

    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntNE(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
    ExpectIntEQ(h.last_tx.code, handshake_failure);
    ExpectIntEQ(h.last_tx.level, alert_fatal);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
#endif
    return EXPECT_RESULT();
}
#else
static int test_extra_alerts_wrong_cs(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) &&   \
    defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)

#define TEST_CS_DOWNGRADE_CLIENT "ECDHE-RSA-AES256-GCM-SHA384"

byte test_wrong_cs_downgrade_sh[] = {
  0x16, 0x03, 0x03, 0x00, 0x56, 0x02, 0x00, 0x00, 0x52, 0x03, 0x03, 0x10,
  0x2c, 0x88, 0xd9, 0x7a, 0x23, 0xc9, 0xbd, 0x11, 0x3b, 0x64, 0x24, 0xab,
  0x5b, 0x45, 0x33, 0xf6, 0x2c, 0x34, 0xe4, 0xcf, 0xf4, 0x78, 0xc8, 0x62,
  0x06, 0xc7, 0xe5, 0x30, 0x39, 0xbf, 0xa1, 0x20, 0xa3, 0x06, 0x74, 0xc3,
  0xa9, 0x74, 0x52, 0x8a, 0xfb, 0xae, 0xf0, 0xd8, 0x6f, 0xb2, 0x9d, 0xfe,
  0x78, 0xf0, 0x3f, 0x51, 0x8f, 0x9c, 0xcf, 0xbe, 0x61, 0x43, 0x9d, 0xf8,
  0x85, 0xe5, 0x2f, 0x54,
  0xc0, 0x2f, /* ECDHE-RSA-AES128-GCM-SHA256 */
  0x00, 0x00, 0x0a, 0x00, 0x0b, 0x00,
  0x02, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00
};

static int test_wrong_cs_downgrade(void)
{
    EXPECT_DECLS;
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL *ssl_c = NULL;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
        wolfSSLv23_client_method, NULL), 0);

    ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, TEST_CS_DOWNGRADE_CLIENT),
        WOLFSSL_SUCCESS);

    /* CH */
    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    /* consume CH */
    test_ctx.s_len = 0;
    /* inject SH */
    XMEMCPY(test_ctx.c_buff, test_wrong_cs_downgrade_sh,
        sizeof(test_wrong_cs_downgrade_sh));
    test_ctx.c_len = sizeof(test_wrong_cs_downgrade_sh);

    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
#ifdef OPENSSL_EXTRA
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WC_NO_ERR_TRACE(WOLFSSL_ERROR_SYSCALL));
#else
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WC_NO_ERR_TRACE(MATCH_SUITE_ERROR));
#endif /* OPENSSL_EXTRA */


    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
#endif
    return EXPECT_RESULT();
}
#else
static int test_wrong_cs_downgrade(void)
{
    return TEST_SKIPPED;
}
#endif

#if !defined(WOLFSSL_NO_TLS12) && defined(WOLFSSL_EXTRA_ALERTS) &&             \
    defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_SP_MATH)

static void test_remove_msg(byte *msg, int tail_len, int *len, int msg_length)
{
    tail_len -= msg_length;
    XMEMMOVE(msg, msg + msg_length, tail_len);
    *len = *len - msg_length;
}

static int test_remove_hs_msg_from_buffer(byte *buf, int *len, byte type,
    byte *found)
{
    const unsigned int  _HANDSHAKE_HEADER_SZ = 4;
    const unsigned int _RECORD_HEADER_SZ = 5;
    const int _change_cipher_hs = 55;
    const int _change_cipher = 20;
    const int _handshake = 22;
    unsigned int tail_len;
    byte *idx, *curr;
    word8 currType;
    word16 rLength;
    word32 hLength;

    idx = buf;
    tail_len = (unsigned int)*len;
    *found = 0;
    while (tail_len > _RECORD_HEADER_SZ) {
        curr = idx;
        currType = *idx;
        ato16(idx + 3, &rLength);
        idx += _RECORD_HEADER_SZ;
        tail_len -= _RECORD_HEADER_SZ;

        if (tail_len < rLength)
            return -1;

        if (type == _change_cipher_hs && currType == _change_cipher) {
            if (rLength != 1)
                return -1;
            /* match */
            test_remove_msg(curr, *len - (int)(curr - buf),
                len, _RECORD_HEADER_SZ + 1);
            *found = 1;
            return 0;
        }

        if (currType != _handshake) {
            idx += rLength;
            tail_len -= rLength;
            continue;
        }

        if (rLength < _HANDSHAKE_HEADER_SZ)
            return -1;
        currType = *idx;
        ato24(idx+1, &hLength);
        hLength += _HANDSHAKE_HEADER_SZ;
        if (tail_len < hLength)
            return -1;
        if (currType != type) {
            idx += hLength;
            tail_len -= hLength;
            continue;
        }

        /* match */
        test_remove_msg(curr, *len - (int)(curr - buf), len,
            hLength + _RECORD_HEADER_SZ);
        *found = 1;
        return 0;
    }

    /* not found */
    return 0;
}

static int test_remove_hs_message(byte hs_message_type,
    int extra_round, byte alert_type)
{
    EXPECT_DECLS;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    WOLFSSL_ALERT_HISTORY h;
    byte found = 0;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);

    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    if (extra_round) {
        ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
            WOLFSSL_ERROR_WANT_READ);

        /* this will complete handshake from server side */
        ExpectIntEQ(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
    }

    ExpectIntEQ(test_remove_hs_msg_from_buffer(test_ctx.c_buff,
         &test_ctx.c_len, hs_message_type, &found), 0);

    if (!found) {
        wolfSSL_free(ssl_c);
        wolfSSL_CTX_free(ctx_c);
        wolfSSL_free(ssl_s);
        wolfSSL_CTX_free(ctx_s);
        return TEST_SKIPPED;
    }

    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntNE(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
    ExpectTrue(alert_type == 0xff || h.last_tx.code == alert_type);
    ExpectIntEQ(h.last_tx.level, alert_fatal);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);

    return EXPECT_RESULT();
}

static int test_extra_alerts_skip_hs(void)
{
    EXPECT_DECLS;
    const byte _server_key_exchange = 12;
    const byte _server_hello = 2;
    const byte _certificate = 11;

    /* server_hello */
    ExpectIntNE(test_remove_hs_message(_server_hello, 0,
        unexpected_message), TEST_FAIL);
    ExpectIntNE(test_remove_hs_message(_certificate, 0,
        0xff), TEST_FAIL);
    ExpectIntNE(test_remove_hs_message(_server_key_exchange, 0,
        unexpected_message), TEST_FAIL);

    return EXPECT_RESULT();
}
#else
static int test_extra_alerts_skip_hs(void)
{
    return TEST_SKIPPED;
}
#endif

#if !defined(WOLFSSL_NO_TLS12) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)\
    && defined(WOLFSSL_EXTRA_ALERTS) && !defined(NO_PSK) && !defined(NO_DH)

static unsigned int test_server_psk_cb(WOLFSSL* ssl, const char* id,
    unsigned char* key, unsigned int key_max_len)
{
    (void)ssl;
    (void)id;
    (void)key_max_len;
    /* zero means error */
    key[0] = 0x10;
    return 1;
}

static int test_extra_alerts_bad_psk(void)
{
    EXPECT_DECLS;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    WOLFSSL_ALERT_HISTORY h;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);

    ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, "DHE-PSK-AES128-GCM-SHA256"),
        WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, "DHE-PSK-AES128-GCM-SHA256"),
        WOLFSSL_SUCCESS);

    wolfSSL_set_psk_server_callback(ssl_s, test_server_psk_cb);

    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntNE(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
    ExpectIntEQ(h.last_tx.code, handshake_failure);
    ExpectIntEQ(h.last_tx.level, alert_fatal);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);

    return EXPECT_RESULT();
}
#else
static int test_extra_alerts_bad_psk(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(OPENSSL_EXTRA) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
/*
 * Emulates wolfSSL_shutdown that goes on EAGAIN,
 * by returning on output WOLFSSL_ERROR_WANT_WRITE.*/
static int custom_wolfSSL_shutdown(WOLFSSL *ssl, char *buf,
        int sz, void *ctx)
{
    (void)ssl;
    (void)buf;
    (void)ctx;
    (void)sz;

    return WOLFSSL_CBIO_ERR_WANT_WRITE;
}

static int test_multiple_alerts_EAGAIN(void)
{
    EXPECT_DECLS;
    size_t size_of_last_packet = 0;

    /* declare wolfSSL objects */
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL, *ssl_s = NULL;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    /* Create and initialize WOLFSSL_CTX and WOLFSSL objects */
#ifdef USE_TLSV13
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
          wolfTLSv1_3_client_method,  wolfTLSv1_3_server_method), 0);
#else
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
         wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
#endif
    ExpectNotNull(ctx_c);
    ExpectNotNull(ssl_c);
    ExpectNotNull(ctx_s);
    ExpectNotNull(ssl_s);

    /* Load client certificates into WOLFSSL_CTX */
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_c, "./certs/ca-cert.pem", NULL), WOLFSSL_SUCCESS);

    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    /*
     * We set the custom callback for the IO to emulate multiple EAGAINs
     * on shutdown, so we can check that we don't send multiple packets.
     * */
    wolfSSL_SSLSetIOSend(ssl_c, custom_wolfSSL_shutdown);

    /*
     * We call wolfSSL_shutdown multiple times to reproduce the behaviour,
     * to check that it doesn't add the CLOSE_NOTIFY packet multiple times
     * on the output buffer.
     * */
    wolfSSL_shutdown(ssl_c);
    wolfSSL_shutdown(ssl_c);

    if (ssl_c != NULL) {
        size_of_last_packet = ssl_c->buffers.outputBuffer.length;
    }
    wolfSSL_shutdown(ssl_c);

    /*
     * Finally we check the length of the output buffer.
     * */
    ExpectIntEQ((ssl_c->buffers.outputBuffer.length - size_of_last_packet), 0);

    /* Cleanup and return */
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_s);
    wolfSSL_free(ssl_s);

    return EXPECT_RESULT();
}
#else
static int test_multiple_alerts_EAGAIN(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(WOLFSSL_TLS13) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)\
    && !defined(NO_PSK)
static unsigned int test_tls13_bad_psk_binder_client_cb(WOLFSSL* ssl,
        const char* hint, char* identity, unsigned int id_max_len,
        unsigned char* key, unsigned int key_max_len)
{
    (void)ssl;
    (void)hint;
    (void)key_max_len;

    /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
    XSTRNCPY(identity, "Client_identity", id_max_len);

    key[0] = 0x20;
    return 1;
}

static unsigned int test_tls13_bad_psk_binder_server_cb(WOLFSSL* ssl,
        const char* id, unsigned char* key, unsigned int key_max_len)
{
    (void)ssl;
    (void)id;
    (void)key_max_len;
    /* zero means error */
    key[0] = 0x10;
    return 1;
}
#endif

static int test_tls13_bad_psk_binder(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)\
    && !defined(NO_PSK)
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    WOLFSSL_ALERT_HISTORY h;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);

    wolfSSL_set_psk_client_callback(ssl_c, test_tls13_bad_psk_binder_client_cb);
    wolfSSL_set_psk_server_callback(ssl_s, test_tls13_bad_psk_binder_server_cb);

    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
    ExpectIntEQ( wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WC_NO_ERR_TRACE(BAD_BINDER));

    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WC_NO_ERR_TRACE(FATAL_ERROR));
    ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
    ExpectIntEQ(h.last_rx.code, illegal_parameter);
    ExpectIntEQ(h.last_rx.level, alert_fatal);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
#endif
    return EXPECT_RESULT();
}

#if defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_NO_TLS12) && \
        defined(HAVE_IO_TESTS_DEPENDENCIES)
static int test_harden_no_secure_renegotiation_io_cb(WOLFSSL *ssl, char *buf,
        int sz, void *ctx)
{
    static int sentServerHello = FALSE;

    if (!sentServerHello) {
        byte renegExt[] = { 0xFF, 0x01, 0x00, 0x01, 0x00 };
        size_t i;

        if (sz < (int)sizeof(renegExt))
            return WOLFSSL_CBIO_ERR_GENERAL;

        /* Remove SCR from ServerHello */
        for (i = 0; i < sz - sizeof(renegExt); i++) {
            if (XMEMCMP(buf + i, renegExt, sizeof(renegExt)) == 0) {
                /* Found the extension. Change it to something unrecognized. */
                buf[i+1] = 0x11;
                break;
            }
        }
        sentServerHello = TRUE;
    }

    return EmbedSend(ssl, buf, sz, ctx);
}

static void test_harden_no_secure_renegotiation_ssl_ready(WOLFSSL* ssl)
{
    wolfSSL_SSLSetIOSend(ssl, test_harden_no_secure_renegotiation_io_cb);
}

static void test_harden_no_secure_renegotiation_on_cleanup(WOLFSSL* ssl)
{
    WOLFSSL_ALERT_HISTORY h;
    AssertIntEQ(wolfSSL_get_alert_history(ssl, &h), WOLFSSL_SUCCESS);
    AssertIntEQ(h.last_rx.code, handshake_failure);
    AssertIntEQ(h.last_rx.level, alert_fatal);
}

static int test_harden_no_secure_renegotiation(void)
{
    EXPECT_DECLS;
    callback_functions client_cbs, server_cbs;

    XMEMSET(&client_cbs, 0, sizeof(client_cbs));
    XMEMSET(&server_cbs, 0, sizeof(server_cbs));

    client_cbs.method = wolfTLSv1_2_client_method;
    server_cbs.method = wolfTLSv1_2_server_method;

    server_cbs.ssl_ready = test_harden_no_secure_renegotiation_ssl_ready;
    server_cbs.on_cleanup = test_harden_no_secure_renegotiation_on_cleanup;
    test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);

    ExpectIntEQ(client_cbs.return_code, TEST_FAIL);
    ExpectIntEQ(client_cbs.last_err, WC_NO_ERR_TRACE(SECURE_RENEGOTIATION_E));
    ExpectIntEQ(server_cbs.return_code, TEST_FAIL);
    ExpectTrue(server_cbs.last_err == WC_NO_ERR_TRACE(SOCKET_ERROR_E) ||
               server_cbs.last_err == WC_NO_ERR_TRACE(FATAL_ERROR));

    return EXPECT_RESULT();
}
#else
static int test_harden_no_secure_renegotiation(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(HAVE_OCSP) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_override_alt_cert_chain_cert_cb(int preverify,
        WOLFSSL_X509_STORE_CTX* store)
{
    fprintf(stderr, "preverify: %d\n", preverify);
    fprintf(stderr, "store->error: %d\n", store->error);
    fprintf(stderr, "error reason: %s\n", wolfSSL_ERR_reason_error_string(store->error));
    if (store->error == WC_NO_ERR_TRACE(OCSP_INVALID_STATUS)) {
        fprintf(stderr, "Overriding OCSP error\n");
        return 1;
    }
#ifndef WOLFSSL_ALT_CERT_CHAINS
    else if ((store->error == WC_NO_ERR_TRACE(ASN_NO_SIGNER_E) ||
              store->error == WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
    defined(HAVE_WEBSERVER)
            || store->error == WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
#endif
            ) && store->error_depth == store->totalCerts - 1) {
        fprintf(stderr, "Overriding no signer error only for root cert\n");
        return 1;
    }
#endif
    else
        return preverify;
}

static int test_override_alt_cert_chain_ocsp_cb(void* ioCtx, const char* url,
        int urlSz, unsigned char* request, int requestSz,
        unsigned char** response)
{
    (void)ioCtx;
    (void)url;
    (void)urlSz;
    (void)request;
    (void)requestSz;
    (void)response;
    return WOLFSSL_CBIO_ERR_GENERAL;
}

static int test_override_alt_cert_chain_client_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER,
            test_override_alt_cert_chain_cert_cb);
    ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL |
            WOLFSSL_OCSP_URL_OVERRIDE), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_SetOCSP_Cb(ctx,
            test_override_alt_cert_chain_ocsp_cb, NULL, NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_SetOCSP_OverrideURL(ctx, "not a url"),
            WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

static int test_override_alt_cert_chain_client_ctx_ready2(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
    ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL |
            WOLFSSL_OCSP_URL_OVERRIDE), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_SetOCSP_Cb(ctx,
            test_override_alt_cert_chain_ocsp_cb, NULL, NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_SetOCSP_OverrideURL(ctx, "not a url"),
            WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

static int test_override_alt_cert_chain_server_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx,
            "./certs/intermediate/server-chain-alt.pem"), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

static int test_override_alt_cert_chain(void)
{
    EXPECT_DECLS;
    size_t i;
    struct test_params {
        ctx_cb client_ctx_cb;
        ctx_cb server_ctx_cb;
        int result;
    } params[] = {
        {test_override_alt_cert_chain_client_ctx_ready,
                test_override_alt_cert_chain_server_ctx_ready, TEST_SUCCESS},
        {test_override_alt_cert_chain_client_ctx_ready2,
                test_override_alt_cert_chain_server_ctx_ready, -1001},
    };

    for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
        test_ssl_cbf client_cbs, server_cbs;
        XMEMSET(&client_cbs, 0, sizeof(client_cbs));
        XMEMSET(&server_cbs, 0, sizeof(server_cbs));

        fprintf(stderr, "test config: %d\n", (int)i);

        client_cbs.ctx_ready = params[i].client_ctx_cb;
        server_cbs.ctx_ready = params[i].server_ctx_cb;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
            &server_cbs, NULL), params[i].result);

        ExpectIntEQ(client_cbs.return_code,
                    params[i].result <= 0 ? -1000 : TEST_SUCCESS);
        ExpectIntEQ(server_cbs.return_code,
                    params[i].result <= 0 ? -1000 : TEST_SUCCESS);
    }

    return EXPECT_RESULT();
}
#else
static int test_override_alt_cert_chain(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(HAVE_RPK)

#define svrRpkCertFile     "./certs/rpk/server-cert-rpk.der"
#define clntRpkCertFile    "./certs/rpk/client-cert-rpk.der"

#if defined(WOLFSSL_ALWAYS_VERIFY_CB) && defined(WOLFSSL_TLS13)
static int MyRpkVerifyCb(int mode, WOLFSSL_X509_STORE_CTX* strctx)
{
    int ret = WOLFSSL_SUCCESS;
    (void)mode;
    (void)strctx;
    WOLFSSL_ENTER("MyRpkVerifyCb");
    return ret;
}
#endif /* WOLFSSL_ALWAYS_VERIFY_CB && WOLFSSL_TLS13 */

static WC_INLINE int test_rpk_memio_setup(
    struct test_memio_ctx *ctx,
    WOLFSSL_CTX **ctx_c,
    WOLFSSL_CTX **ctx_s,
    WOLFSSL **ssl_c,
    WOLFSSL **ssl_s,
    method_provider method_c,
    method_provider method_s,
    const char* certfile_c, int fmt_cc, /* client cert file path and format */
    const char* certfile_s, int fmt_cs, /* server cert file path and format */
    const char* pkey_c,     int fmt_kc, /* client private key and format */
    const char* pkey_s,     int fmt_ks  /* server private key and format */
    )
{
    int ret;
    if (ctx_c != NULL && *ctx_c == NULL) {
        *ctx_c = wolfSSL_CTX_new(method_c());
        if (*ctx_c == NULL) {
            return -1;
        }
        wolfSSL_CTX_set_verify(*ctx_c, WOLFSSL_VERIFY_PEER, NULL);

        ret = wolfSSL_CTX_load_verify_locations(*ctx_c, caCertFile, 0);
        if (ret != WOLFSSL_SUCCESS) {
            return -1;
        }
        wolfSSL_SetIORecv(*ctx_c, test_memio_read_cb);
        wolfSSL_SetIOSend(*ctx_c, test_memio_write_cb);

        ret = wolfSSL_CTX_use_certificate_file(*ctx_c, certfile_c, fmt_cc);
        if (ret != WOLFSSL_SUCCESS) {
            return -1;
        }
        ret = wolfSSL_CTX_use_PrivateKey_file(*ctx_c, pkey_c, fmt_kc);
        if (ret != WOLFSSL_SUCCESS) {
            return -1;
        }
    }

    if (ctx_s != NULL && *ctx_s == NULL) {
        *ctx_s = wolfSSL_CTX_new(method_s());
        if (*ctx_s == NULL) {
            return -1;
        }
        wolfSSL_CTX_set_verify(*ctx_s, WOLFSSL_VERIFY_PEER, NULL);

        ret = wolfSSL_CTX_load_verify_locations(*ctx_s, cliCertFile, 0);
        if (ret != WOLFSSL_SUCCESS) {
            return -1;
        }

        ret = wolfSSL_CTX_use_PrivateKey_file(*ctx_s, pkey_s, fmt_ks);
        if (ret != WOLFSSL_SUCCESS) {
            return -1;
        }
        ret = wolfSSL_CTX_use_certificate_file(*ctx_s, certfile_s, fmt_cs);
        if (ret != WOLFSSL_SUCCESS) {
            return -1;
        }
        wolfSSL_SetIORecv(*ctx_s, test_memio_read_cb);
        wolfSSL_SetIOSend(*ctx_s, test_memio_write_cb);
        if (ctx->s_ciphers != NULL) {
            ret = wolfSSL_CTX_set_cipher_list(*ctx_s, ctx->s_ciphers);
            if (ret != WOLFSSL_SUCCESS) {
                return -1;
            }
        }
    }

    if (ctx_c != NULL && ssl_c != NULL) {
        *ssl_c = wolfSSL_new(*ctx_c);
        if (*ssl_c == NULL) {
            return -1;
        }
        wolfSSL_SetIOWriteCtx(*ssl_c, ctx);
        wolfSSL_SetIOReadCtx(*ssl_c, ctx);
    }
    if (ctx_s != NULL && ssl_s != NULL) {
        *ssl_s = wolfSSL_new(*ctx_s);
        if (*ssl_s == NULL) {
            return -1;
        }
        wolfSSL_SetIOWriteCtx(*ssl_s, ctx);
        wolfSSL_SetIOReadCtx(*ssl_s, ctx);
#if !defined(NO_DH)
        SetDH(*ssl_s);
#endif
    }

    return 0;
}
#endif /* HAVE_RPK */

static int test_rpk_set_xxx_cert_type(void)
{
    EXPECT_DECLS;
#if defined(HAVE_RPK)

    char ctype[MAX_CLIENT_CERT_TYPE_CNT + 1];   /* prepare bigger buffer */
    WOLFSSL_CTX* ctx = NULL;
    WOLFSSL* ssl = NULL;
    int tp;

    ctx = wolfSSL_CTX_new(wolfTLS_client_method());
    ExpectNotNull(ctx);

    ssl = wolfSSL_new(ctx);
    ExpectNotNull(ssl);

    /*--------------------------------------------*/
    /* tests for wolfSSL_CTX_set_client_cert_type */
    /*--------------------------------------------*/

    /* illegal parameter test caces */
    ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(NULL, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
                                                sizeof(ctype)),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ctype[0] = WOLFSSL_CERT_TYPE_RPK;  /* set an identical cert type */
    ctype[1] = WOLFSSL_CERT_TYPE_RPK;

    ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ctype[0] = WOLFSSL_CERT_TYPE_X509;
    ctype[1] = 10;                      /* set unknown cert type */

    ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* pass larger type count */
    ctype[0] = WOLFSSL_CERT_TYPE_RPK;
    ctype[1] = WOLFSSL_CERT_TYPE_X509;
    ctype[2] = 1;                       /* pass unacceptable type count */

    ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT + 1),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* should accept NULL for type buffer */
    ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, NULL,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WOLFSSL_SUCCESS);

    /* should accept zero for type count */
    ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
                                                0),
                                                WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WOLFSSL_SUCCESS);

    /*--------------------------------------------*/
    /* tests for wolfSSL_CTX_set_server_cert_type */
    /*--------------------------------------------*/

    ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(NULL, ctype,
                                                MAX_SERVER_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
                                                sizeof(ctype)),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ctype[0] = WOLFSSL_CERT_TYPE_RPK;  /* set an identical cert type */
    ctype[1] = WOLFSSL_CERT_TYPE_RPK;

    ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
                                                MAX_SERVER_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ctype[0] = WOLFSSL_CERT_TYPE_X509;
    ctype[1] = 10;                      /* set unknown cert type */

    ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
                                                MAX_SERVER_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* pass larger type count */
    ctype[0] = WOLFSSL_CERT_TYPE_RPK;
    ctype[1] = WOLFSSL_CERT_TYPE_X509;
    ctype[2] = 1;                       /* pass unacceptable type count */

    ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
                                                MAX_SERVER_CERT_TYPE_CNT + 1),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* should accept NULL for type buffer */
    ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, NULL,
                                                MAX_SERVER_CERT_TYPE_CNT),
                                                WOLFSSL_SUCCESS);

    /* should accept zero for type count */
    ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
                                                0),
                                                WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WOLFSSL_SUCCESS);

    /*--------------------------------------------*/
    /* tests for wolfSSL_set_client_cert_type */
    /*--------------------------------------------*/

    ExpectIntEQ(wolfSSL_set_client_cert_type(NULL, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
                                                sizeof(ctype)),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ctype[0] = WOLFSSL_CERT_TYPE_RPK;  /* set an identical cert type */
    ctype[1] = WOLFSSL_CERT_TYPE_RPK;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ctype[0] = WOLFSSL_CERT_TYPE_X509;
    ctype[1] = 10;                      /* set unknown cert type */

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* pass larger type count */
    ctype[0] = WOLFSSL_CERT_TYPE_RPK;
    ctype[1] = WOLFSSL_CERT_TYPE_X509;
    ctype[2] = 1;                       /* pass unacceptable type count */

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT + 1),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* should accept NULL for type buffer */
    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, NULL,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WOLFSSL_SUCCESS);

    /* should accept zero for type count */
    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
                                                0),
                                                WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
                                                MAX_CLIENT_CERT_TYPE_CNT),
                                                WOLFSSL_SUCCESS);

    /*--------------------------------------------*/
    /* tests for wolfSSL_CTX_set_server_cert_type */
    /*--------------------------------------------*/

    ExpectIntEQ(wolfSSL_set_server_cert_type(NULL, ctype,
                                                MAX_SERVER_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
                                                sizeof(ctype)),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ctype[0] = WOLFSSL_CERT_TYPE_RPK;  /* set an identical cert type */
    ctype[1] = WOLFSSL_CERT_TYPE_RPK;

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
                                                MAX_SERVER_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ctype[0] = WOLFSSL_CERT_TYPE_X509;
    ctype[1] = 10;                      /* set unknown cert type */

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
                                                MAX_SERVER_CERT_TYPE_CNT),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    /* pass larger type count */
    ctype[0] = WOLFSSL_CERT_TYPE_RPK;
    ctype[1] = WOLFSSL_CERT_TYPE_X509;
    ctype[2] = 1;                       /* pass unacceptable type count */

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
                                                MAX_SERVER_CERT_TYPE_CNT + 1),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    /* should accept NULL for type buffer */
    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, NULL,
                                                MAX_SERVER_CERT_TYPE_CNT),
                                                WOLFSSL_SUCCESS);

    /* should accept zero for type count */
    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
                                                0),
                                                WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
                                                MAX_SERVER_CERT_TYPE_CNT),
                                                WOLFSSL_SUCCESS);

    /*------------------------------------------------*/
    /* tests for wolfSSL_get_negotiated_xxx_cert_type */
    /*------------------------------------------------*/

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(NULL, &tp),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl, NULL),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(NULL, &tp),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl, NULL),
                                                WC_NO_ERR_TRACE(BAD_FUNC_ARG));


    /* clean up */
    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);

#endif
    return EXPECT_RESULT();
}

static int test_tls13_rpk_handshake(void)
{
    EXPECT_DECLS;
#if defined(HAVE_RPK) && (!defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13))
#ifdef WOLFSSL_TLS13
    int ret = 0;
#endif
    WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    int err;
    char certType_c[MAX_CLIENT_CERT_TYPE_CNT];
    char certType_s[MAX_CLIENT_CERT_TYPE_CNT];
    int typeCnt_c;
    int typeCnt_s;
    int tp = 0;
#if defined(WOLFSSL_ALWAYS_VERIFY_CB) && defined(WOLFSSL_TLS13)
    int isServer;
#endif

    (void)err;
    (void)typeCnt_c;
    (void)typeCnt_s;
    (void)certType_c;
    (void)certType_s;

#ifndef WOLFSSL_NO_TLS12
    /*  TLS1.2
     *  Both client and server load x509 cert and start handshaking.
     *  Check no negotiation occurred.
     */
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(
        test_rpk_memio_setup(
            &test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_2_client_method, wolfTLSv1_2_server_method,
            cliCertFile,     WOLFSSL_FILETYPE_PEM,
            svrCertFile,     WOLFSSL_FILETYPE_PEM,
            cliKeyFile,      WOLFSSL_FILETYPE_PEM,
            svrKeyFile,      WOLFSSL_FILETYPE_PEM)
        , 0);


    /* set client certificate type in client end */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_c = 2;

    certType_s[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_s[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_s = 2;

    /*  both client and server do not call client/server_cert_type APIs,
     *  expecting default settings works and no negotiation performed.
     */

    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    /* confirm no negotiation occurred */
    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_c, &tp),
                                                            WOLFSSL_SUCCESS);
    ExpectIntEQ((int)tp, WOLFSSL_CERT_TYPE_UNKNOWN);
    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_c, &tp),
                                                            WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);
    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_s, &tp),
                                                            WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_s, &tp),
                                                            WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    (void)typeCnt_c;
    (void)typeCnt_s;

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;
#endif

#ifdef WOLFSSL_TLS13
    /*  Both client and server load x509 cert and start handshaking.
     *  Check no negotiation occurred.
     */
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(
        test_rpk_memio_setup(
            &test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
            cliCertFile,     WOLFSSL_FILETYPE_PEM,
            svrCertFile,     WOLFSSL_FILETYPE_PEM,
            cliKeyFile,      WOLFSSL_FILETYPE_PEM,
            svrKeyFile,      WOLFSSL_FILETYPE_PEM )
        , 0);

    /* set client certificate type in client end */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_c = 2;

    certType_s[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_s[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_s = 2;

    /*  both client and server do not call client/server_cert_type APIs,
     *  expecting default settings works and no negotiation performed.
     */

    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    /* confirm no negotiation occurred */
    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ((int)tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    (void)typeCnt_c;
    (void)typeCnt_s;

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;


    /*  Both client and server load RPK cert and start handshaking.
     *  Confirm negotiated cert types match as expected.
     */
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(
        test_rpk_memio_setup(
            &test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
            clntRpkCertFile, WOLFSSL_FILETYPE_ASN1,
            svrRpkCertFile,  WOLFSSL_FILETYPE_ASN1,
            cliKeyFile,      WOLFSSL_FILETYPE_PEM,
            svrKeyFile,      WOLFSSL_FILETYPE_PEM )
        , 0);

    /* set client certificate type in client end */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_c = 2;

    certType_s[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_s[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_s = 2;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_c, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* set server certificate type in client end */
    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_c, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    /* set client certificate type in server end */
    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_s, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* set server certificate type in server end */
    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_s, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;
#endif


#ifndef WOLFSSL_NO_TLS12
    /*  TLS1.2
     *  Both client and server load RPK cert and start handshaking.
     *  Confirm negotiated cert types match as expected.
     */
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(
        test_rpk_memio_setup(
            &test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_2_client_method, wolfTLSv1_2_server_method,
            clntRpkCertFile, WOLFSSL_FILETYPE_ASN1,
            svrRpkCertFile,  WOLFSSL_FILETYPE_ASN1,
            cliKeyFile,      WOLFSSL_FILETYPE_PEM,
            svrKeyFile,      WOLFSSL_FILETYPE_PEM )
        , 0);

    /* set client certificate type in client end */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_c = 2;

    certType_s[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_s[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_s = 2;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_c, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* set server certificate type in client end */
    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_c, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    /* set client certificate type in server end */
    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_s, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* set server certificate type in server end */
    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_s, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    if (test_memio_do_handshake(ssl_c, ssl_s, 10, NULL) != 0)
        return TEST_FAIL;

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;
#endif


#ifdef WOLFSSL_TLS13
    /*  Both client and server load x509 cert.
     *  Have client call set_client_cert_type with both RPK and x509.
     *  This doesn't makes client add client cert type extension to ClientHello,
     *  since it does not load RPK cert actually.
     */
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(
        test_rpk_memio_setup(
            &test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
            cliCertFile,     WOLFSSL_FILETYPE_PEM,
            svrCertFile,     WOLFSSL_FILETYPE_PEM,
            cliKeyFile,      WOLFSSL_FILETYPE_PEM,
            svrKeyFile,      WOLFSSL_FILETYPE_PEM )
        , 0);

    /* set client certificate type in client end
     *
     * client indicates both RPK and x509 certs are available but loaded RPK
     * cert only. It does not have client add client-cert-type extension in CH.
     */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_c = 2;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_c, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* client indicates both RPK and x509 certs are acceptable */
    certType_s[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_s[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_s = 2;

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_c, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    /* server indicates both RPK and x509 certs are acceptable */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_c = 2;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_s, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* server should indicate only RPK cert is available */
    certType_s[0] = WOLFSSL_CERT_TYPE_X509;
    certType_s[1] = -1;
    typeCnt_s = 1;

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_s, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    if (test_memio_do_handshake(ssl_c, ssl_s, 10, NULL) != 0)
        return TEST_FAIL;

    /* Negotiation for client-cert-type should NOT happen. Therefore -1 should
     * be returned as cert type.
     */
    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_X509);

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_X509);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;


    /*  Have client load RPK cert and have server load x509 cert.
     *  Check the negotiation result from both ends.
     */
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(
        test_rpk_memio_setup(
            &test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
            clntRpkCertFile, WOLFSSL_FILETYPE_ASN1,
            svrCertFile,     WOLFSSL_FILETYPE_PEM,
            cliKeyFile,      WOLFSSL_FILETYPE_PEM,
            svrKeyFile,      WOLFSSL_FILETYPE_PEM )
        , 0);

    /* have client tell to use RPK cert */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = -1;
    typeCnt_c = 1;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_c, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* have client tell to accept both RPK and x509 cert */
    certType_s[0] = WOLFSSL_CERT_TYPE_X509;
    certType_s[1] = WOLFSSL_CERT_TYPE_RPK;
    typeCnt_s = 2;

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_c, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    /* have server accept to both RPK and x509 cert */
    certType_c[0] = WOLFSSL_CERT_TYPE_X509;
    certType_c[1] = WOLFSSL_CERT_TYPE_RPK;
    typeCnt_c = 2;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_s, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* does not call wolfSSL_set_server_cert_type intentionally in sesrver
     * end, expecting the default setting works.
     */


    if (test_memio_do_handshake(ssl_c, ssl_s, 10, NULL) != 0)
        return TEST_FAIL;

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_X509);

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_X509);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;


    /*  Have both client and server load RPK cert, however, have server
     *  indicate its cert type x509.
     *  Client is expected to detect the cert type mismatch then to send alert
     *  with "unsupported_certificate".
     */
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(
        test_rpk_memio_setup(
            &test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
            clntRpkCertFile, WOLFSSL_FILETYPE_ASN1,
            svrRpkCertFile,  WOLFSSL_FILETYPE_ASN1, /* server sends RPK cert */
            cliKeyFile,      WOLFSSL_FILETYPE_PEM,
            svrKeyFile,      WOLFSSL_FILETYPE_PEM )
        , 0);

    /* have client tell to use RPK cert */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = -1;
    typeCnt_c = 1;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_c, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* have client tell to accept both RPK and x509 cert */
    certType_s[0] = WOLFSSL_CERT_TYPE_X509;
    certType_s[1] = WOLFSSL_CERT_TYPE_RPK;
    typeCnt_s = 2;

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_c, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    /* have server accept to both RPK and x509 cert */
    certType_c[0] = WOLFSSL_CERT_TYPE_X509;
    certType_c[1] = WOLFSSL_CERT_TYPE_RPK;
    typeCnt_c = 2;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_s, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* have server tell to use x509 cert intentionally. This will bring
     * certificate type mismatch in client side.
     */
    certType_s[0] = WOLFSSL_CERT_TYPE_X509;
    certType_s[1] = -1;
    typeCnt_s = 1;

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_s, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    /* expect client detect cert type mismatch then send Alert */
    ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
    if (ret != -1)
        return TEST_FAIL;

    ExpectIntEQ(wolfSSL_get_error(ssl_c, ret), WC_NO_ERR_TRACE(UNSUPPORTED_CERTIFICATE));

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_X509);

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_X509);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;


    /*  Have client load x509 cert and server load RPK cert,
     *  however, have client indicate its cert type RPK.
     *  Server is expected to detect the cert type mismatch then to send alert
     *  with "unsupported_certificate".
     */
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(
        test_rpk_memio_setup(
            &test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
            cliCertFile,     WOLFSSL_FILETYPE_PEM,
            svrRpkCertFile,  WOLFSSL_FILETYPE_ASN1,
            cliKeyFile,      WOLFSSL_FILETYPE_PEM,
            svrKeyFile,      WOLFSSL_FILETYPE_PEM )
        , 0);

    /* have client tell to use RPK cert intentionally */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = -1;
    typeCnt_c = 1;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_c, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* have client tell to accept both RPK and x509 cert */
    certType_s[0] = WOLFSSL_CERT_TYPE_X509;
    certType_s[1] = WOLFSSL_CERT_TYPE_RPK;
    typeCnt_s = 2;

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_c, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    /* have server accept to both RPK and x509 cert */
    certType_c[0] = WOLFSSL_CERT_TYPE_X509;
    certType_c[1] = WOLFSSL_CERT_TYPE_RPK;
    typeCnt_c = 2;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_s, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* have server tell to use x509 cert intentionally. This will bring
     * certificate type mismatch in client side.
     */
    certType_s[0] = WOLFSSL_CERT_TYPE_X509;
    certType_s[1] = -1;
    typeCnt_s = 1;

    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_s, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);

    /* expect server detect cert type mismatch then send Alert */
    ExpectIntNE(ret, 0);
    err = wolfSSL_get_error(ssl_c, ret);
    ExpectIntEQ(err, WC_NO_ERR_TRACE(UNSUPPORTED_CERTIFICATE));

    /* client did not load RPK cert actually, so negotiation did not happen */
    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_X509);

    /* client did not load RPK cert actually, so negotiation did not happen */
    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_X509);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;


#if defined(WOLFSSL_ALWAYS_VERIFY_CB)
    /*  Both client and server load RPK cert and set certificate verify
     *  callbacks then start handshaking.
     *  Confirm both side can refer the peer's cert.
     */
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(
        test_rpk_memio_setup(
            &test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
            clntRpkCertFile, WOLFSSL_FILETYPE_ASN1,
            svrRpkCertFile,  WOLFSSL_FILETYPE_ASN1,
            cliKeyFile,      WOLFSSL_FILETYPE_PEM,
            svrKeyFile,      WOLFSSL_FILETYPE_PEM )
        , 0);

    /* set client certificate type in client end */
    certType_c[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_c[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_c = 2;

    certType_s[0] = WOLFSSL_CERT_TYPE_RPK;
    certType_s[1] = WOLFSSL_CERT_TYPE_X509;
    typeCnt_s = 2;

    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_c, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* set server certificate type in client end */
    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_c, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    /* set client certificate type in server end */
    ExpectIntEQ(wolfSSL_set_client_cert_type(ssl_s, certType_c, typeCnt_c),
                                                        WOLFSSL_SUCCESS);

    /* set server certificate type in server end */
    ExpectIntEQ(wolfSSL_set_server_cert_type(ssl_s, certType_s, typeCnt_s),
                                                        WOLFSSL_SUCCESS);

    /* set certificate verify callback to both client and server */
    isServer = 0;
    wolfSSL_SetCertCbCtx(ssl_c, &isServer);
    wolfSSL_set_verify(ssl_c, SSL_VERIFY_PEER, MyRpkVerifyCb);

    isServer = 1;
    wolfSSL_SetCertCbCtx(ssl_c, &isServer);
    wolfSSL_set_verify(ssl_s, SSL_VERIFY_PEER, MyRpkVerifyCb);

    ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
    if (ret != 0)
        return TEST_FAIL;

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_c, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl_s, &tp),
                                                        WOLFSSL_SUCCESS);
    ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;
#endif /* WOLFSSL_ALWAYS_VERIFY_CB */
#endif /* WOLFSSL_TLS13 */

#endif /* HAVE_RPK && (!WOLFSSL_NO_TLS12 || WOLFSSL_TLS13) */
    return EXPECT_RESULT();
}

#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)


static int test_dtls13_bad_epoch_ch(void)
{
    EXPECT_DECLS;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    const int EPOCH_OFF = 3;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);

    /* disable hrr cookie so we can later check msgsReceived.got_client_hello
     *  with just one message */
    ExpectIntEQ(wolfSSL_disable_hrr_cookie(ssl_s), WOLFSSL_SUCCESS);

    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    ExpectIntGE(test_ctx.s_len, EPOCH_OFF + 2);

    /* first CH should use epoch 0x0 */
    ExpectTrue((test_ctx.s_buff[EPOCH_OFF] == 0x0) &&
        (test_ctx.s_buff[EPOCH_OFF + 1] == 0x0));

    /* change epoch to 2 */
    test_ctx.s_buff[EPOCH_OFF + 1] = 0x2;

    ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    ExpectIntNE(ssl_s->msgsReceived.got_client_hello, 1);

    /* resend the CH */
    ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);

    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);

    return EXPECT_RESULT();
}
#else
static int test_dtls13_bad_epoch_ch(void)
{
    return TEST_SKIPPED;
}
#endif

#if ((defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
      defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_HAVE_ID) && \
      !defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)) || \
     (!defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
      !defined(NO_DES3))) || !defined(WOLFSSL_NO_TLS12)) && \
    !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
    defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && !defined(NO_SESSION_CACHE)
static int test_short_session_id_ssl_ready(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    WOLFSSL_SESSION *sess = NULL;
    /* Setup the session to avoid errors */
    ssl->session->timeout = (word32)-1;
    ssl->session->side = WOLFSSL_CLIENT_END;
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
                               defined(HAVE_SESSION_TICKET))
    ssl->session->version = ssl->version;
#endif
    /* Force a short session ID to be sent */
    ssl->session->sessionIDSz = 4;
#ifndef NO_SESSION_CACHE_REF
    /* Allow the client cache to be used */
    ssl->session->idLen = 4;
#endif
    ssl->session->isSetup = 1;
    ExpectNotNull(sess = wolfSSL_get_session(ssl));
    ExpectIntEQ(wolfSSL_set_session(ssl, sess), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

static int test_short_session_id(void)
{
    EXPECT_DECLS;
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;
    size_t i;
    struct {
        method_provider client_meth;
        method_provider server_meth;
        const char* tls_version;
    } params[] = {
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
    defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_HAVE_ID) && \
    !defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
/* With WOLFSSL_TLS13_MIDDLEBOX_COMPAT a short ID will result in an error */
        { wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" },
#ifdef WOLFSSL_DTLS13
        { wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" },
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
        { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" },
#ifdef WOLFSSL_DTLS
        { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" },
#endif
#endif
#if !defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
        !defined(NO_DES3))
        { wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" },
#ifdef WOLFSSL_DTLS
        { wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" },
#endif
#endif
    };

    fprintf(stderr, "\n");

    for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) {
        XMEMSET(&client_cbf, 0, sizeof(client_cbf));
        XMEMSET(&server_cbf, 0, sizeof(server_cbf));

        fprintf(stderr, "\tTesting short ID with %s\n", params[i].tls_version);

        client_cbf.ssl_ready = test_short_session_id_ssl_ready;
        client_cbf.method = params[i].client_meth;
        server_cbf.method = params[i].server_meth;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
            &server_cbf, NULL), TEST_SUCCESS);
    }
    return EXPECT_RESULT();
}
#else
static int test_short_session_id(void)
{
    return TEST_SKIPPED;
}
#endif

#if defined(HAVE_NULL_CIPHER) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) \
    && defined(WOLFSSL_DTLS13)
static byte* test_find_string(const char *string,
    byte *buf, int buf_size)
{
    int string_size, i;

    string_size = (int)XSTRLEN(string);
    for (i = 0; i < buf_size - string_size - 1; i++) {
        if (XSTRCMP((char*)&buf[i], string) == 0)
            return &buf[i];
    }
    return NULL;
}

static int test_wolfSSL_dtls13_null_cipher(void)
{
    EXPECT_DECLS;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    const char *test_str = "test";
    int test_str_size;
    byte buf[255], *ptr = NULL;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    test_ctx.c_ciphers = test_ctx.s_ciphers = "TLS13-SHA256-SHA256";
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
    test_str_size = XSTRLEN("test") + 1;
    ExpectIntEQ(wolfSSL_write(ssl_c, test_str, test_str_size), test_str_size);
    ExpectIntEQ(wolfSSL_read(ssl_s, buf, sizeof(buf)), test_str_size);
    ExpectIntEQ(XSTRCMP((char*)buf, test_str), 0);

    ExpectIntEQ(wolfSSL_write(ssl_c, test_str, test_str_size), test_str_size);

    /* check that the packet was sent cleartext */
    ExpectNotNull(ptr = test_find_string(test_str, test_ctx.s_buff,
        test_ctx.s_len));
    if (ptr != NULL) {
        /* modify the message */
        *ptr = 'H';
        /* bad messages should be ignored in DTLS */
        ExpectIntEQ(wolfSSL_read(ssl_s, buf, sizeof(buf)), -1);
        ExpectIntEQ(ssl_s->error, WC_NO_ERR_TRACE(WANT_READ));
    }

    ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE);
    ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);
    ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1);
    ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1);

    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
    return TEST_SUCCESS;
}
#else
static int test_wolfSSL_dtls13_null_cipher(void)
{
    return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) &&          \
    !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) &&   \
    !defined(SINGLE_THREADED) && !defined(NO_RSA)

static int test_dtls_msg_get_connected_port(int fd, word16 *port)
{
    SOCKADDR_S peer;
    XSOCKLENT len;
    int ret;

    XMEMSET((byte*)&peer, 0, sizeof(peer));
    len = sizeof(peer);
    ret = getpeername(fd,  (SOCKADDR*)&peer, &len);
    if (ret != 0 || len > (XSOCKLENT)sizeof(peer))
        return -1;
    switch (peer.ss_family) {
#ifdef WOLFSSL_IPV6
    case WOLFSSL_IP6: {
        *port = ntohs(((SOCKADDR_IN6*)&peer)->sin6_port);
        break;
    }
#endif /* WOLFSSL_IPV6 */
    case WOLFSSL_IP4:
        *port = ntohs(((SOCKADDR_IN*)&peer)->sin_port);
        break;
    default:
        return -1;
    }
    return 0;
}

static int test_dtls_msg_from_other_peer_cb(WOLFSSL_CTX *ctx, WOLFSSL *ssl)
{
    char buf[1] = {'t'};
    SOCKADDR_IN_T addr;
    int sock_fd;
    word16 port;
    int err;

    (void)ssl;
    (void)ctx;

    if (ssl == NULL)
        return -1;

    err = test_dtls_msg_get_connected_port(wolfSSL_get_fd(ssl), &port);
    if (err != 0)
        return -1;

    sock_fd = socket(AF_INET_V, SOCK_DGRAM, 0);
    if (sock_fd == -1)
        return -1;
    build_addr(&addr, wolfSSLIP, port, 1, 0);

    /* send a packet to the server. Being another socket, the kernel will ensure
     * the source port will be different. */
    err = (int)sendto(sock_fd, buf, sizeof(buf), 0, (SOCKADDR*)&addr,
        sizeof(addr));

    close(sock_fd);
    if (err == -1)
        return -1;

    return 0;
}

/* setup a SSL session but just after the handshake send a packet to the server
 * with a source address different than the one of the connected client. The I/O
 * callback EmbedRecvFrom should just ignore the packet. Sending of the packet
 * is done in test_dtls_msg_from_other_peer_cb */
static int test_dtls_msg_from_other_peer(void)
{
    EXPECT_DECLS;
    callback_functions client_cbs;
    callback_functions server_cbs;

    XMEMSET((byte*)&client_cbs, 0, sizeof(client_cbs));
    XMEMSET((byte*)&server_cbs, 0, sizeof(server_cbs));

    client_cbs.method = wolfDTLSv1_2_client_method;
    server_cbs.method = wolfDTLSv1_2_server_method;
    client_cbs.doUdp = 1;
    server_cbs.doUdp = 1;

    test_wolfSSL_client_server_nofail_ex(&client_cbs, &server_cbs,
        test_dtls_msg_from_other_peer_cb);

    ExpectIntEQ(client_cbs.return_code, WOLFSSL_SUCCESS);
    ExpectIntEQ(server_cbs.return_code, WOLFSSL_SUCCESS);

    return EXPECT_RESULT();
}
#else
static int test_dtls_msg_from_other_peer(void)
{
    return TEST_SKIPPED;
}
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) &&          \
        *  !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) &&  \
        *  !defined(SINGLE_THREADED) && !defined(NO_RSA) */
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_IPV6) &&               \
    !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) &&   \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
static int test_dtls_ipv6_check(void)
{
    EXPECT_DECLS;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    SOCKADDR_IN fake_addr6;
    int sockfd = -1;

    ExpectNotNull(ctx_c = wolfSSL_CTX_new(wolfDTLSv1_2_client_method()));
    ExpectNotNull(ssl_c  = wolfSSL_new(ctx_c));
    ExpectNotNull(ctx_s = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()));
    ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile,
        WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile,
        WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectNotNull(ssl_s  = wolfSSL_new(ctx_s));
    XMEMSET((byte*)&fake_addr6, 0, sizeof(fake_addr6));
    /* mimic a sockaddr_in6 struct, this way we can't test without
     *  WOLFSSL_IPV6 */
    fake_addr6.sin_family = WOLFSSL_IP6;
    ExpectIntNE(sockfd = socket(AF_INET, SOCK_DGRAM, 0), -1);
    ExpectIntEQ(wolfSSL_set_fd(ssl_c, sockfd), WOLFSSL_SUCCESS);
    /* can't return error here, as the peer is opaque for wolfssl library at
     * this point */
    ExpectIntEQ(wolfSSL_dtls_set_peer(ssl_c, &fake_addr6, sizeof(fake_addr6)),
        WOLFSSL_SUCCESS);
    ExpectIntNE(fcntl(sockfd, F_SETFL, O_NONBLOCK), -1);
    wolfSSL_dtls_set_using_nonblock(ssl_c, 1);
    ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
    ExpectIntEQ(ssl_c->error, WC_NO_ERR_TRACE(SOCKET_ERROR_E));

    ExpectIntEQ(wolfSSL_dtls_set_peer(ssl_s, &fake_addr6, sizeof(fake_addr6)),
        WOLFSSL_SUCCESS);
    /* reuse the socket */
    ExpectIntEQ(wolfSSL_set_fd(ssl_c, sockfd), WOLFSSL_SUCCESS);
    wolfSSL_dtls_set_using_nonblock(ssl_s, 1);
    ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
    ExpectIntEQ(ssl_s->error, WC_NO_ERR_TRACE(SOCKET_ERROR_E));
    if (sockfd != -1)
        close(sockfd);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
    return EXPECT_RESULT();
}
#else
static int test_dtls_ipv6_check(void)
{
    return TEST_SKIPPED;
}
#endif

#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) &&   \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)

static WOLFSSL_SESSION* test_wolfSSL_SCR_after_resumption_session = NULL;

static void test_wolfSSL_SCR_after_resumption_ctx_ready(WOLFSSL_CTX* ctx)
{
    AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
}

static void test_wolfSSL_SCR_after_resumption_on_result(WOLFSSL* ssl)
{
    if (test_wolfSSL_SCR_after_resumption_session == NULL) {
        test_wolfSSL_SCR_after_resumption_session = wolfSSL_get1_session(ssl);
        AssertNotNull(test_wolfSSL_SCR_after_resumption_session);
    }
    else {
        char testMsg[] = "Message after SCR";
        char msgBuf[sizeof(testMsg)];
        int ret;
        if (!wolfSSL_is_server(ssl)) {
            AssertIntEQ(WOLFSSL_SUCCESS,
                    wolfSSL_set_session(ssl,
                       test_wolfSSL_SCR_after_resumption_session));
        }
        AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_SUCCESS);
        AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
                    sizeof(testMsg));
        ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
        if (ret != sizeof(msgBuf)) /* Possibly APP_DATA_READY error. Retry. */
            ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
        AssertIntEQ(ret, sizeof(msgBuf));
    }
}

static void test_wolfSSL_SCR_after_resumption_ssl_ready(WOLFSSL* ssl)
{
    AssertIntEQ(WOLFSSL_SUCCESS,
           wolfSSL_set_session(ssl, test_wolfSSL_SCR_after_resumption_session));
}

static int test_wolfSSL_SCR_after_resumption(void)
{
    EXPECT_DECLS;
    callback_functions func_cb_client;
    callback_functions func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

    func_cb_client.method = wolfTLSv1_2_client_method;
    func_cb_client.ctx_ready = test_wolfSSL_SCR_after_resumption_ctx_ready;
    func_cb_client.on_result = test_wolfSSL_SCR_after_resumption_on_result;
    func_cb_server.method = wolfTLSv1_2_server_method;
    func_cb_server.ctx_ready = test_wolfSSL_SCR_after_resumption_ctx_ready;

    test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

    ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
    ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);

    func_cb_client.ssl_ready = test_wolfSSL_SCR_after_resumption_ssl_ready;
    func_cb_server.on_result = test_wolfSSL_SCR_after_resumption_on_result;

    test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

    ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
    ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);

    wolfSSL_SESSION_free(test_wolfSSL_SCR_after_resumption_session);

    return EXPECT_RESULT();
}

#else
static int test_wolfSSL_SCR_after_resumption(void)
{
    return TEST_SKIPPED;
}
#endif

static int test_wolfSSL_configure_args(void)
{
    EXPECT_DECLS;
#if defined(LIBWOLFSSL_CONFIGURE_ARGS) && defined(HAVE_WC_INTROSPECTION)
    ExpectNotNull(wolfSSL_configure_args());
#endif
    return EXPECT_RESULT();
}

static int test_dtls_no_extensions(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
    !defined(WOLFSSL_NO_TLS12)
    WOLFSSL *ssl_s = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    struct test_memio_ctx test_ctx;
    const byte chNoExtensions[] = {
        /* Handshake type */
        0x16,
        /* Version */
        0xfe, 0xff,
        /* Epoch */
        0x00, 0x00,
        /* Seq number */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        /* Length */
        0x00, 0x40,
        /* CH type */
        0x01,
        /* Length */
        0x00, 0x00, 0x34,
        /* Msg Seq */
        0x00, 0x00,
        /* Frag offset */
        0x00, 0x00, 0x00,
        /* Frag length */
        0x00, 0x00, 0x34,
        /* Version */
        0xfe, 0xff,
        /* Random */
        0x62, 0xfe, 0xbc, 0xfe, 0x2b, 0xfe, 0x3f, 0xeb, 0x03, 0xc4, 0xea, 0x37,
        0xe7, 0x47, 0x7e, 0x8a, 0xd9, 0xbf, 0x77, 0x0f, 0x6c, 0xb6, 0x77, 0x0b,
        0x03, 0x3f, 0x82, 0x2b, 0x21, 0x64, 0x57, 0x1d,
        /* Session Length */
        0x00,
        /* Cookie Length */
        0x00,
        /* CS Length */
        0x00, 0x0c,
        /* CS */
        0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x39, 0x00, 0x33,
        /* Comp Meths Length */
        0x01,
        /* Comp Meths */
        0x00
        /* And finally... no extensions */
    };
    int i;
#ifdef OPENSSL_EXTRA
    int repeats = 2;
#else
    int repeats = 1;
#endif

    for (i = 0; i < repeats; i++) {
        XMEMSET(&test_ctx, 0, sizeof(test_ctx));
        ssl_s = NULL;
        ctx_s = NULL;

        ExpectIntEQ(test_memio_setup(&test_ctx, NULL, &ctx_s, NULL, &ssl_s,
            NULL, wolfDTLS_server_method), 0);

        XMEMCPY(test_ctx.s_buff, chNoExtensions, sizeof(chNoExtensions));
        test_ctx.s_len = sizeof(chNoExtensions);

#ifdef OPENSSL_EXTRA
        if (i > 0) {
            ExpectIntEQ(wolfSSL_set_max_proto_version(ssl_s, DTLS1_2_VERSION),
                        WOLFSSL_SUCCESS);
        }
#endif

        ExpectIntEQ(wolfSSL_accept(ssl_s), -1);
        ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);

        /* Expecting a handshake msg. Either HVR or SH. */
        ExpectIntGT(test_ctx.c_len, 0);
        ExpectIntEQ(test_ctx.c_buff[0], 0x16);

        wolfSSL_free(ssl_s);
        wolfSSL_CTX_free(ctx_s);
    }
#endif
    return EXPECT_RESULT();
}

static int test_tls_alert_no_server_hello(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
    WOLFSSL *ssl_c = NULL;
    WOLFSSL_CTX *ctx_c = NULL;
    struct test_memio_ctx test_ctx;
    unsigned char alert_msg[] = { 0x15, 0x03, 0x01, 0x00, 0x02, 0x02, 0x28 };

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ssl_c = NULL;
    ctx_c = NULL;

    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
        wolfTLSv1_2_client_method, NULL), 0);

    XMEMCPY(test_ctx.c_buff, alert_msg, sizeof(alert_msg));
    test_ctx.c_len = sizeof(alert_msg);

    ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WC_NO_ERR_TRACE(FATAL_ERROR));

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
#endif
    return EXPECT_RESULT();
}

static int test_TLSX_CA_NAMES_bad_extension(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
    !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES) && \
    defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA384) && \
    defined(HAVE_NULL_CIPHER)
    /* This test should only fail (with BUFFER_ERROR) when we actually try to
     * parse the CA Names extension. Otherwise it will return other non-related
     * errors. If CA Names will be parsed in more configurations, that should
     * be reflected in the macro guard above. */
    WOLFSSL *ssl_c = NULL;
    WOLFSSL_CTX *ctx_c = NULL;
    struct test_memio_ctx test_ctx;
    /* HRR + SH using TLS_DHE_PSK_WITH_NULL_SHA384 */
    const byte shBadCaNamesExt[] = {
        0x16, 0x03, 0x04, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0xcf,
        0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e,
        0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07,
        0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, 0x00, 0x13, 0x03, 0x00, 0x00,
        0x13, 0x94, 0x7e, 0x00, 0x03, 0x0b, 0xf7, 0x03, 0x00, 0x2b, 0x00, 0x02,
        0x03, 0x04, 0x00, 0x33, 0x00, 0x02, 0x00, 0x19, 0x16, 0x03, 0x03, 0x00,
        0x5c, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0x03, 0xcf, 0x21, 0xad, 0x74,
        0x00, 0x00, 0x83, 0x3f, 0x3b, 0x80, 0x01, 0xac, 0x65, 0x8c, 0x19, 0x2a,
        0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x02, 0x00, 0x9e, 0x09, 0x1c, 0xe8,
        0xa8, 0x09, 0x9c, 0x00, 0xc0, 0xb5, 0x00, 0x00, 0x11, 0x8f, 0x00, 0x00,
        0x03, 0x3f, 0x00, 0x0c, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, 0x13, 0x05,
        0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00,
        0x0d, 0x00, 0x00, 0x11, 0x00, 0x00, 0x0d, 0x00, 0x2f, 0x00, 0x01, 0xff,
        0xff, 0xff, 0xff, 0xfa, 0x0d, 0x00, 0x00, 0x00, 0xad, 0x02
    };
    const byte shBadCaNamesExt2[] = {
        0x16, 0x03, 0x04, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0xcf,
        0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e,
        0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07,
        0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, 0x00, 0x13, 0x03, 0x00, 0x00,
        0x13, 0x94, 0x7e, 0x00, 0x03, 0x0b, 0xf7, 0x03, 0x00, 0x2b, 0x00, 0x02,
        0x03, 0x04, 0x00, 0x33, 0x00, 0x02, 0x00, 0x19, 0x16, 0x03, 0x03, 0x00,
        0x5e, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0x7f, 0xd0, 0x2d, 0xea, 0x6e,
        0x53, 0xa1, 0x6a, 0xc9, 0xc8, 0x54, 0xef, 0x75, 0xe4, 0xd9, 0xc6, 0x3e,
        0x74, 0xcb, 0x30, 0x80, 0xcc, 0x83, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0xc0, 0x5a, 0x00, 0xc0, 0xb5, 0x00, 0x00, 0x11, 0x8f, 0x00, 0x00,
        0x03, 0x03, 0x00, 0x0c, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, 0x53, 0x25,
        0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x04, 0x02, 0x05, 0x00, 0x00,
        0x0d, 0x00, 0x00, 0x11, 0x00, 0x00, 0x0d, 0x00, 0x2f, 0x00, 0x06, 0x00,
        0x04, 0x00, 0x03, 0x30, 0x00, 0x13, 0x94, 0x00, 0x06, 0x00, 0x04, 0x02
    };
    int i = 0;

    for (i = 0; i < 2; i++) {
        XMEMSET(&test_ctx, 0, sizeof(test_ctx));

        ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
            wolfTLSv1_3_client_method, NULL), 0);

        switch (i) {
            case 0:
                XMEMCPY(test_ctx.c_buff, shBadCaNamesExt,
                        sizeof(shBadCaNamesExt));
                test_ctx.c_len = sizeof(shBadCaNamesExt);
                break;
            case 1:
                XMEMCPY(test_ctx.c_buff, shBadCaNamesExt2,
                        sizeof(shBadCaNamesExt2));
                test_ctx.c_len = sizeof(shBadCaNamesExt2);
                break;
        }

        ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
#ifndef WOLFSSL_DISABLE_EARLY_SANITY_CHECKS
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WC_NO_ERR_TRACE(OUT_OF_ORDER_E));
#else
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WC_NO_ERR_TRACE(BUFFER_ERROR));
#endif

        wolfSSL_free(ssl_c);
        ssl_c = NULL;
        wolfSSL_CTX_free(ctx_c);
        ctx_c = NULL;
    }

#endif
    return EXPECT_RESULT();
}

#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES)
static void test_dtls_1_0_hvr_downgrade_ctx_ready(WOLFSSL_CTX* ctx)
{
    AssertIntEQ(wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_DTLSV1_2),
                WOLFSSL_SUCCESS);
}

static int test_dtls_1_0_hvr_downgrade(void)
{
    EXPECT_DECLS;
    callback_functions func_cb_client;
    callback_functions func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
    XMEMSET(&func_cb_server, 0, sizeof(callback_functions));

    func_cb_client.doUdp = func_cb_server.doUdp = 1;
    func_cb_client.method = wolfDTLS_client_method;
    func_cb_server.method = wolfDTLSv1_2_server_method;
    func_cb_client.ctx_ready = test_dtls_1_0_hvr_downgrade_ctx_ready;

    test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

    ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
    ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);

    return EXPECT_RESULT();
}
#else
static int test_dtls_1_0_hvr_downgrade(void)
{
    EXPECT_DECLS;
    return EXPECT_RESULT();
}
#endif

#if defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12) && \
        defined(HAVE_SESSION_TICKET)

static WOLFSSL_SESSION* test_session_ticket_no_id_session = NULL;

static void test_session_ticket_no_id_on_result(WOLFSSL* ssl)
{
    test_session_ticket_no_id_session = wolfSSL_get1_session(ssl);
    AssertNotNull(test_session_ticket_no_id_session);
}

static void test_session_ticket_no_id_ctx_ready(WOLFSSL_CTX* ctx)
{
    AssertIntEQ(wolfSSL_CTX_UseSessionTicket(ctx), WOLFSSL_SUCCESS);
}

static void test_session_ticket_no_id_ssl_ready(WOLFSSL* ssl)
{
    test_session_ticket_no_id_session->sessionIDSz = 0;
    AssertIntEQ(WOLFSSL_SUCCESS,
           wolfSSL_set_session(ssl, test_session_ticket_no_id_session));
}

static int test_session_ticket_no_id(void)
{
    /* We are testing an expired (invalid crypto context in out case since the
     * ctx changes) session ticket being sent with the session ID being 0
     * length. */
    EXPECT_DECLS;
    callback_functions func_cb_client;
    callback_functions func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
    func_cb_client.method = wolfTLSv1_2_client_method;
    func_cb_client.ctx_ready = test_session_ticket_no_id_ctx_ready;
    func_cb_client.on_result = test_session_ticket_no_id_on_result;
    func_cb_server.method = wolfTLSv1_2_server_method;
    func_cb_server.ctx_ready = test_session_ticket_no_id_ctx_ready;

    test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

    ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
    ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);

    XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
    XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
    func_cb_client.method = wolfTLSv1_2_client_method;
    func_cb_client.ctx_ready = test_session_ticket_no_id_ctx_ready;
    func_cb_client.ssl_ready = test_session_ticket_no_id_ssl_ready;
    func_cb_server.method = wolfTLSv1_2_server_method;
    func_cb_server.ctx_ready = test_session_ticket_no_id_ctx_ready;

    test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

    ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
    ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);

    wolfSSL_SESSION_free(test_session_ticket_no_id_session);

    return EXPECT_RESULT();
}
#else
static int test_session_ticket_no_id(void)
{
    EXPECT_DECLS;
    return EXPECT_RESULT();
}
#endif

static int test_session_ticket_hs_update(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
    defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
    struct test_memio_ctx test_ctx;
    struct test_memio_ctx test_ctx2;
    struct test_memio_ctx test_ctx3;
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_c2 = NULL;
    WOLFSSL *ssl_c3 = NULL;
    WOLFSSL *ssl_s = NULL;
    WOLFSSL *ssl_s2 = NULL;
    WOLFSSL *ssl_s3 = NULL;
    WOLFSSL_SESSION *sess = NULL;
    byte read_data[1];

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    XMEMSET(&test_ctx2, 0, sizeof(test_ctx2));
    XMEMSET(&test_ctx3, 0, sizeof(test_ctx3));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);

    /* Generate tickets */
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
    wolfSSL_SetLoggingPrefix("client");
    /* Read the ticket msg */
    ExpectIntEQ(wolfSSL_read(ssl_c, read_data, sizeof(read_data)),
            WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);
    wolfSSL_SetLoggingPrefix(NULL);

    ExpectIntEQ(test_memio_setup(&test_ctx2, &ctx_c, &ctx_s, &ssl_c2, &ssl_s2,
        wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
    ExpectIntEQ(test_memio_setup(&test_ctx3, &ctx_c, &ctx_s, &ssl_c3, &ssl_s3,
        wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);

    ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
    ExpectIntEQ(wolfSSL_set_session(ssl_c2, sess), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_set_session(ssl_c3, sess), WOLFSSL_SUCCESS);

    wolfSSL_SetLoggingPrefix("client");
    /* Exchange initial flights for the second connection */
    ExpectIntEQ(wolfSSL_connect(ssl_c2), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(wolfSSL_get_error(ssl_c2, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);
    wolfSSL_SetLoggingPrefix(NULL);
    wolfSSL_SetLoggingPrefix("server");
    ExpectIntEQ(wolfSSL_accept(ssl_s2), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(wolfSSL_get_error(ssl_s2, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);
    wolfSSL_SetLoggingPrefix(NULL);

    /* Complete third connection so that new tickets are exchanged */
    ExpectIntEQ(test_memio_do_handshake(ssl_c3, ssl_s3, 10, NULL), 0);
    /* Read the ticket msg */
    wolfSSL_SetLoggingPrefix("client");
    ExpectIntEQ(wolfSSL_read(ssl_c3, read_data, sizeof(read_data)),
            WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(wolfSSL_get_error(ssl_c3, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);
    wolfSSL_SetLoggingPrefix(NULL);

    /* Complete second connection */
    ExpectIntEQ(test_memio_do_handshake(ssl_c2, ssl_s2, 10, NULL), 0);

    ExpectIntEQ(wolfSSL_session_reused(ssl_c2), 1);
    ExpectIntEQ(wolfSSL_session_reused(ssl_c3), 1);

    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_c2);
    wolfSSL_free(ssl_c3);
    wolfSSL_free(ssl_s);
    wolfSSL_free(ssl_s2);
    wolfSSL_free(ssl_s3);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
    wolfSSL_SESSION_free(sess);
#endif
    return EXPECT_RESULT();
}

#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)
static void test_dtls_downgrade_scr_server_ctx_ready_server(WOLFSSL_CTX* ctx)
{
    AssertIntEQ(wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_DTLSV1_2),
                WOLFSSL_SUCCESS);
    AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
}

static void test_dtls_downgrade_scr_server_ctx_ready(WOLFSSL_CTX* ctx)
{
    AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
}

static void test_dtls_downgrade_scr_server_on_result(WOLFSSL* ssl)
{
    char testMsg[] = "Message after SCR";
    char msgBuf[sizeof(testMsg)];
    if (wolfSSL_is_server(ssl)) {
        AssertIntEQ(wolfSSL_Rehandshake(ssl), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
        AssertIntEQ(wolfSSL_get_error(ssl, -1), WC_NO_ERR_TRACE(APP_DATA_READY));
        AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
        AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_SUCCESS);
        AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
                    sizeof(testMsg));
    }
    else {
        AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
                    sizeof(testMsg));
        AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
    }
}

static int test_dtls_downgrade_scr_server(void)
{
    EXPECT_DECLS;
    callback_functions func_cb_client;
    callback_functions func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
    XMEMSET(&func_cb_server, 0, sizeof(callback_functions));

    func_cb_client.doUdp = func_cb_server.doUdp = 1;
    func_cb_client.method = wolfDTLSv1_2_client_method;
    func_cb_server.method = wolfDTLS_server_method;
    func_cb_client.ctx_ready = test_dtls_downgrade_scr_server_ctx_ready;
    func_cb_server.ctx_ready = test_dtls_downgrade_scr_server_ctx_ready_server;
    func_cb_client.on_result = test_dtls_downgrade_scr_server_on_result;
    func_cb_server.on_result = test_dtls_downgrade_scr_server_on_result;

    test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

    ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
    ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);

    return EXPECT_RESULT();
}
#else
static int test_dtls_downgrade_scr_server(void)
{
    EXPECT_DECLS;
    return EXPECT_RESULT();
}
#endif

#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)
static void test_dtls_downgrade_scr_ctx_ready(WOLFSSL_CTX* ctx)
{
    AssertIntEQ(wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_DTLSV1_2),
                WOLFSSL_SUCCESS);
    AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
}

static void test_dtls_downgrade_scr_on_result(WOLFSSL* ssl)
{
    char testMsg[] = "Message after SCR";
    char msgBuf[sizeof(testMsg)];
    if (wolfSSL_is_server(ssl)) {
        AssertIntEQ(wolfSSL_Rehandshake(ssl), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
        AssertIntEQ(wolfSSL_get_error(ssl, -1), WC_NO_ERR_TRACE(APP_DATA_READY));
        AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
        AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_SUCCESS);
        AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
                    sizeof(testMsg));
    }
    else {
        AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
                    sizeof(testMsg));
        AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
    }
}

static int test_dtls_downgrade_scr(void)
{
    EXPECT_DECLS;
    callback_functions func_cb_client;
    callback_functions func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
    XMEMSET(&func_cb_server, 0, sizeof(callback_functions));

    func_cb_client.doUdp = func_cb_server.doUdp = 1;
    func_cb_client.method = wolfDTLS_client_method;
    func_cb_server.method = wolfDTLSv1_2_server_method;
    func_cb_client.ctx_ready = test_dtls_downgrade_scr_ctx_ready;
    func_cb_client.on_result = test_dtls_downgrade_scr_on_result;
    func_cb_server.on_result = test_dtls_downgrade_scr_on_result;

    test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

    ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
    ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);

    return EXPECT_RESULT();
}
#else
static int test_dtls_downgrade_scr(void)
{
    EXPECT_DECLS;
    return EXPECT_RESULT();
}
#endif

#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
    && !defined(WOLFSSL_NO_TLS12)

static int test_dtls_client_hello_timeout_downgrade_read_cb(WOLFSSL *ssl,
        char *data, int sz, void *ctx)
{
    static int call_counter = 0;
    call_counter++;
    (void)ssl;
    (void)data;
    (void)sz;
    (void)ctx;
    switch (call_counter) {
        case 1:
        case 2:
            return WOLFSSL_CBIO_ERR_TIMEOUT;
        case 3:
            return WOLFSSL_CBIO_ERR_WANT_READ;
        default:
            AssertIntLE(call_counter, 3);
            return -1;
    }
}
#endif

/* Make sure we don't send acks before getting a server hello */
static int test_dtls_client_hello_timeout_downgrade(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
    && !defined(WOLFSSL_NO_TLS12)

    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    DtlsRecordLayerHeader* dtlsRH;
    size_t len;
    byte sequence_number[8];
    int i;

    for (i = 0; i < 2; i++) {
        XMEMSET(&test_ctx, 0, sizeof(test_ctx));

        ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfDTLS_client_method, wolfDTLSv1_2_server_method), 0);

        if (i == 0) {
            /* First time simulate timeout in IO layer */
            /* CH1 */
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            /* HVR */
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            /* CH2 */
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            /* SH flight */
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            /* Drop the SH */
            dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.c_buff);
            len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
            if (EXPECT_SUCCESS()) {
                XMEMMOVE(test_ctx.c_buff, test_ctx.c_buff +
                    sizeof(DtlsRecordLayerHeader) + len, test_ctx.c_len -
                   (sizeof(DtlsRecordLayerHeader) + len));
            }
            test_ctx.c_len -= sizeof(DtlsRecordLayerHeader) + len;
            /* Read the remainder of the flight */
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            wolfSSL_SSLSetIORecv(ssl_c,
                    test_dtls_client_hello_timeout_downgrade_read_cb);
            /* CH3 */
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            wolfSSL_SSLSetIORecv(ssl_c, test_memio_read_cb);
        }
        else {
            /* Second time call wolfSSL_dtls_got_timeout */
            /* CH1 */
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            /* HVR */
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            /* CH2 */
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            /* SH flight */
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            /* Drop the SH */
            dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.c_buff);
            len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
            if (EXPECT_SUCCESS()) {
                XMEMMOVE(test_ctx.c_buff, test_ctx.c_buff +
                    sizeof(DtlsRecordLayerHeader) + len, test_ctx.c_len -
                   (sizeof(DtlsRecordLayerHeader) + len));
            }
            test_ctx.c_len -= sizeof(DtlsRecordLayerHeader) + len;
            /* Read the remainder of the flight */
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            /* Quick timeout should be set as we received at least one msg */
            ExpectIntEQ(wolfSSL_dtls13_use_quick_timeout(ssl_c), 1);
            ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
            /* Quick timeout should be cleared after a quick timeout */
            /* CH3 */
            ExpectIntEQ(wolfSSL_dtls13_use_quick_timeout(ssl_c), 0);
            ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
        }

        /* Parse out to make sure we got exactly one ClientHello message */
        XMEMSET(&sequence_number, 0, sizeof(sequence_number));
        /* Second ClientHello after HVR */
        sequence_number[7] = 2;
        dtlsRH = (DtlsRecordLayerHeader*)test_ctx.s_buff;
        ExpectIntEQ(dtlsRH->type, handshake);
        ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
        ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
        ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
                sizeof(sequence_number)), 0);
        len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
        ExpectIntEQ(sizeof(DtlsRecordLayerHeader) + len, test_ctx.s_len);

        /* Connection should be able to continue */
        ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

        wolfSSL_free(ssl_c);
        wolfSSL_free(ssl_s);
        wolfSSL_CTX_free(ctx_c);
        wolfSSL_CTX_free(ctx_s);
        ssl_c = NULL;
        ssl_s = NULL;
        ctx_c = NULL;
        ctx_s = NULL;
        if (!EXPECT_SUCCESS())
            break;
    }

#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
static int test_dtls_client_hello_timeout_read_cb(WOLFSSL *ssl, char *data,
        int sz, void *ctx)
{
    static int call_counter = 0;
    call_counter++;
    (void)ssl;
    (void)data;
    (void)sz;
    (void)ctx;
    switch (call_counter) {
        case 1:
            return WOLFSSL_CBIO_ERR_TIMEOUT;
        case 2:
            return WOLFSSL_CBIO_ERR_WANT_READ;
        default:
            AssertIntLE(call_counter, 2);
            return -1;
    }
}
#endif

/* Make sure we don't send acks before getting a server hello */
static int test_dtls_client_hello_timeout(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
    WOLFSSL *ssl_c = NULL;
    WOLFSSL_CTX *ctx_c = NULL;
    struct test_memio_ctx test_ctx;
    DtlsRecordLayerHeader* dtlsRH;
    size_t idx;
    size_t len;
    byte sequence_number[8];
    int i;

    for (i = 0; i < 2; i++) {
        XMEMSET(&test_ctx, 0, sizeof(test_ctx));

        ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
            wolfDTLSv1_3_client_method, NULL), 0);

        if (i == 0) {
            /* First time simulate timeout in IO layer */
            wolfSSL_SSLSetIORecv(ssl_c, test_dtls_client_hello_timeout_read_cb);
            ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
        }
        else {
            /* Second time call wolfSSL_dtls_got_timeout */
            ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
        }

        /* Parse out to make sure we got exactly two ClientHello messages */
        idx = 0;
        XMEMSET(&sequence_number, 0, sizeof(sequence_number));
        /* First ClientHello */
        dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.s_buff + idx);
        ExpectIntEQ(dtlsRH->type, handshake);
        ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
        ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
        ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
                sizeof(sequence_number)), 0);
        len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
        ExpectIntLT(idx + sizeof(DtlsRecordLayerHeader) + len, test_ctx.s_len);
        idx += sizeof(DtlsRecordLayerHeader) + len;
        /* Second ClientHello */
        sequence_number[7] = 1;
        dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.s_buff + idx);
        ExpectIntEQ(dtlsRH->type, handshake);
        ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
        ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
        ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
                sizeof(sequence_number)), 0);
        len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
        ExpectIntEQ(idx + sizeof(DtlsRecordLayerHeader) + len, test_ctx.s_len);

        wolfSSL_free(ssl_c);
        wolfSSL_CTX_free(ctx_c);
        ssl_c = NULL;
        ctx_c = NULL;
        if (!EXPECT_SUCCESS())
            break;
    }

#endif
    return EXPECT_RESULT();
}

/* DTLS test when dropping the changed cipher spec message */
static int test_dtls_dropped_ccs(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
    && !defined(WOLFSSL_NO_TLS12)

    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    DtlsRecordLayerHeader* dtlsRH;
    size_t len;
    byte data[1];


    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);

    /* CH1 */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    /* HVR */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    /* CH2 */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    /* Server first flight */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    /* Client flight */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    /* Server ccs + finished */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);

    /* Drop the ccs */
    dtlsRH = (DtlsRecordLayerHeader*)test_ctx.c_buff;
    len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
    ExpectIntEQ(len, 1);
    ExpectIntEQ(dtlsRH->type, change_cipher_spec);
    if (EXPECT_SUCCESS()) {
        XMEMMOVE(test_ctx.c_buff, test_ctx.c_buff +
                sizeof(DtlsRecordLayerHeader) + len, test_ctx.c_len -
               (sizeof(DtlsRecordLayerHeader) + len));
    }
    test_ctx.c_len -= sizeof(DtlsRecordLayerHeader) + len;

    /* Client rtx flight */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
    /* Server ccs + finished rtx */
    ExpectIntEQ(wolfSSL_read(ssl_s, data, sizeof(data)), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    /* Client processes finished */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);

    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
    && !defined(WOLFSSL_NO_TLS12)
static int test_dtls_seq_num_downgrade_check_num(byte* ioBuf, int ioBufLen,
        byte seq_num)
{
    EXPECT_DECLS;
    DtlsRecordLayerHeader* dtlsRH;
    byte sequence_number[8];

    XMEMSET(&sequence_number, 0, sizeof(sequence_number));

    ExpectIntGE(ioBufLen, sizeof(*dtlsRH));
    dtlsRH = (DtlsRecordLayerHeader*)ioBuf;
    ExpectIntEQ(dtlsRH->type, handshake);
    ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
    ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
    sequence_number[7] = seq_num;
    ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
            sizeof(sequence_number)), 0);

    return EXPECT_RESULT();
}
#endif

/*
 * Make sure that we send the correct sequence number after a HelloVerifyRequest
 * and after a HelloRetryRequest. This is testing the server side as it is
 * operating statelessly and should copy the sequence number of the ClientHello.
 */
static int test_dtls_seq_num_downgrade(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
    && !defined(WOLFSSL_NO_TLS12)
    WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
    struct test_memio_ctx test_ctx;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_2_client_method, wolfDTLS_server_method), 0);

    /* CH1 */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.s_buff,
            test_ctx.s_len, 0), TEST_SUCCESS);
    /* HVR */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.c_buff,
            test_ctx.c_len, 0), TEST_SUCCESS);
    /* CH2 */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.s_buff,
            test_ctx.s_len, 1), TEST_SUCCESS);
    /* Server first flight */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.c_buff,
            test_ctx.c_len, 1), TEST_SUCCESS);

    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
#endif
    return EXPECT_RESULT();
}

/**
 * Make sure we don't send RSA Signature Hash Algorithms in the
 * CertificateRequest when we don't have any such ciphers set.
 * @return EXPECT_RESULT()
 */
static int test_certreq_sighash_algos(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
    !defined(WOLFSSL_MAX_STRENGTH) && defined(HAVE_ECC) && \
    defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) && \
    defined(HAVE_AES_CBC) && !defined(WOLFSSL_NO_TLS12)
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    int idx = 0;
    int maxIdx = 0;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    test_ctx.c_ciphers = test_ctx.s_ciphers =
            "ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA384";
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);

    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_c,
            "./certs/ca-ecc-cert.pem", NULL), WOLFSSL_SUCCESS);

    wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_PEER, NULL);
    ExpectIntEQ(wolfSSL_use_PrivateKey_file(ssl_s, "./certs/ecc-key.pem",
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_use_certificate_file(ssl_s, "./certs/server-ecc.pem",
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_connect(ssl_c), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    ExpectIntEQ(wolfSSL_accept(ssl_s), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
    ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
        WOLFSSL_ERROR_WANT_READ);

    /* Find the CertificateRequest message */
    for (idx = 0; idx < test_ctx.c_len && EXPECT_SUCCESS();) {
        word16 len;
        ExpectIntEQ(test_ctx.c_buff[idx++], handshake);
        ExpectIntEQ(test_ctx.c_buff[idx++], SSLv3_MAJOR);
        ExpectIntEQ(test_ctx.c_buff[idx++], TLSv1_2_MINOR);
        ato16(test_ctx.c_buff + idx, &len);
        idx += OPAQUE16_LEN;
        if (test_ctx.c_buff[idx] == certificate_request) {
            idx++;
            /* length */
            idx += OPAQUE24_LEN;
            /* cert types */
            idx += 1 + test_ctx.c_buff[idx];
            /* Sig algos */
            ato16(test_ctx.c_buff + idx, &len);
            idx += OPAQUE16_LEN;
            maxIdx = idx + (int)len;
            for (; idx < maxIdx && EXPECT_SUCCESS(); idx += OPAQUE16_LEN) {
                if (test_ctx.c_buff[idx+1] == ED25519_SA_MINOR ||
                        test_ctx.c_buff[idx+1] == ED448_SA_MINOR)
                    ExpectIntEQ(test_ctx.c_buff[idx], NEW_SA_MAJOR);
                else
                    ExpectIntEQ(test_ctx.c_buff[idx+1], ecc_dsa_sa_algo);
            }
            break;
        }
        else {
            idx += (int)len;
        }
    }
    ExpectIntLT(idx, test_ctx.c_len);


    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_CRL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    !defined(WOLFSSL_CRL_ALLOW_MISSING_CDP)
static int test_revoked_loaded_int_cert_ctx_ready1(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
    myVerifyAction = VERIFY_USE_PREVERFIY;
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
            "./certs/ca-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
            "./certs/intermediate/ca-int-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL),
            WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
            "./certs/crl/extra-crls/ca-int-cert-revoked.pem",
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
            "./certs/crl/ca-int.pem",
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

static int test_revoked_loaded_int_cert_ctx_ready2(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
    myVerifyAction = VERIFY_USE_PREVERFIY;
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
            "./certs/ca-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
            "./certs/intermediate/ca-int-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
            "./certs/intermediate/ca-int2-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL),
            WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
            "./certs/crl/ca-int2.pem",
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
            "./certs/crl/extra-crls/ca-int-cert-revoked.pem",
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
            "./certs/crl/ca-int.pem",
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}

static int test_revoked_loaded_int_cert_ctx_ready3_crl_missing_cb(int ret,
        WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm, void* ctx)
{
    (void)crl;
    (void)cm;
    (void)ctx;
    if (ret == WC_NO_ERR_TRACE(CRL_MISSING))
        return 1;
    return 0;
}

/* Here we are allowing missing CRL's but want to error out when its revoked */
static int test_revoked_loaded_int_cert_ctx_ready3(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
    myVerifyAction = VERIFY_USE_PREVERFIY;
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
            "./certs/ca-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
            "./certs/intermediate/ca-int-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
            "./certs/intermediate/ca-int2-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL),
            WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
            "./certs/crl/extra-crls/ca-int-cert-revoked.pem",
            WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_SetCRL_ErrorCb(ctx,
            test_revoked_loaded_int_cert_ctx_ready3_crl_missing_cb, NULL),
            WOLFSSL_SUCCESS);
    return EXPECT_RESULT();
}
#endif

static int test_revoked_loaded_int_cert(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CRL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
    !defined(WOLFSSL_CRL_ALLOW_MISSING_CDP)
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;
    struct {
        const char* certPemFile;
        const char* keyPemFile;
        ctx_cb      client_ctx_ready;
    } test_params[] = {
        {"./certs/intermediate/ca-int2-cert.pem",
            "./certs/intermediate/ca-int2-key.pem",
            test_revoked_loaded_int_cert_ctx_ready1},
        {"./certs/intermediate/server-chain.pem",
            "./certs/server-key.pem", test_revoked_loaded_int_cert_ctx_ready2},
        {"./certs/intermediate/server-chain-short.pem",
            "./certs/server-key.pem", test_revoked_loaded_int_cert_ctx_ready2},
        {"./certs/intermediate/server-chain-short.pem",
            "./certs/server-key.pem", test_revoked_loaded_int_cert_ctx_ready3},
    };
    size_t i;

    printf("\n");

    for (i = 0; i < XELEM_CNT(test_params); i++) {
        XMEMSET(&client_cbf, 0, sizeof(client_cbf));
        XMEMSET(&server_cbf, 0, sizeof(server_cbf));

        printf("\tTesting with %s...\n", test_params[i].certPemFile);

        server_cbf.certPemFile = test_params[i].certPemFile;
        server_cbf.keyPemFile  = test_params[i].keyPemFile;

        client_cbf.ctx_ready = test_params[i].client_ctx_ready;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
            &server_cbf, NULL), -1001);
        ExpectIntEQ(client_cbf.last_err, WC_NO_ERR_TRACE(CRL_CERT_REVOKED));
        ExpectIntEQ(server_cbf.last_err, WC_NO_ERR_TRACE(FATAL_ERROR));

        if (!EXPECT_SUCCESS())
            break;
        printf("\t%s passed\n", test_params[i].certPemFile);
    }
#endif
    return EXPECT_RESULT();
}

static int test_dtls13_frag_ch_pq(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
    && defined(WOLFSSL_DTLS_CH_FRAG) && defined(HAVE_LIBOQS)
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    const char *test_str = "test";
    int test_str_size;
    byte buf[255];
    int group = WOLFSSL_KYBER_LEVEL5;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
    /* Add in a large post-quantum key share to make the CH long. */
    ExpectIntEQ(wolfSSL_set_groups(ssl_c, &group, 1), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, group), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_dtls13_allow_ch_frag(ssl_s, 1), WOLFSSL_SUCCESS);
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
    ExpectStrEQ(wolfSSL_get_curve_name(ssl_c), "KYBER_LEVEL5");
    ExpectStrEQ(wolfSSL_get_curve_name(ssl_s), "KYBER_LEVEL5");
    test_str_size = XSTRLEN("test") + 1;
    ExpectIntEQ(wolfSSL_write(ssl_c, test_str, test_str_size), test_str_size);
    ExpectIntEQ(wolfSSL_read(ssl_s, buf, sizeof(buf)), test_str_size);
    ExpectIntEQ(XSTRCMP((char*)buf, test_str), 0);
    ExpectIntEQ(wolfSSL_write(ssl_c, test_str, test_str_size), test_str_size);
    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
    && defined(WOLFSSL_DTLS_MTU) && defined(WOLFSSL_DTLS_CH_FRAG)
static int test_dtls_frag_ch_count_records(byte* b, int len)
{
    DtlsRecordLayerHeader* dtlsRH;
    int records = 0;
    size_t recordLen;
    while (len > 0) {
        records++;
        dtlsRH = (DtlsRecordLayerHeader*)b;
        recordLen = (dtlsRH->length[0] << 8) | dtlsRH->length[1];
        b += sizeof(DtlsRecordLayerHeader) + recordLen;
        len -= sizeof(DtlsRecordLayerHeader) + recordLen;
    }
    return records;
}
#endif

static int test_dtls_frag_ch(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
    && defined(WOLFSSL_DTLS_MTU) && defined(WOLFSSL_DTLS_CH_FRAG)
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    static unsigned int DUMMY_MTU = 256;
    unsigned char four_frag_CH[] = {
      0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0xda, 0x01, 0x00, 0x02, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0xce, 0xfe, 0xfd, 0xf3, 0x94, 0x01, 0x33, 0x2c, 0xcf, 0x2c, 0x47, 0xb1,
      0xe5, 0xa1, 0x7b, 0x19, 0x3e, 0xac, 0x68, 0xdd, 0xe6, 0x17, 0x6b, 0x85,
      0xad, 0x5f, 0xfc, 0x7f, 0x6e, 0xf0, 0xb9, 0xe0, 0x2e, 0xca, 0x47, 0x00,
      0x00, 0x00, 0x36, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x2c, 0xc0,
      0x2b, 0xc0, 0x30, 0xc0, 0x2f, 0x00, 0x9f, 0x00, 0x9e, 0xcc, 0xa9, 0xcc,
      0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x28, 0xc0, 0x24, 0xc0,
      0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x6b, 0x00, 0x67, 0x00,
      0x39, 0x00, 0x33, 0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0x01, 0x00, 0x02,
      0x7c, 0x00, 0x2b, 0x00, 0x03, 0x02, 0xfe, 0xfc, 0x00, 0x0d, 0x00, 0x20,
      0x00, 0x1e, 0x06, 0x03, 0x05, 0x03, 0x04, 0x03, 0x02, 0x03, 0x08, 0x06,
      0x08, 0x0b, 0x08, 0x05, 0x08, 0x0a, 0x08, 0x04, 0x08, 0x09, 0x06, 0x01,
      0x05, 0x01, 0x04, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x0a, 0x00, 0x0c,
      0x00, 0x0a, 0x00, 0x19, 0x00, 0x18, 0x00, 0x17, 0x00, 0x15, 0x01, 0x00,
      0x00, 0x16, 0x00, 0x00, 0x00, 0x33, 0x02, 0x39, 0x02, 0x37, 0x00, 0x17,
      0x00, 0x41, 0x04, 0x94, 0xdf, 0x36, 0xd7, 0xb3, 0x90, 0x6d, 0x01, 0xa1,
      0xe6, 0xed, 0x67, 0xf4, 0xd9, 0x9d, 0x2c, 0xac, 0x57, 0x74, 0xff, 0x19,
      0xbe, 0x5a, 0xc9, 0x30, 0x11, 0xb7, 0x2b, 0x59, 0x47, 0x80, 0x7c, 0xa9,
      0xb7, 0x31, 0x8c, 0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x01, 0x00, 0xda, 0x01, 0x00, 0x02, 0xdc, 0x00, 0x00, 0x00, 0x00,
      0xce, 0x00, 0x00, 0xce, 0x9e, 0x13, 0x74, 0x3b, 0x86, 0xba, 0x69, 0x1f,
      0x12, 0xf7, 0xcd, 0x78, 0x53, 0xe8, 0x50, 0x4d, 0x71, 0x3f, 0x4b, 0x4e,
      0xeb, 0x3e, 0xe5, 0x43, 0x54, 0x78, 0x17, 0x6d, 0x00, 0x18, 0x00, 0x61,
      0x04, 0xd1, 0x99, 0x66, 0x4f, 0xda, 0xc7, 0x12, 0x3b, 0xff, 0xb2, 0xd6,
      0x2f, 0x35, 0xb6, 0x17, 0x1f, 0xb3, 0xd0, 0xb6, 0x52, 0xff, 0x97, 0x8b,
      0x01, 0xe8, 0xd9, 0x68, 0x71, 0x40, 0x02, 0xd5, 0x68, 0x3a, 0x58, 0xb2,
      0x5d, 0xee, 0xa4, 0xe9, 0x5f, 0xf4, 0xaf, 0x3e, 0x30, 0x9c, 0x3e, 0x2b,
      0xda, 0x61, 0x43, 0x99, 0x02, 0x35, 0x33, 0x9f, 0xcf, 0xb5, 0xd3, 0x28,
      0x19, 0x9d, 0x1c, 0xbe, 0x69, 0x07, 0x9e, 0xfc, 0xe4, 0x8e, 0xcd, 0x86,
      0x4a, 0x1b, 0xf0, 0xfc, 0x17, 0x94, 0x66, 0x53, 0xda, 0x24, 0x5e, 0xaf,
      0xce, 0xec, 0x62, 0x4c, 0x06, 0xb4, 0x52, 0x94, 0xb1, 0x4a, 0x7a, 0x8c,
      0x4f, 0x00, 0x19, 0x00, 0x85, 0x04, 0x00, 0x27, 0xeb, 0x99, 0x49, 0x7f,
      0xcb, 0x2c, 0x46, 0x54, 0x2d, 0x93, 0x5d, 0x25, 0x92, 0x58, 0x5e, 0x06,
      0xc3, 0x7c, 0xfb, 0x9a, 0xa7, 0xec, 0xcd, 0x9f, 0xe1, 0x6b, 0x2d, 0x78,
      0xf5, 0x16, 0xa9, 0x20, 0x52, 0x48, 0x19, 0x0f, 0x1a, 0xd0, 0xce, 0xd8,
      0x68, 0xb1, 0x4e, 0x7f, 0x33, 0x03, 0x7d, 0x0c, 0x39, 0xdb, 0x9c, 0x4b,
      0xf4, 0xe7, 0xc2, 0xf5, 0xdd, 0x51, 0x9b, 0x03, 0xa8, 0x53, 0x2b, 0xe6,
      0x00, 0x15, 0x4b, 0xff, 0xd2, 0xa0, 0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xda, 0x01, 0x00, 0x02, 0xdc, 0x00,
      0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0xce, 0x58, 0x30, 0x10, 0x3d, 0x46,
      0xcc, 0xca, 0x1a, 0x44, 0xc8, 0x58, 0x9b, 0x27, 0x17, 0x67, 0x31, 0x96,
      0x8a, 0x66, 0x39, 0xf4, 0xcc, 0xc1, 0x9f, 0x12, 0x1f, 0x01, 0x30, 0x50,
      0x16, 0xd6, 0x89, 0x97, 0xa3, 0x66, 0xd7, 0x99, 0x50, 0x09, 0x6e, 0x80,
      0x87, 0xe4, 0xa2, 0x88, 0xae, 0xb4, 0x23, 0x57, 0x2f, 0x12, 0x60, 0xe7,
      0x7d, 0x44, 0x2d, 0xad, 0xbe, 0xe9, 0x0d, 0x01, 0x00, 0x01, 0x00, 0xd5,
      0xdd, 0x62, 0xee, 0xf3, 0x0e, 0xd9, 0x30, 0x0e, 0x38, 0xf3, 0x48, 0xf4,
      0xc9, 0x8f, 0x8c, 0x20, 0xf7, 0xd3, 0xa8, 0xb3, 0x87, 0x3c, 0x98, 0x5d,
      0x70, 0xc5, 0x03, 0x76, 0xb7, 0xd5, 0x0b, 0x7b, 0x23, 0x97, 0x6b, 0xe3,
      0xb5, 0x18, 0xeb, 0x64, 0x55, 0x18, 0xb2, 0x8a, 0x90, 0x1a, 0x8f, 0x0e,
      0x15, 0xda, 0xb1, 0x8e, 0x7f, 0xee, 0x1f, 0xe0, 0x3b, 0xb9, 0xed, 0xfc,
      0x4e, 0x3f, 0x78, 0x16, 0x39, 0x95, 0x5f, 0xb7, 0xcb, 0x65, 0x55, 0x72,
      0x7b, 0x7d, 0x86, 0x2f, 0x8a, 0xe5, 0xee, 0xf7, 0x57, 0x40, 0xf3, 0xc4,
      0x96, 0x4f, 0x11, 0x4d, 0x85, 0xf9, 0x56, 0xfa, 0x3d, 0xf0, 0xc9, 0xa4,
      0xec, 0x1e, 0xaa, 0x47, 0x90, 0x53, 0xdf, 0xe1, 0xb7, 0x78, 0x18, 0xeb,
      0xdd, 0x0d, 0x89, 0xb7, 0xf6, 0x15, 0x0e, 0x55, 0x12, 0xb3, 0x23, 0x17,
      0x0b, 0x59, 0x6f, 0x83, 0x05, 0x6b, 0xa6, 0xf8, 0x6c, 0x3a, 0x9b, 0x1b,
      0x50, 0x93, 0x51, 0xea, 0x95, 0x2d, 0x99, 0x96, 0x38, 0x16, 0xfe, 0xfd,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x7e, 0x01, 0x00,
      0x02, 0xdc, 0x00, 0x00, 0x00, 0x02, 0x6a, 0x00, 0x00, 0x72, 0x2d, 0x66,
      0x3e, 0xf2, 0x36, 0x5a, 0xf2, 0x23, 0x8f, 0x28, 0x09, 0xa9, 0x55, 0x8c,
      0x8f, 0xc0, 0x0d, 0x61, 0x98, 0x33, 0x56, 0x87, 0x7a, 0xfd, 0xa7, 0x50,
      0x71, 0x84, 0x2e, 0x41, 0x58, 0x00, 0x87, 0xd9, 0x27, 0xe5, 0x7b, 0xf4,
      0x6d, 0x84, 0x4e, 0x2e, 0x0c, 0x80, 0x0c, 0xf3, 0x8a, 0x02, 0x4b, 0x99,
      0x3a, 0x1f, 0x9f, 0x18, 0x7d, 0x1c, 0xec, 0xad, 0x60, 0x54, 0xa6, 0xa3,
      0x2c, 0x82, 0x5e, 0xf8, 0x8f, 0xae, 0xe1, 0xc4, 0x82, 0x7e, 0x43, 0x43,
      0xc5, 0x99, 0x49, 0x05, 0xd3, 0xf6, 0xdf, 0xa1, 0xb5, 0x2d, 0x0c, 0x13,
      0x2f, 0x1e, 0xb6, 0x28, 0x7c, 0x5c, 0xa1, 0x02, 0x6b, 0x8d, 0xa3, 0xeb,
      0xd4, 0x58, 0xe6, 0xa0, 0x7e, 0x6b, 0xaa, 0x09, 0x43, 0x67, 0x71, 0x87,
      0xa5, 0xcb, 0x68, 0xf3
    };

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);

    /* Fragment msgs */
    ExpectIntEQ(wolfSSL_dtls_set_mtu(ssl_c, DUMMY_MTU), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_dtls_set_mtu(ssl_s, DUMMY_MTU), WOLFSSL_SUCCESS);

    /* Add in some key shares to make the CH long */
    ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_ECC_SECP256R1),
            WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_ECC_SECP384R1),
            WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_ECC_SECP521R1),
            WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_FFDHE_2048),
            WOLFSSL_SUCCESS);

    ExpectIntEQ(wolfSSL_dtls13_allow_ch_frag(ssl_s, 1), WOLFSSL_SUCCESS);

    /* Reject fragmented first CH */
    ExpectIntEQ(test_dtls_frag_ch_count_records(four_frag_CH,
            sizeof(four_frag_CH)), 4);
    XMEMCPY(test_ctx.s_buff, four_frag_CH, sizeof(four_frag_CH));
    test_ctx.s_len = sizeof(four_frag_CH);
    while (test_ctx.s_len > 0 && EXPECT_SUCCESS()) {
        int s_len = test_ctx.s_len;
        ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
        ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
        /* Fail if we didn't advance the buffer to avoid infinite loops */
        ExpectIntLT(test_ctx.s_len, s_len);
    }
    /* Expect all fragments read */
    ExpectIntEQ(test_ctx.s_len, 0);
    /* Expect quietly dropping fragmented first CH */
    ExpectIntEQ(test_ctx.c_len, 0);

#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
    /* Disable ECH as it pushes it over our MTU */
    wolfSSL_SetEchEnable(ssl_c, 0);
#endif

    /* Limit options to make the CH a fixed length */
    /* See wolfSSL_parse_cipher_list for reason why we provide 1.3 AND 1.2
     * ciphersuite. This is only necessary when building with OPENSSL_EXTRA. */
#ifdef OPENSSL_EXTRA
    ExpectTrue(wolfSSL_set_cipher_list(ssl_c, "TLS13-AES256-GCM-SHA384"
                                       ":DHE-RSA-AES256-GCM-SHA384"));
#else
    ExpectTrue(wolfSSL_set_cipher_list(ssl_c, "TLS13-AES256-GCM-SHA384"));
#endif

    /* CH1 */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    /* Count records. Expect 1 unfragmented CH */
    ExpectIntEQ(test_dtls_frag_ch_count_records(test_ctx.s_buff,
            test_ctx.s_len), 1);
    /* HRR */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    /* CH2 */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    /* Count records. Expect fragmented CH */
    ExpectIntGT(test_dtls_frag_ch_count_records(test_ctx.s_buff,
            test_ctx.s_len), 1);

    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
    ssl_c = ssl_s = NULL;
    ctx_c = ctx_s = NULL;
#endif
    return EXPECT_RESULT();
}

static int test_dtls_empty_keyshare_with_cookie(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    unsigned char ch_empty_keyshare_with_cookie[] = {
        0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
        0x12, 0x01, 0x00, 0x01, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
        0x06, 0xfe, 0xfd, 0xfb, 0x8c, 0x9b, 0x28, 0xae, 0x50, 0x1c, 0x4d, 0xf3,
        0xb8, 0xcf, 0x4d, 0xd8, 0x7e, 0x93, 0x13, 0x7b, 0x9e, 0xd9, 0xeb, 0xe9,
        0x13, 0x4b, 0x0d, 0x7f, 0x2e, 0x43, 0x62, 0x8c, 0xe4, 0x57, 0x79, 0x00,
        0x00, 0x00, 0x36, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x2c, 0xc0,
        0x2b, 0xc0, 0x30, 0xc0, 0x2f, 0x00, 0x9f, 0x00, 0x9e, 0xcc, 0xa9, 0xcc,
        0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x28, 0xc0, 0x24, 0xc0,
        0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x6b, 0x00, 0x67, 0x00,
        0x39, 0x00, 0x33, 0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0x01, 0x00, 0x00,
        0xa6, 0x00, 0x2b, 0x00, 0x03, 0x02, 0xfe, 0xfc, 0x00, 0x2c, 0x00, 0x47,
        0x00, 0x45, 0x20, 0xee, 0x4b, 0x17, 0x70, 0x63, 0xa0, 0x4c, 0x82, 0xbf,
        0x43, 0x01, 0x7d, 0x8d, 0xc1, 0x1b, 0x4e, 0x9b, 0xa0, 0x3c, 0x53, 0x1f,
        0xb7, 0xd1, 0x10, 0x81, 0xa8, 0xdf, 0xdf, 0x8c, 0x7f, 0xf3, 0x11, 0x13,
        0x01, 0x02, 0x3d, 0x3b, 0x7d, 0x14, 0x2c, 0x31, 0xb3, 0x60, 0x72, 0x4d,
        0xe5, 0x1a, 0xb2, 0xa3, 0x61, 0x77, 0x73, 0x03, 0x40, 0x0e, 0x5f, 0xc5,
        0x61, 0x38, 0x43, 0x56, 0x21, 0x4a, 0x95, 0xd5, 0x35, 0xa8, 0x0d, 0x00,
        0x0d, 0x00, 0x2a, 0x00, 0x28, 0x06, 0x03, 0x05, 0x03, 0x04, 0x03, 0x02,
        0x03, 0xfe, 0x0b, 0xfe, 0x0e, 0xfe, 0xa0, 0xfe, 0xa3, 0xfe, 0xa5, 0x08,
        0x06, 0x08, 0x0b, 0x08, 0x05, 0x08, 0x0a, 0x08, 0x04, 0x08, 0x09, 0x06,
        0x01, 0x05, 0x01, 0x04, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x0a, 0x00,
        0x18, 0x00, 0x16, 0x00, 0x19, 0x00, 0x18, 0x00, 0x17, 0x00, 0x15, 0x01,
        0x00, 0x02, 0x3a, 0x02, 0x3c, 0x02, 0x3d, 0x2f, 0x3a, 0x2f, 0x3c, 0x2f,
        0x3d, 0x00, 0x16, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x00
    };
    DtlsRecordLayerHeader* dtlsRH;
    byte sequence_number[8];

    XMEMSET(&sequence_number, 0, sizeof(sequence_number));
    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    XMEMCPY(test_ctx.s_buff, ch_empty_keyshare_with_cookie,
            sizeof(ch_empty_keyshare_with_cookie));
    test_ctx.s_len = sizeof(ch_empty_keyshare_with_cookie);
    ExpectIntEQ(test_memio_setup(&test_ctx, NULL, &ctx_s, NULL, &ssl_s,
        NULL, wolfDTLSv1_3_server_method), 0);

    /* CH1 */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    /* Expect an alert. A plaintext alert should be exactly 15 bytes. */
    ExpectIntEQ(test_ctx.c_len, 15);
    dtlsRH = (DtlsRecordLayerHeader*)test_ctx.c_buff;
    ExpectIntEQ(dtlsRH->type, alert);
    ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
    ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
    sequence_number[7] = 1;
    ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
            sizeof(sequence_number)), 0);
    ExpectIntEQ(dtlsRH->length[0], 0);
    ExpectIntEQ(dtlsRH->length[1], 2);
    ExpectIntEQ(test_ctx.c_buff[13], alert_fatal);
    ExpectIntEQ(test_ctx.c_buff[14], illegal_parameter);

    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
#endif
    return EXPECT_RESULT();
}

static int test_dtls_old_seq_number(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS)
    WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
    struct test_memio_ctx test_ctx;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
        wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);

    /* CH1 */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    /* HVR */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    /* CH2 */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    /* Server first flight */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    /* Client second flight */
    ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    /* Modify the sequence number */
    {
        DtlsRecordLayerHeader* dtlsRH = (DtlsRecordLayerHeader*)test_ctx.s_buff;
        XMEMSET(dtlsRH->sequence_number, 0, sizeof(dtlsRH->sequence_number));
    }
    /* Server second flight */
    ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
    /* Server should not do anything as a pkt was dropped */
    ExpectIntEQ(test_ctx.c_len, 0);
    ExpectIntEQ(test_ctx.s_len, 0);
    /* Trigger rtx */
    ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);

    /* Complete connection */
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

    wolfSSL_free(ssl_c);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_s);
#endif
    return EXPECT_RESULT();
}

static int test_dtls12_basic_connection_id(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS_CID)
    unsigned char client_cid[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
    unsigned char server_cid[] = { 0, 1, 2, 3, 4, 5 };
    unsigned char readBuf[40];
    const char* params[] = {
#ifndef NO_RSA
#ifndef NO_SHA256
#if defined(WOLFSSL_AES_128) && defined(WOLFSSL_STATIC_RSA)
        "AES128-SHA256",
#ifdef HAVE_AESCCM
        "AES128-CCM8",
#endif
        "DHE-RSA-AES128-SHA256",
        "ECDHE-RSA-AES128-SHA256",
#ifdef HAVE_AESGCM
        "DHE-RSA-AES128-GCM-SHA256",
        "ECDHE-RSA-AES128-GCM-SHA256",
#endif
#endif /* WOLFSSL_AES_128 && WOLFSSL_STATIC_RSA */
#endif /* NO_SHA256 */
#endif /* NO_RSA */
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
        "DHE-RSA-CHACHA20-POLY1305",
        "DHE-RSA-CHACHA20-POLY1305-OLD",
        "ECDHE-RSA-CHACHA20-POLY1305",
        "ECDHE-RSA-CHACHA20-POLY1305-OLD",
#endif
#ifndef NO_PSK
        "DHE-PSK-AES128-CBC-SHA256",
        "DHE-PSK-AES256-GCM-SHA384",
#ifndef HAVE_NULL_CIPHER
        "DHE-PSK-NULL-SHA256",
#endif
        "DHE-PSK-AES128-CCM",
#endif
    };
    size_t i;
    struct {
        byte drop:1;
        byte changeCID:1;
    } run_params[] = {
        { .drop = 0, .changeCID = 0 },
        { .drop = 1, .changeCID = 0 },
        { .drop = 0, .changeCID = 1 },
    };

    /* We check if the side included the CID in their output */
#define CLIENT_CID() mymemmem(test_ctx.s_buff, test_ctx.s_len, \
                              client_cid, sizeof(client_cid))
#define SERVER_CID() mymemmem(test_ctx.c_buff, test_ctx.c_len, \
                              server_cid, sizeof(server_cid))

    printf("\n");
    for (i = 0; i < XELEM_CNT(params) && EXPECT_SUCCESS(); i++) {
        size_t j;
        for (j = 0; j < XELEM_CNT(run_params); j++) {
            WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
            WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
            struct test_memio_ctx test_ctx;

            printf("Testing %s run #%ld ... ", params[i], j);

            XMEMSET(&test_ctx, 0, sizeof(test_ctx));

            ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
                &ssl_s, wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method),
                0);

            ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, params[i]), 1);
            ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, params[i]), 1);

            ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_c), 1);
            ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, server_cid,
                    sizeof(server_cid)), 1);
            ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_s), 1);
            ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_s, client_cid,
                    sizeof(client_cid)), 1);

#ifndef NO_PSK
            if (XSTRSTR(params[i], "-PSK-") != NULL) {
                wolfSSL_set_psk_client_callback(ssl_c, my_psk_client_cb);
                wolfSSL_set_psk_server_callback(ssl_s, my_psk_server_cb);
            }
#endif

#ifdef HAVE_SECURE_RENEGOTIATION
            ExpectIntEQ(wolfSSL_UseSecureRenegotiation(ssl_c), 1);
            ExpectIntEQ(wolfSSL_UseSecureRenegotiation(ssl_s), 1);
#endif

            /* CH1 */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNull(CLIENT_CID());
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
                ExpectNull(CLIENT_CID());
            }
            /* HVR */
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNull(SERVER_CID());
            /* No point dropping HVR */
            /* CH2 */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNull(CLIENT_CID());
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
                ExpectNull(CLIENT_CID());
            }
            /* Server first flight */
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNull(SERVER_CID());
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
                ExpectNull(SERVER_CID());
            }
            /* Client second flight */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNotNull(CLIENT_CID());
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
                ExpectNotNull(CLIENT_CID());
            }
            /* Server second flight */
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
            ExpectNotNull(SERVER_CID());
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
                ExpectNotNull(SERVER_CID());
            }
            /* Client complete connection */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);
            ExpectNull(CLIENT_CID());

            /* Write some data */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_write(ssl_c, params[i],
                    (int)XSTRLEN(params[i])), XSTRLEN(params[i]));
            ExpectNotNull(CLIENT_CID());
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_write(ssl_s, params[i],
                    (int)XSTRLEN(params[i])), XSTRLEN(params[i]));
            ExpectNotNull(SERVER_CID());
            /* Read the data */
            wolfSSL_SetLoggingPrefix("client");
            XMEMSET(readBuf, 0, sizeof(readBuf));
            ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)),
                    XSTRLEN(params[i]));
            ExpectStrEQ(readBuf, params[i]);
            XMEMSET(readBuf, 0, sizeof(readBuf));
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)),
                    XSTRLEN(params[i]));
            ExpectStrEQ(readBuf, params[i]);
            /* Write short data */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_write(ssl_c, params[i], 1), 1);
            ExpectNotNull(CLIENT_CID());
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_write(ssl_s, params[i], 1), 1);
            ExpectNotNull(SERVER_CID());
            /* Read the short data */
            XMEMSET(readBuf, 0, sizeof(readBuf));
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), 1);
            ExpectIntEQ(readBuf[0], params[i][0]);
            XMEMSET(readBuf, 0, sizeof(readBuf));
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), 1);
            ExpectIntEQ(readBuf[0], params[i][0]);

#ifdef HAVE_SECURE_RENEGOTIATION
            /* do two SCR's */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
            /* SCR's after the first one have extra internal logic */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

            if (run_params[j].changeCID) {
                ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, client_cid,
                        sizeof(client_cid)), 0);
                /* Forcefully change the CID */
                ssl_c->dtlsCidInfo->rx->id[0] = -1;
                /* We need to init the rehandshake from the client, otherwise
                 * we won't be able to test changing the CID. It would be
                 * rejected by the record CID matching code. */
                wolfSSL_SetLoggingPrefix("client");
                ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1);
                ExpectIntEQ(wolfSSL_get_error(ssl_c, -1),
                        WOLFSSL_ERROR_WANT_READ);
                ExpectNotNull(CLIENT_CID());
                ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 1);
                /* Server first flight */
                wolfSSL_SetLoggingPrefix("server");
                ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1);
                /* We expect the server to reject the CID change. */
                ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), DTLS_CID_ERROR);
                goto loop_exit;
            }
            /* Server init'd SCR */
            /* Server request */
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_Rehandshake(ssl_s), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNotNull(SERVER_CID());
            ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_s), 1);
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
                ExpectNotNull(SERVER_CID());
            }
            /* Init SCR on client side with the server's request */
            /* CH no HVR on SCR */
            XMEMSET(readBuf, 0, sizeof(readBuf));
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNotNull(CLIENT_CID());
            ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 1);
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
                ExpectNotNull(CLIENT_CID());
            }
            /* Server first flight */
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNotNull(SERVER_CID());
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
                ExpectNotNull(SERVER_CID());
            }
            /* Client second flight */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNotNull(CLIENT_CID());
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
                ExpectNotNull(CLIENT_CID());
            }
            ExpectIntEQ(wolfSSL_write(ssl_c, params[i],
                    (int)XSTRLEN(params[i])), XSTRLEN(params[i]));
            /* Server second flight */
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), APP_DATA_READY);
            XMEMSET(readBuf, 0, sizeof(readBuf));
            ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)),
                    XSTRLEN(params[i]));
            ExpectStrEQ(readBuf, params[i]);
            if (!run_params[j].drop) {
                ExpectIntEQ(wolfSSL_write(ssl_s, params[i],
                        (int)XSTRLEN(params[i])), XSTRLEN(params[i]));
            }
            ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
            ExpectNotNull(SERVER_CID());
            if (run_params[j].drop) {
                test_ctx.c_len = test_ctx.s_len = 0;
                ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
                ExpectNotNull(SERVER_CID());
            }
            /* Test loading old epoch */
            /* Client complete connection */
            wolfSSL_SetLoggingPrefix("client");
            if (!run_params[j].drop) {
                ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
                ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), APP_DATA_READY);
                XMEMSET(readBuf, 0, sizeof(readBuf));
                ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)),
                        XSTRLEN(params[i]));
                ExpectStrEQ(readBuf, params[i]);
            }
            ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);
            ExpectNull(CLIENT_CID());
            ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 0);
            ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_s), 0);
#endif
            /* Close connection */
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE);
            ExpectNotNull(CLIENT_CID());
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);
            ExpectNotNull(SERVER_CID());
            wolfSSL_SetLoggingPrefix("client");
            ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1);
            wolfSSL_SetLoggingPrefix("server");
            ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1);

#ifdef HAVE_SECURE_RENEGOTIATION
loop_exit:
#endif
            wolfSSL_SetLoggingPrefix(NULL);
            wolfSSL_free(ssl_c);
            wolfSSL_CTX_free(ctx_c);
            wolfSSL_free(ssl_s);
            wolfSSL_CTX_free(ctx_s);

            if (EXPECT_SUCCESS())
                printf("ok\n");
            else
                printf("failed\n");
        }

    }

#undef CLIENT_CID
#undef SERVER_CID
#endif
    return EXPECT_RESULT();
}

static int test_dtls13_basic_connection_id(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
    && defined(WOLFSSL_DTLS_CID)
    unsigned char client_cid[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
    unsigned char server_cid[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    unsigned char readBuf[30];
    const char* params[] = {
#ifndef NO_SHA256
#ifdef WOLFSSL_AES_128
#ifdef HAVE_AESGCM
        "TLS13-AES128-GCM-SHA256",
#endif
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
        "TLS13-CHACHA20-POLY1305-SHA256",
#endif
#ifdef HAVE_AESCCM
        "TLS13-AES128-CCM-8-SHA256",
        "TLS13-AES128-CCM-SHA256",
#endif
#endif
#ifdef HAVE_NULL_CIPHER
        "TLS13-SHA256-SHA256",
#endif
#endif
    };
    size_t i;

    /* We check if the side included the CID in their output */
#define CLIENT_CID() mymemmem(test_ctx.s_buff, test_ctx.s_len, \
                              client_cid, sizeof(client_cid))
#define SERVER_CID() mymemmem(test_ctx.c_buff, test_ctx.c_len, \
                              server_cid, sizeof(server_cid))

    printf("\n");
    for (i = 0; i < XELEM_CNT(params) && EXPECT_SUCCESS(); i++) {
        WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
        WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
        struct test_memio_ctx test_ctx;

        printf("Testing %s ... ", params[i]);

        XMEMSET(&test_ctx, 0, sizeof(test_ctx));

        ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);

        ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, params[i]), WOLFSSL_SUCCESS);
        ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, params[i]), WOLFSSL_SUCCESS);

        ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_c), 1);
        ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, server_cid, sizeof(server_cid)),
                1);
        ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_s), 1);
        ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_s, client_cid, sizeof(client_cid)),
                1);

        /* CH1 */
        ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
        ExpectNull(CLIENT_CID());
        /* HRR */
        ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
        ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
        ExpectNull(SERVER_CID());
        /* CH2 */
        ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
        ExpectNull(CLIENT_CID());
        /* Server first flight */
        ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
        ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
        ExpectNotNull(SERVER_CID());
        /* Client second flight */
        ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
        ExpectNotNull(CLIENT_CID());
        /* Server process flight */
        ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
        /* Client process flight */
        ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);

        /* Write some data */
        ExpectIntEQ(wolfSSL_write(ssl_c, params[i], (int)XSTRLEN(params[i])),
                XSTRLEN(params[i]));
        ExpectNotNull(CLIENT_CID());
        ExpectIntEQ(wolfSSL_write(ssl_s, params[i], (int)XSTRLEN(params[i])),
                XSTRLEN(params[i]));
        ExpectNotNull(SERVER_CID());
        /* Read the data */
        XMEMSET(readBuf, 0, sizeof(readBuf));
        ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)),
                XSTRLEN(params[i]));
        ExpectStrEQ(readBuf, params[i]);
        XMEMSET(readBuf, 0, sizeof(readBuf));
        ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)),
                XSTRLEN(params[i]));
        ExpectStrEQ(readBuf, params[i]);
        /* Write short data */
        ExpectIntEQ(wolfSSL_write(ssl_c, params[i], 1), 1);
        ExpectNotNull(CLIENT_CID());
        ExpectIntEQ(wolfSSL_write(ssl_s, params[i], 1), 1);
        ExpectNotNull(SERVER_CID());
        /* Read the short data */
        XMEMSET(readBuf, 0, sizeof(readBuf));
        ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), 1);
        ExpectIntEQ(readBuf[0], params[i][0]);
        XMEMSET(readBuf, 0, sizeof(readBuf));
        ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), 1);
        ExpectIntEQ(readBuf[0], params[i][0]);

        /* Close connection */
        ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE);
        ExpectNotNull(CLIENT_CID());
        ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);
        ExpectNotNull(SERVER_CID());
        ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1);
        ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1);

        if (EXPECT_SUCCESS())
            printf("ok\n");
        else
            printf("failed\n");

        wolfSSL_free(ssl_c);
        wolfSSL_CTX_free(ctx_c);
        wolfSSL_free(ssl_s);
        wolfSSL_CTX_free(ctx_s);
    }

#undef CLIENT_CID
#undef SERVER_CID

#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
    defined(HAVE_LIBOQS)
static void test_tls13_pq_groups_ctx_ready(WOLFSSL_CTX* ctx)
{
    int group = WOLFSSL_KYBER_LEVEL5;
    AssertIntEQ(wolfSSL_CTX_set_groups(ctx, &group, 1), WOLFSSL_SUCCESS);
}

static void test_tls13_pq_groups_on_result(WOLFSSL* ssl)
{
    AssertStrEQ(wolfSSL_get_curve_name(ssl), "KYBER_LEVEL5");
}
#endif

static int test_tls13_pq_groups(void)
{
    EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
    defined(HAVE_LIBOQS)
    callback_functions func_cb_client;
    callback_functions func_cb_server;

    XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
    XMEMSET(&func_cb_server, 0, sizeof(callback_functions));

    func_cb_client.method = wolfTLSv1_3_client_method;
    func_cb_server.method = wolfTLSv1_3_server_method;
    func_cb_client.ctx_ready = test_tls13_pq_groups_ctx_ready;
    func_cb_client.on_result = test_tls13_pq_groups_on_result;
    func_cb_server.on_result = test_tls13_pq_groups_on_result;

    test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);

    ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
    ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
#endif
    return EXPECT_RESULT();
}

static int test_tls13_early_data(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(WOLFSSL_EARLY_DATA) && defined(HAVE_SESSION_TICKET)
    int written = 0;
    int read = 0;
    size_t i;
    int splitEarlyData;
    char msg[] = "This is early data";
    char msg2[] = "This is client data";
    char msg3[] = "This is server data";
    char msg4[] = "This is server immediate data";
    char msgBuf[50];
    struct {
        method_provider client_meth;
        method_provider server_meth;
        const char* tls_version;
        int isUdp;
    } params[] = {
#ifdef WOLFSSL_TLS13
        { wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
                "TLS 1.3", 0 },
#endif
#ifdef WOLFSSL_DTLS13
        { wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method,
                "DTLS 1.3", 1 },
#endif
    };

    for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) {
        for (splitEarlyData = 0; splitEarlyData < 2; splitEarlyData++) {
            struct test_memio_ctx test_ctx;
            WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
            WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
            WOLFSSL_SESSION *sess = NULL;

            XMEMSET(&test_ctx, 0, sizeof(test_ctx));

            fprintf(stderr, "\tEarly data with %s\n", params[i].tls_version);

            ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
                    &ssl_s, params[i].client_meth, params[i].server_meth), 0);

            /* Get a ticket so that we can do 0-RTT on the next connection */
            ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
            /* Make sure we read the ticket */
            ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
            ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));

            wolfSSL_free(ssl_c);
            ssl_c = NULL;
            wolfSSL_free(ssl_s);
            ssl_s = NULL;
            XMEMSET(&test_ctx, 0, sizeof(test_ctx));
            ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
                    params[i].client_meth, params[i].server_meth), 0);
            ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_DTLS13
            if (params[i].isUdp) {
#ifdef WOLFSSL_DTLS13_NO_HRR_ON_RESUME
                ExpectIntEQ(wolfSSL_dtls13_no_hrr_on_resume(ssl_s, 1), WOLFSSL_SUCCESS);
#else
                /* Let's test this but we generally don't recommend turning off the
                 * cookie exchange */
                ExpectIntEQ(wolfSSL_disable_hrr_cookie(ssl_s), WOLFSSL_SUCCESS);
#endif
            }
#endif

            /* Test 0-RTT data */
            ExpectIntEQ(wolfSSL_write_early_data(ssl_c, msg, sizeof(msg),
                    &written), sizeof(msg));
            ExpectIntEQ(written, sizeof(msg));

            if (splitEarlyData) {
                ExpectIntEQ(wolfSSL_write_early_data(ssl_c, msg, sizeof(msg),
                        &written), sizeof(msg));
                ExpectIntEQ(written, sizeof(msg));
            }

            /* Read first 0-RTT data (if split otherwise entire data) */
            ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
                    &read), sizeof(msg));
            ExpectIntEQ(read, sizeof(msg));
            ExpectStrEQ(msg, msgBuf);

            /* Test 0.5-RTT data */
            ExpectIntEQ(wolfSSL_write(ssl_s, msg4, sizeof(msg4)), sizeof(msg4));

            if (splitEarlyData) {
                /* Read second 0-RTT data */
                ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
                        &read), sizeof(msg));
                ExpectIntEQ(read, sizeof(msg));
                ExpectStrEQ(msg, msgBuf);
            }

            if (params[i].isUdp) {
                ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
                ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WC_NO_ERR_TRACE(APP_DATA_READY));

                /* Read server 0.5-RTT data */
                ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg4));
                ExpectStrEQ(msg4, msgBuf);

                /* Complete handshake */
                ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
                ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
                /* Use wolfSSL_is_init_finished to check if handshake is complete. Normally
                 * a user would loop until it is true but here we control both sides so we
                 * just assert the expected value. wolfSSL_read_early_data does not provide
                 * handshake status to us with non-blocking IO and we can't use
                 * wolfSSL_accept as TLS layer may return ZERO_RETURN due to early data
                 * parsing logic. */
                ExpectFalse(wolfSSL_is_init_finished(ssl_s));
                ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
                        &read), 0);
                ExpectIntEQ(read, 0);
                ExpectTrue(wolfSSL_is_init_finished(ssl_s));

                ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
            }
            else {
                ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);

                ExpectFalse(wolfSSL_is_init_finished(ssl_s));
                ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
                        &read), 0);
                ExpectIntEQ(read, 0);
                ExpectTrue(wolfSSL_is_init_finished(ssl_s));

                /* Read server 0.5-RTT data */
                ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg4));
                ExpectStrEQ(msg4, msgBuf);
            }

            /* Test bi-directional write */
            ExpectIntEQ(wolfSSL_write(ssl_c, msg2, sizeof(msg2)), sizeof(msg2));
            ExpectIntEQ(wolfSSL_read(ssl_s, msgBuf, sizeof(msgBuf)), sizeof(msg2));
            ExpectStrEQ(msg2, msgBuf);
            ExpectIntEQ(wolfSSL_write(ssl_s, msg3, sizeof(msg3)), sizeof(msg3));
            ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg3));
            ExpectStrEQ(msg3, msgBuf);

            ExpectTrue(wolfSSL_session_reused(ssl_c));
            ExpectTrue(wolfSSL_session_reused(ssl_s));

            wolfSSL_SESSION_free(sess);
            wolfSSL_free(ssl_c);
            wolfSSL_free(ssl_s);
            wolfSSL_CTX_free(ctx_c);
            wolfSSL_CTX_free(ctx_s);
        }
    }
#endif
    return EXPECT_RESULT();
}

#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
static int test_self_signed_stapling_client_v1_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1);
    ExpectIntEQ(wolfSSL_CTX_UseOCSPStapling(ctx, WOLFSSL_CSR_OCSP,
            WOLFSSL_CSR_OCSP_USE_NONCE), 1);
    return EXPECT_RESULT();
}
#endif

#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
static int test_self_signed_stapling_client_v2_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1);
    ExpectIntEQ(wolfSSL_CTX_UseOCSPStaplingV2(ctx, WOLFSSL_CSR2_OCSP,
            WOLFSSL_CSR2_OCSP_USE_NONCE), 1);
    return EXPECT_RESULT();
}

static int test_self_signed_stapling_client_v2_multi_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1);
    ExpectIntEQ(wolfSSL_CTX_UseOCSPStaplingV2(ctx, WOLFSSL_CSR2_OCSP_MULTI,
            0), 1);
    return EXPECT_RESULT();
}
#endif

#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
static int test_self_signed_stapling_server_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1);
    return EXPECT_RESULT();
}
#endif

static int test_self_signed_stapling(void)
{
    EXPECT_DECLS;
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;
    size_t i;
    struct {
        method_provider client_meth;
        method_provider server_meth;
        ctx_cb client_ctx;
        const char* tls_version;
    } params[] = {
#if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)
        { wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
            test_self_signed_stapling_client_v1_ctx_ready, "TLSv1_3 v1" },
#endif
#ifndef WOLFSSL_NO_TLS12
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
        { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method,
            test_self_signed_stapling_client_v1_ctx_ready, "TLSv1_2 v1" },
#endif
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
        { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method,
            test_self_signed_stapling_client_v2_ctx_ready, "TLSv1_2 v2" },
        { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method,
            test_self_signed_stapling_client_v2_multi_ctx_ready,
            "TLSv1_2 v2 multi" },
#endif
#endif
    };

    for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) {
        XMEMSET(&client_cbf, 0, sizeof(client_cbf));
        XMEMSET(&server_cbf, 0, sizeof(server_cbf));

        printf("\nTesting self-signed cert with status request: %s\n",
                params[i].tls_version);

        client_cbf.method = params[i].client_meth;
        client_cbf.ctx_ready = params[i].client_ctx;

        server_cbf.method = params[i].server_meth;
        server_cbf.certPemFile = "certs/ca-cert.pem";
        server_cbf.keyPemFile  = "certs/ca-key.pem";
        server_cbf.ctx_ready = test_self_signed_stapling_server_ctx_ready;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
            &server_cbf, NULL), TEST_SUCCESS);
    }
#endif
    return EXPECT_RESULT();
}

static int test_tls_multi_handshakes_one_record(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
    struct test_memio_ctx test_ctx;
    WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
    RecordLayerHeader* rh = NULL;
    byte   *len ;
    int newRecIdx = RECORD_HEADER_SZ;
    int idx = 0;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));

    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLS_client_method, wolfTLSv1_2_server_method), 0);

    ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
    ExpectIntEQ(wolfSSL_accept(ssl_s), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);

    /* Combine server handshake msgs into one record */
    while (idx < test_ctx.c_len) {
        word16 recLen;

        rh = (RecordLayerHeader*)(test_ctx.c_buff + idx);
        len = &rh->length[0];

        ato16((const byte*)len, &recLen);
        idx += RECORD_HEADER_SZ;

        XMEMMOVE(test_ctx.c_buff + newRecIdx, test_ctx.c_buff + idx,
                (size_t)recLen);

        newRecIdx += recLen;
        idx += recLen;
    }
    rh = (RecordLayerHeader*)(test_ctx.c_buff);
    len = &rh->length[0];
    c16toa((word16)newRecIdx - RECORD_HEADER_SZ, len);
    test_ctx.c_len = newRecIdx;

    ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);

    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);
#endif
    return EXPECT_RESULT();
}


static int test_write_dup(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_WRITE_DUP)
    size_t i, j;
    char hiWorld[] = "dup message";
    char readData[sizeof(hiWorld) + 5];
    struct {
        method_provider client_meth;
        method_provider server_meth;
        const char* version_name;
        int version;
    } methods[] = {
#ifndef WOLFSSL_NO_TLS12
        {wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2", WOLFSSL_TLSV1_2},
#endif
#ifdef WOLFSSL_TLS13
        {wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3", WOLFSSL_TLSV1_3},
#endif
    };
    struct {
        const char* cipher;
        int version;
    } ciphers[] = {
/* For simplicity the macros are copied from internal.h */
/* TLS 1.2 */
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256)
    #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
        #ifndef NO_RSA
            {"ECDHE-RSA-CHACHA20-POLY1305", WOLFSSL_TLSV1_2},
        #endif
    #endif
    #if !defined(NO_DH) && !defined(NO_RSA) && !defined(NO_TLS_DH)
        {"DHE-RSA-CHACHA20-POLY1305", WOLFSSL_TLSV1_2},
    #endif
#endif
#if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && \
    !defined(NO_RSA) && defined(HAVE_AESGCM) && !defined(NO_TLS_DH)
    #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128)
        {"DHE-RSA-AES128-GCM-SHA256", WOLFSSL_TLSV1_2},
    #endif
    #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
        {"DHE-RSA-AES256-GCM-SHA384", WOLFSSL_TLSV1_2},
    #endif
#endif
#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)) \
                                         && !defined(NO_TLS) && !defined(NO_AES)
    #ifdef HAVE_AESGCM
        #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128)
            #ifndef NO_RSA
                {"ECDHE-RSA-AES128-GCM-SHA256", WOLFSSL_TLSV1_2},
            #endif
        #endif
        #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
            #ifndef NO_RSA
                {"ECDHE-RSA-AES256-GCM-SHA384", WOLFSSL_TLSV1_2},
            #endif
        #endif
    #endif
#endif
/* TLS 1.3 */
#ifdef WOLFSSL_TLS13
    #ifdef HAVE_AESGCM
        #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128)
            {"TLS13-AES128-GCM-SHA256", WOLFSSL_TLSV1_3},
        #endif
        #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
            {"TLS13-AES256-GCM-SHA384", WOLFSSL_TLSV1_3},
        #endif
    #endif
    #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
        #ifndef NO_SHA256
            {"TLS13-CHACHA20-POLY1305-SHA256", WOLFSSL_TLSV1_3},
        #endif
    #endif
    #ifdef HAVE_AESCCM
        #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128)
            {"TLS13-AES128-CCM-SHA256", WOLFSSL_TLSV1_3},
        #endif
    #endif
#endif
    };

    for (i = 0; i < XELEM_CNT(methods); i++) {
        for (j = 0; j < XELEM_CNT(ciphers) && !EXPECT_FAIL(); j++) {
            struct test_memio_ctx test_ctx;
            WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
            WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
            WOLFSSL *ssl_c2 = NULL;

            if (methods[i].version != ciphers[j].version)
                continue;

            if (i == 0 && j == 0)
                printf("\n");

            printf("Testing %s with %s... ", methods[i].version_name,
                    ciphers[j].cipher);

            XMEMSET(&test_ctx, 0, sizeof(test_ctx));

            test_ctx.c_ciphers = test_ctx.s_ciphers = ciphers[j].cipher;

            ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
                    methods[i].client_meth, methods[i].server_meth), 0);
            ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

            ExpectNotNull(ssl_c2 = wolfSSL_write_dup(ssl_c));
            ExpectIntEQ(wolfSSL_write(ssl_c, hiWorld, sizeof(hiWorld)),
                    WC_NO_ERR_TRACE(WRITE_DUP_WRITE_E));
            ExpectIntEQ(wolfSSL_write(ssl_c2, hiWorld, sizeof(hiWorld)),
                    sizeof(hiWorld));

            ExpectIntEQ(wolfSSL_read(ssl_s, readData, sizeof(readData)),
                    sizeof(hiWorld));
            ExpectIntEQ(wolfSSL_write(ssl_s, hiWorld, sizeof(hiWorld)),
                    sizeof(hiWorld));

            ExpectIntEQ(wolfSSL_read(ssl_c2, readData, sizeof(readData)),
                    WC_NO_ERR_TRACE(WRITE_DUP_READ_E));
            ExpectIntEQ(wolfSSL_read(ssl_c, readData, sizeof(readData)),
                    sizeof(hiWorld));

            if (EXPECT_SUCCESS())
                printf("ok\n");
            else
                printf("failed\n");

            wolfSSL_free(ssl_c);
            wolfSSL_free(ssl_c2);
            wolfSSL_free(ssl_s);
            wolfSSL_CTX_free(ctx_c);
            wolfSSL_CTX_free(ctx_s);
        }
    }
#endif
    return EXPECT_RESULT();
}

static int test_read_write_hs(void)
{

    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
    WOLFSSL_CTX *ctx_s = NULL, *ctx_c = NULL;
    WOLFSSL *ssl_s = NULL, *ssl_c = NULL;
    struct test_memio_ctx test_ctx;
    byte test_buffer[16];
    unsigned int test;

    /* test == 0 : client writes, server reads */
    /* test == 1 : server writes, client reads */
    for (test = 0; test < 2; test++) {
        XMEMSET(&test_ctx, 0, sizeof(test_ctx));
        ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s,  &ssl_c, &ssl_s,
                                     wolfTLSv1_2_client_method,
                                     wolfTLSv1_2_server_method), 0);
        ExpectIntEQ(wolfSSL_set_group_messages(ssl_s), WOLFSSL_SUCCESS);
        /* CH -> */
        if (test == 0) {
            ExpectIntEQ(wolfSSL_write(ssl_c, "hello", 5), -1);
        } else {
            ExpectIntEQ(wolfSSL_read(ssl_c, test_buffer,
                                     sizeof(test_buffer)),  -1);
        }
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);

        /* <- SH + SKE + SHD */
        if (test == 0) {
            ExpectIntEQ(wolfSSL_read(ssl_s, test_buffer,
                                     sizeof(test_buffer)), -1);
        } else {
            ExpectIntEQ(wolfSSL_write(ssl_s, "hello", 5), -1);
        }
        ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);

        /* -> CKE + CLIENT FINISHED */
        if (test == 0) {
            ExpectIntEQ(wolfSSL_write(ssl_c, "hello", 5), -1);
        } else {
            ExpectIntEQ(wolfSSL_read(ssl_c, test_buffer,
                                     sizeof(test_buffer)), -1);
        }
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);

        /* abide clang static analyzer */
        if (ssl_s != NULL) {
            /* disable group message to separate sending of ChangeCipherspec
             * from Finished */
            ssl_s->options.groupMessages = 0;
        }
        /* allow writing of CS, but not FINISHED */
        test_ctx.c_len = TEST_MEMIO_BUF_SZ - 6;

        /* <- CS */
        if (test == 0) {
            ExpectIntEQ(wolfSSL_read(ssl_s, test_buffer,
                                     sizeof(test_buffer)), -1);
        } else {
            ExpectIntEQ(wolfSSL_write(ssl_s, "hello", 5), -1);
        }
        ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_WRITE);

        /* move CS message where the client can read it */
        memmove(test_ctx.c_buff,
                (test_ctx.c_buff + TEST_MEMIO_BUF_SZ - 6), 6);
        test_ctx.c_len = 6;
        /* read CS */
        if (test == 0) {
            ExpectIntEQ(wolfSSL_write(ssl_c, "hello", 5), -1);
        } else {
            ExpectIntEQ(wolfSSL_read(ssl_c, test_buffer,
                                     sizeof(test_buffer)), -1);
        }
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
        ExpectIntEQ(test_ctx.c_len, 0);

        if (test == 0) {
            /* send SERVER FINISHED */
            ExpectIntEQ(wolfSSL_read(ssl_s, test_buffer,
                                     sizeof(test_buffer)), -1);
            ExpectIntEQ(wolfSSL_get_error(ssl_s, -1),
                        WOLFSSL_ERROR_WANT_READ);
        } else {
            /* send SERVER FINISHED + App Data */
            ExpectIntEQ(wolfSSL_write(ssl_s, "hello", 5), 5);
        }

        ExpectIntGT(test_ctx.c_len, 0);

        /* Send and receive the data */
        if (test == 0) {
            ExpectIntEQ(wolfSSL_write(ssl_c, "hello", 5), 5);
            ExpectIntEQ(wolfSSL_read(ssl_s, test_buffer,
                                     sizeof(test_buffer)), 5);
        } else {
            ExpectIntEQ(wolfSSL_read(ssl_c, test_buffer,
                                     sizeof(test_buffer)), 5);
        }

        ExpectBufEQ(test_buffer, "hello", 5);

        wolfSSL_free(ssl_c);
        wolfSSL_free(ssl_s);
        wolfSSL_CTX_free(ctx_c);
        wolfSSL_CTX_free(ctx_s);
        ssl_c = ssl_s = NULL;
        ctx_c = ctx_s = NULL;
    }

#endif
    return EXPECT_RESULT();
}

#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(OPENSSL_EXTRA)
static const char* test_get_signature_nid_siglag;
static int test_get_signature_nid_sig;
static int test_get_signature_nid_hash;

static int test_get_signature_nid_ssl_ready(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "ALL"), WOLFSSL_SUCCESS);
    if (!wolfSSL_is_server(ssl)) {
        ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
            test_get_signature_nid_siglag), WOLFSSL_SUCCESS);
    }
    return EXPECT_RESULT();
}

static int test_get_signature_nid_on_hs_client(WOLFSSL_CTX **ctx, WOLFSSL **ssl)
{
    EXPECT_DECLS;
    int nid = 0;
    (void)ctx;
    if (XSTRSTR(wolfSSL_get_cipher(*ssl), "TLS_RSA_") == NULL) {
        ExpectIntEQ(SSL_get_peer_signature_type_nid(*ssl, &nid), WOLFSSL_SUCCESS);
        ExpectIntEQ(nid, test_get_signature_nid_sig);
        ExpectIntEQ(SSL_get_peer_signature_nid(*ssl, &nid), WOLFSSL_SUCCESS);
        ExpectIntEQ(nid, test_get_signature_nid_hash);
    }
    else /* No sigalg info on static ciphersuite */
        return TEST_SUCCESS;
    return EXPECT_RESULT();
}

static int test_get_signature_nid_on_hs_server(WOLFSSL_CTX **ctx, WOLFSSL **ssl)
{
    EXPECT_DECLS;
    int nid = 0;
    (void)ctx;
    ExpectIntEQ(SSL_get_signature_type_nid(*ssl, &nid), WOLFSSL_SUCCESS);
    ExpectIntEQ(nid, test_get_signature_nid_sig);
    ExpectIntEQ(SSL_get_signature_nid(*ssl, &nid), WOLFSSL_SUCCESS);
    ExpectIntEQ(nid, test_get_signature_nid_hash);
    return EXPECT_RESULT();
}
#endif

static int test_get_signature_nid(void)
{
    EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(OPENSSL_EXTRA)
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;
    size_t i;
#define TGSN_TLS12_RSA(sigalg, sig_nid, hash_nid) \
        { sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_2, svrCertFile, svrKeyFile, \
          caCertFile }
#define TGSN_TLS12_ECDSA(sigalg, sig_nid, hash_nid) \
        { sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_2, eccCertFile, eccKeyFile, \
          caEccCertFile }
#define TGSN_TLS13_RSA(sigalg, sig_nid, hash_nid) \
        { sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_3, svrCertFile, svrKeyFile, \
          caCertFile }
#define TGSN_TLS13_ECDSA(sigalg, sig_nid, hash_nid) \
        { sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_3, eccCertFile, eccKeyFile, \
          caEccCertFile }
#define TGSN_TLS13_ED25519(sigalg, sig_nid, hash_nid) \
        { sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_3, edCertFile, edKeyFile, \
            caEdCertFile }
#define TGSN_TLS13_ED448(sigalg, sig_nid, hash_nid) \
        { sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_3, ed448CertFile, ed448KeyFile, \
            caEd448CertFile }
    struct {
        const char* siglag;
        int sig_nid;
        int hash_nid;
        int tls_ver;
        const char* server_cert;
        const char* server_key;
        const char* client_ca;
    } params[] = {
#ifndef NO_RSA
    #ifndef NO_SHA256
        TGSN_TLS12_RSA("RSA+SHA256", NID_rsaEncryption, NID_sha256),
        #ifdef WC_RSA_PSS
        TGSN_TLS12_RSA("RSA-PSS+SHA256", NID_rsassaPss, NID_sha256),
        TGSN_TLS13_RSA("RSA-PSS+SHA256", NID_rsassaPss, NID_sha256),
        #endif
    #endif
    #ifdef WOLFSSL_SHA512
        TGSN_TLS12_RSA("RSA+SHA512", NID_rsaEncryption, NID_sha512),
        #ifdef WC_RSA_PSS
        TGSN_TLS12_RSA("RSA-PSS+SHA512", NID_rsassaPss, NID_sha512),
        TGSN_TLS13_RSA("RSA-PSS+SHA512", NID_rsassaPss, NID_sha512),
        #endif
    #endif
#endif
#ifdef HAVE_ECC
    #ifndef NO_SHA256
        TGSN_TLS12_ECDSA("ECDSA+SHA256", NID_X9_62_id_ecPublicKey, NID_sha256),
        TGSN_TLS13_ECDSA("ECDSA+SHA256", NID_X9_62_id_ecPublicKey, NID_sha256),
    #endif
#endif
#ifdef HAVE_ED25519
        TGSN_TLS13_ED25519("ED25519", NID_ED25519, NID_sha512),
#endif
#ifdef HAVE_ED448
        TGSN_TLS13_ED448("ED448", NID_ED448, NID_sha512),
#endif
    };

    printf("\n");

    for (i = 0; i < XELEM_CNT(params) && !EXPECT_FAIL(); i++) {

        XMEMSET(&client_cbf, 0, sizeof(client_cbf));
        XMEMSET(&server_cbf, 0, sizeof(server_cbf));

        printf("Testing %s with %s...", tls_desc[params[i].tls_ver],
                params[i].siglag);

        switch (params[i].tls_ver) {
#ifndef WOLFSSL_NO_TLS12
            case WOLFSSL_TLSV1_2:
                client_cbf.method = wolfTLSv1_2_client_method;
                server_cbf.method = wolfTLSv1_2_server_method;
                break;
#endif
#ifdef WOLFSSL_TLS13
            case WOLFSSL_TLSV1_3:
                client_cbf.method = wolfTLSv1_3_client_method;
                server_cbf.method = wolfTLSv1_3_server_method;
                break;
#endif
            default:
                printf("skipping\n");
                continue;
        }

        test_get_signature_nid_siglag = params[i].siglag;
        test_get_signature_nid_sig = params[i].sig_nid;
        test_get_signature_nid_hash = params[i].hash_nid;

        client_cbf.ssl_ready = test_get_signature_nid_ssl_ready;
        server_cbf.ssl_ready = test_get_signature_nid_ssl_ready;

        client_cbf.on_handshake = test_get_signature_nid_on_hs_client;
        server_cbf.on_handshake = test_get_signature_nid_on_hs_server;

        server_cbf.certPemFile = params[i].server_cert;
        server_cbf.keyPemFile = params[i].server_key;

        client_cbf.caPemFile = params[i].client_ca;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
            &server_cbf, NULL), TEST_SUCCESS);
        if (EXPECT_SUCCESS())
            printf("passed\n");
    }

#endif
    return EXPECT_RESULT();
}

#if !defined(NO_CERTS) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static word32 test_tls_cert_store_unchanged_HashCaTable(Signer** caTable)
{
#ifndef NO_MD5
    enum wc_HashType hashType = WC_HASH_TYPE_MD5;
#elif !defined(NO_SHA)
    enum wc_HashType hashType = WC_HASH_TYPE_SHA;
#elif !defined(NO_SHA256)
    enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
#else
    #error "We need a digest to hash the Signer object"
#endif
    byte hashBuf[WC_MAX_DIGEST_SIZE];
    wc_HashAlg hash;
    size_t i;

    AssertIntEQ(wc_HashInit(&hash, hashType), 0);
    for (i = 0; i < CA_TABLE_SIZE; i++) {
        Signer* cur;
        for (cur = caTable[i]; cur != NULL; cur = cur->next)
            AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)cur,
                    sizeof(*cur)), 0);
    }
    AssertIntEQ(wc_HashFinal(&hash, hashType, hashBuf), 0);
    AssertIntEQ(wc_HashFree(&hash, hashType), 0);

    return MakeWordFromHash(hashBuf);
}

static word32 test_tls_cert_store_unchanged_before_hashes[2];
static size_t test_tls_cert_store_unchanged_before_hashes_idx;
static word32 test_tls_cert_store_unchanged_after_hashes[2];
static size_t test_tls_cert_store_unchanged_after_hashes_idx;

static int test_tls_cert_store_unchanged_ctx_ready(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;

    ExpectIntNE(test_tls_cert_store_unchanged_before_hashes
        [test_tls_cert_store_unchanged_before_hashes_idx++] =
            test_tls_cert_store_unchanged_HashCaTable(ctx->cm->caTable), 0);

    wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER |
            WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);

    return EXPECT_RESULT();
}

static int test_tls_cert_store_unchanged_ctx_cleanup(WOLFSSL_CTX* ctx)
{
    EXPECT_DECLS;
    ExpectIntEQ(wolfSSL_CTX_UnloadIntermediateCerts(ctx), WOLFSSL_SUCCESS);
    ExpectIntNE(test_tls_cert_store_unchanged_after_hashes
        [test_tls_cert_store_unchanged_after_hashes_idx++] =
            test_tls_cert_store_unchanged_HashCaTable(ctx->cm->caTable), 0);

    return EXPECT_RESULT();
}

static int test_tls_cert_store_unchanged_on_hs(WOLFSSL_CTX **ctx, WOLFSSL **ssl)
{
    EXPECT_DECLS;
    WOLFSSL_CERT_MANAGER* cm;

    (void)ssl;
    /* WARNING: this approach bypasses the reference counter check in
     * wolfSSL_CTX_UnloadIntermediateCerts. It is not recommended as it may
     * cause unexpected behaviour when other active connections try accessing
     * the caTable. */
    ExpectNotNull(cm = wolfSSL_CTX_GetCertManager(*ctx));
    ExpectIntEQ(wolfSSL_CertManagerUnloadIntermediateCerts(cm),
            WOLFSSL_SUCCESS);
    ExpectIntNE(test_tls_cert_store_unchanged_after_hashes
        [test_tls_cert_store_unchanged_after_hashes_idx++] =
            test_tls_cert_store_unchanged_HashCaTable((*ctx)->cm->caTable), 0);

    return EXPECT_RESULT();
}

static int test_tls_cert_store_unchanged_ssl_ready(WOLFSSL* ssl)
{
    EXPECT_DECLS;
    WOLFSSL_CTX* ctx;

    ExpectNotNull(ctx = wolfSSL_get_SSL_CTX(ssl));

    return EXPECT_RESULT();
}
#endif

static int test_tls_cert_store_unchanged(void)
{
    EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    test_ssl_cbf client_cbf;
    test_ssl_cbf server_cbf;
    int i;

    for (i = 0; i < 2; i++) {
        XMEMSET(&client_cbf, 0, sizeof(client_cbf));
        XMEMSET(&server_cbf, 0, sizeof(server_cbf));

        test_tls_cert_store_unchanged_before_hashes_idx = 0;
        XMEMSET(test_tls_cert_store_unchanged_before_hashes, 0,
                sizeof(test_tls_cert_store_unchanged_before_hashes));
        test_tls_cert_store_unchanged_after_hashes_idx = 0;
        XMEMSET(test_tls_cert_store_unchanged_after_hashes, 0,
                sizeof(test_tls_cert_store_unchanged_after_hashes));

        client_cbf.ctx_ready = test_tls_cert_store_unchanged_ctx_ready;
        server_cbf.ctx_ready = test_tls_cert_store_unchanged_ctx_ready;

        client_cbf.ssl_ready = test_tls_cert_store_unchanged_ssl_ready;
        server_cbf.ssl_ready = test_tls_cert_store_unchanged_ssl_ready;

        switch (i) {
            case 0:
                client_cbf.on_ctx_cleanup =
                        test_tls_cert_store_unchanged_ctx_cleanup;
                server_cbf.on_ctx_cleanup =
                        test_tls_cert_store_unchanged_ctx_cleanup;
                break;
            case 1:
                client_cbf.on_handshake = test_tls_cert_store_unchanged_on_hs;
                server_cbf.on_handshake = test_tls_cert_store_unchanged_on_hs;
                break;
            default:
                Fail(("Should not enter here"), ("Entered here"));
        }


        client_cbf.certPemFile = "certs/intermediate/client-chain.pem";
        server_cbf.certPemFile = "certs/intermediate/server-chain.pem";

        server_cbf.caPemFile = caCertFile;

        ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
            &server_cbf, NULL), TEST_SUCCESS);

        ExpectBufEQ(test_tls_cert_store_unchanged_before_hashes,
                test_tls_cert_store_unchanged_after_hashes,
                sizeof(test_tls_cert_store_unchanged_after_hashes));
    }
#endif
    return EXPECT_RESULT();
}

static int test_wolfSSL_SendUserCanceled(void)
{
    EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
    size_t i;
    struct {
        method_provider client_meth;
        method_provider server_meth;
        const char* tls_version;
    } params[] = {
#if defined(WOLFSSL_TLS13)
/* With WOLFSSL_TLS13_MIDDLEBOX_COMPAT a short ID will result in an error */
        { wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" },
#ifdef WOLFSSL_DTLS13
        { wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" },
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
        { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" },
#ifdef WOLFSSL_DTLS
        { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" },
#endif
#endif
#if !defined(NO_OLD_TLS)
        { wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" },
#ifdef WOLFSSL_DTLS
        { wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" },
#endif
#endif
    };

    for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) {
        WOLFSSL_CTX *ctx_c = NULL;
        WOLFSSL_CTX *ctx_s = NULL;
        WOLFSSL *ssl_c = NULL;
        WOLFSSL *ssl_s = NULL;
        struct test_memio_ctx test_ctx;
        WOLFSSL_ALERT_HISTORY h;

        printf("Testing %s\n", params[i].tls_version);

        XMEMSET(&h, 0, sizeof(h));
        XMEMSET(&test_ctx, 0, sizeof(test_ctx));
        ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
                params[i].client_meth, params[i].server_meth), 0);

        /* CH1 */
        ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);

        ExpectIntEQ(wolfSSL_SendUserCanceled(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);

        /* Alert closed connection */
        ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
        ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_ZERO_RETURN);

        /* Last alert will be close notify because user_canceled should be
         * followed by a close_notify */
        ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
        ExpectIntEQ(h.last_rx.code, close_notify);
        ExpectIntEQ(h.last_rx.level, alert_warning);

        wolfSSL_free(ssl_c);
        wolfSSL_free(ssl_s);
        wolfSSL_CTX_free(ctx_c);
        wolfSSL_CTX_free(ctx_s);
    }
#endif
    return EXPECT_RESULT();
}
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(HAVE_OCSP) && \
    defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
    !defined(WOLFSSL_NO_TLS12)
static int test_ocsp_callback_fails_cb(void* ctx, const char* url, int urlSz,
                        byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
{
    (void)ctx;
    (void)url;
    (void)urlSz;
    (void)ocspReqBuf;
    (void)ocspReqSz;
    (void)ocspRespBuf;
    return WOLFSSL_CBIO_ERR_GENERAL;
}
static int test_ocsp_callback_fails(void)
{
    WOLFSSL_CTX *ctx_c = NULL;
    WOLFSSL_CTX *ctx_s = NULL;
    WOLFSSL *ssl_c = NULL;
    WOLFSSL *ssl_s = NULL;
    struct test_memio_ctx test_ctx;
    EXPECT_DECLS;

    XMEMSET(&test_ctx, 0, sizeof(test_ctx));
    ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
            wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
    ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx_c), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx_s), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_UseOCSPStapling(ssl_c, WOLFSSL_CSR_OCSP,0), WOLFSSL_SUCCESS);
    /* override URL to avoid exing from SendCertificateStatus because of no AuthInfo on the certificate */
    ExpectIntEQ(wolfSSL_CTX_SetOCSP_OverrideURL(ctx_s, "http://dummy.test"), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx_s, WOLFSSL_OCSP_NO_NONCE    | WOLFSSL_OCSP_URL_OVERRIDE), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_s, caCertFile, 0), WOLFSSL_SUCCESS);
    ExpectIntEQ(wolfSSL_SetOCSP_Cb(ssl_s, test_ocsp_callback_fails_cb, NULL, NULL), WOLFSSL_SUCCESS);
    ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), -1);
    ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WC_NO_ERR_TRACE(OCSP_INVALID_STATUS));

    wolfSSL_free(ssl_c);
    wolfSSL_free(ssl_s);
    wolfSSL_CTX_free(ctx_c);
    wolfSSL_CTX_free(ctx_s);

    return EXPECT_RESULT();
}
#else
static int test_ocsp_callback_fails(void)
{
    return TEST_SKIPPED;
}
#endif /* defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
    defined(HAVE_OCSP) && \
    defined(HAVE_CERTIFICATE_STATUS_REQUEST) */


/*----------------------------------------------------------------------------*
 | Main
 *----------------------------------------------------------------------------*/

typedef int (*TEST_FUNC)(void);
typedef struct {
    const char *name;
    TEST_FUNC func;
    byte run:1;
    byte fail:1;
} TEST_CASE;

#define TEST_DECL(func) { #func, func, 0, 0 }

int testAll = 1;

TEST_CASE testCases[] = {
    TEST_DECL(test_fileAccess),

    /*********************************
     * wolfcrypt
     *********************************/

    TEST_DECL(test_ForceZero),

    TEST_DECL(test_wolfCrypt_Init),

    TEST_DECL(test_wc_LoadStaticMemory_ex),

    /* Locking with Compat Mutex */
    TEST_DECL(test_wc_SetMutexCb),
    TEST_DECL(test_wc_LockMutex_ex),

    /* Digests */
    TEST_DECL(test_wc_InitMd5),
    TEST_DECL(test_wc_Md5Update),
    TEST_DECL(test_wc_Md5Final),
    TEST_DECL(test_wc_InitSha),
    TEST_DECL(test_wc_ShaUpdate),
    TEST_DECL(test_wc_ShaFinal),
    TEST_DECL(test_wc_InitSha256),
    TEST_DECL(test_wc_Sha256Update),
    TEST_DECL(test_wc_Sha256Final),
    TEST_DECL(test_wc_Sha256FinalRaw),
    TEST_DECL(test_wc_Sha256GetFlags),
    TEST_DECL(test_wc_Sha256Free),
    TEST_DECL(test_wc_Sha256GetHash),
    TEST_DECL(test_wc_Sha256Copy),

    TEST_DECL(test_wc_InitSha224),
    TEST_DECL(test_wc_Sha224Update),
    TEST_DECL(test_wc_Sha224Final),
    TEST_DECL(test_wc_Sha224SetFlags),
    TEST_DECL(test_wc_Sha224GetFlags),
    TEST_DECL(test_wc_Sha224Free),
    TEST_DECL(test_wc_Sha224GetHash),
    TEST_DECL(test_wc_Sha224Copy),

    TEST_DECL(test_wc_InitSha512),
    TEST_DECL(test_wc_Sha512Update),
    TEST_DECL(test_wc_Sha512Final),
    TEST_DECL(test_wc_Sha512GetFlags),
    TEST_DECL(test_wc_Sha512FinalRaw),
    TEST_DECL(test_wc_Sha512Free),
    TEST_DECL(test_wc_Sha512GetHash),
    TEST_DECL(test_wc_Sha512Copy),

    TEST_DECL(test_wc_InitSha512_224),
    TEST_DECL(test_wc_Sha512_224Update),
    TEST_DECL(test_wc_Sha512_224Final),
    TEST_DECL(test_wc_Sha512_224GetFlags),
    TEST_DECL(test_wc_Sha512_224FinalRaw),
    TEST_DECL(test_wc_Sha512_224Free),
    TEST_DECL(test_wc_Sha512_224GetHash),
    TEST_DECL(test_wc_Sha512_224Copy),
    TEST_DECL(test_wc_InitSha512_256),
    TEST_DECL(test_wc_Sha512_256Update),
    TEST_DECL(test_wc_Sha512_256Final),
    TEST_DECL(test_wc_Sha512_256GetFlags),
    TEST_DECL(test_wc_Sha512_256FinalRaw),
    TEST_DECL(test_wc_Sha512_256Free),
    TEST_DECL(test_wc_Sha512_256GetHash),
    TEST_DECL(test_wc_Sha512_256Copy),

    TEST_DECL(test_wc_InitSha384),
    TEST_DECL(test_wc_Sha384Update),
    TEST_DECL(test_wc_Sha384Final),
    TEST_DECL(test_wc_Sha384GetFlags),
    TEST_DECL(test_wc_Sha384FinalRaw),
    TEST_DECL(test_wc_Sha384Free),
    TEST_DECL(test_wc_Sha384GetHash),
    TEST_DECL(test_wc_Sha384Copy),

    TEST_DECL(test_wc_InitBlake2b),
    TEST_DECL(test_wc_InitBlake2b_WithKey),
    TEST_DECL(test_wc_InitBlake2s_WithKey),
    TEST_DECL(test_wc_InitRipeMd),
    TEST_DECL(test_wc_RipeMdUpdate),
    TEST_DECL(test_wc_RipeMdFinal),

    TEST_DECL(test_wc_InitSha3),
    TEST_DECL(testing_wc_Sha3_Update),
    TEST_DECL(test_wc_Sha3_224_Final),
    TEST_DECL(test_wc_Sha3_256_Final),
    TEST_DECL(test_wc_Sha3_384_Final),
    TEST_DECL(test_wc_Sha3_512_Final),
    TEST_DECL(test_wc_Sha3_224_Copy),
    TEST_DECL(test_wc_Sha3_256_Copy),
    TEST_DECL(test_wc_Sha3_384_Copy),
    TEST_DECL(test_wc_Sha3_512_Copy),
    TEST_DECL(test_wc_Sha3_GetFlags),
    TEST_DECL(test_wc_InitShake256),
    TEST_DECL(testing_wc_Shake256_Update),
    TEST_DECL(test_wc_Shake256_Final),
    TEST_DECL(test_wc_Shake256_Copy),
    TEST_DECL(test_wc_Shake256Hash),

    /* SM3 Digest */
    TEST_DECL(test_wc_InitSm3Free),
    TEST_DECL(test_wc_Sm3UpdateFinal),
    TEST_DECL(test_wc_Sm3GetHash),
    TEST_DECL(test_wc_Sm3Copy),
    TEST_DECL(test_wc_Sm3FinalRaw),
    TEST_DECL(test_wc_Sm3GetSetFlags),
    TEST_DECL(test_wc_Sm3Hash),

    TEST_DECL(test_wc_HashInit),
    TEST_DECL(test_wc_HashSetFlags),
    TEST_DECL(test_wc_HashGetFlags),

    /* HMAC */
    TEST_DECL(test_wc_Md5HmacSetKey),
    TEST_DECL(test_wc_Md5HmacUpdate),
    TEST_DECL(test_wc_Md5HmacFinal),
    TEST_DECL(test_wc_ShaHmacSetKey),
    TEST_DECL(test_wc_ShaHmacUpdate),
    TEST_DECL(test_wc_ShaHmacFinal),
    TEST_DECL(test_wc_Sha224HmacSetKey),
    TEST_DECL(test_wc_Sha224HmacUpdate),
    TEST_DECL(test_wc_Sha224HmacFinal),
    TEST_DECL(test_wc_Sha256HmacSetKey),
    TEST_DECL(test_wc_Sha256HmacUpdate),
    TEST_DECL(test_wc_Sha256HmacFinal),
    TEST_DECL(test_wc_Sha384HmacSetKey),
    TEST_DECL(test_wc_Sha384HmacUpdate),
    TEST_DECL(test_wc_Sha384HmacFinal),

    /* CMAC */
    TEST_DECL(test_wc_InitCmac),
    TEST_DECL(test_wc_CmacUpdate),
    TEST_DECL(test_wc_CmacFinal),
    TEST_DECL(test_wc_AesCmacGenerate),

    /* Cipher */
    TEST_DECL(test_wc_AesGcmStream),

    TEST_DECL(test_wc_Des3_SetIV),
    TEST_DECL(test_wc_Des3_SetKey),
    TEST_DECL(test_wc_Des3_CbcEncryptDecrypt),
    TEST_DECL(test_wc_Des3_CbcEncryptDecryptWithKey),
    TEST_DECL(test_wc_Des3_EcbEncrypt),

    TEST_DECL(test_wc_Chacha_SetKey),
    TEST_DECL(test_wc_Chacha_Process),
    TEST_DECL(test_wc_ChaCha20Poly1305_aead),
    TEST_DECL(test_wc_Poly1305SetKey),

    TEST_DECL(test_wc_CamelliaSetKey),
    TEST_DECL(test_wc_CamelliaSetIV),
    TEST_DECL(test_wc_CamelliaEncryptDecryptDirect),
    TEST_DECL(test_wc_CamelliaCbcEncryptDecrypt),

    TEST_DECL(test_wc_Arc4SetKey),
    TEST_DECL(test_wc_Arc4Process),

    TEST_DECL(test_wc_Rc2SetKey),
    TEST_DECL(test_wc_Rc2SetIV),
    TEST_DECL(test_wc_Rc2EcbEncryptDecrypt),
    TEST_DECL(test_wc_Rc2CbcEncryptDecrypt),

    /* AES cipher and GMAC. */
    TEST_DECL(test_wc_AesSetKey),
    TEST_DECL(test_wc_AesSetIV),
    TEST_DECL(test_wc_AesCbcEncryptDecrypt),
    TEST_DECL(test_wc_AesCtrEncryptDecrypt),
    TEST_DECL(test_wc_AesGcmSetKey),
    TEST_DECL(test_wc_AesGcmEncryptDecrypt),
    TEST_DECL(test_wc_AesGcmMixedEncDecLongIV),
    TEST_DECL(test_wc_GmacSetKey),
    TEST_DECL(test_wc_GmacUpdate),
    TEST_DECL(test_wc_AesCcmSetKey),
    TEST_DECL(test_wc_AesCcmEncryptDecrypt),
#if defined(WOLFSSL_AES_EAX) && \
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
    TEST_DECL(test_wc_AesEaxVectors),
    TEST_DECL(test_wc_AesEaxEncryptAuth),
    TEST_DECL(test_wc_AesEaxDecryptAuth),
#endif /* WOLFSSL_AES_EAX */

    /* SM4 cipher */
    TEST_DECL(test_wc_Sm4),
    TEST_DECL(test_wc_Sm4Ecb),
    TEST_DECL(test_wc_Sm4Cbc),
    TEST_DECL(test_wc_Sm4Ctr),
    TEST_DECL(test_wc_Sm4Gcm),
    TEST_DECL(test_wc_Sm4Ccm),

    /* RNG tests */
#ifdef HAVE_HASHDRBG
#ifdef TEST_RESEED_INTERVAL
    TEST_DECL(test_wc_RNG_GenerateBlock_Reseed),
#endif
    TEST_DECL(test_wc_RNG_GenerateBlock),
#endif
    TEST_DECL(test_get_rand_digit),
    TEST_DECL(test_wc_InitRngNonce),
    TEST_DECL(test_wc_InitRngNonce_ex),

    /* MP API tests */
    TEST_DECL(test_get_digit_count),
    TEST_DECL(test_mp_cond_copy),
    TEST_DECL(test_mp_rand),
    TEST_DECL(test_get_digit),
    TEST_DECL(test_wc_export_int),

    /* RSA */
    TEST_DECL(test_wc_InitRsaKey),
    TEST_DECL(test_wc_RsaPrivateKeyDecode),
    TEST_DECL(test_wc_RsaPublicKeyDecode),
    TEST_DECL(test_wc_RsaPublicKeyDecodeRaw),
    TEST_DECL(test_wc_RsaPrivateKeyDecodeRaw),
    TEST_DECL(test_wc_MakeRsaKey),
    TEST_DECL(test_wc_CheckProbablePrime),
    TEST_DECL(test_wc_RsaPSS_Verify),
    TEST_DECL(test_wc_RsaPSS_VerifyCheck),
    TEST_DECL(test_wc_RsaPSS_VerifyCheckInline),
    TEST_DECL(test_wc_RsaKeyToDer),
    TEST_DECL(test_wc_RsaKeyToPublicDer),
    TEST_DECL(test_wc_RsaPublicEncryptDecrypt),
    TEST_DECL(test_wc_RsaPublicEncryptDecrypt_ex),
    TEST_DECL(test_wc_RsaEncryptSize),
    TEST_DECL(test_wc_RsaSSL_SignVerify),
    TEST_DECL(test_wc_RsaFlattenPublicKey),
    TEST_DECL(test_RsaDecryptBoundsCheck),

    /* DSA */
    TEST_DECL(test_wc_InitDsaKey),
    TEST_DECL(test_wc_DsaSignVerify),
    TEST_DECL(test_wc_DsaPublicPrivateKeyDecode),
    TEST_DECL(test_wc_MakeDsaKey),
    TEST_DECL(test_wc_DsaKeyToDer),
    TEST_DECL(test_wc_DsaKeyToPublicDer),
    TEST_DECL(test_wc_DsaImportParamsRaw),
    TEST_DECL(test_wc_DsaImportParamsRawCheck),
    TEST_DECL(test_wc_DsaExportParamsRaw),
    TEST_DECL(test_wc_DsaExportKeyRaw),

    /* DH */
    TEST_DECL(test_wc_DhPublicKeyDecode),

    /* wolfCrypt ECC tests */
    TEST_DECL(test_wc_ecc_get_curve_size_from_name),
    TEST_DECL(test_wc_ecc_get_curve_id_from_name),
    TEST_DECL(test_wc_ecc_get_curve_id_from_params),
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && \
    !defined(HAVE_SELFTEST) && \
    !(defined(HAVE_FIPS) || defined(HAVE_FIPS_VERSION))
    TEST_DECL(test_wc_ecc_get_curve_id_from_dp_params),
#endif
    TEST_DECL(test_wc_ecc_make_key),
    TEST_DECL(test_wc_ecc_init),
    TEST_DECL(test_wc_ecc_check_key),
    TEST_DECL(test_wc_ecc_get_generator),
    TEST_DECL(test_wc_ecc_size),
    TEST_DECL(test_wc_ecc_params),
    TEST_DECL(test_wc_ecc_signVerify_hash),
    TEST_DECL(test_wc_ecc_shared_secret),
    TEST_DECL(test_wc_ecc_export_x963),
    TEST_DECL(test_wc_ecc_export_x963_ex),
    TEST_DECL(test_wc_ecc_import_x963),
    TEST_DECL(test_wc_ecc_import_private_key),
    TEST_DECL(test_wc_ecc_export_private_only),
    TEST_DECL(test_wc_ecc_rs_to_sig),
    TEST_DECL(test_wc_ecc_import_raw),
    TEST_DECL(test_wc_ecc_import_unsigned),
    TEST_DECL(test_wc_ecc_sig_size),
    TEST_DECL(test_wc_ecc_ctx_new),
    TEST_DECL(test_wc_ecc_ctx_reset),
    TEST_DECL(test_wc_ecc_ctx_set_peer_salt),
    TEST_DECL(test_wc_ecc_ctx_set_info),
    TEST_DECL(test_wc_ecc_encryptDecrypt),
    TEST_DECL(test_wc_ecc_del_point),
    TEST_DECL(test_wc_ecc_pointFns),
    TEST_DECL(test_wc_ecc_shared_secret_ssh),
    TEST_DECL(test_wc_ecc_verify_hash_ex),
    TEST_DECL(test_wc_ecc_mulmod),
    TEST_DECL(test_wc_ecc_is_valid_idx),
    TEST_DECL(test_wc_ecc_get_curve_id_from_oid),
    TEST_DECL(test_wc_ecc_sig_size_calc),
    TEST_DECL(test_wc_EccPrivateKeyToDer),

    /* SM2 elliptic curve */
    TEST_DECL(test_wc_ecc_sm2_make_key),
    TEST_DECL(test_wc_ecc_sm2_shared_secret),
    TEST_DECL(test_wc_ecc_sm2_create_digest),
    TEST_DECL(test_wc_ecc_sm2_verify_hash_ex),
    TEST_DECL(test_wc_ecc_sm2_verify_hash),
    TEST_DECL(test_wc_ecc_sm2_sign_hash_ex),
    TEST_DECL(test_wc_ecc_sm2_sign_hash),

    /* Curve25519 */
    TEST_DECL(test_wc_curve25519_init),
    TEST_DECL(test_wc_curve25519_size),
    TEST_DECL(test_wc_curve25519_export_key_raw),
    TEST_DECL(test_wc_curve25519_export_key_raw_ex),
    TEST_DECL(test_wc_curve25519_make_key),
    TEST_DECL(test_wc_curve25519_shared_secret_ex),
    TEST_DECL(test_wc_curve25519_make_pub),
    TEST_DECL(test_wc_curve25519_export_public_ex),
    TEST_DECL(test_wc_curve25519_export_private_raw_ex),
    TEST_DECL(test_wc_curve25519_import_private_raw_ex),
    TEST_DECL(test_wc_curve25519_import_private),

    /* ED25519 */
    TEST_DECL(test_wc_ed25519_make_key),
    TEST_DECL(test_wc_ed25519_init),
    TEST_DECL(test_wc_ed25519_sign_msg),
    TEST_DECL(test_wc_ed25519_import_public),
    TEST_DECL(test_wc_ed25519_import_private_key),
    TEST_DECL(test_wc_ed25519_export),
    TEST_DECL(test_wc_ed25519_size),
    TEST_DECL(test_wc_ed25519_exportKey),
    TEST_DECL(test_wc_Ed25519PublicKeyToDer),
    TEST_DECL(test_wc_Ed25519KeyToDer),
    TEST_DECL(test_wc_Ed25519PrivateKeyToDer),

    /* Curve448 */
    TEST_DECL(test_wc_curve448_make_key),
    TEST_DECL(test_wc_curve448_shared_secret_ex),
    TEST_DECL(test_wc_curve448_export_public_ex),
    TEST_DECL(test_wc_curve448_export_private_raw_ex),
    TEST_DECL(test_wc_curve448_export_key_raw),
    TEST_DECL(test_wc_curve448_import_private_raw_ex),
    TEST_DECL(test_wc_curve448_import_private),
    TEST_DECL(test_wc_curve448_init),
    TEST_DECL(test_wc_curve448_size),

    /* Ed448 */
    TEST_DECL(test_wc_ed448_make_key),
    TEST_DECL(test_wc_ed448_init),
    TEST_DECL(test_wc_ed448_sign_msg),
    TEST_DECL(test_wc_ed448_import_public),
    TEST_DECL(test_wc_ed448_import_private_key),
    TEST_DECL(test_wc_ed448_export),
    TEST_DECL(test_wc_ed448_size),
    TEST_DECL(test_wc_ed448_exportKey),
    TEST_DECL(test_wc_Ed448PublicKeyToDer),
    TEST_DECL(test_wc_Ed448KeyToDer),
    TEST_DECL(test_wc_Ed448PrivateKeyToDer),
    TEST_DECL(test_wc_Curve448PrivateKeyToDer),

    /* Kyber */
    TEST_DECL(test_wc_kyber_make_key_kats),
    TEST_DECL(test_wc_kyber_encapsulate_kats),
    TEST_DECL(test_wc_kyber_decapsulate_kats),

    /* Dilithium */
    TEST_DECL(test_wc_dilithium),
    TEST_DECL(test_wc_dilithium_make_key),
    TEST_DECL(test_wc_dilithium_sign),
    TEST_DECL(test_wc_dilithium_verify),
    TEST_DECL(test_wc_dilithium_sign_vfy),
    TEST_DECL(test_wc_dilithium_check_key),
    TEST_DECL(test_wc_dilithium_public_der_decode),
    TEST_DECL(test_wc_dilithium_der),
    TEST_DECL(test_wc_dilithium_make_key_from_seed),
    TEST_DECL(test_wc_dilithium_sig_kats),
    TEST_DECL(test_wc_dilithium_verify_kats),

    /* Signature API */
    TEST_DECL(test_wc_SignatureGetSize_ecc),
    TEST_DECL(test_wc_SignatureGetSize_rsa),

    /* PEM and DER APIs. */
    TEST_DECL(test_wc_PemToDer),
    TEST_DECL(test_wc_AllocDer),
    TEST_DECL(test_wc_CertPemToDer),
    TEST_DECL(test_wc_KeyPemToDer),
    TEST_DECL(test_wc_PubKeyPemToDer),
    TEST_DECL(test_wc_PemPubKeyToDer),
    TEST_DECL(test_wc_GetPubKeyDerFromCert),
    TEST_DECL(test_wc_CheckCertSigPubKey),

    /* wolfCrypt ASN tests */
    TEST_DECL(test_ToTraditional),
    TEST_DECL(test_wc_CreateEncryptedPKCS8Key),
    TEST_DECL(test_wc_GetPkcs8TraditionalOffset),

    /* Certificate */
    TEST_DECL(test_wc_SetSubjectRaw),
    TEST_DECL(test_wc_GetSubjectRaw),
    TEST_DECL(test_wc_SetIssuerRaw),
    TEST_DECL(test_wc_SetIssueBuffer),
    TEST_DECL(test_wc_SetSubjectKeyId),
    TEST_DECL(test_wc_SetSubject),
    TEST_DECL(test_CheckCertSignature),
    TEST_DECL(test_wc_ParseCert),
    TEST_DECL(test_wc_ParseCert_Error),
    TEST_DECL(test_MakeCertWithPathLen),
    TEST_DECL(test_MakeCertWith0Ser),
    TEST_DECL(test_MakeCertWithCaFalse),
    TEST_DECL(test_wc_SetKeyUsage),
    TEST_DECL(test_wc_SetAuthKeyIdFromPublicKey_ex),
    TEST_DECL(test_wc_SetSubjectBuffer),
    TEST_DECL(test_wc_SetSubjectKeyIdFromPublicKey_ex),

    /* wolfcrypt PKCS#7 */
    TEST_DECL(test_wc_PKCS7_New),
    TEST_DECL(test_wc_PKCS7_Init),
    TEST_DECL(test_wc_PKCS7_InitWithCert),
    TEST_DECL(test_wc_PKCS7_EncodeData),
    TEST_DECL(test_wc_PKCS7_EncodeSignedData),
    TEST_DECL(test_wc_PKCS7_EncodeSignedData_ex),
    TEST_DECL(test_wc_PKCS7_VerifySignedData_RSA),
    TEST_DECL(test_wc_PKCS7_VerifySignedData_ECC),
    TEST_DECL(test_wc_PKCS7_EncodeDecodeEnvelopedData),
    TEST_DECL(test_wc_PKCS7_EncodeEncryptedData),
    TEST_DECL(test_wc_PKCS7_Degenerate),
    TEST_DECL(test_wc_PKCS7_BER),
    TEST_DECL(test_wc_PKCS7_signed_enveloped),
    TEST_DECL(test_wc_PKCS7_NoDefaultSignedAttribs),
    TEST_DECL(test_wc_PKCS7_SetOriEncryptCtx),
    TEST_DECL(test_wc_PKCS7_SetOriDecryptCtx),
    TEST_DECL(test_wc_PKCS7_DecodeCompressedData),

    /* wolfCrypt PKCS#12 */
    TEST_DECL(test_wc_i2d_PKCS12),

    /*
     * test_wolfCrypt_Cleanup needs to come after the above wolfCrypt tests to
     * avoid memory leaks.
     */
    TEST_DECL(test_wolfCrypt_Cleanup),

    TEST_DECL(test_wolfSSL_Init),

    TEST_DECL(test_dual_alg_support),

    /*********************************
     * OpenSSL compatibility API tests
     *********************************/

    /* If at some point a stub get implemented this test should fail indicating
     * a need to implement a new test case
     */
    TEST_DECL(test_stubs_are_stubs),

    /* ASN.1 compatibility API tests */
    TEST_DECL(test_wolfSSL_ASN1_BIT_STRING),
    TEST_DECL(test_wolfSSL_ASN1_INTEGER),
    TEST_DECL(test_wolfSSL_ASN1_INTEGER_cmp),
    TEST_DECL(test_wolfSSL_ASN1_INTEGER_BN),
    TEST_DECL(test_wolfSSL_ASN1_INTEGER_get_set),
    TEST_DECL(test_wolfSSL_d2i_ASN1_INTEGER),
    TEST_DECL(test_wolfSSL_a2i_ASN1_INTEGER),
    TEST_DECL(test_wolfSSL_i2c_ASN1_INTEGER),
    TEST_DECL(test_wolfSSL_ASN1_OBJECT),
    TEST_DECL(test_wolfSSL_ASN1_get_object),
    TEST_DECL(test_wolfSSL_i2a_ASN1_OBJECT),
    TEST_DECL(test_wolfSSL_i2t_ASN1_OBJECT),
    TEST_DECL(test_wolfSSL_sk_ASN1_OBJECT),
    TEST_DECL(test_wolfSSL_ASN1_STRING),
    TEST_DECL(test_wolfSSL_ASN1_STRING_to_UTF8),
    TEST_DECL(test_wolfSSL_i2s_ASN1_STRING),
    TEST_DECL(test_wolfSSL_ASN1_STRING_canon),
    TEST_DECL(test_wolfSSL_ASN1_STRING_print),
    TEST_DECL(test_wolfSSL_ASN1_STRING_print_ex),
    TEST_DECL(test_wolfSSL_ASN1_UNIVERSALSTRING_to_string),
    TEST_DECL(test_wolfSSL_ASN1_GENERALIZEDTIME_free),
    TEST_DECL(test_wolfSSL_ASN1_GENERALIZEDTIME_print),
    TEST_DECL(test_wolfSSL_ASN1_TIME),
    TEST_DECL(test_wolfSSL_ASN1_TIME_to_string),
    TEST_DECL(test_wolfSSL_ASN1_TIME_diff_compare),
    TEST_DECL(test_wolfSSL_ASN1_TIME_adj),
    TEST_DECL(test_wolfSSL_ASN1_TIME_to_tm),
    TEST_DECL(test_wolfSSL_ASN1_TIME_to_generalizedtime),
    TEST_DECL(test_wolfSSL_ASN1_TIME_print),
    TEST_DECL(test_wolfSSL_ASN1_UTCTIME_print),
    TEST_DECL(test_wolfSSL_ASN1_TYPE),
    TEST_DECL(test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS),
    TEST_DECL(test_wolfSSL_i2d_ASN1_TYPE),
    TEST_DECL(test_wolfSSL_i2d_ASN1_SEQUENCE),
    TEST_DECL(test_ASN1_strings),

    TEST_DECL(test_wolfSSL_lhash),

    TEST_DECL(test_wolfSSL_certs),

    TEST_DECL(test_wolfSSL_private_keys),
    TEST_DECL(test_wolfSSL_PEM_def_callback),
    TEST_DECL(test_wolfSSL_PEM_read_PrivateKey),
    TEST_DECL(test_wolfSSL_PEM_read_RSA_PUBKEY),
    TEST_DECL(test_wolfSSL_PEM_read_PUBKEY),
    TEST_DECL(test_wolfSSL_PEM_PrivateKey_rsa),
    TEST_DECL(test_wolfSSL_PEM_PrivateKey_ecc),
    TEST_DECL(test_wolfSSL_PEM_PrivateKey_dsa),
    TEST_DECL(test_wolfSSL_PEM_PrivateKey_dh),
    TEST_DECL(test_wolfSSL_PEM_PrivateKey),
    TEST_DECL(test_wolfSSL_PEM_file_RSAKey),
    TEST_DECL(test_wolfSSL_PEM_file_RSAPrivateKey),
#ifndef NO_BIO
    TEST_DECL(test_wolfSSL_BIO),
    TEST_DECL(test_wolfSSL_BIO_BIO_ring_read),
    TEST_DECL(test_wolfSSL_PEM_read_bio),
    TEST_DECL(test_wolfSSL_PEM_bio_RSAKey),
    TEST_DECL(test_wolfSSL_PEM_bio_DSAKey),
    TEST_DECL(test_wolfSSL_PEM_bio_ECKey),
    TEST_DECL(test_wolfSSL_PEM_bio_RSAPrivateKey),
    TEST_DECL(test_wolfSSL_PEM_PUBKEY),
#endif

    /* EVP API testing */
    TEST_DECL(test_wolfSSL_EVP_ENCODE_CTX_new),
    TEST_DECL(test_wolfSSL_EVP_ENCODE_CTX_free),
    TEST_DECL(test_wolfSSL_EVP_EncodeInit),
    TEST_DECL(test_wolfSSL_EVP_EncodeUpdate),
    TEST_DECL(test_wolfSSL_EVP_EncodeFinal),
    TEST_DECL(test_wolfSSL_EVP_DecodeInit),
    TEST_DECL(test_wolfSSL_EVP_DecodeUpdate),
    TEST_DECL(test_wolfSSL_EVP_DecodeFinal),

    TEST_DECL(test_wolfSSL_EVP_shake128),
    TEST_DECL(test_wolfSSL_EVP_shake256),
    TEST_DECL(test_wolfSSL_EVP_sm3),
    TEST_DECL(test_EVP_blake2),
#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_EVP_md4),
    TEST_DECL(test_wolfSSL_EVP_ripemd160),
    TEST_DECL(test_wolfSSL_EVP_get_digestbynid),
    TEST_DECL(test_wolfSSL_EVP_MD_nid),

    TEST_DECL(test_wolfSSL_EVP_DigestFinal_ex),
#endif

    TEST_DECL(test_EVP_MD_do_all),
    TEST_DECL(test_wolfSSL_EVP_MD_size),
    TEST_DECL(test_wolfSSL_EVP_MD_pkey_type),
    TEST_DECL(test_wolfSSL_EVP_Digest),
    TEST_DECL(test_wolfSSL_EVP_Digest_all),
    TEST_DECL(test_wolfSSL_EVP_MD_hmac_signing),
    TEST_DECL(test_wolfSSL_EVP_MD_rsa_signing),
    TEST_DECL(test_wolfSSL_EVP_MD_ecc_signing),

    TEST_DECL(test_wolfssl_EVP_aes_gcm),
    TEST_DECL(test_wolfssl_EVP_aes_gcm_AAD_2_parts),
    TEST_DECL(test_wolfssl_EVP_aes_gcm_zeroLen),
    TEST_DECL(test_wolfssl_EVP_aes_ccm),
    TEST_DECL(test_wolfssl_EVP_aes_ccm_zeroLen),
    TEST_DECL(test_wolfssl_EVP_chacha20),
    TEST_DECL(test_wolfssl_EVP_chacha20_poly1305),
    TEST_DECL(test_wolfssl_EVP_sm4_ecb),
    TEST_DECL(test_wolfssl_EVP_sm4_cbc),
    TEST_DECL(test_wolfssl_EVP_sm4_ctr),
    TEST_DECL(test_wolfssl_EVP_sm4_gcm_zeroLen),
    TEST_DECL(test_wolfssl_EVP_sm4_gcm),
    TEST_DECL(test_wolfssl_EVP_sm4_ccm_zeroLen),
    TEST_DECL(test_wolfssl_EVP_sm4_ccm),
#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_EVP_aes_256_gcm),
    TEST_DECL(test_wolfSSL_EVP_aes_192_gcm),
    TEST_DECL(test_wolfSSL_EVP_aes_256_ccm),
    TEST_DECL(test_wolfSSL_EVP_aes_192_ccm),
    TEST_DECL(test_wolfSSL_EVP_aes_128_ccm),
    TEST_DECL(test_wolfSSL_EVP_rc4),
    TEST_DECL(test_wolfSSL_EVP_enc_null),
    TEST_DECL(test_wolfSSL_EVP_rc2_cbc),
    TEST_DECL(test_wolfSSL_EVP_mdc2),

    TEST_DECL(test_evp_cipher_aes_gcm),
#endif
    TEST_DECL(test_wolfssl_EVP_aria_gcm),
    TEST_DECL(test_wolfSSL_EVP_Cipher_extra),
#ifdef OPENSSL_EXTRA
    TEST_DECL(test_wolfSSL_EVP_get_cipherbynid),
    TEST_DECL(test_wolfSSL_EVP_CIPHER_CTX),
#endif
#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_EVP_CIPHER_CTX_iv_length),
    TEST_DECL(test_wolfSSL_EVP_CIPHER_CTX_key_length),
    TEST_DECL(test_wolfSSL_EVP_CIPHER_CTX_set_iv),
    TEST_DECL(test_wolfSSL_EVP_CIPHER_block_size),
    TEST_DECL(test_wolfSSL_EVP_CIPHER_iv_length),
    TEST_DECL(test_wolfSSL_EVP_X_STATE),
    TEST_DECL(test_wolfSSL_EVP_X_STATE_LEN),
    TEST_DECL(test_wolfSSL_EVP_BytesToKey),
#endif

    TEST_DECL(test_wolfSSL_EVP_PKEY_print_public),
    TEST_DECL(test_wolfSSL_EVP_PKEY_new_mac_key),
    TEST_DECL(test_wolfSSL_EVP_PKEY_new_CMAC_key),
    TEST_DECL(test_wolfSSL_EVP_PKEY_up_ref),
    TEST_DECL(test_wolfSSL_EVP_PKEY_hkdf),
    TEST_DECL(test_wolfSSL_EVP_PKEY_derive),
    TEST_DECL(test_wolfSSL_d2i_and_i2d_PublicKey),
    TEST_DECL(test_wolfSSL_d2i_and_i2d_PublicKey_ecc),
#ifndef NO_BIO
    TEST_DECL(test_wolfSSL_d2i_PUBKEY),
#endif
    TEST_DECL(test_wolfSSL_d2i_and_i2d_DSAparams),
    TEST_DECL(test_wolfSSL_i2d_PrivateKey),
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA)
#ifndef NO_BIO
    TEST_DECL(test_wolfSSL_d2i_PrivateKeys_bio),
#endif /* !NO_BIO */
#endif
#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_EVP_PKEY_set1_get1_DSA),
    TEST_DECL(test_wolfSSL_EVP_PKEY_set1_get1_EC_KEY),
    TEST_DECL(test_wolfSSL_EVP_PKEY_set1_get1_DH),
    TEST_DECL(test_wolfSSL_EVP_PKEY_assign),
    TEST_DECL(test_wolfSSL_EVP_PKEY_assign_DH),
    TEST_DECL(test_wolfSSL_EVP_PKEY_base_id),
    TEST_DECL(test_wolfSSL_EVP_PKEY_id),
    TEST_DECL(test_wolfSSL_EVP_PKEY_paramgen),
    TEST_DECL(test_wolfSSL_EVP_PKEY_keygen),
    TEST_DECL(test_wolfSSL_EVP_PKEY_keygen_init),
    TEST_DECL(test_wolfSSL_EVP_PKEY_missing_parameters),
    TEST_DECL(test_wolfSSL_EVP_PKEY_copy_parameters),
    TEST_DECL(test_wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits),
    TEST_DECL(test_wolfSSL_EVP_PKEY_CTX_new_id),
    TEST_DECL(test_wolfSSL_EVP_PKEY_get0_EC_KEY),
#endif

    TEST_DECL(test_EVP_PKEY_rsa),
    TEST_DECL(test_EVP_PKEY_ec),
    TEST_DECL(test_wolfSSL_EVP_PKEY_encrypt),
    TEST_DECL(test_wolfSSL_EVP_PKEY_sign_verify_rsa),
    TEST_DECL(test_wolfSSL_EVP_PKEY_sign_verify_dsa),
    TEST_DECL(test_wolfSSL_EVP_PKEY_sign_verify_ec),
    TEST_DECL(test_EVP_PKEY_cmp),

#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_EVP_SignInit_ex),
    TEST_DECL(test_wolfSSL_EVP_PKEY_param_check),
    TEST_DECL(test_wolfSSL_QT_EVP_PKEY_CTX_free),
#endif

    TEST_DECL(test_wolfSSL_EVP_PBE_scrypt),

    TEST_DECL(test_wolfSSL_CTX_add_extra_chain_cert),
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
    TEST_DECL(test_wolfSSL_ERR_peek_last_error_line),
#endif
#ifndef NO_BIO
    TEST_DECL(test_wolfSSL_ERR_print_errors_cb),
    TEST_DECL(test_wolfSSL_GetLoggingCb),
    TEST_DECL(test_WOLFSSL_ERROR_MSG),
    TEST_DECL(test_wc_ERR_remove_state),
    TEST_DECL(test_wc_ERR_print_errors_fp),
#endif
    TEST_DECL(test_wolfSSL_configure_args),
    TEST_DECL(test_wolfSSL_sk_SSL_CIPHER),
    TEST_DECL(test_wolfSSL_set1_curves_list),
    TEST_DECL(test_wolfSSL_curves_mismatch),
    TEST_DECL(test_wolfSSL_set1_sigalgs_list),

    TEST_DECL(test_wolfSSL_OtherName),
    TEST_DECL(test_wolfSSL_FPKI),
    TEST_DECL(test_wolfSSL_URI),
    TEST_DECL(test_wolfSSL_TBS),

    TEST_DECL(test_wolfSSL_X509_STORE_CTX),
    TEST_DECL(test_wolfSSL_X509_STORE_CTX_ex),
    TEST_DECL(test_X509_STORE_untrusted),
    TEST_DECL(test_wolfSSL_X509_STORE_CTX_trusted_stack_cleanup),
    TEST_DECL(test_wolfSSL_X509_STORE_CTX_get_issuer),
    TEST_DECL(test_wolfSSL_X509_STORE_set_flags),
    TEST_DECL(test_wolfSSL_X509_LOOKUP_load_file),
    TEST_DECL(test_wolfSSL_X509_Name_canon),
    TEST_DECL(test_wolfSSL_X509_LOOKUP_ctrl_file),
    TEST_DECL(test_wolfSSL_X509_LOOKUP_ctrl_hash_dir),
    TEST_DECL(test_wolfSSL_X509_NID),
    TEST_DECL(test_wolfSSL_X509_STORE_CTX_set_time),
    TEST_DECL(test_wolfSSL_get0_param),
    TEST_DECL(test_wolfSSL_X509_VERIFY_PARAM_set1_host),
    TEST_DECL(test_wolfSSL_set1_host),
    TEST_DECL(test_wolfSSL_X509_VERIFY_PARAM_set1_ip),
    TEST_DECL(test_wolfSSL_X509_STORE_CTX_get0_store),
    TEST_DECL(test_wolfSSL_X509_STORE),
    TEST_DECL(test_wolfSSL_X509_STORE_load_locations),
    TEST_DECL(test_X509_STORE_get0_objects),
    TEST_DECL(test_wolfSSL_X509_load_crl_file),
    TEST_DECL(test_wolfSSL_X509_STORE_get1_certs),
    TEST_DECL(test_wolfSSL_X509_STORE_set_get_crl),
    TEST_DECL(test_wolfSSL_X509_NAME_ENTRY_get_object),
    TEST_DECL(test_wolfSSL_X509_cmp_time),
    TEST_DECL(test_wolfSSL_X509_time_adj),

    /* X509 tests */
    TEST_DECL(test_wolfSSL_X509_subject_name_hash),
    TEST_DECL(test_wolfSSL_X509_issuer_name_hash),
    TEST_DECL(test_wolfSSL_X509_check_host),
    TEST_DECL(test_wolfSSL_X509_check_email),
    TEST_DECL(test_wolfSSL_X509_check_private_key),
    TEST_DECL(test_wolfSSL_X509),
    TEST_DECL(test_wolfSSL_X509_VERIFY_PARAM),
    TEST_DECL(test_wolfSSL_X509_sign),
    TEST_DECL(test_wolfSSL_X509_sign2),
    TEST_DECL(test_wolfSSL_X509_verify),
    TEST_DECL(test_wolfSSL_X509_get0_tbs_sigalg),
    TEST_DECL(test_wolfSSL_X509_ALGOR_get0),
    TEST_DECL(test_wolfSSL_X509_get_X509_PUBKEY),
    TEST_DECL(test_wolfSSL_X509_PUBKEY_RSA),
    TEST_DECL(test_wolfSSL_X509_PUBKEY_EC),
    TEST_DECL(test_wolfSSL_X509_PUBKEY_DSA),
    TEST_DECL(test_wolfSSL_PEM_write_bio_X509),
    TEST_DECL(test_wolfSSL_X509_NAME_get_entry),
    TEST_DECL(test_wolfSSL_X509_NAME),
    TEST_DECL(test_wolfSSL_X509_NAME_hash),
    TEST_DECL(test_wolfSSL_X509_NAME_print_ex),
    TEST_DECL(test_wolfSSL_X509_NAME_ENTRY),
    TEST_DECL(test_wolfSSL_X509_set_name),
    TEST_DECL(test_wolfSSL_X509_set_notAfter),
    TEST_DECL(test_wolfSSL_X509_set_notBefore),
    TEST_DECL(test_wolfSSL_X509_set_version),
    TEST_DECL(test_wolfSSL_X509_get_serialNumber),
    TEST_DECL(test_wolfSSL_X509_CRL),
    TEST_DECL(test_wolfSSL_i2d_X509),
    TEST_DECL(test_wolfSSL_d2i_X509_REQ),
    TEST_DECL(test_wolfSSL_PEM_read_X509),
    TEST_DECL(test_wolfSSL_X509_check_ca),
    TEST_DECL(test_wolfSSL_X509_check_ip_asc),
    TEST_DECL(test_wolfSSL_X509_bad_altname),
    TEST_DECL(test_wolfSSL_X509_name_match),
    TEST_DECL(test_wolfSSL_X509_name_match2),
    TEST_DECL(test_wolfSSL_X509_name_match3),
    TEST_DECL(test_wolfSSL_X509_max_altnames),
    TEST_DECL(test_wolfSSL_X509_max_name_constraints),
    TEST_DECL(test_wolfSSL_make_cert),

    /* X509 ACERT tests */
    TEST_DECL(test_wolfSSL_X509_ACERT_verify),
    TEST_DECL(test_wolfSSL_X509_ACERT_misc_api),
    TEST_DECL(test_wolfSSL_X509_ACERT_buffer),
    TEST_DECL(test_wolfSSL_X509_ACERT_asn),

#ifndef NO_BIO
    TEST_DECL(test_wolfSSL_X509_INFO_multiple_info),
    TEST_DECL(test_wolfSSL_X509_INFO),
    TEST_DECL(test_wolfSSL_PEM_X509_INFO_read_bio),
#endif

#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_X509_PUBKEY_get),
#endif

    TEST_DECL(test_wolfSSL_X509_CA_num),
    TEST_DECL(test_x509_get_key_id),
    TEST_DECL(test_wolfSSL_X509_get_version),
#ifndef NO_BIO
    TEST_DECL(test_wolfSSL_X509_print),
    TEST_DECL(test_wolfSSL_X509_CRL_print),
#endif
    TEST_DECL(test_X509_get_signature_nid),
    /* X509 extension testing. */
    TEST_DECL(test_wolfSSL_X509_get_extension_flags),
    TEST_DECL(test_wolfSSL_X509_get_ext),
    TEST_DECL(test_wolfSSL_X509_get_ext_by_NID),
    TEST_DECL(test_wolfSSL_X509_get_ext_subj_alt_name),
    TEST_DECL(test_wolfSSL_X509_get_ext_count),
    TEST_DECL(test_wolfSSL_X509_EXTENSION_new),
    TEST_DECL(test_wolfSSL_X509_EXTENSION_get_object),
    TEST_DECL(test_wolfSSL_X509_EXTENSION_get_data),
    TEST_DECL(test_wolfSSL_X509_EXTENSION_get_critical),
    TEST_DECL(test_wolfSSL_X509V3_EXT_get),
    TEST_DECL(test_wolfSSL_X509V3_EXT_nconf),
    TEST_DECL(test_wolfSSL_X509V3_EXT),
    TEST_DECL(test_wolfSSL_X509V3_EXT_print),
    TEST_DECL(test_wolfSSL_X509_cmp),

    TEST_DECL(test_GENERAL_NAME_set0_othername),
    TEST_DECL(test_othername_and_SID_ext),
    TEST_DECL(test_wolfSSL_dup_CA_list),
    /* OpenSSL sk_X509 API test */
    TEST_DECL(test_sk_X509),
    /* OpenSSL sk_X509_CRL API test */
    TEST_DECL(test_sk_X509_CRL),

    /* OpenSSL X509 REQ API test */
    TEST_DECL(test_X509_REQ),

    /* OpenSSL compatibility outside SSL context w/ CRL lookup directory */
    TEST_DECL(test_X509_STORE_No_SSL_CTX),
    TEST_DECL(test_X509_LOOKUP_add_dir),

    /* RAND compatibility API */
    TEST_DECL(test_wolfSSL_RAND_set_rand_method),
    TEST_DECL(test_wolfSSL_RAND_bytes),
    TEST_DECL(test_wolfSSL_RAND),

    /* BN compatibility API */
    TEST_DECL(test_wolfSSL_BN_CTX),
    TEST_DECL(test_wolfSSL_BN),
    TEST_DECL(test_wolfSSL_BN_init),
    TEST_DECL(test_wolfSSL_BN_enc_dec),
    TEST_DECL(test_wolfSSL_BN_word),
    TEST_DECL(test_wolfSSL_BN_bits),
    TEST_DECL(test_wolfSSL_BN_shift),
    TEST_DECL(test_wolfSSL_BN_math),
    TEST_DECL(test_wolfSSL_BN_math_mod),
    TEST_DECL(test_wolfSSL_BN_math_other),
    TEST_DECL(test_wolfSSL_BN_rand),
    TEST_DECL(test_wolfSSL_BN_prime),

    /* OpenSSL PKCS5 API test */
    TEST_DECL(test_wolfSSL_PKCS5),

    /* OpenSSL PKCS8 API test */
    TEST_DECL(test_wolfSSL_PKCS8_Compat),
    TEST_DECL(test_wolfSSL_PKCS8_d2i),

    /* OpenSSL PKCS7 API test */
    TEST_DECL(test_wolfssl_PKCS7),
    TEST_DECL(test_wolfSSL_PKCS7_certs),
    TEST_DECL(test_wolfSSL_PKCS7_sign),
    TEST_DECL(test_wolfSSL_PKCS7_SIGNED_new),
#ifndef NO_BIO
    TEST_DECL(test_wolfSSL_PEM_write_bio_PKCS7),
#ifdef HAVE_SMIME
    TEST_DECL(test_wolfSSL_SMIME_read_PKCS7),
    TEST_DECL(test_wolfSSL_SMIME_write_PKCS7),
#endif /* HAVE_SMIME */
#endif /* !NO_BIO */

    /* OpenSSL PKCS12 API test */
    TEST_DECL(test_wolfSSL_PKCS12),

    /* Can't memory test as callbacks use Assert. */
    TEST_DECL(test_error_queue_per_thread),
    TEST_DECL(test_wolfSSL_ERR_put_error),
    TEST_DECL(test_wolfSSL_ERR_get_error_order),
#ifndef NO_BIO
    TEST_DECL(test_wolfSSL_ERR_print_errors),
#endif

    TEST_DECL(test_OBJ_NAME_do_all),
    TEST_DECL(test_wolfSSL_OBJ),
    TEST_DECL(test_wolfSSL_OBJ_cmp),
    TEST_DECL(test_wolfSSL_OBJ_txt2nid),
    TEST_DECL(test_wolfSSL_OBJ_txt2obj),
#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_OBJ_ln),
    TEST_DECL(test_wolfSSL_OBJ_sn),
#endif

#ifndef NO_BIO
    TEST_DECL(test_wolfSSL_BIO_gets),
    TEST_DECL(test_wolfSSL_BIO_puts),
    TEST_DECL(test_wolfSSL_BIO_dump),
    /* Can't memory test as server hangs. */
    TEST_DECL(test_wolfSSL_BIO_should_retry),
    TEST_DECL(test_wolfSSL_BIO_write),
    TEST_DECL(test_wolfSSL_BIO_printf),
    TEST_DECL(test_wolfSSL_BIO_f_md),
    TEST_DECL(test_wolfSSL_BIO_up_ref),
    TEST_DECL(test_wolfSSL_BIO_reset),
    TEST_DECL(test_wolfSSL_BIO_get_len),
#endif

    TEST_DECL(test_wolfSSL_check_domain),
    TEST_DECL(test_wolfSSL_cert_cb),
    TEST_DECL(test_wolfSSL_cert_cb_dyn_ciphers),
    TEST_DECL(test_wolfSSL_ciphersuite_auth),
    TEST_DECL(test_wolfSSL_sigalg_info),
    /* Can't memory test as tcp_connect aborts. */
    TEST_DECL(test_wolfSSL_SESSION),
    TEST_DECL(test_wolfSSL_SESSION_expire_downgrade),
    TEST_DECL(test_wolfSSL_CTX_sess_set_remove_cb),
    TEST_DECL(test_wolfSSL_ticket_keys),
    TEST_DECL(test_wolfSSL_sk_GENERAL_NAME),
    TEST_DECL(test_wolfSSL_GENERAL_NAME_print),
    TEST_DECL(test_wolfSSL_sk_DIST_POINT),
    TEST_DECL(test_wolfSSL_verify_mode),
    TEST_DECL(test_wolfSSL_verify_depth),
    TEST_DECL(test_wolfSSL_verify_result),
    TEST_DECL(test_wolfSSL_msg_callback),

    TEST_DECL(test_wolfSSL_OCSP_id_get0_info),
    TEST_DECL(test_wolfSSL_i2d_OCSP_CERTID),
    TEST_DECL(test_wolfSSL_d2i_OCSP_CERTID),
    TEST_DECL(test_wolfSSL_OCSP_id_cmp),
    TEST_DECL(test_wolfSSL_OCSP_SINGLERESP_get0_id),
    TEST_DECL(test_wolfSSL_OCSP_single_get0_status),
    TEST_DECL(test_wolfSSL_OCSP_resp_count),
    TEST_DECL(test_wolfSSL_OCSP_resp_get0),
    TEST_DECL(test_wolfSSL_OCSP_parse_url),
    TEST_DECL(test_wolfSSL_OCSP_REQ_CTX),

    TEST_DECL(test_wolfSSL_PEM_read),

    TEST_DECL(test_wolfSSL_OpenSSL_version),
    TEST_DECL(test_wolfSSL_OpenSSL_add_all_algorithms),
    TEST_DECL(test_wolfSSL_OPENSSL_hexstr2buf),

    TEST_DECL(test_CONF_modules_xxx),
#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_TXT_DB),
    TEST_DECL(test_wolfSSL_NCONF),
#endif

    TEST_DECL(test_wolfSSL_CRYPTO_memcmp),
    TEST_DECL(test_wolfSSL_CRYPTO_get_ex_new_index),
    TEST_DECL(test_wolfSSL_SESSION_get_ex_new_index),
    TEST_DECL(test_CRYPTO_set_dynlock_xxx),
    TEST_DECL(test_CRYPTO_THREADID_xxx),
    TEST_DECL(test_ENGINE_cleanup),
    /* test the no op functions for compatibility */
    TEST_DECL(test_no_op_functions),
    /* OpenSSL error API tests */
    TEST_DECL(test_ERR_load_crypto_strings),

#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_sk_CIPHER_description),
    TEST_DECL(test_wolfSSL_get_ciphers_compat),

    TEST_DECL(test_wolfSSL_CTX_ctrl),
#endif /* OPENSSL_ALL */
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA)
    TEST_DECL(test_wolfSSL_CTX_use_certificate_ASN1),
#endif /* (OPENSSL_ALL || WOLFSSL_ASIO) && !NO_RSA */

    /*********************************
     * Crypto API tests
     *********************************/

    TEST_DECL(test_wolfSSL_MD4),
    TEST_DECL(test_wolfSSL_MD5),
    TEST_DECL(test_wolfSSL_MD5_Transform),
    TEST_DECL(test_wolfSSL_SHA),
    TEST_DECL(test_wolfSSL_SHA_Transform),
    TEST_DECL(test_wolfSSL_SHA224),
    TEST_DECL(test_wolfSSL_SHA256),
    TEST_DECL(test_wolfSSL_SHA256_Transform),
    TEST_DECL(test_wolfSSL_SHA512_Transform),
    TEST_DECL(test_wolfSSL_SHA512_224_Transform),
    TEST_DECL(test_wolfSSL_SHA512_256_Transform),
    TEST_DECL(test_wolfSSL_HMAC_CTX),
    TEST_DECL(test_wolfSSL_HMAC),
    TEST_DECL(test_wolfSSL_CMAC),

    TEST_DECL(test_wolfSSL_DES),
    TEST_DECL(test_wolfSSL_DES_ncbc),
    TEST_DECL(test_wolfSSL_DES_ecb_encrypt),
    TEST_DECL(test_wolfSSL_DES_ede3_cbc_encrypt),
    TEST_DECL(test_wolfSSL_AES_encrypt),
    TEST_DECL(test_wolfSSL_AES_ecb_encrypt),
    TEST_DECL(test_wolfSSL_AES_cbc_encrypt),
    TEST_DECL(test_wolfSSL_AES_cfb128_encrypt),
    TEST_DECL(test_wolfSSL_CRYPTO_cts128),
    TEST_DECL(test_wolfSSL_RC4),

    TEST_DECL(test_wolfSSL_RSA),
    TEST_DECL(test_wolfSSL_RSA_DER),
    TEST_DECL(test_wolfSSL_RSA_print),
    TEST_DECL(test_wolfSSL_RSA_padding_add_PKCS1_PSS),
    TEST_DECL(test_wolfSSL_RSA_sign_sha3),
    TEST_DECL(test_wolfSSL_RSA_get0_key),
    TEST_DECL(test_wolfSSL_RSA_meth),
    TEST_DECL(test_wolfSSL_RSA_verify),
    TEST_DECL(test_wolfSSL_RSA_sign),
    TEST_DECL(test_wolfSSL_RSA_sign_ex),
    TEST_DECL(test_wolfSSL_RSA_public_decrypt),
    TEST_DECL(test_wolfSSL_RSA_private_encrypt),
    TEST_DECL(test_wolfSSL_RSA_public_encrypt),
    TEST_DECL(test_wolfSSL_RSA_private_decrypt),
    TEST_DECL(test_wolfSSL_RSA_GenAdd),
    TEST_DECL(test_wolfSSL_RSA_blinding_on),
    TEST_DECL(test_wolfSSL_RSA_ex_data),
    TEST_DECL(test_wolfSSL_RSA_LoadDer),
    TEST_DECL(test_wolfSSL_RSA_To_Der),
    TEST_DECL(test_wolfSSL_PEM_read_RSAPublicKey),
    TEST_DECL(test_wolfSSL_PEM_write_RSA_PUBKEY),
    TEST_DECL(test_wolfSSL_PEM_write_RSAPrivateKey),
    TEST_DECL(test_wolfSSL_PEM_write_mem_RSAPrivateKey),

    TEST_DECL(test_wolfSSL_DH),
    TEST_DECL(test_wolfSSL_DH_dup),
    TEST_DECL(test_wolfSSL_DH_check),
    TEST_DECL(test_wolfSSL_DH_prime),
    TEST_DECL(test_wolfSSL_DH_1536_prime),
    TEST_DECL(test_wolfSSL_DH_get_2048_256),
    TEST_DECL(test_wolfSSL_PEM_write_DHparams),
    TEST_DECL(test_wolfSSL_PEM_read_DHparams),
    TEST_DECL(test_wolfSSL_d2i_DHparams),
    TEST_DECL(test_wolfSSL_DH_LoadDer),
    TEST_DECL(test_wolfSSL_i2d_DHparams),

#if defined(HAVE_ECC) && !defined(OPENSSL_NO_PK)
    TEST_DECL(test_wolfSSL_EC_GROUP),
    TEST_DECL(test_wolfSSL_i2d_ECPKParameters),
    TEST_DECL(test_wolfSSL_PEM_read_bio_ECPKParameters),
    TEST_DECL(test_wolfSSL_EC_POINT),
    TEST_DECL(test_wolfSSL_SPAKE),
    TEST_DECL(test_wolfSSL_EC_KEY_generate),
    TEST_DECL(test_EC_i2d),
    TEST_DECL(test_wolfSSL_EC_curve),
    TEST_DECL(test_wolfSSL_EC_KEY_dup),
    TEST_DECL(test_wolfSSL_EC_KEY_set_group),
    TEST_DECL(test_wolfSSL_EC_KEY_set_conv_form),
    TEST_DECL(test_wolfSSL_EC_KEY_private_key),
    TEST_DECL(test_wolfSSL_EC_KEY_public_key),
    TEST_DECL(test_wolfSSL_EC_KEY_print_fp),
    TEST_DECL(test_wolfSSL_EC_get_builtin_curves),
    TEST_DECL(test_wolfSSL_ECDSA_SIG),
    TEST_DECL(test_ECDSA_size_sign),
    TEST_DECL(test_ECDH_compute_key),
#endif

#ifdef OPENSSL_EXTRA
    TEST_DECL(test_EC25519),
    TEST_DECL(test_ED25519),
    TEST_DECL(test_EC448),
    TEST_DECL(test_ED448),
#endif

    TEST_DECL(test_DSA_do_sign_verify),
#ifdef OPENSSL_ALL
    TEST_DECL(test_wolfSSL_DSA_generate_parameters),
    TEST_DECL(test_wolfSSL_DSA_SIG),
#endif

    TEST_DECL(test_openssl_generate_key_and_cert),

    TEST_DECL(test_wolfSSL_FIPS_mode),
    TEST_DECL(test_openssl_FIPS_drbg),

    /*********************************
     * CertManager API tests
     *********************************/

    TEST_DECL(test_wolfSSL_CertManagerAPI),
    TEST_DECL(test_wolfSSL_CertManagerLoadCABuffer),
    TEST_DECL(test_wolfSSL_CertManagerLoadCABuffer_ex),
    TEST_DECL(test_wolfSSL_CertManagerGetCerts),
    TEST_DECL(test_wolfSSL_CertManagerSetVerify),
    TEST_DECL(test_wolfSSL_CertManagerNameConstraint),
    TEST_DECL(test_wolfSSL_CertManagerNameConstraint2),
    TEST_DECL(test_wolfSSL_CertManagerNameConstraint3),
    TEST_DECL(test_wolfSSL_CertManagerNameConstraint4),
    TEST_DECL(test_wolfSSL_CertManagerNameConstraint5),
    TEST_DECL(test_wolfSSL_CertManagerCRL),
    TEST_DECL(test_wolfSSL_CertManagerCheckOCSPResponse),
    TEST_DECL(test_wolfSSL_CheckOCSPResponse),
#ifdef HAVE_CERT_CHAIN_VALIDATION
    TEST_DECL(test_various_pathlen_chains),
#endif

    /*********************************
     * SSL/TLS API tests
     *********************************/

    TEST_DECL(test_wolfSSL_Method_Allocators),
#ifndef NO_WOLFSSL_SERVER
    TEST_DECL(test_wolfSSL_CTX_new),
#endif
    TEST_DECL(test_server_wolfSSL_new),
    TEST_DECL(test_client_wolfSSL_new),
#if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
    (!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_FILESYSTEM)
    TEST_DECL(test_for_double_Free),
#endif
    TEST_DECL(test_wolfSSL_set_options),

#ifdef WOLFSSL_TLS13
    /* TLS v1.3 API tests */
    TEST_DECL(test_tls13_apis),
    TEST_DECL(test_tls13_cipher_suites),
#endif

    TEST_DECL(test_wolfSSL_tmp_dh),
    TEST_DECL(test_wolfSSL_ctrl),

#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
    TEST_DECL(test_wolfSSL_set_SSL_CTX),
#endif
    TEST_DECL(test_wolfSSL_CTX_get_min_proto_version),
    TEST_DECL(test_wolfSSL_security_level),
    TEST_DECL(test_wolfSSL_SSL_in_init),
    TEST_DECL(test_wolfSSL_CTX_set_timeout),
    TEST_DECL(test_wolfSSL_set_psk_use_session_callback),

    TEST_DECL(test_CONF_CTX_FILE),
    TEST_DECL(test_CONF_CTX_CMDLINE),

#if !defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
    !defined(WOLFSSL_NO_CLIENT_AUTH)) && !defined(NO_FILESYSTEM)
    /* Use the Cert Manager(CM) API to generate the error ASN_SIG_CONFIRM_E */
    /* Bad certificate signature tests */
    TEST_DECL(test_EccSigFailure_cm),
    TEST_DECL(test_RsaSigFailure_cm),
#endif /* NO_CERTS */

    /* PKCS8 testing */
    TEST_DECL(test_wolfSSL_no_password_cb),
    TEST_DECL(test_wolfSSL_PKCS8),
    TEST_DECL(test_wolfSSL_PKCS8_ED25519),
    TEST_DECL(test_wolfSSL_PKCS8_ED448),

#ifdef HAVE_IO_TESTS_DEPENDENCIES
    TEST_DECL(test_wolfSSL_get_finished),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_CTX_add_session),
    /* Large number of memory allocations. */
    TEST_DECL(test_wolfSSL_CTX_add_session_ext_tls13),
    /* Large number of memory allocations. */
    TEST_DECL(test_wolfSSL_CTX_add_session_ext_dtls13),
    /* Large number of memory allocations. */
    TEST_DECL(test_wolfSSL_CTX_add_session_ext_tls12),
    /* Large number of memory allocations. */
    TEST_DECL(test_wolfSSL_CTX_add_session_ext_dtls12),
    /* Large number of memory allocations. */
    TEST_DECL(test_wolfSSL_CTX_add_session_ext_tls11),
    /* Large number of memory allocations. */
    TEST_DECL(test_wolfSSL_CTX_add_session_ext_dtls1),
#endif
    TEST_DECL(test_SSL_CIPHER_get_xxx),
    TEST_DECL(test_wolfSSL_ERR_strings),
    TEST_DECL(test_wolfSSL_CTX_set_cipher_list_bytes),
    TEST_DECL(test_wolfSSL_CTX_use_certificate),
    TEST_DECL(test_wolfSSL_CTX_use_certificate_file),
    TEST_DECL(test_wolfSSL_CTX_use_certificate_buffer),
    TEST_DECL(test_wolfSSL_use_certificate_buffer),
    TEST_DECL(test_wolfSSL_CTX_use_PrivateKey_file),
    TEST_DECL(test_wolfSSL_CTX_use_RSAPrivateKey_file),
    TEST_DECL(test_wolfSSL_use_RSAPrivateKey_file),
    TEST_DECL(test_wolfSSL_CTX_use_PrivateKey),
    TEST_DECL(test_wolfSSL_CTX_load_verify_locations),
    /* Large number of memory allocations. */
    TEST_DECL(test_wolfSSL_CTX_load_system_CA_certs),

#ifdef HAVE_CERT_CHAIN_VALIDATION
    TEST_DECL(test_wolfSSL_CertRsaPss),
#endif
    TEST_DECL(test_wolfSSL_CTX_load_verify_locations_ex),
    TEST_DECL(test_wolfSSL_CTX_load_verify_buffer_ex),
    TEST_DECL(test_wolfSSL_CTX_load_verify_chain_buffer_format),
    TEST_DECL(test_wolfSSL_CTX_add1_chain_cert),
    TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_buffer_format),
    TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_file_format),
    TEST_DECL(test_wolfSSL_use_certificate_chain_file),
    TEST_DECL(test_wolfSSL_CTX_trust_peer_cert),
    TEST_DECL(test_wolfSSL_CTX_LoadCRL),
    TEST_DECL(test_multiple_crls_same_issuer),
    TEST_DECL(test_wolfSSL_CTX_SetTmpDH_file),
    TEST_DECL(test_wolfSSL_CTX_SetTmpDH_buffer),
    TEST_DECL(test_wolfSSL_CTX_SetMinMaxDhKey_Sz),
    TEST_DECL(test_wolfSSL_CTX_der_load_verify_locations),
    TEST_DECL(test_wolfSSL_CTX_enable_disable),
    TEST_DECL(test_wolfSSL_CTX_ticket_API),
    TEST_DECL(test_wolfSSL_SetTmpDH_file),
    TEST_DECL(test_wolfSSL_SetTmpDH_buffer),
    TEST_DECL(test_wolfSSL_SetMinMaxDhKey_Sz),
    TEST_DECL(test_SetTmpEC_DHE_Sz),
    TEST_DECL(test_wolfSSL_CTX_get0_privatekey),
#ifdef WOLFSSL_DTLS
    TEST_DECL(test_wolfSSL_DtlsUpdateWindow),
    TEST_DECL(test_wolfSSL_DTLS_fragment_buckets),
#endif
    TEST_DECL(test_wolfSSL_dtls_set_mtu),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_dtls_plaintext),
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES)
    TEST_DECL(test_wolfSSL_read_write),
    /* Can't memory test as server hangs if client fails before second connect.
     */
    TEST_DECL(test_wolfSSL_reuse_WOLFSSLobj),
    TEST_DECL(test_wolfSSL_CTX_verifyDepth_ServerClient_1),
    TEST_DECL(test_wolfSSL_CTX_verifyDepth_ServerClient_2),
    TEST_DECL(test_wolfSSL_CTX_verifyDepth_ServerClient_3),
    TEST_DECL(test_wolfSSL_CTX_set_cipher_list),
    /* Can't memory test as server hangs. */
    TEST_DECL(test_wolfSSL_dtls_export),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_tls_export),
#endif
    TEST_DECL(test_wolfSSL_dtls_export_peers),
    TEST_DECL(test_wolfSSL_SetMinVersion),
    TEST_DECL(test_wolfSSL_CTX_SetMinVersion),

    /* wolfSSL handshake APIs. */
    TEST_DECL(test_wolfSSL_CTX_get0_set1_param),
    TEST_DECL(test_wolfSSL_a2i_IPADDRESS),
    TEST_DECL(test_wolfSSL_BUF),
    TEST_DECL(test_wolfSSL_set_tlsext_status_type),
    /* Can't memory test as server hangs. */
    TEST_DECL(test_wolfSSL_CTX_set_client_CA_list),
    TEST_DECL(test_wolfSSL_CTX_add_client_CA),
    TEST_DECL(test_wolfSSL_CTX_set_srp_username),
    TEST_DECL(test_wolfSSL_CTX_set_srp_password),
    TEST_DECL(test_wolfSSL_CTX_set_keylog_callback),
    TEST_DECL(test_wolfSSL_CTX_get_keylog_callback),
    TEST_DECL(test_wolfSSL_Tls12_Key_Logging_test),
    /* Can't memory test as server hangs. */
    TEST_DECL(test_wolfSSL_Tls13_Key_Logging_test),
    TEST_DECL(test_wolfSSL_Tls13_postauth),
    TEST_DECL(test_wolfSSL_set_ecdh_auto),
    TEST_DECL(test_wolfSSL_CTX_set_ecdh_auto),
    TEST_DECL(test_wolfSSL_set_minmax_proto_version),
    TEST_DECL(test_wolfSSL_CTX_set_max_proto_version),
    TEST_DECL(test_wolfSSL_THREADID_hash),

    /* TLS extensions tests */
#ifdef HAVE_IO_TESTS_DEPENDENCIES
#ifdef HAVE_SNI
    TEST_DECL(test_wolfSSL_UseSNI_params),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_UseSNI_connection),
    TEST_DECL(test_wolfSSL_SNI_GetFromBuffer),
#endif /* HAVE_SNI */
#endif
    TEST_DECL(test_wolfSSL_UseTrustedCA),
    TEST_DECL(test_wolfSSL_UseMaxFragment),
    TEST_DECL(test_wolfSSL_UseTruncatedHMAC),
    TEST_DECL(test_wolfSSL_UseSupportedCurve),
#if defined(HAVE_ALPN) && defined(HAVE_IO_TESTS_DEPENDENCIES)
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_UseALPN_connection),
    TEST_DECL(test_wolfSSL_UseALPN_params),
#endif
#ifdef HAVE_ALPN_PROTOS_SUPPORT
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_set_alpn_protos),
#endif
    TEST_DECL(test_wolfSSL_DisableExtendedMasterSecret),
    TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
    TEST_DECL(test_wolfSSL_SCR_Reconnect),
    TEST_DECL(test_tls_ext_duplicate),
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
    defined(HAVE_IO_TESTS_DEPENDENCIES)
    TEST_DECL(test_wolfSSL_Tls13_ECH_params),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_Tls13_ECH),
#endif

    TEST_DECL(test_wolfSSL_X509_TLS_version_test_1),
    TEST_DECL(test_wolfSSL_X509_TLS_version_test_2),

    /* OCSP Stapling */
    TEST_DECL(test_wolfSSL_UseOCSPStapling),
    TEST_DECL(test_wolfSSL_UseOCSPStaplingV2),
    TEST_DECL(test_self_signed_stapling),
    TEST_DECL(test_ocsp_callback_fails),

    /* Multicast */
    TEST_DECL(test_wolfSSL_mcast),

    TEST_DECL(test_wolfSSL_read_detect_TCP_disconnect),

    TEST_DECL(test_wolfSSL_msgCb),
    TEST_DECL(test_wolfSSL_either_side),
    TEST_DECL(test_wolfSSL_DTLS_either_side),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_dtls_fragments),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_dtls_AEAD_limit),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_ignore_alert_before_cookie),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_dtls_bad_record),
    /* Uses Assert in handshake callback. */
    TEST_DECL(test_wolfSSL_dtls_stateless),
    TEST_DECL(test_generate_cookie),

#ifndef NO_BIO
    /* Can't memory test as server hangs. */
    TEST_DECL(test_wolfSSL_BIO_connect),
    /* Can't memory test as server Asserts in thread. */
    TEST_DECL(test_wolfSSL_BIO_accept),
    TEST_DECL(test_wolfSSL_BIO_tls),
    TEST_DECL(test_wolfSSL_BIO_datagram),
#endif

#if defined(HAVE_PK_CALLBACKS) && !defined(WOLFSSL_NO_TLS12)
    TEST_DECL(test_DhCallbacks),
#endif

#if defined(HAVE_KEYING_MATERIAL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
    TEST_DECL(test_export_keying_material),
#endif

    /* Can't memory test as client/server Asserts in thread. */
    TEST_DECL(test_ticket_and_psk_mixing),
    /* Can't memory test as client/server Asserts in thread. */
    TEST_DECL(test_prioritize_psk),

    /* Can't memory test as client/server hangs. */
    TEST_DECL(test_wc_CryptoCb),
    /* Can't memory test as client/server hangs. */
    TEST_DECL(test_wolfSSL_CTX_StaticMemory),
#if !defined(NO_FILESYSTEM) &&                                                 \
     defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) &&                    \
    !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
    TEST_DECL(test_wolfSSL_dtls_stateless_resume),
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
#ifdef HAVE_MAX_FRAGMENT
    TEST_DECL(test_wolfSSL_dtls_stateless_maxfrag),
#endif /* HAVE_MAX_FRAGMENT */
#ifndef NO_RSA
    TEST_DECL(test_wolfSSL_dtls_stateless2),
#if !defined(NO_OLD_TLS)
    TEST_DECL(test_wolfSSL_dtls_stateless_downgrade),
#endif /* !defined(NO_OLD_TLS) */
#endif /* ! NO_RSA */
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) &&     \
        *  !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) */
    TEST_DECL(test_wolfSSL_CTX_set_ciphersuites),
    TEST_DECL(test_wolfSSL_CRL_CERT_REVOKED_alert),
    TEST_DECL(test_TLS_13_ticket_different_ciphers),
    TEST_DECL(test_WOLFSSL_dtls_version_alert),

#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && defined(HAVE_SESSION_TICKET)       \
    && defined(WOLFSSL_TLS13) &&                                               \
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
    TEST_DECL(test_ticket_nonce_malloc),
#endif
    TEST_DECL(test_ticket_ret_create),
    TEST_DECL(test_wrong_cs_downgrade),
    TEST_DECL(test_extra_alerts_wrong_cs),
    TEST_DECL(test_extra_alerts_skip_hs),
    TEST_DECL(test_extra_alerts_bad_psk),
    TEST_DECL(test_multiple_alerts_EAGAIN),
    TEST_DECL(test_tls13_bad_psk_binder),
    /* Can't memory test as client/server Asserts. */
    TEST_DECL(test_harden_no_secure_renegotiation),
    TEST_DECL(test_override_alt_cert_chain),
    TEST_DECL(test_rpk_set_xxx_cert_type),
    TEST_DECL(test_tls13_rpk_handshake),
    TEST_DECL(test_dtls13_bad_epoch_ch),
    TEST_DECL(test_short_session_id),
    TEST_DECL(test_wolfSSL_dtls13_null_cipher),
    /* Can't memory test as client/server hangs. */
    TEST_DECL(test_dtls_msg_from_other_peer),
    TEST_DECL(test_dtls_ipv6_check),
    TEST_DECL(test_wolfSSL_SCR_after_resumption),
    TEST_DECL(test_dtls_no_extensions),
    TEST_DECL(test_tls_alert_no_server_hello),
    TEST_DECL(test_TLSX_CA_NAMES_bad_extension),
    TEST_DECL(test_dtls_1_0_hvr_downgrade),
    TEST_DECL(test_session_ticket_no_id),
    TEST_DECL(test_session_ticket_hs_update),
    TEST_DECL(test_dtls_downgrade_scr_server),
    TEST_DECL(test_dtls_downgrade_scr),
    TEST_DECL(test_dtls_client_hello_timeout_downgrade),
    TEST_DECL(test_dtls_client_hello_timeout),
    TEST_DECL(test_dtls_dropped_ccs),
    TEST_DECL(test_dtls_seq_num_downgrade),
    TEST_DECL(test_certreq_sighash_algos),
    TEST_DECL(test_revoked_loaded_int_cert),
    TEST_DECL(test_dtls_frag_ch),
    TEST_DECL(test_dtls13_frag_ch_pq),
    TEST_DECL(test_dtls_empty_keyshare_with_cookie),
    TEST_DECL(test_dtls_old_seq_number),
    TEST_DECL(test_dtls12_basic_connection_id),
    TEST_DECL(test_dtls13_basic_connection_id),
    TEST_DECL(test_tls13_pq_groups),
    TEST_DECL(test_tls13_early_data),
    TEST_DECL(test_tls_multi_handshakes_one_record),
    TEST_DECL(test_write_dup),
    TEST_DECL(test_read_write_hs),
    TEST_DECL(test_get_signature_nid),
    TEST_DECL(test_tls_cert_store_unchanged),
    TEST_DECL(test_wolfSSL_SendUserCanceled),
    /* This test needs to stay at the end to clean up any caches allocated. */
    TEST_DECL(test_wolfSSL_Cleanup)
};

#define TEST_CASE_CNT (int)(sizeof(testCases) / sizeof(*testCases))

static void TestSetup(void)
{
/* Stub, for now. Add common test setup code here. */
}

static void TestCleanup(void)
{
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
    /* Clear any errors added to the error queue during the test run. */
    wolfSSL_ERR_clear_error();
#endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */
}

/* Print out all API test cases with numeric identifier.
 */
void ApiTest_PrintTestCases(void)
{
    int i;

    printf("All Test Cases:\n");
    for (i = 0; i < TEST_CASE_CNT; i++) {
        printf("%3d: %s\n", i + 1, testCases[i].name);
    }
}

/* Add test case with index to the list to run.
 *
 * @param [in]  idx  Index of test case to run starting at 1.
 * @return  0 on success.
 * @return  BAD_FUNC_ARG when index is out of range of test case identifiers.
 */
int ApiTest_RunIdx(int idx)
{
    if (idx < 1 || idx > TEST_CASE_CNT) {
        printf("Index out of range (1 - %d): %d\n", TEST_CASE_CNT, idx);
        return BAD_FUNC_ARG;
    }

    testAll = 0;
    testCases[idx-1].run = 1;

    return 0;
}

/* Add test case with name to the list to run.
 *
 * @param [in]  name  Name of test case to run.
 * @return  0 on success.
 * @return  BAD_FUNC_ARG when name is not a known test case name.
 */
int ApiTest_RunName(char* name)
{
    int i;

    for (i = 0; i < TEST_CASE_CNT; i++) {
        if (XSTRCMP(testCases[i].name, name) == 0) {
            testAll = 0;
            testCases[i].run = 1;
            return 0;
        }
    }

    printf("Test case name not found: %s\n", name);
    printf("Use --list to see all test case names.\n");
    return BAD_FUNC_ARG;
}

/* Converts the result code to a string.
 *
 * @param [in]  res  Test result code.
 * @return  String describing test result.
 */
static const char* apitest_res_string(int res)
{
    const char* str = "invalid result";

    switch (res) {
    case TEST_SUCCESS:
        str = "passed";
        break;
    case TEST_FAIL:
        str = "failed";
        break;
    case TEST_SKIPPED:
        str = "skipped";
        break;
    }

    return str;
}

#ifndef WOLFSSL_UNIT_TEST_NO_TIMING
static double gettime_secs(void)
    #if defined(_MSC_VER) && defined(_WIN32)
    {
        /* there's no gettimeofday for Windows, so we'll use system time */
        #define EPOCH_DIFF 11644473600LL
        FILETIME currentFileTime;
        GetSystemTimePreciseAsFileTime(&currentFileTime);

        ULARGE_INTEGER uli = { 0, 0 };
        uli.LowPart = currentFileTime.dwLowDateTime;
        uli.HighPart = currentFileTime.dwHighDateTime;

        /* Convert to seconds since Unix epoch */
        return (double)((uli.QuadPart - (EPOCH_DIFF * 10000000)) / 10000000.0);
    }
    #else
    {
        struct timeval tv;
        LIBCALL_CHECK_RET(gettimeofday(&tv, 0));

        return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
    }
    #endif
#endif

int ApiTest(void)
{
    int i;
    int ret;
    int res = 0;
#ifndef WOLFSSL_UNIT_TEST_NO_TIMING
    double timeDiff;
#endif

    printf(" Begin API Tests\n");
    fflush(stdout);

    /* we must perform init and cleanup if not all tests are running */
    if (!testAll) {
    #ifdef WOLFCRYPT_ONLY
        if (wolfCrypt_Init() != 0) {
            printf("wolfCrypt Initialization failed\n");
            res = 1;
        }
    #else
        if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
            printf("wolfSSL Initialization failed\n");
            res = 1;
        }
    #endif
    }

    #ifdef WOLFSSL_DUMP_MEMIO_STREAM
    if (res == 0) {
        if (create_tmp_dir(tmpDirName, sizeof(tmpDirName) - 1) == NULL) {
            printf("failed to create tmp dir\n");
            res = 1;
        }
        else {
            tmpDirNameSet = 1;
        }
    }
    #endif

    if (res == 0) {
        for (i = 0; i < TEST_CASE_CNT; ++i) {
            EXPECT_DECLS;

        #ifdef WOLFSSL_DUMP_MEMIO_STREAM
            currentTestName = testCases[i].name;
        #endif

            /* When not testing all cases then skip if not marked for running.
             */
            if (!testAll && !testCases[i].run) {
                continue;
            }

            TestSetup();

            printf("   %3d: %-52s:", i + 1, testCases[i].name);
            fflush(stdout);
        #ifndef WOLFSSL_UNIT_TEST_NO_TIMING
            timeDiff = gettime_secs();
        #endif
            ret = testCases[i].func();
        #ifndef WOLFSSL_UNIT_TEST_NO_TIMING
            timeDiff = gettime_secs() - timeDiff;
        #endif
        #ifndef WOLFSSL_UNIT_TEST_NO_TIMING
            if (ret != TEST_SKIPPED) {
                printf(" %s (%9.5lf)\n", apitest_res_string(ret), timeDiff);
            }
            else
        #endif
            {
                printf(" %s\n", apitest_res_string(ret));
            }
            fflush(stdout);
            /* if return code is < 0 and not skipped then assert error */
            Expect((ret > 0 || ret == TEST_SKIPPED),
                ("Test failed\n"),
                ("ret %d", ret));
            testCases[i].fail = ((ret <= 0) && (ret != TEST_SKIPPED));
            res |= ((ret <= 0) && (ret != TEST_SKIPPED));

            TestCleanup();
        }
    }

#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) \
                      && (defined(NO_MAIN_DRIVER) || defined(HAVE_STACK_SIZE))
    wc_ecc_fp_free();  /* free per thread cache */
#endif

    if (!testAll) {
    #ifdef WOLFCRYPT_ONLY
        wolfCrypt_Cleanup();
    #else
        wolfSSL_Cleanup();
    #endif
    }

    (void)testDevId;

    if (res != 0) {
        printf("\nFAILURES:\n");
        for (i = 0; i < TEST_CASE_CNT; ++i) {
            if (testCases[i].fail) {
                printf("   %3d: %s\n", i + 1, testCases[i].name);
            }
        }
        printf("\n");
        fflush(stdout);
    }

#ifdef WOLFSSL_DUMP_MEMIO_STREAM
    if (tmpDirNameSet) {
        printf("\nBinary dumps of the memio streams can be found in the\n"
                "%s directory. This can be imported into\n"
                "Wireshark by transforming the file with\n"
                "\tod -Ax -tx1 -v stream.dump > stream.dump.hex\n"
                "And then loading test_output.dump.hex into Wireshark using\n"
                "the \"Import from Hex Dump...\" option and selecting the\n"
                "TCP encapsulation option.\n", tmpDirName);
    }
#endif

    printf(" End API Tests\n");
    fflush(stdout);
    return res;
}
