浏览代码

[netdevice] Use link-layer address as part of RNG seed

iPXE currently seeds the random number generator using the system
timer tick count.  When large numbers of machines are booted
simultaneously, multiple machines may end up choosing the same DHCP
transaction ID (XID) value; this can cause problems.

Fix by using the least significant (and hence most variable) bits of
each network device's link-layer address to perturb the random number
generator.  This introduces some per-machine unique data into the
random number generator's seed, and so reduces the chances of DHCP XID
collisions.

This does not affect the ANS X9.82-compatible random bit generator
used by TLS and other cryptography code, which uses an entirely
separate source of entropy.

Originally-implemented-by: Bernhard Kohl <bernhard.kohl@nsn.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 年前
父节点
当前提交
445ac9fbdc
共有 1 个文件被更改,包括 11 次插入2 次删除
  1. 11
    2
      src/net/netdevice.c

+ 11
- 2
src/net/netdevice.c 查看文件

@@ -442,7 +442,9 @@ struct net_device * alloc_netdev ( size_t priv_size ) {
442 442
  */
443 443
 int register_netdev ( struct net_device *netdev ) {
444 444
 	static unsigned int ifindex = 0;
445
+	struct ll_protocol *ll_protocol = netdev->ll_protocol;
445 446
 	struct net_driver *driver;
447
+	uint32_t seed;
446 448
 	int rc;
447 449
 
448 450
 	/* Create device name */
@@ -453,10 +455,17 @@ int register_netdev ( struct net_device *netdev ) {
453 455
 
454 456
 	/* Set initial link-layer address, if not already set */
455 457
 	if ( ! netdev_has_ll_addr ( netdev ) ) {
456
-		netdev->ll_protocol->init_addr ( netdev->hw_addr,
457
-						 netdev->ll_addr );
458
+		ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr );
458 459
 	}
459 460
 
461
+	/* Use least significant bits of the link-layer address to
462
+	 * improve the randomness of the (non-cryptographic) random
463
+	 * number generator.
464
+	 */
465
+	memcpy ( &seed, ( netdev->ll_addr + ll_protocol->ll_addr_len
466
+			  - sizeof ( seed ) ), sizeof ( seed ) );
467
+	srand ( rand() ^ seed );
468
+
460 469
 	/* Add to device list */
461 470
 	netdev_get ( netdev );
462 471
 	list_add_tail ( &netdev->list, &net_devices );

正在加载...
取消
保存