Dnes se s Arduinem pustíme do trochu vážnějšího experimentování, nicméně pro začátek se raději nebudeme zabývat ani dorozumíváním bez drátů, ani nevkročíme do nebezpečného a nejistého prostoru mezi jedničkou a nulou.
Možná jste si všimli zvláštních kovových článků – dotykových čipů, které vzhledem připomínají knoflíkové baterie a které lidé mívají připnuty na klíčích a s jejich pomocí si otevírají zámky, aktivují taxametry nebo se přihlašují k počítačové síti. Technologii iButton vyvinula společnost Dallas Semiconductor Corp a může se zdát překvapivé, že její prolomení je ve skutečnost dětskou hračkou
: nikdo rozumný by proto neměl tyto čipy používat tam, kde je vyžadován vyšší než minimální stupeň bezpečnosti, anebo by měl sáhnout pro speciálních – ovšem mnohonásobně dražších – dotykových čipech s vrstvou kryptografické ochrany.
Sestrojíme si přenosný přípravek, jehož pomocí můžeme emulovat čip, který jsme předtím do zařízení načetli. Před takovým emulátorem nebude nikdo v bezpečí, stačí, když nechá na pár minut ležet své klíče na stole a jeho identifikační token bude nezvratně kompromitován.
Mohli bychom použít přímo Arduino, ale zařízení, které budeme vyvíjet, se dá stejně dobře postavit z libovolného atmelu. Z důvodu předpokládaného zastarávání předchozích modelů zvolíme ATtiny85; úpravy zdrojového kódu pro kterýkoli jiný typ jsou ovšem triviální a rozdíl v cenách je dnes už zanedbatelný: vše jsou to dnes padesátikorunové šváby
.
Budeme potřebovat minimálně jeden dotykový čip jako vzorek (prodává se i ve třívývodovém pouzdře jako DS2401) a pár zcela běžných součástek. (Bohužel, zatím zápasím s linuxovým programem na kreslení elektronických schemat, doplním proto zapojení později.)
Čtecí zařízení je velice jednoduché, pokud se nechceme starat o ochranu před ESD, postačí jeden resistor 4K7. Kontakty můžeme provést různě, např. jako pružné vodiče zakončené kuličkou – fantasii se meze nekladou. Emulační hlava bude mechanicky stejně jednoduchá, avšak bude vyžadovat přece jen o něco víc elektroniky; důvodem je, že naše přenosné zařízení bude napájeno z lithiového článku 3,0–3,3 V, zatímco nepřátelská
čtecí hlava může být (a nejspíš bude) pětivoltová. Nicméně jeden transistor, jedna Schottkyho dioda a jeden resistor náš problém spolehlivě řeší.
Kromě toho bychom – pro vyšší komfort – měli mít možnost vidět, co emulátor dělá, takže na jeden pin připojíme LED s vhodným resistorem, a pro jeho spuštění potřebujeme tlačítko. O vypnutí se nemusíme starat, po určité době nečinnosti se zařízení může převést do klidového stavu samo. Spotřeba je v této konfiguraci hluboko pod 1 μA, takže si můžeme být jisti, že baterie zahyne přirozenou smrtí, nikoli vybitím provozem našeho emulátoru.
Schema doplňuje jeden filtrační keramický kondensátor (aby se neřeklo
) a to je skutečně vše.
Pro vývoj potřebujeme fungující, protokolu odpovídající čtecí zařízení na iButtony, ale to si v jeho průběhu snadno vyrobíme z dalšího atmelu, a pro reverse engineering bychom měli mít něco, co je schopno zachytit datový průběh na 1-wire sběrnici.
K tomu jsem použil samotné Arduino, z jehož portu K jsem si pomocí jednoduchého programu vyrobil primitivní logický analysátor (nebo, chcete-li, data logger), který jsem zakomponoval do po USB komunikujícího monitoru běžícího na Arduinu. Chtělo to práci s přerušením, trochu BCD arithmetiky a výsledek vypadá takhle:
>l0201
00000000.0000 01 -------1
00000001.0000 (00000001.0000) 01 -------1
00029743.5000 (00029742.5000) 00 -------0
00030230.0000 (00000486.5000) 01 -------1
00030260.5000 (00000030.5000) 00 -------0
00030400.5000 (00000140.0000) 01 -------1
00030712.0000 (00000311.5000) 00 -------0
00030724.0000 (00000012.0000) 01 -------1
00030814.0000 (00000090.0000) 00 -------0
00030827.5000 (00000013.5000) 01 -------1
00030918.0000 (00000090.5000) 00 -------0
00030931.0000 (00000013.0000) 01 -------1
00031021.0000 (00000090.0000) 00 -------0
00031034.0000 (00000013.0000) 01 -------1
00031124.0000 (00000090.0000) 00 -------0
00031201.0000 (00000077.0000) 01 -------1
00031227.5000 (00000026.5000) 00 -------0
00031305.0000 (00000077.5000) 01 -------1
00031331.5000 (00000026.5000) 00 -------0
00031408.5000 (00000077.0000) 01 -------1
00031435.0000 (00000026.5000) 00 -------0
00031512.0000 (00000077.0000) 01 -------1
00031539.5000 (00000027.5000) 00 -------0
00031551.5000 (00000012.0000) 01 -------1
00031642.0000 (00000090.5000) 00 -------0
00031705.5000 (00000063.5000) 01 -------1
00031745.5000 (00000040.0000) 00 -------0
00031808.5000 (00000063.0000) 01 -------1
00031849.5000 (00000041.0000) 00 -------0
00031912.5000 (00000063.0000) 01 -------1
00031953.0000 (00000040.5000) 00 -------0
00032016.0000 (00000063.0000) 01 -------1
00032056.0000 (00000040.0000) 00 -------0
00032119.5000 (00000063.5000) 01 -------1
00032160.0000 (00000040.5000) 00 -------0
00032223.0000 (00000063.0000) 01 -------1
00032263.5000 (00000040.5000) 00 -------0
00032326.5000 (00000063.0000) 01 -------1
00032385.0000 (00000058.5000) 00 -------0
00032448.0000 (00000063.0000) 01 -------1
00032486.5000 (00000038.5000) 00 -------0
00032500.0000 (00000013.5000) 01 -------1
00032590.0000 (00000090.0000) 00 -------0
00032653.0000 (00000063.0000) 01 -------1
00032693.5000 (00000040.5000) 00 -------0
00032756.5000 (00000063.0000) 01 -------1
>
V jednotlivých řádcích si můžeme přečíst údaje o přesném časování čipu v mikrosekundách. Některé vyplývají z katalogového listu, ale některé jsou arbitrární; ty musíme napodobit, protože je možné, že některé čtečky definici protokolu zcela přesně nesplňují, a kdybychom nevyšli z časování skutečných čipů, ale z katalogových hodnot, tyto čtečky by s naším emulátorem nemusely komunikovat.
Zbývá vymyslet pro zařízení scenář
, resp. UI, např. takové, že po stisknutí startovacího tlačítka blikne LED jednou, po přečtení vzorového čipu dvakrát, po time-outu dvakrát rychle, v době, kdy přístroj komunikuje se čtečkou, LED svítí nepřetržitě, a pokud by se stalo, že bychom přiložili ke čtečce neinicialisovaný
emulátor, blikne na znamení chybového stavu třikrát.
Výsledek vypadá takto (pro úplnost include file): celé se to vešlo do méně než 400 instrukcí.
Několik poznámek k implementaci:
- Netradičně je využit WDT, kterým zařízení nebudíme, ale naopak uspáváme.
- Před uspáním přístroje je třeba pečlivě ošetřit všechny piny, včetně nevyužitých (resp. hlavně nevyužité), žádný by neměl zůstat plovoucí, to by mohlo drasticky zvýšit spotřebu.
- Pro čtecí algorithmus používáme osmibitový čítač 0, ale pro emulační, kde potřebujeme dosáhnout maximální přesnosti, časování dopočítáváme pomocí empiricky – na softwarovém simulátoru – určených konstant tc0 až tc13.
- Algorithmicky nejsložitější částí je subrutina eibin/eibout, která generuje bitový slot emulátoru. Musíme se snažit o co nejpřesnější časování, s úvahou toho, že další nepřesnost do emulace může vnést kalibrovaný oscilátor, jímž se generují pro atmel hodiny 8 MHz. Jistě bychom mohli použít krystal, ale domnívám se, že je to zbytečné a konstrukci by to jen prodražilo (a navíc bychom museli řešit problém, jak multiplexovat některý z pinů, protože krystalový oscilátor by zabral dva a nevyužitý máme už jen jeden).
- Zařízení by se samozřejmě dalo nejrůznějším způsobem rozšiřovat, např. o implementaci příkazu SCAN, o možnost ukládat do EEPROM víc kódů a přepínat mezi nimi, o port pro komunikaci s počítačem, tak abychom mohli např. emulovat čipy, které jsme fysicky nikdy neměli v ruce, pouze jsme si přečetli jejich kód (mají ho – patrně pro další snížení bezpečnosti – vyleptaný na pouzdru), atp., opět se fantasii tvůrců a napodobitelů žádné meze nekladou.
Takže závěrem: pohrál jsem si, hardwarově jsem se dokonale vyžil, a postavil jsem si, minimálně jako proof of concept, zařízení, které je sice zcela minimalistické (s náklady na součástky kolem pětapadesáti korun), ale které zároveň mnoho lidí na světě nemá. Současně s tím jsem upozornil na závažný problém ve využívání z bezpečnostního hlediska zcela nezpůsobilé technologie dotykových čipů.
Aktualisováno.
Jak je patrno z obrázku, nad editorem schemat jsem nakonec zvítězil. Ztráty na obou stranách byly nicméně těžké.
Komentáře
prosím, nemohl by jste mi napsat, jak přesně ošetřit nepoužité vstupy procesoru před přechodem do sleep modu? A jak naložit se vstupy / výstupy, které vedou do nenapájených periferií. Potřebuji minimalizovat spotřebu u ATMEGA328 a zatím mi i ve sleep modu "žere" o pár mA více, než by měla. Prosím o radu na davidhart(zavináč)seznam.cz Díky David Hart
RSS kanál komentářů k tomuto článku