## Introduction Managing hardware devices (GPUs, CPUs, NICs) in data centers often requires multiple tools, each with its own device identification method. This inconsistency complicates device correlation and management, especially across different vendors. The **Component Unified Identifier (CUID)** solves this by providing a deterministic, unique identifier for each device type, enabling consistent referencing and easier integration. ### What is CUID? The **Component Unified Identifier (CUID or CUUID)** is generated by combining device-specific data into a 122 bit ID value as follows: | Bits | Name | Comments | |------|------|----------| | 0:63 | Device Serial Number/Fingerprint | from PCIe configuration DSN caps (endpoint), SMBIOS platform serial number, ACPI or other architectural component identifier (if not available, SW generated fingerprint from proprietary individual marker) Integer, may be MSB 0-extended if smaller than 64 bit or truncated if larger | | 64:71 | UnitID (part 1) | if component supports unitID, 0 otherwise | | 72:79 | RevisionID | if component supports revision ID, 0 otherwise | | 80:95 | DeviceID | from PCIe configuration space or SMBIOS ID, For CPU: Family # and Model # values combined | | 96:111 | VendorID | from PCIe configuration space or SMBIOS vendor ID, follows PCIe vendor ID 16 bit value definition (e.g. 0x1022 or 0x1002 for AMD) | | 112:117 | UnitID (part 2) | if UnitID value is >= 256, 0 otherwise | | 118:121 | Device Type | See `amdcuid_device_type_t` in amd_cuid.h | This value is then used to fill out a UUIDv8 style format as follows: | Bit position | Value | Comments | |--------------|-------|----------| | 0:47 | ID value (part 1) | LSB of ID value | | 48:51 | must be 8 (fixed) | for RFC 9562 compliance | | 52:63 | ID value (part 2) || | 64:65 | 10b (fixed) | for RFC 9562 compliance | | 66:127 | ID value (part 3) | MSB of ID value | A **derived CUID** is derived by hashing the primary CUID using HMAC-SHA2-256 (keyed hash) with a 256-bit key. This obscures hardware details from lower-privilege software and prevents precomputed table attacks. To protect the serial number with sensitive information, users of the tool must provide the 256-bit key to use for the keyed hashing function, as described in FIPS 198-1, The Keyed-Hash Message Authentication Code (HMAC). This key must be unique, random, and protected from unauthorized use. This scheme will result in additional management overhead to securely store the key. The key should only be accessible to privileged users or the privileged service who would then use the key along with the primary ID in the HMAC-SHA2-256 function to generate the derived ID. ### CUID File Privileged applications generate and share derived CUIDs with non-privileged users via a file (the **CUID file**) or IPC. The file should be stored in `/tmp` or a `tmpfs` directory and readable by non-privileged users. It is updated by a daemon, boot script, or cron job. #### Example CUID File Format ```ini [GPU:0] derived_cuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX vendor_id=1022 device_id=1974 pci_class=0004 revision_id=01 unit_id=0002 device_node=/sys/class/drm/renderD128 last_update=1753987166 [CPU:0] derived_cuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX vendor_id=1022 device_id=1974 revision_id=01 family=0019 model=0074 unit_id=0004 package_id=0 last_update=6980d761 [NIC:0] derived_cuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX vendor_id=1414 device_id=0003 pci_class=0005 revision_id=10 device_node=/sys/class/net/enp131s0 last_update=1753987166 [PLATFORM] derived_cuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX vendor_id=1573 last_update=1753987166 ``` - **GPU:** `device_node` links the CUID to hardware. - **CPU:** `package_id` identifies physical CPU package, akin to the socket. - **NIC:** `device_node` links to the network device. - **PLATFORM:** Only the derived CUID is listed. `last_update` is a Unix timestamp for the last modification. #### Including Primary CUID (Privileged Users) Privileged users can map `primary_cuid` to `derived_cuid`: ```ini [GPU:0] primary_cuid=YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY derived_cuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX hardware_fingerprint=ZZZZZZZZ vendor_id=1022 device_id=1974 pci_class=0004 revision_id=01 unit_id=0002 device_node=/sys/class/drm/renderD128 last_update=1753987166 ``` > **Note:** The file contains sensitive information. Restrict access to `primary_cuid`. ### CUID Tool Overview The CUID tool supports both privileged and non-privileged users: #### CUID Library - Discovers hardware and constructs primary CUIDs. - Generates derived CUIDs via hashing. - Provides APIs for device info and identifiers. #### Command Line Interface (CLI) - Uses the library to detect devices and generate CUIDs. - Allows creation of primary/derived CUIDs (if privileged). - Simplifies device management and integration. ### Build and Install Instructions The below instructions allow the building of the CUID project and also the installation of its files and services: ```sh mkdir build cd build # Set CMAKE_INSTALL_PREFIX as needed (default is typically /opt/rocm/core) # Add -DBUILD_DAEMON=ON to also build the daemon (optional) cmake -DCMAKE_INSTALL_PREFIX=/opt/rocm .. make # Use sudo if installing to a system prefix like /opt sudo make install # Replace with the value used for CMAKE_INSTALL_PREFIX above sudo /share/amdcuid/amdcuid_postinst.sh ``` Both static and shared libraries are built. The post-install script is a unified entry point: it always provisions the HMAC key required by the library, and automatically configures the `systemd` service and `udev` rules if the daemon was also installed. If users need to uninstall the CUID project, they can do so with the following instructions: ```sh cd build # Replace with the value used for CMAKE_INSTALL_PREFIX above sudo /share/amdcuid/amdcuid_prerm.sh sudo make uninstall ``` The pre-removal script automatically stops and removes the `systemd` service and `udev` rules if the daemon is installed, and skips those steps otherwise. The HMAC key and daemon config in `/etc/amdcuid/` are intentionally preserved so that reinstalls keep the same CUID values. To fully purge all configuration, run `sudo rm -rf /etc/amdcuid` after uninstalling. Documentation can be built using the following instructions: ```sh pip install -r docs/sphinx/requirements.txt sphinx-build docs docs/_build/html ``` ### Supported Operating Systems #### Minimum Requirements | Component | Minimum Version | Notes | |-----------|-----------------|-------| | **OpenSSL** | 1.1.0 | Uses `HMAC_CTX_new()`/`HMAC_CTX_free()` (1.1.x) or `EVP_MAC` API (3.0+) | | **CMake** | 3.14 | Build system requirement | | **GCC** | 5.0 | C++14 standard required | | **Kernel** | 2.6+ | Standard sysfs interfaces | | **Architecture** | x86_64 required for CPUID-based CPU fields | Limited fallback via `/proc/cpuinfo` on other architectures | #### Linux Distribution Compatibility | Distribution | Version | Kernel | GLibc | Status | |--------------|---------|--------|-------|--------| | **Ubuntu** | 24.04.4 | 6.8 (GA), 6.17(HWE) | 2.39 | ✅ Supported | | | 22.04.5 | 5.15(GA), 6.8(HWE) | 2.35 | ✅ Supported | | **RHEL** | 10.1 | 6.12.0-124 | 2.39 | ✅ Supported | | | 10.0 | 6.12.0-55 | 2.39 | ✅ Supported | | | 9.7 | 5.14.0-611 | 2.34 | ✅ Supported | | | 9.6 | 5.14.0-570 | 2.34 | ✅ Supported | | | 9.4 | 5.14.0-427 | 2.34 | ✅ Supported | | | 8.10 | 4.18.0-553 | 2.28 | ✅ Supported | | **SLES** | 15 SP7 | 6.4.0-150700.51 | 2.38 | ✅ Supported | | **Debian** | 13 | 6.12 | 2.36 | ✅ Supported | | | 12 | 6.1.0 | 2.36 | ✅ Supported | | **Rocky Linux** | 9 | 5.14.0-570 | 2.34 | ✅ Supported | | **Oracle Linux** | 10 | 6.12.0 (UEK) | 2.39 | ✅ Supported | | | 9 | 5.15.0 (UEK) | 2.34 | ✅ Supported | | | 8 | 5.15.0 (UEK) | 2.28 | ✅ Supported | #### Notes - **LibreSSL** and **BoringSSL** are supported via the HMAC_CTX backend - Root/administrator privileges are required for full functionality (ACPI tables, SMBIOS UUID, PCI config space access) - systemd is only needed for `udevd` reloads and optional service management; the daemon can also be started using other mechanisms such as an `@reboot` cron job ## License Copyright (c) Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.