1

I'd like to build a linux kernel that's specific to a given Raspberry, ie. one that won't boot on any other Raspberries. My idea is to bind the kernel to the cpu's serial number bit I haven't found any infos on this topic.

Yes, I know
a) I'd have to build/compile a custom kernel for every device;
b) that exchanging the kernel for a clean one would forgo this piece of "security", but there are keys stored in the kernel which are needed for userland later on which would be unavailable then.

Any "later" stages (ie. checks for a specific serial number once the kernel is booted by some userland tool) do work theoretically but are out of the question here as they could very easily (as in: easier then reverse engineering the complex kernel) be reverse engineered.

Any ideas and pointers are, as always, highly appreciated.

  • 1
    I think you will get more ideas on Ubunut Stack. I know there are ways yo automount encrypted volumes during boot. But the key is is readable. I suspect even if you embed your keys into the kerner somebody can easily extract them too and use them on a clean kernel. This is why DRM is so successful as a web service authenticates the software/device and it lets the the software know if it has access or not, or uses a token or one time access key. So really trying to build a kernel for each Pi will be pointless as somebody will figure out how to get the keys one way or another :( – Piotr Kula Mar 21 '14 at 12:34
  • Thanks for the input (+1 ;), but I'm really not looking into DRM here but rather intellectual property safety. There's code executed later on that's to be protected from being run on some machine but which has to stay on this one machine. I am well aware that it's technically impossible to decrypt something automatically without storing the key somewhere, but I found the kernel to be a rather good storage for keys that are to be available at it#s own runtime only. This might be more of a thought experiment I guess. – Christian Mar 21 '14 at 13:59
  • 1
    You might have better luck by installing a root certificate authority on the device and validate certificate in the software against this. THe only reason I am trying to deffer from kernel compilations is because no big vendors do this either. Google, for example distribute Android with Root certificates against which application are verified to legitimate. Otherwise they would have to compile millions of kernelels everyday which would be madnness. – Piotr Kula Mar 21 '14 at 14:22
  • That still leaves my code open to easy decryption / analysis. I need not to sign but to encrypt some things. I wouldn't even mind if someone would use the Radpberry for any purposes he likes, as long as it doesn't go the oter way 'round: Running this instance of the software on another/man other Raspberries. Think of tokenless "poor man's software security token". – Christian Mar 21 '14 at 15:19
  • 1
    This is really difficult. One way I have seen devices lock codes away is using a SIM card. Yea, it needs extra interface but then you lock each sim card to the serial number of the Pi (like a pin number) So with out serial number (or any other ocmbination of prgramitc and obscured key) you cant get the data on the card. I see these in Sattelite boxes so that Linux, modified by the vendor has to read the card, before it will load the "kernel/image" image. Maybe have a look into that and see if you can repalce the sim card with something in the kernel? – Piotr Kula Mar 21 '14 at 15:24
2

I'm not sure about the CPU serial, but you might have luck modifying the Ethernet module to check the current MAC address against a programmed one. Include that driver in the kernel, and then you should be able to trigger a kernel panic that locks up the device if it doesn't match.

The smsc95xx_init_mac_address function looks promising. Check line 827. Modified version here:

    if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
            dev->net->dev_addr) == 0) {
        if (is_valid_ether_addr(dev->net->dev_addr)) {
            // check against a registered MAC address
            if (dev->net->dev_addr[0] != 0xB8 || dev->net->dev_addr[1] != 0x27 || dev->net->dev_addr[2] != 0xEB || dev->net->dev_addr[3] != 0xFF || dev->net->dev_addr[4] != 0xFF || dev->net->dev_addr[5] != 0xFF) {
                // kernel panic if it doesn't match!
                panic("Invalid device!!!!\n");
            }
            /* eeprom values are valid so use them */
            netif_dbg(dev, ifup, dev->net, "MAC address read from EEPROM\n");
            return;
        }
    }

I've added a check against the MAC address B8:27:EB:FF:FF:FF, which if any one of the 6 portions don't match, will cause the kernel to panic. (dev_addr is a pointer to a u8 array of 6 elements, which is to say six 8-bit integers... the MAC address.)

  • Great idea - plus, it should work on non-Raspian Systems. Thanks for the idea, I'll try this asap. – Christian Mar 25 '14 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.