diff options
-rw-r--r-- | pages/hackabike.md | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/pages/hackabike.md b/pages/hackabike.md new file mode 100644 index 00000000..47036744 --- /dev/null +++ b/pages/hackabike.md | |||
@@ -0,0 +1,352 @@ | |||
1 | title: hackabike | ||
2 | date: 2009-11-02 01:04:00 | ||
3 | updated: 2009-11-02 01:10:40 | ||
4 | author: admin | ||
5 | tags: | ||
6 | |||
7 | Schon immer mal nachts ohne Transportmöglichkeit in einem fremden Bezirk aufgewacht? "Mal schnell" ein Fahrrad benötigt? In Berlin und anderen Großstädten Deutschlands bietet Die Deutsche Bahn mit dem Call-A-Bike Service Abhilfe. | ||
8 | |||
9 | <!-- TEASER_END --> | ||
10 | |||
11 | **Kurzeinführung in das CallABike System**Als Kunde ruft man die | ||
12 | CallABike-Zentrale und gibt per DTMF-Wahl die vierstellige Radnummer | ||
13 | durch. Von der Zentrale erhält man dann den vierstelligen Code, mit dem | ||
14 | man das CallABike-Fahrad öffnen kann. Zur Sicherheit wird man nach dem | ||
15 | Anruf von der Zentrale zurückgerufen. Die letzten vier Ziffern des | ||
16 | Rückrufes enthalten nochmal den Code - annehmen muss man den Anruf | ||
17 | deswegen nicht.\ | ||
18 | \ | ||
19 | Jetzt läuft die Uhr und der Kunde muss pro Minute 6 Cent bezahlen (mit | ||
20 | Bahncard nur 4 Cent). Wenn der Kunde das CallABike einfach mal schnell | ||
21 | abstellen will (z.B. für einen kurzen Einkauf), kann man das CallABike | ||
22 | abschließen und im Display auf ‘Nicht Abgeben’ tippen. Es ist sozusagen | ||
23 | kurz geparkt. Danach kann man das CallABike mit dem gleichen Code wie | ||
24 | beim ersten Mal öffnen. Das kann man so oft wiederholen, wie man möchte. | ||
25 | Die Zeit, die man bezahlen muss, läuft natürlich weiter.\ | ||
26 | \ | ||
27 | Wenn der Kunde das CallABike dann endgültig abgeben will, muss er beim | ||
28 | Schließen auf ‘Abgeben’ tippen; das CallABike gibt einem dann den | ||
29 | Rückgabecode. Mit diesem Code kann man gegenüber der Zentrale | ||
30 | ‘beweisen’, dass man das CallABike wirklich wieder abgeschlossen hat. | ||
31 | Man ruft jetzt einfach wieder die Zentrale an und gibt den Rückgabecode | ||
32 | durch. Danach muss man noch die Straßenecke auf Band sprechen, an der | ||
33 | man das CallABike abgestellt hat. Die Mietzeit wird damit dann auch | ||
34 | beendet.\ | ||
35 | \ | ||
36 | Es ist auch möglich, zwei Räder mit einem Anruf auszuleihen oder | ||
37 | abzugeben. Wenn der Kunde in seiner Nähe kein CallABike-Rad findet, kann | ||
38 | er auch die Zentrale anrufen und fragen, wo das nächste CallABike- Rad | ||
39 | steht. Ein Servicemitarbeiter der Bahn schaut dann in der Datenbank nach | ||
40 | und gibt den Standort des nächstgelegenen CallABike-Rads durch.\ | ||
41 | [Offizielle CallABike Webseite](http://www.callabike.de/i_fahrrad.html)\ | ||
42 | \ | ||
43 | ..."Es gibt natürlich auch andere Zeitgenossen, die haben, schon aus | ||
44 | sportiven Gründen, allerlei versucht, um die Standfestigkeit der | ||
45 | Hardware oder das elektronische Prinzip der eingebauten Mikrochips und | ||
46 | Prozessoren zu ergründen. Sie rückten dem Schloss mit Schraubenziehern | ||
47 | und gängigen Imbusschlüsseln zu Leibe. Sie versuchten ihr Glück mit | ||
48 | Brechstange, Vorschlaghammer, sogar mit der Motorflex. Oder, ganz Smart, | ||
49 | mit Laptop, mit Dechiffrierprogrammen, auch mit Fangfragen an das | ||
50 | Wartungspersonal. Doch vergebens! Wieder lächelt Reth, der einst erste | ||
51 | Ausflüge auf einem grünen Puky-Rad unternahm, sich heutzutage aber als | ||
52 | “postmoderner Urbaniker”, denn als “Fahrradfreak” versteht. Er lächelt | ||
53 | und sagt: “Erst diese Technik macht uns zum weltweit einzigen | ||
54 | stationsunabhängigen Stadtradsystem. Der Code ist nicht zu knacken und | ||
55 | darauf sind wir richtig stolz.”... Kurzer Auszug eines Interviews mit | ||
56 | einem Call A Bike Techniker im Magazin Mobil der Deutschen Bahn | ||
57 | |||
58 | ## Artikel: | ||
59 | |||
60 | Im November 2003 wurde uns ein CallABike ‘zugetragen’, das nicht richtig | ||
61 | abgeschlossen wurde. Dieses musste erstmal als Testobjekt herhalten. Die | ||
62 | meisten dachten, dass in dem Schlosskasten GPS oder sonstiger Funk | ||
63 | enthalten sei, nach dem öffnen war hiervon jedoch nix zu sehen. Um die | ||
64 | Schrauben der Schlosskästen zu öffnen, benötigt man nur ein Torx TR | ||
65 | (Tamper Resistant). In dem Kasten ohne Display ist die Stromversorgung | ||
66 | durch Batterien sichergestellt (3x 1.5V Mono). Die beiden Kästen sind | ||
67 | durch eine Art Bügel miteinander verbunden. In diesem Bügel befindet | ||
68 | sich ein sechspoliges Kabel für den Strom und zwei Spulen. Damit kann | ||
69 | geprüft werden, ob das Schloss wirklich geschlossen ist, oder einfach | ||
70 | kein oder nur irgendein anderer Bolzen zum Verschließen genommen wurde.\ | ||
71 | \ | ||
72 | Der Kasten mit dem Display enthält den Exzentermotor zum öffnen des | ||
73 | Schlosses, zwei Taster (Mikroschalter) und ein kapazitives 5x2-Touchpad. | ||
74 | Die Hauptlogik sitzt unter dem Display. Sie ist nochmal durch eine | ||
75 | Metallplatte abgesichert, welche nur die Kabel zum Display/Touchpad | ||
76 | durchlässt. Damit wird der Motor und der Verschlussmechanismus vor einer | ||
77 | Attacke durchs Display geschützt.\ | ||
78 | \ | ||
79 | Die gesamte Platine ist mit schwarzem Silikon übergossen, das man | ||
80 | erstmal runterkratzen muss. Das geht prima mit einer Mess-Spitze. Außer | ||
81 | einer streichholzschachtelgroßen Platine (Rückseite Datenschleuder 82), | ||
82 | auf der ein [Atmel | ||
83 | AT90S8535](http://www.atmel.com/dyn/products/product_card.asp?family_id=607&family_name=AVR+8%2DBit+RISC+&part_id=2000) | ||
84 | (8-Bit-Risc-Prozessor, 4x8-IO-Pins, 8KB Flash, 512-Bytes-EEProm und | ||
85 | 512-Bytes-RAM) \[1\], ein paar LEDs (rot, grün und IR) und IR-Receiver | ||
86 | aufgebracht sind, enthält der Kasten noch ein paar andere elektrische | ||
87 | Bauteile (Motor, Schalter und ein Beeper). Es ist auch ein | ||
88 | Neigungssensor vorhanden, aber im Code wird er nicht benutzt. Daher | ||
89 | bestand keine Gefahr, uns zu orten. Es wurden ein paar Bilder von der | ||
90 | Aktion gemacht, aber dann lag die Technik erstmal zwei Monate einsam in | ||
91 | einer Kiste, weil wir es nicht geschafft haben, das CallABike zu booten. | ||
92 | Es dauerte eine Weile, bis wir merkten, dass das System nach dem Booten | ||
93 | durch ein Infrarot-Signal aktiviert werden muss. Das war mehr oder | ||
94 | weniger Zufall.\ | ||
95 | \ | ||
96 | Wenn man eine normale Glühlampe benutzt, um besser sehen zu koennen, | ||
97 | piepte die Elektronik gelegentlich scheinbar unmotiviert. Wie sich | ||
98 | später herausstellte, reichte der durch die Glühlampe emittierte | ||
99 | IR-Anteil aus, um den IR-Receiver zu triggern und den Bootvorgang | ||
100 | fortzusetzen. Beim Booten testet sich das System selbst, und der Empfang | ||
101 | eines Infrarot Signals gehört eben dazu. Im Zuge fortschreitender | ||
102 | Professionalisierung™ wurde in der Folgezeit die Glühlampe durch ein | ||
103 | Infrarot-Photon-Micro-Light ersetzt. Bei unserer weiteren Analyse des | ||
104 | Systems begannen wir damit, alle Anschlüsse des Atmel durchzumessen, um | ||
105 | uns einen ungefähren Schaltplan zu erstellen (siehe Bild). Die | ||
106 | Datenblätter für den Atmel und das verwendete Display haben wir uns aus | ||
107 | dem Web besorgt.\ | ||
108 | \ | ||
109 | Im Januar hatte einer der Beteiligten dann endlich eine Idee, wie weiter | ||
110 | vorzugehen sei. Auf der Platine war uns eine unbenutzte 6-polige | ||
111 | Steckerleiste aufgefallen, und wie sich herausstellte, handelt es sich | ||
112 | dabei um den ISP-Connector (In System Programming) des Atmel. Daran | ||
113 | schlossen wir dann ein Atmel-Developer-Board | ||
114 | [STK500](http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2735) | ||
115 | an. Zum Auslesen wurde hauptsächlich das freie | ||
116 | [UISP](http://savannah.nongnu.org/projects/uisp/) (“Uisp is a tool for | ||
117 | AVR microcontrollers which can interface to many hardware in-system | ||
118 | programmers”) benutzt. Die auf dem Atmel vorhandenen | ||
119 | „Intellectual-Property“-Bits waren in einem undefinierten Zustand, | ||
120 | deswegen konnten wir das Flash des Atmels mit der 8KB großen Firmware | ||
121 | auslesen.\ | ||
122 | \ | ||
123 | In den nächsten Wochen waren mehrere Hacker damit beschäftigt, den | ||
124 | ausgelesenen Assemblercode zu verstehen und zu dokumentieren. Dazu | ||
125 | verwendeten wir AVR-Studio und [Ida | ||
126 | Pro](http://www.datarescue.com/idabase/). Den Scramble Code (zum | ||
127 | berechnen der Ausleih- und Abgabecodes) fanden wir relativ schnell, da | ||
128 | sich dort eine Menge rotate-und-shift-Befehle befanden. Den | ||
129 | Initialisierungscode erkannten wir wieder, da wir wussten, dass der | ||
130 | Motor sich beim Einschalten zweimal herumdreht. So konnten wir das | ||
131 | gelernte immer wieder an unserem Prototyp auf Richtigkeit überprüfen.\ | ||
132 | \ | ||
133 | Die Ausleih- und Abgabecodes werden durch einen Scrambler generiert, der | ||
134 | mit einem 16Bit-Counter des CallABikes und einem Zustandswert aufgerufen | ||
135 | wird. Ein gerader Counterwert erzeugt Ausleihcodes und ein ungerader | ||
136 | erzeugt die Abgabecodes. Der Scrambler nutzt den Counter und das | ||
137 | Zustandsbyte, um ein Offset auf ein 1024 Bit großes Feld zu errechnen. | ||
138 | Dieses Feld ist ein für jedes CallABike eindeutiger binärer String, der | ||
139 | als der (wahrscheinlich) eindeutige Key des CallABikes bezeichnet werden | ||
140 | könnte. Von diesem Offset aus werden dann 4x4 Bit genutzt, die die vier | ||
141 | Ziffern für die Ausleih- und Abgabecodes repräsentieren. Die 16 Bit des | ||
142 | Counters werden aber schlecht genutzt, denn schon nach 1024 Iterationen | ||
143 | wiederholen sich die Ausleih- und Abgabecodes. Das bedeutet auch, dass | ||
144 | es nur 512 Ausleihcodes je CallABike gibt, da es nur 512 gerade Offsets | ||
145 | gibt die auf den Key (1024 Bit) zeigen können. CallABikes, die wir | ||
146 | geöffnet haben und die wir wegen der Lockbits nicht auslesen konnten, | ||
147 | haben wir mit einem Script 511 mal resetten lassen (bei einem Reset | ||
148 | erhöht sich der Counter immer um zwei). Damit haben wir den | ||
149 | ursprünglichen Zustand wiederhergestellt, und das CallABike war wieder | ||
150 | ‘in sync’ mit der Zentrale.\ | ||
151 | \ | ||
152 | Wer sich das Display mal genauer angeschaut hat, wird festgestellt | ||
153 | haben, dass der Zeichensatz ein proportionaler ist. Dazu gibt es im Code | ||
154 | eine Tabelle, in der die Länge des Zeichens und die Position im Flash | ||
155 | gespeichert sind. Ein ‘i’ und ein ‘!’ belegen nur ein Byte, wogegen z.B. | ||
156 | ein ‘w’ sieben Bytes belegt. Die großen Logos und das Zahleneingabefeld | ||
157 | liegen als 400 Byte große Bitmaps vor. Die lange schwarze Linie im | ||
158 | CallABike-Logo zeigt die Stärke der Spule im Schloss an. Das haben wir | ||
159 | nur durch das Code-Auditing herausgefunden.\ | ||
160 | \ | ||
161 | Unser erstes Ziel war es, den aus unserem Disassembler erhaltenen | ||
162 | Sourcecode so anzupassen, dass nach dem Assemblieren mit dem Commandline | ||
163 | Tool [Avra](http://avra.sourceforge.net/) (“Assembler for the Atmel AVR | ||
164 | microcontrollers”) ein EXAKT identisches Binary herauskam. Auf der | ||
165 | Grundlage dieses Referenzcodes konnten wir dann endlich änderungen | ||
166 | vornehmen.\ | ||
167 | \ | ||
168 | Nachdem wir uns diese Grundlage geschaffen hatten, konnten wir das | ||
169 | CallABike mit unserem eigenen Code flashen. Da wir keine Vulnerabilities | ||
170 | oder Backdoors fanden (jedes CallABike hat einen eigenen Key, der im | ||
171 | EEPROM gespeichert ist), mit denen man ein CallABike exploiten könnte, | ||
172 | ohne es aufzuschrauben, kamen wir auf die Idee, uns eine eigene Backdoor | ||
173 | in den Code zu programmieren. Hört sich eigentlich ganz leicht an, ist | ||
174 | es aber nicht. Erstmal mussten wir den Code der BAHN optimieren, um uns | ||
175 | den entsprechenden Platz zu schaffen. Schließlich sollte ja auch noch | ||
176 | ein Logo mit 400 Bytes von uns in das 8KB große Flash. Den Datenmüll, | ||
177 | den man über unserem HackABike Logo sehen kann, ist der Backdoor Code. | ||
178 | Das sparte nochmal ca. 150 Bytes. Außerdem wollten wir nicht, dass man | ||
179 | mit dem Backdoor Code normalen Kunden, die das Rad nur geparkt | ||
180 | (verschlossen, aber nicht abgegeben) haben, das ausgeliehene HackABike | ||
181 | wegschnappen konnte. Das erforderte noch ein paar Zeilen mehr im Code. | ||
182 | Auch kann man mit unserem Backdoor Code das HackABike nicht ‘parken’, da | ||
183 | ja der öffner nichts bezahlen muss und deswegen nicht motiviert ist, | ||
184 | sich weiter um das Rad zu kümmern, und es aber auch niemand anders | ||
185 | aufmachen könnte. Um das HackABike auch auf größere Entfernung noch von | ||
186 | seinen unbehandelten Verwandten unterscheiden zu können, haben wir ihm | ||
187 | eine leicht veränderte Blink-Sequenz beigebracht.\ | ||
188 | \ | ||
189 | Im Verlauf der weiteren Analyse des Codes ist uns aufgefallen, dass das | ||
190 | CallABike im Abgabecode integriert Statusinformationen an die Zentrale | ||
191 | durchgeben kann. Je nachdem, in welchem technischen Zustand sich das | ||
192 | CallABike befindet, kann es unterschiedliche Rückgabecodes - abhängig | ||
193 | vom bereits erwähnten Zustandsbyte - angeben. Das CallABike kann z.B. | ||
194 | melden, dass die Batterie nicht mehr lange hält, oder der Motor für das | ||
195 | Schloss nicht mehr in der richtigen Stellung ist. Wenn man z.B. den | ||
196 | Schließknopf sieben mal ohne eingeführten Bolzen drückt, liefert der | ||
197 | Scrambler einen entsprechenden Rückgabecode, der gültig ist, diesen | ||
198 | Zustand aber für die Zentrale erkennbar anzeigt. Von diesen Codes gibt | ||
199 | es 52 (eine Matrix aus 4x13).\ | ||
200 | \ | ||
201 | Die Backdoor erlaubt, das HackABike mit einem von uns festgelegten | ||
202 | Ausleihcode einfach zu öffnen. Wenn man das HackABike dann wieder | ||
203 | abgibt, ist es ganz normal wieder ausleihbar. Es steht auch wieder der | ||
204 | Ausleihcode des vorherigen Kunden im Display. Die Zentrale merkt von | ||
205 | diesem eingeschobenen Ausleihvorgang nichts - außer, dass es an einem | ||
206 | anderem Ort steht, als es in der Datenbank vermerkt ist. Wenn es dann | ||
207 | aber wieder normal ausgeliehen und abgestellt wird, ist auch in der | ||
208 | Zentrale alles wieder in Ordnung.\ | ||
209 | \ | ||
210 | Um ein CallABike in ein HackABike zu verwandeln, mussten wir sechs | ||
211 | Schrauben auf der Innenseite des Schlosskastens mit dem Display öffnen | ||
212 | und das Kabel des STK500 an den ISP-Anschluss der Platine stecken. | ||
213 | Danach haben wir ein Script gestartet, dass das Flash und den EEPROM | ||
214 | Bereich ausliest. Das EEPROM wird danach mit zurückgesetztem Counter und | ||
215 | dem Flash mit unserer Backdoor wieder zurückgeschrieben. Damit niemand | ||
216 | unsere Backdoor auslesen kann, haben wir natürlich noch die Lockbits | ||
217 | gesetzt. Ein geschulter Hacker brauchte ca. 12 Minuten, um zwei | ||
218 | CallABikes parallel in HackABikes zu verwandeln. Insgesamt wurden knappe | ||
219 | 10% der in Berlin verteilten CallABikes in ein HackABike umgebaut indem | ||
220 | ihnen eine neue firmware verpasst wurde. Da UISP das Setzen der Lockbits | ||
221 | nicht korrekt unterstützte, mussten wir das erstmal einbauen. Dazu haben | ||
222 | wir den Output von AVR-Studio mit einem serial sniffer mitgelesen und | ||
223 | uns die entsprechenden Kommandos für das STK500 rausgesucht und in UISP | ||
224 | eingebaut.\ | ||
225 | \ | ||
226 | Abschließend ist festzustellen, dass das technische Design des CallABike | ||
227 | in unseren Augen sehr gut ist. Jedes CallABike hat vermutlich einen | ||
228 | eigenen 1024 Bit Key, der benötigt wird, um die Abgabe- und Ausleihcodes | ||
229 | berechnen zu können. Dazu muss vermutlich das CallABike geöffnet und | ||
230 | ausgelesen werden. Es wurde nur versäumt, die Lockbits zu setzen, um die | ||
231 | Firmware vor dem Auslesen zu schützen. Unsere Attacke ist von den | ||
232 | verbrauchten Mannstunden wohl mehr Wert als ein paar Dutzend CallABikes. | ||
233 | |||
234 | EEPROM Content: | ||
235 | |||
236 | 0x0000 - 0x0001 unused | ||
237 | 0x0002 lock_sensor_calibration | ||
238 | 0x0003 - 0x0019 unused | ||
239 | 0x001A - 0x001B 16bit counter (scrambler) | ||
240 | 0x001C unused | ||
241 | 0x001D - 0x001F CallABike Number | ||
242 | 0x0020 - 0x009F 128 Byte Random (Key) | ||
243 | 0x00A0 - 0x00A2 first three bytes of key again | ||
244 | 0x00A3 - 0x00AF unused | ||
245 | 0x00B0 - 0x01FF textmessages for display | ||
246 | |||
247 | |||
248 | bikecounter: 0x015E | ||
249 | EEPROM belongs to bike 3856 | ||
250 | |||
251 | Counter 0x0162: 3042 9843 5360 <-- rentcode | ||
252 | |||
253 | -00- -01- -02- -03- -04- -05- -06- -07- -08- -09- -10- -11- -12- -13- | ||
254 | 00: 8584 7572 6970 4597 9119 4285 2144 0277 3197 0072 5545 6487 6341 9664 | ||
255 | 01: 5244 2345 5463 6065 9493 2971 9352 5402 5519 4579 8355 9533 9245 4926 | ||
256 | 10: 6615 7508 8159 7355 8125 3632 2920 4348 0484 7784 0084 6154 8905 6742 | ||
257 | 11: 6234 7953 4741 7386 8181 2930 6280 8658 6805 5432 4092 7161 2070 8554 | ||
258 | |||
259 | Counter 0x0164: 7240 7043 9766 <-- rentcode | ||
260 | |||
261 | -00- -01- -02- -03- -04- -05- -06- -07- -08- -09- -10- -11- -12- -13- | ||
262 | 00: 1542 5463 4821 7206 8181 5293 5100 8370 7662 7831 6561 1071 9350 7554 | ||
263 | 01: 8480 7640 5094 4420 7470 5025 6472 0596 9260 5499 4274 0341 7092 7363 | ||
264 | 10: 6369 3545 6991 9042 0121 7702 7931 5600 6755 8264 9063 9596 6918 8761 | ||
265 | 11: 4254 0960 8294 7529 9793 4954 5455 9345 0183 3995 4992 5949 4392 9538 | ||
266 | |||
267 | Here you see the open and close pins of the bike 3856 with | ||
268 | the counter at 0x0162 | ||
269 | At first the Customer gets the open pin 3042. When the customer | ||
270 | closes the lock and everything is ok he gets the return code 8584. | ||
271 | When for example the battery (-01-) is exhausted he gets the return code | ||
272 | 7572. | ||
273 | |||
274 | |||
275 | The following commands are possible via infrared: | ||
276 | 0x5B read bikenumber | ||
277 | 0xCE calibrate coil | ||
278 | 0xC5 read RAM from 0x00AD | ||
279 | |||
280 | after transmit of the first 32 bytes of the key | ||
281 | 0xCA enable watchdog (reboot) | ||
282 | 0xC8 write and read the key of the EEPROM | ||
283 | 0xCD write and read other parts of the EEPROM | ||
284 | |||
285 | |||
286 | //Code zum Generieren der Abgabe/Ausleihcodes bei gegebenem Key aus dem eeprom | ||
287 | |||
288 | unsigned char g_key[4]; | ||
289 | |||
290 | void scrambler(uchar param, long counter) | ||
291 | { | ||
292 | long bitoffset; | ||
293 | uchar r21 = param, r28 = 1; | ||
294 | short r27_26 = counter, short r31_30; | ||
295 | r28 <<= r27_26 & 7; | ||
296 | r27_26 += r21; | ||
297 | r27_26 &= 0x3ff; | ||
298 | r31_30 = r27_26; | ||
299 | r27_26 <<= 5; | ||
300 | r27_26 -= r31_30; | ||
301 | r27_26 &= 0x3ff; | ||
302 | r27_26 += r28; | ||
303 | r27_26 &= 0x3ff; | ||
304 | bitoffset = r27_26 & 7; | ||
305 | r27_26 >>= 3; | ||
306 | r27_26 += 0x20; | ||
307 | r27_26 &= 0xff; | ||
308 | fillkey(r27_26,bitoffset); | ||
309 | } | ||
310 | |||
311 | void fillkey(long address, long bitoffset) | ||
312 | { | ||
313 | uchar r16; | ||
314 | long fullkey; | ||
315 | fullkey = eeprom[address++] << 16; | ||
316 | fullkey += eeprom[address++] << 8; | ||
317 | fullkey += eeprom[address++]; | ||
318 | fullkey >>= bitoffset; | ||
319 | r16 = fullkey & 0xf; | ||
320 | if(r16 >= 10) r16 -= 10; | ||
321 | g_key[3] = r16; | ||
322 | r16 = (fullkey >> 4 ) & 0xf; | ||
323 | if(r16 >= 10) r16 -= 6; | ||
324 | g_key[2] = r16; | ||
325 | r16 = (fullkey >> 8 ) & 0xf; | ||
326 | if(r16 >= 10) r16 -= 10; | ||
327 | g_key[1] = r16; | ||
328 | r16 = (fullkey >> 12) & 0xf; | ||
329 | if(r16 >= 10) r16 -= 6; | ||
330 | g_key[0] = r16; | ||
331 | } | ||
332 | |||
333 | //Fürs CallABike mit der Nummer 2883 z.B.: | ||
334 | unsigned char eeprom[ ] = | ||
335 | { | ||
336 | 0x5A,0xD5,0xAD,0x6B,0xFD,0xD7,0x34,0x78, | ||
337 | 0xB3,0x03,0x22,0x13,0x61,0x23,0xAD,0xFE, | ||
338 | 0x51,0x6E,0xAA,0xA2,0xD4,0xB7,0xBA,0xC0, | ||
339 | 0x78,0x9A,0x84,0x55,0x2A,0xB9,0x6E,0xBC, | ||
340 | 0x33,0x15,0x2C,0x97,0x33,0x98,0x4B,0x78, | ||
341 | 0x43,0xE5,0x20,0xD5,0x1C,0x1C,0x75,0x12, | ||
342 | 0x2A,0x91,0x17,0xFC,0x0C,0x61,0x31,0x31, | ||
343 | 0x50,0x6D,0xFD,0x5C,0xC5,0x60,0x8D,0xE0, | ||
344 | 0x0A,0xF2,0x85,0xF1,0x3B,0xA3,0xBD,0x74, | ||
345 | 0xF3,0xD4,0x9E,0xBB,0x45,0x95,0x69,0x24, | ||
346 | 0x79,0x36,0x9A,0xA6,0x66,0x96,0xFB,0xE8, | ||
347 | 0x5D,0x38,0x34,0x28,0xC0,0x51,0x3B,0x18, | ||
348 | 0x46,0xCA,0xD9,0xE3,0xD7,0xC8,0x86,0x01, | ||
349 | 0x11,0x60,0xF2,0xF0,0xA4,0xA4,0xEF,0x16, | ||
350 | 0x3E,0xBE,0xB9,0x1F,0xA8,0xF9,0x61,0x0B, | ||
351 | 0xD6,0x7F,0x75,0xE7,0xF4,0x31,0x3F,0x6B | ||
352 | }; | ||