1160814Ssimon/* crypto/ecdsa/ecdsatest.c */ 2160814Ssimon/* 3160814Ssimon * Written by Nils Larsch for the OpenSSL project. 4160814Ssimon */ 5160814Ssimon/* ==================================================================== 6160814Ssimon * Copyright (c) 2000-2005 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 13296341Sdelphij * 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 * 61296341Sdelphij * 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 * 67296341Sdelphij * 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 79296341Sdelphijint main(int argc, char *argv[]) 80296341Sdelphij{ 81296341Sdelphij puts("Elliptic curves are disabled."); 82296341Sdelphij return 0; 83296341Sdelphij} 84160814Ssimon#else 85160814Ssimon 86296341Sdelphij# include <openssl/crypto.h> 87296341Sdelphij# include <openssl/bio.h> 88296341Sdelphij# include <openssl/evp.h> 89296341Sdelphij# include <openssl/bn.h> 90296341Sdelphij# include <openssl/ecdsa.h> 91296341Sdelphij# ifndef OPENSSL_NO_ENGINE 92296341Sdelphij# include <openssl/engine.h> 93296341Sdelphij# endif 94296341Sdelphij# include <openssl/err.h> 95296341Sdelphij# include <openssl/rand.h> 96160814Ssimon 97160814Ssimonstatic const char rnd_seed[] = "string to make the random number generator " 98296341Sdelphij "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 110296341SdelphijRAND_METHOD fake_rand; 111160814Ssimonconst RAND_METHOD *old_rand; 112160814Ssimon 113160814Ssimonint change_rand(void) 114296341Sdelphij{ 115296341Sdelphij /* save old rand method */ 116296341Sdelphij if ((old_rand = RAND_get_rand_method()) == NULL) 117296341Sdelphij return 0; 118160814Ssimon 119296341Sdelphij fake_rand.seed = old_rand->seed; 120296341Sdelphij fake_rand.cleanup = old_rand->cleanup; 121296341Sdelphij fake_rand.add = old_rand->add; 122296341Sdelphij fake_rand.status = old_rand->status; 123296341Sdelphij /* use own random function */ 124296341Sdelphij fake_rand.bytes = fbytes; 125296341Sdelphij fake_rand.pseudorand = old_rand->bytes; 126296341Sdelphij /* set new RAND_METHOD */ 127296341Sdelphij if (!RAND_set_rand_method(&fake_rand)) 128296341Sdelphij return 0; 129296341Sdelphij return 1; 130296341Sdelphij} 131160814Ssimon 132160814Ssimonint restore_rand(void) 133296341Sdelphij{ 134296341Sdelphij if (!RAND_set_rand_method(old_rand)) 135296341Sdelphij return 0; 136296341Sdelphij else 137296341Sdelphij return 1; 138296341Sdelphij} 139160814Ssimon 140160814Ssimonstatic int fbytes_counter = 0; 141160814Ssimonstatic const char *numbers[8] = { 142296341Sdelphij "651056770906015076056810763456358567190100156695615665659", 143296341Sdelphij "6140507067065001063065065565667405560006161556565665656654", 144296341Sdelphij "8763001015071075675010661307616710783570106710677817767166" 145296341Sdelphij "71676178726717", 146296341Sdelphij "7000000175690566466555057817571571075705015757757057795755" 147296341Sdelphij "55657156756655", 148296341Sdelphij "1275552191113212300012030439187146164646146646466749494799", 149296341Sdelphij "1542725565216523985789236956265265265235675811949404040041", 150296341Sdelphij "1456427555219115346513212300075341203043918714616464614664" 151296341Sdelphij "64667494947990", 152296341Sdelphij "1712787255652165239672857892369562652652652356758119494040" 153296341Sdelphij "40041670216363" 154296341Sdelphij}; 155160814Ssimon 156160814Ssimonint fbytes(unsigned char *buf, int num) 157296341Sdelphij{ 158296341Sdelphij int ret; 159296341Sdelphij BIGNUM *tmp = NULL; 160160814Ssimon 161296341Sdelphij if (fbytes_counter >= 8) 162296341Sdelphij return 0; 163296341Sdelphij tmp = BN_new(); 164296341Sdelphij if (!tmp) 165296341Sdelphij return 0; 166296341Sdelphij if (!BN_dec2bn(&tmp, numbers[fbytes_counter])) { 167296341Sdelphij BN_free(tmp); 168296341Sdelphij return 0; 169296341Sdelphij } 170296341Sdelphij fbytes_counter++; 171296341Sdelphij if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf)) 172296341Sdelphij ret = 0; 173296341Sdelphij else 174296341Sdelphij ret = 1; 175296341Sdelphij if (tmp) 176296341Sdelphij BN_free(tmp); 177296341Sdelphij return ret; 178296341Sdelphij} 179160814Ssimon 180160814Ssimon/* some tests from the X9.62 draft */ 181160814Ssimonint x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in) 182296341Sdelphij{ 183296341Sdelphij int ret = 0; 184296341Sdelphij const char message[] = "abc"; 185296341Sdelphij unsigned char digest[20]; 186296341Sdelphij unsigned int dgst_len = 0; 187296341Sdelphij EVP_MD_CTX md_ctx; 188296341Sdelphij EC_KEY *key = NULL; 189296341Sdelphij ECDSA_SIG *signature = NULL; 190296341Sdelphij BIGNUM *r = NULL, *s = NULL; 191160814Ssimon 192296341Sdelphij EVP_MD_CTX_init(&md_ctx); 193296341Sdelphij /* get the message digest */ 194296341Sdelphij EVP_DigestInit(&md_ctx, EVP_ecdsa()); 195296341Sdelphij EVP_DigestUpdate(&md_ctx, (const void *)message, 3); 196296341Sdelphij EVP_DigestFinal(&md_ctx, digest, &dgst_len); 197160814Ssimon 198296341Sdelphij BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid)); 199296341Sdelphij /* create the key */ 200296341Sdelphij if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) 201296341Sdelphij goto x962_int_err; 202296341Sdelphij if (!EC_KEY_generate_key(key)) 203296341Sdelphij goto x962_int_err; 204296341Sdelphij BIO_printf(out, "."); 205296341Sdelphij (void)BIO_flush(out); 206296341Sdelphij /* create the signature */ 207296341Sdelphij signature = ECDSA_do_sign(digest, 20, key); 208296341Sdelphij if (signature == NULL) 209296341Sdelphij goto x962_int_err; 210296341Sdelphij BIO_printf(out, "."); 211296341Sdelphij (void)BIO_flush(out); 212296341Sdelphij /* compare the created signature with the expected signature */ 213296341Sdelphij if ((r = BN_new()) == NULL || (s = BN_new()) == NULL) 214296341Sdelphij goto x962_int_err; 215296341Sdelphij if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in)) 216296341Sdelphij goto x962_int_err; 217296341Sdelphij if (BN_cmp(signature->r, r) || BN_cmp(signature->s, s)) 218296341Sdelphij goto x962_int_err; 219296341Sdelphij BIO_printf(out, "."); 220296341Sdelphij (void)BIO_flush(out); 221296341Sdelphij /* verify the signature */ 222296341Sdelphij if (ECDSA_do_verify(digest, 20, signature, key) != 1) 223296341Sdelphij goto x962_int_err; 224296341Sdelphij BIO_printf(out, "."); 225296341Sdelphij (void)BIO_flush(out); 226160814Ssimon 227296341Sdelphij BIO_printf(out, " ok\n"); 228296341Sdelphij ret = 1; 229296341Sdelphij x962_int_err: 230296341Sdelphij if (!ret) 231296341Sdelphij BIO_printf(out, " failed\n"); 232296341Sdelphij if (key) 233296341Sdelphij EC_KEY_free(key); 234296341Sdelphij if (signature) 235296341Sdelphij ECDSA_SIG_free(signature); 236296341Sdelphij if (r) 237296341Sdelphij BN_free(r); 238296341Sdelphij if (s) 239296341Sdelphij BN_free(s); 240296341Sdelphij EVP_MD_CTX_cleanup(&md_ctx); 241296341Sdelphij return ret; 242296341Sdelphij} 243160814Ssimon 244160814Ssimonint x9_62_tests(BIO *out) 245296341Sdelphij{ 246296341Sdelphij int ret = 0; 247160814Ssimon 248296341Sdelphij BIO_printf(out, "some tests from X9.62:\n"); 249160814Ssimon 250296341Sdelphij /* set own rand method */ 251296341Sdelphij if (!change_rand()) 252296341Sdelphij goto x962_err; 253160814Ssimon 254296341Sdelphij if (!x9_62_test_internal(out, NID_X9_62_prime192v1, 255296341Sdelphij "3342403536405981729393488334694600415596881826869351677613", 256296341Sdelphij "5735822328888155254683894997897571951568553642892029982342")) 257296341Sdelphij goto x962_err; 258296341Sdelphij if (!x9_62_test_internal(out, NID_X9_62_prime239v1, 259296341Sdelphij "3086361431751678114926225473006680188549593787585317781474" 260296341Sdelphij "62058306432176", 261296341Sdelphij "3238135532097973577080787768312505059318910517550078427819" 262296341Sdelphij "78505179448783")) 263296341Sdelphij goto x962_err; 264296341Sdelphij# ifndef OPENSSL_NO_EC2M 265296341Sdelphij if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1, 266296341Sdelphij "87194383164871543355722284926904419997237591535066528048", 267296341Sdelphij "308992691965804947361541664549085895292153777025772063598")) 268296341Sdelphij goto x962_err; 269296341Sdelphij if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1, 270296341Sdelphij "2159633321041961198501834003903461262881815148684178964245" 271296341Sdelphij "5876922391552", 272296341Sdelphij "1970303740007316867383349976549972270528498040721988191026" 273296341Sdelphij "49413465737174")) 274296341Sdelphij goto x962_err; 275296341Sdelphij# endif 276296341Sdelphij ret = 1; 277296341Sdelphij x962_err: 278296341Sdelphij if (!restore_rand()) 279296341Sdelphij ret = 0; 280296341Sdelphij return ret; 281296341Sdelphij} 282160814Ssimon 283160814Ssimonint test_builtin(BIO *out) 284296341Sdelphij{ 285296341Sdelphij EC_builtin_curve *curves = NULL; 286296341Sdelphij size_t crv_len = 0, n = 0; 287296341Sdelphij EC_KEY *eckey = NULL, *wrong_eckey = NULL; 288296341Sdelphij EC_GROUP *group; 289296341Sdelphij ECDSA_SIG *ecdsa_sig = NULL; 290296341Sdelphij unsigned char digest[20], wrong_digest[20]; 291296341Sdelphij unsigned char *signature = NULL; 292296341Sdelphij const unsigned char *sig_ptr; 293296341Sdelphij unsigned char *sig_ptr2; 294296341Sdelphij unsigned char *raw_buf = NULL; 295296341Sdelphij unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; 296296341Sdelphij int nid, ret = 0; 297160814Ssimon 298296341Sdelphij /* fill digest values with some random data */ 299296341Sdelphij if (RAND_pseudo_bytes(digest, 20) <= 0 || 300296341Sdelphij RAND_pseudo_bytes(wrong_digest, 20) <= 0) { 301296341Sdelphij BIO_printf(out, "ERROR: unable to get random data\n"); 302296341Sdelphij goto builtin_err; 303296341Sdelphij } 304160814Ssimon 305296341Sdelphij /* 306296341Sdelphij * create and verify a ecdsa signature with every availble curve (with ) 307296341Sdelphij */ 308296341Sdelphij BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " 309296341Sdelphij "with some internal curves:\n"); 310160814Ssimon 311296341Sdelphij /* get a list of all internal curves */ 312296341Sdelphij crv_len = EC_get_builtin_curves(NULL, 0); 313160814Ssimon 314296341Sdelphij curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); 315160814Ssimon 316296341Sdelphij if (curves == NULL) { 317296341Sdelphij BIO_printf(out, "malloc error\n"); 318296341Sdelphij goto builtin_err; 319296341Sdelphij } 320160814Ssimon 321296341Sdelphij if (!EC_get_builtin_curves(curves, crv_len)) { 322296341Sdelphij BIO_printf(out, "unable to get internal curves\n"); 323296341Sdelphij goto builtin_err; 324296341Sdelphij } 325160814Ssimon 326296341Sdelphij /* now create and verify a signature for every curve */ 327296341Sdelphij for (n = 0; n < crv_len; n++) { 328296341Sdelphij unsigned char dirt, offset; 329237657Sjkim 330296341Sdelphij nid = curves[n].nid; 331296341Sdelphij if (nid == NID_ipsec4) 332296341Sdelphij continue; 333296341Sdelphij /* create new ecdsa key (== EC_KEY) */ 334296341Sdelphij if ((eckey = EC_KEY_new()) == NULL) 335296341Sdelphij goto builtin_err; 336296341Sdelphij group = EC_GROUP_new_by_curve_name(nid); 337296341Sdelphij if (group == NULL) 338296341Sdelphij goto builtin_err; 339296341Sdelphij if (EC_KEY_set_group(eckey, group) == 0) 340296341Sdelphij goto builtin_err; 341296341Sdelphij EC_GROUP_free(group); 342296341Sdelphij degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); 343296341Sdelphij if (degree < 160) 344296341Sdelphij /* drop the curve */ 345296341Sdelphij { 346296341Sdelphij EC_KEY_free(eckey); 347296341Sdelphij eckey = NULL; 348296341Sdelphij continue; 349296341Sdelphij } 350296341Sdelphij BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); 351296341Sdelphij /* create key */ 352296341Sdelphij if (!EC_KEY_generate_key(eckey)) { 353296341Sdelphij BIO_printf(out, " failed\n"); 354296341Sdelphij goto builtin_err; 355296341Sdelphij } 356296341Sdelphij /* create second key */ 357296341Sdelphij if ((wrong_eckey = EC_KEY_new()) == NULL) 358296341Sdelphij goto builtin_err; 359296341Sdelphij group = EC_GROUP_new_by_curve_name(nid); 360296341Sdelphij if (group == NULL) 361296341Sdelphij goto builtin_err; 362296341Sdelphij if (EC_KEY_set_group(wrong_eckey, group) == 0) 363296341Sdelphij goto builtin_err; 364296341Sdelphij EC_GROUP_free(group); 365296341Sdelphij if (!EC_KEY_generate_key(wrong_eckey)) { 366296341Sdelphij BIO_printf(out, " failed\n"); 367296341Sdelphij goto builtin_err; 368296341Sdelphij } 369237657Sjkim 370296341Sdelphij BIO_printf(out, "."); 371296341Sdelphij (void)BIO_flush(out); 372296341Sdelphij /* check key */ 373296341Sdelphij if (!EC_KEY_check_key(eckey)) { 374296341Sdelphij BIO_printf(out, " failed\n"); 375296341Sdelphij goto builtin_err; 376296341Sdelphij } 377296341Sdelphij BIO_printf(out, "."); 378296341Sdelphij (void)BIO_flush(out); 379296341Sdelphij /* create signature */ 380296341Sdelphij sig_len = ECDSA_size(eckey); 381296341Sdelphij if ((signature = OPENSSL_malloc(sig_len)) == NULL) 382296341Sdelphij goto builtin_err; 383296341Sdelphij if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { 384296341Sdelphij BIO_printf(out, " failed\n"); 385296341Sdelphij goto builtin_err; 386296341Sdelphij } 387296341Sdelphij BIO_printf(out, "."); 388296341Sdelphij (void)BIO_flush(out); 389296341Sdelphij /* verify signature */ 390296341Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { 391296341Sdelphij BIO_printf(out, " failed\n"); 392296341Sdelphij goto builtin_err; 393296341Sdelphij } 394296341Sdelphij BIO_printf(out, "."); 395296341Sdelphij (void)BIO_flush(out); 396296341Sdelphij /* verify signature with the wrong key */ 397296341Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { 398296341Sdelphij BIO_printf(out, " failed\n"); 399296341Sdelphij goto builtin_err; 400296341Sdelphij } 401296341Sdelphij BIO_printf(out, "."); 402296341Sdelphij (void)BIO_flush(out); 403296341Sdelphij /* wrong digest */ 404296341Sdelphij if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { 405296341Sdelphij BIO_printf(out, " failed\n"); 406296341Sdelphij goto builtin_err; 407296341Sdelphij } 408296341Sdelphij BIO_printf(out, "."); 409296341Sdelphij (void)BIO_flush(out); 410296341Sdelphij /* wrong length */ 411296341Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) { 412296341Sdelphij BIO_printf(out, " failed\n"); 413296341Sdelphij goto builtin_err; 414296341Sdelphij } 415296341Sdelphij BIO_printf(out, "."); 416296341Sdelphij (void)BIO_flush(out); 417237657Sjkim 418296341Sdelphij /* 419296341Sdelphij * Modify a single byte of the signature: to ensure we don't garble 420296341Sdelphij * the ASN1 structure, we read the raw signature and modify a byte in 421296341Sdelphij * one of the bignums directly. 422296341Sdelphij */ 423296341Sdelphij sig_ptr = signature; 424296341Sdelphij if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) { 425296341Sdelphij BIO_printf(out, " failed\n"); 426296341Sdelphij goto builtin_err; 427296341Sdelphij } 428237657Sjkim 429296341Sdelphij /* Store the two BIGNUMs in raw_buf. */ 430296341Sdelphij r_len = BN_num_bytes(ecdsa_sig->r); 431296341Sdelphij s_len = BN_num_bytes(ecdsa_sig->s); 432296341Sdelphij bn_len = (degree + 7) / 8; 433296341Sdelphij if ((r_len > bn_len) || (s_len > bn_len)) { 434296341Sdelphij BIO_printf(out, " failed\n"); 435296341Sdelphij goto builtin_err; 436296341Sdelphij } 437296341Sdelphij buf_len = 2 * bn_len; 438296341Sdelphij if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL) 439296341Sdelphij goto builtin_err; 440296341Sdelphij /* Pad the bignums with leading zeroes. */ 441296341Sdelphij memset(raw_buf, 0, buf_len); 442296341Sdelphij BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len); 443296341Sdelphij BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len); 444237657Sjkim 445296341Sdelphij /* Modify a single byte in the buffer. */ 446296341Sdelphij offset = raw_buf[10] % buf_len; 447296341Sdelphij dirt = raw_buf[11] ? raw_buf[11] : 1; 448296341Sdelphij raw_buf[offset] ^= dirt; 449296341Sdelphij /* Now read the BIGNUMs back in from raw_buf. */ 450296341Sdelphij if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || 451296341Sdelphij (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) 452296341Sdelphij goto builtin_err; 453160814Ssimon 454296341Sdelphij sig_ptr2 = signature; 455296341Sdelphij sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); 456296341Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { 457296341Sdelphij BIO_printf(out, " failed\n"); 458296341Sdelphij goto builtin_err; 459296341Sdelphij } 460296341Sdelphij /* 461296341Sdelphij * Sanity check: undo the modification and verify signature. 462296341Sdelphij */ 463296341Sdelphij raw_buf[offset] ^= dirt; 464296341Sdelphij if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || 465296341Sdelphij (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) 466296341Sdelphij goto builtin_err; 467160814Ssimon 468296341Sdelphij sig_ptr2 = signature; 469296341Sdelphij sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); 470296341Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { 471296341Sdelphij BIO_printf(out, " failed\n"); 472296341Sdelphij goto builtin_err; 473296341Sdelphij } 474296341Sdelphij BIO_printf(out, "."); 475296341Sdelphij (void)BIO_flush(out); 476160814Ssimon 477296341Sdelphij BIO_printf(out, " ok\n"); 478296341Sdelphij /* cleanup */ 479296341Sdelphij /* clean bogus errors */ 480296341Sdelphij ERR_clear_error(); 481296341Sdelphij OPENSSL_free(signature); 482296341Sdelphij signature = NULL; 483296341Sdelphij EC_KEY_free(eckey); 484296341Sdelphij eckey = NULL; 485296341Sdelphij EC_KEY_free(wrong_eckey); 486296341Sdelphij wrong_eckey = NULL; 487296341Sdelphij ECDSA_SIG_free(ecdsa_sig); 488296341Sdelphij ecdsa_sig = NULL; 489296341Sdelphij OPENSSL_free(raw_buf); 490296341Sdelphij raw_buf = NULL; 491296341Sdelphij } 492296341Sdelphij 493296341Sdelphij ret = 1; 494296341Sdelphij builtin_err: 495296341Sdelphij if (eckey) 496296341Sdelphij EC_KEY_free(eckey); 497296341Sdelphij if (wrong_eckey) 498296341Sdelphij EC_KEY_free(wrong_eckey); 499296341Sdelphij if (ecdsa_sig) 500296341Sdelphij ECDSA_SIG_free(ecdsa_sig); 501296341Sdelphij if (signature) 502296341Sdelphij OPENSSL_free(signature); 503296341Sdelphij if (raw_buf) 504296341Sdelphij OPENSSL_free(raw_buf); 505296341Sdelphij if (curves) 506296341Sdelphij OPENSSL_free(curves); 507296341Sdelphij 508296341Sdelphij return ret; 509296341Sdelphij} 510296341Sdelphij 511160814Ssimonint main(void) 512296341Sdelphij{ 513296341Sdelphij int ret = 1; 514296341Sdelphij BIO *out; 515160814Ssimon 516296341Sdelphij out = BIO_new_fp(stdout, BIO_NOCLOSE); 517160814Ssimon 518296341Sdelphij /* enable memory leak checking unless explicitly disabled */ 519296341Sdelphij if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && 520296341Sdelphij (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { 521296341Sdelphij CRYPTO_malloc_debug_init(); 522296341Sdelphij CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 523296341Sdelphij } else { 524296341Sdelphij /* OPENSSL_DEBUG_MEMORY=off */ 525296341Sdelphij CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); 526296341Sdelphij } 527296341Sdelphij CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 528160814Ssimon 529296341Sdelphij ERR_load_crypto_strings(); 530160814Ssimon 531296341Sdelphij /* initialize the prng */ 532296341Sdelphij RAND_seed(rnd_seed, sizeof(rnd_seed)); 533296341Sdelphij 534296341Sdelphij /* the tests */ 535296341Sdelphij if (!x9_62_tests(out)) 536296341Sdelphij goto err; 537296341Sdelphij if (!test_builtin(out)) 538296341Sdelphij goto err; 539296341Sdelphij 540296341Sdelphij ret = 0; 541296341Sdelphij err: 542296341Sdelphij if (ret) 543296341Sdelphij BIO_printf(out, "\nECDSA test failed\n"); 544296341Sdelphij else 545296341Sdelphij BIO_printf(out, "\nECDSA test passed\n"); 546296341Sdelphij if (ret) 547296341Sdelphij ERR_print_errors(out); 548296341Sdelphij CRYPTO_cleanup_all_ex_data(); 549296341Sdelphij ERR_remove_thread_state(NULL); 550296341Sdelphij ERR_free_strings(); 551296341Sdelphij CRYPTO_mem_leaks(out); 552296341Sdelphij if (out != NULL) 553296341Sdelphij BIO_free(out); 554296341Sdelphij return ret; 555296341Sdelphij} 556160814Ssimon#endif 557