Forum: Mikrocontroller und Digitale Elektronik Prüfsumme/CRC aus Bitfolge bestimmen?


von Volker D. (fohlen)


Lesenswert?

Hallo zusammen,

ich sitze an einer seriellen Schnittstelle (USARTs (ISO 7816, IrDA)) von 
einem Arm Cortex M3 (stm32l151rbt6) und höre mit einem Raspberry Pi3 die 
Nachrichten ab.


Laut STM Datenblatt wird ein CRC verwendet:
• CRC calculation unit, 96-bit unique ID

Meine Frage/Problem ich weiß nicht wie die letzten 2-Byte vor dem 
Endezeichen Zustande kommen. Ich würde gerne die Tastensignale mit 
meinem PI "kopieren" dazu müsste ich allerdings den Klartext und die 
CRC-Calculation kennen. Möglicherweise wird ein STM CRC32 verwendet, 
kenn mich dabei aber zu wenig aus.
Gibt es eine Möglichleit die entsprechenden Nachrichten zu berechnen?
1
Hex                                                                                      ASCII    
2
Ruhezustand:
3
2a 46 30 31 30 32 30 30   30 32 30 32 30 34 0d 0a   *F010200  020204␍␊ Start einmalig
4
2a 46 30 32 30 32 30 30   30 32 30 32 39 31 0d 0a   *F020200  020291␍␊ Start einmalig
5
2a 46 30 33 30 30 30 30   30 30 30 44 37 43 0d 0a   *F030000  000D7C␍␊
6
2a 46 30 34 30 30 30 30   30 30 30 44 46 46 0d 0a   *F040000  000DFF␍␊
7
2a 46 30 35 30 30 30 30   30 30 30 44 45 31 0d 0a   *F050000  000DE1␍␊
8
...
9
2a 46 46 46 30 30 30 30   30 30 30 44 44 30 0d 0a   *FFF0000  000DD0␍␊
10
2a 46 30 30 30 30 30 30   30 30 30 44 45 39 0d 0a   *F000000  000DE9␍␊
11
2a 46 30 31 30 30 30 30   30 30 30 44 46 37 0d 0a   *F010000  000DF7␍␊
12
2a 46 30 32 30 30 30 30   30 30 30 44 36 32 0d 0a   *F020000  000D62␍␊
13
2a 46 30 33 30 30 30 30   30 30 30 44 37 43 0d 0a   *F030000  000D7C␍␊
14
15
Taste gedrückt:
16
2a 46 46 46 30 30 30 30   36 34 30 43 45 34 0d 0a   *FFF0000  640CE4␍␊
17
2a 46 30 30 30 30 30 30   36 34 30 43 44 44 0d 0a   *F000000  640CDD␍␊
18
2a 46 30 31 30 30 30 30   36 34 30 43 43 33 0d 0a   *F010000  640CC3␍␊
19
2a 46 30 32 30 30 30 30   36 34 30 43 35 36 0d 0a   *F020000  640C56␍␊
20
2a 46 30 33 30 30 30 30   36 34 30 43 34 38 0d 0a   *F030000  640C48␍␊
21
2a 46 30 34 30 30 30 30   36 34 30 43 43 42 0d 0a   *F040000  640CCB␍␊
22
2a 46 30 35 30 30 30 30   36 34 30 43 44 35 0d 0a   *F050000  640CD5␍␊
23
...

Bin für jede Erklärung/Hilfe dankbar :)

Lg fohlen

von Nop (Gast)


Lesenswert?

Da schaust Du erstmal in Reference Manual nach, Kapitel 4. Da findet 
sich u.a. Folgendes:

"Uses CRC-32 (Ethernet) polynomial: 0x4C11DB7"

"Data register (CRC_DR)
Address offset: 0x00
Reset value: 0xFFFF FFFF"

Mit anderen Worten, das ist die Ethernet-CRC32, die zu 0xffffffff 
initialisiert steht.

Mit diesem Wissen gehst Du jetzt zu 
http://create.stephan-brumme.com/crc32/  und ziehst Dir eine geeignete 
Implementation. Üblich ist die hier, wenn Du Daten byte-weise berechnen 
willst:

http://create.stephan-brumme.com/crc32/#sarwate

von Nop (Gast)


Lesenswert?

Ac hja, die CRC ist CRC32, also 4 Byte und nicht 2. Der Programmierer 
hat also entweder nur 2 der 4 Bytes verwendet, entweder die beiden 
höchsten oder niedrigsten wahrscheinlich, oder er nutzt gar nicht die 
CRC32 des ST-Chips, sondern hat per Software eine CRC-16 implementiert, 
die käme mit 2 Bytes auch hin. Wenn Du den Quelltext hast, guck nach, 
sonst ist Basteln angesagt.

Also: probier erstmal mit den Code-Fragmenten von Brumme, die CRC einer 
Nachricht (ohne CRC und RC/LF natürlich) zu rechnen, und guck, ob die 
Bytes da so hinkommen.

Wenn nicht, wird's ne CRC-16 sein, und dann mußt Du mal in einem der 
Code-Fragmente einfach den Datentyp der CRC auf uint16_t verändern. Also 
Polynomial und crc als uint16_t, und dann so wie hier weitermachen, die 
bit-weise Variante. Das ist einfach zu ändern:

http://create.stephan-brumme.com/crc32/#bitwise

Problem:
a) welches Generatorpolynom wurde gewählt?
b) wurde die CRC mit 0xFFFF (16 bit, wo 32-bit 0xFFFFFFFF wäre) 
initialisiert oder mit 0?

Problem a) kannst Du lösen, indem Du hier guckst:
https://en.wikipedia.org/wiki/Cyclic_redundancy_check

Wahrscheinlich CRC-16-CCITT, das wäre die üblichste. Und dann alle 4 
Repräsentationen des Polynoms nacheinander durchprobieren, ob eine das 
gewünschte Ergebnis liefert.

Problem b) auch durch ausprobieren, fang mal mit 0xFFFF an und versuch 
danach erst mit 0 zu initialisieren.

von Volker D. (fohlen)


Lesenswert?

Vielen Dank @Nop, dass hilft mir schon deutlich weiter :)

von Volker D. (fohlen)


Lesenswert?

Guten Abend nochmal,

Leider bin ich bisher nicht auf das erhoffte CRC gekommen. Ich habe mit 
den Brumme Code-Fragmenten den CRC32 und CRC16 versucht allerdings komme 
ich einfach nicht auf die richtige Prüfsumme.

Auf http://www.sunshine2k.de/coding/javascript/crc/crc_js.html habe ich 
meine Ergebnisse kontrolliert und ein paar Varianten durchgespielt.

Hast du noch einen Tipp für mich?

von Nop (Gast)


Lesenswert?

Hmm, wenn ich mir das hier ansehe:

2a 46 30 31 30 32 30 30   30 32 30 32 30 34 0d 0a   *F010200  020204␍␊
2a 46 30 32 30 32 30 30   30 32 30 32 39 31 0d 0a   *F020200  020291␍␊

1) was ist denn das Sternchen? Oder hat die Forensoftware da irgendwas 
umgewandelt?

2) bei den letzten zwei Bytes vor dem CR ist das erste Halbbyte immer 0. 
Das wäre für eine CRC extrem untypisch. Zudem unterscheidet sich in den 
beiden Zeilen die Checksumme auch untypisch wenig. Bei CRCs ist es so, 
daß wenig Unterschiede in den Eingabedaten eine komplett andere 
Checksumme ergeben.

=> Bist Du Dir sicher, daß es sich wirklich um eine CRC handelt? Oder 
könnte das auch eine Checksumme sein, die keine CRC ist?

3) Wenn Du im Laufe der Zeit zweimal einen identischen Zustand 
überträgst, sind die beiden zugehörigen Nachrichten dann auch komplett 
identisch? Oder ist da vielleicht irgendeine Art von Zähler drin?

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Hier:
Beitrag "Tip: Reverse-Engineering von CRCs"
wird doch ein wunderhuebsches Programm fuer solche Probleme 
vorgestellt...

Gruss
WK

von Volker D. (fohlen)


Lesenswert?

1) Die Sternchen werden ebenfalls übertragen '*' = 2a.

2)
- F01 wird bis FFF inkrementiert und fängt dann wieder bei F00 an.
- Am Ende bleibt das 'D' immer gleich außer man drückt eine Taste, daher 
denke ich das sich nur das die letzten zwei Byte ein CRC oder eine 
andere Prüfsumme ist. Bin mir wie gesagt nicht sicher da wir kein 
Quellcode zur Verfügung haben.

3) Die Nachrichten sind immer gleich, daher könnte ich auch eine 
Lookup-Tabelle anlegen. Aber bei 6 analogen Tasten, sind das ca. 20000 
Einträge.

von Nop (Gast)


Lesenswert?

Ahhh, jetzt fällt der Groschen: mit den letzten zwei Bytes meinst Du 
zwei Bytes in ASCII, also zwei Textzeichen. Das wäre dann ein Binärbyte. 
Dann könnte es höchstens eine CRC-8 sein, nicht CRC-16. Wenn CRC. Aber 
das Tool von Weka sieht cool aus für den Zweck, vielleicht findet das ja 
was heraus.

Was man schonmal ausschließen kann, ist eine arithmetische Checksumme:

*F000000  640CDD␍␊
*F010000  640CC3␍␊

Die unterscheidet sich nur in einem Bit, und da würde ich keinen so 
großen Sprung erwarten beim Aufaddieren.

Außerdem kann das aus demselben Grund keine XOR-Checksumme sein, denn 
die dürfte sich im Ergebnis ja nur auf ein Bit auswirken - es ändern 
sich aber beide Halbbytes.

von Georg A. (georga)


Lesenswert?

./reveng -w 8 -s F010200020204 F020200020291 F030000000D7C
./reveng: no models found

Dito mit 16 Bit, aber das ist aufgrund der festen 0 an der viertletzten 
Stelle ohnehin unwahrscheinlich gewesen. Also ist es wohl irgendwas 
Anderes.

Das Ding erfüllt auch ohne reveng nicht den Test auf normale CRCs:

     v         CRC
a) F000000000D E9
b) F010000000D F7
c) F020000000D 62

CRC(a) XOR CRC(b) = 1E
CRC(a) XOR CRC(c) = 8B

Wenn es eine echte CRC wäre, müsste
     v
   F030000000D 7C   (3 = 1 XOR 2 an Position v)

eigentlich ein (1E XOR 8B) = 95 sein. Ist aber 7C. Mööp.

Nachtrag: Die Werte sind eh keine ganzen Bytes. Evtl. ist das F an 
Anfang überflüssig, aber auch das hilft nichts.

: Bearbeitet durch User
von Alexxx (Gast)


Lesenswert?

Also für mich sieht es so aus als wäre der Start mit "2A" eine 
Zeilen-Anfangskennung und die "0D0A" ist die Zeilenende-Kennung.
Schätze mal, dass diese Zeichen aus der CRC-Berechnung ausgenommen sind, 
da sie immer gleich sein müssen...

von C. (Gast)


Lesenswert?

Volker D. schrieb:
> 2a 46 30 35 30 30 30 30   30 30 30 44 45 31 0d 0a   *F050000  000DE1␍␊

Ich weiß nicht ob das hier jedem klar ist, das ist ein Mitschnitt eine 
seriellen Übertragung, n Linke Seite in HEX Ansicht, rechte Seite in 
ASCII Ansicht
2a 46 30 35 30 30 30 30   30 30 30 44 45 31 0d 0a
*  F  0  5  0  0  0  0    0  0  0  D  E  1  CR LF


Es sieht so aus, das mit *FFF ein Komando/Ereigins startet
Danach werden die Parameter nach einander übertragen

Sein die letzten ein oder zwei Bytes überhaupt eine Prüfsumme/CRC

von Nop (Gast)


Lesenswert?

C. schrieb:

> Sein die letzten ein oder zwei Bytes überhaupt eine Prüfsumme/CRC

Denke mal schon, denn die Nachrichten z.B. bei gedrückter Taste sind ja 
identisch, nur der Paketzähler wird bei jeder Nachricht um 1 erhöht. 
Parallel dazu ändern sich die letzten beiden ASCII-Bytes auf nicht 
einfach ersichtliche Weise.

von C. (Gast)


Lesenswert?

Ah, jetzt sehe ich den Unterschied.
*Fxx0000000D?? nicht gedrückt
*Fxx0000640C?? Taste gedrückt

Für eine CRC Berechnung sieht es nicht aus, dafür unterscheidet sich das 
erste Bytes der Prüfsumme nicht weit genung.

Warum ändern sich da mehrer Bytes wenn nur ein Eingangsignal ändert.
Gibt es da noch andere Ereignisse, welche Einfluss auf die gesendete 
Bytefolge haben?

Ich denke das ist ein klassischer Fall von security by obscurity

von Nop (Gast)


Lesenswert?

C. schrieb:

> Ich denke das ist ein klassischer Fall von security by obscurity

Ich denke nicht, daß das überhaupt ein Sicherheitsfeature ist - denn das 
wäre hier ja schon dadurch trivial ausgehebelt, daß man eine 
Replay-Attacke fahren könnte.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.