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> 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *, const BIGNUM *, EC_KEY *eckey); 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM **rp); 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const ECDSA_SIG *sig, EC_KEY *eckey); 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ECDSA_METHOD openssl_ecdsa_meth = { 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project "OpenSSL ECDSA method", 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ecdsa_do_sign, 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ecdsa_sign_setup, 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ecdsa_do_verify, 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL, /* init */ 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL, /* finish */ 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0, /* flags */ 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL /* app_data */ 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}; 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst ECDSA_METHOD *ECDSA_OpenSSL(void) 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return &openssl_ecdsa_meth; 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM **rp) 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *ctx = NULL; 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT *tmp_point=NULL; 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const EC_GROUP *group; 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0; 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx_in == NULL) 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ctx = BN_CTX_new()) == NULL) 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE); 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx = ctx_in; 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project k = BN_new(); /* this value is later returned in *kinvp */ 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r = BN_new(); /* this value is later returned in *rp */ 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project order = BN_new(); 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X = BN_new(); 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!k || !r || !order || !X) 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((tmp_point = EC_POINT_new(group)) == NULL) 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_GROUP_get_order(group, order, ctx)) 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do 136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* get random k */ 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_rand_range(k, order)) 140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, 142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (BN_is_zero(k)); 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 147ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom /* We do not want timing information to leak the length of k, 148ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom * so we compute G*k using an equivalent scalar of fixed 149ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom * bit-length. */ 150ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom 151ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom if (!BN_add(k, k, order)) goto err; 152ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom if (BN_num_bits(k) <= BN_num_bits(order)) 153ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom if (!BN_add(k, k, order)) goto err; 154ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom 155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* compute r the x-coordinate of generator * k */ 156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) 157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GFp(group, 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmp_point, X, NULL, ctx)) 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); 167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 170392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_EC2M 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else /* NID_X9_62_characteristic_two_field */ 172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GF2m(group, 174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmp_point, X, NULL, ctx)) 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_nnmod(r, X, order, ctx)) 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (BN_is_zero(r)); 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* compute the inverse of k */ 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_inverse(k, k, order, ctx)) 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* clear old values if necessary */ 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (*rp != NULL) 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(*rp); 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (*kinvp != NULL) 199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(*kinvp); 200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* save the pre-computed values */ 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *rp = r; 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *kinvp = k; 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ret) 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (k != NULL) BN_clear_free(k); 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (r != NULL) BN_clear_free(r); 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx_in == NULL) 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(ctx); 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (order != NULL) 213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(order); 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (tmp_point != NULL) 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT_free(tmp_point); 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (X) 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(X); 218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 22598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom int ok = 0, i; 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL; 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *ckinv; 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *ctx = NULL; 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const EC_GROUP *group; 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSA_SIG *ret; 231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSA_DATA *ecdsa; 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *priv_key; 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ecdsa = ecdsa_check(eckey); 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project group = EC_KEY_get0_group(eckey); 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project priv_key = EC_KEY_get0_private_key(eckey); 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (group == NULL || priv_key == NULL || ecdsa == NULL) 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = ECDSA_SIG_new(); 245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ret) 246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); 248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project s = ret->s; 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_GROUP_get_order(group, order, ctx)) 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 26498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom i = BN_num_bits(order); 26598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom /* Need to truncate digest if it is too long: first truncate whole 26698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom * bytes. 26798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom */ 26898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if (8 * dgst_len > i) 26998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom dgst_len = (i + 7)/8; 27098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if (!BN_bin2bn(dgst, dgst_len, m)) 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 27298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 27598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom /* If still too long truncate remaining bits with a shift */ 27698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (in_kinv == NULL || in_r == NULL) 284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB); 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ckinv = kinv; 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ckinv = in_kinv; 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_copy(ret->r, in_r) == NULL) 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_add_quick(s, tmp, m, order)) 308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_mul(s, s, ckinv, order, ctx)) 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_is_zero(s)) 318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* if kinv and r have been supplied by the caller 320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * don't to generate new kinv and r values */ 321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (in_kinv != NULL && in_r != NULL) 322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES); 324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* s != 0 => we have a valid signature */ 329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (1); 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ok = 1; 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ok) 336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSA_SIG_free(ret); 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = NULL; 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx) 341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(ctx); 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (m) 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(m); 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (tmp) 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(tmp); 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (order) 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(order); 348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (kinv) 349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(kinv); 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const ECDSA_SIG *sig, EC_KEY *eckey) 355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 35698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom int ret = -1, i; 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *ctx; 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *order, *u1, *u2, *m, *X; 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT *point = NULL; 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const EC_GROUP *group; 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const EC_POINT *pub_key; 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* check input values */ 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx = BN_CTX_new(); 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ctx) 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_start(ctx); 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project order = BN_CTX_get(ctx); 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project u1 = BN_CTX_get(ctx); 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project u2 = BN_CTX_get(ctx); 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project m = BN_CTX_get(ctx); 382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X = BN_CTX_get(ctx); 383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!X) 384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_GROUP_get_order(group, order, ctx)) 390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); 392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || 396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || 397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) 398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); 400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; /* signature is invalid */ 401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* calculate tmp1 = inv(S) mod order */ 404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_inverse(u2, sig->s, order, ctx)) 405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* digest -> m */ 41098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom i = BN_num_bits(order); 41198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom /* Need to truncate digest if it is too long: first truncate whole 41298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom * bytes. 41398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom */ 41498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if (8 * dgst_len > i) 41598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom dgst_len = (i + 7)/8; 416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_bin2bn(dgst, dgst_len, m)) 417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 42198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom /* If still too long truncate remaining bits with a shift */ 42298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) 42398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom { 42498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 42598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom goto err; 42698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom } 427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* u1 = m * tmp mod order */ 428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_mul(u1, m, u2, order, ctx)) 429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* u2 = r * w mod q */ 434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) 435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((point = EC_POINT_new(group)) == NULL) 441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); 443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) 446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); 448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GFp(group, 453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project point, X, NULL, ctx)) 454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); 456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 459392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_EC2M 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else /* NID_X9_62_characteristic_two_field */ 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GF2m(group, 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project point, X, NULL, ctx)) 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 469392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_nnmod(u1, X, order, ctx)) 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* if the signature is correct u1 is equal to sig->r */ 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (BN_ucmp(u1, sig->r) == 0); 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_end(ctx); 479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(ctx); 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (point) 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT_free(point); 482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 484