Esempio n. 1
0
/* returns
 *      1: correct signature
 *      0: incorrect signature
 *     -1: error
 */
int
ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
    const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
{
	ECDSA_SIG *s;
	unsigned char *der = NULL;
	const unsigned char *p = sigbuf;
	int derlen = -1;
	int ret = -1;

	s = ECDSA_SIG_new();
	if (s == NULL)
		return (ret);
	if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
		goto err;
	/* Ensure signature uses DER and doesn't have trailing garbage */
	derlen = i2d_ECDSA_SIG(s, &der);
	if (derlen != sig_len || memcmp(sigbuf, der, derlen))
		goto err;
	ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);

err:
	freezero(der, derlen);
	ECDSA_SIG_free(s);
	return (ret);
}
Esempio n. 2
0
bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
{
    if (vchSig.empty())
        return false;

    // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
    unsigned char *norm_der = NULL;
    ECDSA_SIG *norm_sig = ECDSA_SIG_new();
    const unsigned char* sigptr = &vchSig[0];
    assert(norm_sig);
    if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
    {
        /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on
        * error. But OpenSSL's own use of this function redundantly frees the
        * result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a
        * clear contract for the function behaving the same way is more
        * conservative.
        */
        ECDSA_SIG_free(norm_sig);
        return false;
    }
    int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
    ECDSA_SIG_free(norm_sig);
    if (derlen <= 0)
        return false;

    // -1 = error, 0 = bad sig, 1 = good
    bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
    OPENSSL_free(norm_der);
    return ret;
}
Esempio n. 3
0
static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len,
                                    const BIGNUM *inv, const BIGNUM *rp,
                                    EC_KEY *ecdsa) {
    struct pkcs11_key_data *pkd = NULL;
	CK_MECHANISM mech = {
		CKM_ECDSA, NULL_PTR, 0
	};
	CK_ULONG tlen = 0;
	CK_RV rv;

#if OPENSSL_VERSION_NUMBER < 0x10100000L
    pkd = ECDSA_get_ex_data(ecdsa, pkcs11_ecdsa_key_idx);
#else
    pkd = EC_KEY_get_ex_data(ecdsa, pkcs11_ecdsa_key_idx);
#endif
    if((pkd != NULL) &&
       ((rv = pkd->funcs->C_SignInit(pkd->session, &mech, pkd->key)) == CKR_OK)) {
		CK_BYTE_PTR buf = NULL;
        ECDSA_SIG *rval;
        BIGNUM *r, *s;
        int nlen;
        
        /* Make a call to C_Sign to find out the size of the signature */
        rv = pkd->funcs->C_Sign(pkd->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen);
        if (rv != CKR_OK) {
            return NULL;
        }
        
        if ((buf = malloc(tlen)) == NULL) {
            return NULL;
        }
        
        rv = pkd->funcs->C_Sign(pkd->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen);
        if (rv != CKR_OK) {
            free(buf);
            return NULL;
        }
        
        if ((rval = ECDSA_SIG_new()) != NULL) {
            /* 
             * ECDSA signature is 2 large integers of same size returned
             * concatenated by PKCS#11, we separate them to create an
             * ECDSA_SIG for OpenSSL.
             */
            nlen = tlen / 2;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
            ECDSA_SIG_get0(&r, &s, rval);
#else
            r = rval->r;
            s = rval->s;
#endif
            BN_bin2bn(&buf[0], nlen, r);
            BN_bin2bn(&buf[nlen], nlen, s);
        }
        free(buf);
        return rval;
    } else {
        return NULL;
    }
}
Esempio n. 4
0
int verification(
    const unsigned char m[SHORTHASH_BYTES],const unsigned long long mlen,
    const unsigned char sm[SIGNATURE_BYTES],const unsigned long long smlen,
    const unsigned char pk[PUBLICKEY_BYTES],const unsigned long long pklen
    )
{
  unsigned char h[20];
  EC_GROUP *group;
  EC_KEY *k;
  EC_POINT *kxy;
  BIGNUM *kx;
  BIGNUM *ky;
  ECDSA_SIG *rs;
  int len;

  if (smlen != SIGNATURE_BYTES) return -1;
  if (mlen > SHORTHASH_BYTES) return -1;
  SHA1(m,mlen,h);

  group = EC_GROUP_new_by_curve_name(NID);
  if (!group) return -1;

  kx = BN_new(); if (!kx) return -1;
  ky = BN_new(); if (!ky) { BN_free(kx); return -1; }
  kxy = EC_POINT_new(group); if (!kxy) { BN_free(ky); BN_free(kx); return -1; }
  k = EC_KEY_new(); if (!k) { EC_POINT_free(kxy); BN_free(ky); BN_free(kx); return -1; }
  rs = ECDSA_SIG_new(); if (!rs) { EC_KEY_free(k); EC_POINT_free(kxy); BN_free(ky); BN_free(kx); return -1; }

  if (!EC_KEY_set_group(k,group)) goto error;
  if (!BN_bin2bn(pk,PRIME_BYTES,kx)) goto error; pk += PRIME_BYTES;
  if (!BN_bin2bn(pk,PRIME_BYTES,ky)) goto error;
#ifdef PRIME_FIELD
  if (!EC_POINT_set_affine_coordinates_GFp(group,kxy,kx,ky,0)) goto error;
#else
  if (!EC_POINT_set_affine_coordinates_GF2m(group,kxy,kx,ky,0)) goto error;
#endif
  if (!EC_KEY_set_public_key(k,kxy)) goto error;

  if (!BN_bin2bn(sm,PRIME_BYTES,rs->r)) goto error; sm += PRIME_BYTES;
  if (!BN_bin2bn(sm,PRIME_BYTES,rs->s)) goto error;

  len = ECDSA_do_verify(h,20,rs,k);
  ECDSA_SIG_free(rs);
  EC_KEY_free(k);
  EC_POINT_free(kxy);
  BN_free(ky);
  BN_free(kx);

  if (len == 1) return 0;
  if (len == 0) return -100;
  return -1;
  
error:
  ECDSA_SIG_free(rs);
  EC_KEY_free(k);
  EC_POINT_free(kxy);
  BN_free(ky);
  BN_free(kx);
  return -1;
}
Esempio n. 5
0
/**
 * Setup the ECDSA signature in its encoding that the library wants.
 * Converts from plain numbers to ASN formatted.
 * @param sig: input is signature, output alloced ptr (unless failure).
 * 	caller must free alloced ptr if this routine returns true.
 * @param len: input is initial siglen, output is output len.
 * @return false on failure.
 */
static int
setup_ecdsa_sig(unsigned char** sig, unsigned int* len)
{
	ECDSA_SIG* ecdsa_sig;
	int newlen;
	int bnsize = (int)((*len)/2);
	/* if too short or not even length, fails */
	if(*len < 16 || bnsize*2 != (int)*len)
		return 0;
	/* use the raw data to parse two evenly long BIGNUMs, "r | s". */
	ecdsa_sig = ECDSA_SIG_new();
	if(!ecdsa_sig) return 0;
	ecdsa_sig->r = BN_bin2bn(*sig, bnsize, ecdsa_sig->r);
	ecdsa_sig->s = BN_bin2bn(*sig+bnsize, bnsize, ecdsa_sig->s);
	if(!ecdsa_sig->r || !ecdsa_sig->s) {
		ECDSA_SIG_free(ecdsa_sig);
		return 0;
	}

	/* spool it into ASN format */
	*sig = NULL;
	newlen = i2d_ECDSA_SIG(ecdsa_sig, sig);
	if(newlen <= 0) {
		ECDSA_SIG_free(ecdsa_sig);
		free(*sig);
		return 0;
	}
	*len = (unsigned int)newlen;
	ECDSA_SIG_free(ecdsa_sig);
	return 1;
}
    public_key::public_key( const compact_signature& c, const fc::sha256& digest, bool check_canonical )
    {
        int nV = c.data[0];
        if (nV<27 || nV>=35)
            FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" );

        ECDSA_SIG *sig = ECDSA_SIG_new();
        BN_bin2bn(&c.data[1],32,sig->r);
        BN_bin2bn(&c.data[33],32,sig->s);

        if( check_canonical )
        {
            FC_ASSERT( is_canonical( c ), "signature is not canonical" );
        }

        my->_key = EC_KEY_new_by_curve_name(NID_secp256k1);

        if (nV >= 31)
        {
            EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
            nV -= 4;
//            fprintf( stderr, "compressed\n" );
        }

        if (detail::public_key_impl::ECDSA_SIG_recover_key_GFp(my->_key, sig, (unsigned char*)&digest, sizeof(digest), nV - 27, 0) == 1)
        {
            ECDSA_SIG_free(sig);
            return;
        }
        ECDSA_SIG_free(sig);
        FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" );
    }
Esempio n. 7
0
// reconstruct public key from a compact signature
// This is only slightly more CPU intensive than just verifying it.
// If this function succeeds, the recovered public key is guaranteed to be valid
// (the signature is a valid signature of the given data for that key)
bool CKey::SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
{
    if (vchSig.size() != 65)
        return false;
    int nV = vchSig[0];
    if (nV<27 || nV>=35)
        return false;
    ECDSA_SIG *sig = ECDSA_SIG_new();
    BN_bin2bn(&vchSig[1],32,sig->r);
    BN_bin2bn(&vchSig[33],32,sig->s);

    EC_KEY_free(pkey);
    pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
    if (nV >= 31)
    {
        SetCompressedPubKey();
        nV -= 4;
    }
    if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1)
    {
        fSet = true;
        ECDSA_SIG_free(sig);
        return true;
    }
    return false;
}
Esempio n. 8
0
/**
 * ECDSA signing method (replaces ossl_ecdsa_sign_sig)
 *
 *  @param  dgst     hash value to sign
 *  @param  dlen     length of the hash value
 *  @param  kinv     precomputed inverse k (from the sign_setup method)
 *  @param  rp       precomputed rp (from the sign_setup method)
 *  @param  ec       private EC signing key
 *  @return pointer to a ECDSA_SIG structure or NULL if an error occurred
 */
static ECDSA_SIG *pkcs11_ecdsa_sign_sig(const unsigned char *dgst, int dlen,
		const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *ec)
{
	unsigned char sigret[512]; /* HACK for now */
	ECDSA_SIG *sig;
	PKCS11_KEY *key;
	unsigned int siglen;
	BIGNUM *r, *s, *order;

	(void)kinv; /* Precomputed values are not used for PKCS#11 */
	(void)rp; /* Precomputed values are not used for PKCS#11 */

	key = pkcs11_get_ex_data_ec(ec);
	if (check_key_fork(key) < 0) {
		sign_sig_fn orig_sign_sig;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
		const EC_KEY_METHOD *meth = EC_KEY_OpenSSL();
		EC_KEY_METHOD_get_sign((EC_KEY_METHOD *)meth,
			NULL, NULL, &orig_sign_sig);
#else
		const ECDSA_METHOD *meth = ECDSA_OpenSSL();
		orig_sign_sig = meth->ecdsa_do_sign;
#endif
		return orig_sign_sig(dgst, dlen, kinv, rp, ec);
	}

	/* Truncate digest if its byte size is longer than needed */
	order = BN_new();
	if (order) {
		const EC_GROUP *group = EC_KEY_get0_group(ec);
		if (group && EC_GROUP_get_order(group, order, NULL)) {
			int klen = BN_num_bits(order);
			if (klen < 8*dlen)
				dlen = (klen+7)/8;
		}
		BN_free(order);
	}

	siglen = sizeof sigret;
	if (pkcs11_ecdsa_sign(dgst, dlen, sigret, &siglen, key) <= 0)
		return NULL;

	r = BN_bin2bn(sigret, siglen/2, NULL);
	s = BN_bin2bn(sigret + siglen/2, siglen/2, NULL);
	sig = ECDSA_SIG_new();
	if (sig == NULL)
		return NULL;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
	ECDSA_SIG_set0(sig, r, s);
#else
	BN_free(sig->r);
	sig->r = r;
	BN_free(sig->s);
	sig->s = s;
#endif
	return sig;
}
Esempio n. 9
0
File: sign.c Progetto: dnstap/knot
/*!
 * \brief Finish the signing and write out the ECDSA signature.
 * \see rsa_sign_write
 */
static int ecdsa_sign_write(const knot_dnssec_sign_context_t *context,
                            uint8_t *signature, size_t signature_size)
{
	assert(context);
	assert(signature);

	size_t output_size = ecdsa_sign_size(context->key);
	if (output_size != signature_size) {
		return KNOT_DNSSEC_EUNEXPECTED_SIGNATURE_SIZE;
	}

	// create raw signature

	uint8_t *raw_signature = NULL;
	size_t raw_size = 0;
	int result = sign_alloc_and_write(context, &raw_signature, &raw_size);
	if (result != KNOT_EOK) {
		return result;
	}

	// decode signature

	ECDSA_SIG *decoded = ECDSA_SIG_new();
	if (!decoded) {
		free(raw_signature);
		return KNOT_ENOMEM;
	}

	const uint8_t *decode_scan = raw_signature;
	if (!d2i_ECDSA_SIG(&decoded, &decode_scan, (long)raw_size)) {
		ECDSA_SIG_free(decoded);
		free(raw_signature);
		return KNOT_DNSSEC_EDECODE_RAW_SIGNATURE;
	}

	free(raw_signature);

	// convert to format defined by RFC 6605 (EC DSA for DNSSEC)
	// R and S parameters are encoded in halves of the output signature

	uint8_t *signature_r;
	uint8_t *signature_s;
	size_t param_size = output_size / 2;

	memset(signature, '\0', output_size);
	signature_r = signature + param_size - BN_num_bytes(decoded->r);
	signature_s = signature + 2 * param_size - BN_num_bytes(decoded->s);

	BN_bn2bin(decoded->r, signature_r);
	BN_bn2bin(decoded->s, signature_s);

	ECDSA_SIG_free(decoded);

	return KNOT_EOK;
}
Esempio n. 10
0
bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec)
{
    if (rec<0 || rec>=3)
        return false;
    ECDSA_SIG *sig = ECDSA_SIG_new();
    BN_bin2bn(&p64[0],  32, sig->r);
    BN_bin2bn(&p64[32], 32, sig->s);
    bool ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1;
    ECDSA_SIG_free(sig);
    return ret;
}
Esempio n. 11
0
int el_verify_license_key(el_context_t ctxt,
                          const char *licenseKey, const char *name)
{
    // TODO: change this back to use C99 variable length arrays once Visual C++
    //       can deal with it (2013 still can't)
    ECDSA_SIG *signature = NULL;
    uint8_t *signatureData = NULL;
    uint8_t *digest = NULL;

    if (!licenseKey || !strlen(licenseKey) || !name || !strlen(name))
        return 0;

    // TODO: blocked keys checking

    int signatureLength = el_base32_decode_buffer_size(strlen(licenseKey));

    signatureData = malloc(signatureLength);
    signatureLength = el_base32_decode(licenseKey, signatureData, signatureLength);

    // Check length of signature before verifying
    if (signatureLength != ctxt->digestLength * 2)
    {
        free(signatureData);
        return 0;
    }

    signature = ECDSA_SIG_new();
    if (!signature)
    {
        free(signatureData);
        return 0;
    }

    size_t partLen = signatureLength / 2;
    signature->r = BN_bin2bn(signatureData,           partLen, signature->r);
    signature->s = BN_bin2bn(signatureData + partLen, partLen, signature->s);
    if (!signature->r || !signature->s)
    {
        free(signatureData);
        ECDSA_SIG_free(signature);
        return 0;
    }

    digest = malloc(ctxt->digestLength);
    el_compute_digest(name, digest, ctxt->digestLength);

    int result = ECDSA_do_verify(digest, ctxt->digestLength, signature, ctxt->ecKey) == 1;

    free(signatureData);
    free(digest);
    ECDSA_SIG_free(signature);

    return result;
}
Esempio n. 12
0
// Credit: https://github.com/ppcoin/ppcoin/pull/101/files
bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSigParam)
{
    // Prevent the problem described here:
    // https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-July/009697.html
    // by removing the extra length bytes
    std::vector<unsigned char> vchSig(vchSigParam.begin(), vchSigParam.end());
    if (vchSig.size() > 1 && vchSig[1] & 0x80)
    {
        unsigned char nLengthBytes = vchSig[1] & 0x7f;

        if (vchSig.size() < 2 + nLengthBytes)
            return false;

        if (nLengthBytes > 4)
        {
            unsigned char nExtraBytes = nLengthBytes - 4;
            for (unsigned char i = 0; i < nExtraBytes; i++)
                if (vchSig[2 + i])
                    return false;
            vchSig.erase(vchSig.begin() + 2, vchSig.begin() + 2 + nExtraBytes);
            vchSig[1] = 0x80 | (nLengthBytes - nExtraBytes);
        }
    }

    if (vchSig.empty())
        return false;

    // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
    unsigned char *norm_der = NULL;
    ECDSA_SIG *norm_sig = ECDSA_SIG_new();
    const unsigned char* sigptr = &vchSig[0];
    assert(norm_sig);
    if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
    {
        /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on
         * error. But OpenSSL's own use of this function redundantly frees the
         * result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a
         * clear contract for the function behaving the same way is more
         * conservative.
         */
        ECDSA_SIG_free(norm_sig);
        return false;
    }
    int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
    ECDSA_SIG_free(norm_sig);
    if (derlen <= 0)
        return false;

    // -1 = error, 0 = bad sig, 1 = good
    bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
    OPENSSL_free(norm_der);
    return ret;
}
Esempio n. 13
0
/**
 * ECDSA signing method (replaces ossl_ecdsa_sign_sig)
 *
 *  @param  dgst     hash value to sign
 *  @param  dlen     length of the hash value
 *  @param  kinv     precomputed inverse k (from the sign_setup method)
 *  @param  rp       precomputed rp (from the sign_setup method)
 *  @param  ec       private EC signing key
 *  @return pointer to a ECDSA_SIG structure or NULL if an error occurred
 */
static ECDSA_SIG *pkcs11_ecdsa_sign_sig(const unsigned char *dgst, int dlen,
		const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *ec)
{
	unsigned char sigret[512]; /* HACK for now */
	ECDSA_SIG *sig;
	PKCS11_KEY *key;
	unsigned int siglen;
	BIGNUM *r, *s, *order;

	(void)kinv; /* Precomputed values are not used for PKCS#11 */
	(void)rp; /* Precomputed values are not used for PKCS#11 */

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	key = (PKCS11_KEY *)EC_KEY_get_ex_data(ec, ec_ex_index);
#else
	key = (PKCS11_KEY *)ECDSA_get_ex_data(ec, ec_ex_index);
#endif
	if (key == NULL) {
		PKCS11err(PKCS11_F_PKCS11_EC_KEY_SIGN, PKCS11_ALIEN_KEY);
		return NULL;
	}
	/* TODO: Add an atfork check */

	/* Truncate digest if its byte size is longer than needed */
	order = BN_new();
	if (order) {
		const EC_GROUP *group = EC_KEY_get0_group(ec);
		if (group && EC_GROUP_get_order(group, order, NULL)) {
			int klen = BN_num_bits(order);
			if (klen < 8*dlen)
				dlen = (klen+7)/8;
		}
		BN_free(order);
	}

	siglen = sizeof sigret;
	if (pkcs11_ecdsa_sign(dgst, dlen, sigret, &siglen, key) <= 0)
		return NULL;

	sig = ECDSA_SIG_new();
	if (sig == NULL)
		return NULL;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	ECDSA_SIG_get0(&r, &s, sig);
#else
	r = sig->r;
	s = sig->s;
#endif
	BN_bin2bn(sigret, siglen/2, r);
	BN_bin2bn(sigret + siglen/2, siglen/2, s);
	return sig;
}
Esempio n. 14
0
static ECDSA_SIG * pkcs11_ecdsa_do_sign(const unsigned char *dgst, int dlen,
			const BIGNUM *inv, const BIGNUM *r, EC_KEY * ec)
{

	unsigned char sigret[512]; /* HACK for now */
	ECDSA_SIG * sig = NULL;
	PKCS11_KEY * key = NULL;
	unsigned int siglen;
	int nLen = 48; /* HACK */
	int rv;

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	key = (PKCS11_KEY *) EC_KEY_get_ex_data(ec, ec_key_ex_index);
#else
	key = (PKCS11_KEY *) ECDSA_get_ex_data(ec, ecdsa_ex_index);
#endif
	if (key == NULL)
		return NULL;

	siglen = sizeof(sigret);

	rv = PKCS11_ecdsa_sign(dgst, dlen, sigret, &siglen, key);
	nLen = siglen / 2;
	if (rv > 0) {
		sig = ECDSA_SIG_new();
		if (sig) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		/*
		 * OpenSSL 1.1 does not have a way to allocate r and s 
		 * in ECDSA_SIG as it is now hidden. 
		 * Will us dummy ASN1 so r and s are allocated then
		 * use ECDSA_SIG_get0 to get access to r and s 
		 * can then update r annd s
		 */
			const unsigned char *a;
			unsigned char dasn1[8] =
				{0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00};
			BIGNUM *r;
			BIGNUM *s;
			a = dasn1;
			d2i_ECDSA_SIG(&sig, &a, 8);
			ECDSA_SIG_get0(&r, &s, sig);
			BN_bin2bn(&sigret[0], nLen, r);
			BN_bin2bn(&sigret[nLen], nLen, s);
#else
			BN_bin2bn(&sigret[0], nLen, sig->r);
			BN_bin2bn(&sigret[nLen], nLen, sig->s);
#endif
		}
	}
	return sig;
}
Esempio n. 15
0
static isc_result_t
opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
	isc_result_t ret;
	dst_key_t *key = dctx->key;
	int status;
	unsigned char *cp = sig->base;
	ECDSA_SIG *ecdsasig = NULL;
	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
	EVP_PKEY *pkey = key->keydata.pkey;
	EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
	unsigned int dgstlen, siglen;
	unsigned char digest[EVP_MAX_MD_SIZE];

	REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
		key->key_alg == DST_ALG_ECDSA384);

	if (eckey == NULL)
		return (ISC_R_FAILURE);

	if (key->key_alg == DST_ALG_ECDSA256)
		siglen = DNS_SIG_ECDSA256SIZE;
	else
		siglen = DNS_SIG_ECDSA384SIZE;

	if (sig->length != siglen)
		return (DST_R_VERIFYFAILURE);

	if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen))
		DST_RET (ISC_R_FAILURE);

	ecdsasig = ECDSA_SIG_new();
	if (ecdsasig == NULL)
		DST_RET (ISC_R_NOMEMORY);
	ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL);
	cp += siglen / 2;
	ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL);
	/* cp += siglen / 2; */

	status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey);
	if (status != 1)
		DST_RET (dst__openssl_toresult(DST_R_VERIFYFAILURE));
	ret = ISC_R_SUCCESS;

 err:
	if (ecdsasig != NULL)
		ECDSA_SIG_free(ecdsasig);
	if (eckey != NULL)
		EC_KEY_free(eckey);
	return (ret);
}
Esempio n. 16
0
/* returns
 *      1: correct signature
 *      0: incorrect signature
 *     -1: error
 */
int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
		const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
 	{
	ECDSA_SIG *s;
	int ret=-1;

	s = ECDSA_SIG_new();
	if (s == NULL) return(ret);
	if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
	ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
err:
	ECDSA_SIG_free(s);
	return(ret);
	}
Esempio n. 17
0
File: sign.c Progetto: dnstap/knot
/*!
 * \brief Verify the DNSSEC signature for supplied data and ECDSA algorithm.
 * \see any_sign_verify
 */
static int ecdsa_sign_verify(const knot_dnssec_sign_context_t *context,
                             const uint8_t *signature, size_t signature_size)
{
	assert(context);
	assert(signature);

	if (signature_size != ecdsa_sign_size(context->key)) {
		return KNOT_EINVAL;
	}

	// see ecdsa_sign_write() for conversion details

	size_t parameter_size = signature_size / 2;
	const uint8_t *signature_r = signature;
	const uint8_t *signature_s = signature + parameter_size;

	ECDSA_SIG *decoded = ECDSA_SIG_new();
	if (!decoded) {
		return KNOT_ENOMEM;
	}

	decoded->r = BN_bin2bn(signature_r, parameter_size, decoded->r);
	decoded->s = BN_bin2bn(signature_s, parameter_size, decoded->s);

	size_t max_size = EVP_PKEY_size(context->key->data->private_key);
	uint8_t *raw_signature = malloc(max_size);
	if (!raw_signature) {
		ECDSA_SIG_free(decoded);
		return KNOT_ENOMEM;
	}

	uint8_t *raw_write = raw_signature;
	int raw_size = i2d_ECDSA_SIG(decoded, &raw_write);
	if (raw_size < 0) {
		free(raw_signature);
		ECDSA_SIG_free(decoded);
		return KNOT_DNSSEC_EDECODE_RAW_SIGNATURE;
	}
	assert(raw_write == raw_signature + raw_size);

	int result = any_sign_verify(context, raw_signature, raw_size);

	ECDSA_SIG_free(decoded);

	free(raw_signature);

	return result;
}
Esempio n. 18
0
bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSigParam)
{
    // Fix invalid signature with crafted length by removing extra length bytes
    std::vector<unsigned char> vchSig(vchSigParam.begin(), vchSigParam.end());
    if (vchSig.size() > 1 && vchSig[1] & 0x80)
    {
        unsigned char nLengthBytes = vchSig[1] & 0x7f;

        if (vchSig.size() < 2 + nLengthBytes)   // Avoid invalid memory access on crafted signature
            return false;

        if (nLengthBytes > 4)
        {
            unsigned char nExtraBytes = nLengthBytes - 4;
            for (unsigned char i = 0; i < nExtraBytes; i++)
                if (vchSig[2 + i])
                    return false;
            vchSig.erase(vchSig.begin() + 2, vchSig.begin() + 2 + nExtraBytes);
            vchSig[1] = 0x80 | (nLengthBytes - nExtraBytes);
        }
    }

    if (vchSig.empty())
        return false;

    // New versions of OpenSSL will reject non-canonical DER signatures. De/re-serialize first.
    unsigned char *norm_der = NULL;
    ECDSA_SIG *norm_sig = ECDSA_SIG_new();
    const unsigned char* sigptr = &vchSig[0];
    assert(norm_sig);
    if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
    {
        /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on error.
         * But OpenSSL's own use of this function redundantly frees the result.
         * As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a clear contract for the function behaving the same way is more conservative. */
        ECDSA_SIG_free(norm_sig);
        return false;
    }
    int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
    ECDSA_SIG_free(norm_sig);
    if (derlen <= 0)
        return false;

    // -1 = error, 0 = bad sig, 1 = good
    bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
    OPENSSL_free(norm_der);
    return ret;
}
Esempio n. 19
0
int
_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
      const unsigned char *r, size_t r_len,
      const unsigned char *s, size_t s_len,
      const unsigned char *m, size_t m_len)
{
    int ret = 0;
    EC_KEY *ec_key = (EC_KEY*)ctx;
    libssh2_curve_type type = _libssh2_ecdsa_key_get_curve_type(ec_key);

#ifdef HAVE_OPAQUE_STRUCTS
    ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new();
    BIGNUM *pr = BN_new();
    BIGNUM *ps = BN_new();

    BN_bin2bn(r, r_len, pr);
    BN_bin2bn(s, s_len, ps);
    ECDSA_SIG_set0(ecdsa_sig, pr, ps);

#else
    ECDSA_SIG ecdsa_sig_;
    ECDSA_SIG *ecdsa_sig = &ecdsa_sig_;
    ecdsa_sig_.r = BN_new();
    BN_bin2bn(r, r_len, ecdsa_sig_.r);
    ecdsa_sig_.s = BN_new();
    BN_bin2bn(s, s_len, ecdsa_sig_.s);
#endif

    if(type == LIBSSH2_EC_CURVE_NISTP256) {
        LIBSSH2_ECDSA_VERIFY(256);
    }
    else if(type == LIBSSH2_EC_CURVE_NISTP384) {
        LIBSSH2_ECDSA_VERIFY(384);
    }
    else if(type == LIBSSH2_EC_CURVE_NISTP521) {
        LIBSSH2_ECDSA_VERIFY(512);
    }

#ifdef HAVE_OPAQUE_STRUCTS
    if(ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);
#else
    BN_clear_free(ecdsa_sig_.s);
    BN_clear_free(ecdsa_sig_.r);
#endif

    return (ret == 1) ? 0 : -1;
}
Esempio n. 20
0
ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) {
  ECDSA_SIG *ret = ECDSA_SIG_new();
  if (ret == NULL) {
    return NULL;
  }
  CBS child;
  if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
      !BN_parse_asn1_unsigned(&child, ret->r) ||
      !BN_parse_asn1_unsigned(&child, ret->s) ||
      CBS_len(&child) != 0) {
    OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
    ECDSA_SIG_free(ret);
    return NULL;
  }
  return ret;
}
Esempio n. 21
0
bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
{
    // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
    unsigned char *norm_der = NULL;
    ECDSA_SIG *norm_sig = ECDSA_SIG_new();
    const unsigned char* sigptr = &vchSig[0];
    d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size());
    int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
    ECDSA_SIG_free(norm_sig);
    if (derlen <= 0)
        return false;

    // -1 = error, 0 = bad sig, 1 = good
    bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
    OPENSSL_free(norm_der);
    return ret;
}
Esempio n. 22
0
BUF_MEM *
convert_from_plain_sig(const BUF_MEM *plain_sig)
{
    ECDSA_SIG *ecdsa_sig = NULL;
    BIGNUM *r, *s;
    BUF_MEM *x962_sig = NULL;
    int l;
    unsigned char *p = NULL;

    check(plain_sig, "Invalid arguments");

    check(plain_sig->length%2 == 0, "Invalid data");

    ecdsa_sig = ECDSA_SIG_new();
    if (!ecdsa_sig)
        goto err;

    /* The first l/2 bytes of the plain signature contain the number r, the second
     * l/2 bytes contain the number s. */
    r = BN_bin2bn((unsigned char *) plain_sig->data,
            plain_sig->length/2, NULL);
    s = BN_bin2bn((unsigned char *) plain_sig->data + plain_sig->length/2,
            plain_sig->length/2, NULL);
    if (!r || !s || !ECDSA_SIG_set0(ecdsa_sig, r, s))
        goto err;
    r = NULL;
    s = NULL;

    /* ASN.1 encode the signature*/
    l = i2d_ECDSA_SIG(ecdsa_sig, &p);
    if (l < 0)
        goto err;
    x962_sig = BUF_MEM_create_init(p, l);

err:
    if (p)
        OPENSSL_free(p);
    if (ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);
    if (r)
        BN_free(r);
    if (s)
        BN_free(s);

    return x962_sig;
}
Esempio n. 23
0
File: jws.c Progetto: cisco/cjose
static bool _cjose_jws_verify_sig_ec(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    bool retval = false;

    // ensure jwk is EC
    if (jwk->kty != CJOSE_JWK_KTY_EC)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    ec_keydata *keydata = (ec_keydata *)jwk->keydata;
    EC_KEY *ec = keydata->key;

    ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new();
    int key_len = jws->sig_len / 2;

#if defined(CJOSE_OPENSSL_11X)
    BIGNUM *pr = BN_new(), *ps = BN_new();
    BN_bin2bn(jws->sig, key_len, pr);
    BN_bin2bn(jws->sig + key_len, key_len, ps);
    ECDSA_SIG_set0(ecdsa_sig, pr, ps);
#else
    BN_bin2bn(jws->sig, key_len, ecdsa_sig->r);
    BN_bin2bn(jws->sig + key_len, key_len, ecdsa_sig->s);
#endif

    if (ECDSA_do_verify(jws->dig, jws->dig_len, ecdsa_sig, ec) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ec_cleanup;
    }

    // if we got this far - success
    retval = true;

_cjose_jws_verify_sig_ec_cleanup:
    if (ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);

    return retval;
}
Esempio n. 24
0
static int openssl_ecdsa_verify(lua_State*L)
{
  size_t l;
  int ret;
  EC_KEY* ec = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key");
  const char* dgst = luaL_checklstring(L, 2, &l);
  BIGNUM *r = CHECK_OBJECT(3, BIGNUM, "openssl.bn");
  BIGNUM *s = CHECK_OBJECT(4, BIGNUM, "openssl.bn");

  ECDSA_SIG* sig = ECDSA_SIG_new();
  BN_copy(sig->r, r);
  BN_copy(sig->s, s);

  ret = ECDSA_do_verify((const unsigned char*)dgst, l, sig, ec);
  if (ret == -1)
    lua_pushnil(L);
  else
    lua_pushboolean(L, ret);
  ECDSA_SIG_free(sig);
  return 1;
}
Esempio n. 25
0
bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec)
{
	if (rec<0 || rec>=3)
		return false;
	ECDSA_SIG *sig = ECDSA_SIG_new();
    // OpenSSL-1.1 compatibility layer:
#if OPENSSL_VERSION_NUMBER > 0x1000ffffL
    BIGNUM *sig_r=BN_new();
    BIGNUM *sig_s=BN_new();
    BN_bin2bn(&p64[0],  32, sig_r);
    BN_bin2bn(&p64[32], 32, sig_s);
    ECDSA_SIG_set0(sig, sig_r, sig_s);
#else
    BN_bin2bn(&p64[0],  32, sig->r);
    BN_bin2bn(&p64[32], 32, sig->s);
#endif
    //
	bool ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1;
	ECDSA_SIG_free(sig);
	return ret;
}
Esempio n. 26
0
// reconstruct public key from a compact signature
// This is only slightly more CPU intensive than just verifying it.
// If this function succeeds, the recovered public key is guaranteed to be valid
// (the signature is a valid signature of the given data for that key)
bool CKey::SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
{
    if (vchSig.size() != 65)
        return false;
    int nV = vchSig[0];
    if (nV<27 || nV>=35)
        return false;
    ECDSA_SIG *sig = ECDSA_SIG_new();
    if (!sig) return false;

    #if OPENSSL_VERSION_NUMBER > 0x1000ffffL
    // sig_r and sig_s are deallocated by ECDSA_SIG_free(sig);
    BIGNUM *sig_r = BN_bin2bn(&vchSig[1],32,BN_new());
    BIGNUM *sig_s = BN_bin2bn(&vchSig[33],32,BN_new());
    if (!sig_r || !sig_s) return false;
    // copy and transfer ownership to sig
    ECDSA_SIG_set0(sig, sig_r, sig_s);
    #else
    BN_bin2bn(&vchSig[1],32,sig->r);
    BN_bin2bn(&vchSig[33],32,sig->s);
    #endif

    EC_KEY_free(pkey);
    pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
    if (nV >= 31)
    {
        SetCompressedPubKey();
        nV -= 4;
    }
    if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1)
    {
        fSet = true;
        ECDSA_SIG_free(sig);
        return true;
    }
    ECDSA_SIG_free(sig);
    return false;
}
Esempio n. 27
0
File: ecs_ossl.c Progetto: izick/eme
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 
		const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
{
	int     ok = 0, i;
	BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
	const BIGNUM *ckinv;
	BN_CTX     *ctx = NULL;
	const EC_GROUP   *group;
	ECDSA_SIG  *ret;
	ECDSA_DATA *ecdsa;
	const BIGNUM *priv_key;

	ecdsa    = ecdsa_check(eckey);
	group    = EC_KEY_get0_group(eckey);
	priv_key = EC_KEY_get0_private_key(eckey);
	
	if (group == NULL || priv_key == NULL || ecdsa == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
		return NULL;
	}

#ifdef OPENSSL_FIPS
	if (!fips_check_ec_prng(eckey))
		return NULL;
#endif

	ret = ECDSA_SIG_new();
	if (!ret)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	s = ret->s;

	if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
		(tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
		goto err;
	}

	if (!EC_GROUP_get_order(group, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
		goto err;
	}
	i = BN_num_bits(order);
	/* Need to truncate digest if it is too long: first truncate whole
	 * bytes.
	 */
	if (8 * dgst_len > i)
		dgst_len = (i + 7)/8;
	if (!BN_bin2bn(dgst, dgst_len, m))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
		goto err;
	}
	/* If still too long truncate remaining bits with a shift */
	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
		goto err;
	}
	do
	{
		if (in_kinv == NULL || in_r == NULL)
		{
			if (!ecdsa->meth->ecdsa_sign_setup(eckey, ctx,
								&kinv, &ret->r))
			{
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
				goto err;
			}
			ckinv = kinv;
		}
		else
		{
			ckinv  = in_kinv;
			if (BN_copy(ret->r, in_r) == NULL)
			{
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
				goto err;
			}
		}

		if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_add_quick(s, tmp, m, order))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_mul(s, s, ckinv, order, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (BN_is_zero(s))
		{
			/* if kinv and r have been supplied by the caller
			 * don't to generate new kinv and r values */
			if (in_kinv != NULL && in_r != NULL)
			{
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
				goto err;
			}
		}
		else
			/* s != 0 => we have a valid signature */
			break;
	}
	while (1);

	ok = 1;
err:
	if (!ok)
	{
		ECDSA_SIG_free(ret);
		ret = NULL;
	}
	if (ctx)
		BN_CTX_free(ctx);
	if (m)
		BN_clear_free(m);
	if (tmp)
		BN_clear_free(tmp);
	if (order)
		BN_free(order);
	if (kinv)
		BN_clear_free(kinv);
	return ret;
}
Esempio n. 28
0
// Verification functions
bool OSSLECDSA::verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const std::string mechanism)
{
	std::string lowerMechanism;
	lowerMechanism.resize(mechanism.size());
	std::transform(mechanism.begin(), mechanism.end(), lowerMechanism.begin(), tolower);

	if (lowerMechanism.compare("ecdsa"))
	{
		ERROR_MSG("Invalid mechanism supplied (%s)", mechanism.c_str());
		return false;
	}

	// Check if the private key is the right type
	if (!publicKey->isOfType(OSSLECPublicKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		return false;
	}

	OSSLECPublicKey* pk = (OSSLECPublicKey*) publicKey;
	EC_KEY* eckey = pk->getOSSLKey();

	if (eckey == NULL)
	{
		ERROR_MSG("Could not get the OpenSSL public key");

		return false;
	}

	// Perform the verify operation
	size_t len = pk->getOrderLength();
	if (len == 0)
		return false;
	if (signature.size() != 2 * len)
		return false;
	ECDSA_SIG* sig = ECDSA_SIG_new();
	if (sig == NULL)
		return false;
	if (sig->r != NULL)
		BN_clear_free(sig->r);
	const unsigned char *s = signature.const_byte_str();
	sig->r = BN_bin2bn(s, len, NULL);
	if (sig->s != NULL)
		BN_clear_free(sig->s);
	sig->s = BN_bin2bn(s + len, len, NULL);
	if (sig->r == NULL || sig->s == NULL)
	{
		ECDSA_SIG_free(sig);
		return false;
	}
	int ret = ECDSA_do_verify(originalData.const_byte_str(), originalData.size(), sig, eckey);
	if (ret != 1)
	{
		if (ret < 0)
			ERROR_MSG("ECDSA verify failed (0x%08X)", ERR_get_error());

		ECDSA_SIG_free(sig);
		return false;
	}

	ECDSA_SIG_free(sig);
	return true;
}
Esempio n. 29
0
int ssh_ecdsa_verify(EC_KEY *key, ssh_keytype keytype,
                     u_char *signature, u_int signaturelen,
                     u_char *data, u_int datalen)
{
	ECDSA_SIG *sig;
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
	unsigned int len, dlen;
	int ret, nid = NID_undef;
	char *ptr;

	OpenSSL_add_all_digests();

	if (key == NULL) {
		return -2;
	}

	ptr = signature;

	len = get_uint32_MSBfirst(ptr);
	ptr += 4;
	if (strncmp(get_ssh_keytype_name(keytype), ptr, len) != 0) {
		return -3;
	}
	ptr += len;

	len = get_uint32_MSBfirst(ptr);
	ptr += 4;
	sigblob = ptr;
	ptr += len;

	/* parse signature */
	if ((sig = ECDSA_SIG_new()) == NULL)
		return -4;
	if ((sig->r = BN_new()) == NULL)
		return -5;
	if ((sig->s = BN_new()) == NULL)
		return -6;

	buffer_get_bignum2(&sigblob, sig->r);
	buffer_get_bignum2(&sigblob, sig->s);
	if (sigblob != ptr) {
		return -7;
	}

	/* hash the data */
	nid = keytype_to_hash_nid(keytype);
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		return -8;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = ECDSA_do_verify(digest, dlen, sig, key);
	memset(digest, 'd', sizeof(digest));

	ECDSA_SIG_free(sig);

	return ret;
}
Esempio n. 30
0
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 
		const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
{
	int     ok = 0;
	BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
	const BIGNUM *ckinv;
	BN_CTX     *ctx = NULL;
	const EC_GROUP   *group;
	ECDSA_SIG  *ret;
	ECDSA_DATA *ecdsa;
	const BIGNUM *priv_key;

	ecdsa    = ecdsa_check(eckey);
	group    = EC_KEY_get0_group(eckey);
	priv_key = EC_KEY_get0_private_key(eckey);
	
	if (group == NULL || priv_key == NULL || ecdsa == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
		return NULL;
	}

	ret = ECDSA_SIG_new();
	if (!ret)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	s = ret->s;

	if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
		(tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
		goto err;
	}

	if (!EC_GROUP_get_order(group, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
		goto err;
	}
	if (8 * dgst_len > BN_num_bits(order))
	{
		/* XXX
		 * 
		 * Should provide for optional hash truncation:
		 * Keep the BN_num_bits(order) leftmost bits of dgst
		 * (see March 2006 FIPS 186-3 draft, which has a few
		 * confusing errors in this part though)
		 */

		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
			ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
		goto err;
	}

	if (!BN_bin2bn(dgst, dgst_len, m))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
		goto err;
	}
	do
	{
		if (in_kinv == NULL || in_r == NULL)
		{
			if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r))
			{
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
				goto err;
			}
			ckinv = kinv;
		}
		else
		{
			ckinv  = in_kinv;
			if (BN_copy(ret->r, in_r) == NULL)
			{
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
				goto err;
			}
		}

		if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_add_quick(s, tmp, m, order))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_mul(s, s, ckinv, order, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (BN_is_zero(s))
		{
			/* if kinv and r have been supplied by the caller
			 * don't to generate new kinv and r values */
			if (in_kinv != NULL && in_r != NULL)
			{
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
				goto err;
			}
		}
		else
			/* s != 0 => we have a valid signature */
			break;
	}
	while (1);

	ok = 1;
err:
	if (!ok)
	{
		ECDSA_SIG_free(ret);
		ret = NULL;
	}
	if (ctx)
		BN_CTX_free(ctx);
	if (m)
		BN_clear_free(m);
	if (tmp)
		BN_clear_free(tmp);
	if (order)
		BN_free(order);
	if (kinv)
		BN_clear_free(kinv);
	return ret;
}