1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/dsa/dsa_ossl.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,419 @@
1.4 +/* crypto/dsa/dsa_ossl.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +
1.62 +/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
1.63 +/*
1.64 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.65 + */
1.66 +
1.67 +#include <stdio.h>
1.68 +#include "cryptlib.h"
1.69 +#include <openssl/bn.h>
1.70 +#include <openssl/dsa.h>
1.71 +#include <openssl/rand.h>
1.72 +#include <openssl/asn1.h>
1.73 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
1.74 +#include "libcrypto_wsd_macros.h"
1.75 +#include "libcrypto_wsd.h"
1.76 +#endif
1.77 +
1.78 +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
1.79 +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
1.80 +static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
1.81 + DSA *dsa);
1.82 +static int dsa_init(DSA *dsa);
1.83 +static int dsa_finish(DSA *dsa);
1.84 +
1.85 +#ifndef EMULATOR
1.86 +static DSA_METHOD openssl_dsa_meth = {
1.87 +"OpenSSL DSA method",
1.88 +dsa_do_sign,
1.89 +dsa_sign_setup,
1.90 +dsa_do_verify,
1.91 +NULL, /* dsa_mod_exp, */
1.92 +NULL, /* dsa_bn_mod_exp, */
1.93 +dsa_init,
1.94 +dsa_finish,
1.95 +0,
1.96 +NULL,
1.97 +NULL,
1.98 +NULL
1.99 +};
1.100 +#else
1.101 +GET_STATIC_VAR_FROM_TLS(openssl_dsa_meth,dsa_ossl,DSA_METHOD)
1.102 +#define openssl_dsa_meth (*GET_WSD_VAR_NAME(openssl_dsa_meth,dsa_ossl, s)())
1.103 +const DSA_METHOD temp_s_openssl_dsa_meth = {
1.104 +"OpenSSL DSA method",
1.105 +dsa_do_sign,
1.106 +dsa_sign_setup,
1.107 +dsa_do_verify,
1.108 +NULL, /* dsa_mod_exp, */
1.109 +NULL, /* dsa_bn_mod_exp, */
1.110 +dsa_init,
1.111 +dsa_finish,
1.112 +0,
1.113 +NULL,
1.114 +NULL,
1.115 +NULL
1.116 +};
1.117 +#endif
1.118 +
1.119 +/* These macro wrappers replace attempts to use the dsa_mod_exp() and
1.120 + * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of
1.121 + * having a the macro work as an expression by bundling an "err_instr". So;
1.122 + *
1.123 + * if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
1.124 + * dsa->method_mont_p)) goto err;
1.125 + *
1.126 + * can be replaced by;
1.127 + *
1.128 + * DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx,
1.129 + * dsa->method_mont_p);
1.130 + */
1.131 +
1.132 +#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \
1.133 + do { \
1.134 + int _tmp_res53; \
1.135 + if((dsa)->meth->dsa_mod_exp) \
1.136 + _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \
1.137 + (a2), (p2), (m), (ctx), (in_mont)); \
1.138 + else \
1.139 + _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \
1.140 + (m), (ctx), (in_mont)); \
1.141 + if(!_tmp_res53) err_instr; \
1.142 + } while(0)
1.143 +#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \
1.144 + do { \
1.145 + int _tmp_res53; \
1.146 + if((dsa)->meth->bn_mod_exp) \
1.147 + _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \
1.148 + (m), (ctx), (m_ctx)); \
1.149 + else \
1.150 + _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \
1.151 + if(!_tmp_res53) err_instr; \
1.152 + } while(0)
1.153 +
1.154 +EXPORT_C const DSA_METHOD *DSA_OpenSSL(void)
1.155 +{
1.156 + return &openssl_dsa_meth;
1.157 +}
1.158 +
1.159 +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
1.160 + {
1.161 + BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
1.162 + BIGNUM m;
1.163 + BIGNUM xr;
1.164 + BN_CTX *ctx=NULL;
1.165 + int i,reason=ERR_R_BN_LIB;
1.166 + DSA_SIG *ret=NULL;
1.167 +
1.168 + BN_init(&m);
1.169 + BN_init(&xr);
1.170 +
1.171 + if (!dsa->p || !dsa->q || !dsa->g)
1.172 + {
1.173 + reason=DSA_R_MISSING_PARAMETERS;
1.174 + goto err;
1.175 + }
1.176 +
1.177 + s=BN_new();
1.178 + if (s == NULL) goto err;
1.179 +
1.180 + i=BN_num_bytes(dsa->q); /* should be 20 */
1.181 + if ((dlen > i) || (dlen > 50))
1.182 + {
1.183 + reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
1.184 + goto err;
1.185 + }
1.186 +
1.187 + ctx=BN_CTX_new();
1.188 + if (ctx == NULL) goto err;
1.189 +
1.190 + if ((dsa->kinv == NULL) || (dsa->r == NULL))
1.191 + {
1.192 + if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
1.193 + }
1.194 + else
1.195 + {
1.196 + kinv=dsa->kinv;
1.197 + dsa->kinv=NULL;
1.198 + r=dsa->r;
1.199 + dsa->r=NULL;
1.200 + }
1.201 +
1.202 + if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;
1.203 +
1.204 + /* Compute s = inv(k) (m + xr) mod q */
1.205 + if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
1.206 + if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */
1.207 + if (BN_cmp(s,dsa->q) > 0)
1.208 + BN_sub(s,s,dsa->q);
1.209 + if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
1.210 +
1.211 + ret=DSA_SIG_new();
1.212 + if (ret == NULL) goto err;
1.213 + ret->r = r;
1.214 + ret->s = s;
1.215 +
1.216 +err:
1.217 + if (!ret)
1.218 + {
1.219 + DSAerr(DSA_F_DSA_DO_SIGN,reason);
1.220 + BN_free(r);
1.221 + BN_free(s);
1.222 + }
1.223 + if (ctx != NULL) BN_CTX_free(ctx);
1.224 + BN_clear_free(&m);
1.225 + BN_clear_free(&xr);
1.226 + if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
1.227 + BN_clear_free(kinv);
1.228 + return(ret);
1.229 + }
1.230 +
1.231 +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
1.232 + {
1.233 + BN_CTX *ctx;
1.234 + BIGNUM k,kq,*K,*kinv=NULL,*r=NULL;
1.235 + int ret=0;
1.236 +
1.237 + if (!dsa->p || !dsa->q || !dsa->g)
1.238 + {
1.239 + DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
1.240 + return 0;
1.241 + }
1.242 +
1.243 + BN_init(&k);
1.244 + BN_init(&kq);
1.245 +
1.246 + if (ctx_in == NULL)
1.247 + {
1.248 + if ((ctx=BN_CTX_new()) == NULL) goto err;
1.249 + }
1.250 + else
1.251 + ctx=ctx_in;
1.252 +
1.253 + if ((r=BN_new()) == NULL) goto err;
1.254 +
1.255 + /* Get random k */
1.256 + do
1.257 + if (!BN_rand_range(&k, dsa->q)) goto err;
1.258 + while (BN_is_zero(&k));
1.259 + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
1.260 + {
1.261 + BN_set_flags(&k, BN_FLG_CONSTTIME);
1.262 + }
1.263 +
1.264 + if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
1.265 + {
1.266 + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
1.267 + CRYPTO_LOCK_DSA,
1.268 + dsa->p, ctx))
1.269 + goto err;
1.270 + }
1.271 +
1.272 + /* Compute r = (g^k mod p) mod q */
1.273 +
1.274 + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
1.275 + {
1.276 + if (!BN_copy(&kq, &k)) goto err;
1.277 +
1.278 + /* We do not want timing information to leak the length of k,
1.279 + * so we compute g^k using an equivalent exponent of fixed length.
1.280 + *
1.281 + * (This is a kludge that we need because the BN_mod_exp_mont()
1.282 + * does not let us specify the desired timing behaviour.) */
1.283 +
1.284 + if (!BN_add(&kq, &kq, dsa->q)) goto err;
1.285 + if (BN_num_bits(&kq) <= BN_num_bits(dsa->q))
1.286 + {
1.287 + if (!BN_add(&kq, &kq, dsa->q)) goto err;
1.288 + }
1.289 +
1.290 + K = &kq;
1.291 + }
1.292 + else
1.293 + {
1.294 + K = &k;
1.295 + }
1.296 + DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
1.297 + dsa->method_mont_p);
1.298 + if (!BN_mod(r,r,dsa->q,ctx)) goto err;
1.299 +
1.300 + /* Compute part of 's = inv(k) (m + xr) mod q' */
1.301 + if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
1.302 +
1.303 + if (*kinvp != NULL) BN_clear_free(*kinvp);
1.304 + *kinvp=kinv;
1.305 + kinv=NULL;
1.306 + if (*rp != NULL) BN_clear_free(*rp);
1.307 + *rp=r;
1.308 + ret=1;
1.309 +err:
1.310 + if (!ret)
1.311 + {
1.312 + DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
1.313 + if (kinv != NULL) BN_clear_free(kinv);
1.314 + if (r != NULL) BN_clear_free(r);
1.315 + }
1.316 + if (ctx_in == NULL) BN_CTX_free(ctx);
1.317 + if (kinv != NULL) BN_clear_free(kinv);
1.318 + BN_clear_free(&k);
1.319 + BN_clear_free(&kq);
1.320 + return(ret);
1.321 + }
1.322 +
1.323 +static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
1.324 + DSA *dsa)
1.325 + {
1.326 + BN_CTX *ctx;
1.327 + BIGNUM u1,u2,t1;
1.328 + BN_MONT_CTX *mont=NULL;
1.329 + int ret = -1;
1.330 + if (!dsa->p || !dsa->q || !dsa->g)
1.331 + {
1.332 + DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
1.333 + return -1;
1.334 + }
1.335 +
1.336 + if (BN_num_bits(dsa->q) != 160)
1.337 + {
1.338 + DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
1.339 + return -1;
1.340 + }
1.341 +
1.342 + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
1.343 + {
1.344 + DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
1.345 + return -1;
1.346 + }
1.347 +
1.348 + BN_init(&u1);
1.349 + BN_init(&u2);
1.350 + BN_init(&t1);
1.351 +
1.352 + if ((ctx=BN_CTX_new()) == NULL) goto err;
1.353 +
1.354 + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
1.355 + BN_ucmp(sig->r, dsa->q) >= 0)
1.356 + {
1.357 + ret = 0;
1.358 + goto err;
1.359 + }
1.360 + if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
1.361 + BN_ucmp(sig->s, dsa->q) >= 0)
1.362 + {
1.363 + ret = 0;
1.364 + goto err;
1.365 + }
1.366 +
1.367 + /* Calculate W = inv(S) mod Q
1.368 + * save W in u2 */
1.369 + if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
1.370 +
1.371 + /* save M in u1 */
1.372 + if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
1.373 +
1.374 + /* u1 = M * w mod q */
1.375 + if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
1.376 +
1.377 + /* u2 = r * w mod q */
1.378 + if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
1.379 +
1.380 +
1.381 + if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
1.382 + {
1.383 + mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
1.384 + CRYPTO_LOCK_DSA, dsa->p, ctx);
1.385 + if (!mont)
1.386 + goto err;
1.387 + }
1.388 +
1.389 +
1.390 + DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont);
1.391 + /* BN_copy(&u1,&t1); */
1.392 + /* let u1 = u1 mod q */
1.393 + if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
1.394 +
1.395 + /* V is now in u1. If the signature is correct, it will be
1.396 + * equal to R. */
1.397 + ret=(BN_ucmp(&u1, sig->r) == 0);
1.398 +
1.399 + err:
1.400 + /* XXX: surely this is wrong - if ret is 0, it just didn't verify;
1.401 + there is no error in BN. Test should be ret == -1 (Ben) */
1.402 + if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
1.403 + if (ctx != NULL) BN_CTX_free(ctx);
1.404 + BN_free(&u1);
1.405 + BN_free(&u2);
1.406 + BN_free(&t1);
1.407 + return(ret);
1.408 + }
1.409 +
1.410 +static int dsa_init(DSA *dsa)
1.411 +{
1.412 + dsa->flags|=DSA_FLAG_CACHE_MONT_P;
1.413 + return(1);
1.414 +}
1.415 +
1.416 +static int dsa_finish(DSA *dsa)
1.417 +{
1.418 + if(dsa->method_mont_p)
1.419 + BN_MONT_CTX_free(dsa->method_mont_p);
1.420 + return(1);
1.421 +}
1.422 +