1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/ecdsa/ecs_ossl.c */ 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Written by Nils Larsch for the OpenSSL project 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved. 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the documentation and/or other materials provided with the 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * distribution. 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * software must display the following acknowledgment: 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * endorse or promote products derived from this software without 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * prior written permission. For written permission, please contact 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * openssl-core@OpenSSL.org. 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL" 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * nor may "OpenSSL" appear in their names without prior written 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * permission of the OpenSSL Project. 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * acknowledgment: 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE. 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ==================================================================== 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com). This product includes software written by Tim 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com). 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "ecs_locl.h" 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h> 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/obj_mac.h> 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/bn.h> 6323b9568fd705172c870175f42556ae21861da399Adam Langley#include <openssl/rand.h> 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *, const BIGNUM *, EC_KEY *eckey); 6723b9568fd705172c870175f42556ae21861da399Adam Langleystatic int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, 6823b9568fd705172c870175f42556ae21861da399Adam Langley BIGNUM **kinvp, BIGNUM **rp, 6923b9568fd705172c870175f42556ae21861da399Adam Langley const unsigned char *dgst, int dlen); 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const ECDSA_SIG *sig, EC_KEY *eckey); 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ECDSA_METHOD openssl_ecdsa_meth = { 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project "OpenSSL ECDSA method", 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ecdsa_do_sign, 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ecdsa_sign_setup, 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ecdsa_do_verify, 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL, /* init */ 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL, /* finish */ 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0, /* flags */ 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL /* app_data */ 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}; 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst ECDSA_METHOD *ECDSA_OpenSSL(void) 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return &openssl_ecdsa_meth; 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 9123b9568fd705172c870175f42556ae21861da399Adam Langleystatic int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, 9223b9568fd705172c870175f42556ae21861da399Adam Langley BIGNUM **kinvp, BIGNUM **rp, 9323b9568fd705172c870175f42556ae21861da399Adam Langley const unsigned char *dgst, int dlen) 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *ctx = NULL; 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT *tmp_point=NULL; 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const EC_GROUP *group; 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0; 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx_in == NULL) 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ctx = BN_CTX_new()) == NULL) 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE); 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx = ctx_in; 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project k = BN_new(); /* this value is later returned in *kinvp */ 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r = BN_new(); /* this value is later returned in *rp */ 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project order = BN_new(); 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X = BN_new(); 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!k || !r || !order || !X) 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((tmp_point = EC_POINT_new(group)) == NULL) 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_GROUP_get_order(group, order, ctx)) 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* get random k */ 141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do 14223b9568fd705172c870175f42556ae21861da399Adam Langley#ifndef OPENSSL_NO_SHA512 14323b9568fd705172c870175f42556ae21861da399Adam Langley if (EC_KEY_get_nonce_from_hash(eckey)) 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 14523b9568fd705172c870175f42556ae21861da399Adam Langley if (!BN_generate_dsa_nonce( 14623b9568fd705172c870175f42556ae21861da399Adam Langley k, order, 14723b9568fd705172c870175f42556ae21861da399Adam Langley EC_KEY_get0_private_key(eckey), 14823b9568fd705172c870175f42556ae21861da399Adam Langley dgst, dlen, ctx)) 14923b9568fd705172c870175f42556ae21861da399Adam Langley { 15023b9568fd705172c870175f42556ae21861da399Adam Langley ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, 15123b9568fd705172c870175f42556ae21861da399Adam Langley ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); 15223b9568fd705172c870175f42556ae21861da399Adam Langley goto err; 15323b9568fd705172c870175f42556ae21861da399Adam Langley } 15423b9568fd705172c870175f42556ae21861da399Adam Langley } 15523b9568fd705172c870175f42556ae21861da399Adam Langley else 15623b9568fd705172c870175f42556ae21861da399Adam Langley#endif 15723b9568fd705172c870175f42556ae21861da399Adam Langley { 15823b9568fd705172c870175f42556ae21861da399Adam Langley if (!BN_rand_range(k, order)) 15923b9568fd705172c870175f42556ae21861da399Adam Langley { 16023b9568fd705172c870175f42556ae21861da399Adam Langley ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, 16123b9568fd705172c870175f42556ae21861da399Adam Langley ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); 16223b9568fd705172c870175f42556ae21861da399Adam Langley goto err; 16323b9568fd705172c870175f42556ae21861da399Adam Langley } 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (BN_is_zero(k)); 166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 167ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom /* We do not want timing information to leak the length of k, 168ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom * so we compute G*k using an equivalent scalar of fixed 169ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom * bit-length. */ 170ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom 171ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom if (!BN_add(k, k, order)) goto err; 172ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom if (BN_num_bits(k) <= BN_num_bits(order)) 173ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom if (!BN_add(k, k, order)) goto err; 174ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* compute r the x-coordinate of generator * k */ 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GFp(group, 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmp_point, X, NULL, ctx)) 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); 187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_EC2M 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else /* NID_X9_62_characteristic_two_field */ 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GF2m(group, 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmp_point, X, NULL, ctx)) 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_nnmod(r, X, order, ctx)) 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (BN_is_zero(r)); 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* compute the inverse of k */ 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_inverse(k, k, order, ctx)) 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); 213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* clear old values if necessary */ 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (*rp != NULL) 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(*rp); 218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (*kinvp != NULL) 219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(*kinvp); 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* save the pre-computed values */ 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *rp = r; 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *kinvp = k; 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ret) 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (k != NULL) BN_clear_free(k); 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (r != NULL) BN_clear_free(r); 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx_in == NULL) 231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(ctx); 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (order != NULL) 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(order); 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (tmp_point != NULL) 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT_free(tmp_point); 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (X) 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(X); 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) 244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 24598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom int ok = 0, i; 246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL; 247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *ckinv; 248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *ctx = NULL; 249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const EC_GROUP *group; 250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSA_SIG *ret; 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSA_DATA *ecdsa; 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *priv_key; 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ecdsa = ecdsa_check(eckey); 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project group = EC_KEY_get0_group(eckey); 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project priv_key = EC_KEY_get0_private_key(eckey); 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (group == NULL || priv_key == NULL || ecdsa == NULL) 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = ECDSA_SIG_new(); 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ret) 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project s = ret->s; 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_GROUP_get_order(group, order, ctx)) 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 28498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom i = BN_num_bits(order); 28598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom /* Need to truncate digest if it is too long: first truncate whole 28698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom * bytes. 28798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom */ 28898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if (8 * dgst_len > i) 28998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom dgst_len = (i + 7)/8; 29098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if (!BN_bin2bn(dgst, dgst_len, m)) 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 29298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 29598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom /* If still too long truncate remaining bits with a shift */ 29698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (in_kinv == NULL || in_r == NULL) 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 30523b9568fd705172c870175f42556ae21861da399Adam Langley if (!ecdsa->meth->ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB); 308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ckinv = kinv; 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ckinv = in_kinv; 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_copy(ret->r, in_r) == NULL) 316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); 318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) 323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_add_quick(s, tmp, m, order)) 328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_mul(s, s, ckinv, order, ctx)) 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_is_zero(s)) 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* if kinv and r have been supplied by the caller 340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * don't to generate new kinv and r values */ 341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (in_kinv != NULL && in_r != NULL) 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES); 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* s != 0 => we have a valid signature */ 349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (1); 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ok = 1; 354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ok) 356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSA_SIG_free(ret); 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = NULL; 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx) 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(ctx); 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (m) 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(m); 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (tmp) 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(tmp); 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (order) 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(order); 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (kinv) 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(kinv); 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const ECDSA_SIG *sig, EC_KEY *eckey) 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 37698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom int ret = -1, i; 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *ctx; 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *order, *u1, *u2, *m, *X; 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT *point = NULL; 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const EC_GROUP *group; 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const EC_POINT *pub_key; 382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* check input values */ 384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || 385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) 386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); 388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx = BN_CTX_new(); 392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ctx) 393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); 395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_start(ctx); 398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project order = BN_CTX_get(ctx); 399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project u1 = BN_CTX_get(ctx); 400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project u2 = BN_CTX_get(ctx); 401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project m = BN_CTX_get(ctx); 402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X = BN_CTX_get(ctx); 403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!X) 404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_GROUP_get_order(group, order, ctx)) 410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); 412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || 416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || 417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) 418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); 420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; /* signature is invalid */ 421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* calculate tmp1 = inv(S) mod order */ 424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_inverse(u2, sig->s, order, ctx)) 425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* digest -> m */ 43098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom i = BN_num_bits(order); 43198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom /* Need to truncate digest if it is too long: first truncate whole 43298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom * bytes. 43398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom */ 43498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if (8 * dgst_len > i) 43598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom dgst_len = (i + 7)/8; 436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_bin2bn(dgst, dgst_len, m)) 437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 44198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom /* If still too long truncate remaining bits with a shift */ 44298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) 44398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom { 44498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 44598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom goto err; 44698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom } 447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* u1 = m * tmp mod order */ 448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_mul(u1, m, u2, order, ctx)) 449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* u2 = r * w mod q */ 454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) 455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((point = EC_POINT_new(group)) == NULL) 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GFp(group, 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project point, X, NULL, ctx)) 474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 479392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_EC2M 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else /* NID_X9_62_characteristic_two_field */ 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GF2m(group, 483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project point, X, NULL, ctx)) 484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); 486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 489392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_nnmod(u1, X, order, ctx)) 491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* if the signature is correct u1 is equal to sig->r */ 496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (BN_ucmp(u1, sig->r) == 0); 497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_end(ctx); 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(ctx); 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (point) 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT_free(point); 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 504