BN_init(&xr);
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 		EC_KEY *eckey){	BIGNUM *kinv=NULL,*r=NULL,*s=NULL,*m=NULL,*tmp=NULL,*order=NULL;	BIGNUM xr;	BN_CTX *ctx=NULL;	ECDSA_SIG *ret=NULL;	ECDSA_DATA *ecdsa;	ecdsa = ecdsa_check(eckey);	if (!eckey || !eckey->group || !eckey->pub_key || !eckey->priv_key 		|| !ecdsa)	{		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);		goto err;	}	BN_init(&xr);	if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||		(tmp = BN_new()) == NULL || (m = BN_new()) == NULL ||		(s = BN_new()) == NULL )	{		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);		goto err;	}	if (!EC_GROUP_get_order(eckey->group,order,ctx))	{		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);		goto err;	}	if (dgst_len > BN_num_bytes(order))	{		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,			ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);		goto err;	}	if (BN_bin2bn(dgst,dgst_len,m) == NULL)	{		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);		goto err;	}	do	{		if (ecdsa->kinv == NULL || ecdsa->r == NULL)		{			if (!ECDSA_sign_setup(eckey,ctx,&kinv,&r))			{				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,					ERR_R_ECDSA_LIB);				goto err;			}		}		else		{			kinv = ecdsa->kinv;			ecdsa->kinv = NULL;			r = ecdsa->r;			ecdsa->r = NULL;		}		if (!BN_mod_mul(tmp,eckey->priv_key,r,order,ctx))		{			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);			goto err;		}		if (!BN_add(s,tmp,m))		{			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);			goto err;		}		if (BN_cmp(s,order) > 0)			BN_sub(s,s,order);		if (!BN_mod_mul(s,s,kinv,order,ctx))		{			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);			goto err;		}	}	while (BN_is_zero(s));	if ((ret = ECDSA_SIG_new()) == NULL)	{		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);		goto err;	}	if (BN_copy(ret->r, r) == NULL || BN_copy(ret->s, s) == NULL)	{		ECDSA_SIG_free(ret);		ret = NULL;		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);	}	err:	if (r)		BN_clear_free(r);	if (s)		BN_clear_free(s);	if (ctx)		BN_CTX_free(ctx);	if (m)		BN_clear_free(m);	if (tmp)		BN_clear_free(tmp);	if (order)		BN_clear_free(order);	if (kinv)		BN_clear_free(kinv);	return(ret);}