~andreserl/ubuntu/lucid/bind9/bind9-apport-533601

« back to all changes in this revision

Viewing changes to lib/isc/entropy.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones, LaMont Jones, Internet Software Consortium, Inc, localization folks
  • Date: 2008-08-02 14:20:20 UTC
  • mfrom: (1.2.1 upstream) (6.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080802142020-l1hon9jy8lbbjxmg
[LaMont Jones]

* default to using resolvconf if it is installed
* fix sonames and dependencies.  Closes: #149259, #492418
* Do not build-depend libcap2-dev on non-linux.  Closes: #493392
* drop unused query-loc manpage.  Closes: #492564
* lwresd: Deliver /etc/bind directory.  Closes: #490027
* fix query-source comment in default install

[Internet Software Consortium, Inc]

* 9.5.0-P2.  Closes: #492949

[localization folks]

* l10n: Spanish debconf translation.  Closes: #492425 (Ignacio Mondino)
* l10n: Swedish debconf templates.  Closes: #491369 (Martin Ågren)
* l10n: Japanese debconf translations.  Closes: #492048 (Hideki Yamane
  (Debian-JP))
* l10n: Finnish translation.  Closes: #490630 (Esko Arajärvi)
* l10n: Italian debconf translations.  Closes: #492587 (Alessandro Vietta)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
 
2
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
3
3
 * Copyright (C) 2000-2003  Internet Software Consortium.
4
4
 *
5
 
 * Permission to use, copy, modify, and distribute this software for any
 
5
 * Permission to use, copy, modify, and/or distribute this software for any
6
6
 * purpose with or without fee is hereby granted, provided that the above
7
7
 * copyright notice and this permission notice appear in all copies.
8
8
 *
15
15
 * PERFORMANCE OF THIS SOFTWARE.
16
16
 */
17
17
 
18
 
/* $Id: entropy.c,v 1.3.2.2.2.7 2004/03/08 09:04:48 marka Exp $ */
 
18
/* $Id: entropy.c,v 1.18 2007/06/19 23:47:17 tbox Exp $ */
19
19
 
20
 
/*
 
20
/*! \file
 
21
 * \brief
21
22
 * This is the system independent part of the entropy module.  It is
22
23
 * compiled via inclusion from the relevant OS source file, ie,
23
 
 * unix/entropy.c or win32/entropy.c.
 
24
 * \link unix/entropy.c unix/entropy.c \endlink or win32/entropy.c.
 
25
 *
 
26
 * \author Much of this code is modeled after the NetBSD /dev/random implementation,
 
27
 * written by Michael Graff <explorer@netbsd.org>.
24
28
 */
25
29
 
26
30
#include <errno.h>
42
46
#include <isc/time.h>
43
47
#include <isc/util.h>
44
48
 
45
 
/*
46
 
 * Much of this code is modeled after the NetBSD /dev/random implementation,
47
 
 * written by Michael Graff <explorer@netbsd.org>.
48
 
 */
49
49
 
50
50
#define ENTROPY_MAGIC           ISC_MAGIC('E', 'n', 't', 'e')
51
51
#define SOURCE_MAGIC            ISC_MAGIC('E', 'n', 't', 's')
58
58
 *** you are doing.
59
59
 ***/
60
60
 
61
 
/*
62
 
 * size of entropy pool in 32-bit words.  This _MUST_ be a power of 2.
 
61
/*%
 
62
 * Size of entropy pool in 32-bit words.  This _MUST_ be a power of 2.
63
63
 */
64
64
#define RND_POOLWORDS   128
 
65
/*% Pool in bytes. */
65
66
#define RND_POOLBYTES   (RND_POOLWORDS * 4)
 
67
/*% Pool in bits. */
66
68
#define RND_POOLBITS    (RND_POOLWORDS * 32)
67
69
 
68
 
/*
 
70
/*%
69
71
 * Number of bytes returned per hash.  This must be true:
70
72
 *      threshold * 2 <= digest_size_in_bytes
71
73
 */
72
74
#define RND_ENTROPY_THRESHOLD   10
73
75
#define THRESHOLD_BITS          (RND_ENTROPY_THRESHOLD * 8)
74
76
 
75
 
/*
 
77
/*%
76
78
 * Size of the input event queue in samples.
77
79
 */
78
80
#define RND_EVENTQSIZE  32
79
81
 
80
 
/*
 
82
/*%
81
83
 * The number of times we'll "reseed" for pseudorandom seeds.  This is an
82
84
 * extremely weak pseudorandom seed.  If the caller is using lots of
83
85
 * pseudorandom data and they cannot provide a stronger random source,
86
88
 */
87
89
#define RND_INITIALIZE  128
88
90
 
 
91
/*% Entropy Pool */
89
92
typedef struct {
90
 
        isc_uint32_t    cursor;         /* current add point in the pool */
91
 
        isc_uint32_t    entropy;        /* current entropy estimate in bits */
92
 
        isc_uint32_t    pseudo;         /* bits extracted in pseudorandom */
93
 
        isc_uint32_t    rotate;         /* how many bits to rotate by */
94
 
        isc_uint32_t    pool[RND_POOLWORDS];    /* random pool data */
 
93
        isc_uint32_t    cursor;         /*%< current add point in the pool */
 
94
        isc_uint32_t    entropy;        /*%< current entropy estimate in bits */
 
95
        isc_uint32_t    pseudo;         /*%< bits extracted in pseudorandom */
 
96
        isc_uint32_t    rotate;         /*%< how many bits to rotate by */
 
97
        isc_uint32_t    pool[RND_POOLWORDS];    /*%< random pool data */
95
98
} isc_entropypool_t;
96
99
 
97
100
struct isc_entropy {
107
110
        ISC_LIST(isc_entropysource_t)   sources;
108
111
};
109
112
 
 
113
/*% Sample Queue */
110
114
typedef struct {
111
 
        isc_uint32_t    last_time;      /* last time recorded */
112
 
        isc_uint32_t    last_delta;     /* last delta value */
113
 
        isc_uint32_t    last_delta2;    /* last delta2 value */
114
 
        isc_uint32_t    nsamples;       /* number of samples filled in */
115
 
        isc_uint32_t   *samples;        /* the samples */
116
 
        isc_uint32_t   *extra;          /* extra samples added in */
 
115
        isc_uint32_t    last_time;      /*%< last time recorded */
 
116
        isc_uint32_t    last_delta;     /*%< last delta value */
 
117
        isc_uint32_t    last_delta2;    /*%< last delta2 value */
 
118
        isc_uint32_t    nsamples;       /*%< number of samples filled in */
 
119
        isc_uint32_t   *samples;        /*%< the samples */
 
120
        isc_uint32_t   *extra;          /*%< extra samples added in */
117
121
} sample_queue_t;
118
122
 
119
123
typedef struct {
137
141
        unsigned int    magic;
138
142
        unsigned int    type;
139
143
        isc_entropy_t  *ent;
140
 
        isc_uint32_t    total;          /* entropy from this source */
 
144
        isc_uint32_t    total;          /*%< entropy from this source */
141
145
        ISC_LINK(isc_entropysource_t)   link;
142
146
        char            name[32];
143
147
        isc_boolean_t   bad;
151
155
        } sources;
152
156
};
153
157
 
154
 
#define ENTROPY_SOURCETYPE_SAMPLE       1       /* Type is a sample source */
155
 
#define ENTROPY_SOURCETYPE_FILE         2       /* Type is a file source */
156
 
#define ENTROPY_SOURCETYPE_CALLBACK     3       /* Type is a callback source */
157
 
#define ENTROPY_SOURCETYPE_USOCKET      4       /* Type is a Unix socket source */
 
158
#define ENTROPY_SOURCETYPE_SAMPLE       1       /*%< Type is a sample source */
 
159
#define ENTROPY_SOURCETYPE_FILE         2       /*%< Type is a file source */
 
160
#define ENTROPY_SOURCETYPE_CALLBACK     3       /*%< Type is a callback source */
 
161
#define ENTROPY_SOURCETYPE_USOCKET      4       /*%< Type is a Unix socket source */
158
162
 
159
 
/*
 
163
/*@{*/
 
164
/*%
160
165
 * The random pool "taps"
161
166
 */
162
167
#define TAP1    99
164
169
#define TAP3    31
165
170
#define TAP4     9
166
171
#define TAP5     7
 
172
/*@}*/
167
173
 
168
 
/*
 
174
/*@{*/
 
175
/*%
169
176
 * Declarations for function provided by the system dependent sources that
170
177
 * include this file.
171
178
 */
181
188
static void
182
189
destroyusocketsource(isc_entropyusocketsource_t *source);
183
190
 
 
191
/*@}*/
184
192
 
185
193
static void
186
194
samplequeue_release(isc_entropy_t *ent, sample_queue_t *sq) {
211
219
        return (ISC_R_SUCCESS);
212
220
}
213
221
 
214
 
/*
 
222
/*%
215
223
 * Add in entropy, even when the value we're adding in could be
216
224
 * very large.
217
225
 */
225
233
        ent->pool.entropy = ISC_MIN(entropy, RND_POOLBITS);
226
234
}
227
235
 
228
 
/*
 
236
/*%
229
237
 * Decrement the amount of entropy the pool has.
230
238
 */
231
239
static inline void
234
242
        ent->pool.entropy -= entropy;
235
243
}
236
244
 
237
 
/*
 
245
/*!
238
246
 * Add in entropy, even when the value we're adding in could be
239
247
 * very large.
240
248
 */
248
256
        ent->pool.pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8);
249
257
}
250
258
 
251
 
/*
 
259
/*!
252
260
 * Decrement the amount of pseudo the pool has.
253
261
 */
254
262
static inline void
257
265
        ent->pool.pseudo -= pseudo;
258
266
}
259
267
 
260
 
/*
 
268
/*!
261
269
 * Add one word to the pool, rotating the input as needed.
262
270
 */
263
271
static inline void
292
300
        }
293
301
}
294
302
 
295
 
/*
 
303
/*!
296
304
 * Add a buffer's worth of data to the pool.
297
305
 *
298
306
 * Requires that the lock is held on the entropy pool.
362
370
                entropypool_adddata(ent, &pid, sizeof(pid), 0);
363
371
        }
364
372
 
365
 
        /*
 
373
        /*!
366
374
         * After we've reseeded 100 times, only add new timing info every
367
375
         * 50 requests.  This will keep us from using lots and lots of
368
376
         * CPU just to return bad pseudorandom data anyway.
382
390
        isc_int32_t             delta2;
383
391
        isc_int32_t             delta3;
384
392
 
385
 
        /*
 
393
        /*!
386
394
         * If the time counter has overflowed, calculate the real difference.
387
395
         * If it has not, it is simpler.
388
396
         */
661
669
 
662
670
isc_result_t
663
671
isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp) {
664
 
        isc_result_t ret;
 
672
        isc_result_t result;
665
673
        isc_entropy_t *ent;
666
674
 
667
675
        REQUIRE(mctx != NULL);
674
682
        /*
675
683
         * We need a lock.
676
684
         */
677
 
        if (isc_mutex_init(&ent->lock) != ISC_R_SUCCESS) {
678
 
                ret = ISC_R_UNEXPECTED;
 
685
        result = isc_mutex_init(&ent->lock);
 
686
        if (result != ISC_R_SUCCESS)
679
687
                goto errout;
680
 
        }
681
688
 
682
689
        /*
683
690
         * From here down, no failures will/can occur.
700
707
 errout:
701
708
        isc_mem_put(mctx, ent, sizeof(isc_entropy_t));
702
709
 
703
 
        return (ret);
 
710
        return (result);
704
711
}
705
712
 
706
 
/*
 
713
/*!
707
714
 * Requires "ent" be locked.
708
715
 */
709
716
static void
851
858
                                 void *arg,
852
859
                                 isc_entropysource_t **sourcep)
853
860
{
854
 
        isc_result_t ret;
 
861
        isc_result_t result;
855
862
        isc_entropysource_t *source;
856
863
        isc_cbsource_t *cbs;
857
864
 
863
870
 
864
871
        source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
865
872
        if (source == NULL) {
866
 
                ret = ISC_R_NOMEMORY;
 
873
                result = ISC_R_NOMEMORY;
867
874
                goto errout;
868
875
        }
869
876
        source->bad = ISC_FALSE;
870
877
 
871
878
        cbs = &source->sources.callback;
872
879
 
873
 
        ret = samplesource_allocate(ent, &cbs->samplequeue);
874
 
        if (ret != ISC_R_SUCCESS)
 
880
        result = samplesource_allocate(ent, &cbs->samplequeue);
 
881
        if (result != ISC_R_SUCCESS)
875
882
                goto errout;
876
883
 
877
884
        cbs->start_called = ISC_FALSE;
907
914
 
908
915
        UNLOCK(&ent->lock);
909
916
 
910
 
        return (ret);
 
917
        return (result);
911
918
}
912
919
 
913
920
void
939
946
isc_entropy_createsamplesource(isc_entropy_t *ent,
940
947
                               isc_entropysource_t **sourcep)
941
948
{
942
 
        isc_result_t ret;
 
949
        isc_result_t result;
943
950
        isc_entropysource_t *source;
944
951
        sample_queue_t *sq;
945
952
 
950
957
 
951
958
        source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
952
959
        if (source == NULL) {
953
 
                ret = ISC_R_NOMEMORY;
 
960
                result = ISC_R_NOMEMORY;
954
961
                goto errout;
955
962
        }
956
963
 
957
964
        sq = &source->sources.sample.samplequeue;
958
 
        ret = samplesource_allocate(ent, sq);
959
 
        if (ret != ISC_R_SUCCESS)
 
965
        result = samplesource_allocate(ent, sq);
 
966
        if (result != ISC_R_SUCCESS)
960
967
                goto errout;
961
968
 
962
969
        /*
986
993
 
987
994
        UNLOCK(&ent->lock);
988
995
 
989
 
        return (ret);
 
996
        return (result);
990
997
}
991
998
 
992
 
/*
 
999
/*!
993
1000
 * Add a sample, and return ISC_R_SUCCESS if the queue has become full,
994
1001
 * ISC_R_NOENTROPY if it has space remaining, and ISC_R_NOMORE if the
995
1002
 * queue was full when this function was called.
1095
1102
        UNLOCK(&ent->lock);
1096
1103
}
1097
1104
 
 
1105
unsigned int
 
1106
isc_entropy_status(isc_entropy_t *ent) {
 
1107
        unsigned int estimate;
 
1108
 
 
1109
        LOCK(&ent->lock);
 
1110
        estimate = ent->pool.entropy;
 
1111
        UNLOCK(&ent->lock);
 
1112
 
 
1113
        return estimate;
 
1114
}
 
1115
 
1098
1116
void
1099
1117
isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp) {
1100
1118
        REQUIRE(VALID_ENTROPY(ent));