In “How does firmware get onto the device?”, we learned that every single IoT device is identical after leaving the manufacturing floor. This is different to traditional network security where every computer has unique private keys and unique passwords.
Anything with an Ethernet, WiFi or Bluetooth interface gets a unique MAC address. Theoretically, these could be programmed at test/bringup time. In practice, this is hard to do (manufacturing floors don’t have reliable network access and can’t afford downtime). It turns out that EEPROM vendors will sell you tiny EEPROMs preprogrammed with a range of guaranteed unique MAC addresses, so they just populate the board with one of those. The production process is thus consistent! Many modern CPUs/SoCs/radio interfaces also provide a built-in unique device ID or MAC address, and so we use those.
(There are plenty of Ethernet devices out there that don’t have unique MAC addresses at all; they just generate one randomly and hope for the best. Thirty cents saved. Just sayin’.)
You can script your device to generate its own private keys at first-boot. I know that Raspberry Pi firmware images do this. I don’t know of any production IoT devices do this, probably because it delays bringup by a minute, and on a manufacturing floor, more time means more floor space means higher manufacturing cost.
So, in practice, we have thousands to millions of devices being shipped which have exactly the same private keys and exactly the same hidden passwords.
Remember risk analysis: likelihood of breach times impact of a breach.
For something like an SSL private key, the likelihood is very low. Consider the XBox public key attacks. We’ve got unlimited access to the public keys and hardware and known plaintexts. But without being able to generate that private key, we’re stuck.
If that private key is leaked or reconstructed somehow, the whole system falls apart. People can write their own software and run pirate games. There’s massive impact that would end that product line and most future development for it.
Consider a DVD player. It contains a symmetric encryption key which is shared across that class of players. If one player’s key leaks, the key is leaked for all players using that key. There was consideration given to this in the DVD CSS scheme (new content will not be decrytable using a revoked key), but the impact is still huge. All past content is now decryptable because one device out of billions was compromised. So the likelihood and impact are both fairly high; this is (was) a high-risk system.
Impersonation becomes a real issue. If you’re trying to attack a particular device on a target network (say, a router or a camera), you don’t have to gain access to that exact device. You can buy a device of the same type and attack that instead, in the comfort of your own home/office/dungeon, taking as much time as you like. You can buy a hundred of them and subject them to a range of attacks, including destructive attacks. You can backdoor one of your devices and physically swap it with the target device. And in extreme examples – say the device carries a private key – you can extract the private key from your device and use it to perform crypto-level attacks on the target device.
None of this is possible if each device has its own unique private keys.
Did you put in a reasonable source of randomness? Most embedded devices have no random number source; many don’t even have a clock (which is a weak but tolerable substitute). There’s no point in generating keys on first boot if every device ‘randomly’ generates the same keys because they’re starting from the same state. Manufacturing processes encourage every device to be identical!
Your unique identifier can help a lot. It’s predictable, but at least every device will be different.