blob: ff29e55c8df787b68ba8e459103246b035674e0b [file] [log] [blame]
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +00001/* crypto/dsa/dsa_ossl.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
60
Dr. Stephen Henson73e45b22014-10-20 13:13:59 +010061
Dr. Stephen Henson14ae26f2011-02-03 17:00:24 +000062
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +000063#include <stdio.h>
64#include "cryptlib.h"
65#include <openssl/bn.h>
Nils Larsch357d5de2007-02-03 14:41:12 +000066#include <openssl/sha.h>
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +000067#include <openssl/dsa.h>
68#include <openssl/rand.h>
69#include <openssl/asn1.h>
70
71static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
Dr. Stephen Henson8d6a75d2013-07-17 18:05:43 +010072static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
73static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
Adam Langley190c6152013-07-15 12:42:15 +010074 BIGNUM **kinvp, BIGNUM **rp,
75 const unsigned char *dgst, int dlen);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +000076static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
Ben Laurie84948b32006-11-08 09:45:12 +000077 DSA *dsa);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +000078static int dsa_init(DSA *dsa);
79static int dsa_finish(DSA *dsa);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +000080
81static DSA_METHOD openssl_dsa_meth = {
82"OpenSSL DSA method",
83dsa_do_sign,
Dr. Stephen Henson8d6a75d2013-07-17 18:05:43 +010084dsa_sign_setup_no_digest,
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +000085dsa_do_verify,
Geoff Thorpe879650b2003-03-11 01:49:21 +000086NULL, /* dsa_mod_exp, */
87NULL, /* dsa_bn_mod_exp, */
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +000088dsa_init,
89dsa_finish,
Dr. Stephen Henson20818e02011-01-26 15:46:26 +000090DSA_FLAG_FIPS_METHOD,
Geoff Thorpe0e4aa0d2003-01-15 02:01:55 +000091NULL,
92NULL,
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +000093NULL
94};
95
Geoff Thorpe879650b2003-03-11 01:49:21 +000096/* These macro wrappers replace attempts to use the dsa_mod_exp() and
97 * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of
98 * having a the macro work as an expression by bundling an "err_instr". So;
99 *
100 * if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
101 * dsa->method_mont_p)) goto err;
102 *
103 * can be replaced by;
104 *
105 * DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx,
106 * dsa->method_mont_p);
107 */
108
109#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \
110 do { \
111 int _tmp_res53; \
112 if((dsa)->meth->dsa_mod_exp) \
113 _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \
114 (a2), (p2), (m), (ctx), (in_mont)); \
115 else \
116 _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \
117 (m), (ctx), (in_mont)); \
118 if(!_tmp_res53) err_instr; \
119 } while(0)
120#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \
121 do { \
122 int _tmp_res53; \
123 if((dsa)->meth->bn_mod_exp) \
124 _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \
125 (m), (ctx), (m_ctx)); \
126 else \
127 _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \
128 if(!_tmp_res53) err_instr; \
129 } while(0)
130
Richard Levittea4aba802000-11-07 13:54:39 +0000131const DSA_METHOD *DSA_OpenSSL(void)
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000132{
133 return &openssl_dsa_meth;
134}
135
136static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
137 {
138 BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
Matt Caswellc0d43902014-10-28 22:56:18 +0000139 BIGNUM *m;
140 BIGNUM *xr;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000141 BN_CTX *ctx=NULL;
Nils Larschb900a6b2007-02-11 19:33:21 +0000142 int reason=ERR_R_BN_LIB;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000143 DSA_SIG *ret=NULL;
Dr. Stephen Henson245a7ee2011-01-25 16:01:29 +0000144 int noredo = 0;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000145
Matt Caswellc0d43902014-10-28 22:56:18 +0000146 m = BN_new();
147 xr = BN_new();
148 if(!m || !xr) goto err;
Lutz Jänickea74333f2003-01-15 14:54:59 +0000149
Dr. Stephen Hensonc9624792001-04-21 12:06:01 +0000150 if (!dsa->p || !dsa->q || !dsa->g)
151 {
152 reason=DSA_R_MISSING_PARAMETERS;
153 goto err;
154 }
Lutz Jänickea74333f2003-01-15 14:54:59 +0000155
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000156 s=BN_new();
157 if (s == NULL) goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000158 ctx=BN_CTX_new();
159 if (ctx == NULL) goto err;
Dr. Stephen Henson245a7ee2011-01-25 16:01:29 +0000160redo:
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000161 if ((dsa->kinv == NULL) || (dsa->r == NULL))
162 {
Dr. Stephen Henson8d6a75d2013-07-17 18:05:43 +0100163 if (!dsa_sign_setup(dsa,ctx,&kinv,&r,dgst,dlen))
Adam Langley8a99cb22013-01-24 16:27:28 -0500164 goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000165 }
166 else
167 {
168 kinv=dsa->kinv;
169 dsa->kinv=NULL;
170 r=dsa->r;
171 dsa->r=NULL;
Dr. Stephen Henson245a7ee2011-01-25 16:01:29 +0000172 noredo = 1;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000173 }
174
Nils Larschb900a6b2007-02-11 19:33:21 +0000175
176 if (dlen > BN_num_bytes(dsa->q))
Nils Larsch357d5de2007-02-03 14:41:12 +0000177 /* if the digest length is greater than the size of q use the
178 * BN_num_bits(dsa->q) leftmost bits of the digest, see
179 * fips 186-3, 4.2 */
Nils Larschb900a6b2007-02-11 19:33:21 +0000180 dlen = BN_num_bytes(dsa->q);
Matt Caswellc0d43902014-10-28 22:56:18 +0000181 if (BN_bin2bn(dgst,dlen,m) == NULL)
Nils Larschb900a6b2007-02-11 19:33:21 +0000182 goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000183
184 /* Compute s = inv(k) (m + xr) mod q */
Matt Caswellc0d43902014-10-28 22:56:18 +0000185 if (!BN_mod_mul(xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
186 if (!BN_add(s, xr, m)) goto err; /* s = m + xr */
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000187 if (BN_cmp(s,dsa->q) > 0)
Dr. Stephen Henson776654a2010-10-11 23:49:22 +0000188 if (!BN_sub(s,s,dsa->q)) goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000189 if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
Ben Laurie71fa4512012-06-03 22:00:21 +0000190
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000191 ret=DSA_SIG_new();
192 if (ret == NULL) goto err;
Dr. Stephen Henson245a7ee2011-01-25 16:01:29 +0000193 /* Redo if r or s is zero as required by FIPS 186-3: this is
194 * very unlikely.
195 */
196 if (BN_is_zero(r) || BN_is_zero(s))
197 {
198 if (noredo)
199 {
200 reason = DSA_R_NEED_NEW_SETUP_VALUES;
201 goto err;
202 }
203 goto redo;
204 }
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000205 ret->r = r;
206 ret->s = s;
207
208err:
209 if (!ret)
210 {
211 DSAerr(DSA_F_DSA_DO_SIGN,reason);
212 BN_free(r);
213 BN_free(s);
214 }
215 if (ctx != NULL) BN_CTX_free(ctx);
Matt Caswellc0d43902014-10-28 22:56:18 +0000216 BN_clear_free(m);
217 BN_clear_free(xr);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000218 if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
219 BN_clear_free(kinv);
220 return(ret);
221 }
222
Dr. Stephen Henson8d6a75d2013-07-17 18:05:43 +0100223static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in,
Adam Langley190c6152013-07-15 12:42:15 +0100224 BIGNUM **kinvp, BIGNUM **rp) {
Dr. Stephen Henson8d6a75d2013-07-17 18:05:43 +0100225 return dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0);
Adam Langley190c6152013-07-15 12:42:15 +0100226}
227
Dr. Stephen Henson8d6a75d2013-07-17 18:05:43 +0100228static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
Adam Langley190c6152013-07-15 12:42:15 +0100229 BIGNUM **kinvp, BIGNUM **rp,
230 const unsigned char *dgst, int dlen)
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000231 {
Matt Caswellc0d43902014-10-28 22:56:18 +0000232 BN_CTX *ctx = NULL;
233 BIGNUM *k,*kq,*K,*kinv=NULL,*r=NULL;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000234 int ret=0;
235
Dr. Stephen Hensonc9624792001-04-21 12:06:01 +0000236 if (!dsa->p || !dsa->q || !dsa->g)
237 {
238 DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
239 return 0;
240 }
Lutz Jänickea74333f2003-01-15 14:54:59 +0000241
Matt Caswellc0d43902014-10-28 22:56:18 +0000242 k = BN_new();
243 kq = BN_new();
244 if(!k || !kq) goto err;
Lutz Jänickea74333f2003-01-15 14:54:59 +0000245
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000246 if (ctx_in == NULL)
247 {
248 if ((ctx=BN_CTX_new()) == NULL) goto err;
249 }
250 else
251 ctx=ctx_in;
252
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000253 if ((r=BN_new()) == NULL) goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000254
255 /* Get random k */
Bodo Möller35ed8cb2001-02-08 12:14:51 +0000256 do
Adam Langley8a99cb22013-01-24 16:27:28 -0500257 {
258#ifndef OPENSSL_NO_SHA512
Adam Langley190c6152013-07-15 12:42:15 +0100259 if (dgst != NULL)
Adam Langley8a99cb22013-01-24 16:27:28 -0500260 {
Adam Langley190c6152013-07-15 12:42:15 +0100261 /* We calculate k from SHA512(private_key + H(message)
262 * + random). This protects the private key from a weak
263 * PRNG. */
Matt Caswellc0d43902014-10-28 22:56:18 +0000264 if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst,
Adam Langley8a99cb22013-01-24 16:27:28 -0500265 dlen, ctx))
266 goto err;
267 }
268 else
269#endif
Matt Caswellc0d43902014-10-28 22:56:18 +0000270 if (!BN_rand_range(k, dsa->q)) goto err;
271 } while (BN_is_zero(k));
Adam Langley8a99cb22013-01-24 16:27:28 -0500272
Bodo Möller46a64372005-05-16 01:43:31 +0000273 if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
274 {
Matt Caswellc0d43902014-10-28 22:56:18 +0000275 BN_set_flags(k, BN_FLG_CONSTTIME);
Bodo Möller46a64372005-05-16 01:43:31 +0000276 }
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000277
Dr. Stephen Henson6ec8e632005-04-26 23:58:54 +0000278 if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000279 {
Dr. Stephen Henson879b1982005-04-27 00:04:59 +0000280 if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
Dr. Stephen Henson6ec8e632005-04-26 23:58:54 +0000281 CRYPTO_LOCK_DSA,
282 dsa->p, ctx))
283 goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000284 }
285
286 /* Compute r = (g^k mod p) mod q */
Bodo Möller0ebfcc82005-05-26 04:40:52 +0000287
288 if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
289 {
Matt Caswellc0d43902014-10-28 22:56:18 +0000290 if (!BN_copy(kq, k)) goto err;
Bodo Möller0ebfcc82005-05-26 04:40:52 +0000291
292 /* We do not want timing information to leak the length of k,
293 * so we compute g^k using an equivalent exponent of fixed length.
294 *
295 * (This is a kludge that we need because the BN_mod_exp_mont()
296 * does not let us specify the desired timing behaviour.) */
297
Matt Caswellc0d43902014-10-28 22:56:18 +0000298 if (!BN_add(kq, kq, dsa->q)) goto err;
299 if (BN_num_bits(kq) <= BN_num_bits(dsa->q))
Bodo Möller0ebfcc82005-05-26 04:40:52 +0000300 {
Matt Caswellc0d43902014-10-28 22:56:18 +0000301 if (!BN_add(kq, kq, dsa->q)) goto err;
Bodo Möller0ebfcc82005-05-26 04:40:52 +0000302 }
303
Matt Caswellc0d43902014-10-28 22:56:18 +0000304 K = kq;
Bodo Möller0ebfcc82005-05-26 04:40:52 +0000305 }
306 else
307 {
Matt Caswellc0d43902014-10-28 22:56:18 +0000308 K = k;
Bodo Möller0ebfcc82005-05-26 04:40:52 +0000309 }
310 DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
Dr. Stephen Henson879b1982005-04-27 00:04:59 +0000311 dsa->method_mont_p);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000312 if (!BN_mod(r,r,dsa->q,ctx)) goto err;
313
314 /* Compute part of 's = inv(k) (m + xr) mod q' */
Matt Caswellc0d43902014-10-28 22:56:18 +0000315 if ((kinv=BN_mod_inverse(NULL,k,dsa->q,ctx)) == NULL) goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000316
317 if (*kinvp != NULL) BN_clear_free(*kinvp);
318 *kinvp=kinv;
319 kinv=NULL;
320 if (*rp != NULL) BN_clear_free(*rp);
321 *rp=r;
322 ret=1;
323err:
324 if (!ret)
325 {
326 DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
Nils Larsch67b6f1c2006-03-15 17:45:43 +0000327 if (r != NULL)
328 BN_clear_free(r);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000329 }
330 if (ctx_in == NULL) BN_CTX_free(ctx);
Matt Caswellc0d43902014-10-28 22:56:18 +0000331 BN_clear_free(k);
332 BN_clear_free(kq);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000333 return(ret);
334 }
335
336static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
Ben Laurie84948b32006-11-08 09:45:12 +0000337 DSA *dsa)
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000338 {
339 BN_CTX *ctx;
Matt Caswellc0d43902014-10-28 22:56:18 +0000340 BIGNUM *u1,*u2,*t1;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000341 BN_MONT_CTX *mont=NULL;
Nils Larschb900a6b2007-02-11 19:33:21 +0000342 int ret = -1, i;
Dr. Stephen Hensonc9624792001-04-21 12:06:01 +0000343 if (!dsa->p || !dsa->q || !dsa->g)
344 {
345 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
346 return -1;
347 }
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000348
Nils Larsch357d5de2007-02-03 14:41:12 +0000349 i = BN_num_bits(dsa->q);
350 /* fips 186-3 allows only different sizes for q */
351 if (i != 160 && i != 224 && i != 256)
Bodo Möller5e3225c2006-09-28 13:45:34 +0000352 {
353 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
354 return -1;
355 }
356
Bodo Möller5e3225c2006-09-28 13:45:34 +0000357 if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
358 {
359 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
360 return -1;
361 }
Matt Caswellc0d43902014-10-28 22:56:18 +0000362 u1 = BN_new();
363 u2 = BN_new();
364 t1 = BN_new();
365 ctx=BN_CTX_new();
366 if(!u1 || !u2 || !t1 || !ctx) goto err;
Lutz Jänickea74333f2003-01-15 14:54:59 +0000367
Nils Larschff22e912005-04-22 20:02:44 +0000368 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
Bodo Möllerb53e44e2002-11-04 13:17:22 +0000369 BN_ucmp(sig->r, dsa->q) >= 0)
Bodo Möllerc458a332001-06-26 09:48:17 +0000370 {
371 ret = 0;
372 goto err;
373 }
Nils Larschff22e912005-04-22 20:02:44 +0000374 if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
Bodo Möllerb53e44e2002-11-04 13:17:22 +0000375 BN_ucmp(sig->s, dsa->q) >= 0)
Bodo Möllerc458a332001-06-26 09:48:17 +0000376 {
377 ret = 0;
378 goto err;
379 }
380
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000381 /* Calculate W = inv(S) mod Q
382 * save W in u2 */
Matt Caswellc0d43902014-10-28 22:56:18 +0000383 if ((BN_mod_inverse(u2,sig->s,dsa->q,ctx)) == NULL) goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000384
385 /* save M in u1 */
Nils Larschb900a6b2007-02-11 19:33:21 +0000386 if (dgst_len > (i >> 3))
Nils Larsch357d5de2007-02-03 14:41:12 +0000387 /* if the digest length is greater than the size of q use the
388 * BN_num_bits(dsa->q) leftmost bits of the digest, see
389 * fips 186-3, 4.2 */
Nils Larschb900a6b2007-02-11 19:33:21 +0000390 dgst_len = (i >> 3);
Matt Caswellc0d43902014-10-28 22:56:18 +0000391 if (BN_bin2bn(dgst,dgst_len,u1) == NULL) goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000392
393 /* u1 = M * w mod q */
Matt Caswellc0d43902014-10-28 22:56:18 +0000394 if (!BN_mod_mul(u1,u1,u2,dsa->q,ctx)) goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000395
396 /* u2 = r * w mod q */
Matt Caswellc0d43902014-10-28 22:56:18 +0000397 if (!BN_mod_mul(u2,sig->r,u2,dsa->q,ctx)) goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000398
Dr. Stephen Henson6ec8e632005-04-26 23:58:54 +0000399
400 if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000401 {
Dr. Stephen Henson879b1982005-04-27 00:04:59 +0000402 mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
Dr. Stephen Henson6ec8e632005-04-26 23:58:54 +0000403 CRYPTO_LOCK_DSA, dsa->p, ctx);
404 if (!mont)
405 goto err;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000406 }
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000407
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000408
Matt Caswellc0d43902014-10-28 22:56:18 +0000409 DSA_MOD_EXP(goto err, dsa, t1, dsa->g, u1, dsa->pub_key, u2, dsa->p, ctx, mont);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000410 /* BN_copy(&u1,&t1); */
411 /* let u1 = u1 mod q */
Matt Caswellc0d43902014-10-28 22:56:18 +0000412 if (!BN_mod(u1,t1,dsa->q,ctx)) goto err;
Geoff Thorpe879650b2003-03-11 01:49:21 +0000413
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000414 /* V is now in u1. If the signature is correct, it will be
415 * equal to R. */
Matt Caswellc0d43902014-10-28 22:56:18 +0000416 ret=(BN_ucmp(u1, sig->r) == 0);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000417
418 err:
Matt Caswelleb63bce2014-09-09 16:50:06 -0400419 if (ret < 0) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000420 if (ctx != NULL) BN_CTX_free(ctx);
Matt Caswellc0d43902014-10-28 22:56:18 +0000421 if(u1) BN_free(u1);
422 if(u2) BN_free(u2);
423 if(t1) BN_free(t1);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000424 return(ret);
425 }
426
427static int dsa_init(DSA *dsa)
428{
Dr. Stephen Henson13066ce1999-08-23 23:11:32 +0000429 dsa->flags|=DSA_FLAG_CACHE_MONT_P;
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000430 return(1);
431}
432
433static int dsa_finish(DSA *dsa)
434{
Dr. Stephen Henson13066ce1999-08-23 23:11:32 +0000435 if(dsa->method_mont_p)
Dr. Stephen Henson879b1982005-04-27 00:04:59 +0000436 BN_MONT_CTX_free(dsa->method_mont_p);
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000437 return(1);
438}
439