~ubuntu-branches/ubuntu/lucid/openssl/lucid-proposed

« back to all changes in this revision

Viewing changes to fips/dsa/fips_dsa_ossl.c

  • Committer: Bazaar Package Importer
  • Author(s): Nicolas Valcárcel Scerpella (Canonical)
  • Date: 2009-12-06 20:16:24 UTC
  • mfrom: (11.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20091206201624-u126qjpqm2n2uuhu
Tags: 0.9.8k-7ubuntu1
* Merge from debian unstable, remaining changes (LP: #493392):
  - Link using -Bsymbolic-functions
  - Add support for lpia
  - Disable SSLv2 during compile
  - Ship documentation in openssl-doc, suggested by the package.
  - Use a different priority for libssl0.9.8/restart-services
    depending on whether a desktop, or server dist-upgrade is being
    performed.
  - Display a system restart required notification bubble on libssl0.9.8
    upgrade.
  - Replace duplicate files in the doc directory with symlinks.
  - Move runtime libraries to /lib, for the benefit of wpasupplicant
* Strip the patches out of the source into quilt patches
* Disable CVE-2009-3555.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, DSA_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_BITS))
 
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 length.
 
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, DSA_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_BITS))
 
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 */