1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ====================================================================
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met:
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer.
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer in
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    the documentation and/or other materials provided with the
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    distribution.
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    software must display the following acknowledgment:
18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    endorse or promote products derived from this software without
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    prior written permission. For written permission, please contact
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    openssl-core@OpenSSL.org.
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL"
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    nor may "OpenSSL" appear in their names without prior written
28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    permission of the OpenSSL Project.
29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following
31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    acknowledgment:
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE.
47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ====================================================================
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com).  This product includes software written by Tim
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). */
52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ecdsa.h>
54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h>
56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/bn.h>
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h>
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h>
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "../ec/internal.h"
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
64d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig,
65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley               unsigned int *sig_len, EC_KEY *eckey) {
66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) {
67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return eckey->ecdsa_meth->sign(digest, digest_len, sig, sig_len, eckey);
68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ECDSA_sign_ex(type, digest, digest_len, sig, sig_len, NULL, NULL,
71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                       eckey);
72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
74d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ECDSA_verify(int type, const uint8_t *digest, size_t digest_len,
75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                 const uint8_t *sig, size_t sig_len, EC_KEY *eckey) {
76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ECDSA_SIG *s;
77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int ret = 0;
78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t *der = NULL;
79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return eckey->ecdsa_meth->verify(digest, digest_len, sig, sig_len, eckey);
82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s = ECDSA_SIG_new();
85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const uint8_t *sigp = sig;
86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s == NULL || d2i_ECDSA_SIG(&s, &sigp, sig_len) == NULL ||
87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      sigp != sig + sig_len) {
88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Ensure that the signature uses DER and doesn't have trailing garbage. */
92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const int der_len = i2d_ECDSA_SIG(s, &der);
93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (der_len < 0 || (size_t) der_len != sig_len || memcmp(sig, der, sig_len)) {
94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ret = ECDSA_do_verify(digest, digest_len, s, eckey);
98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr:
100e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(der);
101e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ECDSA_SIG_free(s);
102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* digest_to_bn interprets |digest_len| bytes from |digest| as a big-endian
106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * number and sets |out| to that value. It then truncates |out| so that it's,
107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * at most, as long as |order|. It returns one on success and zero otherwise. */
108d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int digest_to_bn(BIGNUM *out, const uint8_t *digest, size_t digest_len,
109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        const BIGNUM *order) {
110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t num_bits;
111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  num_bits = BN_num_bits(order);
113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Need to truncate digest if it is too long: first truncate whole
114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * bytes. */
115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (8 * digest_len > num_bits) {
116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    digest_len = (num_bits + 7) / 8;
117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!BN_bin2bn(digest, digest_len, out)) {
119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, digest_to_bn, ERR_R_BN_LIB);
120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* If still too long truncate remaining bits with a shift */
124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if ((8 * digest_len > num_bits) &&
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !BN_rshift(out, out, 8 - (num_bits & 0x7))) {
126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, digest_to_bn, ERR_R_BN_LIB);
127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
133d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len,
134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                         EC_KEY *key) {
135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ECDSA_do_sign_ex(digest, digest_len, NULL, NULL, key);
136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
138d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                    const ECDSA_SIG *sig, EC_KEY *eckey) {
140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int ret = 0;
141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BN_CTX *ctx;
142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BIGNUM *order, *u1, *u2, *m, *X;
143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EC_POINT *point = NULL;
144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const EC_GROUP *group;
145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const EC_POINT *pub_key;
146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_NOT_IMPLEMENTED);
149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* check input values */
153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if ((group = EC_KEY_get0_group(eckey)) == NULL ||
154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      (pub_key = EC_KEY_get0_public_key(eckey)) == NULL ||
155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      sig == NULL) {
156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_MISSING_PARAMETERS);
157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx = BN_CTX_new();
161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!ctx) {
162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_MALLOC_FAILURE);
163d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BN_CTX_start(ctx);
166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  order = BN_CTX_get(ctx);
167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  u1 = BN_CTX_get(ctx);
168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  u2 = BN_CTX_get(ctx);
169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  m = BN_CTX_get(ctx);
170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  X = BN_CTX_get(ctx);
171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!X) {
172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EC_GROUP_get_order(group, order, ctx)) {
177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB);
178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
179d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_BAD_SIGNATURE);
185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ret = 0; /* signature is invalid */
186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* calculate tmp1 = inv(S) mod order */
189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
191d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
192d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!digest_to_bn(m, digest, digest_len, order)) {
194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* u1 = m * tmp mod order */
197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!BN_mod_mul(u1, m, u2, order, ctx)) {
198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* u2 = r * w mod q */
202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
204d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  point = EC_POINT_new(group);
208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (point == NULL) {
209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_MALLOC_FAILURE);
210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB);
214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
216d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB);
218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!BN_nnmod(u1, X, order, ctx)) {
221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* if the signature is correct u1 is equal to sig->r */
225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ret = (BN_ucmp(u1, sig->r) == 0);
226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
227d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr:
228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BN_CTX_end(ctx);
229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BN_CTX_free(ctx);
230e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  EC_POINT_free(point);
231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
234d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                            BIGNUM **rp, const uint8_t *digest,
236d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                            size_t digest_len) {
237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BN_CTX *ctx = NULL;
238d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
239d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EC_POINT *tmp_point = NULL;
240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const EC_GROUP *group;
241d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int ret = 0;
242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_PASSED_NULL_PARAMETER);
245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
246d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
247d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
248d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx_in == NULL) {
249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if ((ctx = BN_CTX_new()) == NULL) {
250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_MALLOC_FAILURE);
251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
253d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ctx = ctx_in;
255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  k = BN_new(); /* this value is later returned in *kinvp */
258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  r = BN_new(); /* this value is later returned in *rp    */
259d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  order = BN_new();
260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  X = BN_new();
261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!k || !r || !order || !X) {
262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_MALLOC_FAILURE);
263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
264d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
265d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  tmp_point = EC_POINT_new(group);
266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (tmp_point == NULL) {
267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EC_GROUP_get_order(group, order, ctx)) {
271d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
275d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  do {
276d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* If possible, we'll include the private key and message digest in the k
277d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * generation. The |digest| argument is only empty if |ECDSA_sign_setup| is
278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * being used. */
279d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    do {
280d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      int ok;
281d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
282d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (digest_len > 0) {
283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        ok = BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                   digest, digest_len, ctx);
285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      } else {
286d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        ok = BN_rand_range(k, order);
287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (!ok) {
289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup,
290d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                          ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
291d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        goto err;
292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    } while (BN_is_zero(k));
294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
295d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* We do not want timing information to leak the length of k,
296d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * so we compute G*k using an equivalent scalar of fixed
297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * bit-length. */
298d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
299d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!BN_add(k, k, order)) {
300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (BN_num_bits(k) <= BN_num_bits(order)) {
303d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (!BN_add(k, k, order)) {
304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        goto err;
305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* compute r the x-coordinate of generator * k */
309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
310d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, X, NULL, ctx)) {
314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!BN_nnmod(r, X, order, ctx)) {
319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_BN_LIB);
320d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
321d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
322d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } while (BN_is_zero(r));
323d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* compute the inverse of k */
325d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!BN_mod_inverse(k, k, order, ctx)) {
326d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_BN_LIB);
327d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
328d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
329d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* clear old values if necessary */
330e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  BN_clear_free(*rp);
331e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  BN_clear_free(*kinvp);
332d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* save the pre-computed values  */
334d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *rp = r;
335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *kinvp = k;
336d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ret = 1;
337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
338d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr:
339d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!ret) {
340e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    BN_clear_free(k);
341e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    BN_clear_free(r);
342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
343e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (ctx_in == NULL) {
344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    BN_CTX_free(ctx);
345e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
346e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  BN_free(order);
347e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  EC_POINT_free(tmp_point);
348e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  BN_clear_free(X);
349d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
352d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp) {
353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ecdsa_sign_setup(eckey, ctx, kinv, rp, NULL, 0);
354d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
356d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
357d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                            const BIGNUM *in_kinv, const BIGNUM *in_r,
358d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                            EC_KEY *eckey) {
359d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int ok = 0;
360d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
361d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const BIGNUM *ckinv;
362d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BN_CTX *ctx = NULL;
363d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const EC_GROUP *group;
364d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ECDSA_SIG *ret;
365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const BIGNUM *priv_key;
366d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
367d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) {
368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ECDSA_R_NOT_IMPLEMENTED);
369d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
370d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
372d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  group = EC_KEY_get0_group(eckey);
373d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  priv_key = EC_KEY_get0_private_key(eckey);
374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (group == NULL || priv_key == NULL) {
376d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_PASSED_NULL_PARAMETER);
377d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
378d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
379d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
380d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ret = ECDSA_SIG_new();
381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!ret) {
382d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE);
383d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s = ret->s;
386d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
388d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
389d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE);
390d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
393d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EC_GROUP_get_order(group, order, ctx)) {
394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_EC_LIB);
395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!digest_to_bn(m, digest, digest_len, order)) {
398d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
400d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  for (;;) {
401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (in_kinv == NULL || in_r == NULL) {
402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, digest, digest_len)) {
403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_ECDSA_LIB);
404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        goto err;
405d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ckinv = kinv;
407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    } else {
408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ckinv = in_kinv;
409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (BN_copy(ret->r, in_r) == NULL) {
410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE);
411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        goto err;
412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
413d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
414d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB);
417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
419d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!BN_mod_add_quick(s, tmp, m, order)) {
420d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB);
421d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
422d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB);
425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (BN_is_zero(s)) {
428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* if kinv and r have been supplied by the caller
429d9e397b599b13d642138480a28c14db7a136bf0Adam Langley       * don't to generate new kinv and r values */
430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (in_kinv != NULL && in_r != NULL) {
431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ECDSA_R_NEED_NEW_SETUP_VALUES);
432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        goto err;
433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    } else {
435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* s != 0 => we have a valid signature */
436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      break;
437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ok = 1;
441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
442d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr:
443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!ok) {
444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ECDSA_SIG_free(ret);
445d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ret = NULL;
446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
447e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  BN_CTX_free(ctx);
448e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  BN_clear_free(m);
449e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  BN_clear_free(tmp);
450e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  BN_free(order);
451e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  BN_clear_free(kinv);
452d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
453d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
454d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
455d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ECDSA_sign_ex(int type, const uint8_t *digest, size_t digest_len,
456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                  uint8_t *sig, unsigned int *sig_len, const BIGNUM *kinv,
457d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                  const BIGNUM *r, EC_KEY *eckey) {
458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ECDSA_SIG *s = NULL;
459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) {
461d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(ECDSA, ECDSA_sign_ex, ECDSA_R_NOT_IMPLEMENTED);
462d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    *sig_len = 0;
463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s = ECDSA_do_sign_ex(digest, digest_len, kinv, r, eckey);
467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s == NULL) {
468d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    *sig_len = 0;
469d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
470d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
471d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *sig_len = i2d_ECDSA_SIG(s, &sig);
472d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ECDSA_SIG_free(s);
473d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
474d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
475