randpool.c
Go to the documentation of this file.00001
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #include "randpool.h"
00077 #include "md2.h"
00078
00079 #include <stdio.h>
00080 #include <string.h>
00081
00082 #include <cfg/compiler.h>
00083 #include <cfg/debug.h>
00084 #include <cfg/macros.h>
00085
00086 #if CONFIG_RANDPOOL_TIMER
00087 #include <drv/timer.h>
00088 #endif
00089
00090
00091
00092
00093
00094
00095
00096 static void randpool_push(EntropyPool *pool, void *_byte, size_t n_byte)
00097 {
00098 size_t i = pool->pos_add;
00099 uint8_t *byte;
00100
00101 byte = (uint8_t *)_byte;
00102
00103
00104
00105
00106 for(int j = 0; j < n_byte; j++)
00107 {
00108 pool->pool_entropy[i] = pool->pool_entropy[i] ^ byte[j];
00109 i = (++i) % CONFIG_SIZE_ENTROPY_POOL;
00110 }
00111
00112 pool->pos_add = i;
00113 }
00114
00115
00116
00117
00118
00119
00120 static void randpool_stir(EntropyPool *pool)
00121 {
00122 size_t entropy = pool->entropy;
00123 Md2Context context;
00124 uint8_t tmp_buf[((sizeof(size_t) * 2) + sizeof(int)) * 2 + 1];
00125
00126 md2_init(&context);
00127
00128 randpool_add(pool, NULL, 0);
00129
00130 for (int i = 0; i < (CONFIG_SIZE_ENTROPY_POOL / MD2_DIGEST_LEN); i++)
00131 {
00132 sprintf(tmp_buf, "%0x%0x%0x",pool->counter, i, pool->pos_add);
00133
00134
00135
00136
00137 md2_update(&context, pool->pool_entropy, CONFIG_SIZE_ENTROPY_POOL);
00138
00139 md2_update(&context, tmp_buf, sizeof(tmp_buf) - 1);
00140
00141
00142 randpool_push(pool, md2_end(&context), MD2_DIGEST_LEN);
00143
00144 pool->counter = pool->counter + 1;
00145
00146 }
00147
00148
00149 randpool_add(pool, NULL, 0);
00150
00151 pool->entropy = entropy;
00152 }
00153
00157 void randpool_add(EntropyPool *pool, void *data, size_t entropy)
00158 {
00159 uint8_t sep[] = "\xaa\xaa\xaa\xaa";
00160 size_t data_len = ROUND_UP(entropy, 8) / 8;
00161
00162 randpool_push(pool, data, data_len);
00163
00164 #if CONFIG_RANDPOOL_TIMER
00165
00166 ticks_t event = timer_clock();
00167 ticks_t delta;
00168
00169
00170 delta = event - pool->last_counter;
00171
00172 randpool_push(pool, &event, sizeof(ticks_t));
00173 randpool_push(pool, sep, sizeof(sep) - 1);
00174 randpool_push(pool, &delta, sizeof(delta));
00175
00176
00177
00178
00179 delta = delta & 0xff;
00180 while(delta)
00181 {
00182 delta >>= 1;
00183 entropy++;
00184 }
00185
00186 pool->last_counter = event;
00187
00188 #endif
00189
00190 pool->entropy += entropy;
00191 }
00192
00198 void randpool_init(EntropyPool *pool, void *_data, size_t len)
00199 {
00200 uint8_t *data;
00201
00202 data = (uint8_t *)_data;
00203
00204 memset(pool, 0, sizeof(EntropyPool));
00205 pool->pos_get = MD2_DIGEST_LEN;
00206
00207 #if CONFIG_RANDPOOL_TIMER
00208 pool->last_counter = timer_clock();
00209 #endif
00210
00211 if(data)
00212 {
00213
00214
00215
00216
00217
00218 len = MIN(len,(size_t)CONFIG_SIZE_ENTROPY_POOL);
00219 memcpy(pool->pool_entropy, data, len);
00220 pool->entropy = len;
00221 }
00222
00223 }
00224
00228 size_t randpool_size(EntropyPool *pool)
00229 {
00230 return pool->entropy;
00231 }
00232
00242 void randpool_get(EntropyPool *pool, void *_data, size_t n_byte)
00243 {
00244 Md2Context context;
00245 size_t i = pool->pos_get;
00246 size_t n = n_byte;
00247 size_t pos_write = 0;
00248 size_t len = MIN((size_t)MD2_DIGEST_LEN, n_byte);
00249 uint8_t *data;
00250
00251 data = (uint8_t *)_data;
00252
00253
00254 ASSERT((MD2_DIGEST_LEN + i) < CONFIG_SIZE_ENTROPY_POOL);
00255
00256 md2_init(&context);
00257
00258 while(n > 0)
00259 {
00260
00261
00262 md2_update(&context, &pool->pool_entropy[i], MD2_DIGEST_LEN);
00263
00264 memcpy(&data[pos_write], md2_end(&context), len);
00265
00266 pos_write += len;
00267 n -= len;
00268
00269 len = MIN(n,(size_t)MD2_DIGEST_LEN);
00270
00271 i = (i + MD2_DIGEST_LEN) % CONFIG_SIZE_ENTROPY_POOL;
00272
00273
00274 if(i < MD2_DIGEST_LEN)
00275 {
00276 randpool_stir(pool);
00277 i = pool->pos_get;
00278 }
00279
00280 }
00281
00282 pool->pos_get = i;
00283 pool->entropy -= n_byte;
00284
00285
00286 if(pool->entropy < 0)
00287 pool->entropy = 0;
00288
00289 }
00290
00294 uint8_t *randpool_pool(EntropyPool *pool)
00295 {
00296 return pool->pool_entropy;
00297 }
00298