~ubuntu-branches/ubuntu/lucid/openssh/lucid

« back to all changes in this revision

Viewing changes to openbsd-compat/bsd-arc4random.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2008-09-30 23:09:58 UTC
  • mfrom: (1.13.3 upstream) (29 hardy)
  • mto: This revision was merged to the branch mainline in revision 43.
  • Revision ID: james.westby@ubuntu.com-20080930230958-o6vsgn8c4mm959s0
Tags: 1:5.1p1-3
* Remove unnecessary ssh-vulnkey output in non-verbose mode when no
  compromised or unknown keys were found (closes: #496495).
* Configure with --disable-strip; dh_strip will deal with stripping
  binaries and will honour DEB_BUILD_OPTIONS (thanks, Bernhard R. Link;
  closes: #498681).
* Fix handling of zero-length server banners (thanks, Tomas Mraz; closes:
  #497026).

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include <sys/types.h>
20
20
 
21
21
#include <string.h>
 
22
#include <stdlib.h>
22
23
#include <stdarg.h>
23
24
 
24
25
#include "log.h"
82
83
        rc4_ready = REKEY_BYTES;
83
84
}
84
85
#endif /* !HAVE_ARC4RANDOM */
 
86
 
 
87
#ifndef ARC4RANDOM_BUF
 
88
void
 
89
arc4random_buf(void *_buf, size_t n)
 
90
{
 
91
        size_t i;
 
92
        u_int32_t r = 0;
 
93
        char *buf = (char *)_buf;
 
94
 
 
95
        for (i = 0; i < n; i++) {
 
96
                if (i % 4 == 0)
 
97
                        r = arc4random();
 
98
                buf[i] = r & 0xff;
 
99
                r >>= 8;
 
100
        }
 
101
        i = r = 0;
 
102
}
 
103
#endif /* !HAVE_ARC4RANDOM_BUF */
 
104
 
 
105
#ifndef ARC4RANDOM_UNIFORM
 
106
/*
 
107
 * Calculate a uniformly distributed random number less than upper_bound
 
108
 * avoiding "modulo bias".
 
109
 *
 
110
 * Uniformity is achieved by generating new random numbers until the one
 
111
 * returned is outside the range [0, 2**32 % upper_bound).  This
 
112
 * guarantees the selected random number will be inside
 
113
 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
 
114
 * after reduction modulo upper_bound.
 
115
 */
 
116
u_int32_t
 
117
arc4random_uniform(u_int32_t upper_bound)
 
118
{
 
119
        u_int32_t r, min;
 
120
 
 
121
        if (upper_bound < 2)
 
122
                return 0;
 
123
 
 
124
#if (ULONG_MAX > 0xffffffffUL)
 
125
        min = 0x100000000UL % upper_bound;
 
126
#else
 
127
        /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
 
128
        if (upper_bound > 0x80000000)
 
129
                min = 1 + ~upper_bound;         /* 2**32 - upper_bound */
 
130
        else {
 
131
                /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
 
132
                min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
 
133
        }
 
134
#endif
 
135
 
 
136
        /*
 
137
         * This could theoretically loop forever but each retry has
 
138
         * p > 0.5 (worst case, usually far better) of selecting a
 
139
         * number inside the range we need, so it should rarely need
 
140
         * to re-roll.
 
141
         */
 
142
        for (;;) {
 
143
                r = arc4random();
 
144
                if (r >= min)
 
145
                        break;
 
146
        }
 
147
 
 
148
        return r % upper_bound;
 
149
}
 
150
#endif /* !HAVE_ARC4RANDOM_UNIFORM */