int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
                      word32* outlen)
{
   int err;
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
   CRYS_ECDH_TempData_t tempBuff;
#endif
   if (private_key == NULL || public_key == NULL || out == NULL ||
                                                            outlen == NULL) {
       return BAD_FUNC_ARG;
   }

#ifdef WOLF_CRYPTO_CB
    if (private_key->devId != INVALID_DEVID) {
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
        if (err != CRYPTOCB_UNAVAILABLE)
            return err;
        /* fall-through when unavailable */
    }
#endif

   /* type valid? */
   if (private_key->type != ECC_PRIVATEKEY &&
           private_key->type != ECC_PRIVATEKEY_ONLY) {
      return ECC_BAD_ARG_E;
   }

   /* Verify domain params supplied */
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 ||
       wc_ecc_is_valid_idx(public_key->idx)  == 0) {
      return ECC_BAD_ARG_E;
   }

   /* Verify curve id matches */
   if (private_key->dp->id != public_key->dp->id) {
      return ECC_BAD_ARG_E;
   }

#ifdef WOLFSSL_ATECC508A
   /* For SECP256R1 use hardware */
   if (private_key->dp->id == ECC_SECP256R1) {
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
       *outlen = private_key->dp->size;
   }
   else {
      err = NOT_COMPILED_IN;
   }
#elif defined(WOLFSSL_CRYPTOCELL)

    /* generate a secret*/
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
                            &private_key->ctx.privKey,
                            out,
                            outlen,
                            &tempBuff);

    if (err != SA_SILIB_RET_OK){
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
        return err;
    }

#else
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
#endif /* WOLFSSL_ATECC508A */

   return err;
}
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
                      word32* outlen)
{
   int err;
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
   CRYS_ECDH_TempData_t tempBuff;
#endif
   if (private_key == NULL || public_key == NULL || out == NULL ||
                                                            outlen == NULL) {
       return BAD_FUNC_ARG;
   }

#ifdef WOLF_CRYPTO_CB
    if (private_key->devId != INVALID_DEVID) {
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
        if (err != CRYPTOCB_UNAVAILABLE)
            return err;
         
    }
#endif

    
   if (private_key->type != ECC_PRIVATEKEY &&
           private_key->type != ECC_PRIVATEKEY_ONLY) {
      return ECC_BAD_ARG_E;
   }

    
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 ||
       wc_ecc_is_valid_idx(public_key->idx)  == 0) {
      return ECC_BAD_ARG_E;
   }

    
   if (private_key->dp->id != public_key->dp->id) {
      return ECC_BAD_ARG_E;
   }

#ifdef WOLFSSL_ATECC508A
    
   if (private_key->dp->id == ECC_SECP256R1) {
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
       *outlen = private_key->dp->size;
   }
   else {
      err = NOT_COMPILED_IN;
   }
#elif defined(WOLFSSL_CRYPTOCELL)

     
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
                            &private_key->ctx.privKey,
                            out,
                            outlen,
                            &tempBuff);

    if (err != SA_SILIB_RET_OK){
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
        return err;
    }

#else
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
#endif  

   return err;
}