NEW: This is the first Desfire project that has ever been written for Arduino/Teensy!
With very few changes you can also compile the code on Windows, Linux or other platforms. |
About Burglars
Recently the Spiegel published an article about burglars in Germany:
- Burglars prefer the dark months. In december the insurances report 3 times more housebreakings than in july.
- The police reports that it is very difficult to find the delinquents. Mostly there are no witnesses and no traces. Only in 2,6% of the housebreakings the culprit can be condemned.
- Burglars do not only break into houses of rich people. Everybody can be the victim. In nearly every house they find handies, laptops or money in cash. Especially drug addicts chose houses in their near environment.
- According to the experience of the police the best prevention is a mechanical protection at doors and windows and attentive neighbours. Mostly burglars try only 2 - 3 minutes to break into a house. But in 60% of the cases they are successful.
- This article tells that the German police observes that more and more housebreakings are organized by professional gangs from Serbia, Romania, Turkey, Albania and Georgia. These people apply for asylum and travel through different countries of Europe to do just one thing: steal.
- There is also another article with a map of Germany that shows the cities where the majority of housebreakings take place. The police counted 152.000 cases in 2015 - tendency increasing.
The majority of door locks is highly insecure
Does your door lock protect you against burglars ?
If your key looks like this one:
it surely does not.
Your door can be opened within a few seconds and you don't even notice that someone has entered while you were not at home, because there is no damage, neither at the door nor at the lock. Also your neighbours will not hear anything because lockpicking is absolutely silent.
You don't believe that ?
Then watch this video:
As you have seen: Lockpicking is very easy.
A thief does not even need special tools. He can open your lock with two hairpins!
When you search for "lockpicking" on Youtube you will find 169.000 results.
With electrical vibrators (pick gun) it takes less than 10 seconds to open a lock as you see in this video.
Even for cross locks there are special lockpicking tools that open a lock in 10 seconds as you see in this video.
Better mechanical locks
There are better locks where the key has round holes instead of notches like this KESO 2000 key.
These locks are very expensive. Nevertheless they can also be opened by lockpicking, although it may take 3 minutes to open them as you see in this video.
Finally locks can be broken with a big plier or opened with a drill as you see in this video.
Conclusion: You will not find a mechanical lock that is really safe.
Copying of keys
If you rent a flat, your tenant can make copies of the key and give them to other persons. So he can sublease your flat. And if he leaves some day and you want to rent the flat anew, you have to change the lock because otherwise the previous tenant can still access the flat.
Electronic door locks
The advantage of an electronic door lock is that the above security issues do not apply.
It is much better to have a safe door lock which prevents that the thief can enter than to have an alarm system which makes noise when the thief is already in. Until the police arrives he will be gone and probably some precious things will be missing. Secure locks are always better than alarm systems or cameras.
What are the options on the market?
I searched for an electronic alternative, but what I found did not satisfy me:
- There are fingerprint readers, but I did not find a waterproof one, so not usefull for outdoor installation. Additionally you expose an electronic device to the street which a malicious person might destroy easily.
- There are these electronic door locks that you probably have seen in hotels, that open the door with a card.
But these are for indoor installation only and they depend on a tiny battery in the lock that soon will expire. - None of the electronic solutions that I found will work when you have a power failure because they all lack a powerfull backup battery. A lock that does not open in case of a power failure is useless.
- Mostly the electronic solutions are much too expensive.
My project
So I designed my own solution with the following characteristics:
- Designed for the main door of the building: No electronic device is exposed to the street or to the rain. You just mount an RFID reader on the inside of the door which reads the RFID card through the closed door.
- There is nothing visible from the outside of the door that could be manipulated by an intruder.
- A powerfull backup battery assures that the device is working even during a power failure of more than one week.
- The processor checks the battery voltage and alerts if it is out of range.
- The processor checks if the battery is old and alerts when the battery must be replaced.
- Provides a very easy to use interface accessible through an USB cable with a terminal program which lets you add or remove users within a few seconds. Even a computer beginner can manage the user authorization quickly.
- You can store 64 users with their cards in the EEPROM of the microprocessor. More then 64 users are possible by modifying the source code.
- The access to the terminal interface can be protected with a password.
- If you or your tenant loses the RFID card, you can easily delete the card from the EEPROM without having to change the mechanical door lock.
- I designed a layout for the board that can be soldered by an electronics beginner.
- The entire solution is cheap compared with commercial solutions.
- Supposed that you have a secure door that cannot be opened with a crowbar, this solution is much cheaper than any insurance that you pay your entire life. I don't pay any insurance anymore.
- The entire project has been designed and tested by a very experienced hardware and software engineer.
RFID cards and tokens
What will replace your mechanic key?
You can either chose an RFID card or a token like these:
The cards are sensible to bending so you should not carry them in your pocket because they may break.
Other names for tokens are "tag" and "keyfob".
Each RFID card or token has a unique ID number, which is assigned by the factory and which cannot be modified afterwards. There are cards (like Mifare Classic) that have a 4 byte ID which allows 2^32 possible ID's and other cards (like MIFARE Desfire) that use a 7 byte ID which allows 2^56 possible ID's: Far more than any mechanic key will ever have.
My project supports any 13,56 MHz cards that comply with the smartcard standards ISO 14443 A and B, or ISO 18092. More details in Wikipedia.
You can compile the source code for two possible operation modes:
- For Mifare Classic cards: In this mode only the ID of the card is used to recognize a user and open the door. (not recommended)
- For Mifare Desfire cards: In this mode a cryprographic key of 128 bit or 168 bit protects the access to your door.
But even in Mifare Classic mode a brute force attack is impossible because the attacker does not know your card ID, which means that he would have to try 2^32 or even 2^56 possible card ID's. This is not possible because the code running in the Teensy makes a delay of 1 second after an invalid trial to open the door. The attacker would not live long enough to test all possibilities because this would take 140 years.
Mifare Classic Cards
It would be possible to store a secret value on the Mifare Classic cards and protect it with a key. But this does not make sense because the encryption of Mifare Classic has been broken. When Philips designed the Classic cards they made the error to implement a weak cryptographic algorithm (Crypto-1) and trust in "security-through-obscurity". The reason that these cards are so wide spread (over 4 billions sold) is that the algorithm has been kept secret for 14 years. But in 2008 a research team analyzed the chip under a microscope and the algorithm implemented in hardware could be deduced. They found that the key is a 48 bit key with several design flaws. You find more details in Reverse Engineering Mifare Classic cards.pdf in the ZIP file. The result is that today Mifare Classic cards can be cloned in a few seconds including all the data stored in the EEPROM even if the data is protected with a key.
Normally the unique ID of a RFID card is assigned in the factory and cannot be modified afterwards. But on eBay you can buy chinese clones which allow to write any ID to the card. (Search for "UID changeable card")
So it would theoretically be possible that a malicious person reads your Mifare Classic card through your pocket and clones it to get access to your house. This could be done with an Android NFC application that communicates with RFID cards. There are also devices like the Tastic RFID Thief which can read RFID cards from a distance of half a meter. So if you decide to use Mifare Classic cards you should buy a Stainless Steel Wallet which has a metal shield that blocks any external RF frequency getting to your card, so cloning your card becomes impossible:
Old Mifare Desfire Cards
In 2002 Philips introduced the Desfire cards which do not rely on a proprietary algorithm anymore. Desfire uses (as the name says) DES encryption. However for the first generation of Desfire cards an attack has been published that allows to obtain encrypted data from the EEPROM by a Side Channel Attack. With a complex hardware the power consumption of the card is measured during the encryption process. But this attack is far more difficult than the Mifare Classic attack and takes about 7 hours.
You find a video on Youtube where Timo Kaspar from Ruhr University in Bochum, Germany explains (in english) how they hacked the old Desfire cards. At 18:20 minutes he starts speaking about the Desfire attack and how they extracted all the encryption keys from the card, but the rest of the video is also very interesting.
You should not use the old Desfire cards anymore. My project does not support them because they require legacy authentication which is not implemented.
Mifare Desfire EV1 Cards
In 2009 the next generation came on the market: the Mifare Desfire EV1 cards which have been improved once again and until today no attack is known. So if you use Desfire EV1 cards you do not need a Stainless Steel Wallet.
Buying Desfire EV1 cards is more difficult. There are not so many offers and the cheaper ones require that you buy quantities of 50, 100 or even 500 cards. I found these two companies which sell also smaller amounts: RyscCorp and Smartcard Focus. You can also order from Smartcard America who sell via eBay but their shipping is very expensive to other countries.
Be carefull with counterfeit offers from China on eBay: There is no guarantee that chinese clones fulfill the same security criteria as original NXP cards.
Mifare Desfire EV2 Cards
EV2 cards are improved EV1 cards. They have extended functionality and a reduced power consumption. I did not test EV2 cards on my own. But users have reported that they use EV2 cards from Karteo or ZutrittsShop and that they can even read them up to 8 cm distance with the reader from Elchouse or Paradisetronic which has a smaller antenna than the Adafruit reader. The version V4 from Elchouse has an improved PCB design for larger reading distance.
NOTE: The card which is shipped with the Elchouse Reader is not a Desfire card.
Keyfobs
I ordered MIFARE Desfire EV3 keyfobs from Yarongtech on Amazon because they were relatively cheap (10 key tags for $30). But they are useless. Already at a distance of more than 2 centimeters they cannot be read anymore. The only key fobs that work well are Desfile Classic, but these are not secure.
Comparison Mifare Classic <-> Desfire
| Mifare Classic | Mifare Desfire EV1 |
Unique Identifier | 4 bytes
UID can always be read without encryption | 7 bytes
UID can always be read without encryption in normal mode, but requires the PICC master key in random ID mode. |
EEPROM Storage | On a card with 1kB memory:
16 sectors of 4 blocks of 16 bytes each
(Blocks and sectors have fixed size) | Up to 28 applications of which each can contain up to 32 files of variable size |
Keys | Each sector can be protected with two keys (key A and key B) with different permissions per key | Each application can be protected with up to 14 different keys with different permissions per key |
Encryption | Proprietary (Crypto-1, 48 bit) | DES (56 bit), 2K3DES (112 bit), 3K3DES (168 bit), AES (128 bit) |
Security | Encryption has been cracked in 2008 | No attacks known today |
While Classic cards are completely static, the Desfire cards store data in "files" of dynamic size that are contained in "applications". What is an application? An application is nothing more than a container for files.
Imagine a RFID card issued to the students of a university.
With the same card the student can eat in the canteen and he can park his car.
In this example there would be two independent applications on the card: One canteen application and one parking application.
The student can charge money for lunch and for parking which is stored in a file in the corresponding application.
Each application has one or multiple encryption keys (the application keys) which allow to change the value stored in the respective application.
Each key may have only read permission, only write permission or both.
Additionally the card has another important key: The PICC master key, which is the "god key".
The PICC master key allows to create and delete applications, assign keys to each application or even format the entire card. But interestingly the PICC master key can NOT access the data stored in the applications.
Neither the canteen nor the parking deck know the PICC master key.
They have only access to their corresponding application but not outside of it.
The RFID reader
The PN532 breakout board from Adafruit (USD $40) has a chip from NXP (former Phillips).
When you order this board, it ships already with a white MIFARE card.
The board has a size of 12 cm x 5 cm and a thickness of 3 mm.
It works internally at 3,3V, but can be fed with 5V.
This board does not only read Mifare cards. It reads also your biometric passport, FeliCa cards and does NFC (Near Field Communication). It also communicates with Mastercard and Visa which have RFID integrated (PayPass, PayWave, ExpressPay), Calypso and many more...
The major advantage of this board over other hardware is that the antenna (printed on the board) is very big (size of a RFID card). This allows larger read distances than other hardware with smaller antennas.
Adafruit says that the antenna detects a card from a distance of up to 10 cm.
This is true for the white Mifare Classic card that ships with the board.
But I have another card (from public transportation) that requires 7,5 cm to be detected.
And I have a token that requires 5,5 cm to be detected. (The antenna in a token is smaller than the antenna of a card)
For Desfire EV1 cards the maximum distance despends on the encryption, because encryption increases the power consumption of the card:
- If compiled in Classic mode (no encryption used) the distance can be up to 6,3 cm.
- If compiled in Desfire mode with DES encryption the distance can be up to 5,3 cm.
- If compiled in Desfire mode with AES encryption the distance can be up to 4,0 cm.
UPDATE: Please read about EV2 cards.
Additionally I measured that the card consumes more power the more memory it has.
A 4 kB card can be read from a larger distance than an 8 kB card. The difference is approx 5 mm.
As my project occupies only a few bytes of the card's EEPROM you should buy the smallest cards that you can find.
You mount the breakout board on the inside of your door.
You can mount a plastic or wooden box on top of it to protect it from mechanical damage.
Into that box you also mount a two-color LED (red / green) that always shows if the system is working properly.
A long flat cable connects it with the main board.
Here you see a foto of the breakout board with the flat cable and the two-color LED connected:
First you must solder two jumpers on the board that define the communication mode.
I2C is too weak over a longer cable because I2C is an open collector bus with pull up resistors.
I use SPI communication with a low speed of 10 kHz.
So you must set the jumpers: SEL0 = OFF and SEL1 = ON.
Read Wikipedia about SPI and I2C.
Intentionally I do not use any plugs here because a soldered connection is much more secure on a door, that may be slammed.
ATTENTION:
If you think that you can safe money by buying a much cheaper PN532 board from China like the one at the right you are wrong. These boards are offered in many places but do NOT work with Desfire cards.
The antenna of these boards is too tiny (4cm x 4cm) to send enough HF energy to the card. The result will be that you see TIMEOUT errors at the moment when authenticating.
If you use EV1 cards you must order the PN532 board from Adafruit otherwise you will waste your time and money. You may try the small Chinese boards only if you use EV2 cards, but I have no experience with them.
Please read about EV2 cards.
Using I2C Bus
The PN532 can also be controlled over the I2C Bus instead of SPI.
A user has reported that he gets TIMEOUT errors at the moment when authenticating with I2C.
He says the reason is that the Arduino library defines a buffer of only 32 bytes which is too small.
I cannot prove if this is correct, but I publish his information here.
Search the files Wire.h and Twi.h in your Arduino installation folder. There may be multiple.
In Wire.h change
#define BUFFER_LENGTH 32
into
#define BUFFER_LENGTH 64
In Twi.h change
#define TWI_BUFFER_LENGTH 32
into
#define TWI_BUFFER_LENGTH 64
The cable connection between the boards
Between the breakout board (mounted on the inside of the door) and the main board (that you put in a safe place near the door) there is a longer cable required. I use a flat cable of 10 wires.
If you don't want to use a flat cable you can also use a network cable. But network cables have only 8 wires. In this case you can mount the LED at another place (not on the door) and you will need only 8 wires.
SPI buses run normally with speeds of several Megahertz. This cannot be transmitted over longer cables. So I use SPI at a speed of 10kHz. Even over a cable of 3 meters the signals look absolutely clean on the oscilloscope. I suppose that even 10 meters would work without any problem.
When using Defire cards you could even attach an SPI spy to the cable but you will never see a cryptographic key transmitted over the cable. During authentitacion only encrypted random values are transferred and during a key change the new key is sent encrypted with the secret session key that never leaves the Teensy.
Teensy 3.2
The heart of the main board is the microprocessor. I use a Teensy 3.2 from PJRC.com.
Teensy has several advantages compared with other Arduino-like boards:
- It is very fast (32 bit ARM processor running at 96MHz)
- It is very tiny (3,5 cm x 1,5 cm)
- It has more RAM (64 kB) and flash program storage (260 kB) than other boards and it has an EEPROM.
The newer Arduino boards (Due, Zero, 101) have no EEPROM at all, which makes them useless. - It is cheap (USD $20)
- The power consumption is low.
- It works internally at 3,3V, but can be fed with 5V.
- The Teensy library (TeensyDuino) has more and better functionality than the offical Arduino libraries.
First you must destroy a tiny jumper on the bottom side of the Teensy with a cardboard cutter.
Otherwise the 5V coming from the USB cable would be connected directly with the 5V power of the main board.
This would result in a current flowing if the main board is turned on while the computer is turned off or vice versa.
ATTENTION:
If you think that you can safe money by buying a much cheaper Arduino board you are wrong. These boards do not have enough memory.
When you compile the sketch for Teensy you get this output from the compiler:
This means that the sketch requires 11% of 64kByte = 7,6kB of RAM alone for the global variables. Additionally more RAM is needed for the stack which stores the local variables. This additional amount of RAM is dynamic and cannot be calculated previously. The Arduino Uno has a ridiculous RAM of 2kB. The sketch does not even run on the Arduino Mega which has 8kB RAM. You must buy a Teensy 3.2 with 64kB RAM or you will waste your money and your time. When you run the code on a board with insufficient RAM, the consequence may be errors, crippled messages in the terminal or even crashes. You notice a crash when the board does not respond anymore. The LED stops blinking.
The Battery
To assure that the door opens even during a power failure I use a 12V lead-acid stationary battery (deep cycle battery). The battery delivers the high current (1..2 Ampere) required to open the door.
If there is a power failure, the battery can keep the system working for more than one week.
The electronics holds the battery voltage permanently at 13,6V. At this voltage (the so called "float charge") the battery has the longest life. If the battery would be charged and discharged in longer intervals the life would be shortened.
A too high voltage (> 14,4V) results in grid corrosion of the positive electrode.
A too low voltage results in sulfation on the negative plate.
At 13,6V the battery has a very high impedance. When you unplug the power supply you will see that the voltage falls quickly (within 2 minutes) from 13,6V to 12,8V and then very very slowly to 12,0V (within several days). This is normal.
This diagram shows the charge state of a lead-acid battery which can be directly deduced from the voltage.
You see that at 12,8V the battery is 100% full.
There are different types of lead acid batteries:
There are different technologies of lead acid batteries:
If you want to learn more about batteries have a look at batteryuniversity.com.
I use a stationary, deep cycle AGM battery with 15Ah (USD $30). 12Ah is also sufficient. The size is 94 x 151 x 98 mm. This battery is MF (Maintenance Free) which means that it will never be necessary to fill destilled water into it as in the good old days. When you buy it, it comes already charged and sealed.
As the content of the battery is not liquid, it is possible to mount the battery in any position. You can lay the battery on the back side and mount the main board on top of it to save space.
Lead-Acid batteries don't like high temperatures and you should store them only in charged state, otherwise their life is shortened.
Be very carefull with the battery! If you produce a shortcut, the current that flows will be more than 100 Ampere! Anything between the poles will convert into a cloud of smoke!
IMPORTANT: Lead is toxic. An old battery must be recycled.
The Main Board
When the relay switches the door opens. The relay is activated for 100 ms (the interval can be configured in the source code).
The second relay is optional and is missing in the diagram to keep it simple. But you find it in the board layout (see below).
The transformer has just the power to charge the battery. The battery should not be charged with a current higher than 10% of it's capacity, otherwise the lifetime would be shortened. For a 12Ah battery this results in a maximum charging current of 1,2A which is more than the maximum current of the 7815, so it will never be reached. A 16V transformer delivers a peak voltage of 16V * √2 = 22,5V. When the battery is very empty this voltage may collapse.
The 7815 is a voltage regulator with the following characteristics:
Min. Input Voltage: | 17,5V |
Max. Input Voltage: | 35V |
Output voltage: | 15V |
Max Current: | 1A |
Voltage Drop (at 1A) | 2V |
Shortcut Protection | yes |
Overheating Protection | yes |
When the battery is full the 7815 only delivers the current for the Teensy and the PN532 (average 46 mA). Only after a long power failure more current will flow into the battery. So normally the 7815 will not become hot and a cooler is not necessary. If you have long power failures in your country a cooler is recommended. In the photo above you see a cooler (aluminium plate) which is used for both, the 7805 and the 7815.
When the processor detects that something is wrong with the voltage (< 13,0V or > 14,0V) the red LED will flash to show that there is a problem. The cause may be a power failure or a defect.
When the processor detects that the battery voltage drops more than 1 Volt when the door is opened this means that the battery is old and must be replaced soon. A new battery can deliver several Amperes without voltage drop. But the older the battery gets the higher becomes its impedance. When the battery must be replaced the red and green LED flash alternatingly.
The resistor marked with a yellow exclamation mark acts like a fuse. In case of a shortcut (e.g. in the 7805) it will die and avoid that more than 100A flow through the circuit. This resistor should be 1/4W.
Parts List
- 1 x Adafruit PN532 (comes with one Mifare Classic card)
- 1 x Teensy 3.2
- 1 x Stationary battery 12V, 12Ah or 15Ah (see chapter about battery)
- 1 x Breadboard 13,5 cm x 11 cm
- 1 x 7805
- 1 x 7815 (optionally with a cooler if your country has long power failures)
- 1 x BC546
- 1 x 1N4148
- 2 x BY255
- 1 x Relay: Solenoid 12V, Switch 220V, 16A
- 1 x Two-color LED with 3 pins (red / green)
- 1 x Rectifier at least 80V, 1A or better 400V, 3A for a very long life
- 1 x Transformer 16V (or 15V) and 0,25A (up to 0,5A)
- 1 x Fuse 30 mA
- 1 x Fuse socket
- 1 x 0,22 Ω, 1/4W (not more, not less)
- 2 x 820 Ω, 1/4W
- 1 x 10 kΩ, 1/4W
- 1 x 220 kΩ, 1%, 1/4W
- 1 x 15 kΩ, 1%, 1/4W
- 1 x Rx (see next chapter)
- 1 x 100 nF, 63V (not more!)
- 1 x 330 nF, 63V
- 2 x 1 µF, 50V (Electrolyte has a longer life than Tantal)
- 1 x 10 µF, 35V (Electrolyte has a longer life than Tantal)
- 1 x 1000 µF, 50V
- 1 x Header, 10 pin, male, with gold contacts
- 1 x Shrouded Box Header, 10 pin, female, with gold contacts
- 1 x Long flat cable of 10 wires
- 1 x Long 2-wire cable for door opener (for 2A current)
- 1 x Power cable with power plug
- 1 x Thick copper cable, 1 mm diameter, red (for battery)
- 1 x Thick copper cable, 1 mm diameter, black (for battery)
- 1 x USB micro cable
- 1 x Heat shrink tube, diameter 3 mm, length 20 cm (for LED)
- 2 x Screw M3 + nut + washer (for transformer)
- Additional Mifare cards or tokens
If you want to open 2 doors independently you need additionally:
- 1 x Relay: Solenoid 12V, Switch 220V, 16A
- 1 x 1N4148
- 1 x BC546
- 1 x 10k Ω
- 1 x 330 nF, 63V
If you want to open the door from inside without card you need additionally:
- 1 x 1 µF, 50V
- 1 x 1kΩ, 1/4W
- 1 x push button
If you don't have a local electronic shop you can order everything in this list from DigiKey or Farnell or TME or Newark which are very good online mail-order sellers offering hundreds of thousands of electronic parts.
The Board Layout
In the ZIP file you find my design for a single layer breadboard to be soldered manually. This board is very easy to solder even for electronic beginners. It took me only half a day to connect everything.
On the board you see two relay. The upper relay is optional. It allows to open two doors independently. If you don't need that you can omit the green parts.
How to calculate Rx
The resistor Rx limits the current through the door opener solenoid which you see in the picture below.
Here you see the lock opened (bottom plate removed).
I mount this lock on top of the inside of the door. I removed the former key lock so there is nothing that can be manipulated from the outside.
First you connect the solenoid to a regulatable DC power supply. Rise the voltage from zero slowly up until the lock opens.
In my case this happens at 2,8V.
But this is too insecure. A higher voltage must be applied to be sure that it always opens.
I chose to apply 3,5V.
Then I measure the current that flows at 3,5V which is 1,3A.
As I have to open two doors simultaneously I connect both solenoids in series.
So I need 7V at a current of 1,3A for both.
At Rx there will be a voltage of 12V - 7V = 5V which results in a resistor of:
R = U/I = 5V/1,3A = 3,8 Ohm
Now calculate the power of the resistor:
P = U*I = 5V*1,3A = 6,5W
If your local electronic shop does not have this value you can switch multiple resistors in parallel.
For example 4 * 15Ω of which each should have a power of 2 Watt.
This will result in a total resistor of 3,75Ω with 8 Watt.
To calculate two resistors in parallel you can use the formula:
R total = (R1 * R2) / (R1 + R2)
The meaning of the LED
The two-color LED should be mounted on the inside of the door or at any place where it is visible.
It constantly shows if everything is working correctly.
Green LED permanently flashing fast | Everything is OK |
Green LED flashing once for 1 second | The door is beeing opened for an authorized person |
Red LED permanently flashing fast | The battery voltage is out of range. The cause may be a power failure or a defect. |
Red LED flashing once for 1 second | An unauthorized person tries to open the door with an invalid card or token. |
Red LED permanently flashing very slowly | Shows a comunication problem with the PN532 board. This is a severe error. |
Green LED and Red LED flash alternatingly | The battery is old and must be replaced soon. |
The LED is permanently off | This indicates a defect. |
Optimizing Power Consumption
Everything has been done to reduce the power consumption:
The highest power consumption comes from the PN532 board: As chipcards and tokens have no battery, they must be powered externally.
The PN532 has to generate a RF field of 13 MHz that feeds power to the chipcard through the antenna. When generating that field, the PN532 consumes 110mA. There is a command that allows to turn the RF field off. But without RF field there is no card detection possible. So what my code does is to turn on the RF field for 100ms to check if there is a card and then turn off the field for 1 second. When the RF field is off the PN532 consumes only 18mA. The result is an average consumption of 26mA.
The power consumption of the Teensy is 40mA at a CPU clock of 96MHz. As such a high speed is not needed, the clock is set to 24MHz which reduces the power consumption to 20mA.
Finally the total current is on average 46mA.
The interval that the relay is powered is optimized. A high current is flowing through the solenoid. You have to test which interval works for your solenoid. You can modify that in source code. In my case the solenoid already works with an interval of 20 ms. But to make it bulletproof I programed 100 ms.
Life Expectations
Today we are used that electronic devices have a short life, especially those that come from China.
But it has not been like this ever since.
Once upon a time there was the good old "Made in Germany" which always meant high quality and long life. I have an amplifier from Grundig that I bought in the beginning of the 1990's. It is still working today. I repaired it only once in neary 30 years!
But already in the 1980's the first japanese products came on the market which were just cheaper but worse in quality. In those years the clients have chosen that they prefer to pay less for a cheaper japanese product than for a high quality german brand. In these years there was a high quality decrease world wide. Today China is continuing these tendencies.
There are even people who suspect that companies build their devices intentionally to have a short life ("Planned Obsolescence"). But this could not be confirmed till this day. The truth is that the industry is in a hard price war. Companies HAVE to design their products cheap because otherwise the client will not buy them. The client is the culprit because he is not willing to pay more for higher quality. Do you remember the war between the cheap japanese VHS and the much better german Video 2000? The worse system won the war because the client didn't want to pay the price that quality costs!
How do companies lower the price? In the first place by using the cheapest electronic parts possible. The result is that often parts are underdesigned. If for example a transistor is designed for a maximum voltage of 1500 Volt and it is running permanently with a voltage of 1200 Volt it is obvious that this transistor will have a short life (approx 5 years), because it is permanently running at it's limits. On the other hand a transistor designed for 100 Volt, but running at 5 Volt will have a significantly longer life (> 30 years). The same applies for currents.
Also mostly the coolers for power transistors or ICs are designed too small (or even missing) to save money and space.
Another common cause for failures are plugs and switches. With the years their contacts oxidate and the connection may get lost completely. Good plugs have golden contacts, but as gold is expensive, companies mostly don't use them.
But also the other extreme exists. Think about high quality electronics that must not fail:
For example in medicine, in a satellite or in a military jet.
Here the engineers surely will NOT chose the cheapest parts (that run at their limits) to make the electronic as fail safe as possible. They may even add electronic parts that take over control when other parts fail. For example 5 condensators switched parallel where one would be enough.
I have repaired electronic devices for many years and have a lot of experience which are the electronic parts that fail first. These are generally semiconductors that work with high voltages, high currents and that become hot. Also electrolyte condensators that operate with high currents are failing frequently (which is the most common reason for the death of switched-mode power supplies).
I have designed this door opener for a long life. There are no parts that become hot in normal operation. The high current for the door opener solenoid is switched by a relay rather than a transistor, because relays are much more robust.
I recommend to use a rectifier that tolerates 3 Ampere although only a few mA are flowing if the battery is full.
Do NOT replace the transformer and rectifier with a DC power supply (like those for laptops). The switched power supplies from China have cheap electronic parts inside which are exposed to 220V and will die soon. On the other hand a regular transformer has an eternal life. I never had to replace a dead power transformer in decades of repairing all kind of electronic stuff. The ONLY advantage of switched power supplies is that they are smaller and have less weight, but apart from that they are the worst solution because they have a short life.
You should avoid plugs wherever possible. In my photo you see that the Teensy is soldered directly on the board just to avoid contact problems in the future. The plug for the flat cable should have gold contacts. I also soldered the cables directly to the battery to avoid plugs. To make it easier to disconnect the battery I added 2 screw joints. Other battery models already come with screw clamps.
The only part that must be replaced after some years is the battery. When you see the LED flashing alternatingly in green and red, the battery is dying.
Finally I suppose that the life expectation of the electronics should be 20 - 30 years or even more.
Loading the firmware into the Teensy
- Option A:
You can either install the Arduino compiler from arduino.cc and the Teensyduino library from PJRC.com and compile the sketch that you find in the ZIP file above. You must configure the compiler settings like this:
- Option B:
Or you don't install anything and load the precompiled firmware directly to a Teensy 3.1 or 3.2 board. You find the HEX file and the TeensyLoader.exe in the ZIP file.
Communicating with the Teensy
You need a Micro USB cable to connect your computer with the Teensy.
First you have to install the Teensy Serial driver that makes the Teensy appear as a virtual COM port on your PC.
You find the driver in the ZIP file.
You can communicate to the Teensy with a terminal program.
You can use the freeware TeraTerm or the Serial Monitor that is built into the Arduino Compiler.
You don't have to care about the baudrate, because theTeensy ignores it (unlike older Arduino boards). The data is always transmitted with USB speed.
If you use the Serial Monitor you must select the COM port (Menu "Tools", see image above) and configure it to send LineFeeds:
If you use TeraTerm you only have to select the COM port:
IMPORTANT: If the Teensy does not have power (if you disconnect the battery) or if you press the "Program" button on the Teensy while the COM port is open in the terminal program you will first have to close the COM port, disconnect the USB cable, reconnect it and then open the COM port anew!
To avoid this you should first close the COM port (Menu "Disconnect" in TeraTerm) before you remove power supply from the Teensy or press the "Program" button.
The reason is that Windows does not remove the COM port while any program has the port still open (although the Teensy has already been disconnected).
Managing Users
After opening the COM port in the terminal program you will first see nothing.
If password protection is enabled you must enter the password now and hit Enter, otherwise you only hit Enter.
In both cases the main menu will appear:
The menu shows the available commands and the actual status.
You can store more than 64 users in the EEPROM if you reduce the amount of characters for the user name.
CLEAR
The first thing that you always have to do on a new Teensy board is to clear the EEPROM:
Type "clear" and hit Enter.
ADD
To add access permission for a new user, type "add" followed by the user name and Enter.
As you see, these cards use a 7 byte UID (Desfire).
Apart from storing the card ID and user name in Teensy's EEPROM several steps are executed on a Desfire card. See below.
It is possible to store multiple cards for the same user name.
If you later delete that user with the DEL command all his cards will be deleted at once.
If you prefer to be able to delete the cards individually you can give each card a unique name like "John Hilton 1", "John Hilton 2", etc...
DOOR1, DOOR2, DOOR12
By default a new user can open only door 1. You can give the user permission to open one of the doors or both.
LIST
To show all users that are authorized, use the LIST command. Users are sorted alphabetically.
DEL
This command deletes a user and his card from the EEPROM so he will not be able to open the door anymore.
The DEL command does not require a card to be present, so the changes made on the card will not be reverted.
Use this command if a user has lost his card.
RESTORE
The RESTORE command also deletes a card and it's user from the EEPROM, but it additionally reverts all changes on the card.
RESTORE resets the PICC master key to the factory default key and deletes the application that has been created on a Desfire default card.
RESET
The RESET command pulls the RSTPDN line of the PN532 to LOW for 400ms which resets the board.
Afterwards the chip initialization runs anew and the capabilities of the chip are read.
Apart from this command the PN532 is automatically reset when a communication error has been detected.
MAKERANDOM
This command configures a Desfire card to always send a different random ID and hide it's real UID.
See below for more details about the different operation modes.
TEST
Executes a Selftest that tests all Desfire commands. (see below)
The PN532 Communication Protocol
The PN532 uses a very complicated communication protocol. You find the description in the manual in the ZIP file.
- First the Host sends one single byte (DW = Data Write) which tells the PN532 that now data will be sent.
- Then the host sends a command frame which contains an instruction to be executed.
- Then the host sends one single byte (SR = Status Read) that asks for the status of the PN532.
- If the PN532 is not yet ready it responds with a 0x00 byte. This means that the host has to wait. When the PN532 is ready it responds with a 0x01 byte.
- Then the host sends one single byte (DR = Data Read) which tells the PN532 that it expects a data packet.
- Then the PN532 sends an ACK frame (Acknowledge) which is a fixed sequence of bytes (00, 00, FF, 00, FF, 00). This confirms that the command has been received correctly.
- Then the host sends one single byte (SR = Status Read) that asks for the status of the PN532.
- When the PN532 is ready it responds with a 0x01 byte.
- Then the host sends one single byte (DR = Data Read) which tells the PN532 that it expects a data packet.
- And finally the PN532 sends the response frame.
The Data Frames
The Command frame and the Response frame look like this:
The Preamble and Postamble are optional.
The receiver of the packet must first search for the start sequence {00, FF} which marks the begin of the packet.
Then comes the length of the data followed by a length checksum.
The frame identifier (TFI) is 0xD4 if the frame is sent from the host to the PN532 and 0xD5 for the opposite direction.
After the packet data comes a checksum.
The Adafruit Library
A library of 1000 lines of code is required to communicate with the PN532.
From the Adafruit site you can download an Arduino code and samples that show the communication with the PN532. But sadly this code can only be used for testing but the code is sloppy and buggy and cannot be used in production.
I had to rewrite the Adafruit code completely. Here the list of my changes:
- Removed all compiler warnings that appeared when compiling Adafruit code.
- Bugfix: (Severe bug) Adafruit used
strncmp()
to compare binary data (which contains zeroes). This is completey wrong -> replaced with memcmp()
- Bugfix: (Severe bug) Adafruit code does not check for valid response packets. The checksum is completely ignored. Bytes received before the start code are not skipped!
- Bugfix: (Severe bug) Adafruit code used a timeout = 0 (wait forever). This is completely wrong. If the chip does not respond, the code hangs forever! My code is "self healing" which means that even after unplugging the PN532 board and reconnecting it, the chip will be reset and afterwards it works again.
- Bugfix: Adafruit code does not allow to distinguish why
readPassiveTargetID()
returns false. (Because there is no card or because of a communication problem?) - Added support for Value blocks (in Mifare.cpp)
- Added memory Dump (in Mifare.cpp)
- The IRQ line is not required anymore in I2C mode. Now the software handshake is used instead.
- Software SPI slow speed added (to get 10kHz clock)
- Implemented the correct wake up procedure (sending PN532_WAKEUP) instead of sending getFirmwareVersion.
- Debug output was buggy: The checksum bytes were displayed as 0xFFFFFFFC instead of 0xFC. Removed useless "0x" before each byte.
- Detailed debug output was missing.
- Added display of valid data bytes inside the packet in debug output.
- Using
getFirmwareVersion()
was very clumsy -> completely rewritten writeGPIO()
rewritten -> no warning about wrong usage anymore. AuthenticateDataBlock()
, ReadDataBlock()
and WriteDataBlock()
rewritten. setPassiveActivationRetries()
did not have any error checking at all. - Ugly code in
writecommand()
completely rewritten - Crappy code like this removed:
int offset = _usingSPI ? 5 : 6;
- The library completely avoids the
new
operator.
My new PN532 library, that you find in the ZIP file, supports 3 communication modes:
- Software SPI:
This one is used because it allows to throttle the SPI bus to run at 10kHz for transmission over a long cable.
The advantage of Software SPI is that you can chose any Teensy pin for SCK, MISO, MOSI and SSEL. - Hardware SPI:
This also works but one disadvantage is that the Teensy uses the same pin for hardware SCK as the built-in LED on the board. (Pin 13) So the LED cannot be used in this mode. Additionally the Teensy library does not allow to set a clock of 10kHz. - I2C:
This also works but an open collector bus cannot be transmitted over a long cable. I changed the I2C code so that the IRQ line is not needed anymore.
Read Wikipedia about SPI and I2C.
The Desfire EV1 Library
In addition to re-writing the PN532 code I created a new Desfire library (about 2700 lines of code). Currently there is no code available in internet to control Desfire cards with Ardiuno/Teensy.
This is the first library that has ever been written for the Arduino family. You have to change only a few lines in Utils.h and you can compile the library on Visual Studio, Linux or other platforms.
Using my library is very easy and the integrated Selftest gives a living example how to call the functions.
The library completely avoids the new
operator.
The code is professional C++ code, reusable, very well structured and commented.
The library will not work with old Desfire cards (deprecated) because legacy authentication is not implemented. You really need EV1 cards.
If you search a datasheet for Desfire EV1 cards you will only find the "short version" on the NXP website which is quite useless.
To get the complete documentation you have to make a Non-Disclosure Agreement (NDA) with NXP where you promise not to give this documentation to anybody else. This NDA is made only with companies. It is incredible that NXP did not learn from their own errors in the past. Did the Mifare Classic desaster not show clearly that "security-through-obscurity" does not work? Is Windows more secure than Linux because Microsoft maintains the source code secret? And does NXP really believe that hiding information still works in the age of file sharing, Wikileaks and Edward Snowden? Or is NXP so naive to believe that a chinese company, that wants to produce a counterfeit card, is not able to obtain that documentation? Whatever might be the idea behind that NDA: Any sane person will agree that it is pure nonsense.
However, I never made that contract with NXP and so I do not have the full documentation.
But this documentation is not needed at all because I found some Desfire open source projects that are hosted on Github: easypay, libfreefare and liblogicalaccess. By studying their code, fixing their bugs, experimenting with the card and with the help of Google I wrote my own Desfire library:
Function | Description |
GetCardVersion() | Obtains details about the Desfire card like hardware and software version, EEPROM size, week and year of production, a batch number, etc.. |
FormatCard() | Erases ALL content from the card except the PICC master key |
Authenticate() | Authenticates with a 2K3DES, 3K3DES key (ISO authentication) or an AES key either at the PICC level or at the application level |
ChangeKey() | Changes the PICC master key or any application key |
GetKeyVersion() | Gets the key version (an optional value stored in the key) |
GetKeySettings() | Gets the settings of a key (permissions) |
ChangeKeySettings() | Changes the settings of a key |
GetApplicationIDs() | Enumerates all applications on the card |
SelectApplication() | Selects an application to which the following commands will be sent |
DeleteApplication() | Deletes an application with all it's files and keys |
CreateApplication() | Creates a new application with 2K3DES, 3K3DES or AES keys. You can mix different key types on one card. |
GetFileIDs() | Enumerates all files in an application |
GetFileSettings() | Gets information about a file (file type, encryption, permissions, size, etc..) |
DeleteFile() | Deletes a file |
CreateStdDataFile() | Creates a Standard Data File (the file size can be defined at creation time but not changed later) |
ReadFileData() | Reads data from a data file |
WriteFileData() | Writes data to a data file |
ReadFileValue() | Reads the value from a value file |
EnableRandomIDForever() | Enables random ID mode where the card sends another ID each time (!This cannot be reversed!) |
GetRealCardID() | Obtains the real card UID. (Usefull in random ID mode) |
GetFreeMemory() | Returns the remaining free memory in the card's EEPROM. |
Selftest() | Executes a selftest that tests ALL the above commands on an empty card.
You find debug output of the entire selftest with all bytes sent and received in the ZIP file. |
Writing this library was really a challenge, especially due to the lack of documentation. It took weeks of my life to finish this project. The most difficult parts are the authentication with a cryptographic key and the key change. During authentication random values are encrypted and exchanged between the card and the host to prove that both sides share the same master key. From these random values a session key is generated. All encryption goes through Cipher Block Chaining, where NXP distinguishes between Enciphering/Deciphering and Send Mode/Receive Mode. The cryptographic initialization vector (IV) is reset only once when authenticating, then for all further commands it must be maintained up to date. If your IV vector comes out of sync with the one that the card has calculated internally you will get an Integrity Error. All the data sent to the card and all the data received from the card must go though a CMAC calculation (something like a hash). Some functions calculate a CMAC, others do not. When changing a key, two CRC32 values have to be calculated and the old key and the new key are XORed, padded and then encrypted with the session key. Each type of key has it's own peculiarities: AES encrypts blocks of 16 byte while DES uses 8 byte blocks and the length of the key itself may be 8, 16 or 24 byte. As a consquence also the length of the random values and the session key vary with the key type. All this stuff is HIGHLY complicated and you have thousands of pitfalls. And the worst of all is that in internet you find nearly no usefull information. I feel like a pioneer in Defire EV1 development.
I have chosen the smallest open source crypto libraries that I could find: AES128 from Texas Instruments and 3DES from Eric Young. Although the entire Desfire source code has about 2700 lines, the size of the compiled code is small:
- Compiled for Mifare Classic cards it consumes 18% of the flash memory
- Compiled for Mifare Desfire cards it consumes 27% of the flash memory
So all the crypto stuff consumes only 9% of the flash memory. Please note that the compiler omits all functions from compilation that are not in use.
The Three Operation Modes
Depending on the compiler switches and the card types you can have 3 different operation modes:
- Compiled with
#define USE_DESFIRE false
you get Classic mode, - Compiled with
#define USE_DESFIRE true
and default Desfire cards you get Desfire Default mode, - Compiled with
#define USE_DESFIRE true
and random ID Desfire cards you get Desfire Random mode.
It depends only on the card if the system is working in Desfire default mode or in Desfire random mode. So these both types of cards can be used mixed at the same time.
To convert a default Desfire card into a random Desfire card you have to execute the command MAKERANDOM.
ATTENTION: If a card has once been converted to use random ID, NXP does not allow to reverse this anymore. (Why??)
| Classic Mode | Desfire Default Mode | Desfire Random Mode |
Supported cards | Classic cards,
Desfire cards with default ID | Desfire cards | Desfire cards |
Unsupported cards | Desfire cards with random ID | Classic cards | Classic cards |
Access to card UID | The UID can be obtained always. | The UID can be obtained always. | The card sends a random ID. Getting the real UID requires cryptographic authentication. |
User Authentication | Only by UID of the card. | By the UID of the card and the application master key. | By the UID of the card and the PICC master key. |
Security | Not secure because the card can be cloned very easily. In China you can buy cards that allow to write any UID. You need a stainless steel wallet to prevent this. | Very secure because currently there are no known attacks on Desfire EV1 cards. The secret application master key (AES or 3K3DES) would be required to clone the card. | Very secure because currently there are no known attacks on Desfire EV1 cards. The secret PICC master key (AES or 3K3DES) would be required to clone the card. |
Card Personalization | Classic cards are not personalized. (It would be possible to store secret data on a classic card but due to the broken encryption this would not be secure.) | When the card is personalized (with command ADD) the PICC master key is changed into a secret key and a new file in a new application is created on the card that stores a 16 byte secret store value. The file and the application are protected with a secret application master key. The application master key is frozen, so it cannot be changed later. Both, the 16 byte secret store value and the application master key are diversified by deriving them from the card UID, the user name and additional random data that is stored in the EEPROM of the Teensy. | When the card is personalized (with command ADD) the PICC master key is changed into a secret key. |
Door Access | The UID of the card is compared with the UID's stored in the EEPROM of the Teensy. | The UID of the card is compared with the UID's stored in the EEPROM of the Teensy. After authentication with the diversified application master key the secret store value is read from the file and compared with the expected value. | After authentication with the PICC master key the real card UID is read and compared with the UID's stored in the EEPROM of the Teensy. |
In source code you can additionally chose which master keys you want to use for Desfire cards:
- Compiled with
#define USE_AES true
you use 128 bit AES keys (max. reader distance: 4,0 cm) - Compiled with
#define USE_AES false
you use 168 bit 3K3DES keys (max. reader distance: 5,3 cm)
In source code you find the file Secrets.h which contains:
- The PICC master key (AES or 3K3DES),
- A cryptographic key (3K3DES) to derive the application master key from card ID, user name and random data (for Desfire default mode),
- A cryptographic key (3K3DES) to derive the secret store value from card ID, user name and random data (for Desfire default mode).
Before compiling the source code for the fist time you should change these 3 keys to anything else.
ATTENTION: If you already have personalized cards and then change the PICC master key in source code you cannot authenticate these cards anymore. Therefore it is important that you first execute the RESTORE command on all personalized cards and afterwards change the PICC master key in code. The RESTORE command resets the PICC master key to the factory default DES key full of zeroes.
Debug Level 1
If anything goes wrong in the communication you can use the debugging that I have implemented.
Via terminal enter the command "debug 1" to activate basic debugging.
Here you see a part of the debug output at level 1 when a default Desfire card is personalized:
NOTE: You find debug output of the entire selftest in the ZIP file.
Debug Level 2
Enter "debug 2" and additionally the data packets will be shown:
Now you see the commands sent to the PN532 and the responses received from the PN532.
The data bytes are marked between '<' and '>' characters in each valid packet.
The command ReadPassiveTargetID
turns on the RF field and checks if there is a card present.
If there is no card, only 3 data bytes are returned (D5 4B 00).
The command SwitchOffRfField
turns the RF field off to save battery.
If a card has been detected the response looks like this:
You see that now more bytes are transmitted. They contain the unique ID of the card and additional information about the card.
In this example the code has been compiled for Mifare Classic cards. The ID is 4 bytes long.
When the card is authorized, the door opens and the green LED flashes for 1 second.
If the card is not authorized, the red LED flashes for 1 second and the door does not open.
If the code is compiled for Mifare Desfire cards additional cryptographic operations are executed before the door is opened.
Debug Level 3
Enter "debug 3" to activate detailed debugging:
Now you see each and every byte that is transmitted between the Teensy and the PN532, including the ACK package and the status bytes.
Errors
Whenever the Teensy detects that the PN532 did not respond as expected, an error is printed to the terminal.
This example shows the case that the PN532 did not respond at all. The Teensy pulls the RSTPDN line to LOW to reset the chip, sends the WakeUp packet (see Manual) and tries again to communicate with the chip.
Additionally the red LED will flash very slowly so you see immediately that there is a severe error.
If you use Desfire cards you will probably see a Timeout Error from time to time. This happens only when the card is too far away from the antenna of the PN532. This Timeout means that the PN532 did not receive an answer from the card. In this case any further command sent to the card will return another Timeout error. Any communication with the card is stalled. The only way out is to call SwitchOffRfField()
and connect again with ReadPassiveTargetID()
. The commands executed first (GetKeyVersion()
and SelectApplication()
) work fine and when it comes to authenticate the communication breaks down. The reason is that encryption increases the power consumption of the card. Strangely AES uses more power than DES. When you use AES the card must be in a distance of 4,0 cm from the PN532. When using DES the distance can be up to 5,3 cm.
Note that there are basically two types of timeouts: (First the Teensy waiting for response from the PN532 and second the PN532 waiting for response from the card) If you put the card directly on the antenna of the reader you should never get a timeout error. Turn on Debugging to see what happens.
More projects with Teensy
This is my third electronic project with a Teensy published on Codeproject. You may also be interested in: