GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: dsa_ossl.c,v 1.26 2016/06/21 04:16:53 bcook Exp $ */ |
||
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 |
|||
61 |
#include <stdio.h> |
||
62 |
|||
63 |
#include <openssl/asn1.h> |
||
64 |
#include <openssl/bn.h> |
||
65 |
#include <openssl/dsa.h> |
||
66 |
#include <openssl/err.h> |
||
67 |
#include <openssl/sha.h> |
||
68 |
|||
69 |
static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); |
||
70 |
static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, |
||
71 |
BIGNUM **rp); |
||
72 |
static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, |
||
73 |
DSA *dsa); |
||
74 |
static int dsa_init(DSA *dsa); |
||
75 |
static int dsa_finish(DSA *dsa); |
||
76 |
|||
77 |
static DSA_METHOD openssl_dsa_meth = { |
||
78 |
.name = "OpenSSL DSA method", |
||
79 |
.dsa_do_sign = dsa_do_sign, |
||
80 |
.dsa_sign_setup = dsa_sign_setup, |
||
81 |
.dsa_do_verify = dsa_do_verify, |
||
82 |
.init = dsa_init, |
||
83 |
.finish = dsa_finish |
||
84 |
}; |
||
85 |
|||
86 |
const DSA_METHOD * |
||
87 |
DSA_OpenSSL(void) |
||
88 |
2 |
{ |
|
89 |
2 |
return &openssl_dsa_meth; |
|
90 |
} |
||
91 |
|||
92 |
static DSA_SIG * |
||
93 |
dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) |
||
94 |
2 |
{ |
|
95 |
2 |
BIGNUM *kinv = NULL, *r = NULL, *s = NULL; |
|
96 |
BIGNUM m; |
||
97 |
BIGNUM xr; |
||
98 |
2 |
BN_CTX *ctx = NULL; |
|
99 |
2 |
int reason = ERR_R_BN_LIB; |
|
100 |
2 |
DSA_SIG *ret = NULL; |
|
101 |
2 |
int noredo = 0; |
|
102 |
|||
103 |
2 |
BN_init(&m); |
|
104 |
2 |
BN_init(&xr); |
|
105 |
|||
106 |
✓✗✓✗ ✗✓ |
2 |
if (!dsa->p || !dsa->q || !dsa->g) { |
107 |
reason = DSA_R_MISSING_PARAMETERS; |
||
108 |
goto err; |
||
109 |
} |
||
110 |
|||
111 |
2 |
s = BN_new(); |
|
112 |
✗✓ | 2 |
if (s == NULL) |
113 |
goto err; |
||
114 |
2 |
ctx = BN_CTX_new(); |
|
115 |
✗✓ | 2 |
if (ctx == NULL) |
116 |
goto err; |
||
117 |
2 |
redo: |
|
118 |
✗✓✗✗ |
2 |
if (dsa->kinv == NULL || dsa->r == NULL) { |
119 |
✗✓ | 2 |
if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) |
120 |
goto err; |
||
121 |
} else { |
||
122 |
kinv = dsa->kinv; |
||
123 |
dsa->kinv = NULL; |
||
124 |
r = dsa->r; |
||
125 |
dsa->r = NULL; |
||
126 |
noredo = 1; |
||
127 |
} |
||
128 |
|||
129 |
|||
130 |
/* |
||
131 |
* If the digest length is greater than the size of q use the |
||
132 |
* BN_num_bits(dsa->q) leftmost bits of the digest, see |
||
133 |
* fips 186-3, 4.2 |
||
134 |
*/ |
||
135 |
✗✓ | 2 |
if (dlen > BN_num_bytes(dsa->q)) |
136 |
dlen = BN_num_bytes(dsa->q); |
||
137 |
✗✓ | 2 |
if (BN_bin2bn(dgst,dlen,&m) == NULL) |
138 |
goto err; |
||
139 |
|||
140 |
/* Compute s = inv(k) (m + xr) mod q */ |
||
141 |
✗✓ | 2 |
if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) /* s = xr */ |
142 |
goto err; |
||
143 |
✗✓ | 2 |
if (!BN_add(s, &xr, &m)) /* s = m + xr */ |
144 |
goto err; |
||
145 |
✗✓ | 2 |
if (BN_cmp(s, dsa->q) > 0) |
146 |
if (!BN_sub(s, s, dsa->q)) |
||
147 |
goto err; |
||
148 |
✗✓ | 2 |
if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) |
149 |
goto err; |
||
150 |
|||
151 |
2 |
ret = DSA_SIG_new(); |
|
152 |
✗✓ | 2 |
if (ret == NULL) |
153 |
goto err; |
||
154 |
/* |
||
155 |
* Redo if r or s is zero as required by FIPS 186-3: this is |
||
156 |
* very unlikely. |
||
157 |
*/ |
||
158 |
✓✗✗✓ |
2 |
if (BN_is_zero(r) || BN_is_zero(s)) { |
159 |
if (noredo) { |
||
160 |
reason = DSA_R_NEED_NEW_SETUP_VALUES; |
||
161 |
goto err; |
||
162 |
} |
||
163 |
goto redo; |
||
164 |
} |
||
165 |
2 |
ret->r = r; |
|
166 |
2 |
ret->s = s; |
|
167 |
|||
168 |
2 |
err: |
|
169 |
✗✓ | 2 |
if (!ret) { |
170 |
DSAerr(DSA_F_DSA_DO_SIGN, reason); |
||
171 |
BN_free(r); |
||
172 |
BN_free(s); |
||
173 |
} |
||
174 |
2 |
BN_CTX_free(ctx); |
|
175 |
2 |
BN_clear_free(&m); |
|
176 |
2 |
BN_clear_free(&xr); |
|
177 |
2 |
BN_clear_free(kinv); |
|
178 |
2 |
return ret; |
|
179 |
} |
||
180 |
|||
181 |
static int |
||
182 |
dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) |
||
183 |
2 |
{ |
|
184 |
BN_CTX *ctx; |
||
185 |
2 |
BIGNUM k, *kinv = NULL, *r = NULL; |
|
186 |
2 |
int ret = 0; |
|
187 |
|||
188 |
✓✗✓✗ ✗✓ |
2 |
if (!dsa->p || !dsa->q || !dsa->g) { |
189 |
DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); |
||
190 |
return 0; |
||
191 |
} |
||
192 |
|||
193 |
2 |
BN_init(&k); |
|
194 |
|||
195 |
✗✓ | 2 |
if (ctx_in == NULL) { |
196 |
if ((ctx = BN_CTX_new()) == NULL) |
||
197 |
goto err; |
||
198 |
} else |
||
199 |
2 |
ctx = ctx_in; |
|
200 |
|||
201 |
✗✓ | 2 |
if ((r = BN_new()) == NULL) |
202 |
goto err; |
||
203 |
|||
204 |
/* Get random k */ |
||
205 |
do { |
||
206 |
✗✓ | 2 |
if (!BN_rand_range(&k, dsa->q)) |
207 |
goto err; |
||
208 |
✗✓ | 2 |
} while (BN_is_zero(&k)); |
209 |
|||
210 |
2 |
BN_set_flags(&k, BN_FLG_CONSTTIME); |
|
211 |
|||
212 |
✓✗ | 2 |
if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { |
213 |
✗✓ | 2 |
if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, |
214 |
CRYPTO_LOCK_DSA, dsa->p, ctx)) |
||
215 |
goto err; |
||
216 |
} |
||
217 |
|||
218 |
/* Compute r = (g^k mod p) mod q */ |
||
219 |
|||
220 |
/* |
||
221 |
* We do not want timing information to leak the length of k, |
||
222 |
* so we compute g^k using an equivalent exponent of fixed |
||
223 |
* length. |
||
224 |
* |
||
225 |
* (This is a kludge that we need because the BN_mod_exp_mont() |
||
226 |
* does not let us specify the desired timing behaviour.) |
||
227 |
*/ |
||
228 |
|||
229 |
✗✓ | 2 |
if (!BN_add(&k, &k, dsa->q)) |
230 |
goto err; |
||
231 |
✓✗ | 2 |
if (BN_num_bits(&k) <= BN_num_bits(dsa->q)) { |
232 |
✗✓ | 2 |
if (!BN_add(&k, &k, dsa->q)) |
233 |
goto err; |
||
234 |
} |
||
235 |
|||
236 |
✗✓ | 2 |
if (dsa->meth->bn_mod_exp != NULL) { |
237 |
if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, &k, dsa->p, ctx, |
||
238 |
dsa->method_mont_p)) |
||
239 |
goto err; |
||
240 |
} else { |
||
241 |
✗✓ | 2 |
if (!BN_mod_exp_mont(r, dsa->g, &k, dsa->p, ctx, dsa->method_mont_p)) |
242 |
goto err; |
||
243 |
} |
||
244 |
|||
245 |
✗✓ | 2 |
if (!BN_mod(r,r,dsa->q,ctx)) |
246 |
goto err; |
||
247 |
|||
248 |
/* Compute part of 's = inv(k) (m + xr) mod q' */ |
||
249 |
✗✓ | 2 |
if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL) |
250 |
goto err; |
||
251 |
|||
252 |
2 |
BN_clear_free(*kinvp); |
|
253 |
2 |
*kinvp = kinv; |
|
254 |
2 |
kinv = NULL; |
|
255 |
2 |
BN_clear_free(*rp); |
|
256 |
2 |
*rp = r; |
|
257 |
2 |
ret = 1; |
|
258 |
2 |
err: |
|
259 |
✗✓ | 2 |
if (!ret) { |
260 |
DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB); |
||
261 |
BN_clear_free(r); |
||
262 |
} |
||
263 |
✗✓ | 2 |
if (ctx_in == NULL) |
264 |
BN_CTX_free(ctx); |
||
265 |
2 |
BN_clear_free(&k); |
|
266 |
2 |
return ret; |
|
267 |
} |
||
268 |
|||
269 |
static int |
||
270 |
dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) |
||
271 |
2 |
{ |
|
272 |
BN_CTX *ctx; |
||
273 |
BIGNUM u1, u2, t1; |
||
274 |
2 |
BN_MONT_CTX *mont = NULL; |
|
275 |
2 |
int ret = -1, i; |
|
276 |
|||
277 |
✓✗✓✗ ✗✓ |
2 |
if (!dsa->p || !dsa->q || !dsa->g) { |
278 |
DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS); |
||
279 |
return -1; |
||
280 |
} |
||
281 |
|||
282 |
2 |
i = BN_num_bits(dsa->q); |
|
283 |
/* fips 186-3 allows only different sizes for q */ |
||
284 |
✗✓✗✗ |
2 |
if (i != 160 && i != 224 && i != 256) { |
285 |
DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE); |
||
286 |
return -1; |
||
287 |
} |
||
288 |
|||
289 |
✗✓ | 2 |
if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { |
290 |
DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE); |
||
291 |
return -1; |
||
292 |
} |
||
293 |
2 |
BN_init(&u1); |
|
294 |
2 |
BN_init(&u2); |
|
295 |
2 |
BN_init(&t1); |
|
296 |
|||
297 |
✗✓ | 2 |
if ((ctx = BN_CTX_new()) == NULL) |
298 |
goto err; |
||
299 |
|||
300 |
✓✗✓✗ ✗✓ |
2 |
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || |
301 |
BN_ucmp(sig->r, dsa->q) >= 0) { |
||
302 |
ret = 0; |
||
303 |
goto err; |
||
304 |
} |
||
305 |
✓✗✓✗ ✗✓ |
2 |
if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || |
306 |
BN_ucmp(sig->s, dsa->q) >= 0) { |
||
307 |
ret = 0; |
||
308 |
goto err; |
||
309 |
} |
||
310 |
|||
311 |
/* Calculate W = inv(S) mod Q |
||
312 |
* save W in u2 */ |
||
313 |
✗✓ | 2 |
if ((BN_mod_inverse(&u2, sig->s, dsa->q, ctx)) == NULL) |
314 |
goto err; |
||
315 |
|||
316 |
/* save M in u1 */ |
||
317 |
/* |
||
318 |
* If the digest length is greater than the size of q use the |
||
319 |
* BN_num_bits(dsa->q) leftmost bits of the digest, see |
||
320 |
* fips 186-3, 4.2 |
||
321 |
*/ |
||
322 |
✗✓ | 2 |
if (dgst_len > (i >> 3)) |
323 |
dgst_len = (i >> 3); |
||
324 |
✗✓ | 2 |
if (BN_bin2bn(dgst, dgst_len, &u1) == NULL) |
325 |
goto err; |
||
326 |
|||
327 |
/* u1 = M * w mod q */ |
||
328 |
✗✓ | 2 |
if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) |
329 |
goto err; |
||
330 |
|||
331 |
/* u2 = r * w mod q */ |
||
332 |
✗✓ | 2 |
if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) |
333 |
goto err; |
||
334 |
|||
335 |
|||
336 |
✓✗ | 2 |
if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { |
337 |
2 |
mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p, |
|
338 |
CRYPTO_LOCK_DSA, dsa->p, ctx); |
||
339 |
✗✓ | 2 |
if (!mont) |
340 |
goto err; |
||
341 |
} |
||
342 |
|||
343 |
✗✓ | 2 |
if (dsa->meth->dsa_mod_exp != NULL) { |
344 |
if (!dsa->meth->dsa_mod_exp(dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, |
||
345 |
dsa->p, ctx, mont)) |
||
346 |
goto err; |
||
347 |
} else { |
||
348 |
✗✓ | 2 |
if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, |
349 |
mont)) |
||
350 |
goto err; |
||
351 |
} |
||
352 |
|||
353 |
/* BN_copy(&u1,&t1); */ |
||
354 |
/* let u1 = u1 mod q */ |
||
355 |
✗✓ | 2 |
if (!BN_mod(&u1, &t1, dsa->q, ctx)) |
356 |
goto err; |
||
357 |
|||
358 |
/* V is now in u1. If the signature is correct, it will be |
||
359 |
* equal to R. */ |
||
360 |
2 |
ret = BN_ucmp(&u1, sig->r) == 0; |
|
361 |
|||
362 |
2 |
err: |
|
363 |
✗✓ | 2 |
if (ret < 0) |
364 |
DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_BN_LIB); |
||
365 |
2 |
BN_CTX_free(ctx); |
|
366 |
2 |
BN_free(&u1); |
|
367 |
2 |
BN_free(&u2); |
|
368 |
2 |
BN_free(&t1); |
|
369 |
2 |
return ret; |
|
370 |
} |
||
371 |
|||
372 |
static int |
||
373 |
dsa_init(DSA *dsa) |
||
374 |
2 |
{ |
|
375 |
2 |
dsa->flags |= DSA_FLAG_CACHE_MONT_P; |
|
376 |
2 |
return 1; |
|
377 |
} |
||
378 |
|||
379 |
static int |
||
380 |
dsa_finish(DSA *dsa) |
||
381 |
2 |
{ |
|
382 |
2 |
BN_MONT_CTX_free(dsa->method_mont_p); |
|
383 |
2 |
return 1; |
|
384 |
} |
||
385 |
Generated by: GCOVR (Version 3.3) |