ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) { return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey); }
/*- * 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; }
ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, EC_KEY *key) { return ECDSA_do_sign_ex(digest, digest_len, NULL, NULL, key); }
/* 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; BIGNUM *kinv = NULL, *rp = NULL; EVP_MD_CTX_init(&md_ctx); /* get the message digest */ if (!EVP_DigestInit(&md_ctx, EVP_ecdsa()) || !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; 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"); EC_KEY_free(key); ECDSA_SIG_free(signature); BN_free(r); BN_free(s); EVP_MD_CTX_cleanup(&md_ctx); BN_clear_free(kinv); BN_clear_free(rp); 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; }