static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
    word32 *outlen, WC_RNG* rng, ecc_key* key)
{
    int err;
    mp_int *r = NULL, *s = NULL;

    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
                                                                rng == NULL) {
        return ECC_BAD_ARG_E;
    }

    err = wc_ecc_alloc_async(key);
    if (err != 0) {
        return err;
    }
    r = key->r;
    s = key->s;

    switch(key->state) {
        case ECC_STATE_NONE:
        case ECC_STATE_SIGN_DO:
            key->state = ECC_STATE_SIGN_DO;

            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
                break;
            }

            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
            if (err < 0) {
                break;
            }

            FALL_THROUGH;

        case ECC_STATE_SIGN_ENCODE:
            key->state = ECC_STATE_SIGN_ENCODE;

            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
                #ifdef HAVE_CAVIUM_V
                    /* Nitrox requires r and s in sep buffer, so split it */
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
                #endif
                #ifndef WOLFSSL_ASYNC_CRYPT_TEST
                    /* only do this if not simulator, since it overwrites result */
                    wc_bigint_to_mp(&r->raw, r);
                    wc_bigint_to_mp(&s->raw, s);
                #endif
            }

            /* encoded with DSA header */
            err = StoreECC_DSA_Sig(out, outlen, r, s);

            /* done with R/S */
            mp_clear(r);
            mp_clear(s);
            break;

        default:
            err = BAD_STATE_E;
            break;
    }

    /* if async pending then return and skip done cleanup below */
    if (err == WC_PENDING_E) {
        key->state++;
        return err;
    }

    /* cleanup */
    wc_ecc_free_async(key);
    key->state = ECC_STATE_NONE;

    return err;
}
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
    word32 *outlen, WC_RNG* rng, ecc_key* key)
{
    int err;
    mp_int *r = NULL, *s = NULL;

    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
                                                                rng == NULL) {
        return ECC_BAD_ARG_E;
    }

    err = wc_ecc_alloc_async(key);
    if (err != 0) {
        return err;
    }
    r = key->r;
    s = key->s;

    switch(key->state) {
        case ECC_STATE_NONE:
        case ECC_STATE_SIGN_DO:
            key->state = ECC_STATE_SIGN_DO;

            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
                break;
            }

            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
            if (err < 0) {
                break;
            }

            FALL_THROUGH;

        case ECC_STATE_SIGN_ENCODE:
            key->state = ECC_STATE_SIGN_ENCODE;

            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
                #ifdef HAVE_CAVIUM_V
                     
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
                #endif
                #ifndef WOLFSSL_ASYNC_CRYPT_TEST
                     
                    wc_bigint_to_mp(&r->raw, r);
                    wc_bigint_to_mp(&s->raw, s);
                #endif
            }

             
            err = StoreECC_DSA_Sig(out, outlen, r, s);

             
            mp_clear(r);
            mp_clear(s);
            break;

        default:
            err = BAD_STATE_E;
            break;
    }

     
    if (err == WC_PENDING_E) {
        key->state++;
        return err;
    }

     
    wc_ecc_free_async(key);
    key->state = ECC_STATE_NONE;

    return err;
}