Secure iButton: Difference between revisions
mNo edit summary |
m (Juerd moved page SecureIButton to Secure iButton) |
||
(9 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{Project | {{Project | ||
|Name=Secure iButton | |Name=Secure iButton | ||
|Status= | |Status=Completed | ||
|Contact=User:Bertrik Sikken | |Contact=User:Bertrik Sikken | ||
|Picture=ibutton.png | |||
}} | }} | ||
'''Project status: software library has been integrated in our hacker space physical access system.''' | |||
This project is about investigating and using the secure features of the iButton that people currently use for physical access to RevSpace. See also [[Doorduino]] and the [https://github.com/revspace/doorduino Doorduino] GitHub project. | |||
This project is about investigating and using the secure features of the iButton that people currently use for physical access to RevSpace. | |||
Planned project phases are: | Planned project phases are: | ||
Line 24: | Line 19: | ||
* 4 pages of 32-byte user data each | * 4 pages of 32-byte user data each | ||
* an 8-byte write-only "secret" | * an 8-byte write-only "secret" | ||
* SHA-1 algorithm that can calculate a hash over a 32-byte user data page, the 8-byte secret, a 3-byte "challenge" and the unique iButton id | * SHA-1 algorithm that can calculate a hash over a 32-byte user data page stored on the iButton, the 8-byte secret, a 3-byte "challenge" and the unique iButton id. | ||
===Bus pirate experimentation=== | ===Bus pirate experimentation=== | ||
Line 47: | Line 33: | ||
* Reset the iButton and get iButton unique id | * Reset the iButton and get iButton unique id | ||
(240) | (240) | ||
* | * Example exchange for command 0xA5 (Read Auth Page), which is the secure read command | ||
<pre> | <pre> | ||
1-WIRE>0xa5 0 0 r:32 r r:2 &:1500 r:20 r:2 | 1-WIRE>0xa5 0 0 r:32 r r:2 &:1500 r:20 r:2 | ||
Line 70: | Line 50: | ||
0xAA 0x6D | 0xAA 0x6D | ||
</pre> | </pre> | ||
Conclusion: the bus pirate has proven to be an excellent tool for initial prototyping with the DS1961 iButton. | |||
==DS1961 library== | ==DS1961 library== | ||
This library provides an API for the DS1961 specific functions. | This library provides an API for the DS1961 specific functions. | ||
It will be targeted at the Arduino microcontroller, to run on top of the existing | It will be targeted at the Arduino microcontroller, to run on top of the existing [http://playground.arduino.cc/Learning/OneWire Arduino OneWire] library. | ||
Experimental code is available on the GitHub [https://github.com/bertrik/ibutton-test ibutton-test] project. | |||
==Application== | ==Application== | ||
Line 84: | Line 68: | ||
* how advanced do we make the authentication scheme / how is key management handled? | * how advanced do we make the authentication scheme / how is key management handled? | ||
** Simplest: one secret for all revspace iButtons. Disadvantage: cracking one iButton means that *all* revspace iButtons are cracked. | ** Simplest: one secret for all revspace iButtons. Disadvantage: cracking one iButton means that *all* revspace iButtons are cracked. | ||
** More advanced: different secret for each revspace iButton (e.g. calculated from a master secret and the iButton serial number) | ** More advanced: different secret for each revspace iButton (e.g. calculated from a master secret and the iButton serial number, or just generated every time and stored) | ||
** | |||
===Concrete proposal=== | |||
The following protocol extension for communication with the Arduino is proposed. | |||
On the Arduino side, the following command/response exchange is added: | |||
* an extra command to send the 3-byte '''C'''hallenge (in hex-ascii), example | |||
<pre>C AB34EF</pre> | |||
* a corresponding response to return the 32-byte data and the 20-byte hash, example | |||
<pre>C 0000000000000000000000000000000000000000000000000000000000000000 D54A4731DC5EDF675D7B0A23A6D83534FAE12E3F</pre> | |||
TODO: what to respond if communication with the ibutton fails somehow? | |||
On the server side, the access control sequence is extended as follows: | |||
* receive an ibutton id from the Arduino | |||
* lookup the id in the access control list | |||
* if the id is not present, don't open the door | |||
* if the id has no associated secret, open the door | |||
* if the id has an associated secret, generate the 3-byte challenge and perform the challenge/response sequence | |||
* if the response matches the expected response, open the door | |||
==External Links== | ==External Links== | ||
[http://www.maximintegrated.com/products/ibutton/software/1wire/wirekit.cfm Maxim iButton 1-wire public domain kit] | [http://www.maximintegrated.com/products/ibutton/software/1wire/wirekit.cfm Maxim iButton 1-wire public domain kit] | ||
==Idee voor betere challenge== | |||
'''Inmiddels [https://github.com/revspace/doorduino/commit/2bc8631bef87e64e34a68fe0ae96313420bbdec0 geïplementeerd].''' | |||
3 bytes challenge is nogal karig: 2<sup>24</sup> mogelijke antwoorden per secret betekent en ca. 3 ms per hash betekent dat je een iButton maar 2<sup>24</sup> * 3 ms = 14 h in bezit hoeft te hebben om genoeg informatie te krijgen om 'm volledig te na te bootsen met een [https://github.com/orgua/OneWireHub iButton slave]-emulator. Als je akkoord gaat met authenticatiefouten, kun je met een minder volledige (iButton-specifieke) rainbow table volstaan: 7 uur voor 50% kans, 3,5 uur voor 25% kans, 1 uur voor 14% kans. | |||
Echter, de iButton berekent niet zomaar sha1(id; secret; challenge), maar sha1(id; secret; data; challenge), waarbij ''data'' 1 van de 4 EEPROM-pagina's is, van elk 32 bytes. Met kennis van de secret kun je een datapagina overschrijven: iedere pagina is weer verdeeld in 4 blokken van 8 bytes. | |||
* addr = rand(16) * 8 | |||
* (data, hash) = ReadAuthPage(addr & 0xffe0, challenge) | |||
* check hash == sha1(...) | |||
* rs = random string van 8 bytes | |||
* data[addr % 32 : 8] = rs | |||
* mac = sha1(id; data; secret; rs; ...) | |||
* WriteData(addr, data, mac) | |||
* nieuwe challenge | |||
* (newdata, hash) = ReadAuthPage(addr & 0xffe0, challenge) | |||
* check newdata == data, hash == sha1(...) | |||
Dit gaat van 2<sup>24</sup> naar minimaal 2<sup>24</sup> + 2<sup>24 + 64</sup> bij een nieuwe ibutton, maar omdat een hele datapagina wordt gebruikt terwijl er maar 8 bytes veranderen, kan het in het beste geval zelfs 2<sup>24</sup> + 2<sup>24 + 4 * 64</sup> worden. | |||
De vraag is vooral of het snel genoeg zal zijn om in het korte contactmoment allemaal te doen. Het aantal hashes dat berekend wordt door de iButton gaat van 1 naar 3 (dus 3 * T<sub>CSHA</sub> = 6 ms (want ruim gedefinieerd in DS1961.cpp)), het aantal 1-wire-command's na de initiele search gaat van 2 naar 10, waaronder 2x T<sub>PROG</sub> = 20 ms extra wachten. | |||
'''Update:''' goed te doen na wat [https://github.com/revspace/doorduino/commit/09d93c0568d3ed95386befda44a8e7dcfef89c95 tweaks]. | |||
Onduidelijk is of RefreshScratchpad en LoadFirstScret, die instabiele EEPROM-data voorkomen, wel nodig zijn voor deze use-case. Als er een byte van het EEPROM onbetrouwbaar blijkt, wordt in het ergste geval een deur-opening geweigerd. De volgende keer zal ie waarschijnlijk wel werken, als de cel alsnog stabiliseert. Ik weet niet of dat gebeurt, en moet me verdiepen in failure modes van EEPROMs. Als we deze commando's kunnen overslaag scheelt dat 2 commando's en 1x T<sub>PROG</sub>. | |||
'''Update:''' ja, is nodig. Gaat best vaak fout als je de refresh weglaat. | |||
De iButtons ondersteunen een snellere communicatie via "Overdrive mode". Uitgezocht moet worden hoeveel tijd hiermee kan worden bespaard en hoeveel moeite het is om dit is om te implementeren; de standaard OneWire-library voor Arduino ondersteunt het niet, maar er is een [http://forum.arduino.cc/index.php?topic=201776.0 fork uit 2013]. | |||
'''Update:''' Wordt op diverse plekken afgeraden voor 1-wire over lange kabels (tientallen meters), dus niet geprobeerd. | |||
Het aantal EEPROM-cycles lijkt geen probleem. Er zijn 16 stukken EEPROM van 8 bytes. In de worst case wordt willekeurig steeds hetzelfde blok overschreven. Uitgaande van de helft van de gespecte 50k writes kom je dan nog op 25k uit, of bijvoorbeeld 8 jaar lang, 3 keer per week 20 keer per bezoek... |
Latest revision as of 03:37, 11 September 2016
Project Secure iButton | |
---|---|
Status | Completed |
Contact | User:Bertrik Sikken |
Last Update | 2016-09-11 |
Project status: software library has been integrated in our hacker space physical access system.
This project is about investigating and using the secure features of the iButton that people currently use for physical access to RevSpace. See also Doorduino and the Doorduino GitHub project.
Planned project phases are:
- phase 1: investigate possbilities of the iButton and experiment with it
- phase 2: write software for the iButton functionality and package it into a library
- phase 3: apply knowledge and software for application within RevSpace
iButton investigation
The iButton used at RevSpace is the DS1961, with the following features:
- 4 pages of 32-byte user data each
- an 8-byte write-only "secret"
- SHA-1 algorithm that can calculate a hash over a 32-byte user data page stored on the iButton, the 8-byte secret, a 3-byte "challenge" and the unique iButton id.
Bus pirate experimentation
Investigation of the DS1961-specific commands can be done with a Bus Pirate. A bus pirate speaks the 1-wire protocol that any iButton-like device uses.
Examples of bus pirate commands to communicate with the DS1961:
- Initialise the bus pirate
# (reset the bus pirate) M (select mode) 2 (1-wire mode) W (enable power)
- Reset the iButton and get iButton unique id
(240)
- Example exchange for command 0xA5 (Read Auth Page), which is the secure read command
1-WIRE>0xa5 0 0 r:32 r r:2 &:1500 r:20 r:2 WRITE: 0xA5 WRITE: 0x00 WRITE: 0x00 READ 0x20 BYTES: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 READ: 0xFF READ 0x02 BYTES: 0x6D 0x0D DELAY 0xDCuS READ 0x14 BYTES: 0x45 0x31 0x40 0x42 0xAE 0xD3 0x4B 0xC5 0x18 0xCC 0x10 0x43 0x27 0x56 0x33 0xD0 0xEB 0x47 0xA7 0x81 READ 0x02 BYTES: 0xAA 0x6D
Conclusion: the bus pirate has proven to be an excellent tool for initial prototyping with the DS1961 iButton.
DS1961 library
This library provides an API for the DS1961 specific functions. It will be targeted at the Arduino microcontroller, to run on top of the existing Arduino OneWire library.
Experimental code is available on the GitHub ibutton-test project.
Application
We could apply this to improve the security of RevSpace access for example. to be discussed.
Stuff to be considered for access control:
- an extra initialisation step to install the secret before use is needed
- how can we handle the transition of the current iButton system to a more secure system?
- how advanced do we make the authentication scheme / how is key management handled?
- Simplest: one secret for all revspace iButtons. Disadvantage: cracking one iButton means that *all* revspace iButtons are cracked.
- More advanced: different secret for each revspace iButton (e.g. calculated from a master secret and the iButton serial number, or just generated every time and stored)
Concrete proposal
The following protocol extension for communication with the Arduino is proposed.
On the Arduino side, the following command/response exchange is added:
- an extra command to send the 3-byte Challenge (in hex-ascii), example
C AB34EF
- a corresponding response to return the 32-byte data and the 20-byte hash, example
C 0000000000000000000000000000000000000000000000000000000000000000 D54A4731DC5EDF675D7B0A23A6D83534FAE12E3F
TODO: what to respond if communication with the ibutton fails somehow?
On the server side, the access control sequence is extended as follows:
- receive an ibutton id from the Arduino
- lookup the id in the access control list
- if the id is not present, don't open the door
- if the id has no associated secret, open the door
- if the id has an associated secret, generate the 3-byte challenge and perform the challenge/response sequence
- if the response matches the expected response, open the door
External Links
Maxim iButton 1-wire public domain kit
Idee voor betere challenge
Inmiddels geïplementeerd.
3 bytes challenge is nogal karig: 224 mogelijke antwoorden per secret betekent en ca. 3 ms per hash betekent dat je een iButton maar 224 * 3 ms = 14 h in bezit hoeft te hebben om genoeg informatie te krijgen om 'm volledig te na te bootsen met een iButton slave-emulator. Als je akkoord gaat met authenticatiefouten, kun je met een minder volledige (iButton-specifieke) rainbow table volstaan: 7 uur voor 50% kans, 3,5 uur voor 25% kans, 1 uur voor 14% kans.
Echter, de iButton berekent niet zomaar sha1(id; secret; challenge), maar sha1(id; secret; data; challenge), waarbij data 1 van de 4 EEPROM-pagina's is, van elk 32 bytes. Met kennis van de secret kun je een datapagina overschrijven: iedere pagina is weer verdeeld in 4 blokken van 8 bytes.
- addr = rand(16) * 8
- (data, hash) = ReadAuthPage(addr & 0xffe0, challenge)
- check hash == sha1(...)
- rs = random string van 8 bytes
- data[addr % 32 : 8] = rs
- mac = sha1(id; data; secret; rs; ...)
- WriteData(addr, data, mac)
- nieuwe challenge
- (newdata, hash) = ReadAuthPage(addr & 0xffe0, challenge)
- check newdata == data, hash == sha1(...)
Dit gaat van 224 naar minimaal 224 + 224 + 64 bij een nieuwe ibutton, maar omdat een hele datapagina wordt gebruikt terwijl er maar 8 bytes veranderen, kan het in het beste geval zelfs 224 + 224 + 4 * 64 worden.
De vraag is vooral of het snel genoeg zal zijn om in het korte contactmoment allemaal te doen. Het aantal hashes dat berekend wordt door de iButton gaat van 1 naar 3 (dus 3 * TCSHA = 6 ms (want ruim gedefinieerd in DS1961.cpp)), het aantal 1-wire-command's na de initiele search gaat van 2 naar 10, waaronder 2x TPROG = 20 ms extra wachten.
Update: goed te doen na wat tweaks.
Onduidelijk is of RefreshScratchpad en LoadFirstScret, die instabiele EEPROM-data voorkomen, wel nodig zijn voor deze use-case. Als er een byte van het EEPROM onbetrouwbaar blijkt, wordt in het ergste geval een deur-opening geweigerd. De volgende keer zal ie waarschijnlijk wel werken, als de cel alsnog stabiliseert. Ik weet niet of dat gebeurt, en moet me verdiepen in failure modes van EEPROMs. Als we deze commando's kunnen overslaag scheelt dat 2 commando's en 1x TPROG.
Update: ja, is nodig. Gaat best vaak fout als je de refresh weglaat.
De iButtons ondersteunen een snellere communicatie via "Overdrive mode". Uitgezocht moet worden hoeveel tijd hiermee kan worden bespaard en hoeveel moeite het is om dit is om te implementeren; de standaard OneWire-library voor Arduino ondersteunt het niet, maar er is een fork uit 2013.
Update: Wordt op diverse plekken afgeraden voor 1-wire over lange kabels (tientallen meters), dus niet geprobeerd.
Het aantal EEPROM-cycles lijkt geen probleem. Er zijn 16 stukken EEPROM van 8 bytes. In de worst case wordt willekeurig steeds hetzelfde blok overschreven. Uitgaande van de helft van de gespecte 50k writes kom je dan nog op 25k uit, of bijvoorbeeld 8 jaar lang, 3 keer per week 20 keer per bezoek...