//

,

Read SD Card Serial Number from CID

May 10, 2013

I tried to read the serial number from an SD Card because the number is factory stamped and unchangeable, so it easily could be used to protect embedded firmware from being copied (1). The serial number is stored in the the Card Identification Register (CID) which is read by ‘Command 10′ as stated in the SD Simplified Specifications. One point by doing so is that it is not possible to read the CID if the card is plugged into a USB adapter — you need to have the card plugged into a ‘direct’ SD interface.  Our own iMX233 based development board has 2 of them, so it was an easy task to improve our firmware to read the CID and extract the serial number, but how do I check if I get the correct information?

Luckily the Linux kernel provides the CID via the SD and MMC Block Device Attributes, so you may use a Linux device containing a direct SD interface like your Android phone or an embedded Linux board.  Unfortunately you cannot know the real path of the SD card in the /sys file system  so I can only give some examples and you have to try out the real path yourself.

For example, on my Samsung Galaxy Note running Gingerbread  there is a /sys/block/mmcblk0 soft link pointing to:

So I check the CID using the adb tool from the Android SDK (rooting is not necessary):

On my Olimex iMX233 OLinuXino embedded Linux board I call the following (directly on the board):

You will get a long hexadecimal number which have to be decoded. The information is stored as:

Based on our iMX233 CPU Board it may be easy to build a intelligent USB card-reader supporting for example CID / CSD information and autonomic card tests. What do you think, is there a need for such a card-reader? Your comments are welcome in the comment section below.

Update:

I got a few eMails pointing out that using the CID as copy protection is not a good idea, because there are some cards on the market which are not compliant to the standard. These cards don’t prohibit CMD26 in SPI mode and therefore allow writing the CID. However, I’ve never seend such a card.

Share Button
The following two tabs change content below.
Mike Bergmann is Senior Software Engineer / Senior System Designer at Bones AG. He is currently focusing on design, development and production of ARM SoC based embedded audio solutions.
  • Glenn

    I’ve been unsuccessfully trying to read CID info from SD Card using my netbook (and built-in card reader) with Mint 15.

    Given the plethora of “fake” SD cards, being able to read manufacturer ID, date, CID, and testing cards for capacity.

    Would this be something that can be done as a personal project of mine, built using iMX233 board, or are you suggesting a turnkey package?

    How can I contact you for details?

    • http://blog.bones-embedded.ch/ Mike Bergmann

      Hi Glenn, sorry for the late reply.

      Maybe your card reader is attached internally via USB and therefore will not work. I’ve good results reading CID with several iMX233 boards. If you want to read CID only from micro SD cards you can use the OLinuXino Boards by Olimex. If you want to read the CID of standard SD cards you may use the original iMX233 dev board by Freescale or our Bones Audio Dev Board.

      Btw: Bunny has a great post about fake SD cards and CID on her blog:
      http://www.bunniestudios.com/blog/?page_id=1022

      For further questions you may use this comment section or private mail via mike[at]bones[dot]ch

      • Kyle

        I have an application where I need to read CID from microSD cards and generate a license file based on the number. Looking at the OLinuXino board, I assume the microSD card contains the Linux OS, where as I need a dedicated slot to insert and remove microSD cards formatted as FAT. Any thoughts?

        • http://blog.bones-embedded.ch/ Mike Bergmann

          Hi Kyle,

          if you want to use the OlinuxXino board you may use a custom firmware running solely from RAM reading the CID (like we do). Another way may be to configure your Linux distro the way it runs completely on initrd not using the SD card filesystem for rootfs.

          There are some boards with 2 SD cards on the market like the Freescale Dev Board or our Bones Audio Dev Board, others using a NAND to start from like the SK-iMX233.

  • STeve

    HI Mike

    Thanks for the info, very very useful.
    I have however a problem and maybe you can point me in the right direction.
    I’m trying to read the CID on a SD card plugged in a Sheevaplug.
    The Sheevaplug has a SD card reader, not an USB one.
    At the location in your example I can actually read something, but I’m not sure is a CID.
    I say so because I tested different SD cards with on a Linux distribution (Debian Wheezy). On some of them, using your method to read the CID, I obtain the same identical number.
    However during the boot, the boot loader shows the SD card serial number and it is different for each card.
    So, I have to assume that the CID field in the Linux distro (/sys/block/mmcblk0/device/cid) is not correctly assigned. Do you have some more info about how the /sys/block/mmcblk0/device/cid field is assigned ?

    STeve

    • http://blog.bones-embedded.ch/ Mike Bergmann

      Hi Steve,

      I tried it on our board with Linux (Kernel 3.12) as well as with our own software and getting the same numbers per card and always different numbers for different cards.

      I took some screenshots:

      Linux: http://blog.bones-embedded.ch/wp-content/uploads/2013/12/Linux_CID.jpg

      Own: http://blog.bones-embedded.ch/wp-content/uploads/2013/12/Own_CID.jpg

      The Linux kernel code reading the CID is located within:

      int mmc_send_cid(struct mmc_host *host, u32 *cid)

      file:

      driversmmccoremmc_ops.c

      and is called during the initialization of the card.

      I hope this is of some help.

      Btw. I’m very interested in you findings, so I’ll be very happy if you share them in this thread.

      Thanks
      Mike

      • STeve

        Hi Mike, thanks !!

        The Debian distro I’m using on the Sheevaplug has a 3.2.0-4 kernel (here the uname -a return : Linux tsiserver 3.2.0-4-kirkwood #1 Debian 3.2.51-1 armv5tel GNU/Linux.

        I’ll try to follow the initialization operations.
        Just to be sure .. when you say “during the initialization of the card”, are you referring to the “preparation of the SD card”, i.e. when you load the distribution on the SD card, or are you referring to an operation performed every time the kernel starts ?
        I’m asking that because the final purpose is to be able to “clone” an SD card from a generic image (copied from a generated SD card).
        i.e. I need to avoid to spend two hours every time I need to install the distro on a Sheevaplug.
        Initially I though that when cloning the SD card the CID was cloned as well, but then I noticed that the bootloader was always reporting a different serial number for each SD card used.
        So I’m sure each SD card has a different CID, but cloned cards reports the same CID in the /sys/block/mmcblk0/device/cid field.
        Since the /sys/block/mmcblk0/device/cid field is built runtime I have to discovery the reading mechanism.

        Sure I’ll report any progress (or failure) here.

        Thanks
        STeve