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

« back to all changes in this revision

Viewing changes to random.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:
25
25
#include "includes.h"
26
26
#include "buffer.h"
27
27
#include "dbutil.h"
 
28
#include "bignum.h"
28
29
 
29
 
int donerandinit = 0;
 
30
static int donerandinit = 0;
30
31
 
31
32
/* this is used to generate unique output from the same hashpool */
32
 
unsigned int counter = 0;
 
33
static unsigned int counter = 0;
33
34
#define MAX_COUNTER 1000000/* the max value for the counter, so it won't loop */
34
35
 
35
 
unsigned char hashpool[SHA1_HASH_SIZE];
 
36
static unsigned char hashpool[SHA1_HASH_SIZE];
36
37
 
37
38
#define INIT_SEED_SIZE 32 /* 256 bits */
38
39
 
50
51
 
51
52
static void readrand(unsigned char* buf, unsigned int buflen) {
52
53
 
 
54
        static int already_blocked = 0;
53
55
        int readfd;
54
56
        unsigned int readpos;
55
57
        int readlen;
92
94
        /* read the actual random data */
93
95
        readpos = 0;
94
96
        do {
 
97
                if (!already_blocked)
 
98
                {
 
99
                        int ret;
 
100
                        struct timeval timeout;
 
101
                        fd_set read_fds;
 
102
 
 
103
                        timeout.tv_sec = 2; /* two seconds should be enough */
 
104
                        timeout.tv_usec = 0;
 
105
 
 
106
                        FD_ZERO(&read_fds);
 
107
                        FD_SET(readfd, &read_fds);
 
108
                        ret = select(readfd + 1, &read_fds, NULL, NULL, &timeout);
 
109
                        if (ret == 0)
 
110
                        {
 
111
                                dropbear_log(LOG_INFO, "Warning: Reading the random source seems to have blocked.\nIf you experience problems, you probably need to find a better entropy source.");
 
112
                                already_blocked = 1;
 
113
                        }
 
114
                }
95
115
                readlen = read(readfd, &buf[readpos], buflen - readpos);
96
116
                if (readlen <= 0) {
97
117
                        if (readlen < 0 && errno == EINTR) {
159
179
        }
160
180
        m_burn(hash, sizeof(hash));
161
181
}
 
182
 
 
183
/* Generates a random mp_int. 
 
184
 * max is a *mp_int specifying an upper bound.
 
185
 * rand must be an initialised *mp_int for the result.
 
186
 * the result rand satisfies:  0 < rand < max 
 
187
 * */
 
188
void gen_random_mpint(mp_int *max, mp_int *rand) {
 
189
 
 
190
        unsigned char *randbuf = NULL;
 
191
        unsigned int len = 0;
 
192
        const char masks[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
 
193
 
 
194
        const int size_bits = mp_count_bits(max);
 
195
 
 
196
        len = size_bits / 8;
 
197
        if ((size_bits % 8) != 0) {
 
198
                len += 1;
 
199
        }
 
200
 
 
201
        randbuf = (unsigned char*)m_malloc(len);
 
202
        do {
 
203
                genrandom(randbuf, len);
 
204
                /* Mask out the unrequired bits - mp_read_unsigned_bin expects
 
205
                 * MSB first.*/
 
206
                randbuf[0] &= masks[size_bits % 8];
 
207
 
 
208
                bytes_to_mp(rand, randbuf, len);
 
209
 
 
210
                /* keep regenerating until we get one satisfying
 
211
                 * 0 < rand < max    */
 
212
        } while ( ( (max != NULL) && (mp_cmp(rand, max) != MP_LT) )
 
213
                        || (mp_cmp_d(rand, 0) != MP_GT) );
 
214
        m_burn(randbuf, len);
 
215
        m_free(randbuf);
 
216
}