~ubuntu-branches/ubuntu/utopic/dropbear/utopic-proposed

« back to all changes in this revision

Viewing changes to libtomcrypt/dsa_make_key.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Johnston
  • Date: 2005-12-08 19:20:21 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051208192021-nyp9rwnt77nsg6ty
Tags: 0.47-1
* New upstream release.
* SECURITY: Fix incorrect buffer sizing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2
 
 *
3
 
 * LibTomCrypt is a library that provides various cryptographic
4
 
 * algorithms in a highly modular and flexible manner.
5
 
 *
6
 
 * The library is free for all purposes without any express
7
 
 * guarantee it works.
8
 
 *
9
 
 * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
10
 
 */
11
 
#include "mycrypt.h"
12
 
 
13
 
#ifdef MDSA
14
 
 
15
 
int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
16
 
{
17
 
   mp_int         tmp, tmp2;
18
 
   int            err, res;
19
 
   unsigned char *buf;
20
 
 
21
 
   _ARGCHK(key  != NULL);
22
 
 
23
 
   /* check prng */
24
 
   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
25
 
      return err;
26
 
   }
27
 
 
28
 
   /* check size */
29
 
   if (group_size >= MDSA_MAX_GROUP || group_size <= 15 || 
30
 
       group_size >= modulus_size || (modulus_size - group_size) >= MDSA_DELTA) {
31
 
      return CRYPT_INVALID_ARG;
32
 
   }
33
 
 
34
 
   /* allocate ram */
35
 
   buf = XMALLOC(MDSA_DELTA);
36
 
   if (buf == NULL) {
37
 
      return CRYPT_MEM;
38
 
   }
39
 
 
40
 
   /* init mp_ints  */
41
 
   if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != MP_OKAY) {
42
 
      err = mpi_to_ltc_error(err);
43
 
      goto __ERR;
44
 
   }
45
 
 
46
 
   /* make our prime q */
47
 
   if ((err = rand_prime(&key->q, group_size*8, prng, wprng)) != CRYPT_OK)             { goto __ERR; }
48
 
 
49
 
   /* double q  */
50
 
   if ((err = mp_mul_2(&key->q, &tmp)) != MP_OKAY)                                     { goto error; }
51
 
 
52
 
   /* now make a random string and multply it against q */
53
 
   if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) {
54
 
      err = CRYPT_ERROR_READPRNG;
55
 
      goto __ERR;
56
 
   }
57
 
 
58
 
   /* force magnitude */
59
 
   buf[0] = 1;
60
 
 
61
 
   /* force even */
62
 
   buf[modulus_size - group_size] &= ~1;
63
 
 
64
 
   if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size+1)) != MP_OKAY) { goto error; }
65
 
   if ((err = mp_mul(&key->q, &tmp2, &key->p)) != MP_OKAY)                             { goto error; }
66
 
   if ((err = mp_add_d(&key->p, 1, &key->p)) != MP_OKAY)                               { goto error; }
67
 
   
68
 
   /* now loop until p is prime */
69
 
   for (;;) {
70
 
       if ((err = is_prime(&key->p, &res)) != CRYPT_OK)                                { goto __ERR; }
71
 
       if (res == MP_YES) break;
72
 
 
73
 
       /* add 2q to p and 2 to tmp2 */
74
 
       if ((err = mp_add(&tmp, &key->p, &key->p)) != MP_OKAY)                          { goto error; }
75
 
       if ((err = mp_add_d(&tmp2, 2, &tmp2)) != MP_OKAY)                               { goto error; }
76
 
   }
77
 
 
78
 
   /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */
79
 
   mp_set(&key->g, 1);
80
 
 
81
 
   do {
82
 
      if ((err = mp_add_d(&key->g, 1, &key->g)) != MP_OKAY)                            { goto error; }
83
 
      if ((err = mp_exptmod(&key->g, &tmp2, &key->p, &tmp)) != MP_OKAY)                { goto error; }
84
 
   } while (mp_cmp_d(&tmp, 1) == MP_EQ);
85
 
 
86
 
   /* at this point tmp generates a group of order q mod p */
87
 
   mp_exch(&tmp, &key->g);
88
 
 
89
 
   /* so now we have our DH structure, generator g, order q, modulus p 
90
 
      Now we need a random exponent [mod q] and it's power g^x mod p 
91
 
    */
92
 
   do {
93
 
      if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) {
94
 
         err = CRYPT_ERROR_READPRNG;
95
 
         goto __ERR;
96
 
      }
97
 
      if ((err = mp_read_unsigned_bin(&key->x, buf, group_size)) != MP_OKAY)           { goto error; }
98
 
   } while (mp_cmp_d(&key->x, 1) != MP_GT);
99
 
   if ((err = mp_exptmod(&key->g, &key->x, &key->p, &key->y)) != MP_OKAY)              { goto error; }
100
 
   
101
 
   key->type = PK_PRIVATE;
102
 
   key->qord = group_size;
103
 
 
104
 
   /* shrink the ram required */
105
 
   if ((err = mp_shrink(&key->g)) != MP_OKAY)                                          { goto error; }
106
 
   if ((err = mp_shrink(&key->p)) != MP_OKAY)                                          { goto error; }
107
 
   if ((err = mp_shrink(&key->q)) != MP_OKAY)                                          { goto error; }
108
 
   if ((err = mp_shrink(&key->x)) != MP_OKAY)                                          { goto error; }
109
 
   if ((err = mp_shrink(&key->y)) != MP_OKAY)                                          { goto error; }
110
 
 
111
 
#ifdef CLEAN_STACK
112
 
   zeromem(buf, MDSA_DELTA);
113
 
#endif
114
 
 
115
 
   err = CRYPT_OK;
116
 
   goto done;
117
 
error: 
118
 
    err = mpi_to_ltc_error(err);
119
 
__ERR: 
120
 
    mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL);
121
 
done: 
122
 
    mp_clear_multi(&tmp, &tmp2, NULL);
123
 
 
124
 
    XFREE(buf);
125
 
    return err;
126
 
}
127
 
 
128
 
#endif