Fix missing semicolon from previous commit in test-restart
[sipe-libnice.git] / stun / rand.c
blob0de7f6e144fb93be4cfdf964127286e5f93056ad
1 /*
2 * This file is part of the Nice GLib ICE library.
4 * (C) 2008 Collabora Ltd. All rights reserved.
5 * Contact: Youness Alaoui
6 * (C) 2008 Nokia Corporation. All rights reserved.
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/
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.
18 * The Original Code is the Nice GLib ICE library.
20 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
21 * Corporation. All Rights Reserved.
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.
36 #ifdef HAVE_CONFIG_H
37 # include <config.h>
38 #endif
40 #include "rand.h"
43 #ifdef _WIN32
45 #include <windows.h>
46 #include <wincrypt.h>
48 void RAND_bytes (uint8_t *dst, int len)
50 HCRYPTPROV hCryptProv;
51 LPCSTR container = "Libnice key container";
53 if(!CryptAcquireContext(&hCryptProv, container, NULL, PROV_RSA_FULL, 0)) {
54 /* non existing container. try to create a new one */
55 // I hope this cast here doesn't cause issues
56 // gcc was complaining about comparing signed and unsigned values
57 if (GetLastError() == (DWORD) NTE_BAD_KEYSET) {
58 if(!CryptAcquireContext(&hCryptProv, container, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
59 return;
62 return;
65 CryptGenRandom (hCryptProv, len, dst);
67 CryptReleaseContext(hCryptProv,0);
69 #else
71 /* ------------- Start original implementation. ----------------- */
72 /* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html */
75 A C-program for MT19937, with initialization improved 2002/1/26.
76 Coded by Takuji Nishimura and Makoto Matsumoto.
78 Before using, initialize the state by using init_genrand(seed)
79 or init_by_array(init_key, key_length).
81 Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
82 All rights reserved
84 Redistribution and use in source and binary forms, with or without
85 modification, are permitted provided that the following conditions
86 are met:
88 1. Redistributions of source code must retain the above copyright
89 notice, this list of conditions and the following disclaimer.
91 2. Redistributions in binary form must reproduce the above copyright
92 notice, this list of conditions and the following disclaimer in the
93 documentation and/or other materials provided with the distribution.
95 3. The names of its contributors may not be used to endorse or promote
96 products derived from this software without specific prior written
97 permission.
99 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
100 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
101 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
102 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
103 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
104 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
105 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
106 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
107 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
108 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
109 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
112 Any feedback is very welcome.
113 http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
114 email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
117 /* Period parameters */
118 #define N 624
119 #define M 397
120 #define MATRIX_A 0x9908b0dfUL /* constant vector a */
121 #define UPPER_MASK 0x80000000UL /* most significant w-r bits */
122 #define LOWER_MASK 0x7fffffffUL /* least significant r bits */
124 static unsigned long mt[N]; /* the array for the state vector */
125 static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
127 /* initializes mt[N] with a seed */
128 static void init_genrand(unsigned long s)
130 mt[0]= s & 0xffffffffUL;
131 for (mti=1; mti<N; mti++) {
132 mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
133 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
134 /* In the previous versions, MSBs of the seed affect */
135 /* only MSBs of the array mt[]. */
136 /* 2002/01/09 modified by Makoto Matsumoto */
137 mt[mti] &= 0xffffffffUL;
138 /* for >32 bit machines */
142 /* initialize by an array with array-length */
143 /* init_key is the array for initializing keys */
144 /* key_length is its length */
145 /* slight change for C++, 2004/2/26 */
146 static void init_by_array(unsigned long init_key[], int key_length)
148 int i, j, k;
149 init_genrand(19650218UL);
150 i=1; j=0;
151 k = (N>key_length ? N : key_length);
152 for (; k; k--) {
153 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
154 + init_key[j] + j; /* non linear */
155 mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
156 i++; j++;
157 if (i>=N) { mt[0] = mt[N-1]; i=1; }
158 if (j>=key_length) j=0;
160 for (k=N-1; k; k--) {
161 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
162 - i; /* non linear */
163 mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
164 i++;
165 if (i>=N) { mt[0] = mt[N-1]; i=1; }
168 mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
171 /* generates a random number on [0,0xffffffff]-interval */
172 static unsigned long genrand_int32(void)
174 unsigned long y;
175 static unsigned long mag01[2]={0x0UL, MATRIX_A};
176 /* mag01[x] = x * MATRIX_A for x=0,1 */
178 if (mti >= N) { /* generate N words at one time */
179 int kk;
181 if (mti == N+1) /* if init_genrand() has not been called, */
182 init_genrand(5489UL); /* a default initial seed is used */
184 for (kk=0;kk<N-M;kk++) {
185 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
186 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
188 for (;kk<N-1;kk++) {
189 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
190 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
192 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
193 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
195 mti = 0;
198 y = mt[mti++];
200 /* Tempering */
201 y ^= (y >> 11);
202 y ^= (y << 7) & 0x9d2c5680UL;
203 y ^= (y << 15) & 0xefc60000UL;
204 y ^= (y >> 18);
206 return y;
209 /* These real versions are due to Isaku Wada, 2002/01/09 added */
211 /* ------------- End original implementation. ----------------- */
213 #include <stdio.h>
214 #include <time.h>
216 static int initialized = 0;
218 void RAND_bytes (uint8_t *dst, int len)
220 int i;
222 if (!initialized) {
223 /* Seed the generator with an array from /dev/urandom if available
224 Otherwise use time() and clock() values */
226 FILE *urandom = fopen( "/dev/urandom", "rb" );
227 unsigned long init_key[10] = {};
228 int key_length = 0;
229 if (urandom) {
230 while (fread(&init_key[key_length++], sizeof(unsigned long), 1,
231 urandom) > 0 && key_length < 10);
232 fclose(urandom);
233 } else {
234 time_t t = time (NULL);
235 clock_t c = clock ();
236 unsigned long cl = c;
237 unsigned long tl = t;
238 init_key[0] = *((unsigned long *) dst);
239 init_key[1] = 0x6c69626e;
240 init_key[2] = 0x69636500;
241 init_key[3] = tl;
242 init_key[4] = cl;
243 key_length = 5;
245 init_by_array(init_key, key_length);
246 initialized = 1;
249 for (i = 0; i < len; i++) {
250 dst[i] = genrand_int32 () & 0xFF;
254 #endif /* _WIN32 */