summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/dsa/dsa_ossl.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/dsa/dsa_ossl.c (renamed from src/lib/libssl/src/fips-1.0/dsa/fips_dsa_ossl.c)220
1 files changed, 105 insertions, 115 deletions
diff --git a/src/lib/libssl/src/fips-1.0/dsa/fips_dsa_ossl.c b/src/lib/libcrypto/dsa/dsa_ossl.c
index f8f3a39343..a3ddd7d281 100644
--- a/src/lib/libssl/src/fips-1.0/dsa/fips_dsa_ossl.c
+++ b/src/lib/libcrypto/dsa/dsa_ossl.c
@@ -59,78 +59,84 @@
59/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */ 59/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
60 60
61#include <stdio.h> 61#include <stdio.h>
62#include "cryptlib.h"
62#include <openssl/bn.h> 63#include <openssl/bn.h>
64#include <openssl/sha.h>
63#include <openssl/dsa.h> 65#include <openssl/dsa.h>
64#include <openssl/rand.h> 66#include <openssl/rand.h>
65#include <openssl/asn1.h> 67#include <openssl/asn1.h>
66#ifndef OPENSSL_NO_ENGINE
67#include <openssl/engine.h>
68#endif
69#include <openssl/fips.h>
70 68
71#ifdef OPENSSL_FIPS 69static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
72
73static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa);
74static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); 70static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
75static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig, 71static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
76 DSA *dsa); 72 DSA *dsa);
77static int dsa_init(DSA *dsa); 73static int dsa_init(DSA *dsa);
78static int dsa_finish(DSA *dsa); 74static int dsa_finish(DSA *dsa);
79static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, 75
80 BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, 76static DSA_METHOD openssl_dsa_meth = {
81 BN_MONT_CTX *in_mont); 77"OpenSSL DSA method",
82static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
83 const BIGNUM *m, BN_CTX *ctx,
84 BN_MONT_CTX *m_ctx);
85
86static const DSA_METHOD openssl_dsa_meth = {
87"OpenSSL FIPS DSA method",
88dsa_do_sign, 78dsa_do_sign,
89dsa_sign_setup, 79dsa_sign_setup,
90dsa_do_verify, 80dsa_do_verify,
91dsa_mod_exp, 81NULL, /* dsa_mod_exp, */
92dsa_bn_mod_exp, 82NULL, /* dsa_bn_mod_exp, */
93dsa_init, 83dsa_init,
94dsa_finish, 84dsa_finish,
950, 850,
86NULL,
87NULL,
96NULL 88NULL
97}; 89};
98 90
99int FIPS_dsa_check(struct dsa_st *dsa) 91/* These macro wrappers replace attempts to use the dsa_mod_exp() and
100 { 92 * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of
101 if(dsa->meth != &openssl_dsa_meth || dsa->meth->dsa_do_sign != dsa_do_sign 93 * having a the macro work as an expression by bundling an "err_instr". So;
102 || dsa->meth->dsa_sign_setup != dsa_sign_setup 94 *
103 || dsa->meth->dsa_mod_exp != dsa_mod_exp 95 * if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
104 || dsa->meth->bn_mod_exp != dsa_bn_mod_exp 96 * dsa->method_mont_p)) goto err;
105 || dsa->meth->init != dsa_init 97 *
106 || dsa->meth->finish != dsa_finish) 98 * can be replaced by;
107 { 99 *
108 FIPSerr(FIPS_F_FIPS_DSA_CHECK,FIPS_R_NON_FIPS_METHOD); 100 * DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx,
109 return 0; 101 * dsa->method_mont_p);
110 } 102 */
111 return 1; 103
112 } 104#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \
105 do { \
106 int _tmp_res53; \
107 if((dsa)->meth->dsa_mod_exp) \
108 _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \
109 (a2), (p2), (m), (ctx), (in_mont)); \
110 else \
111 _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \
112 (m), (ctx), (in_mont)); \
113 if(!_tmp_res53) err_instr; \
114 } while(0)
115#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \
116 do { \
117 int _tmp_res53; \
118 if((dsa)->meth->bn_mod_exp) \
119 _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \
120 (m), (ctx), (m_ctx)); \
121 else \
122 _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \
123 if(!_tmp_res53) err_instr; \
124 } while(0)
113 125
114const DSA_METHOD *DSA_OpenSSL(void) 126const DSA_METHOD *DSA_OpenSSL(void)
115{ 127{
116 return &openssl_dsa_meth; 128 return &openssl_dsa_meth;
117} 129}
118 130
119static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa) 131static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
120 { 132 {
121 BIGNUM *kinv=NULL,*r=NULL,*s=NULL; 133 BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
122 BIGNUM m; 134 BIGNUM m;
123 BIGNUM xr; 135 BIGNUM xr;
124 BN_CTX *ctx=NULL; 136 BN_CTX *ctx=NULL;
125 int i,reason=ERR_R_BN_LIB; 137 int reason=ERR_R_BN_LIB;
126 DSA_SIG *ret=NULL; 138 DSA_SIG *ret=NULL;
127 139
128 if(FIPS_selftest_failed())
129 {
130 FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED);
131 return NULL;
132 }
133
134 BN_init(&m); 140 BN_init(&m);
135 BN_init(&xr); 141 BN_init(&xr);
136 142
@@ -142,26 +148,35 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA
142 148
143 s=BN_new(); 149 s=BN_new();
144 if (s == NULL) goto err; 150 if (s == NULL) goto err;
145
146 i=BN_num_bytes(dsa->q); /* should be 20 */
147 if ((dlen > i) || (dlen > 50))
148 {
149 reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
150 goto err;
151 }
152
153 ctx=BN_CTX_new(); 151 ctx=BN_CTX_new();
154 if (ctx == NULL) goto err; 152 if (ctx == NULL) goto err;
155 153
156 if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err; 154 if ((dsa->kinv == NULL) || (dsa->r == NULL))
155 {
156 if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
157 }
158 else
159 {
160 kinv=dsa->kinv;
161 dsa->kinv=NULL;
162 r=dsa->r;
163 dsa->r=NULL;
164 }
157 165
158 if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; 166
167 if (dlen > BN_num_bytes(dsa->q))
168 /* if the digest length is greater than the size of q use the
169 * BN_num_bits(dsa->q) leftmost bits of the digest, see
170 * fips 186-3, 4.2 */
171 dlen = BN_num_bytes(dsa->q);
172 if (BN_bin2bn(dgst,dlen,&m) == NULL)
173 goto err;
159 174
160 /* Compute s = inv(k) (m + xr) mod q */ 175 /* Compute s = inv(k) (m + xr) mod q */
161 if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ 176 if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
162 if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */ 177 if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */
163 if (BN_cmp(s,dsa->q) > 0) 178 if (BN_cmp(s,dsa->q) > 0)
164 BN_sub(s,s,dsa->q); 179 if (!BN_sub(s,s,dsa->q)) goto err;
165 if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err; 180 if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
166 181
167 ret=DSA_SIG_new(); 182 ret=DSA_SIG_new();
@@ -214,12 +229,12 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
214 while (BN_is_zero(&k)); 229 while (BN_is_zero(&k));
215 if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) 230 if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
216 { 231 {
217 BN_set_flags(&k, BN_FLG_EXP_CONSTTIME); 232 BN_set_flags(&k, BN_FLG_CONSTTIME);
218 } 233 }
219 234
220 if (dsa->flags & DSA_FLAG_CACHE_MONT_P) 235 if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
221 { 236 {
222 if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, 237 if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
223 CRYPTO_LOCK_DSA, 238 CRYPTO_LOCK_DSA,
224 dsa->p, ctx)) 239 dsa->p, ctx))
225 goto err; 240 goto err;
@@ -249,8 +264,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
249 { 264 {
250 K = &k; 265 K = &k;
251 } 266 }
252 if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,K,dsa->p,ctx, 267 DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
253 (BN_MONT_CTX *)dsa->method_mont_p)) goto err; 268 dsa->method_mont_p);
254 if (!BN_mod(r,r,dsa->q,ctx)) goto err; 269 if (!BN_mod(r,r,dsa->q,ctx)) goto err;
255 270
256 /* Compute part of 's = inv(k) (m + xr) mod q' */ 271 /* Compute part of 's = inv(k) (m + xr) mod q' */
@@ -266,48 +281,55 @@ err:
266 if (!ret) 281 if (!ret)
267 { 282 {
268 DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB); 283 DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
269 if (kinv != NULL) BN_clear_free(kinv); 284 if (r != NULL)
270 if (r != NULL) BN_clear_free(r); 285 BN_clear_free(r);
271 } 286 }
272 if (ctx_in == NULL) BN_CTX_free(ctx); 287 if (ctx_in == NULL) BN_CTX_free(ctx);
273 if (kinv != NULL) BN_clear_free(kinv);
274 BN_clear_free(&k); 288 BN_clear_free(&k);
275 BN_clear_free(&kq); 289 BN_clear_free(&kq);
276 return(ret); 290 return(ret);
277 } 291 }
278 292
279static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig, 293static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
280 DSA *dsa) 294 DSA *dsa)
281 { 295 {
282 BN_CTX *ctx; 296 BN_CTX *ctx;
283 BIGNUM u1,u2,t1; 297 BIGNUM u1,u2,t1;
284 BN_MONT_CTX *mont=NULL; 298 BN_MONT_CTX *mont=NULL;
285 int ret = -1; 299 int ret = -1, i;
286
287 if (!dsa->p || !dsa->q || !dsa->g) 300 if (!dsa->p || !dsa->q || !dsa->g)
288 { 301 {
289 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS); 302 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
290 return -1; 303 return -1;
291 } 304 }
292 305
293 if(FIPS_selftest_failed()) 306 i = BN_num_bits(dsa->q);
294 { 307 /* fips 186-3 allows only different sizes for q */
295 FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED); 308 if (i != 160 && i != 224 && i != 256)
296 return -1; 309 {
297 } 310 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
311 return -1;
312 }
298 313
314 if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
315 {
316 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
317 return -1;
318 }
299 BN_init(&u1); 319 BN_init(&u1);
300 BN_init(&u2); 320 BN_init(&u2);
301 BN_init(&t1); 321 BN_init(&t1);
302 322
303 if ((ctx=BN_CTX_new()) == NULL) goto err; 323 if ((ctx=BN_CTX_new()) == NULL) goto err;
304 324
305 if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0) 325 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
326 BN_ucmp(sig->r, dsa->q) >= 0)
306 { 327 {
307 ret = 0; 328 ret = 0;
308 goto err; 329 goto err;
309 } 330 }
310 if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0) 331 if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
332 BN_ucmp(sig->s, dsa->q) >= 0)
311 { 333 {
312 ret = 0; 334 ret = 0;
313 goto err; 335 goto err;
@@ -318,6 +340,11 @@ static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DS
318 if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; 340 if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
319 341
320 /* save M in u1 */ 342 /* save M in u1 */
343 if (dgst_len > (i >> 3))
344 /* if the digest length is greater than the size of q use the
345 * BN_num_bits(dsa->q) leftmost bits of the digest, see
346 * fips 186-3, 4.2 */
347 dgst_len = (i >> 3);
321 if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; 348 if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
322 349
323 /* u1 = M * w mod q */ 350 /* u1 = M * w mod q */
@@ -329,43 +356,25 @@ static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DS
329 356
330 if (dsa->flags & DSA_FLAG_CACHE_MONT_P) 357 if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
331 { 358 {
332 mont = BN_MONT_CTX_set_locked( 359 mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
333 (BN_MONT_CTX **)&dsa->method_mont_p,
334 CRYPTO_LOCK_DSA, dsa->p, ctx); 360 CRYPTO_LOCK_DSA, dsa->p, ctx);
335 if (!mont) 361 if (!mont)
336 goto err; 362 goto err;
337 } 363 }
338 364
339#if 0 365
340 { 366 DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont);
341 BIGNUM t2;
342
343 BN_init(&t2);
344 /* v = ( g^u1 * y^u2 mod p ) mod q */
345 /* let t1 = g ^ u1 mod p */
346 if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err;
347 /* let t2 = y ^ u2 mod p */
348 if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err;
349 /* let u1 = t1 * t2 mod p */
350 if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn;
351 BN_free(&t2);
352 }
353 /* let u1 = u1 mod q */
354 if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err;
355#else
356 {
357 if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2,
358 dsa->p,ctx,mont)) goto err;
359 /* BN_copy(&u1,&t1); */ 367 /* BN_copy(&u1,&t1); */
360 /* let u1 = u1 mod q */ 368 /* let u1 = u1 mod q */
361 if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err; 369 if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
362 } 370
363#endif
364 /* V is now in u1. If the signature is correct, it will be 371 /* V is now in u1. If the signature is correct, it will be
365 * equal to R. */ 372 * equal to R. */
366 ret=(BN_ucmp(&u1, sig->r) == 0); 373 ret=(BN_ucmp(&u1, sig->r) == 0);
367 374
368 err: 375 err:
376 /* XXX: surely this is wrong - if ret is 0, it just didn't verify;
377 there is no error in BN. Test should be ret == -1 (Ben) */
369 if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB); 378 if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
370 if (ctx != NULL) BN_CTX_free(ctx); 379 if (ctx != NULL) BN_CTX_free(ctx);
371 BN_free(&u1); 380 BN_free(&u1);
@@ -383,26 +392,7 @@ static int dsa_init(DSA *dsa)
383static int dsa_finish(DSA *dsa) 392static int dsa_finish(DSA *dsa)
384{ 393{
385 if(dsa->method_mont_p) 394 if(dsa->method_mont_p)
386 BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p); 395 BN_MONT_CTX_free(dsa->method_mont_p);
387 return(1); 396 return(1);
388} 397}
389 398
390static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
391 BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
392 BN_MONT_CTX *in_mont)
393{
394 return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont);
395}
396
397static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
398 const BIGNUM *m, BN_CTX *ctx,
399 BN_MONT_CTX *m_ctx)
400{
401 return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
402}
403
404#else /* ndef OPENSSL_FIPS */
405
406static void *dummy=&dummy;
407
408#endif /* ndef OPENSSL_FIPS */