~ubuntu-branches/debian/squeeze/libnice/squeeze

« back to all changes in this revision

Viewing changes to stun/rand.c

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2009-01-04 17:45:34 UTC
  • Revision ID: james.westby@ubuntu.com-20090104174534-dh5u1pfonumqa99c
Tags: upstream-0.0.4
ImportĀ upstreamĀ versionĀ 0.0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of the Nice GLib ICE library.
 
3
 *
 
4
 * (C) 2008 Nokia Corporation. All rights reserved.
 
5
 * (C) 2008 Collabora Ltd. All rights reserved.
 
6
 *  Contact: Youness Alaoui
 
7
 *
 
8
 * The contents of this file are subject to the Mozilla Public License Version
 
9
 * 1.1 (the "License"); you may not use this file except in compliance with
 
10
 * the License. You may obtain a copy of the License at
 
11
 * http://www.mozilla.org/MPL/
 
12
 *
 
13
 * Software distributed under the License is distributed on an "AS IS" basis,
 
14
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
15
 * for the specific language governing rights and limitations under the
 
16
 * License.
 
17
 *
 
18
 * The Original Code is the Nice GLib ICE library.
 
19
 *
 
20
 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
 
21
 * Corporation. All Rights Reserved.
 
22
 *
 
23
 * Alternatively, the contents of this file may be used under the terms of the
 
24
 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
 
25
 * case the provisions of LGPL are applicable instead of those above. If you
 
26
 * wish to allow use of your version of this file only under the terms of the
 
27
 * LGPL and not to allow others to use your version of this file under the
 
28
 * MPL, indicate your decision by deleting the provisions above and replace
 
29
 * them with the notice and other provisions required by the LGPL. If you do
 
30
 * not delete the provisions above, a recipient may use your version of this
 
31
 * file under either the MPL or the LGPL.
 
32
 */
 
33
 
 
34
 
 
35
 
 
36
#ifdef HAVE_CONFIG_H
 
37
# include <config.h>
 
38
#endif
 
39
 
 
40
#include "rand.h"
 
41
 
 
42
 
 
43
#ifdef _WIN32
 
44
 
 
45
#include <windows.h>
 
46
 
 
47
void RAND_bytes (uint8_t *dst, int len)
 
48
{
 
49
  HCRYPTPROV hCryptProv;
 
50
  LPCSTR container = "Libnice key container";
 
51
 
 
52
  if(!CryptAcquireContext(&hCryptProv, container, NULL, PROV_RSA_FULL, 0)) {
 
53
    /* non existing container. try to create a new one */
 
54
    if (GetLastError() == NTE_BAD_KEYSET) {
 
55
      if(!CryptAcquireContext(&hCryptProv, container, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
 
56
        return;
 
57
      }
 
58
    }
 
59
    return;
 
60
  }
 
61
 
 
62
  CryptGenRandom (hCryptProv, len, dst);
 
63
 
 
64
  CryptReleaseContext(hCryptProv,0);
 
65
}
 
66
#else
 
67
 
 
68
/* ------------- Start original implementation. ----------------- */
 
69
/* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html */
 
70
 
 
71
/*
 
72
   A C-program for MT19937, with initialization improved 2002/1/26.
 
73
   Coded by Takuji Nishimura and Makoto Matsumoto.
 
74
 
 
75
   Before using, initialize the state by using init_genrand(seed)
 
76
   or init_by_array(init_key, key_length).
 
77
 
 
78
   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
 
79
   All rights reserved
 
80
 
 
81
   Redistribution and use in source and binary forms, with or without
 
82
   modification, are permitted provided that the following conditions
 
83
   are met:
 
84
 
 
85
     1. Redistributions of source code must retain the above copyright
 
86
        notice, this list of conditions and the following disclaimer.
 
87
 
 
88
     2. Redistributions in binary form must reproduce the above copyright
 
89
        notice, this list of conditions and the following disclaimer in the
 
90
        documentation and/or other materials provided with the distribution.
 
91
 
 
92
     3. The names of its contributors may not be used to endorse or promote
 
93
        products derived from this software without specific prior written
 
94
        permission.
 
95
 
 
96
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
97
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
98
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
99
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 
100
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
101
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
102
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
103
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
104
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
105
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
106
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
107
 
 
108
 
 
109
   Any feedback is very welcome.
 
110
   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
 
111
   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
 
112
*/
 
113
 
 
114
/* Period parameters */
 
115
#define N 624
 
116
#define M 397
 
117
#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
 
118
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
 
119
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
 
120
 
 
121
static unsigned long mt[N]; /* the array for the state vector  */
 
122
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
 
123
 
 
124
/* initializes mt[N] with a seed */
 
125
static void init_genrand(unsigned long s)
 
126
{
 
127
  mt[0]= s & 0xffffffffUL;
 
128
  for (mti=1; mti<N; mti++) {
 
129
    mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
 
130
    /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
 
131
    /* In the previous versions, MSBs of the seed affect   */
 
132
    /* only MSBs of the array mt[].                        */
 
133
    /* 2002/01/09 modified by Makoto Matsumoto             */
 
134
    mt[mti] &= 0xffffffffUL;
 
135
    /* for >32 bit machines */
 
136
  }
 
137
}
 
138
 
 
139
/* initialize by an array with array-length */
 
140
/* init_key is the array for initializing keys */
 
141
/* key_length is its length */
 
142
/* slight change for C++, 2004/2/26 */
 
143
static void init_by_array(unsigned long init_key[], int key_length)
 
144
{
 
145
  int i, j, k;
 
146
  init_genrand(19650218UL);
 
147
  i=1; j=0;
 
148
  k = (N>key_length ? N : key_length);
 
149
  for (; k; k--) {
 
150
    mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
 
151
        + init_key[j] + j; /* non linear */
 
152
    mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
 
153
    i++; j++;
 
154
    if (i>=N) { mt[0] = mt[N-1]; i=1; }
 
155
    if (j>=key_length) j=0;
 
156
  }
 
157
  for (k=N-1; k; k--) {
 
158
    mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
 
159
        - i; /* non linear */
 
160
    mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
 
161
    i++;
 
162
    if (i>=N) { mt[0] = mt[N-1]; i=1; }
 
163
  }
 
164
 
 
165
  mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
 
166
}
 
167
 
 
168
/* generates a random number on [0,0xffffffff]-interval */
 
169
static unsigned long genrand_int32(void)
 
170
{
 
171
  unsigned long y;
 
172
  static unsigned long mag01[2]={0x0UL, MATRIX_A};
 
173
  /* mag01[x] = x * MATRIX_A  for x=0,1 */
 
174
 
 
175
  if (mti >= N) { /* generate N words at one time */
 
176
    int kk;
 
177
 
 
178
    if (mti == N+1)   /* if init_genrand() has not been called, */
 
179
      init_genrand(5489UL); /* a default initial seed is used */
 
180
 
 
181
    for (kk=0;kk<N-M;kk++) {
 
182
      y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
 
183
      mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
 
184
    }
 
185
    for (;kk<N-1;kk++) {
 
186
      y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
 
187
      mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
 
188
    }
 
189
    y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
 
190
    mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
 
191
 
 
192
    mti = 0;
 
193
  }
 
194
 
 
195
  y = mt[mti++];
 
196
 
 
197
  /* Tempering */
 
198
  y ^= (y >> 11);
 
199
  y ^= (y << 7) & 0x9d2c5680UL;
 
200
  y ^= (y << 15) & 0xefc60000UL;
 
201
  y ^= (y >> 18);
 
202
 
 
203
  return y;
 
204
}
 
205
 
 
206
/* These real versions are due to Isaku Wada, 2002/01/09 added */
 
207
 
 
208
/* ------------- End original implementation. ----------------- */
 
209
 
 
210
#include <stdio.h>
 
211
#include <time.h>
 
212
 
 
213
static int initialized = 0;
 
214
 
 
215
void RAND_bytes (uint8_t *dst, int len)
 
216
{
 
217
  int i;
 
218
 
 
219
  if (!initialized) {
 
220
    /* Seed the generator with an array from /dev/urandom if available
 
221
       Otherwise use time() and clock() values */
 
222
 
 
223
    FILE *urandom = fopen( "/dev/urandom", "rb" );
 
224
    unsigned long init_key[10] = {};
 
225
    int key_length = 0;
 
226
    if (urandom) {
 
227
      while (fread(&init_key[key_length++], sizeof(unsigned long), 1,
 
228
              urandom) > 0 &&    key_length < 10);
 
229
      fclose(urandom);
 
230
    } else {
 
231
      time_t t = time (NULL);
 
232
      clock_t c = clock ();
 
233
      init_key[0] = *((unsigned long *) dst);
 
234
      init_key[1] = 0x6c69626e;
 
235
      init_key[2] = 0x69636500;
 
236
      init_key[3] = *(unsigned long *) &t;
 
237
      init_key[4] = *(unsigned long *) &c;
 
238
      key_length = 5;
 
239
    }
 
240
    init_by_array(init_key, key_length);
 
241
    initialized = 1;
 
242
  }
 
243
 
 
244
  for (i = 0; i < len; i++) {
 
245
    dst[i] = genrand_int32 () & 0xFF;
 
246
  }
 
247
}
 
248
 
 
249
#endif /* _WIN32 */