u2fs_rc verify_ECDSA(const unsigned char *dgst, int dgst_len, const u2fs_ECDSA_t * sig, u2fs_EC_KEY_t * eckey) { if (dgst == NULL || dgst_len == 0 || sig == NULL || eckey == NULL) return U2FS_MEMORY_ERROR; int rc = ECDSA_do_verify(dgst, dgst_len, (ECDSA_SIG *) sig, (EC_KEY *) eckey); if (rc != 1) { if (rc == -1) { if (debug) { unsigned long err = 0; err = ERR_get_error(); fprintf(stderr, "Error: %s, %s, %s\n", ERR_lib_error_string(err), ERR_func_error_string(err), ERR_reason_error_string(err)); } return U2FS_CRYPTO_ERROR; } else { return U2FS_SIGNATURE_ERROR; } } return U2FS_OK; }
/* 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); }
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; }
int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len, const uint8_t *sig, size_t sig_len, const EC_KEY *eckey) { ECDSA_SIG *s; int ret = 0; uint8_t *der = NULL; /* Decode the ECDSA signature. */ s = ECDSA_SIG_from_bytes(sig, sig_len); if (s == NULL) { goto err; } /* Defend against potential laxness in the DER parser. */ size_t der_len; if (!ECDSA_SIG_to_bytes(&der, &der_len, s) || der_len != sig_len || OPENSSL_memcmp(sig, der, sig_len) != 0) { /* This should never happen. crypto/bytestring is strictly DER. */ OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR); goto err; } ret = ECDSA_do_verify(digest, digest_len, s, eckey); err: OPENSSL_free(der); ECDSA_SIG_free(s); return ret; }
int main() { uint8_t pub_bytes[33] = { 0x02, 0x82, 0x00, 0x6e, 0x93, 0x98, 0xa6, 0x98, 0x6e, 0xda, 0x61, 0xfe, 0x91, 0x67, 0x4c, 0x3a, 0x10, 0x8c, 0x39, 0x94, 0x75, 0xbf, 0x1e, 0x73, 0x8f, 0x19, 0xdf, 0xc2, 0xdb, 0x11, 0xdb, 0x1d, 0x28 }; uint8_t der_bytes[] = { 0x30, 0x44, 0x02, 0x20, 0x2b, 0x2b, 0x52, 0x9b, 0xdb, 0xdc, 0x93, 0xe7, 0x8a, 0xf7, 0xe0, 0x02, 0x28, 0xb1, 0x79, 0x91, 0x8b, 0x03, 0x2d, 0x76, 0x90, 0x2f, 0x74, 0xef, 0x45, 0x44, 0x26, 0xf7, 0xd0, 0x6c, 0xd0, 0xf9, 0x02, 0x20, 0x62, 0xdd, 0xc7, 0x64, 0x51, 0xcd, 0x04, 0xcb, 0x56, 0x7c, 0xa5, 0xc5, 0xe0, 0x47, 0xe8, 0xac, 0x41, 0xd3, 0xd4, 0xcf, 0x7c, 0xb9, 0x24, 0x34, 0xd5, 0x5c, 0xb4, 0x86, 0xcc, 0xcf, 0x6a, 0xf2 }; const char message[] = "This is a very confidential message\n"; EC_KEY *key; const uint8_t *der_bytes_copy; ECDSA_SIG *signature; uint8_t digest[32]; int verified; key = bbp_ec_new_pubkey(pub_bytes, sizeof(pub_bytes)); if (!key) { puts("Unable to create keypair"); return -1; } der_bytes_copy = der_bytes; signature = d2i_ECDSA_SIG(NULL, &der_bytes_copy, sizeof(der_bytes)); printf("r: %s\n", BN_bn2hex(signature->r)); printf("s: %s\n", BN_bn2hex(signature->s)); bbp_sha256(digest, (uint8_t *)message, strlen(message)); bbp_print_hex("digest", digest, 32); verified = ECDSA_do_verify(digest, sizeof(digest), signature, key); switch (verified) { case 1: puts("verified"); break; case 0: puts("not verified"); break; case -1: puts("library error"); break; } ECDSA_SIG_free(signature); EC_KEY_free(key); return 0; }
bool BackendOpenSsl::verify_data(const ecdsa256::PublicKey& key, const ByteBuffer& data, const EcdsaSignature& sig) { auto digest = calculate_digest(data); auto pub = internal_public_key(key); openssl::Signature signature(sig); return (ECDSA_do_verify(digest.data(), digest.size(), signature, pub) == 1); }
static void bench_openssl_ecdsa_verify (void *p) { const struct openssl_ecdsa_ctx *ctx = p; if (ECDSA_do_verify (ctx->digest, ctx->digest_length, ctx->signature, ctx->key) != 1) die ("Openssl ECDSA_do_verify failed.\n"); }
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; }
bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr) { EC_KEY * eckey = NULL; byte rgbDigest[EVP_MAX_MD_SIZE]; unsigned int cbDigest = sizeof(rgbDigest); const EVP_MD * digest; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pSigner->m_allocContext; #endif cn_cbor * p = NULL; ECDSA_SIG sig = { NULL, NULL }; int cbR; cn_cbor * pSig; size_t cbSignature; eckey = ECKey_From(pKey, &cbR, perr); if (eckey == NULL) { errorReturn: if (sig.r != NULL) BN_free(sig.r); if (sig.s != NULL) BN_free(sig.s); if (p != NULL) CN_CBOR_FREE(p, context); if (eckey != NULL) EC_KEY_free(eckey); return false; } switch (cbitDigest) { case 256: digest = EVP_sha256(); break; case 512: digest = EVP_sha512(); break; case 384: digest = EVP_sha384(); break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, NULL); pSig = _COSE_arrayget_int(pSigner, index); CHECK_CONDITION(pSig != NULL, CN_CBOR_ERR_INVALID_PARAMETER); cbSignature = pSig->length; CHECK_CONDITION(cbSignature / 2 == cbR, COSE_ERR_INVALID_PARAMETER); sig.r = BN_bin2bn(pSig->v.bytes,(int) cbSignature/2, NULL); sig.s = BN_bin2bn(pSig->v.bytes+cbSignature/2, (int) cbSignature/2, NULL); CHECK_CONDITION(ECDSA_do_verify(rgbDigest, cbDigest, &sig, eckey) == 1, COSE_ERR_CRYPTO_FAIL); BN_free(sig.r); BN_free(sig.s); if (eckey != NULL) EC_KEY_free(eckey); return true; }
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); }
/* 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); }
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; }
int main(int argc, char **argv) { int ok; EC_KEY *ec_key; ECDSA_SIG *sig; unsigned char dgst[32]; ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1); OPENSSL_assert(ec_key); ok = EC_KEY_generate_key(ec_key); OPENSSL_assert(ok); sig = ECDSA_do_sign(dgst, 32, ec_key); ok = ECDSA_do_verify(dgst, 32, sig, ec_key); printf("ok = %d\n", ok); return 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; }
/*- * This function hijacks the RNG to feed it the chosen ECDSA key and nonce. * The ECDSA KATs are from: * - the X9.62 draft (4) * - NIST CAVP (720) * * It uses the low-level ECDSA_sign_setup instead of EVP to control the RNG. * NB: This is not how applications should use ECDSA; this is only for testing. * * Tests the library can successfully: * - generate public keys that matches those KATs * - create ECDSA signatures that match those KATs * - accept those signatures as valid */ static int x9_62_tests(int n) { int nid, md_nid, ret = 0; const char *r_in = NULL, *s_in = NULL, *tbs = NULL; unsigned char *pbuf = NULL, *qbuf = NULL, *message = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dgst_len = 0; long q_len, msg_len = 0; size_t p_len; EVP_MD_CTX *mctx = NULL; EC_KEY *key = NULL; ECDSA_SIG *signature = NULL; BIGNUM *r = NULL, *s = NULL; BIGNUM *kinv = NULL, *rp = NULL; const BIGNUM *sig_r = NULL, *sig_s = NULL; nid = ecdsa_cavs_kats[n].nid; md_nid = ecdsa_cavs_kats[n].md_nid; r_in = ecdsa_cavs_kats[n].r; s_in = ecdsa_cavs_kats[n].s; tbs = ecdsa_cavs_kats[n].msg; numbers[0] = ecdsa_cavs_kats[n].d; numbers[1] = ecdsa_cavs_kats[n].k; TEST_info("ECDSA KATs for curve %s", OBJ_nid2sn(nid)); if (!TEST_ptr(mctx = EVP_MD_CTX_new()) /* get the message digest */ || !TEST_ptr(message = OPENSSL_hexstr2buf(tbs, &msg_len)) || !TEST_true(EVP_DigestInit_ex(mctx, EVP_get_digestbynid(md_nid), NULL)) || !TEST_true(EVP_DigestUpdate(mctx, message, msg_len)) || !TEST_true(EVP_DigestFinal_ex(mctx, digest, &dgst_len)) /* create the key */ || !TEST_ptr(key = EC_KEY_new_by_curve_name(nid)) /* load KAT variables */ || !TEST_ptr(r = BN_new()) || !TEST_ptr(s = BN_new()) || !TEST_true(BN_hex2bn(&r, r_in)) || !TEST_true(BN_hex2bn(&s, s_in)) /* swap the RNG source */ || !TEST_true(change_rand())) goto err; /* public key must match KAT */ use_fake = 1; if (!TEST_true(EC_KEY_generate_key(key)) || !TEST_true(p_len = EC_KEY_key2buf(key, POINT_CONVERSION_UNCOMPRESSED, &pbuf, NULL)) || !TEST_ptr(qbuf = OPENSSL_hexstr2buf(ecdsa_cavs_kats[n].Q, &q_len)) || !TEST_int_eq(q_len, p_len) || !TEST_mem_eq(qbuf, q_len, pbuf, p_len)) goto err; /* create the signature via ECDSA_sign_setup to avoid use of ECDSA nonces */ use_fake = 1; if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp)) || !TEST_ptr(signature = ECDSA_do_sign_ex(digest, dgst_len, kinv, rp, key)) /* verify the signature */ || !TEST_int_eq(ECDSA_do_verify(digest, dgst_len, signature, key), 1)) goto err; /* compare the created signature with the expected signature */ ECDSA_SIG_get0(signature, &sig_r, &sig_s); if (!TEST_BN_eq(sig_r, r) || !TEST_BN_eq(sig_s, s)) goto err; ret = 1; err: /* restore the RNG source */ if (!TEST_true(restore_rand())) ret = 0; OPENSSL_free(message); OPENSSL_free(pbuf); OPENSSL_free(qbuf); EC_KEY_free(key); ECDSA_SIG_free(signature); BN_free(r); BN_free(s); EVP_MD_CTX_free(mctx); BN_clear_free(kinv); BN_clear_free(rp); return ret; }
// 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; }
/* Verify the signature on this transaction using the public key * prev_tx->dest_pubkey. The return value is: * 1 for successful verification; * 0 for failed verification; * -1 for any runtime error. */ int transaction_verify(struct transaction *tx, const struct transaction *prev_tx) { unsigned char uint32_buf[4]; SHA256_CTX sha; hash_output h; EC_KEY *pubkey; ECDSA_SIG *sig; BIGNUM *x, *y; int v, rc; pubkey = NULL; sig = NULL; x = NULL; y = NULL; SHA256_Init(&sha); serialize_uint32(uint32_buf, tx->height); SHA256_Update(&sha, uint32_buf, sizeof(uint32_buf)); SHA256_Update(&sha, tx->prev_transaction_hash, sizeof(tx->prev_transaction_hash)); SHA256_Update(&sha, tx->dest_pubkey.x, sizeof(tx->dest_pubkey.x)); SHA256_Update(&sha, tx->dest_pubkey.y, sizeof(tx->dest_pubkey.y)); SHA256_Final(h, &sha); x = BN_bin2bn(prev_tx->dest_pubkey.x, sizeof(prev_tx->dest_pubkey.x), NULL); if (x == NULL) goto err; y = BN_bin2bn(prev_tx->dest_pubkey.y, sizeof(prev_tx->dest_pubkey.y), NULL); if (y == NULL) goto err; pubkey = EC_KEY_new_by_curve_name(EC_GROUP_NID); if (pubkey == NULL) goto err; rc = EC_KEY_set_public_key_affine_coordinates(pubkey, x, y); if (rc != 1) { EC_KEY_free(pubkey); BN_free(x); BN_free(y); return 0; } BN_free(x); x = NULL; BN_free(y); y = NULL; sig = ECDSA_SIG_new(); if (sig == NULL) goto err; sig->r = BN_bin2bn(tx->src_signature.r, sizeof(tx->src_signature.r), sig->r); if (sig->r == NULL) goto err; sig->s = BN_bin2bn(tx->src_signature.s, sizeof(tx->src_signature.s), sig->s); if (sig->s == NULL) goto err; v = ECDSA_do_verify(h, sizeof(h), sig, pubkey); EC_KEY_free(pubkey); ECDSA_SIG_free(sig); return v; err: if (pubkey != NULL) EC_KEY_free(pubkey); if (sig != NULL) ECDSA_SIG_free(sig); if (x != NULL) BN_free(x); if (y != NULL) BN_free(y); return -1; }
/* some tests from the X9.62 draft */ static int x9_62_test_internal(int nid, const char *r_in, const char *s_in) { int ret = 0; const char message[] = "abc"; unsigned char digest[20]; unsigned int dgst_len = 0; EVP_MD_CTX *md_ctx; EC_KEY *key = NULL; ECDSA_SIG *signature = NULL; BIGNUM *r = NULL, *s = NULL; BIGNUM *kinv = NULL, *rp = NULL; const BIGNUM *sig_r, *sig_s; if (!TEST_ptr(md_ctx = EVP_MD_CTX_new())) goto x962_int_err; /* get the message digest */ if (!TEST_true(EVP_DigestInit(md_ctx, EVP_sha1())) || !TEST_true(EVP_DigestUpdate(md_ctx, (const void *)message, 3)) || !TEST_true(EVP_DigestFinal(md_ctx, digest, &dgst_len))) goto x962_int_err; TEST_info("testing %s", OBJ_nid2sn(nid)); /* create the key */ if (!TEST_ptr(key = EC_KEY_new_by_curve_name(nid))) goto x962_int_err; use_fake = 1; if (!TEST_true(EC_KEY_generate_key(key))) goto x962_int_err; /* create the signature */ use_fake = 1; /* Use ECDSA_sign_setup to avoid use of ECDSA nonces */ if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp))) goto x962_int_err; if (!TEST_ptr(signature = ECDSA_do_sign_ex(digest, 20, kinv, rp, key))) goto x962_int_err; /* compare the created signature with the expected signature */ if (!TEST_ptr(r = BN_new()) || !TEST_ptr(s = BN_new())) goto x962_int_err; if (!TEST_true(BN_dec2bn(&r, r_in)) || !TEST_true(BN_dec2bn(&s, s_in))) goto x962_int_err; ECDSA_SIG_get0(signature, &sig_r, &sig_s); if (!TEST_BN_eq(sig_r, r) || !TEST_BN_eq(sig_s, s)) goto x962_int_err; /* verify the signature */ if (!TEST_int_eq(ECDSA_do_verify(digest, 20, signature, key), 1)) goto x962_int_err; ret = 1; x962_int_err: EC_KEY_free(key); ECDSA_SIG_free(signature); BN_free(r); BN_free(s); EVP_MD_CTX_free(md_ctx); BN_clear_free(kinv); BN_clear_free(rp); return ret; }
/* some tests from the X9.62 draft */ int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in) { int ret = 0; const char message[] = "abc"; unsigned char digest[20]; unsigned int dgst_len = 0; EVP_MD_CTX md_ctx; EC_KEY *key = NULL; ECDSA_SIG *signature = NULL; BIGNUM *r = NULL, *s = NULL; EVP_MD_CTX_init(&md_ctx); /* get the message digest */ EVP_DigestInit(&md_ctx, EVP_ecdsa()); EVP_DigestUpdate(&md_ctx, (const void *)message, 3); EVP_DigestFinal(&md_ctx, digest, &dgst_len); BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid)); /* create the key */ if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) goto x962_int_err; if (!EC_KEY_generate_key(key)) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); /* create the signature */ signature = ECDSA_do_sign(digest, 20, key); if (signature == NULL) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); /* compare the created signature with the expected signature */ if ((r = BN_new()) == NULL || (s = BN_new()) == NULL) goto x962_int_err; if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in)) goto x962_int_err; if (BN_cmp(signature->r, r) || BN_cmp(signature->s, s)) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); /* verify the signature */ if (ECDSA_do_verify(digest, 20, signature, key) != 1) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); ret = 1; x962_int_err: if (!ret) BIO_printf(out, " failed\n"); if (key) EC_KEY_free(key); if (signature) ECDSA_SIG_free(signature); if (r) BN_free(r); if (s) BN_free(s); EVP_MD_CTX_cleanup(&md_ctx); return ret; }
int main(int argc, char **argv) { char *prog = basename(argv[0]); EC_GROUP *ec_group = NULL; EC_KEY *ec_key = NULL; BN_CTX *ctx = BN_CTX_new(); const char *id = "*****@*****.**"; unsigned char za[32]; BIGNUM *k = NULL; BIGNUM *x = NULL; ECDSA_SIG *sig = NULL; unsigned char dgst[20] = "abc"; int ret; if (!(ec_group = EC_GROUP_new_by_curve_name(NID_sm2t257v1))) { fprintf(stderr, "%s: no such curve\n", prog); return -1; } if (!(ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1))) { fprintf(stderr, "%s: %s %d\n", prog, __FUNCTION__, __LINE__); return -1; } if (!EC_KEY_generate_key(ec_key)) { ERR_print_errors_fp(stderr); return -1; } if ((ret = EC_KEY_compute_za(za, EVP_sha256(), id, strlen(id), ec_key)) < 0) { ERR_print_errors_fp(stderr); return -1; } printf("Za length = %d\n", ret); if (!(sig = ECDSA_do_sign(dgst, sizeof(dgst), ec_key))) { ERR_print_errors_fp(stderr); return -1; } if ((ret = ECDSA_do_verify(dgst, sizeof(dgst), sig, ec_key)) < 0) { ERR_print_errors_fp(stderr); return -1; } printf("result = %d\n", ret); if (!ECDSA_sign_setup(ec_key, ctx, &k, &x)) { ERR_print_errors_fp(stderr); return -1; } if (!(sig = ECDSA_do_sign_ex(dgst, sizeof(dgst), k, x, ec_key))) { ERR_print_errors_fp(stderr); return -1; } if ((ret = ECDSA_do_verify(dgst, sizeof(dgst), sig, ec_key)) < 0) { ERR_print_errors_fp(stderr); return -1; } printf("result = %d\n", ret); return 0; }
// Verification functions bool OSSLECDSA::verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* /* param = NULL */, const size_t /* paramLen = 0 */) { if (mechanism != AsymMech::ECDSA) { ERROR_MSG("Invalid mechanism supplied (%i)", mechanism); 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; } // Use the OpenSSL implementation and not any engine ECDSA_set_method(eckey, ECDSA_OpenSSL()); // Perform the verify operation size_t len = pk->getOrderLength(); if (len == 0) { ERROR_MSG("Could not get the order length"); return false; } if (signature.size() != 2 * len) { ERROR_MSG("Invalid buffer length"); return false; } ECDSA_SIG* sig = ECDSA_SIG_new(); if (sig == NULL) { ERROR_MSG("Could not create an ECDSA_SIG object"); 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) { ERROR_MSG("Could not add data to the ECDSA_SIG object"); 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; }
/* ARGSUSED */ int ssh_ecdsa_verify(const struct sshkey *key, const u_char *signature, size_t signaturelen, const u_char *data, size_t datalen, u_int compat) { ECDSA_SIG *sig = NULL; int hash_alg; u_char digest[SSH_DIGEST_MAX_LENGTH]; size_t dlen; int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL, *sigbuf = NULL; char *ktype = NULL; if (key == NULL || key->ecdsa == NULL || sshkey_type_plain(key->type) != KEY_ECDSA) return SSH_ERR_INVALID_ARGUMENT; if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || (dlen = ssh_digest_bytes(hash_alg)) == 0) return SSH_ERR_INTERNAL_ERROR; /* fetch signature */ if ((b = sshbuf_from(signature, signaturelen)) == NULL) return SSH_ERR_ALLOC_FAIL; if (sshbuf_get_cstring(b, &ktype, NULL) != 0 || sshbuf_froms(b, &sigbuf) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if (strcmp(sshkey_ssh_name_plain(key), ktype) != 0) { ret = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (sshbuf_len(b) != 0) { ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; goto out; } /* parse signature */ if ((sig = ECDSA_SIG_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 || sshbuf_get_bignum2(sigbuf, sig->s) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if (sshbuf_len(sigbuf) != 0) { ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; goto out; } if ((ret = ssh_digest_memory(hash_alg, data, datalen, digest, sizeof(digest))) != 0) goto out; switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) { case 1: ret = 0; break; case 0: ret = SSH_ERR_SIGNATURE_INVALID; goto out; default: ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } out: explicit_bzero(digest, sizeof(digest)); if (sigbuf != NULL) sshbuf_free(sigbuf); if (b != NULL) sshbuf_free(b); if (sig != NULL) ECDSA_SIG_free(sig); free(ktype); return ret; }
int ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, const u_char *data, u_int datalen) { ECDSA_SIG *sig; int hash_alg; u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob; u_int len, dlen; int rlen, ret; Buffer b, bb; char *ktype; if (key == NULL || key_type_plain(key->type) != KEY_ECDSA || key->ecdsa == NULL) { error("%s: no ECDSA key", __func__); return -1; } /* fetch signature */ buffer_init(&b); buffer_append(&b, signature, signaturelen); ktype = buffer_get_string(&b, NULL); if (strcmp(key_ssh_name_plain(key), ktype) != 0) { error("%s: cannot handle type %s", __func__, ktype); buffer_free(&b); free(ktype); return -1; } free(ktype); sigblob = buffer_get_string(&b, &len); rlen = buffer_len(&b); buffer_free(&b); if (rlen != 0) { error("%s: remaining bytes in signature %d", __func__, rlen); free(sigblob); return -1; } /* parse signature */ if ((sig = ECDSA_SIG_new()) == NULL) fatal("%s: ECDSA_SIG_new failed", __func__); buffer_init(&bb); buffer_append(&bb, sigblob, len); buffer_get_bignum2(&bb, sig->r); buffer_get_bignum2(&bb, sig->s); if (buffer_len(&bb) != 0) fatal("%s: remaining bytes in inner sigblob", __func__); buffer_free(&bb); /* clean up */ explicit_bzero(sigblob, len); free(sigblob); /* hash the data */ hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid); if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { error("%s: bad hash algorithm %d", __func__, hash_alg); return -1; } if (ssh_digest_memory(hash_alg, data, datalen, digest, sizeof(digest)) != 0) { error("%s: digest_memory failed", __func__); return -1; } ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); explicit_bzero(digest, sizeof(digest)); ECDSA_SIG_free(sig); debug("%s: signature %s", __func__, ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); return ret; }
void ecdsa_sigverify(val_context_t * ctx, const u_char *data, size_t data_len, const val_dnskey_rdata_t * dnskey, const val_rrsig_rdata_t * rrsig, val_astatus_t * key_status, val_astatus_t * sig_status) { char buf[1028]; size_t buflen = 1024; u_char sha_hash[MAX_DIGEST_LENGTH]; EC_KEY *eckey = NULL; BIGNUM *bn_x = NULL; BIGNUM *bn_y = NULL; ECDSA_SIG *ecdsa_sig; size_t hashlen = 0; ecdsa_sig = ECDSA_SIG_new(); memset(sha_hash, 0, sizeof(sha_hash)); val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): parsing the public key..."); if (rrsig->algorithm == ALG_ECDSAP256SHA256) { hashlen = SHA256_DIGEST_LENGTH; SHA256(data, data_len, sha_hash); eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); /* P-256 */ } else if (rrsig->algorithm == ALG_ECDSAP384SHA384) { hashlen = SHA384_DIGEST_LENGTH; SHA384(data, data_len, sha_hash); eckey = EC_KEY_new_by_curve_name(NID_secp384r1); /* P-384 */ } if (eckey == NULL) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): could not create key for ECDSA group."); *key_status = VAL_AC_INVALID_KEY; goto err; }; /* * contruct an EC_POINT from the "Q" field in the * dnskey->public_key, dnskey->public_key_len */ if (dnskey->public_key_len != 2*hashlen) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): dnskey length does not match expected size."); *key_status = VAL_AC_INVALID_KEY; goto err; } bn_x = BN_bin2bn(dnskey->public_key, hashlen, NULL); bn_y = BN_bin2bn(&dnskey->public_key[hashlen], hashlen, NULL); if (1 != EC_KEY_set_public_key_affine_coordinates(eckey, bn_x, bn_y)) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): Error associating ECSA structure with key."); *key_status = VAL_AC_INVALID_KEY; goto err; } val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): SHA hash = %s", get_hex_string(sha_hash, hashlen, buf, buflen)); val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): verifying ECDSA signature..."); /* * contruct ECDSA signature from the "r" and "s" fileds in * rrsig->signature, rrsig->signature_len */ if (rrsig->signature_len != 2*hashlen) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): Signature length does not match expected size."); *sig_status = VAL_AC_RRSIG_VERIFY_FAILED; goto err; } ECDSA_SIG_set0(ecdsa_sig, BN_bin2bn(rrsig->signature, hashlen, NULL), BN_bin2bn(&rrsig->signature[hashlen], hashlen, NULL)); if (ECDSA_do_verify(sha_hash, hashlen, ecdsa_sig, eckey) == 1) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned SUCCESS"); *sig_status = VAL_AC_RRSIG_VERIFIED; } else { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned FAILURE"); *sig_status = VAL_AC_RRSIG_VERIFY_FAILED; } /* Free all structures allocated */ err: if (ecdsa_sig) ECDSA_SIG_free(ecdsa_sig); if (bn_x) BN_free(bn_x); if (bn_y) BN_free(bn_y); if (eckey) EC_KEY_free(eckey); return; }
int signMessageWithPem(char *message, char *pem, char **signature) { unsigned int meslen = strlen(message); unsigned char *messagebytes = calloc(meslen, sizeof(unsigned char)); int derSigLen = 0; int i = 0; memcpy(messagebytes, message, meslen); EC_KEY *key = NULL; BIO *in = NULL; unsigned char *buffer = NULL; char *sha256ofMsg = calloc(SHA256_HEX_STRING, sizeof(char)); unsigned char *outBytesOfsha256ofMsg = calloc(SHA256_STRING, sizeof(unsigned char)); digestOfBytes(messagebytes, &sha256ofMsg, "sha256", meslen); sha256ofMsg[64] = '\0'; createDataWithHexString(sha256ofMsg, &outBytesOfsha256ofMsg); in = BIO_new(BIO_s_mem()); BIO_puts(in, pem); key = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL); if(key == NULL) { return ERROR; } while(derSigLen < 70 && i < 10) { i++; ECDSA_SIG *sig = ECDSA_do_sign((const unsigned char*)outBytesOfsha256ofMsg, SHA256_DIGEST_LENGTH, key); int verify = ECDSA_do_verify((const unsigned char*)outBytesOfsha256ofMsg, SHA256_DIGEST_LENGTH, sig, key); if(verify != 1) { return ERROR; } int buflen = ECDSA_size(key); buffer = OPENSSL_malloc(buflen); derSigLen = i2d_ECDSA_SIG(sig, &buffer); } if(i == 10) return ERROR; char *hexData = calloc(derSigLen, sizeof(char)); memcpy(hexData, buffer-derSigLen, derSigLen); char *hexString = calloc(derSigLen*2+1, sizeof(char)); toHexString(hexData, derSigLen, &hexString); hexString[derSigLen * 2] = '\0'; memcpy(*signature, hexString, (derSigLen*2)+ 1); EC_KEY_free(key); BIO_free_all(in); free(messagebytes); free(sha256ofMsg); free(outBytesOfsha256ofMsg); free(hexData); free(hexString); return NOERROR; }
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; }
/* some tests from the X9.62 draft */ int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in) { int ret = 0; const char message[] = "abc"; unsigned char digest[20]; unsigned int dgst_len = 0; EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); EC_KEY *key = NULL; ECDSA_SIG *signature = NULL; BIGNUM *r = NULL, *s = NULL; BIGNUM *kinv = NULL, *rp = NULL; BIGNUM *sig_r, *sig_s; if (md_ctx == NULL) goto x962_int_err; /* get the message digest */ if (!EVP_DigestInit(md_ctx, EVP_sha1()) || !EVP_DigestUpdate(md_ctx, (const void *)message, 3) || !EVP_DigestFinal(md_ctx, digest, &dgst_len)) goto x962_int_err; BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid)); /* create the key */ if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) goto x962_int_err; use_fake = 1; if (!EC_KEY_generate_key(key)) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); /* create the signature */ use_fake = 1; /* Use ECDSA_sign_setup to avoid use of ECDSA nonces */ if (!ECDSA_sign_setup(key, NULL, &kinv, &rp)) goto x962_int_err; signature = ECDSA_do_sign_ex(digest, 20, kinv, rp, key); if (signature == NULL) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); /* compare the created signature with the expected signature */ if ((r = BN_new()) == NULL || (s = BN_new()) == NULL) goto x962_int_err; if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in)) goto x962_int_err; ECDSA_SIG_get0(&sig_r, &sig_s, signature); if (BN_cmp(sig_r, r) || BN_cmp(sig_s, s)) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); /* verify the signature */ if (ECDSA_do_verify(digest, 20, signature, key) != 1) goto x962_int_err; BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); ret = 1; x962_int_err: if (!ret) BIO_printf(out, " failed\n"); EC_KEY_free(key); ECDSA_SIG_free(signature); BN_free(r); BN_free(s); EVP_MD_CTX_free(md_ctx); BN_clear_free(kinv); BN_clear_free(rp); return ret; }
TACK_RETVAL tackOpenSSLVerifyFunc(uint8_t publicKey[TACK_PUBKEY_LENGTH], uint8_t signature[TACK_SIG_LENGTH], uint8_t* data, uint32_t dataLen) { uint8_t pubKeyBuf[TACK_PUBKEY_LENGTH + 1]; uint8_t hashBuf[TACK_HASH_LENGTH]; EC_KEY* ec_key = 0; EC_GROUP* ec_group = 0; EC_POINT* ec_point = 0; ECDSA_SIG* ecdsa_sig = 0; SHA256_CTX sha256_ctx; TACK_RETVAL retval = TACK_ERR_CRYPTO_FUNC; int ret = 0; /* Prepare the public key to be passed into OpenSSL */ pubKeyBuf[0] = 0x04; memcpy(pubKeyBuf+1, publicKey, TACK_PUBKEY_LENGTH); /* Create EC_KEY from raw bytes */ if ((ec_key = EC_KEY_new_by_curve_name(OBJ_txt2nid("prime256v1"))) == 0) goto end; if ((ec_group = EC_GROUP_new_by_curve_name(OBJ_txt2nid("prime256v1"))) == 0) goto end; if ((ec_point = EC_POINT_new(ec_group)) == 0) goto end; if (EC_POINT_oct2point(ec_group, ec_point, pubKeyBuf, 65, 0) == 0) { retval = TACK_ERR_BAD_PUBKEY; goto end; } if (EC_KEY_set_public_key(ec_key, ec_point) == 0) goto end; /* Create ECDSA_SIG from raw bytes */ if ((ecdsa_sig = ECDSA_SIG_new()) == 0) goto end; if (BN_bin2bn(signature, TACK_SIG_LENGTH/2, ecdsa_sig->r) == 0) goto end; if (BN_bin2bn(signature + TACK_SIG_LENGTH/2, TACK_SIG_LENGTH/2, ecdsa_sig->s) == 0) goto end; /* Hash the input data */ SHA256_Init(&sha256_ctx); SHA256_Update(&sha256_ctx, data, dataLen); SHA256_Final(hashBuf, &sha256_ctx); /* Verify the signature */ ret = ECDSA_do_verify(hashBuf, TACK_HASH_LENGTH, ecdsa_sig, ec_key); if (ret == 1) retval = TACK_OK; else if (ret == 0) retval = TACK_ERR_BAD_SIGNATURE; else if (ret == -1) retval = TACK_ERR_CRYPTO_FUNC; end: if (ec_key) EC_KEY_free(ec_key); if (ec_group) EC_GROUP_free(ec_group); if (ec_point) EC_POINT_free(ec_point); if (ecdsa_sig) ECDSA_SIG_free(ecdsa_sig); return(retval); }
int ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, const u_char *data, u_int datalen) { ECDSA_SIG *sig; const EVP_MD *evp_md; EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE], *sigblob; u_int len, dlen; int rlen, ret; Buffer b, bb; char *ktype; if (key == NULL || key->ecdsa == NULL || (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { error("%s: no ECDSA key", __func__); return -1; } evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid); /* fetch signature */ buffer_init(&b); buffer_append(&b, signature, signaturelen); ktype = buffer_get_string(&b, NULL); if (strcmp(key_ssh_name_plain(key), ktype) != 0) { error("%s: cannot handle type %s", __func__, ktype); buffer_free(&b); free(ktype); return -1; } free(ktype); sigblob = buffer_get_string(&b, &len); rlen = buffer_len(&b); buffer_free(&b); if (rlen != 0) { error("%s: remaining bytes in signature %d", __func__, rlen); free(sigblob); return -1; } /* parse signature */ if ((sig = ECDSA_SIG_new()) == NULL) fatal("%s: ECDSA_SIG_new failed", __func__); if ((sig->r = BN_new()) == NULL || (sig->s = BN_new()) == NULL) fatal("%s: BN_new failed", __func__); buffer_init(&bb); buffer_append(&bb, sigblob, len); buffer_get_bignum2(&bb, sig->r); buffer_get_bignum2(&bb, sig->s); if (buffer_len(&bb) != 0) fatal("%s: remaining bytes in inner sigblob", __func__); buffer_free(&bb); /* clean up */ memset(sigblob, 0, len); free(sigblob); /* hash the data */ EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); memset(digest, 'd', sizeof(digest)); ECDSA_SIG_free(sig); debug("%s: signature %s", __func__, ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); return ret; }