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 13296465Sdelphij * 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 * 61296465Sdelphij * 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 * 67296465Sdelphij * 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 79296465Sdelphijint main(int argc, char *argv[]) 80296465Sdelphij{ 81296465Sdelphij puts("Elliptic curves are disabled."); 82296465Sdelphij return 0; 83296465Sdelphij} 84160814Ssimon#else 85160814Ssimon 86296465Sdelphij# include <openssl/crypto.h> 87296465Sdelphij# include <openssl/bio.h> 88296465Sdelphij# include <openssl/evp.h> 89296465Sdelphij# include <openssl/bn.h> 90296465Sdelphij# include <openssl/ecdsa.h> 91296465Sdelphij# ifndef OPENSSL_NO_ENGINE 92296465Sdelphij# include <openssl/engine.h> 93296465Sdelphij# endif 94296465Sdelphij# include <openssl/err.h> 95296465Sdelphij# include <openssl/rand.h> 96160814Ssimon 97160814Ssimonstatic const char rnd_seed[] = "string to make the random number generator " 98296465Sdelphij "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 110296465SdelphijRAND_METHOD fake_rand; 111160814Ssimonconst RAND_METHOD *old_rand; 112160814Ssimon 113160814Ssimonint change_rand(void) 114296465Sdelphij{ 115296465Sdelphij /* save old rand method */ 116296465Sdelphij if ((old_rand = RAND_get_rand_method()) == NULL) 117296465Sdelphij return 0; 118160814Ssimon 119296465Sdelphij fake_rand.seed = old_rand->seed; 120296465Sdelphij fake_rand.cleanup = old_rand->cleanup; 121296465Sdelphij fake_rand.add = old_rand->add; 122296465Sdelphij fake_rand.status = old_rand->status; 123296465Sdelphij /* use own random function */ 124296465Sdelphij fake_rand.bytes = fbytes; 125296465Sdelphij fake_rand.pseudorand = old_rand->bytes; 126296465Sdelphij /* set new RAND_METHOD */ 127296465Sdelphij if (!RAND_set_rand_method(&fake_rand)) 128296465Sdelphij return 0; 129296465Sdelphij return 1; 130296465Sdelphij} 131160814Ssimon 132160814Ssimonint restore_rand(void) 133296465Sdelphij{ 134296465Sdelphij if (!RAND_set_rand_method(old_rand)) 135296465Sdelphij return 0; 136296465Sdelphij else 137296465Sdelphij return 1; 138296465Sdelphij} 139160814Ssimon 140160814Ssimonstatic int fbytes_counter = 0; 141160814Ssimonstatic const char *numbers[8] = { 142296465Sdelphij "651056770906015076056810763456358567190100156695615665659", 143296465Sdelphij "6140507067065001063065065565667405560006161556565665656654", 144296465Sdelphij "8763001015071075675010661307616710783570106710677817767166" 145296465Sdelphij "71676178726717", 146296465Sdelphij "7000000175690566466555057817571571075705015757757057795755" 147296465Sdelphij "55657156756655", 148296465Sdelphij "1275552191113212300012030439187146164646146646466749494799", 149296465Sdelphij "1542725565216523985789236956265265265235675811949404040041", 150296465Sdelphij "1456427555219115346513212300075341203043918714616464614664" 151296465Sdelphij "64667494947990", 152296465Sdelphij "1712787255652165239672857892369562652652652356758119494040" 153296465Sdelphij "40041670216363" 154296465Sdelphij}; 155160814Ssimon 156160814Ssimonint fbytes(unsigned char *buf, int num) 157296465Sdelphij{ 158296465Sdelphij int ret; 159296465Sdelphij BIGNUM *tmp = NULL; 160160814Ssimon 161296465Sdelphij if (fbytes_counter >= 8) 162296465Sdelphij return 0; 163296465Sdelphij tmp = BN_new(); 164296465Sdelphij if (!tmp) 165296465Sdelphij return 0; 166296465Sdelphij if (!BN_dec2bn(&tmp, numbers[fbytes_counter])) { 167296465Sdelphij BN_free(tmp); 168296465Sdelphij return 0; 169296465Sdelphij } 170296465Sdelphij fbytes_counter++; 171296465Sdelphij if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf)) 172296465Sdelphij ret = 0; 173296465Sdelphij else 174296465Sdelphij ret = 1; 175296465Sdelphij if (tmp) 176296465Sdelphij BN_free(tmp); 177296465Sdelphij return ret; 178296465Sdelphij} 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) 182296465Sdelphij{ 183296465Sdelphij int ret = 0; 184296465Sdelphij const char message[] = "abc"; 185296465Sdelphij unsigned char digest[20]; 186296465Sdelphij unsigned int dgst_len = 0; 187296465Sdelphij EVP_MD_CTX md_ctx; 188296465Sdelphij EC_KEY *key = NULL; 189296465Sdelphij ECDSA_SIG *signature = NULL; 190296465Sdelphij BIGNUM *r = NULL, *s = NULL; 191160814Ssimon 192296465Sdelphij EVP_MD_CTX_init(&md_ctx); 193296465Sdelphij /* get the message digest */ 194296465Sdelphij EVP_DigestInit(&md_ctx, EVP_ecdsa()); 195296465Sdelphij EVP_DigestUpdate(&md_ctx, (const void *)message, 3); 196296465Sdelphij EVP_DigestFinal(&md_ctx, digest, &dgst_len); 197160814Ssimon 198296465Sdelphij BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid)); 199296465Sdelphij /* create the key */ 200296465Sdelphij if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) 201296465Sdelphij goto x962_int_err; 202296465Sdelphij if (!EC_KEY_generate_key(key)) 203296465Sdelphij goto x962_int_err; 204296465Sdelphij BIO_printf(out, "."); 205296465Sdelphij (void)BIO_flush(out); 206296465Sdelphij /* create the signature */ 207296465Sdelphij signature = ECDSA_do_sign(digest, 20, key); 208296465Sdelphij if (signature == NULL) 209296465Sdelphij goto x962_int_err; 210296465Sdelphij BIO_printf(out, "."); 211296465Sdelphij (void)BIO_flush(out); 212296465Sdelphij /* compare the created signature with the expected signature */ 213296465Sdelphij if ((r = BN_new()) == NULL || (s = BN_new()) == NULL) 214296465Sdelphij goto x962_int_err; 215296465Sdelphij if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in)) 216296465Sdelphij goto x962_int_err; 217296465Sdelphij if (BN_cmp(signature->r, r) || BN_cmp(signature->s, s)) 218296465Sdelphij goto x962_int_err; 219296465Sdelphij BIO_printf(out, "."); 220296465Sdelphij (void)BIO_flush(out); 221296465Sdelphij /* verify the signature */ 222296465Sdelphij if (ECDSA_do_verify(digest, 20, signature, key) != 1) 223296465Sdelphij goto x962_int_err; 224296465Sdelphij BIO_printf(out, "."); 225296465Sdelphij (void)BIO_flush(out); 226160814Ssimon 227296465Sdelphij BIO_printf(out, " ok\n"); 228296465Sdelphij ret = 1; 229296465Sdelphij x962_int_err: 230296465Sdelphij if (!ret) 231296465Sdelphij BIO_printf(out, " failed\n"); 232296465Sdelphij if (key) 233296465Sdelphij EC_KEY_free(key); 234296465Sdelphij if (signature) 235296465Sdelphij ECDSA_SIG_free(signature); 236296465Sdelphij if (r) 237296465Sdelphij BN_free(r); 238296465Sdelphij if (s) 239296465Sdelphij BN_free(s); 240296465Sdelphij EVP_MD_CTX_cleanup(&md_ctx); 241296465Sdelphij return ret; 242296465Sdelphij} 243160814Ssimon 244160814Ssimonint x9_62_tests(BIO *out) 245296465Sdelphij{ 246296465Sdelphij int ret = 0; 247160814Ssimon 248296465Sdelphij BIO_printf(out, "some tests from X9.62:\n"); 249160814Ssimon 250296465Sdelphij /* set own rand method */ 251296465Sdelphij if (!change_rand()) 252296465Sdelphij goto x962_err; 253160814Ssimon 254296465Sdelphij if (!x9_62_test_internal(out, NID_X9_62_prime192v1, 255296465Sdelphij "3342403536405981729393488334694600415596881826869351677613", 256296465Sdelphij "5735822328888155254683894997897571951568553642892029982342")) 257296465Sdelphij goto x962_err; 258296465Sdelphij if (!x9_62_test_internal(out, NID_X9_62_prime239v1, 259296465Sdelphij "3086361431751678114926225473006680188549593787585317781474" 260296465Sdelphij "62058306432176", 261296465Sdelphij "3238135532097973577080787768312505059318910517550078427819" 262296465Sdelphij "78505179448783")) 263296465Sdelphij goto x962_err; 264296465Sdelphij if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1, 265296465Sdelphij "87194383164871543355722284926904419997237591535066528048", 266296465Sdelphij "308992691965804947361541664549085895292153777025772063598")) 267296465Sdelphij goto x962_err; 268296465Sdelphij if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1, 269296465Sdelphij "2159633321041961198501834003903461262881815148684178964245" 270296465Sdelphij "5876922391552", 271296465Sdelphij "1970303740007316867383349976549972270528498040721988191026" 272296465Sdelphij "49413465737174")) 273296465Sdelphij goto x962_err; 274160814Ssimon 275296465Sdelphij ret = 1; 276296465Sdelphij x962_err: 277296465Sdelphij if (!restore_rand()) 278296465Sdelphij ret = 0; 279296465Sdelphij return ret; 280296465Sdelphij} 281160814Ssimon 282160814Ssimonint test_builtin(BIO *out) 283296465Sdelphij{ 284296465Sdelphij EC_builtin_curve *curves = NULL; 285296465Sdelphij size_t crv_len = 0, n = 0; 286296465Sdelphij EC_KEY *eckey = NULL, *wrong_eckey = NULL; 287296465Sdelphij EC_GROUP *group; 288296465Sdelphij ECDSA_SIG *ecdsa_sig = NULL; 289296465Sdelphij unsigned char digest[20], wrong_digest[20]; 290296465Sdelphij unsigned char *signature = NULL; 291296465Sdelphij const unsigned char *sig_ptr; 292296465Sdelphij unsigned char *sig_ptr2; 293296465Sdelphij unsigned char *raw_buf = NULL; 294296465Sdelphij unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; 295296465Sdelphij int nid, ret = 0; 296160814Ssimon 297296465Sdelphij /* fill digest values with some random data */ 298296465Sdelphij if (!RAND_pseudo_bytes(digest, 20) || 299296465Sdelphij !RAND_pseudo_bytes(wrong_digest, 20)) { 300296465Sdelphij BIO_printf(out, "ERROR: unable to get random data\n"); 301296465Sdelphij goto builtin_err; 302296465Sdelphij } 303160814Ssimon 304296465Sdelphij /* 305296465Sdelphij * create and verify a ecdsa signature with every availble curve (with ) 306296465Sdelphij */ 307296465Sdelphij BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " 308296465Sdelphij "with some internal curves:\n"); 309160814Ssimon 310296465Sdelphij /* get a list of all internal curves */ 311296465Sdelphij crv_len = EC_get_builtin_curves(NULL, 0); 312160814Ssimon 313296465Sdelphij curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); 314160814Ssimon 315296465Sdelphij if (curves == NULL) { 316296465Sdelphij BIO_printf(out, "malloc error\n"); 317296465Sdelphij goto builtin_err; 318296465Sdelphij } 319160814Ssimon 320296465Sdelphij if (!EC_get_builtin_curves(curves, crv_len)) { 321296465Sdelphij BIO_printf(out, "unable to get internal curves\n"); 322296465Sdelphij goto builtin_err; 323296465Sdelphij } 324160814Ssimon 325296465Sdelphij /* now create and verify a signature for every curve */ 326296465Sdelphij for (n = 0; n < crv_len; n++) { 327296465Sdelphij unsigned char dirt, offset; 328237998Sjkim 329296465Sdelphij nid = curves[n].nid; 330296465Sdelphij if (nid == NID_ipsec4) 331296465Sdelphij continue; 332296465Sdelphij /* create new ecdsa key (== EC_KEY) */ 333296465Sdelphij if ((eckey = EC_KEY_new()) == NULL) 334296465Sdelphij goto builtin_err; 335296465Sdelphij group = EC_GROUP_new_by_curve_name(nid); 336296465Sdelphij if (group == NULL) 337296465Sdelphij goto builtin_err; 338296465Sdelphij if (EC_KEY_set_group(eckey, group) == 0) 339296465Sdelphij goto builtin_err; 340296465Sdelphij EC_GROUP_free(group); 341296465Sdelphij degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); 342296465Sdelphij if (degree < 160) 343296465Sdelphij /* drop the curve */ 344296465Sdelphij { 345296465Sdelphij EC_KEY_free(eckey); 346296465Sdelphij eckey = NULL; 347296465Sdelphij continue; 348296465Sdelphij } 349296465Sdelphij BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); 350296465Sdelphij /* create key */ 351296465Sdelphij if (!EC_KEY_generate_key(eckey)) { 352296465Sdelphij BIO_printf(out, " failed\n"); 353296465Sdelphij goto builtin_err; 354296465Sdelphij } 355296465Sdelphij /* create second key */ 356296465Sdelphij if ((wrong_eckey = EC_KEY_new()) == NULL) 357296465Sdelphij goto builtin_err; 358296465Sdelphij group = EC_GROUP_new_by_curve_name(nid); 359296465Sdelphij if (group == NULL) 360296465Sdelphij goto builtin_err; 361296465Sdelphij if (EC_KEY_set_group(wrong_eckey, group) == 0) 362296465Sdelphij goto builtin_err; 363296465Sdelphij EC_GROUP_free(group); 364296465Sdelphij if (!EC_KEY_generate_key(wrong_eckey)) { 365296465Sdelphij BIO_printf(out, " failed\n"); 366296465Sdelphij goto builtin_err; 367296465Sdelphij } 368237998Sjkim 369296465Sdelphij BIO_printf(out, "."); 370296465Sdelphij (void)BIO_flush(out); 371296465Sdelphij /* check key */ 372296465Sdelphij if (!EC_KEY_check_key(eckey)) { 373296465Sdelphij BIO_printf(out, " failed\n"); 374296465Sdelphij goto builtin_err; 375296465Sdelphij } 376296465Sdelphij BIO_printf(out, "."); 377296465Sdelphij (void)BIO_flush(out); 378296465Sdelphij /* create signature */ 379296465Sdelphij sig_len = ECDSA_size(eckey); 380296465Sdelphij if ((signature = OPENSSL_malloc(sig_len)) == NULL) 381296465Sdelphij goto builtin_err; 382296465Sdelphij if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { 383296465Sdelphij BIO_printf(out, " failed\n"); 384296465Sdelphij goto builtin_err; 385296465Sdelphij } 386296465Sdelphij BIO_printf(out, "."); 387296465Sdelphij (void)BIO_flush(out); 388296465Sdelphij /* verify signature */ 389296465Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { 390296465Sdelphij BIO_printf(out, " failed\n"); 391296465Sdelphij goto builtin_err; 392296465Sdelphij } 393296465Sdelphij BIO_printf(out, "."); 394296465Sdelphij (void)BIO_flush(out); 395296465Sdelphij /* verify signature with the wrong key */ 396296465Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { 397296465Sdelphij BIO_printf(out, " failed\n"); 398296465Sdelphij goto builtin_err; 399296465Sdelphij } 400296465Sdelphij BIO_printf(out, "."); 401296465Sdelphij (void)BIO_flush(out); 402296465Sdelphij /* wrong digest */ 403296465Sdelphij if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { 404296465Sdelphij BIO_printf(out, " failed\n"); 405296465Sdelphij goto builtin_err; 406296465Sdelphij } 407296465Sdelphij BIO_printf(out, "."); 408296465Sdelphij (void)BIO_flush(out); 409296465Sdelphij /* wrong length */ 410296465Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) { 411296465Sdelphij BIO_printf(out, " failed\n"); 412296465Sdelphij goto builtin_err; 413296465Sdelphij } 414296465Sdelphij BIO_printf(out, "."); 415296465Sdelphij (void)BIO_flush(out); 416237998Sjkim 417296465Sdelphij /* 418296465Sdelphij * Modify a single byte of the signature: to ensure we don't garble 419296465Sdelphij * the ASN1 structure, we read the raw signature and modify a byte in 420296465Sdelphij * one of the bignums directly. 421296465Sdelphij */ 422296465Sdelphij sig_ptr = signature; 423296465Sdelphij if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) { 424296465Sdelphij BIO_printf(out, " failed\n"); 425296465Sdelphij goto builtin_err; 426296465Sdelphij } 427237998Sjkim 428296465Sdelphij /* Store the two BIGNUMs in raw_buf. */ 429296465Sdelphij r_len = BN_num_bytes(ecdsa_sig->r); 430296465Sdelphij s_len = BN_num_bytes(ecdsa_sig->s); 431296465Sdelphij bn_len = (degree + 7) / 8; 432296465Sdelphij if ((r_len > bn_len) || (s_len > bn_len)) { 433296465Sdelphij BIO_printf(out, " failed\n"); 434296465Sdelphij goto builtin_err; 435296465Sdelphij } 436296465Sdelphij buf_len = 2 * bn_len; 437296465Sdelphij if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL) 438296465Sdelphij goto builtin_err; 439296465Sdelphij /* Pad the bignums with leading zeroes. */ 440296465Sdelphij memset(raw_buf, 0, buf_len); 441296465Sdelphij BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len); 442296465Sdelphij BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len); 443237998Sjkim 444296465Sdelphij /* Modify a single byte in the buffer. */ 445296465Sdelphij offset = raw_buf[10] % buf_len; 446296465Sdelphij dirt = raw_buf[11] ? raw_buf[11] : 1; 447296465Sdelphij raw_buf[offset] ^= dirt; 448296465Sdelphij /* Now read the BIGNUMs back in from raw_buf. */ 449296465Sdelphij if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || 450296465Sdelphij (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) 451296465Sdelphij goto builtin_err; 452160814Ssimon 453296465Sdelphij sig_ptr2 = signature; 454296465Sdelphij sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); 455296465Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { 456296465Sdelphij BIO_printf(out, " failed\n"); 457296465Sdelphij goto builtin_err; 458296465Sdelphij } 459296465Sdelphij /* 460296465Sdelphij * Sanity check: undo the modification and verify signature. 461296465Sdelphij */ 462296465Sdelphij raw_buf[offset] ^= dirt; 463296465Sdelphij if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || 464296465Sdelphij (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) 465296465Sdelphij goto builtin_err; 466160814Ssimon 467296465Sdelphij sig_ptr2 = signature; 468296465Sdelphij sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); 469296465Sdelphij if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { 470296465Sdelphij BIO_printf(out, " failed\n"); 471296465Sdelphij goto builtin_err; 472296465Sdelphij } 473296465Sdelphij BIO_printf(out, "."); 474296465Sdelphij (void)BIO_flush(out); 475160814Ssimon 476296465Sdelphij BIO_printf(out, " ok\n"); 477296465Sdelphij /* cleanup */ 478296465Sdelphij /* clean bogus errors */ 479296465Sdelphij ERR_clear_error(); 480296465Sdelphij OPENSSL_free(signature); 481296465Sdelphij signature = NULL; 482296465Sdelphij EC_KEY_free(eckey); 483296465Sdelphij eckey = NULL; 484296465Sdelphij EC_KEY_free(wrong_eckey); 485296465Sdelphij wrong_eckey = NULL; 486296465Sdelphij ECDSA_SIG_free(ecdsa_sig); 487296465Sdelphij ecdsa_sig = NULL; 488296465Sdelphij OPENSSL_free(raw_buf); 489296465Sdelphij raw_buf = NULL; 490296465Sdelphij } 491296465Sdelphij 492296465Sdelphij ret = 1; 493296465Sdelphij builtin_err: 494296465Sdelphij if (eckey) 495296465Sdelphij EC_KEY_free(eckey); 496296465Sdelphij if (wrong_eckey) 497296465Sdelphij EC_KEY_free(wrong_eckey); 498296465Sdelphij if (ecdsa_sig) 499296465Sdelphij ECDSA_SIG_free(ecdsa_sig); 500296465Sdelphij if (signature) 501296465Sdelphij OPENSSL_free(signature); 502296465Sdelphij if (raw_buf) 503296465Sdelphij OPENSSL_free(raw_buf); 504296465Sdelphij if (curves) 505296465Sdelphij OPENSSL_free(curves); 506296465Sdelphij 507296465Sdelphij return ret; 508296465Sdelphij} 509296465Sdelphij 510160814Ssimonint main(void) 511296465Sdelphij{ 512296465Sdelphij int ret = 1; 513296465Sdelphij BIO *out; 514160814Ssimon 515296465Sdelphij out = BIO_new_fp(stdout, BIO_NOCLOSE); 516160814Ssimon 517296465Sdelphij /* enable memory leak checking unless explicitly disabled */ 518296465Sdelphij if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && 519296465Sdelphij (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { 520296465Sdelphij CRYPTO_malloc_debug_init(); 521296465Sdelphij CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 522296465Sdelphij } else { 523296465Sdelphij /* OPENSSL_DEBUG_MEMORY=off */ 524296465Sdelphij CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); 525296465Sdelphij } 526296465Sdelphij CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 527160814Ssimon 528296465Sdelphij ERR_load_crypto_strings(); 529160814Ssimon 530296465Sdelphij /* initialize the prng */ 531296465Sdelphij RAND_seed(rnd_seed, sizeof(rnd_seed)); 532296465Sdelphij 533296465Sdelphij /* the tests */ 534296465Sdelphij if (!x9_62_tests(out)) 535296465Sdelphij goto err; 536296465Sdelphij if (!test_builtin(out)) 537296465Sdelphij goto err; 538296465Sdelphij 539296465Sdelphij ret = 0; 540296465Sdelphij err: 541296465Sdelphij if (ret) 542296465Sdelphij BIO_printf(out, "\nECDSA test failed\n"); 543296465Sdelphij else 544296465Sdelphij BIO_printf(out, "\nECDSA test passed\n"); 545296465Sdelphij if (ret) 546296465Sdelphij ERR_print_errors(out); 547296465Sdelphij CRYPTO_cleanup_all_ex_data(); 548296465Sdelphij ERR_remove_state(0); 549296465Sdelphij ERR_free_strings(); 550296465Sdelphij CRYPTO_mem_leaks(out); 551296465Sdelphij if (out != NULL) 552296465Sdelphij BIO_free(out); 553296465Sdelphij return ret; 554296465Sdelphij} 555160814Ssimon#endif 556