* [PATCH v3 0/2] Allow generating MAC addresses from machine ID
@ 2023-11-22 9:47 Uwe Kleine-König
2023-11-22 9:47 ` [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs Uwe Kleine-König
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2023-11-22 9:47 UTC (permalink / raw)
To: Sascha Hauer
Cc: Ahmad Fatoum, Alexander Shiyan, Thorsten Scherer, Ahmad Fatoum, barebox
Hello,
On Tue, Nov 21, 2023 at 09:33:58AM +0100, Sascha Hauer wrote:
> This series neither applies to master nor to next, please resend
here is the rebased series. Applies to current next. There are no other
changes.
Best regards
Uwe
Ahmad Fatoum (2):
common: machine_id: support deriving app specific UUIDs
net: add generic MAC address derivation from machine ID
common/machine_id.c | 83 +++++++++++++++++++++++++++++++++++++++++++-
include/linux/uuid.h | 8 +++++
include/machine_id.h | 11 ++++++
include/net.h | 2 ++
net/Kconfig | 17 +++++++++
net/eth.c | 15 ++++++--
net/net.c | 49 ++++++++++++++++++++++++--
7 files changed, 179 insertions(+), 6 deletions(-)
base-commit: 7c12dcdbe20ffc872af8b433c91263c6520cf669
--
2.42.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs
2023-11-22 9:47 [PATCH v3 0/2] Allow generating MAC addresses from machine ID Uwe Kleine-König
@ 2023-11-22 9:47 ` Uwe Kleine-König
2023-11-22 9:47 ` [PATCH v3 2/2] net: add generic MAC address derivation from machine ID Uwe Kleine-König
2023-11-22 15:24 ` [PATCH v3 0/2] Allow generating MAC addresses " Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2023-11-22 9:47 UTC (permalink / raw)
To: Sascha Hauer
Cc: Ahmad Fatoum, Ahmad Fatoum, Alexander Shiyan, Thorsten Scherer, barebox
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
libsystemd provides a sd_id128_get_machine_app_specific() function that
allows deriving an application specific UUID without directly leaking
the machine ID.
Let's provide an equivalent for barebox that will be used in a following
commit to generate a stable MAC instead of randomizing it.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/machine_id.c | 83 +++++++++++++++++++++++++++++++++++++++++++-
include/linux/uuid.h | 8 +++++
include/machine_id.h | 11 ++++++
3 files changed, 101 insertions(+), 1 deletion(-)
diff --git a/common/machine_id.c b/common/machine_id.c
index f0b148fb9b99..e670886d8538 100644
--- a/common/machine_id.c
+++ b/common/machine_id.c
@@ -13,6 +13,7 @@
#define MACHINE_ID_LENGTH 32
+static bool __machine_id_initialized;
static void *__machine_id_hashable;
static size_t __machine_id_hashable_length;
@@ -22,13 +23,92 @@ const void *machine_id_get_hashable(size_t *len)
return __machine_id_hashable;
}
+/**
+ * machine_id_set_hashable - Provide per-board unique data
+ * @hashable: Buffer
+ * @len: size of buffer
+ *
+ * The data supplied to the last call of this function prior to
+ * late_initcall will be hashed and stored into global.machine_id,
+ * which can be later used for fixup into the kernel command line
+ * or for deriving application specific unique IDs via
+ * machine_id_get_app_specific().
+ */
void machine_id_set_hashable(const void *hashable, size_t len)
{
-
__machine_id_hashable = xmemdup(hashable, len);
__machine_id_hashable_length = len;
}
+/**
+ * machine_id_get_app_specific - Generates an application-specific UUID
+ * @result: UUID output of the function
+ * @...: pairs of (const void *, size_t) arguments of data to factor
+ * into the UUID followed by a NULL sentinel value.
+ *
+ * Combines the machine ID with the application specific varargs data
+ * to arrive at an application-specific and board-specific UUID that is
+ * stable and unique.
+ *
+ * The function returns 0 if a UUID was successfully written into @result
+ * and a negative error code otherwise.
+ */
+int machine_id_get_app_specific(uuid_t *result, ...)
+{
+ static u8 hmac[SHA256_DIGEST_SIZE];
+ const void *data;
+ size_t size;
+ va_list args;
+ struct digest *d;
+ int ret;
+
+ if (!__machine_id_initialized)
+ return -ENODATA;
+
+ d = digest_alloc("hmac(sha256)");
+ if (!d)
+ return -ENOSYS;
+
+ ret = digest_set_key(d, __machine_id_hashable, __machine_id_hashable_length);
+ if (ret)
+ goto out;
+
+ ret = digest_init(d);
+ if (ret)
+ goto out;
+
+ ret = -ENODATA;
+
+ va_start(args, result);
+
+ while ((data = va_arg(args, const void *))) {
+ size = va_arg(args, size_t);
+
+ ret = digest_update(d, data, size);
+ if (ret)
+ break;
+ }
+
+ va_end(args);
+
+ if (ret)
+ goto out;
+
+ ret = digest_final(d, hmac);
+ if (ret)
+ goto out;
+
+ /* Take only the first half. */
+ memcpy(result, hmac, min(sizeof(hmac), sizeof(*result)));
+
+ uuid_make_v4(result);
+
+out:
+ digest_free(d);
+
+ return ret;
+}
+
static int machine_id_set_globalvar(void)
{
struct digest *digest = NULL;
@@ -66,6 +146,7 @@ static int machine_id_set_globalvar(void)
env_machine_id = basprintf("%.*s", MACHINE_ID_LENGTH, hex_machine_id);
globalvar_add_simple("machine_id", env_machine_id);
free(env_machine_id);
+ __machine_id_initialized = true;
out:
digest_free(digest);
diff --git a/include/linux/uuid.h b/include/linux/uuid.h
index 6b1a3efa1e0b..1e4ffb343452 100644
--- a/include/linux/uuid.h
+++ b/include/linux/uuid.h
@@ -107,6 +107,14 @@ extern const u8 uuid_index[16];
int guid_parse(const char *uuid, guid_t *u);
int uuid_parse(const char *uuid, uuid_t *u);
+static inline void uuid_make_v4(uuid_t *u) {
+ /* Set UUID version to 4 --- truly random generation */
+ u->b[6] = (u->b[6] & 0x0F) | 0x40;
+
+ /* Set the UUID variant to DCE */
+ u->b[8] = (u->b[8] & 0x3F) | 0x80;
+}
+
/* MEI UUID type, don't use anywhere else */
#include <uapi/linux/uuid.h>
diff --git a/include/machine_id.h b/include/machine_id.h
index 9699e7f2072b..29600483ddc5 100644
--- a/include/machine_id.h
+++ b/include/machine_id.h
@@ -3,11 +3,15 @@
#ifndef __MACHINE_ID_H__
#define __MACHINE_ID_H__
+#include <linux/types.h>
+#include <linux/uuid.h>
+
#if IS_ENABLED(CONFIG_MACHINE_ID)
const void *machine_id_get_hashable(size_t *len);
void machine_id_set_hashable(const void *hashable, size_t len);
+int machine_id_get_app_specific(uuid_t *result, ...) __attribute__((__sentinel__));
#else
@@ -20,6 +24,13 @@ static inline void machine_id_set_hashable(const void *hashable, size_t len)
{
}
+static inline int machine_id_get_app_specific(uuid_t *result, ...)
+ __attribute__((__sentinel__));
+static inline int machine_id_get_app_specific(uuid_t *result, ...)
+{
+ return -ENOSYS;
+}
+
#endif /* CONFIG_MACHINE_ID */
#endif /* __MACHINE_ID_H__ */
--
2.42.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 2/2] net: add generic MAC address derivation from machine ID
2023-11-22 9:47 [PATCH v3 0/2] Allow generating MAC addresses from machine ID Uwe Kleine-König
2023-11-22 9:47 ` [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs Uwe Kleine-König
@ 2023-11-22 9:47 ` Uwe Kleine-König
2023-11-22 15:24 ` [PATCH v3 0/2] Allow generating MAC addresses " Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2023-11-22 9:47 UTC (permalink / raw)
To: Sascha Hauer
Cc: Ahmad Fatoum, Alexander Shiyan, Thorsten Scherer, Ahmad Fatoum, barebox
From: Ahmad Fatoum <ahmad@a3f.at>
Especially during development, devices often lack a MAC address. While a
MAC address can be easily added to the environment:
nv dev.eth0.ethaddr="aa:bb:cc:dd:ee:ff"
It's easily lost when flashing complete new images, e.g. from CI.
Make the development experience neater by deriving a stable MAC address
if possible.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
include/net.h | 2 ++
net/Kconfig | 17 +++++++++++++++++
net/eth.c | 15 ++++++++++++---
net/net.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 78 insertions(+), 5 deletions(-)
diff --git a/include/net.h b/include/net.h
index a0ef8bee0404..de43c29f74ac 100644
--- a/include/net.h
+++ b/include/net.h
@@ -418,6 +418,8 @@ static inline int is_broadcast_ether_addr(const u8 *addr)
#define ETH_ALEN 6 /* Octets in an Ethernet address */
#define ETH_HLEN 14 /* Total octets in header.*/
+int generate_ether_addr(u8 *addr, int ethid);
+
/**
* random_ether_addr - Generate software assigned random Ethernet address
* @addr: Pointer to a six-byte array containing the Ethernet address
diff --git a/net/Kconfig b/net/Kconfig
index 59f14c23cba2..07e623670e22 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -6,6 +6,23 @@ menuconfig NET
if NET
+config NET_ETHADDR_FROM_MACHINE_ID
+ bool
+ prompt "generate stable Ethernet address"
+ depends on MACHINE_ID && HAVE_DIGEST_SHA256 && HAVE_DIGEST_HMAC
+ help
+ By default, barebox will generate random Ethernet addresses for
+ interfaces that had no explicit Ethernet address set via
+ either board code or NVMEM properties in device tree.
+
+ Say y here, to randomize Ethernet addresses only if no machine ID
+ is available. Should barebox have a machine ID, it will be used
+ alongside the hostname to generate MAC addresses that are unlikely
+ to change between subsequent runs of barebox.
+
+ This is not recommended for use in production as it may leak
+ information about the machine ID.
+
config NET_NFS
bool
prompt "nfs support"
diff --git a/net/eth.c b/net/eth.c
index ccac5e2a6488..d1474ec57df3 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -10,6 +10,7 @@
#include <dhcp.h>
#include <net.h>
#include <dma.h>
+#include <machine_id.h>
#include <of.h>
#include <of_net.h>
#include <linux/phy.h>
@@ -554,10 +555,11 @@ void eth_open_all(void)
}
}
-static int of_populate_ethaddr(void)
+static int populate_ethaddr(void)
{
char str[sizeof("xx:xx:xx:xx:xx:xx")];
struct eth_device *edev;
+ bool generated = false;
int ret;
list_for_each_entry(edev, &netdev_list, list) {
@@ -566,14 +568,21 @@ static int of_populate_ethaddr(void)
ret = of_get_mac_addr_nvmem(edev->parent->of_node,
edev->ethaddr);
+ if (IS_ENABLED(CONFIG_NET_ETHADDR_FROM_MACHINE_ID) && ret) {
+ ret = generate_ether_addr(edev->ethaddr, edev->dev.id);
+ generated = true;
+ }
if (ret)
continue;
ethaddr_to_string(edev->ethaddr, str);
- dev_info(&edev->dev, "Got preset MAC address from device tree: %s\n", str);
+ if (generated)
+ dev_notice(&edev->dev, "Generated MAC address from unique id: %s\n", str);
+ else
+ dev_info(&edev->dev, "Got preset MAC address from NVMEM: %s\n", str);
eth_set_ethaddr(edev, edev->ethaddr);
}
return 0;
}
-postenvironment_initcall(of_populate_ethaddr);
+postenvironment_initcall(populate_ethaddr);
diff --git a/net/net.c b/net/net.c
index bf2117ff7ec2..e38179491d7a 100644
--- a/net/net.c
+++ b/net/net.c
@@ -25,6 +25,7 @@
#include <init.h>
#include <globalvar.h>
#include <magicvar.h>
+#include <machine_id.h>
#include <linux/ctype.h>
#include <linux/err.h>
@@ -365,6 +366,43 @@ IPaddr_t net_get_gateway(void)
static LIST_HEAD(connection_list);
+/**
+ * generate_ether_addr - Generates stable software assigned Ethernet address
+ * @addr: Pointer to a six-byte array to contain the Ethernet address
+ * @ethid: index of the Ethernet interface
+ *
+ * Derives an Ethernet address (MAC) from the machine ID, that's stable
+ * per board that is not multicast and has the local assigned bit set.
+ *
+ * Return 0 if an address could be generated or a negative error code otherwise.
+ */
+int generate_ether_addr(u8 *ethaddr, int ethid)
+{
+ const char *hostname;
+ uuid_t id;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_NET_ETHADDR_FROM_MACHINE_ID))
+ return -ENOSYS;
+
+ hostname = barebox_get_hostname();
+ if (!hostname)
+ return -EINVAL;
+
+ ret = machine_id_get_app_specific(&id, ARRAY_AND_SIZE("barebox-macaddr:"),
+ hostname, strlen(hostname), NULL);
+ if (ret)
+ return ret;
+
+ memcpy(ethaddr, &id.b, ETH_ALEN);
+ eth_addr_add(ethaddr, ethid);
+
+ ethaddr[0] &= 0xfe; /* clear multicast bit */
+ ethaddr[0] |= 0x02; /* set local assignment bit (IEEE802) */
+
+ return 0;
+}
+
static struct net_connection *net_new(struct eth_device *edev, IPaddr_t dest,
rx_handler_f *handler, void *ctx)
{
@@ -381,9 +419,16 @@ static struct net_connection *net_new(struct eth_device *edev, IPaddr_t dest,
if (!is_valid_ether_addr(edev->ethaddr)) {
char str[sizeof("xx:xx:xx:xx:xx:xx")];
- random_ether_addr(edev->ethaddr);
+
+ ret = generate_ether_addr(edev->ethaddr, edev->dev.id);
+ if (ret)
+ random_ether_addr(edev->ethaddr);
+
ethaddr_to_string(edev->ethaddr, str);
- dev_warn(&edev->dev, "No MAC address set. Using random address %s\n", str);
+
+ dev_warn(&edev->dev, "No MAC address set. Using %s %s\n",
+ ret == 1 ? "address computed from unique ID" : "random address",
+ str);
eth_set_ethaddr(edev, edev->ethaddr);
}
--
2.42.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3 0/2] Allow generating MAC addresses from machine ID
2023-11-22 9:47 [PATCH v3 0/2] Allow generating MAC addresses from machine ID Uwe Kleine-König
2023-11-22 9:47 ` [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs Uwe Kleine-König
2023-11-22 9:47 ` [PATCH v3 2/2] net: add generic MAC address derivation from machine ID Uwe Kleine-König
@ 2023-11-22 15:24 ` Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2023-11-22 15:24 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Ahmad Fatoum, Alexander Shiyan, Thorsten Scherer, Ahmad Fatoum, barebox
On Wed, Nov 22, 2023 at 10:47:48AM +0100, Uwe Kleine-König wrote:
> Hello,
>
> On Tue, Nov 21, 2023 at 09:33:58AM +0100, Sascha Hauer wrote:
> > This series neither applies to master nor to next, please resend
>
> here is the rebased series. Applies to current next. There are no other
> changes.
>
> Best regards
> Uwe
>
> Ahmad Fatoum (2):
> common: machine_id: support deriving app specific UUIDs
> net: add generic MAC address derivation from machine ID
Applied, thanks
Sascha
>
> common/machine_id.c | 83 +++++++++++++++++++++++++++++++++++++++++++-
> include/linux/uuid.h | 8 +++++
> include/machine_id.h | 11 ++++++
> include/net.h | 2 ++
> net/Kconfig | 17 +++++++++
> net/eth.c | 15 ++++++--
> net/net.c | 49 ++++++++++++++++++++++++--
> 7 files changed, 179 insertions(+), 6 deletions(-)
>
> base-commit: 7c12dcdbe20ffc872af8b433c91263c6520cf669
> --
> 2.42.0
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-11-22 15:25 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-22 9:47 [PATCH v3 0/2] Allow generating MAC addresses from machine ID Uwe Kleine-König
2023-11-22 9:47 ` [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs Uwe Kleine-König
2023-11-22 9:47 ` [PATCH v3 2/2] net: add generic MAC address derivation from machine ID Uwe Kleine-König
2023-11-22 15:24 ` [PATCH v3 0/2] Allow generating MAC addresses " Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox