10Sstevel@tonic-gate /* crypto/dsa/dsa_ossl.c */ 20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 30Sstevel@tonic-gate * All rights reserved. 40Sstevel@tonic-gate * 50Sstevel@tonic-gate * This package is an SSL implementation written 60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 150Sstevel@tonic-gate * 160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 170Sstevel@tonic-gate * the code are not to be removed. 180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 190Sstevel@tonic-gate * as the author of the parts of the library used. 200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 210Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 220Sstevel@tonic-gate * 230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 240Sstevel@tonic-gate * modification, are permitted provided that the following conditions 250Sstevel@tonic-gate * are met: 260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 320Sstevel@tonic-gate * must display the following acknowledgement: 330Sstevel@tonic-gate * "This product includes cryptographic software written by 340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 360Sstevel@tonic-gate * being used are not cryptographic related :-). 370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 400Sstevel@tonic-gate * 410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 510Sstevel@tonic-gate * SUCH DAMAGE. 520Sstevel@tonic-gate * 530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 550Sstevel@tonic-gate * copied and put under another distribution licence 560Sstevel@tonic-gate * [including the GNU Public Licence.] 570Sstevel@tonic-gate */ 580Sstevel@tonic-gate 590Sstevel@tonic-gate /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */ 600Sstevel@tonic-gate 610Sstevel@tonic-gate #include <stdio.h> 620Sstevel@tonic-gate #include "cryptlib.h" 630Sstevel@tonic-gate #include <openssl/bn.h> 640Sstevel@tonic-gate #include <openssl/dsa.h> 650Sstevel@tonic-gate #include <openssl/rand.h> 660Sstevel@tonic-gate #include <openssl/asn1.h> 670Sstevel@tonic-gate 680Sstevel@tonic-gate static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); 690Sstevel@tonic-gate static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); 700Sstevel@tonic-gate static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, 710Sstevel@tonic-gate DSA *dsa); 720Sstevel@tonic-gate static int dsa_init(DSA *dsa); 730Sstevel@tonic-gate static int dsa_finish(DSA *dsa); 740Sstevel@tonic-gate 750Sstevel@tonic-gate static DSA_METHOD openssl_dsa_meth = { 760Sstevel@tonic-gate "OpenSSL DSA method", 770Sstevel@tonic-gate dsa_do_sign, 780Sstevel@tonic-gate dsa_sign_setup, 790Sstevel@tonic-gate dsa_do_verify, 80*2139Sjp161948 NULL, /* dsa_mod_exp, */ 81*2139Sjp161948 NULL, /* dsa_bn_mod_exp, */ 820Sstevel@tonic-gate dsa_init, 830Sstevel@tonic-gate dsa_finish, 840Sstevel@tonic-gate 0, 85*2139Sjp161948 NULL, 86*2139Sjp161948 NULL, 870Sstevel@tonic-gate NULL 880Sstevel@tonic-gate }; 890Sstevel@tonic-gate 90*2139Sjp161948 /* These macro wrappers replace attempts to use the dsa_mod_exp() and 91*2139Sjp161948 * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of 92*2139Sjp161948 * having a the macro work as an expression by bundling an "err_instr". So; 93*2139Sjp161948 * 94*2139Sjp161948 * if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx, 95*2139Sjp161948 * dsa->method_mont_p)) goto err; 96*2139Sjp161948 * 97*2139Sjp161948 * can be replaced by; 98*2139Sjp161948 * 99*2139Sjp161948 * DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx, 100*2139Sjp161948 * dsa->method_mont_p); 101*2139Sjp161948 */ 102*2139Sjp161948 103*2139Sjp161948 #define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \ 104*2139Sjp161948 do { \ 105*2139Sjp161948 int _tmp_res53; \ 106*2139Sjp161948 if((dsa)->meth->dsa_mod_exp) \ 107*2139Sjp161948 _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \ 108*2139Sjp161948 (a2), (p2), (m), (ctx), (in_mont)); \ 109*2139Sjp161948 else \ 110*2139Sjp161948 _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \ 111*2139Sjp161948 (m), (ctx), (in_mont)); \ 112*2139Sjp161948 if(!_tmp_res53) err_instr; \ 113*2139Sjp161948 } while(0) 114*2139Sjp161948 #define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \ 115*2139Sjp161948 do { \ 116*2139Sjp161948 int _tmp_res53; \ 117*2139Sjp161948 if((dsa)->meth->bn_mod_exp) \ 118*2139Sjp161948 _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \ 119*2139Sjp161948 (m), (ctx), (m_ctx)); \ 120*2139Sjp161948 else \ 121*2139Sjp161948 _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \ 122*2139Sjp161948 if(!_tmp_res53) err_instr; \ 123*2139Sjp161948 } while(0) 124*2139Sjp161948 1250Sstevel@tonic-gate const DSA_METHOD *DSA_OpenSSL(void) 1260Sstevel@tonic-gate { 1270Sstevel@tonic-gate return &openssl_dsa_meth; 1280Sstevel@tonic-gate } 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) 1310Sstevel@tonic-gate { 1320Sstevel@tonic-gate BIGNUM *kinv=NULL,*r=NULL,*s=NULL; 1330Sstevel@tonic-gate BIGNUM m; 1340Sstevel@tonic-gate BIGNUM xr; 1350Sstevel@tonic-gate BN_CTX *ctx=NULL; 1360Sstevel@tonic-gate int i,reason=ERR_R_BN_LIB; 1370Sstevel@tonic-gate DSA_SIG *ret=NULL; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate BN_init(&m); 1400Sstevel@tonic-gate BN_init(&xr); 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate if (!dsa->p || !dsa->q || !dsa->g) 1430Sstevel@tonic-gate { 1440Sstevel@tonic-gate reason=DSA_R_MISSING_PARAMETERS; 1450Sstevel@tonic-gate goto err; 1460Sstevel@tonic-gate } 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate s=BN_new(); 1490Sstevel@tonic-gate if (s == NULL) goto err; 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate i=BN_num_bytes(dsa->q); /* should be 20 */ 1520Sstevel@tonic-gate if ((dlen > i) || (dlen > 50)) 1530Sstevel@tonic-gate { 1540Sstevel@tonic-gate reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; 1550Sstevel@tonic-gate goto err; 1560Sstevel@tonic-gate } 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate ctx=BN_CTX_new(); 1590Sstevel@tonic-gate if (ctx == NULL) goto err; 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate if ((dsa->kinv == NULL) || (dsa->r == NULL)) 1620Sstevel@tonic-gate { 1630Sstevel@tonic-gate if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err; 1640Sstevel@tonic-gate } 1650Sstevel@tonic-gate else 1660Sstevel@tonic-gate { 1670Sstevel@tonic-gate kinv=dsa->kinv; 1680Sstevel@tonic-gate dsa->kinv=NULL; 1690Sstevel@tonic-gate r=dsa->r; 1700Sstevel@tonic-gate dsa->r=NULL; 1710Sstevel@tonic-gate } 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate /* Compute s = inv(k) (m + xr) mod q */ 1760Sstevel@tonic-gate if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ 1770Sstevel@tonic-gate if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */ 1780Sstevel@tonic-gate if (BN_cmp(s,dsa->q) > 0) 1790Sstevel@tonic-gate BN_sub(s,s,dsa->q); 1800Sstevel@tonic-gate if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err; 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate ret=DSA_SIG_new(); 1830Sstevel@tonic-gate if (ret == NULL) goto err; 1840Sstevel@tonic-gate ret->r = r; 1850Sstevel@tonic-gate ret->s = s; 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate err: 1880Sstevel@tonic-gate if (!ret) 1890Sstevel@tonic-gate { 1900Sstevel@tonic-gate DSAerr(DSA_F_DSA_DO_SIGN,reason); 1910Sstevel@tonic-gate BN_free(r); 1920Sstevel@tonic-gate BN_free(s); 1930Sstevel@tonic-gate } 1940Sstevel@tonic-gate if (ctx != NULL) BN_CTX_free(ctx); 1950Sstevel@tonic-gate BN_clear_free(&m); 1960Sstevel@tonic-gate BN_clear_free(&xr); 1970Sstevel@tonic-gate if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ 1980Sstevel@tonic-gate BN_clear_free(kinv); 1990Sstevel@tonic-gate return(ret); 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) 2030Sstevel@tonic-gate { 2040Sstevel@tonic-gate BN_CTX *ctx; 205*2139Sjp161948 BIGNUM k,kq,*K,*kinv=NULL,*r=NULL; 2060Sstevel@tonic-gate int ret=0; 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate if (!dsa->p || !dsa->q || !dsa->g) 2090Sstevel@tonic-gate { 2100Sstevel@tonic-gate DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS); 2110Sstevel@tonic-gate return 0; 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate BN_init(&k); 215*2139Sjp161948 BN_init(&kq); 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate if (ctx_in == NULL) 2180Sstevel@tonic-gate { 2190Sstevel@tonic-gate if ((ctx=BN_CTX_new()) == NULL) goto err; 2200Sstevel@tonic-gate } 2210Sstevel@tonic-gate else 2220Sstevel@tonic-gate ctx=ctx_in; 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate if ((r=BN_new()) == NULL) goto err; 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate /* Get random k */ 2270Sstevel@tonic-gate do 2280Sstevel@tonic-gate if (!BN_rand_range(&k, dsa->q)) goto err; 2290Sstevel@tonic-gate while (BN_is_zero(&k)); 230*2139Sjp161948 if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) 2310Sstevel@tonic-gate { 232*2139Sjp161948 BN_set_flags(&k, BN_FLG_EXP_CONSTTIME); 233*2139Sjp161948 } 234*2139Sjp161948 235*2139Sjp161948 if (dsa->flags & DSA_FLAG_CACHE_MONT_P) 236*2139Sjp161948 { 237*2139Sjp161948 if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, 238*2139Sjp161948 CRYPTO_LOCK_DSA, 239*2139Sjp161948 dsa->p, ctx)) 240*2139Sjp161948 goto err; 2410Sstevel@tonic-gate } 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate /* Compute r = (g^k mod p) mod q */ 244*2139Sjp161948 245*2139Sjp161948 if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) 246*2139Sjp161948 { 247*2139Sjp161948 if (!BN_copy(&kq, &k)) goto err; 248*2139Sjp161948 249*2139Sjp161948 /* We do not want timing information to leak the length of k, 250*2139Sjp161948 * so we compute g^k using an equivalent exponent of fixed length. 251*2139Sjp161948 * 252*2139Sjp161948 * (This is a kludge that we need because the BN_mod_exp_mont() 253*2139Sjp161948 * does not let us specify the desired timing behaviour.) */ 254*2139Sjp161948 255*2139Sjp161948 if (!BN_add(&kq, &kq, dsa->q)) goto err; 256*2139Sjp161948 if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) 257*2139Sjp161948 { 258*2139Sjp161948 if (!BN_add(&kq, &kq, dsa->q)) goto err; 259*2139Sjp161948 } 260*2139Sjp161948 261*2139Sjp161948 K = &kq; 262*2139Sjp161948 } 263*2139Sjp161948 else 264*2139Sjp161948 { 265*2139Sjp161948 K = &k; 266*2139Sjp161948 } 267*2139Sjp161948 DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx, 268*2139Sjp161948 dsa->method_mont_p); 2690Sstevel@tonic-gate if (!BN_mod(r,r,dsa->q,ctx)) goto err; 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate /* Compute part of 's = inv(k) (m + xr) mod q' */ 2720Sstevel@tonic-gate if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err; 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate if (*kinvp != NULL) BN_clear_free(*kinvp); 2750Sstevel@tonic-gate *kinvp=kinv; 2760Sstevel@tonic-gate kinv=NULL; 2770Sstevel@tonic-gate if (*rp != NULL) BN_clear_free(*rp); 2780Sstevel@tonic-gate *rp=r; 2790Sstevel@tonic-gate ret=1; 2800Sstevel@tonic-gate err: 2810Sstevel@tonic-gate if (!ret) 2820Sstevel@tonic-gate { 2830Sstevel@tonic-gate DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB); 2840Sstevel@tonic-gate if (kinv != NULL) BN_clear_free(kinv); 2850Sstevel@tonic-gate if (r != NULL) BN_clear_free(r); 2860Sstevel@tonic-gate } 2870Sstevel@tonic-gate if (ctx_in == NULL) BN_CTX_free(ctx); 2880Sstevel@tonic-gate if (kinv != NULL) BN_clear_free(kinv); 2890Sstevel@tonic-gate BN_clear_free(&k); 290*2139Sjp161948 BN_clear_free(&kq); 2910Sstevel@tonic-gate return(ret); 2920Sstevel@tonic-gate } 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, 2950Sstevel@tonic-gate DSA *dsa) 2960Sstevel@tonic-gate { 2970Sstevel@tonic-gate BN_CTX *ctx; 2980Sstevel@tonic-gate BIGNUM u1,u2,t1; 2990Sstevel@tonic-gate BN_MONT_CTX *mont=NULL; 3000Sstevel@tonic-gate int ret = -1; 3010Sstevel@tonic-gate if (!dsa->p || !dsa->q || !dsa->g) 3020Sstevel@tonic-gate { 3030Sstevel@tonic-gate DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS); 3040Sstevel@tonic-gate return -1; 3050Sstevel@tonic-gate } 3060Sstevel@tonic-gate 3070Sstevel@tonic-gate BN_init(&u1); 3080Sstevel@tonic-gate BN_init(&u2); 3090Sstevel@tonic-gate BN_init(&t1); 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate if ((ctx=BN_CTX_new()) == NULL) goto err; 3120Sstevel@tonic-gate 313*2139Sjp161948 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || 314*2139Sjp161948 BN_ucmp(sig->r, dsa->q) >= 0) 3150Sstevel@tonic-gate { 3160Sstevel@tonic-gate ret = 0; 3170Sstevel@tonic-gate goto err; 3180Sstevel@tonic-gate } 319*2139Sjp161948 if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || 320*2139Sjp161948 BN_ucmp(sig->s, dsa->q) >= 0) 3210Sstevel@tonic-gate { 3220Sstevel@tonic-gate ret = 0; 3230Sstevel@tonic-gate goto err; 3240Sstevel@tonic-gate } 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate /* Calculate W = inv(S) mod Q 3270Sstevel@tonic-gate * save W in u2 */ 3280Sstevel@tonic-gate if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; 3290Sstevel@tonic-gate 3300Sstevel@tonic-gate /* save M in u1 */ 3310Sstevel@tonic-gate if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate /* u1 = M * w mod q */ 3340Sstevel@tonic-gate if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err; 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate /* u2 = r * w mod q */ 3370Sstevel@tonic-gate if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err; 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate 340*2139Sjp161948 if (dsa->flags & DSA_FLAG_CACHE_MONT_P) 341*2139Sjp161948 { 342*2139Sjp161948 mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p, 343*2139Sjp161948 CRYPTO_LOCK_DSA, dsa->p, ctx); 344*2139Sjp161948 if (!mont) 345*2139Sjp161948 goto err; 346*2139Sjp161948 } 347*2139Sjp161948 348*2139Sjp161948 349*2139Sjp161948 DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont); 3500Sstevel@tonic-gate /* BN_copy(&u1,&t1); */ 3510Sstevel@tonic-gate /* let u1 = u1 mod q */ 3520Sstevel@tonic-gate if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err; 353*2139Sjp161948 3540Sstevel@tonic-gate /* V is now in u1. If the signature is correct, it will be 3550Sstevel@tonic-gate * equal to R. */ 3560Sstevel@tonic-gate ret=(BN_ucmp(&u1, sig->r) == 0); 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate err: 359*2139Sjp161948 /* XXX: surely this is wrong - if ret is 0, it just didn't verify; 360*2139Sjp161948 there is no error in BN. Test should be ret == -1 (Ben) */ 3610Sstevel@tonic-gate if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB); 3620Sstevel@tonic-gate if (ctx != NULL) BN_CTX_free(ctx); 3630Sstevel@tonic-gate BN_free(&u1); 3640Sstevel@tonic-gate BN_free(&u2); 3650Sstevel@tonic-gate BN_free(&t1); 3660Sstevel@tonic-gate return(ret); 3670Sstevel@tonic-gate } 3680Sstevel@tonic-gate 3690Sstevel@tonic-gate static int dsa_init(DSA *dsa) 3700Sstevel@tonic-gate { 3710Sstevel@tonic-gate dsa->flags|=DSA_FLAG_CACHE_MONT_P; 3720Sstevel@tonic-gate return(1); 3730Sstevel@tonic-gate } 3740Sstevel@tonic-gate 3750Sstevel@tonic-gate static int dsa_finish(DSA *dsa) 3760Sstevel@tonic-gate { 3770Sstevel@tonic-gate if(dsa->method_mont_p) 378*2139Sjp161948 BN_MONT_CTX_free(dsa->method_mont_p); 3790Sstevel@tonic-gate return(1); 3800Sstevel@tonic-gate } 3810Sstevel@tonic-gate 382