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).
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
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.
Home