243
244
/* This is the central step in the MD5 algorithm. */
244
245
#define pmd5_step(f, w, x, y, z, data, s) \
245
(w += (f(x, y, z) + data) & 0xffffffff, w = w<<s | w>>(32-s), w += x)
246
(w += (f(x, y, z) + data) & 0xffffffff, w = w<<s | w>>(32-s), w += x)
248
249
* The core of the MD5 algorithm, this alters an existing MD5 hash to
249
250
* reflect the addition of 16 longwords of new data.
252
pMD5Hash( unsigned *out, unsigned const in[16] )
253
pMD5Hash(unsigned *out, unsigned const in[16])
261
pmd5_step( F1, a, b, c, d, in[0] + 0xd76aa478, 7 );
262
pmd5_step( F1, d, a, b, c, in[1] + 0xe8c7b756, 12 );
263
pmd5_step( F1, c, d, a, b, in[2] + 0x242070db, 17 );
264
pmd5_step( F1, b, c, d, a, in[3] + 0xc1bdceee, 22 );
265
pmd5_step( F1, a, b, c, d, in[4] + 0xf57c0faf, 7 );
266
pmd5_step( F1, d, a, b, c, in[5] + 0x4787c62a, 12 );
267
pmd5_step( F1, c, d, a, b, in[6] + 0xa8304613, 17 );
268
pmd5_step( F1, b, c, d, a, in[7] + 0xfd469501, 22 );
269
pmd5_step( F1, a, b, c, d, in[8] + 0x698098d8, 7 );
270
pmd5_step( F1, d, a, b, c, in[9] + 0x8b44f7af, 12 );
271
pmd5_step( F1, c, d, a, b, in[10] + 0xffff5bb1, 17 );
272
pmd5_step( F1, b, c, d, a, in[11] + 0x895cd7be, 22 );
273
pmd5_step( F1, a, b, c, d, in[12] + 0x6b901122, 7 );
274
pmd5_step( F1, d, a, b, c, in[13] + 0xfd987193, 12 );
275
pmd5_step( F1, c, d, a, b, in[14] + 0xa679438e, 17 );
276
pmd5_step( F1, b, c, d, a, in[15] + 0x49b40821, 22 );
278
pmd5_step( F2, a, b, c, d, in[1] + 0xf61e2562, 5 );
279
pmd5_step( F2, d, a, b, c, in[6] + 0xc040b340, 9 );
280
pmd5_step( F2, c, d, a, b, in[11] + 0x265e5a51, 14 );
281
pmd5_step( F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20 );
282
pmd5_step( F2, a, b, c, d, in[5] + 0xd62f105d, 5 );
283
pmd5_step( F2, d, a, b, c, in[10] + 0x02441453, 9 );
284
pmd5_step( F2, c, d, a, b, in[15] + 0xd8a1e681, 14 );
285
pmd5_step( F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20 );
286
pmd5_step( F2, a, b, c, d, in[9] + 0x21e1cde6, 5 );
287
pmd5_step( F2, d, a, b, c, in[14] + 0xc33707d6, 9 );
288
pmd5_step( F2, c, d, a, b, in[3] + 0xf4d50d87, 14 );
289
pmd5_step( F2, b, c, d, a, in[8] + 0x455a14ed, 20 );
290
pmd5_step( F2, a, b, c, d, in[13] + 0xa9e3e905, 5 );
291
pmd5_step( F2, d, a, b, c, in[2] + 0xfcefa3f8, 9 );
292
pmd5_step( F2, c, d, a, b, in[7] + 0x676f02d9, 14 );
293
pmd5_step( F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20 );
295
pmd5_step( F3, a, b, c, d, in[5] + 0xfffa3942, 4 );
296
pmd5_step( F3, d, a, b, c, in[8] + 0x8771f681, 11 );
297
pmd5_step( F3, c, d, a, b, in[11] + 0x6d9d6122, 16 );
298
pmd5_step( F3, b, c, d, a, in[14] + 0xfde5380c, 23 );
299
pmd5_step( F3, a, b, c, d, in[1] + 0xa4beea44, 4 );
300
pmd5_step( F3, d, a, b, c, in[4] + 0x4bdecfa9, 11 );
301
pmd5_step( F3, c, d, a, b, in[7] + 0xf6bb4b60, 16 );
302
pmd5_step( F3, b, c, d, a, in[10] + 0xbebfbc70, 23 );
303
pmd5_step( F3, a, b, c, d, in[13] + 0x289b7ec6, 4 );
304
pmd5_step( F3, d, a, b, c, in[0] + 0xeaa127fa, 11 );
305
pmd5_step( F3, c, d, a, b, in[3] + 0xd4ef3085, 16 );
306
pmd5_step( F3, b, c, d, a, in[6] + 0x04881d05, 23 );
307
pmd5_step( F3, a, b, c, d, in[9] + 0xd9d4d039, 4 );
308
pmd5_step( F3, d, a, b, c, in[12] + 0xe6db99e5, 11 );
309
pmd5_step( F3, c, d, a, b, in[15] + 0x1fa27cf8, 16 );
310
pmd5_step( F3, b, c, d, a, in[2] + 0xc4ac5665, 23 );
312
pmd5_step( F4, a, b, c, d, in[0] + 0xf4292244, 6 );
313
pmd5_step( F4, d, a, b, c, in[7] + 0x432aff97, 10 );
314
pmd5_step( F4, c, d, a, b, in[14] + 0xab9423a7, 15 );
315
pmd5_step( F4, b, c, d, a, in[5] + 0xfc93a039, 21 );
316
pmd5_step( F4, a, b, c, d, in[12] + 0x655b59c3, 6 );
317
pmd5_step( F4, d, a, b, c, in[3] + 0x8f0ccc92, 10 );
318
pmd5_step( F4, c, d, a, b, in[10] + 0xffeff47d, 15 );
319
pmd5_step( F4, b, c, d, a, in[1] + 0x85845dd1, 21 );
320
pmd5_step( F4, a, b, c, d, in[8] + 0x6fa87e4f, 6 );
321
pmd5_step( F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10 );
322
pmd5_step( F4, c, d, a, b, in[6] + 0xa3014314, 15 );
323
pmd5_step( F4, b, c, d, a, in[13] + 0x4e0811a1, 21 );
324
pmd5_step( F4, a, b, c, d, in[4] + 0xf7537e82, 6 );
325
pmd5_step( F4, d, a, b, c, in[11] + 0xbd3af235, 10 );
326
pmd5_step( F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15 );
327
pmd5_step( F4, b, c, d, a, in[9] + 0xeb86d391, 21 );
262
pmd5_step(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
263
pmd5_step(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
264
pmd5_step(F1, c, d, a, b, in[2] + 0x242070db, 17);
265
pmd5_step(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
266
pmd5_step(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
267
pmd5_step(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
268
pmd5_step(F1, c, d, a, b, in[6] + 0xa8304613, 17);
269
pmd5_step(F1, b, c, d, a, in[7] + 0xfd469501, 22);
270
pmd5_step(F1, a, b, c, d, in[8] + 0x698098d8, 7);
271
pmd5_step(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
272
pmd5_step(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
273
pmd5_step(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
274
pmd5_step(F1, a, b, c, d, in[12] + 0x6b901122, 7);
275
pmd5_step(F1, d, a, b, c, in[13] + 0xfd987193, 12);
276
pmd5_step(F1, c, d, a, b, in[14] + 0xa679438e, 17);
277
pmd5_step(F1, b, c, d, a, in[15] + 0x49b40821, 22);
279
pmd5_step(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
280
pmd5_step(F2, d, a, b, c, in[6] + 0xc040b340, 9);
281
pmd5_step(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
282
pmd5_step(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
283
pmd5_step(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
284
pmd5_step(F2, d, a, b, c, in[10] + 0x02441453, 9);
285
pmd5_step(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
286
pmd5_step(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
287
pmd5_step(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
288
pmd5_step(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
289
pmd5_step(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
290
pmd5_step(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
291
pmd5_step(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
292
pmd5_step(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
293
pmd5_step(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
294
pmd5_step(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
296
pmd5_step(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
297
pmd5_step(F3, d, a, b, c, in[8] + 0x8771f681, 11);
298
pmd5_step(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
299
pmd5_step(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
300
pmd5_step(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
301
pmd5_step(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
302
pmd5_step(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
303
pmd5_step(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
304
pmd5_step(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
305
pmd5_step(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
306
pmd5_step(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
307
pmd5_step(F3, b, c, d, a, in[6] + 0x04881d05, 23);
308
pmd5_step(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
309
pmd5_step(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
310
pmd5_step(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
311
pmd5_step(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
313
pmd5_step(F4, a, b, c, d, in[0] + 0xf4292244, 6);
314
pmd5_step(F4, d, a, b, c, in[7] + 0x432aff97, 10);
315
pmd5_step(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
316
pmd5_step(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
317
pmd5_step(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
318
pmd5_step(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
319
pmd5_step(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
320
pmd5_step(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
321
pmd5_step(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
322
pmd5_step(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
323
pmd5_step(F4, c, d, a, b, in[6] + 0xa3014314, 15);
324
pmd5_step(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
325
pmd5_step(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
326
pmd5_step(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
327
pmd5_step(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
328
pmd5_step(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
335
336
/* ####################################################################### */
339
sumFile( const char *name, int len, int whence, long offset )
340
sumFile(const char *name, int len, int whence, long offset)
341
int fd, i, cnt, readlen = 0;
342
unsigned char buf[0x1000];
342
int fd, i, cnt, readlen = 0;
343
unsigned char buf[0x1000];
344
if ((fd = open( name, O_RDONLY )) < 0) {
345
debug( "cannot open entropy source %\"s: %m\n", name );
348
lseek( fd, offset, whence );
349
while (readlen < len) {
350
if (!(cnt = read( fd, buf, sizeof(buf) )))
354
debug( "cannot read entropy source %\"s: %m\n", name );
358
if (sizeof(unsigned) == 4)
359
addEntropy( (unsigned *)buf, (cnt + 3) / 4 );
361
unsigned buf2[sizeof(buf) / 4];
362
for (i = 0; i < cnt; i += 8) {
363
buf2[i / 4] = *(unsigned *)(buf + i) & 0xffffffff;
364
buf2[i / 4 + 1] = *(unsigned *)(buf + i) >> 32;
366
addEntropy( buf2, (cnt + 3) / 4 );
370
debug( "read %d bytes from entropy source %\"s\n", readlen, name );
345
if ((fd = open(name, O_RDONLY)) < 0) {
346
debug("cannot open entropy source %\"s: %m\n", name);
349
lseek(fd, offset, whence);
350
while (readlen < len) {
351
if (!(cnt = read(fd, buf, sizeof(buf))))
355
debug("cannot read entropy source %\"s: %m\n", name);
359
if (sizeof(unsigned) == 4) {
360
addEntropy((unsigned *)buf, (cnt + 3) / 4);
362
unsigned buf2[sizeof(buf) / 4];
363
for (i = 0; i < cnt; i += 8) {
364
buf2[i / 4] = *(unsigned *)(buf + i) & 0xffffffff;
365
buf2[i / 4 + 1] = *(unsigned *)(buf + i) >> 32;
367
addEntropy(buf2, (cnt + 3) / 4);
371
debug("read %d bytes from entropy source %\"s\n", readlen, name);
375
addTimerEntropy( void )
376
addTimerEntropy(void)
378
gettimeofday( &now, 0 );
379
addEntropy( (unsigned *)&now, sizeof(now)/sizeof(unsigned) );
379
gettimeofday(&now, 0);
380
addEntropy((unsigned *)&now, sizeof(now) / sizeof(unsigned));
382
383
#define BSIZ 0x10000
385
addOtherEntropy( void )
386
addOtherEntropy(void)
388
/* XXX -- setup-specific ... use some common ones */
389
sumFile( "/var/log/messages", 0x1000, SEEK_END, -0x1000 );
390
sumFile( "/var/log/syslog", 0x1000, SEEK_END, -0x1000 );
391
sumFile( "/var/log/debug", 0x1000, SEEK_END, -0x1000 );
392
sumFile( "/var/log/kern.log", 0x1000, SEEK_END, -0x1000 );
393
sumFile( "/var/log/daemon.log", 0x1000, SEEK_END, -0x1000 );
389
/* XXX -- setup-specific ... use some common ones */
390
sumFile("/var/log/messages", 0x1000, SEEK_END, -0x1000);
391
sumFile("/var/log/syslog", 0x1000, SEEK_END, -0x1000);
392
sumFile("/var/log/debug", 0x1000, SEEK_END, -0x1000);
393
sumFile("/var/log/kern.log", 0x1000, SEEK_END, -0x1000);
394
sumFile("/var/log/daemon.log", 0x1000, SEEK_END, -0x1000);
394
395
/* root hardly ever has an own box ... maybe pick a random mailbox instead? eek ...
395
sumFile( "/var/spool/mail/root", 0x1000, SEEK_END, -0x1000 );
396
sumFile("/var/spool/mail/root", 0x1000, SEEK_END, -0x1000);
400
addPreGetEntropy( void )
401
addPreGetEntropy(void)
406
if ((readlen = sumFile( randomFile, BSIZ, SEEK_SET, offset )) == BSIZ) {
407
if ((readlen = sumFile(randomFile, BSIZ, SEEK_SET, offset)) == BSIZ) {
408
409
#if defined(__i386__) || defined(amiga)
409
if (!strcmp( randomFile, "/dev/mem" )) {
410
if (offset == 0xa0000) /* skip 640kB-1MB ROM mappings */
412
else if (offset == 0xf00000) /* skip 15-16MB memory hole */
410
if (!strcmp(randomFile, "/dev/mem")) {
411
if (offset == 0xa0000) /* skip 640kB-1MB ROM mappings */
413
else if (offset == 0xf00000) /* skip 15-16MB memory hole */
417
} else if (readlen >= 0 && offset) {
418
if ((offset = sumFile( randomFile, BSIZ, SEEK_SET, 0 )) == BSIZ)
421
logError( "Cannot read randomFile %\"s; "
422
"X cookies may be easily guessable\n", randomFile );
418
} else if (readlen >= 0 && offset) {
419
if ((offset = sumFile(randomFile, BSIZ, SEEK_SET, 0)) == BSIZ)
422
logError("Cannot read randomFile %\"s; "
423
"X cookies may be easily guessable\n", randomFile);
426
427
/* len MUST be multiple of sizeof(unsigned) and not more than 16! */
427
428
/* auth MUST be sizeof(unsigned)-aligned! */
429
generateAuthData( char *auth, int len )
430
generateAuthData(char *auth, int len)
431
432
#ifdef HAVE_ARC4RANDOM
433
unsigned *rnd = (unsigned *)auth;
434
if (sizeof(unsigned) == 4)
435
for (i = 0; i < len; i += 4)
436
rnd[i / 4] = arc4random();
438
for (i = 0; i < len; i += 8)
439
rnd[i / 8] = arc4random() | (arc4random() << 32);
434
unsigned *rnd = (unsigned *)auth;
435
if (sizeof(unsigned) == 4)
436
for (i = 0; i < len; i += 4)
437
rnd[i / 4] = arc4random();
439
for (i = 0; i < len; i += 8)
440
rnd[i / 8] = arc4random() | (arc4random() << 32);
443
const char *rd = randomDevice;
444
const char *rd = randomDevice;
444
445
# ifdef DEV_RANDOM
450
if ((fd = open( rd, O_RDONLY )) >= 0) {
451
if (read( fd, auth, len ) == len) {
456
logError( "Cannot read randomDevice %\"s: %m\n", rd );
458
logError( "Cannot open randomDevice %\"s: %m\n", rd );
451
if ((fd = open(rd, O_RDONLY)) >= 0) {
452
if (read(fd, auth, len) == len) {
457
logError("Cannot read randomDevice %\"s: %m\n", rd);
459
logError("Cannot open randomDevice %\"s: %m\n", rd);
459
460
# ifdef DEV_RANDOM
464
if (!getPrngdBytes( auth, len, prngdPort, prngdSocket ))
468
unsigned *rnd = (unsigned *)auth;
469
unsigned tmp[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
471
pMD5Hash( tmp, epool );
472
addEntropy( tmp, 1 );
473
pMD5Hash( tmp, epool + 16 );
474
addEntropy( tmp + 2, 1 );
475
if (sizeof(unsigned) == 4)
476
memcpy( auth, tmp, len );
479
for (i = 0; i < len; i += 8)
480
rnd[i / 8] = tmp[i / 4] | (tmp[i / 4 + 1] << 32);
465
if (!getPrngdBytes(auth, len, prngdPort, prngdSocket))
469
unsigned *rnd = (unsigned *)auth;
470
unsigned tmp[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
472
pMD5Hash(tmp, epool);
474
pMD5Hash(tmp, epool + 16);
475
addEntropy(tmp + 2, 1);
476
if (sizeof(unsigned) == 4) {
477
memcpy(auth, tmp, len);
480
for (i = 0; i < len; i += 8)
481
rnd[i / 8] = tmp[i / 4] | (tmp[i / 4 + 1] << 32);
488
489
#ifndef HAVE_ARC4RANDOM
493
generateAuthData( (char *)&rslt, sizeof(int) );
494
return rslt & 0x7fffffff;
494
generateAuthData((char *)&rslt, sizeof(int));
495
return rslt & 0x7fffffff;