Build the SD Locker and Make Your SD Cards More Secure
(Last updated 10 Nov 2013)

SD and SDHC cards have a number of features intended to secure the data stored on the cards.  I'm not counting the write-lock switch on the side of the SDHC cards here.  That "switch" is only a mechanical device intended to provide a hint to the host computer that it should not write to the card.  Nothing in the SD card electronics can sense the state of that slider and there is no way for the card's electronics to enforce your request that the card contents not change.

The first layer of protection enforced by the card is the TMP_WRITE_PROTECT bit in the card's CSD register.  The TMP_WRITE_PROTECT bit allows you to write-lock or unlock the card.  If the TMP_WRITE_PROTECT bit is set, the card's electronics will refuse to modify the data contents of the card, though the data can still be read by the host computer.  You can modify the TMP_WRITE_PROTECT bit as often as you like.

The second layer of protection is the PERM_WRITE_PROTECT bit in the card's CSD register.  As its name implies, this is a permanent write-lock, though the card's data can still be read.  The bit is cleared from the factory and can be set one time only; once set, it cannot be cleared.

The third layer of protection is the PWD (password) register in the card.  This register and its associated PWD_LEN register allow you to set a non-volatile password of up to 16 bytes for the card.  If the password is set, the card will deny any read or write attempt to the card's data unless the host computer first sends a matching password command to the card.  This password protection applies after each power-up; the password must be resent after each power-cycle.  One interesting feature of the password is that it need not be ASCII characters.  You can set a password that is entirely binary (non-printable ASCII), should that be to your advantage.  Refer to Section 4.3.7, Card Lock/Unlock Operation, for more details (Physical Layer Simplified Specification, Ver 2.00, SD Group).

The SD Locker
The SD locker is a small electronic device that provides one-button lock/unlock capability for SD cards, using the TMP_WRITE_PROTECT bit.  The SD locker uses an Atmel ATmega328p microcontroller (MCU) to control the SD card via the SPI bus.  The SD locker is small enough to build into an Altoids can, complete with a pair of AA batteries for a power supply.  Operation could not be simpler.  Turn on the device, plug in an SD card, press the LOCK button to lock the card or the UNLOCK button to unlock the card; done.

You can see the schematic here (PDF).

The SD locker

Here you see the SD locker in its Altoids chassis.  The small, green PCB taped to the top of the SD card socket is a 3.3 VDC boost regulator, available from Pololu.  To the front of the picture are three LEDs; left to right, they are power, UNLOCK, and LOCK

Pushbuttons and LEDs

Here is a closeup showing the tiny pushbuttons (left and middle) and slide switch (far right) used in the design.  Space is really cramped, due to the size of the SD card socket.  The LOCK button is on the left, next to the red LOCK LED.

Although I've been referring to SD cards, the SD locker works equally well with SDHC and microSDHC cards.

I built my prototype SD locker on a piece of Vector perfboard with plated-through holes.  The component placement isn't critical, but space is tight if you want to fit this into an Altoids can.  It helps to use tiny pushbuttons and a tiny slide switch (for power).  I got all of my switches from Pololu, who sells some excellent tiny parts for the robot builder or experimenter.  Besides the switches, I also added Pololu's 2563 3.3 VDC boost regulator, which turns the 3 VDC from the AA batteries into the 3.3 VDC needed by the MCU and SD card.  Note that if you use such a regulator in your device, make sure you only use alkaline batteries to power your device.  If you use rechargeable batteries, such as NiMH, the regulator will run the batteries so low that they may not recharge.

The design includes a 4-pin serial port terminal, so I can connect my SD locker to HyperTerm or another comm program.  I have built a lot of capability into the firmware that uses the serial port for control and for feedback.  Note that the SD locker works just fine without using the serial port.  In fact, you can omit the 4-pin terminal and associated wiring to save space.  If you choose to add the serial port, you will have to provide an RS-232 level-shifter circuit, as the signals on the connector are CMOS level (0 to 3.3 VDC).  You can connect the SD locker to a comm port set for 38.4K, 8N1.

If you are using the serial port, you can use a few one-letter commands to read or modify the SD card.  Use '?' to show several of the card's registers, 'l' to lock the SD card, 'u' to unlock the card, and 'r' to read  and display the contents of the card's block 0.

How it works
When powered up, the device sits in a loop, waiting for you to press one of the two buttons.  When you press either button, the code tries to access the SD card.  If it can't read the card (for example, if no card has been plugged in yet), the code blinks the LOCK LED in an error pattern.

If the code can access the card, it sends a CMD9 to read the card's CSD register.  To lock the card, the code sets TMP_WRITE_PROTECT (bit 12) of the CSD image; to unlock, it clears bit 12.  The code then uses CMD27 to write the modified CSD data back to the card.  Next, the code rereads the CSD register and verifies that the TMP_WRITE_PROTECT bit changed as expected.  Finally, the code lights the LED corresponding to the state of the TMP_WRITE_PROTECT bit.  This means that if either LED is lit, it reflects the state of the TMP_WRITE_PROTECT bit, even if the bit didn't change state for some reason.

Using CMD27 requires the ability to calculate a CRC7 checksum of the data block you are sending to the card.  In my case, I lifted a CRC7 generator function from the Pololu website and used it with no functional modifications; thanks, Pololu!

The code makes no assumptions about the card staying in the SD socket.  Each time you press a button, the code restarts the initialization ritual.  This means you can change the lock on as many cards as you want, in any order, with no fears that the SD locker will get mixed up by the swap.

You can get the source code and a HEX image here.  Note that you will not be able to rebuild this C source, as it uses a lot of my custom UART library code.  If you want to rebuild the source, either replace my UART functions with your own functions, or strip out the UART library calls and use just the pushbuttons and LEDs.

The source code is built on code from various web sources, notably ChaN, of FatFS fame.  I borrowed some of the SD card primitives from ChaN, who did a really cool MP3 player with an ATtiny45 and an SD card; if you haven't seen this project, check it out.

Where to from here?
This code only addresses use of the TMP_WRITE_PROTECT bit to write-lock the SD card.  This makes the SD locker a good choice for use as part of a stealth PC.  Since the image on the locked card cannot be modified by the OS, even if the card is used in an USB adapter, you can boot from the card, do your stuff, then shut down knowing that the image hasn't changed.  This means your boot image is free of cookies, malware, or modified files.

The obvious improvment to this project would be support for password protection.  The simplest method would be to use a single, fixed password for all SD cards.  To do card-specific passwords without having to open up serial port access, the code could read the card's ID register (CID) and build a password from that information.  If you add serial port access for the user, you could allow the user to set the password for each card (as identified by reading the CID), then record the passwords in the MCU's EEPROM.

With password support, you will also need a way to remove any password.  This can be done one of two ways.  If you know the original password, you can change it to be empty (PWD LEN of 0).  If you don't know the original password, your code can use the appropriate SD commands to erase the entire SD card.  This will remove the password, but obviously it will also remove the data.  You can find details on these operations in the SD Association's reference material.