static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
    ecc_key* key)
{
    int err;
#ifdef PLUTON_CRYPTO_ECC
    if (key->devId != INVALID_DEVID) /* use hardware */
#endif
    {
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
        word32 raw_sig_size = *outlen;
        word32 msgLenInBytes = inlen;
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
    #endif
        word32 keysize = (word32)key->dp->size;
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);

        /* Check args */
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
            return ECC_BAD_ARG_E;
        }

    #if defined(WOLFSSL_ATECC508A)
        key->slot = atmel_ecc_alloc(ATMEL_SLOT_DEVICE);
        if (key->slot == ATECC_INVALID_SLOT) {
            return ECC_BAD_ARG_E;
        }

        /* Sign: Result is 32-bytes of R then 32-bytes of S */
        err = atmel_ecc_sign(key->slot, in, out);
        if (err != 0) {
           return err;
        }
    #elif defined(PLUTON_CRYPTO_ECC)
        {
            /* if the input is larger than curve order, we must truncate */
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
            }

            /* perform ECC sign */
            word32 raw_sig_size = *outlen;
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
               return BAD_COND_E;
            }
        }
    #elif defined(WOLFSSL_CRYPTOCELL)

        hash_mode = cc310_hashModeECC(msgLenInBytes);
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
            hash_mode = cc310_hashModeECC(keysize);
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
        }

        /* truncate if hash is longer than key size */
        if (msgLenInBytes > keysize) {
            msgLenInBytes = keysize;
        }

        /* create signature from an input buffer using a private key*/
        err = CRYS_ECDSA_Sign(&wc_rndState,
                               wc_rndGenVectFunc,
                               &sigCtxTemp,
                               &key->ctx.privKey,
                               hash_mode,
                               (byte*)in,
                               msgLenInBytes,
                               out,
                               &raw_sig_size);

        if (err != SA_SILIB_RET_OK){
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
            return err;
        }
    #endif

        /* Load R and S */
        err = mp_read_unsigned_bin(r, &out[0], keysize);
        if (err != MP_OKAY) {
            return err;
        }
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
        if (err != MP_OKAY) {
            return err;
        }

        /* Check for zeros */
        if (mp_iszero(r) || mp_iszero(s)) {
            return MP_ZERO_E;
        }
    }
#ifdef PLUTON_CRYPTO_ECC
    else {
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
    }
#endif
    (void)rng;

    return err;
}
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
    ecc_key* key)
{
    int err;
#ifdef PLUTON_CRYPTO_ECC
    if (key->devId != INVALID_DEVID)  
#endif
    {
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
        word32 raw_sig_size = *outlen;
        word32 msgLenInBytes = inlen;
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
    #endif
        word32 keysize = (word32)key->dp->size;
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);

         
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
            return ECC_BAD_ARG_E;
        }

    #if defined(WOLFSSL_ATECC508A)
        key->slot = atmel_ecc_alloc(ATMEL_SLOT_DEVICE);
        if (key->slot == ATECC_INVALID_SLOT) {
            return ECC_BAD_ARG_E;
        }

         
        err = atmel_ecc_sign(key->slot, in, out);
        if (err != 0) {
           return err;
        }
    #elif defined(PLUTON_CRYPTO_ECC)
        {
             
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
            }

             
            word32 raw_sig_size = *outlen;
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
               return BAD_COND_E;
            }
        }
    #elif defined(WOLFSSL_CRYPTOCELL)

        hash_mode = cc310_hashModeECC(msgLenInBytes);
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
            hash_mode = cc310_hashModeECC(keysize);
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
        }

         
        if (msgLenInBytes > keysize) {
            msgLenInBytes = keysize;
        }

         
        err = CRYS_ECDSA_Sign(&wc_rndState,
                               wc_rndGenVectFunc,
                               &sigCtxTemp,
                               &key->ctx.privKey,
                               hash_mode,
                               (byte*)in,
                               msgLenInBytes,
                               out,
                               &raw_sig_size);

        if (err != SA_SILIB_RET_OK){
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
            return err;
        }
    #endif

         
        err = mp_read_unsigned_bin(r, &out[0], keysize);
        if (err != MP_OKAY) {
            return err;
        }
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
        if (err != MP_OKAY) {
            return err;
        }

         
        if (mp_iszero(r) || mp_iszero(s)) {
            return MP_ZERO_E;
        }
    }
#ifdef PLUTON_CRYPTO_ECC
    else {
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
    }
#endif
    (void)rng;

    return err;
}