00001
00002
00003
00004 #include "db_config.h"
00005
00006 #include "db_int.h"
00007 #include "dbinc/crypto.h"
00008 #include "dbinc/hmac.h"
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define N 624
00038 #define M 397
00039 #define MATRIX_A 0x9908b0df
00040 #define UPPER_MASK 0x80000000
00041 #define LOWER_MASK 0x7fffffff
00042
00043
00044 #define TEMPERING_MASK_B 0x9d2c5680
00045 #define TEMPERING_MASK_C 0xefc60000
00046 #define TEMPERING_SHIFT_U(y) (y >> 11)
00047 #define TEMPERING_SHIFT_S(y) (y << 7)
00048 #define TEMPERING_SHIFT_T(y) (y << 15)
00049 #define TEMPERING_SHIFT_L(y) (y >> 18)
00050
00051 static void __db_sgenrand __P((unsigned long, unsigned long *, int *));
00052 #ifdef NOT_USED
00053 static void __db_lsgenrand __P((unsigned long *, unsigned long *, int *));
00054 #endif
00055 static unsigned long __db_genrand __P((DB_ENV *));
00056
00057
00058
00059
00060
00061
00062
00063 int
00064 __db_generate_iv(dbenv, iv)
00065 DB_ENV *dbenv;
00066 u_int32_t *iv;
00067 {
00068 int i, n, ret;
00069
00070 ret = 0;
00071 n = DB_IV_BYTES / sizeof(u_int32_t);
00072 MUTEX_LOCK(dbenv, dbenv->mtx_mt);
00073 if (dbenv->mt == NULL) {
00074 if ((ret = __os_calloc(dbenv, 1, N*sizeof(unsigned long),
00075 &dbenv->mt)) != 0)
00076 return (ret);
00077
00078 dbenv->mti = N + 1;
00079 }
00080 for (i = 0; i < n; i++) {
00081
00082
00083
00084 do {
00085 iv[i] = (u_int32_t)__db_genrand(dbenv);
00086 } while (iv[i] == 0);
00087 }
00088
00089 MUTEX_UNLOCK(dbenv, dbenv->mtx_mt);
00090 return (0);
00091 }
00092
00093
00094 static void
00095 __db_sgenrand(seed, mt, mtip)
00096 unsigned long seed;
00097 unsigned long mt[];
00098 int *mtip;
00099 {
00100 int i;
00101
00102 DB_ASSERT(seed != 0);
00103 for (i=0;i<N;i++) {
00104 mt[i] = seed & 0xffff0000;
00105 seed = 69069 * seed + 1;
00106 mt[i] |= (seed & 0xffff0000) >> 16;
00107 seed = 69069 * seed + 1;
00108 }
00109 *mtip = N;
00110 }
00111
00112 #ifdef NOT_USED
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 static void
00123 __db_lsgenrand(seed_array, mt, mtip)
00124 unsigned long seed_array[];
00125 unsigned long mt[];
00126 int *mtip;
00127
00128 {
00129 int i;
00130
00131 for (i=0;i<N;i++)
00132 mt[i] = seed_array[i];
00133 *mtip=N;
00134 }
00135 #endif
00136
00137 static unsigned long
00138 __db_genrand(dbenv)
00139 DB_ENV *dbenv;
00140 {
00141 unsigned long y;
00142 static unsigned long mag01[2]={0x0, MATRIX_A};
00143
00144 u_int32_t secs, seed, usecs;
00145
00146
00147
00148
00149 if (dbenv->mti >= N) {
00150 int kk;
00151
00152 if (dbenv->mti == N+1) {
00153
00154
00155
00156
00157 do {
00158 __os_clock(dbenv, &secs, &usecs);
00159 __db_chksum((u_int8_t *)&secs, sizeof(secs), NULL,
00160 (u_int8_t *)&seed);
00161 } while (seed == 0);
00162 __db_sgenrand((long)seed, dbenv->mt, &dbenv->mti);
00163 }
00164
00165 for (kk=0;kk<N-M;kk++) {
00166 y = (dbenv->mt[kk]&UPPER_MASK)|(dbenv->mt[kk+1]&LOWER_MASK);
00167 dbenv->mt[kk] = dbenv->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
00168 }
00169 for (;kk<N-1;kk++) {
00170 y = (dbenv->mt[kk]&UPPER_MASK)|(dbenv->mt[kk+1]&LOWER_MASK);
00171 dbenv->mt[kk] = dbenv->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
00172 }
00173 y = (dbenv->mt[N-1]&UPPER_MASK)|(dbenv->mt[0]&LOWER_MASK);
00174 dbenv->mt[N-1] = dbenv->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
00175
00176 dbenv->mti = 0;
00177 }
00178
00179 y = dbenv->mt[dbenv->mti++];
00180 y ^= TEMPERING_SHIFT_U(y);
00181 y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
00182 y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
00183 y ^= TEMPERING_SHIFT_L(y);
00184
00185 return y;
00186 }