Changeset View
Standalone View
sys/kern/subr_bus.c
Show First 20 Lines • Show All 2,919 Lines • ▼ Show 20 Lines | |||||
* @retval ENXIO no driver was found | * @retval ENXIO no driver was found | ||||
* @retval ENOMEM memory allocation failure | * @retval ENOMEM memory allocation failure | ||||
* @retval non-zero some other unix error code | * @retval non-zero some other unix error code | ||||
*/ | */ | ||||
int | int | ||||
device_attach(device_t dev) | device_attach(device_t dev) | ||||
{ | { | ||||
uint64_t attachtime; | uint64_t attachtime; | ||||
uint16_t attachentropy; | |||||
int error; | int error; | ||||
if (resource_disabled(dev->driver->name, dev->unit)) { | if (resource_disabled(dev->driver->name, dev->unit)) { | ||||
device_disable(dev); | device_disable(dev); | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(dev, "disabled via hints entry\n"); | device_printf(dev, "disabled via hints entry\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
Show All 9 Lines | if ((error = DEVICE_ATTACH(dev)) != 0) { | ||||
if (!(dev->flags & DF_FIXEDCLASS)) | if (!(dev->flags & DF_FIXEDCLASS)) | ||||
devclass_delete_device(dev->devclass, dev); | devclass_delete_device(dev->devclass, dev); | ||||
(void)device_set_driver(dev, NULL); | (void)device_set_driver(dev, NULL); | ||||
device_sysctl_fini(dev); | device_sysctl_fini(dev); | ||||
KASSERT(dev->busy == 0, ("attach failed but busy")); | KASSERT(dev->busy == 0, ("attach failed but busy")); | ||||
dev->state = DS_NOTPRESENT; | dev->state = DS_NOTPRESENT; | ||||
return (error); | return (error); | ||||
} | } | ||||
dev->flags |= DF_ATTACHED_ONCE; | dev->flags |= DF_ATTACHED_ONCE; | ||||
attachtime = get_cyclecount() - attachtime; | /* We only need the low bits of this time, but ranges from tens to thousands | ||||
cem: Trivial style(9) nit: the first `/*` should be on a line by itself. | |||||
/* | * have been seen, so keep 2 bytes' worth. | ||||
Done Inline Actionsstyle(9) nitpick: comment style looks like this: /* * We only ... */ Or maybe: /* We only ... */ if it all fits in one 80-char line. But not: /* We only ... */ cem: style(9) nitpick: comment style looks like this:
```
/*
* We only ...
*/
```
Or maybe:
```… | |||||
Done Inline ActionsI think the fact that we only see thousands suggests maybe we should throw away the 9th-16th bits too. But I am ok with this improvement (8 -> 2 bytes) for now. cem: I think the fact that we only see thousands suggests maybe we should throw away the 9th-16th… | |||||
Done Inline ActionsRanges form tens to thousands have been seen. :-) markm: Ranges form tens to thousands have been seen. :-)
This is a *GOOD* entropy source. | |||||
* 4 bits per device is a reasonable value for desktop and server | |||||
* hardware with good get_cyclecount() implementations, but WILL | |||||
* need to be adjusted on other platforms. | |||||
*/ | */ | ||||
#define RANDOM_PROBE_BIT_GUESS 4 | attachentropy = (uint16_t)(get_cyclecount() - attachtime); | ||||
Done Inline ActionsThis comment is now obsolete. cem: This comment is now obsolete. | |||||
if (bootverbose) | random_harvest_direct(&attachentropy, sizeof(attachentropy), RANDOM_ATTACH); | ||||
Done Inline ActionsIs this print really useful? We don't print most harvest sources. Also consider that printf may go to system logs with a timestamp which may reduce the entropy from an attacker's perspective. cem: Is this print really useful? We don't print most harvest sources. Also consider that printf… | |||||
printf("random: harvesting attach, %zu bytes (%d bits) from %s%d\n", | |||||
sizeof(attachtime), RANDOM_PROBE_BIT_GUESS, | |||||
dev->driver->name, dev->unit); | |||||
random_harvest_direct(&attachtime, sizeof(attachtime), | |||||
RANDOM_PROBE_BIT_GUESS, RANDOM_ATTACH); | |||||
device_sysctl_update(dev); | device_sysctl_update(dev); | ||||
Done Inline ActionsThe Fortuna authors suggest only harvesting the low bits from timing events since the high bits are fairly predictable. My understanding is that it doesn't really matter if we're well-seeded with a saved entropy file due to the properties of SHA_d-256, but if we *don't* have that and are still initially seeding we probably don't want to count highly-predictable high-order attach bytes (many of which are likely to be zero, and even the rest may be highly predictable from logs) towards our minimum seed size. Maybe: uint8_t attachentropy; ... attachentropy = attachtime & 0xFF; random_harvest_direct(&attachentropy, 1, RANDOM_ATTACH); cem: The Fortuna authors suggest only harvesting the low bits from timing events since the high bits… | |||||
if (dev->busy) | if (dev->busy) | ||||
dev->state = DS_BUSY; | dev->state = DS_BUSY; | ||||
else | else | ||||
dev->state = DS_ATTACHED; | dev->state = DS_ATTACHED; | ||||
dev->flags &= ~DF_DONENOMATCH; | dev->flags &= ~DF_DONENOMATCH; | ||||
EVENTHANDLER_DIRECT_INVOKE(device_attach, dev); | EVENTHANDLER_DIRECT_INVOKE(device_attach, dev); | ||||
devadded(dev); | devadded(dev); | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 2,840 Lines • Show Last 20 Lines |
Trivial style(9) nit: the first /* should be on a line by itself.