1160814Ssimon/* crypto/ecdsa/ecdsatest.c */ 2160814Ssimon/* 3160814Ssimon * Written by Nils Larsch for the OpenSSL project. 4160814Ssimon */ 5160814Ssimon/* ==================================================================== 6337982Sjkim * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved. 7160814Ssimon * 8160814Ssimon * Redistribution and use in source and binary forms, with or without 9160814Ssimon * modification, are permitted provided that the following conditions 10160814Ssimon * are met: 11160814Ssimon * 12160814Ssimon * 1. Redistributions of source code must retain the above copyright 13280297Sjkim * notice, this list of conditions and the following disclaimer. 14160814Ssimon * 15160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 16160814Ssimon * notice, this list of conditions and the following disclaimer in 17160814Ssimon * the documentation and/or other materials provided with the 18160814Ssimon * distribution. 19160814Ssimon * 20160814Ssimon * 3. All advertising materials mentioning features or use of this 21160814Ssimon * software must display the following acknowledgment: 22160814Ssimon * "This product includes software developed by the OpenSSL Project 23160814Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24160814Ssimon * 25160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26160814Ssimon * endorse or promote products derived from this software without 27160814Ssimon * prior written permission. For written permission, please contact 28160814Ssimon * licensing@OpenSSL.org. 29160814Ssimon * 30160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 31160814Ssimon * nor may "OpenSSL" appear in their names without prior written 32160814Ssimon * permission of the OpenSSL Project. 33160814Ssimon * 34160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 35160814Ssimon * acknowledgment: 36160814Ssimon * "This product includes software developed by the OpenSSL Project 37160814Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38160814Ssimon * 39160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 51160814Ssimon * ==================================================================== 52160814Ssimon * 53160814Ssimon * This product includes cryptographic software written by Eric Young 54160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 55160814Ssimon * Hudson (tjh@cryptsoft.com). 56160814Ssimon * 57160814Ssimon */ 58160814Ssimon/* ==================================================================== 59160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60160814Ssimon * 61280297Sjkim * Portions of the attached software ("Contribution") are developed by 62160814Ssimon * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 63160814Ssimon * 64160814Ssimon * The Contribution is licensed pursuant to the OpenSSL open source 65160814Ssimon * license provided above. 66160814Ssimon * 67280297Sjkim * The elliptic curve binary polynomial software is originally written by 68160814Ssimon * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. 69160814Ssimon * 70160814Ssimon */ 71160814Ssimon 72160814Ssimon#include <stdio.h> 73160814Ssimon#include <stdlib.h> 74160814Ssimon#include <string.h> 75160814Ssimon 76160814Ssimon#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_ECDSA is defined */ 77160814Ssimon 78160814Ssimon#ifdef OPENSSL_NO_ECDSA 79280297Sjkimint main(int argc, char *argv[]) 80280297Sjkim{ 81280297Sjkim puts("Elliptic curves are disabled."); 82280297Sjkim return 0; 83280297Sjkim} 84160814Ssimon#else 85160814Ssimon 86280297Sjkim# include <openssl/crypto.h> 87280297Sjkim# include <openssl/bio.h> 88280297Sjkim# include <openssl/evp.h> 89280297Sjkim# include <openssl/bn.h> 90280297Sjkim# include <openssl/ecdsa.h> 91280297Sjkim# ifndef OPENSSL_NO_ENGINE 92280297Sjkim# include <openssl/engine.h> 93280297Sjkim# endif 94280297Sjkim# include <openssl/err.h> 95280297Sjkim# include <openssl/rand.h> 96160814Ssimon 97160814Ssimonstatic const char rnd_seed[] = "string to make the random number generator " 98280297Sjkim "think it has entropy"; 99160814Ssimon 100160814Ssimon/* declaration of the test functions */ 101160814Ssimonint x9_62_tests(BIO *); 102160814Ssimonint x9_62_test_internal(BIO *out, int nid, const char *r, const char *s); 103160814Ssimonint test_builtin(BIO *); 104160814Ssimon 105160814Ssimon/* functions to change the RAND_METHOD */ 106160814Ssimonint change_rand(void); 107160814Ssimonint restore_rand(void); 108160814Ssimonint fbytes(unsigned char *buf, int num); 109160814Ssimon 110280297SjkimRAND_METHOD fake_rand; 111160814Ssimonconst RAND_METHOD *old_rand; 112160814Ssimon 113160814Ssimonint change_rand(void) 114280297Sjkim{ 115280297Sjkim /* save old rand method */ 116280297Sjkim if ((old_rand = RAND_get_rand_method()) == NULL) 117280297Sjkim return 0; 118160814Ssimon 119280297Sjkim fake_rand.seed = old_rand->seed; 120280297Sjkim fake_rand.cleanup = old_rand->cleanup; 121280297Sjkim fake_rand.add = old_rand->add; 122280297Sjkim fake_rand.status = old_rand->status; 123280297Sjkim /* use own random function */ 124280297Sjkim fake_rand.bytes = fbytes; 125280297Sjkim fake_rand.pseudorand = old_rand->bytes; 126280297Sjkim /* set new RAND_METHOD */ 127280297Sjkim if (!RAND_set_rand_method(&fake_rand)) 128280297Sjkim return 0; 129280297Sjkim return 1; 130280297Sjkim} 131160814Ssimon 132160814Ssimonint restore_rand(void) 133280297Sjkim{ 134280297Sjkim if (!RAND_set_rand_method(old_rand)) 135280297Sjkim return 0; 136280297Sjkim else 137280297Sjkim return 1; 138280297Sjkim} 139160814Ssimon 140337982Sjkimstatic int fbytes_counter = 0, use_fake = 0; 141160814Ssimonstatic const char *numbers[8] = { 142280297Sjkim "651056770906015076056810763456358567190100156695615665659", 143280297Sjkim "6140507067065001063065065565667405560006161556565665656654", 144280297Sjkim "8763001015071075675010661307616710783570106710677817767166" 145280297Sjkim "71676178726717", 146280297Sjkim "7000000175690566466555057817571571075705015757757057795755" 147280297Sjkim "55657156756655", 148280297Sjkim "1275552191113212300012030439187146164646146646466749494799", 149280297Sjkim "1542725565216523985789236956265265265235675811949404040041", 150280297Sjkim "1456427555219115346513212300075341203043918714616464614664" 151280297Sjkim "64667494947990", 152280297Sjkim "1712787255652165239672857892369562652652652356758119494040" 153280297Sjkim "40041670216363" 154280297Sjkim}; 155160814Ssimon 156160814Ssimonint fbytes(unsigned char *buf, int num) 157280297Sjkim{ 158280297Sjkim int ret; 159280297Sjkim BIGNUM *tmp = NULL; 160160814Ssimon 161337982Sjkim if (use_fake == 0) 162337982Sjkim return old_rand->bytes(buf, num); 163337982Sjkim 164337982Sjkim use_fake = 0; 165337982Sjkim 166280297Sjkim if (fbytes_counter >= 8) 167280297Sjkim return 0; 168280297Sjkim tmp = BN_new(); 169280297Sjkim if (!tmp) 170280297Sjkim return 0; 171280297Sjkim if (!BN_dec2bn(&tmp, numbers[fbytes_counter])) { 172280297Sjkim BN_free(tmp); 173280297Sjkim return 0; 174280297Sjkim } 175280297Sjkim fbytes_counter++; 176280297Sjkim if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf)) 177280297Sjkim ret = 0; 178280297Sjkim else 179280297Sjkim ret = 1; 180280297Sjkim if (tmp) 181280297Sjkim BN_free(tmp); 182280297Sjkim return ret; 183280297Sjkim} 184160814Ssimon 185160814Ssimon/* some tests from the X9.62 draft */ 186160814Ssimonint x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in) 187280297Sjkim{ 188280297Sjkim int ret = 0; 189280297Sjkim const char message[] = "abc"; 190280297Sjkim unsigned char digest[20]; 191280297Sjkim unsigned int dgst_len = 0; 192280297Sjkim EVP_MD_CTX md_ctx; 193280297Sjkim EC_KEY *key = NULL; 194280297Sjkim ECDSA_SIG *signature = NULL; 195280297Sjkim BIGNUM *r = NULL, *s = NULL; 196160814Ssimon 197280297Sjkim EVP_MD_CTX_init(&md_ctx); 198280297Sjkim /* get the message digest */ 199280297Sjkim EVP_DigestInit(&md_ctx, EVP_ecdsa()); 200280297Sjkim EVP_DigestUpdate(&md_ctx, (const void *)message, 3); 201280297Sjkim EVP_DigestFinal(&md_ctx, digest, &dgst_len); 202160814Ssimon 203280297Sjkim BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid)); 204280297Sjkim /* create the key */ 205280297Sjkim if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) 206280297Sjkim goto x962_int_err; 207337982Sjkim use_fake = 1; 208280297Sjkim if (!EC_KEY_generate_key(key)) 209280297Sjkim goto x962_int_err; 210280297Sjkim BIO_printf(out, "."); 211280297Sjkim (void)BIO_flush(out); 212280297Sjkim /* create the signature */ 213337982Sjkim use_fake = 1; 214280297Sjkim signature = ECDSA_do_sign(digest, 20, key); 215280297Sjkim if (signature == NULL) 216280297Sjkim goto x962_int_err; 217280297Sjkim BIO_printf(out, "."); 218280297Sjkim (void)BIO_flush(out); 219280297Sjkim /* compare the created signature with the expected signature */ 220280297Sjkim if ((r = BN_new()) == NULL || (s = BN_new()) == NULL) 221280297Sjkim goto x962_int_err; 222280297Sjkim if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in)) 223280297Sjkim goto x962_int_err; 224280297Sjkim if (BN_cmp(signature->r, r) || BN_cmp(signature->s, s)) 225280297Sjkim goto x962_int_err; 226280297Sjkim BIO_printf(out, "."); 227280297Sjkim (void)BIO_flush(out); 228280297Sjkim /* verify the signature */ 229280297Sjkim if (ECDSA_do_verify(digest, 20, signature, key) != 1) 230280297Sjkim goto x962_int_err; 231280297Sjkim BIO_printf(out, "."); 232280297Sjkim (void)BIO_flush(out); 233160814Ssimon 234280297Sjkim BIO_printf(out, " ok\n"); 235280297Sjkim ret = 1; 236280297Sjkim x962_int_err: 237280297Sjkim if (!ret) 238280297Sjkim BIO_printf(out, " failed\n"); 239280297Sjkim if (key) 240280297Sjkim EC_KEY_free(key); 241280297Sjkim if (signature) 242280297Sjkim ECDSA_SIG_free(signature); 243280297Sjkim if (r) 244280297Sjkim BN_free(r); 245280297Sjkim if (s) 246280297Sjkim BN_free(s); 247280297Sjkim EVP_MD_CTX_cleanup(&md_ctx); 248280297Sjkim return ret; 249280297Sjkim} 250160814Ssimon 251160814Ssimonint x9_62_tests(BIO *out) 252280297Sjkim{ 253280297Sjkim int ret = 0; 254160814Ssimon 255280297Sjkim BIO_printf(out, "some tests from X9.62:\n"); 256160814Ssimon 257280297Sjkim /* set own rand method */ 258280297Sjkim if (!change_rand()) 259280297Sjkim goto x962_err; 260160814Ssimon 261280297Sjkim if (!x9_62_test_internal(out, NID_X9_62_prime192v1, 262280297Sjkim "3342403536405981729393488334694600415596881826869351677613", 263280297Sjkim "5735822328888155254683894997897571951568553642892029982342")) 264280297Sjkim goto x962_err; 265280297Sjkim if (!x9_62_test_internal(out, NID_X9_62_prime239v1, 266280297Sjkim "3086361431751678114926225473006680188549593787585317781474" 267280297Sjkim "62058306432176", 268280297Sjkim "3238135532097973577080787768312505059318910517550078427819" 269280297Sjkim "78505179448783")) 270280297Sjkim goto x962_err; 271280297Sjkim# ifndef OPENSSL_NO_EC2M 272280297Sjkim if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1, 273280297Sjkim "87194383164871543355722284926904419997237591535066528048", 274280297Sjkim "308992691965804947361541664549085895292153777025772063598")) 275280297Sjkim goto x962_err; 276280297Sjkim if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1, 277280297Sjkim "2159633321041961198501834003903461262881815148684178964245" 278280297Sjkim "5876922391552", 279280297Sjkim "1970303740007316867383349976549972270528498040721988191026" 280280297Sjkim "49413465737174")) 281280297Sjkim goto x962_err; 282280297Sjkim# endif 283280297Sjkim ret = 1; 284280297Sjkim x962_err: 285280297Sjkim if (!restore_rand()) 286280297Sjkim ret = 0; 287280297Sjkim return ret; 288280297Sjkim} 289160814Ssimon 290160814Ssimonint test_builtin(BIO *out) 291280297Sjkim{ 292280297Sjkim EC_builtin_curve *curves = NULL; 293280297Sjkim size_t crv_len = 0, n = 0; 294280297Sjkim EC_KEY *eckey = NULL, *wrong_eckey = NULL; 295280297Sjkim EC_GROUP *group; 296280297Sjkim ECDSA_SIG *ecdsa_sig = NULL; 297280297Sjkim unsigned char digest[20], wrong_digest[20]; 298280297Sjkim unsigned char *signature = NULL; 299280297Sjkim const unsigned char *sig_ptr; 300280297Sjkim unsigned char *sig_ptr2; 301280297Sjkim unsigned char *raw_buf = NULL; 302280297Sjkim unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; 303280297Sjkim int nid, ret = 0; 304160814Ssimon 305280297Sjkim /* fill digest values with some random data */ 306284283Sjkim if (RAND_pseudo_bytes(digest, 20) <= 0 || 307284283Sjkim RAND_pseudo_bytes(wrong_digest, 20) <= 0) { 308280297Sjkim BIO_printf(out, "ERROR: unable to get random data\n"); 309280297Sjkim goto builtin_err; 310280297Sjkim } 311160814Ssimon 312280297Sjkim /* 313280297Sjkim * create and verify a ecdsa signature with every availble curve (with ) 314280297Sjkim */ 315280297Sjkim BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " 316280297Sjkim "with some internal curves:\n"); 317160814Ssimon 318280297Sjkim /* get a list of all internal curves */ 319280297Sjkim crv_len = EC_get_builtin_curves(NULL, 0); 320160814Ssimon 321280297Sjkim curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); 322160814Ssimon 323280297Sjkim if (curves == NULL) { 324280297Sjkim BIO_printf(out, "malloc error\n"); 325280297Sjkim goto builtin_err; 326280297Sjkim } 327160814Ssimon 328280297Sjkim if (!EC_get_builtin_curves(curves, crv_len)) { 329280297Sjkim BIO_printf(out, "unable to get internal curves\n"); 330280297Sjkim goto builtin_err; 331280297Sjkim } 332160814Ssimon 333280297Sjkim /* now create and verify a signature for every curve */ 334280297Sjkim for (n = 0; n < crv_len; n++) { 335280297Sjkim unsigned char dirt, offset; 336237657Sjkim 337280297Sjkim nid = curves[n].nid; 338280297Sjkim if (nid == NID_ipsec4) 339280297Sjkim continue; 340280297Sjkim /* create new ecdsa key (== EC_KEY) */ 341280297Sjkim if ((eckey = EC_KEY_new()) == NULL) 342280297Sjkim goto builtin_err; 343280297Sjkim group = EC_GROUP_new_by_curve_name(nid); 344280297Sjkim if (group == NULL) 345280297Sjkim goto builtin_err; 346280297Sjkim if (EC_KEY_set_group(eckey, group) == 0) 347280297Sjkim goto builtin_err; 348280297Sjkim EC_GROUP_free(group); 349280297Sjkim degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); 350280297Sjkim if (degree < 160) 351280297Sjkim /* drop the curve */ 352280297Sjkim { 353280297Sjkim EC_KEY_free(eckey); 354280297Sjkim eckey = NULL; 355280297Sjkim continue; 356280297Sjkim } 357280297Sjkim BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); 358280297Sjkim /* create key */ 359280297Sjkim if (!EC_KEY_generate_key(eckey)) { 360280297Sjkim BIO_printf(out, " failed\n"); 361280297Sjkim goto builtin_err; 362280297Sjkim } 363280297Sjkim /* create second key */ 364280297Sjkim if ((wrong_eckey = EC_KEY_new()) == NULL) 365280297Sjkim goto builtin_err; 366280297Sjkim group = EC_GROUP_new_by_curve_name(nid); 367280297Sjkim if (group == NULL) 368280297Sjkim goto builtin_err; 369280297Sjkim if (EC_KEY_set_group(wrong_eckey, group) == 0) 370280297Sjkim goto builtin_err; 371280297Sjkim EC_GROUP_free(group); 372280297Sjkim if (!EC_KEY_generate_key(wrong_eckey)) { 373280297Sjkim BIO_printf(out, " failed\n"); 374280297Sjkim goto builtin_err; 375280297Sjkim } 376237657Sjkim 377280297Sjkim BIO_printf(out, "."); 378280297Sjkim (void)BIO_flush(out); 379280297Sjkim /* check key */ 380280297Sjkim if (!EC_KEY_check_key(eckey)) { 381280297Sjkim BIO_printf(out, " failed\n"); 382280297Sjkim goto builtin_err; 383280297Sjkim } 384280297Sjkim BIO_printf(out, "."); 385280297Sjkim (void)BIO_flush(out); 386280297Sjkim /* create signature */ 387280297Sjkim sig_len = ECDSA_size(eckey); 388280297Sjkim if ((signature = OPENSSL_malloc(sig_len)) == NULL) 389280297Sjkim goto builtin_err; 390280297Sjkim if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { 391280297Sjkim BIO_printf(out, " failed\n"); 392280297Sjkim goto builtin_err; 393280297Sjkim } 394280297Sjkim BIO_printf(out, "."); 395280297Sjkim (void)BIO_flush(out); 396280297Sjkim /* verify signature */ 397280297Sjkim if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { 398280297Sjkim BIO_printf(out, " failed\n"); 399280297Sjkim goto builtin_err; 400280297Sjkim } 401280297Sjkim BIO_printf(out, "."); 402280297Sjkim (void)BIO_flush(out); 403280297Sjkim /* verify signature with the wrong key */ 404280297Sjkim if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { 405280297Sjkim BIO_printf(out, " failed\n"); 406280297Sjkim goto builtin_err; 407280297Sjkim } 408280297Sjkim BIO_printf(out, "."); 409280297Sjkim (void)BIO_flush(out); 410280297Sjkim /* wrong digest */ 411280297Sjkim if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { 412280297Sjkim BIO_printf(out, " failed\n"); 413280297Sjkim goto builtin_err; 414280297Sjkim } 415280297Sjkim BIO_printf(out, "."); 416280297Sjkim (void)BIO_flush(out); 417280297Sjkim /* wrong length */ 418280297Sjkim if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) { 419280297Sjkim BIO_printf(out, " failed\n"); 420280297Sjkim goto builtin_err; 421280297Sjkim } 422280297Sjkim BIO_printf(out, "."); 423280297Sjkim (void)BIO_flush(out); 424237657Sjkim 425280297Sjkim /* 426280297Sjkim * Modify a single byte of the signature: to ensure we don't garble 427280297Sjkim * the ASN1 structure, we read the raw signature and modify a byte in 428280297Sjkim * one of the bignums directly. 429280297Sjkim */ 430280297Sjkim sig_ptr = signature; 431280297Sjkim if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) { 432280297Sjkim BIO_printf(out, " failed\n"); 433280297Sjkim goto builtin_err; 434280297Sjkim } 435237657Sjkim 436280297Sjkim /* Store the two BIGNUMs in raw_buf. */ 437280297Sjkim r_len = BN_num_bytes(ecdsa_sig->r); 438280297Sjkim s_len = BN_num_bytes(ecdsa_sig->s); 439280297Sjkim bn_len = (degree + 7) / 8; 440280297Sjkim if ((r_len > bn_len) || (s_len > bn_len)) { 441280297Sjkim BIO_printf(out, " failed\n"); 442280297Sjkim goto builtin_err; 443280297Sjkim } 444280297Sjkim buf_len = 2 * bn_len; 445280297Sjkim if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL) 446280297Sjkim goto builtin_err; 447280297Sjkim /* Pad the bignums with leading zeroes. */ 448280297Sjkim memset(raw_buf, 0, buf_len); 449280297Sjkim BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len); 450280297Sjkim BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len); 451237657Sjkim 452280297Sjkim /* Modify a single byte in the buffer. */ 453280297Sjkim offset = raw_buf[10] % buf_len; 454280297Sjkim dirt = raw_buf[11] ? raw_buf[11] : 1; 455280297Sjkim raw_buf[offset] ^= dirt; 456280297Sjkim /* Now read the BIGNUMs back in from raw_buf. */ 457280297Sjkim if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || 458280297Sjkim (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) 459280297Sjkim goto builtin_err; 460160814Ssimon 461280297Sjkim sig_ptr2 = signature; 462280297Sjkim sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); 463280297Sjkim if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { 464280297Sjkim BIO_printf(out, " failed\n"); 465280297Sjkim goto builtin_err; 466280297Sjkim } 467280297Sjkim /* 468280297Sjkim * Sanity check: undo the modification and verify signature. 469280297Sjkim */ 470280297Sjkim raw_buf[offset] ^= dirt; 471280297Sjkim if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || 472280297Sjkim (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) 473280297Sjkim goto builtin_err; 474160814Ssimon 475280297Sjkim sig_ptr2 = signature; 476280297Sjkim sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); 477280297Sjkim if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { 478280297Sjkim BIO_printf(out, " failed\n"); 479280297Sjkim goto builtin_err; 480280297Sjkim } 481280297Sjkim BIO_printf(out, "."); 482280297Sjkim (void)BIO_flush(out); 483160814Ssimon 484280297Sjkim BIO_printf(out, " ok\n"); 485280297Sjkim /* cleanup */ 486280297Sjkim /* clean bogus errors */ 487280297Sjkim ERR_clear_error(); 488280297Sjkim OPENSSL_free(signature); 489280297Sjkim signature = NULL; 490280297Sjkim EC_KEY_free(eckey); 491280297Sjkim eckey = NULL; 492280297Sjkim EC_KEY_free(wrong_eckey); 493280297Sjkim wrong_eckey = NULL; 494280297Sjkim ECDSA_SIG_free(ecdsa_sig); 495280297Sjkim ecdsa_sig = NULL; 496280297Sjkim OPENSSL_free(raw_buf); 497280297Sjkim raw_buf = NULL; 498280297Sjkim } 499280297Sjkim 500280297Sjkim ret = 1; 501280297Sjkim builtin_err: 502280297Sjkim if (eckey) 503280297Sjkim EC_KEY_free(eckey); 504280297Sjkim if (wrong_eckey) 505280297Sjkim EC_KEY_free(wrong_eckey); 506280297Sjkim if (ecdsa_sig) 507280297Sjkim ECDSA_SIG_free(ecdsa_sig); 508280297Sjkim if (signature) 509280297Sjkim OPENSSL_free(signature); 510280297Sjkim if (raw_buf) 511280297Sjkim OPENSSL_free(raw_buf); 512280297Sjkim if (curves) 513280297Sjkim OPENSSL_free(curves); 514280297Sjkim 515280297Sjkim return ret; 516280297Sjkim} 517280297Sjkim 518160814Ssimonint main(void) 519280297Sjkim{ 520280297Sjkim int ret = 1; 521280297Sjkim BIO *out; 522160814Ssimon 523280297Sjkim out = BIO_new_fp(stdout, BIO_NOCLOSE); 524160814Ssimon 525280297Sjkim /* enable memory leak checking unless explicitly disabled */ 526280297Sjkim if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && 527280297Sjkim (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { 528280297Sjkim CRYPTO_malloc_debug_init(); 529280297Sjkim CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 530280297Sjkim } else { 531280297Sjkim /* OPENSSL_DEBUG_MEMORY=off */ 532280297Sjkim CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); 533280297Sjkim } 534280297Sjkim CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 535160814Ssimon 536280297Sjkim ERR_load_crypto_strings(); 537160814Ssimon 538280297Sjkim /* initialize the prng */ 539280297Sjkim RAND_seed(rnd_seed, sizeof(rnd_seed)); 540280297Sjkim 541280297Sjkim /* the tests */ 542280297Sjkim if (!x9_62_tests(out)) 543280297Sjkim goto err; 544280297Sjkim if (!test_builtin(out)) 545280297Sjkim goto err; 546280297Sjkim 547280297Sjkim ret = 0; 548280297Sjkim err: 549280297Sjkim if (ret) 550280297Sjkim BIO_printf(out, "\nECDSA test failed\n"); 551280297Sjkim else 552280297Sjkim BIO_printf(out, "\nECDSA test passed\n"); 553280297Sjkim if (ret) 554280297Sjkim ERR_print_errors(out); 555280297Sjkim CRYPTO_cleanup_all_ex_data(); 556280297Sjkim ERR_remove_thread_state(NULL); 557280297Sjkim ERR_free_strings(); 558280297Sjkim CRYPTO_mem_leaks(out); 559280297Sjkim if (out != NULL) 560280297Sjkim BIO_free(out); 561280297Sjkim return ret; 562280297Sjkim} 563160814Ssimon#endif 564