195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* ==================================================================== 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the above copyright 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the documentation and/or other materials provided with the 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * distribution. 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * software must display the following acknowledgment: 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software developed by the OpenSSL Project 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * endorse or promote products derived from this software without 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * prior written permission. For written permission, please contact 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * openssl-core@OpenSSL.org. 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5. Products derived from this software may not be called "OpenSSL" 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * nor may "OpenSSL" appear in their names without prior written 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * permission of the OpenSSL Project. 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6. Redistributions of any form whatsoever must retain the following 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * acknowledgment: 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software developed by the OpenSSL Project 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ==================================================================== 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This product includes cryptographic software written by Eric Young 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * (eay@cryptsoft.com). This product includes software written by Tim 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Hudson (tjh@cryptsoft.com). */ 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/ecdsa.h> 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/bn.h> 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h> 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/thread.h> 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "../ec/internal.h" 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned int *sig_len, EC_KEY *eckey) { 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return eckey->ecdsa_meth->sign(digest, digest_len, sig, sig_len, eckey); 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ECDSA_sign_ex(type, digest, digest_len, sig, sig_len, NULL, NULL, 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley eckey); 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ECDSA_verify(int type, const uint8_t *digest, size_t digest_len, 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const uint8_t *sig, size_t sig_len, EC_KEY *eckey) { 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ECDSA_SIG *s; 765129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley int ret = 0; 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) { 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return eckey->ecdsa_meth->verify(digest, digest_len, sig, sig_len, eckey); 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley s = ECDSA_SIG_new(); 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (s == NULL || d2i_ECDSA_SIG(&s, &sig, sig_len) == NULL) { 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = ECDSA_do_verify(digest, digest_len, s, eckey); 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr: 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (s != NULL) { 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ECDSA_SIG_free(s); 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* digest_to_bn interprets |digest_len| bytes from |digest| as a big-endian 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * number and sets |out| to that value. It then truncates |out| so that it's, 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * at most, as long as |order|. It returns one on success and zero otherwise. */ 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int digest_to_bn(BIGNUM *out, const uint8_t *digest, size_t digest_len, 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const BIGNUM *order) { 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t num_bits; 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley num_bits = BN_num_bits(order); 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Need to truncate digest if it is too long: first truncate whole 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * bytes. */ 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (8 * digest_len > num_bits) { 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley digest_len = (num_bits + 7) / 8; 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_bin2bn(digest, digest_len, out)) { 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, digest_to_bn, ERR_R_BN_LIB); 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If still too long truncate remaining bits with a shift */ 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((8 * digest_len > num_bits) && 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley !BN_rshift(out, out, 8 - (num_bits & 0x7))) { 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, digest_to_bn, ERR_R_BN_LIB); 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EC_KEY *key) { 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ECDSA_do_sign_ex(digest, digest_len, NULL, NULL, key); 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ECDSA_do_verify(const uint8_t *digest, size_t digest_len, 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ECDSA_SIG *sig, EC_KEY *eckey) { 1305129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley int ret = 0; 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_CTX *ctx; 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIGNUM *order, *u1, *u2, *m, *X; 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EC_POINT *point = NULL; 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const EC_GROUP *group; 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const EC_POINT *pub_key; 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) { 138e09170f8f580f159b1e5c8a1b6b4f54f081b7122David Benjamin OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_NOT_IMPLEMENTED); 1395129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* check input values */ 143b2cb0ece7678586c9ca9c02dbc40069037b4f5a9Adam Langley if ((group = EC_KEY_get0_group(eckey)) == NULL || 144b2cb0ece7678586c9ca9c02dbc40069037b4f5a9Adam Langley (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || 145b2cb0ece7678586c9ca9c02dbc40069037b4f5a9Adam Langley sig == NULL) { 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_MISSING_PARAMETERS); 1475129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx = BN_CTX_new(); 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ctx) { 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_MALLOC_FAILURE); 1535129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_CTX_start(ctx); 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley order = BN_CTX_get(ctx); 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley u1 = BN_CTX_get(ctx); 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley u2 = BN_CTX_get(ctx); 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley m = BN_CTX_get(ctx); 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X = BN_CTX_get(ctx); 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!X) { 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB); 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!EC_GROUP_get_order(group, order, ctx)) { 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB); 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_BAD_SIGNATURE); 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = 0; /* signature is invalid */ 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* calculate tmp1 = inv(S) mod order */ 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_mod_inverse(u2, sig->s, order, ctx)) { 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB); 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!digest_to_bn(m, digest, digest_len, order)) { 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* u1 = m * tmp mod order */ 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_mod_mul(u1, m, u2, order, ctx)) { 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB); 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* u2 = r * w mod q */ 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB); 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley point = EC_POINT_new(group); 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (point == NULL) { 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_MALLOC_FAILURE); 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB); 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB); 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_nnmod(u1, X, order, ctx)) { 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB); 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* if the signature is correct u1 is equal to sig->r */ 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = (BN_ucmp(u1, sig->r) == 0); 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr: 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_CTX_end(ctx); 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_CTX_free(ctx); 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (point) { 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EC_POINT_free(point); 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 226d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langleystatic int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, 227d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley BIGNUM **rp, const uint8_t *digest, 228d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley size_t digest_len) { 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_CTX *ctx = NULL; 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EC_POINT *tmp_point = NULL; 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const EC_GROUP *group; 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret = 0; 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { 236d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_PASSED_NULL_PARAMETER); 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx_in == NULL) { 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((ctx = BN_CTX_new()) == NULL) { 242d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_MALLOC_FAILURE); 24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx = ctx_in; 24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley k = BN_new(); /* this value is later returned in *kinvp */ 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r = BN_new(); /* this value is later returned in *rp */ 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley order = BN_new(); 25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X = BN_new(); 25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!k || !r || !order || !X) { 254d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_MALLOC_FAILURE); 25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tmp_point = EC_POINT_new(group); 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tmp_point == NULL) { 259d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB); 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!EC_GROUP_get_order(group, order, ctx)) { 263d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB); 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley do { 268d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley /* If possible, we'll include the private key and message digest in the k 269d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley * generation. The |digest| argument is only empty if |ECDSA_sign_setup| is 270d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley * being used. */ 27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley do { 272d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley int ok; 273d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley 274d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley if (digest_len > 0) { 275d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley ok = BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey), 276d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley digest, digest_len, ctx); 277d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley } else { 278d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley ok = BN_rand_range(k, order); 279d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley } 280d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley if (!ok) { 281d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, 28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); 28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } while (BN_is_zero(k)); 28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We do not want timing information to leak the length of k, 28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * so we compute G*k using an equivalent scalar of fixed 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * bit-length. */ 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_add(k, k, order)) { 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (BN_num_bits(k) <= BN_num_bits(order)) { 29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_add(k, k, order)) { 29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* compute r the x-coordinate of generator * k */ 30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { 302d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB); 30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, X, NULL, ctx)) { 306d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB); 30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_nnmod(r, X, order, ctx)) { 311d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_BN_LIB); 31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 31495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } while (BN_is_zero(r)); 31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* compute the inverse of k */ 31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_mod_inverse(k, k, order, ctx)) { 318d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_BN_LIB); 31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* clear old values if necessary */ 32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (*rp != NULL) { 32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_clear_free(*rp); 32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (*kinvp != NULL) { 32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_clear_free(*kinvp); 32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* save the pre-computed values */ 33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *rp = r; 33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *kinvp = k; 33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = 1; 33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr: 33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) { 33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (k != NULL) { 33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_clear_free(k); 33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (r != NULL) { 34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_clear_free(r); 34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx_in == NULL) 34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_CTX_free(ctx); 34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (order != NULL) 34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_free(order); 34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tmp_point != NULL) 34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EC_POINT_free(tmp_point); 34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (X) 35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_clear_free(X); 35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 354d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langleyint ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp) { 355d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley return ecdsa_sign_setup(eckey, ctx, kinv, rp, NULL, 0); 356d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley} 357d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley 35895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len, 35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const BIGNUM *in_kinv, const BIGNUM *in_r, 36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EC_KEY *eckey) { 36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ok = 0; 36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; 36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const BIGNUM *ckinv; 36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_CTX *ctx = NULL; 36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const EC_GROUP *group; 36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ECDSA_SIG *ret; 36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const BIGNUM *priv_key; 36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { 370e09170f8f580f159b1e5c8a1b6b4f54f081b7122David Benjamin OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ECDSA_R_NOT_IMPLEMENTED); 37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley group = EC_KEY_get0_group(eckey); 37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley priv_key = EC_KEY_get0_private_key(eckey); 37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (group == NULL || priv_key == NULL) { 37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_PASSED_NULL_PARAMETER); 37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = ECDSA_SIG_new(); 38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) { 38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE); 38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley s = ret->s; 38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || 39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { 39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE); 39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!EC_GROUP_get_order(group, order, ctx)) { 39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_EC_LIB); 39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!digest_to_bn(m, digest, digest_len, order)) { 40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (;;) { 40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in_kinv == NULL || in_r == NULL) { 404d4b4f085d9c8bf0ae28769e53cceb2b47a2b34fbAdam Langley if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, digest, digest_len)) { 40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_ECDSA_LIB); 40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ckinv = kinv; 40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ckinv = in_kinv; 41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (BN_copy(ret->r, in_r) == NULL) { 41295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE); 41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 41695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { 41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB); 41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_mod_add_quick(s, tmp, m, order)) { 42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB); 42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_mod_mul(s, s, ckinv, order, ctx)) { 42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB); 42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (BN_is_zero(s)) { 43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* if kinv and r have been supplied by the caller 43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * don't to generate new kinv and r values */ 43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in_kinv != NULL && in_r != NULL) { 43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ECDSA_R_NEED_NEW_SETUP_VALUES); 43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* s != 0 => we have a valid signature */ 43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ok = 1; 44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr: 44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ok) { 44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ECDSA_SIG_free(ret); 44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = NULL; 44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx) 45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_CTX_free(ctx); 45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (m) 45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_clear_free(m); 45395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tmp) 45495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_clear_free(tmp); 45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (order) 45695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_free(order); 45795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (kinv) 45895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_clear_free(kinv); 45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 46095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ECDSA_sign_ex(int type, const uint8_t *digest, size_t digest_len, 46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley uint8_t *sig, unsigned int *sig_len, const BIGNUM *kinv, 46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const BIGNUM *r, EC_KEY *eckey) { 46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ECDSA_SIG *s = NULL; 46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { 46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ECDSA, ECDSA_sign_ex, ECDSA_R_NOT_IMPLEMENTED); 46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *sig_len = 0; 47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley s = ECDSA_do_sign_ex(digest, digest_len, kinv, r, eckey); 47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (s == NULL) { 47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *sig_len = 0; 47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *sig_len = i2d_ECDSA_SIG(s, &sig); 47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ECDSA_SIG_free(s); 48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 482