ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
device_id.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file device_id.cpp
6 * @brief Stable MAC-derived device UUID - implementation. See device_id.h.
7 */
8
9#include "device_id.h"
11
12#if PC_ENABLE_DEVICE_ID
13
14#include "crypto/hash/sha1.h"
15
16#ifdef ARDUINO
17#include <esp_mac.h> // esp_read_mac()
18#endif
19
20namespace
21{
22// RFC 4122 DNS namespace UUID (6ba7b810-9dad-11d1-80b4-00c04fd430c8).
23const uint8_t NS_DNS[16] = {0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1,
24 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8};
25} // namespace
26
27void pc_uuid_from_mac(const uint8_t mac[6], char out[PC_UUID_STR_LEN])
28{
29 // UUIDv5 name = lowercase MAC hex (12 chars, no separators).
30 uint8_t input[16 + 12];
31 for (int i = 0; i < 16; i++)
32 {
33 input[i] = NS_DNS[i];
34 }
35 for (int i = 0; i < 6; i++)
36 {
37 input[16 + i * 2] = (uint8_t)pc_hex_digit((uint8_t)(mac[i] >> 4));
38 input[16 + i * 2 + 1] = (uint8_t)pc_hex_digit((uint8_t)(mac[i] & 0x0F));
39 }
40
41 uint8_t h[PC_SHA1_DIGEST_LEN];
42 pc_sha1(input, sizeof(input), h);
43 h[6] = (uint8_t)((h[6] & 0x0F) | 0x50); // version 5
44 h[8] = (uint8_t)((h[8] & 0x3F) | 0x80); // RFC 4122 variant
45
46 // Format as 8-4-4-4-12 (16 bytes -> 32 hex + 4 dashes).
47 static const int groups[5] = {4, 2, 2, 2, 6};
48 int hi = 0;
49 int oi = 0;
50 for (int g = 0; g < 5; g++)
51 {
52 if (g)
53 {
54 out[oi++] = '-';
55 }
56 for (int b = 0; b < groups[g]; b++)
57 {
58 out[oi++] = pc_hex_digit((uint8_t)(h[hi] >> 4));
59 out[oi++] = pc_hex_digit((uint8_t)(h[hi] & 0x0F));
60 hi++;
61 }
62 }
63 out[oi] = '\0';
64}
65
66#ifdef ARDUINO
67void pc_device_uuid(char out[PC_UUID_STR_LEN])
68{
69 uint8_t mac[6] = {0};
70 esp_read_mac(mac, ESP_MAC_WIFI_STA); // stable factory MAC
71 pc_uuid_from_mac(mac, out);
72}
73#endif
74
75#endif // PC_ENABLE_DEVICE_ID
Stable device UUID derived from the chip MAC (PC_ENABLE_DEVICE_ID).
Base-16 conversion between raw bytes and their ASCII digits.
char pc_hex_digit(uint8_t nibble, bool upper=false)
Low nibble of nibble as a hex character, uppercase when upper.
Definition hex.h:30
PC_CRYPTO_HOT void pc_sha1(const uint8_t *data, size_t len, uint8_t digest[PC_SHA1_DIGEST_LEN])
Compute a SHA-1 digest over an arbitrary byte buffer.
Definition sha1.cpp:26
SHA-1 (FIPS 180-4) - one-shot digest.
#define PC_SHA1_DIGEST_LEN
SHA-1 digest length in bytes.
Definition sha1.h:23