• Keine Ergebnisse gefunden

Chipkarten-Ansteuerung

Inter-IC-Bus-Komponenten

CONFIGURATION REGISTER

9.7 Chipkarten-Ansteuerung

EEPROM-Speicher in Chipkartenform werden auf Bankkarten, Krankenkas-senkarten und in SIM-Karten von Mobiltelefonen verwendet. Mit Speicher-gr¨oßen bis zu 64 kByte lassen sich nicht allzu viele Informationen darauf ab-speichern. F¨ur pers¨onliche Daten wie Adresse oder Identifikationsnummern

12Vgl. Tabelle 9 im Datenblatt<embedded-linux-dir>/datasheets/tmc222.pdf.

reicht dies jedoch aus. F¨ur die Integration in eigene Anwendungen steht eine Vielzahl von M¨oglichkeiten offen. Beispiele sind die Umsetzung einer Zugangs-kontrolle oder eines Abrechnungssystems. Da EEPROM-Chipkarten ¨uber eine I2C-Schnittstelle angesprochen werden, bietet sich eine Eingliederung in das vorgestellte Buskonzept an. Abbildung 9.13 zeigt eine Chipkarte mit Kontak-tiereinrichtung (vgl. hierzu auch die Bezugsquellentabelle in Anhang E).

Abb. 9.13.EEPROM-Chipkarte AT24C128SC mit Kontaktiereinrichtung.

9.7.1 EEPROM-Chipkarte AT24Cxx

Die EEPROM-Chipkarten der Reihe AT24Cxx von Atmel sind mit Spei-chergr¨oßen zwischen 2 kByte und 64 kByte erh¨altlich und entsprechen dem Standard ISO 7816 f¨ur Smart Cards. In diesem Abschnitt wird eine Karte AT24C128SC mit 16 kByte Speicher (128 kbit) verwendet. Die Zugriffsfunktio-nen sind f¨ur alle Speichergr¨oßen gleich, sodass problemlos auch andere Karten eingesetzt werden k¨onnen. Der Speicher ist in Seiten bzw. Pages `a 64 Bytes organisiert, im vorliegenden Falle in 256 Seiten. Die Adresse ist auf den Wert 0x50festgelegt und nicht ver¨anderbar. Da in der Regel nur ein Leseger¨at am Bus angeschlossen ist sollte dies kein Problem darstellen.

!

1

Adresse

0 1 0 0 0 0 R/W

Abb. 9.14.Adressregister des AT24C128SC.

192 9 Inter-IC-Bus-Komponenten

Nach der ¨Ubertragung einer 16-Bit-Adresse f¨ur die zugeh¨orige Seite nach dem I2C-Adressbyte k¨onnen f¨ur diese Seite bis zu 64 Bytes geschrieben werden. Da-bei ist Vorsicht geboten: Werden mehr als 64 Byte geschrieben, so findet ein sog. Roll-Over innerhalb der Seite statt. Die zu Beginn gespeicherten Bytes werden dann erneut geschrieben bzw. ¨uberschrieben. Ein Lesen hingegen ist

¨uber den gesamten Bereich m¨oglich. Die interne Adresse wird dabei nach je-dem Zugriff auf ein einzelnes Daten-Byte (Current Address Read) oder ei-ne Sequenz (Sequential Read) erh¨oht. Die Adresse kann zuvor mit einem Schreibvorgang ohne Datentransfer gesetzt werden.

Neben den genannten Zugriffsmethoden k¨onnen Daten-Bytes auch zuf¨allig ausgelesen werden. Daf¨ur ist zun¨achst eine Dummy-Adresse zu senden, im Anschluss wird ein zuf¨alliger Wert gelesen. Abbildung 9.15 zeigt die Spei-cheraufteilung der Karte und eine f¨ur die Klasse IICChipcard gew¨ahlte Re-pr¨asentationsform mit Header- und Datenteil.

9.7.2 Die Klasse IICChipcard

Folgende ¨Uberlegungen fließen in die Konzeption der Schnittstelle ein: Die KlasseIICChipcardsoll I2C-Module vom Typ einer SmartCard repr¨asentieren und abstrakte Zugriffsfunktionen bereitstellen. Hier stellt sich zun¨achst die Frage, in welcher Form die Daten auf der Karte hinterlegt werden sollen. Je nach Art der zu speichernden Daten sind vielf¨altige M¨oglichkeiten denkbar.

Sinnvoll ist es in jedem Fall, vor den eigentlichen Daten Informationen ¨uber die Karte selbst sowie ¨uber den enthaltenen Datentyp abzulegen, um die Chipkar-ten dieses Typs eindeutig identifizieren zu k¨onnen. Hiermit kann im regul¨aren Betrieb eine ¨Uberpr¨ufung des Kartentyps erfolgen, um nicht f¨alschlicherweise die Chipkarte einer Bank oder einer Krankenkasse zu ¨uberschreiben. Diese In-formationen werden in einemHeaderenthalten sein, welcher die erste Seite des Speichers belegt – 64 Byte sollten hierf¨ur ausreichen (vgl. Abbildung 9.15).

!

Page 0

Header (max. 64 Bytes)

Page 1 Page 255

!

Daten (max. 16,32 kB)

0 64 255*64

Abb. 9.15.Speicherorganisation eines AT24C128SC-EEPROM-Chips: 16 384 Bytes Gesamtspeicher, organisiert in Seiten (Pages) zu je 64 Byte. In der Klasse IICChipcardwird die erste Seite f¨ur Header-Informationen verwendet, die restlichen Seiten stehen f¨ur Nutzdaten zur Verf¨ugung.

F¨ur den Header wurde in Chipcard.h die nachfolgende Struktur definiert, um Informationen ¨uber die Karte zu speichern. Falls ben¨otigt, kann diese

zus¨atzlich um Informationen ¨uber den verwendeten Datentyp bzw. die Gr¨oße der Daten erweitert werden:

t y p e d e f s t r u c t {

c h a r t y p e _ i d [ 1 0 + 1 ] ; // ID f o r c a r d s of t h i s t y p e c h a r c a r d _ n u m b e r [ 1 0 + 1 ] ; // i n d i v i d u a l c a r d n u m b e r c h a r d e s c r [ 3 0 + 1 ] ; // d e s c r i p t i o n

} C h i p c a r d H e a d e r _ t ;

Je nach Anwendungsfall sind die Kartendaten sehr unterschiedlich, sodass in dieser Klasse keine generische Struktur vorgeschlagen wird. Dies soll durch die Definition einer Struktur in der Anwendung selbst geschehen. Die Kartendaten werden direkt ¨uber die API bezogen bzw. an diese weitergeleitet und nicht in der Klasse zwischengespeichert. Als einzige Membervariable wird die Header-Information vorgehalten:

C h i p c a r d H e a d e r _ t m _ H e a d e r ; // h e a d e r o b j e c t

Die folgenden Methoden stehen dem Anwender als API zur Verf¨ugung:

IICChipCard(IICBus& bus, int addr, string name);

Legt ein Objekt vom Typ IICChipCardan. Neben den Standardangaben f¨ur Bus-Objekt bus, Adresseaddrund Bezeichnung name sind keine wei-teren Informationen notwendig. ¨UbersetIsRemovable()wird angegeben, dass es sich bei diesem Modul um eine steckbare I2C-Komponente handelt, welche nicht immer am Bus vorhanden ist. Eine Fehlerkorrektur und eine automatische Abschaltung wird damit unterbunden.

int readSCHeader();

Liest den Header der Karte und liefert den Wert 0 zur¨uck, falls die Typ-ID der Karte mit der Definition intype id¨ubereinstimmt. Im Fehlerfall wird

−1 zur¨uckgegeben.

void printSCHeader();

Liest den Header der Karte aus und gibt die Informationen auf der Stan-dardausgabe aus.

int formatSCHeader(const char* card number, const char* descr);

Schreibt die Header-Informationen mit Kartennummer card number und Beschreibung descr auf eine neue Karte. Diese Funktion ist mit Vor-sicht zu verwenden und sollte nur auf eindeutig bekannte Chipkarten an-gewandt werden. In der Applikation ist eine entsprechende Absicherung gegen¨uber vorschnellem Formatieren vorzusehen. Im Erfolgsfall wird 0 zur¨uckgegeben, im Fehlerfall−1.

int readSCData(char* dest, unsigned long size);

Liest size Daten-Bytes von der Karte und legt diese an der Stelle dest ab. Im Erfolgsfall wird die Anzahl gelesener Daten-Bytes zur¨uckgegeben, sonst −1.

194 9 Inter-IC-Bus-Komponenten

int writeSCData(char* source, unsigned long size);

WiereadSCData(), hier aber schreibend mit Bezug der Daten vonsource. Das Schreiben erfolgt seitenweise mit mehrmaliger Adressierung der Ein-zelseiten, da hierbei nicht wie beim Lesen einroll-over zur n¨achsten Sei-te stattfindet. Im Erfolgsfall wird die Anzahl geschriebener DaSei-ten-BySei-tes zur¨uckgegeben, sonst−1.

bool isAvailable();

F¨uhrt einen Dummy-Zugriffsversuch auf die Karte durch und ¨uberpr¨uft so, ob diese eingesteckt ist. Diese Routine kann verwendet werden, falls keine Auswertung des entsprechenden Pins der Kontaktierungseinrichtung m¨oglich ist.

Im Beispielverzeichnis chipcard veranschaulichen die zwei Beispiele read chipcard.cpp undwrite chipcard.cppdie Verwendung der Klasse in einer eigenen Anwendung. Die Formatierungsanweisung ist sicherheitshalber in write chipcard.cppzun¨achst deaktiviert und muss einkommentiert werden, um initial eine neue, leere Chipkarte zu beschreiben:

// # d e f i n e W R I T E _ H E A D E R

Falls die Lese- und Schreibzugriffe mit verschiedenen Host-Rechner-Architekturen durchgef¨uhrt werden, so spielt auch hier – wie bei jeder

¨Ubertragung von Ganzzahlen als Bin¨ardaten – die Byte-Reihenfolge eine wich-tige Rolle. Abschnitt 13.2.5 im Kapitel zur Netzwerkkommunikation widmet sich dieser Problematik.

Eine Anmerkung: F¨ur die KlasseIICChipCardbedeutet es keinen Unterschied, welcher Art die Daten auf der Karte sind, da nur reine Zeichenketten abge-legt werden. Zugriffs- und Manipulationsmethoden werden im Anwendungs-programm implementiert. Der folgende Abschnitt zeigt, wie sensible Daten durch eine AES-Verschl¨usselung abgesichert werden k¨onnen.

9.7.3 AES-Verschl¨usselung

Wenn auf einer Chipkarte sensible Daten gespeichert werden, so ist es sinnvoll, diese verschl¨usselt abzulegen. Unter vielen m¨oglichen Ver-schl¨usselungsverfahren hat sich in den letzten Jahren der sog. Advanced En-cryption Standard (AES)in vielen Anwendungen der Kommunikationstechnik und Datenhaltung durchgesetzt und wird unter anderem auch in WPA213, SSH14, und RAR15 verwendet.

13Wi-Fi Protected Access 2, Implementierung eines Sicherheitsstandards f¨ur Funk-netzwerke.

14Secure Shell, verschl¨usseltes Netzwerkprotokoll.

15Roshal Archive, Datenkompressionsalgorithmus.

Der AES-Algorithmus soll lediglich in den Grundz¨ugen vorgestellt werden, um die Implementierung der Klasse AES im n¨achsten Abschnitt zu erkl¨aren. F¨ur weiterf¨uhrende Informationen sei auf die offizielle AES-Spezifikation verwie-sen [NIST 08]. AES ging als Gewinner eines vomNational Institute of Stan-dards and Technology (NIST) ausgeschriebenen, offenen Wettbewerbs hervor und l¨oste den bis dahin verwendeten Data Encryption Standard (DES) als neuen Standard ab. AES gilt als sehr sicher und ist in den USA auch f¨ur die Verschl¨usselung von Dokumenten mit hoher Geheimhaltungsstufe zugelassen.

AES ist ein iterativer Blockchiffrier-Algorithmus, bei dem Datenbl¨ocke von 128 bit mit einem Schl¨ussel der L¨ange 128, 192 oder 256 bit verschl¨usselt wer-den. Er basiert auf dem Rijndael-Algorithmus und stellt durch die Daten-blockl¨ange eine spezialisierte Form dar. In der Originalversion ist diese mit 128, 160, 192, 224 oder 256 bit variabel gehalten. Ein 128-Bit-Datenblock l¨asst sich als Matrix mit 4×4 Bytes darstellen. Auf jeden Datenblock werden nach-einander bestimmte Transformationen angewandt (vgl. Abbildung 9.16). Diese Transformationen h¨angen dabei nicht vom vollst¨andigen Originalschl¨ussel ab, sondern von Teilen davon.

Abb. 9.16. Vier m¨ogliche AES-Transformatiosschritte f¨ur einen 4×4-Datenblock.

Die AES-Verschl¨usselung l¨auft in mehreren Runden ab, wobei die Anzahl n von der gew¨ahlten Verschl¨usselungstiefe abh¨angt (vgl. Abbildung 9.17). Mit ei-nem Schl¨ussel der Gr¨oße 128 werden 10 Verschl¨usselungsrunden durchgef¨uhrt, bei einer L¨ange von 192 oder 256 bit sind dies 12 bzw. 14 Runden. In einem initialen Schritt werden aus dem Schl¨ussel (n+ 1) sog. Rundenschl¨ussel extra-hiert (KeyExpansion). Der Datenblock wird dann zun¨achst mit dem Runden-schl¨ussel verkn¨upft (AddRoundKey), bevor mit dem Schleifendurchlauf begon-nen wird. W¨ahrend jeder Runde werden nacheinander die folgenden Operatio-nen auf dem zu verschl¨usselnden Datenblock angewandt:

1. SubBytes: In jeder Runde wird zun¨achst f¨ur alle Felder im Block ein

¨Aquivalent in der S-Box gesucht. Die Daten werden damit monoalpha-betisch verschl¨usselt.

2. ShiftRow: Bei dieser Transformation werden die Zeilen der 4×4-Matrix um eine bestimmte Anzahl von Spalten nach links verschoben. ¨Uberlaufende

196 9 Inter-IC-Bus-Komponenten

Zellen werden erneut rechts beginnend fortgesetzt. Bei einer Blockl¨ange von 128 bit betr¨agt die Anzahl der Verschiebungen 0, 1, 2 und 3.

3. MixColumn: NachShiftRow werden nun die Spalten vermischt. Jede Zel-le einer Spalte wird dazu mit einer Konstanten multipliziert. Anschlie-ßend werden die Ergebnisse bitweise XOR-verkn¨upft. Durch diese Trans-formation tritt jedes Byte einer Spalte in Wechselwirkung mit jedem ande-ren Byte der Spalte. Der mathematische Zusammenhang ist in [NIST 08]

ausf¨uhrlich erkl¨art.

4. AddRoundKey: In der Initialisierung und am Ende jeder Ver-schl¨usselungsrunde wirdAddRoundKey ausgef¨uhrt. Hierbei wird der Block mit dem aktuellen Rundenschl¨ussel bitweise XOR-verkn¨upft. Dies ist die einzige Funktion in AES, in die der Benutzerschl¨ussel eingeht.

AddRoundKey

SubBytes ShiftRows MixColumns AddRoundKey

Schlüssel Block

KeyExpansion

Runden-schlüssel 1..n+1 n Runden

n-1

Abb. 9.17. AES-Verschl¨usselungsprozess.

In der letzten Verschl¨usselungsrunde wird auf die TransformationMixColumns verzichtet. F¨ur die Durchf¨uhrung einer Verschl¨usselung wird in umgekehrter Reihenfolge vorgegangen. Die AES-Implementierung ist im Vergleich zu an-deren Algorithmen sehr performant und l¨asst sich auch auf kleineren Pro-zessoren bis hin zu 8-Bit-Mikrocontrollern schnell durchf¨uhren. Der RAM-Speicherbedarf ist durch die blockweise Behandlung relativ gering. Bei stark beschr¨ankten Ressourcen k¨onnen die einzelnen Rundenschl¨ussel auch nachein-ander berechnet werden.

Im folgenden Abschnitt wird der AES-Algorithmus in einer Klasse AES im-plementiert, um ¨uber eine allgemein gehaltene Schnittstelle aus Dateien oder Speicherbereichen verschl¨usselte Datenobjekte zu erzeugen.

9.7.4 Die Klasse AES

Die Klasse AES repr¨asentiert verschl¨usselte oder unverschl¨usselte Datenobjek-te und sDatenobjek-tellt Methoden zur Manipulation bereit. Als DaDatenobjek-tenquellen kommen je nach Anwendung Dateien oder Speicherbereiche in Frage. Die bereitgestellten Daten k¨onnen bereits verschl¨usselt sein oder auch im Klartext vorliegen.

F¨ur eine m¨oglichst ¨ubersichtliche Gestaltung der API wird keine spezielle Ein-und Ausgabemethode f¨ur ver- oder entschl¨usselte Daten implementiert, son-dern ein Großteil der Logik in die Klasse integriert. Die AES-Quelltext-Dateien sind unter<embedded-linux-dir>/src/tools/abgelegt.

Die Betrachtungsweise ist wie folgt: Ein Objekt vom Typ AES wird als ab-strakter Datenspeicher angesehen, in welchen ver- oder entschl¨usselte Daten geladen werden k¨onnen (vgl. Abbildung 9.18). Eine Platzierung der Daten in den Membervariablenmp data encrodermp data decrgeschieht automa-tisch. Der Anwender muss lediglich die Datenquelle in Form einer Speicherstelle oder einer Datei angeben, nicht aber den Verschl¨usselungszustand.