/* Portable arc4random.c based on arc4random.c from OpenBSD. *PortableversionbyChrisDavis,adaptedforLibeventbyNickMathewson *Copyright(c)2010ChrisDavis,NielsProvos,andNickMathewson *Copyright(c)2010-2012NielsProvosandNickMathewson * *NotethatinLibevent,thisfileisn'tcompileddirectly.Instead, *it'sincludedfromevutil_rand.c
*/
for (len = 0; len < sizeof(buf); len += n) {
n = sizeof(buf) - len;
if (0 == getrandom(&buf[len], n, 0)) return -1;
} /* make sure that the buffer actually got set. */ for (i=0,any_set=0; i<sizeof(buf); ++i) {
any_set |= buf[i];
} if (!any_set) return -1;
#ifdefined(EVENT__HAVE_SYS_SYSCTL_H) && defined(EVENT__HAVE_SYSCTL) #if EVENT__HAVE_DECL_CTL_KERN && EVENT__HAVE_DECL_KERN_ARND #define TRY_SEED_SYSCTL_BSD staticint
arc4_seed_sysctl_bsd(void)
{ /* Based on code from William Ahern and from OpenBSD, this function *triestousetheKERN_ARNDsyscalltogetentropyfromthekernel. *Thiscanworkevenif/dev/urandomisinaccessibleforsomereason
* (e.g., we're running in a chroot). */ int mib[] = { CTL_KERN, KERN_ARND }; unsignedchar buf[ADD_ENTROPY];
size_t len, n; int i, any_set;
memset(buf, 0, sizeof(buf));
len = sizeof(buf); if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) { for (len = 0; len < sizeof(buf); len += sizeof(unsigned)) {
n = sizeof(unsigned); if (n + len > sizeof(buf))
n = len - sizeof(buf); if (sysctl(mib, 2, &buf[len], &n, NULL, 0) == -1) return -1;
}
} /* make sure that the buffer actually got set. */ for (i=any_set=0; i<sizeof(buf); ++i) {
any_set |= buf[i];
} if (!any_set) return -1;
staticint arc4_seed_urandom_helper_(constchar *fname)
{ unsignedchar buf[ADD_ENTROPY]; int fd;
size_t n;
fd = evutil_open_closeonexec_(fname, O_RDONLY, 0); if (fd<0) return -1;
n = read_all(fd, buf, sizeof(buf));
close(fd); if (n != sizeof(buf)) return -1;
arc4_addrandom(buf, sizeof(buf));
evutil_memclear_(buf, sizeof(buf)); return0;
}
staticint
arc4_seed_urandom(void)
{ /* This is adapted from Tor's crypto_seed_rng() */ staticconstchar *filenames[] = { "/dev/srandom", "/dev/urandom", "/dev/random", NULL
}; int i; if (arc4random_urandom_filename) return arc4_seed_urandom_helper_(arc4random_urandom_filename);
for (i = 0; filenames[i]; ++i) { if (arc4_seed_urandom_helper_(filenames[i]) == 0) { return0;
}
}
return -1;
} #endif
staticint
arc4_seed(void)
{ int ok = 0; /* We try every method that might work, and don't give up even if one *doesseemtowork.There'snorealharminover-seeding,andif
* one of these sources turns out to be broken, that would be bad. */ #ifdef TRY_SEED_WIN32 if (0 == arc4_seed_win32())
ok = 1; #endif #ifdef TRY_SEED_GETRANDOM if (0 == arc4_seed_getrandom())
ok = 1; #endif #ifdef TRY_SEED_URANDOM if (0 == arc4_seed_urandom())
ok = 1; #endif #ifdef TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID if (arc4random_urandom_filename == NULL && 0 == arc4_seed_proc_sys_kernel_random_uuid())
ok = 1; #endif #ifdef TRY_SEED_SYSCTL_BSD if (0 == arc4_seed_sysctl_bsd())
ok = 1; #endif return ok ? 0 : -1;
}
staticint
arc4_stir(void)
{ int i;
if (!rs_initialized) {
arc4_init();
rs_initialized = 1;
}
if (0 != arc4_seed()) return -1;
/* *Discardearlykeystream,asperrecommendationsin *"WeaknessesintheKeySchedulingAlgorithmofRC4"by *ScottFluhrer,ItsikMantin,andAdiShamir. *http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps * *IlyaMironov's"(NotSo)RandomShufflesofRC4"suggeststhat *wedropatleast2*256bytes,with12*256asaconservative *value. * *RFC4345saystodrop6*256. * *Atleastsomeversionsofthiscodedrop4*256,inamistaken *beliefthat"words"intheFluhrer/Mantin/Shamirpaperrefers *toprocessorwords. * *Weaddanothersecttothecargocult,andchoose12*256.
*/ for (i = 0; i < 12*256; i++)
(void)arc4_getbyte();
val = arc4_getbyte() << 24;
val |= arc4_getbyte() << 16;
val |= arc4_getbyte() << 8;
val |= arc4_getbyte();
return val;
}
#ifndef ARC4RANDOM_NOSTIR
ARC4RANDOM_EXPORT int
arc4random_stir(void)
{ int val;
ARC4_LOCK_();
val = arc4_stir();
ARC4_UNLOCK_(); return val;
} #endif
#ifndef ARC4RANDOM_NOADDRANDOM
ARC4RANDOM_EXPORT void
arc4random_addrandom(constunsignedchar *dat, int datlen)
{ int j;
ARC4_LOCK_(); if (!rs_initialized)
arc4_stir(); for (j = 0; j < datlen; j += 256) { /* arc4_addrandom() ignores all but the first 256 bytes of *itsinput.WewanttomakesuretolookatALLthe *datain'dat',justincasetheuserisdoingsomething
* crazy like passing us all the files in /var/log. */
arc4_addrandom(dat + j, datlen - j);
}
ARC4_UNLOCK_();
} #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.