| OLD | NEW |
| (Empty) |
| 1 /* 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 | |
| 61 #include <stdio.h> | |
| 62 #include <openssl/bn.h> | |
| 63 #include <openssl/dsa.h> | |
| 64 #include <openssl/rand.h> | |
| 65 #include <openssl/asn1.h> | |
| 66 #include <openssl/err.h> | |
| 67 #ifndef OPENSSL_NO_ENGINE | |
| 68 #include <openssl/engine.h> | |
| 69 #endif | |
| 70 #include <openssl/fips.h> | |
| 71 | |
| 72 #ifdef OPENSSL_FIPS | |
| 73 | |
| 74 static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA
*dsa); | |
| 75 static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
; | |
| 76 static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DS
A_SIG *sig, | |
| 77 DSA *dsa); | |
| 78 static int dsa_init(DSA *dsa); | |
| 79 static int dsa_finish(DSA *dsa); | |
| 80 static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, | |
| 81 BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, | |
| 82 BN_MONT_CTX *in_mont); | |
| 83 static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | |
| 84 const BIGNUM *m, BN_CTX *ctx, | |
| 85 BN_MONT_CTX *m_ctx); | |
| 86 | |
| 87 static const DSA_METHOD openssl_dsa_meth = { | |
| 88 "OpenSSL FIPS DSA method", | |
| 89 dsa_do_sign, | |
| 90 dsa_sign_setup, | |
| 91 dsa_do_verify, | |
| 92 dsa_mod_exp, | |
| 93 dsa_bn_mod_exp, | |
| 94 dsa_init, | |
| 95 dsa_finish, | |
| 96 DSA_FLAG_FIPS_METHOD, | |
| 97 NULL | |
| 98 }; | |
| 99 #if 0 | |
| 100 int FIPS_dsa_check(struct dsa_st *dsa) | |
| 101 { | |
| 102 if(dsa->meth != &openssl_dsa_meth || dsa->meth->dsa_do_sign != dsa_do_sign | |
| 103 || dsa->meth->dsa_sign_setup != dsa_sign_setup | |
| 104 || dsa->meth->dsa_mod_exp != dsa_mod_exp | |
| 105 || dsa->meth->bn_mod_exp != dsa_bn_mod_exp | |
| 106 || dsa->meth->init != dsa_init | |
| 107 || dsa->meth->finish != dsa_finish) | |
| 108 { | |
| 109 FIPSerr(FIPS_F_FIPS_DSA_CHECK,FIPS_R_NON_FIPS_METHOD); | |
| 110 return 0; | |
| 111 } | |
| 112 return 1; | |
| 113 } | |
| 114 #endif | |
| 115 | |
| 116 const DSA_METHOD *DSA_OpenSSL(void) | |
| 117 { | |
| 118 return &openssl_dsa_meth; | |
| 119 } | |
| 120 | |
| 121 static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA
*dsa) | |
| 122 { | |
| 123 BIGNUM *kinv=NULL,*r=NULL,*s=NULL; | |
| 124 BIGNUM m; | |
| 125 BIGNUM xr; | |
| 126 BN_CTX *ctx=NULL; | |
| 127 int i,reason=ERR_R_BN_LIB; | |
| 128 DSA_SIG *ret=NULL; | |
| 129 | |
| 130 if(FIPS_selftest_failed()) | |
| 131 { | |
| 132 FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED); | |
| 133 return NULL; | |
| 134 } | |
| 135 | |
| 136 if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_B
ITS)) | |
| 137 { | |
| 138 DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL); | |
| 139 return NULL; | |
| 140 } | |
| 141 | |
| 142 BN_init(&m); | |
| 143 BN_init(&xr); | |
| 144 | |
| 145 if (!dsa->p || !dsa->q || !dsa->g) | |
| 146 { | |
| 147 reason=DSA_R_MISSING_PARAMETERS; | |
| 148 goto err; | |
| 149 } | |
| 150 | |
| 151 s=BN_new(); | |
| 152 if (s == NULL) goto err; | |
| 153 | |
| 154 i=BN_num_bytes(dsa->q); /* should be 20 */ | |
| 155 if ((dlen > i) || (dlen > 50)) | |
| 156 { | |
| 157 reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; | |
| 158 goto err; | |
| 159 } | |
| 160 | |
| 161 ctx=BN_CTX_new(); | |
| 162 if (ctx == NULL) goto err; | |
| 163 | |
| 164 if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r)) goto err; | |
| 165 | |
| 166 if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; | |
| 167 | |
| 168 /* Compute s = inv(k) (m + xr) mod q */ | |
| 169 if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ | |
| 170 if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */ | |
| 171 if (BN_cmp(s,dsa->q) > 0) | |
| 172 BN_sub(s,s,dsa->q); | |
| 173 if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err; | |
| 174 | |
| 175 ret= DSA_SIG_new(); | |
| 176 if (ret == NULL) goto err; | |
| 177 ret->r = r; | |
| 178 ret->s = s; | |
| 179 | |
| 180 err: | |
| 181 if (!ret) | |
| 182 { | |
| 183 DSAerr(DSA_F_DSA_DO_SIGN,reason); | |
| 184 BN_free(r); | |
| 185 BN_free(s); | |
| 186 } | |
| 187 if (ctx != NULL) BN_CTX_free(ctx); | |
| 188 BN_clear_free(&m); | |
| 189 BN_clear_free(&xr); | |
| 190 if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ | |
| 191 BN_clear_free(kinv); | |
| 192 return(ret); | |
| 193 } | |
| 194 | |
| 195 static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) | |
| 196 { | |
| 197 BN_CTX *ctx; | |
| 198 BIGNUM k,kq,*K,*kinv=NULL,*r=NULL; | |
| 199 int ret=0; | |
| 200 | |
| 201 if (!dsa->p || !dsa->q || !dsa->g) | |
| 202 { | |
| 203 DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS); | |
| 204 return 0; | |
| 205 } | |
| 206 | |
| 207 BN_init(&k); | |
| 208 BN_init(&kq); | |
| 209 | |
| 210 if (ctx_in == NULL) | |
| 211 { | |
| 212 if ((ctx=BN_CTX_new()) == NULL) goto err; | |
| 213 } | |
| 214 else | |
| 215 ctx=ctx_in; | |
| 216 | |
| 217 if ((r=BN_new()) == NULL) goto err; | |
| 218 | |
| 219 /* Get random k */ | |
| 220 do | |
| 221 if (!BN_rand_range(&k, dsa->q)) goto err; | |
| 222 while (BN_is_zero(&k)); | |
| 223 if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) | |
| 224 { | |
| 225 BN_set_flags(&k, BN_FLG_CONSTTIME); | |
| 226 } | |
| 227 | |
| 228 if (dsa->flags & DSA_FLAG_CACHE_MONT_P) | |
| 229 { | |
| 230 if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, | |
| 231 CRYPTO_LOCK_DSA, | |
| 232 dsa->p, ctx)) | |
| 233 goto err; | |
| 234 } | |
| 235 | |
| 236 /* Compute r = (g^k mod p) mod q */ | |
| 237 | |
| 238 if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) | |
| 239 { | |
| 240 if (!BN_copy(&kq, &k)) goto err; | |
| 241 | |
| 242 /* We do not want timing information to leak the length of k, | |
| 243 * so we compute g^k using an equivalent exponent of fixed lengt
h. | |
| 244 * | |
| 245 * (This is a kludge that we need because the BN_mod_exp_mont() | |
| 246 * does not let us specify the desired timing behaviour.) */ | |
| 247 | |
| 248 if (!BN_add(&kq, &kq, dsa->q)) goto err; | |
| 249 if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) | |
| 250 { | |
| 251 if (!BN_add(&kq, &kq, dsa->q)) goto err; | |
| 252 } | |
| 253 | |
| 254 K = &kq; | |
| 255 } | |
| 256 else | |
| 257 { | |
| 258 K = &k; | |
| 259 } | |
| 260 if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,K,dsa->p,ctx, | |
| 261 (BN_MONT_CTX *)dsa->method_mont_p)) goto err; | |
| 262 if (!BN_mod(r,r,dsa->q,ctx)) goto err; | |
| 263 | |
| 264 /* Compute part of 's = inv(k) (m + xr) mod q' */ | |
| 265 if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err; | |
| 266 | |
| 267 if (*kinvp != NULL) BN_clear_free(*kinvp); | |
| 268 *kinvp=kinv; | |
| 269 kinv=NULL; | |
| 270 if (*rp != NULL) BN_clear_free(*rp); | |
| 271 *rp=r; | |
| 272 ret=1; | |
| 273 err: | |
| 274 if (!ret) | |
| 275 { | |
| 276 DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB); | |
| 277 if (kinv != NULL) BN_clear_free(kinv); | |
| 278 if (r != NULL) BN_clear_free(r); | |
| 279 } | |
| 280 if (ctx_in == NULL) BN_CTX_free(ctx); | |
| 281 if (kinv != NULL) BN_clear_free(kinv); | |
| 282 BN_clear_free(&k); | |
| 283 BN_clear_free(&kq); | |
| 284 return(ret); | |
| 285 } | |
| 286 | |
| 287 static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DS
A_SIG *sig, | |
| 288 DSA *dsa) | |
| 289 { | |
| 290 BN_CTX *ctx; | |
| 291 BIGNUM u1,u2,t1; | |
| 292 BN_MONT_CTX *mont=NULL; | |
| 293 int ret = -1; | |
| 294 | |
| 295 if (!dsa->p || !dsa->q || !dsa->g) | |
| 296 { | |
| 297 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS); | |
| 298 return -1; | |
| 299 } | |
| 300 | |
| 301 if(FIPS_selftest_failed()) | |
| 302 { | |
| 303 FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED); | |
| 304 return -1; | |
| 305 } | |
| 306 | |
| 307 if (BN_num_bits(dsa->q) != 160) | |
| 308 { | |
| 309 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE); | |
| 310 return -1; | |
| 311 } | |
| 312 | |
| 313 if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) | |
| 314 { | |
| 315 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE); | |
| 316 return -1; | |
| 317 } | |
| 318 | |
| 319 if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_B
ITS)) | |
| 320 { | |
| 321 DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); | |
| 322 return -1; | |
| 323 } | |
| 324 | |
| 325 BN_init(&u1); | |
| 326 BN_init(&u2); | |
| 327 BN_init(&t1); | |
| 328 | |
| 329 if ((ctx=BN_CTX_new()) == NULL) goto err; | |
| 330 | |
| 331 if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0) | |
| 332 { | |
| 333 ret = 0; | |
| 334 goto err; | |
| 335 } | |
| 336 if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0) | |
| 337 { | |
| 338 ret = 0; | |
| 339 goto err; | |
| 340 } | |
| 341 | |
| 342 /* Calculate W = inv(S) mod Q | |
| 343 * save W in u2 */ | |
| 344 if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; | |
| 345 | |
| 346 /* save M in u1 */ | |
| 347 if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; | |
| 348 | |
| 349 /* u1 = M * w mod q */ | |
| 350 if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err; | |
| 351 | |
| 352 /* u2 = r * w mod q */ | |
| 353 if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err; | |
| 354 | |
| 355 | |
| 356 if (dsa->flags & DSA_FLAG_CACHE_MONT_P) | |
| 357 { | |
| 358 mont = BN_MONT_CTX_set_locked( | |
| 359 (BN_MONT_CTX **)&dsa->method_mont_p, | |
| 360 CRYPTO_LOCK_DSA, dsa->p, ctx); | |
| 361 if (!mont) | |
| 362 goto err; | |
| 363 } | |
| 364 | |
| 365 #if 0 | |
| 366 { | |
| 367 BIGNUM t2; | |
| 368 | |
| 369 BN_init(&t2); | |
| 370 /* v = ( g^u1 * y^u2 mod p ) mod q */ | |
| 371 /* let t1 = g ^ u1 mod p */ | |
| 372 if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err; | |
| 373 /* let t2 = y ^ u2 mod p */ | |
| 374 if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err; | |
| 375 /* let u1 = t1 * t2 mod p */ | |
| 376 if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn; | |
| 377 BN_free(&t2); | |
| 378 } | |
| 379 /* let u1 = u1 mod q */ | |
| 380 if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err; | |
| 381 #else | |
| 382 { | |
| 383 if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2, | |
| 384 dsa->p,ctx,mont)) goto err; | |
| 385 /* BN_copy(&u1,&t1); */ | |
| 386 /* let u1 = u1 mod q */ | |
| 387 if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err; | |
| 388 } | |
| 389 #endif | |
| 390 /* V is now in u1. If the signature is correct, it will be | |
| 391 * equal to R. */ | |
| 392 ret=(BN_ucmp(&u1, sig->r) == 0); | |
| 393 | |
| 394 err: | |
| 395 if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB); | |
| 396 if (ctx != NULL) BN_CTX_free(ctx); | |
| 397 BN_free(&u1); | |
| 398 BN_free(&u2); | |
| 399 BN_free(&t1); | |
| 400 return(ret); | |
| 401 } | |
| 402 | |
| 403 static int dsa_init(DSA *dsa) | |
| 404 { | |
| 405 FIPS_selftest_check(); | |
| 406 dsa->flags|=DSA_FLAG_CACHE_MONT_P; | |
| 407 return(1); | |
| 408 } | |
| 409 | |
| 410 static int dsa_finish(DSA *dsa) | |
| 411 { | |
| 412 if(dsa->method_mont_p) | |
| 413 BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p); | |
| 414 return(1); | |
| 415 } | |
| 416 | |
| 417 static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, | |
| 418 BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, | |
| 419 BN_MONT_CTX *in_mont) | |
| 420 { | |
| 421 return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont); | |
| 422 } | |
| 423 | |
| 424 static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | |
| 425 const BIGNUM *m, BN_CTX *ctx, | |
| 426 BN_MONT_CTX *m_ctx) | |
| 427 { | |
| 428 return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); | |
| 429 } | |
| 430 | |
| 431 #else /* ndef OPENSSL_FIPS */ | |
| 432 | |
| 433 static void *dummy=&dummy; | |
| 434 | |
| 435 #endif /* ndef OPENSSL_FIPS */ | |
| OLD | NEW |