Unique ID of an embedded system running Yocto - c++

I have an embedded system running Yocto. The MAC address is not stable (it is random one that changes at every restart). The CPU ID is the same for all devices of this embedded system model.
What other options should I look for to use as unique ID of the system? I need a unique ID for licensing purposes. I should retrieve this ID from an C++ Application.

try to ask Intel if they have space on the MCU, we usually store our MAC Address, Serial number, as well as ddr configuration there; This can be a one time flash.
After you have confirmed the address; You could use smbus to write the serial number into that space and retrieve it later;
This is a better way than UUID because the serial will always be there even after you have delete everything;
By the way, if the MAC Address is random, it is most likely because there are no MAC Address flashed into the system.
Again, ask Intel on how to flash your own MAC Address into the system. This might eliminate the need to create another serial number;

Related

Is there a way to reliably get the MAC address of an onboard network adapter in Windows 10 with C++?

I'm looking to reliably retrieve the MAC address of the onboard network adapter for any machine running Windows 10 using C++. However, when I plug in an external network adapter (in this case a USB to ethernet device) I've found that my code will sometimes read the MAC address for this device instead of the onboard one.
I've been using the GetAdapterInfo function, iterating over the list of adapters and using the index from the IP adapter info structure to pick the earliest one as this article led me to believe that the adapter with the lowest index would be an onboard one (though the author does note that they can't find a reliable source for this).
I did notice this in the description for the index field in the IP_ADAPTER_INFO structure:
The adapter index may change when an adapter is disabled and then enabled, or under other circumstances, and should not be considered persistent.
So maybe that indicates that I can't necessarily trust this index value.
I have also looked over the GetAdapterAddresses function, but it doesn't look like I'll get a better network adapter index from the list that this returns.
Any help/insight would be much appreciated. Thanks!

Returning Device GUIDs and Bios ID, C++, Linux

I am trying to write a function to return all the GUIDs of the devices attached to the machine, as well as returning the BIOS Id. How would I achieve this? I can only seem to find ways of doing it on a windows machine, but not a linux.
Linux does not assign a GUID to everything. Hardware is identified by hardware-native means, e.g. USB and PCI devices are identifies by vendor and device ID (and serial number).
You can see what data the kernel offers by browsing /sys. I'd also check the source of tools like lspci and lsusb to get an idea on how one retrieves data programmatically (i.e. without parsing files in /sys).
There is, by the way, also a tool called dmidecode, that does operate directly on DMI data.

Linux Equivalent of MachineGuid

I have program that needs OS installation fingerprint like one in MSW stored at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid
In Microsoft Windows I have it ready for me but I cannot find equivalent for Linux. Is there anything close to this in Linux? I will not have root access so anything like dmidecode -s system-uuid becomes out of the question.
An example will be nice but no necessary.
One possibility would be to read /etc/ssh/ssh_host_{d,r}sa_key.pub, which are readable by all, and are randomly generated during installation.
Obviously the problem is that those files may not exist at all, if there is no SSH (server) installed. They are also often copied from an older installation.
I believe MAC addresses are not a good choice for identifying a machine. There are many USB dongles which may be plugged into a PC to provide a mobile/3G/H+/etc. network interface, so while such a dongle is plugged into the machine, it will have a different id derived from available network interface MAC addresses.
Is /etc/machine-id (/var/lib/dbus/machine-id) available on your target system?
see: http://man7.org/linux/man-pages/man5/machine-id.5.html
see: http://0pointer.de/blog/projects/ids.html
The canonical Unix'y answer is the Host ID, but in practice, this often ends up falling back on a hash of the IP address…
#include <unistd.h>
long gethostid(void);
int sethostid(long hostid);
DESCRIPTION
gethostid() and sethostid() respectively get or set a unique 32-bit identifier for
the current machine. The 32-bit identifier is intended to be unique among all UNIX
systems in existence. This normally resembles the Internet address for the local
machine, as returned by gethostbyname(3), and thus usually never needs to be set.
NOTES
In the glibc implementation, the hostid is stored in the file /etc/hostid. (In glibc
versions before 2.2, the file /var/adm/hostid was used.)
In the glibc implementation, if gethostid() cannot open the file containing the host
ID, then it obtains the hostname using gethostname(2), passes that hostname to geth‐
ostbyname_r(3) in order to obtain the host's IPv4 address, and returns a value
obtained by bit-twiddling the IPv4 address. (This value may not be unique.)
I assume you're trying to do this because you want to "lock" the software to a specific piece of hardware?
One option is to use the MAC address of a network interface to identify the current machine. The MAC address is fairly easy to get at, see this Stackoverflow question.
This nicely works around issues with changing IPs etc as the MAC address of an interface is much less likely to change unless someone replaces the network card.

Uniquely identify PC based on software/hardware

For a requirement to generate per-PC license keys, I need some code which will return a stable and (near) unique key on any PC. It doesn't have to be guaranteed unique, but close. It does need to be reasonably stable though, so that a given PC always generates the same result unless the hardware is substantially changed.
This is for a Windows application, using wxWidgets but a Win32 or other option is fine.
I was thinking about MAC address but what about laptops which can routinely disable the network card in power-saving mode? I came across GetCurrentHwProfile but it doesn't quite look like what I want?
One idea I had a while back for this is to use CryptProtectData as a way to identify a machine. Behind-the-scenes in that API, Microsoft has done what you're looking for. I never tested it though and I'm curious if it's actually viable.
Basically you would encode a constant magic value with CryptProtectData with CRYPTPROTECT_LOCAL_MACHINE, and the result is your machine ID.
I would just go with the MAC address method; when the wireless / LAN cards are turned off they still show up in Network Connections. You should therefore still be able to get the MAC.
Consider this: Any time you'd be able to contact your webserver or whatever you're cataloging these IDs with, the user is going to have to have some form of network card available.
Oh, and you might be able to use CPU serial number of the customer's computer supports it.
I think there no really easy and unique method so far discovered here.
GetVolumeInformation retrieves not even close to unique ID.....
To use any hardware serial is problematic because manufactures are not committed to supported it always and especially to keep it globally unique
GetCurrentHwProfile retrieves GUID but it's value affected by minor! hardware changes...
Using Product Key ... will bring U to deal with the stolen software - there lot of pirate installations over the globe.
Creation of own GUID and preserving it under registry (in any place) will not prevent duplication by cloning of image ....
etc...
From my perspective of view the best way is combine:
Volume ID + MAC's list + Machine SID + Machine Name. And obviously manage license policy on the server side ;0)
Regards
Mickel.
If you want something a bit harder to spoof than whatever the machine itself can tell you, you'll probably need to provide a USB dongle dedicated for this purpose (not just a flash drive).
For a pretty brain dead test I am using the ProductID code of the OS and the computer name - both extracted from the registry. Not really secure, but its all pretend security anyway.
edit
To answer John's question about what keys I am reading:
SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID
SYSTEM\CurrentControlset\Control\ComputerName\ComputerName\ComputerName
How about using the serial number of the harddisk where windows is installed?
The function GetVolumeInformation() will give you such serial number.
To access the ID assigned by the harddisk vendor instead of the ID assigned by Windows, you can use the Win32_PhysicalMedia Class.
To determine the drive where windows is installed, you could expand the variable %windir" by using the function ExpandEnvironmentStrings()
Another option, if your architecture allows, is to use UuidCreate() to generate a random GUID at installation time and save it permanently in the registry. This GUID can then be used as the ID as long as the registry remains. A new registry database is generally considered as a new installation.
A third option is to have a well-known server assigning the IDs. Upon starting up, the software could look up for the ID in the registry and if not found, would contact the server and supply it with its MAC address, hostname, harddisk serial number, Machine SID and any number of indentifyable information (keys).
The server then determines if the client is already registered or not based on the information given. The server could have a relaxed policy and for example only require most of the keys for a match, so that the mechanism would work even in the event of a complete wipe out of the registry and if part (but not all) of the hardware was replaced.
How about using the serial number of a CPU. I remember Microsoft used to provide an api for this that would run the necessary assembler code and give you back all sorts of info about the CPU including serial number. Not sure if it'd work with AMD chips or not, I think it was intel specific.
Surely CPU Id is secure and static enough!!

Restrict application usage

I would like to restrict people using my application to one Computer, so I was thinking about IP's.. but people in some countries get new IP's after they reboot their Internet.. so I need something better to identify the users, like some value that doesn't change until the user performs a format.
Thanks
The MAC address of e.g. an ethernet interface typically doesn't change even across formats (only if the user changes ethernet interface card). Don't worry, nothing to do with Apple Macs, MAC stands for Media Access Control;-).
You will probably need some registration process, so you could tell the user that you will connect to get some update, and in that process send the serial number of the application and the mac address. If the serial number has already been registered then return an error to the user.
Ideally you should perhaps download some needed dll that is tied to a specific serial number and perhaps mac address, so that if the user copies the dll to a different program it will require more work to get it to work.
It depends on how much you want to inconvenience the user as to the best approach, I believe.
Where I specified dll could be any assembly, jar file, etc, that the language in question uses for running the application.