Université de Caen Basse-Normandie Projet individuel Comunication sécurisée pour Arduino Auteur : sami Allani Encadrant : M. Jacque Madleine 07 mars 2013
Table des matières 1 Context 2 2 Arduino 2 3 Problématique 4 4 Authentification HMAC 4 4.1 HMAC............................... 4 4.2 Keccak............................... 5 5 mise en œuvre 8 5.1 Partie serveur :.......................... 8 5.2 Partie client :........................... 8 5.3 Partie importante du code :................... 8 1
1 Context Le but de ce projet est de mettre en œuvre un protocole d authentification et de mettre en place un chiffrement pour la communication entre le module Arduino et un serveur. 2 étapes : 1. Mettre en œuvre une authentification de type HMAC en utilisant Keccak. 2. Proposer le protocole de chiffrement qui convient le mieux à notre architecture. 2 Arduino Figure 1 Arduino Ethernet Arduino : Le système Arduino est un outil pour fabriquer de petits ordinateurs qui peuvent capter et contrôler davantage de choses du monde matériel que votre ordinateur de bureau. C est une plateforme open-source d électronique programmée qui est basée sur une simple carte à microcontrôleur (de la famille AVR), et un logiciel, véritable environnement de développement intégré, pour écrire, compiler et transférer le programme vers la carte à microcontrôleur. Arduino peut être utilisé pour développer des objets interactifs, pouvant recevoir des entrées d une grande variété d interrupteurs ou de capteurs, et pouvant contrôler une grande variété de lumières, moteurs ou toutes autres sorties matérielles. Les projets Arduino peuvent être autonomes, ou bien ils peuvent communiquer avec des logiciels tournant sur votre ordinateur (tels que Flash, Processing ou MaxMSP). Les cartes électroniques peuvent être fabriquées manuellement ou bien être 2
achetées pré-assemblées ; le logiciel de développement open-source peut être téléchargé gratuitement. Le langage de programmation Arduino est une implémentation de Wiring, une plateforme de développement similaire, qui est basée sur l environnement multimédia de programmation Processing. Le logiciel Arduino et le langage Arduino sont publiés sous licence open source, disponible pour être complété par des programmateurs expérimentés. Le langage peut être aussi étendu à l aide de librairies C++, et les personnes qui veulent comprendre les détails techniques peuvent reconstruire le passage du langage Arduino au langage C pour microcontrôleur AVR sur lequel il est basé. De la même façon, vous pouvez ajouter du code du langage AVR-C directement dans vos programmes Arduino si vous voulez. Arduino Ethernet : L Ethernet Arduino est une carte basée sur le microcontrôleur ATmega328. Il dispose de 14 entrées / sorties TOR broches, 6 entrées analogiques, d un oscillateur à quartz 16 MHz, une connexion RJ45, une prise de courant, d une embase ICSP, et un bouton de réinitialisation. L Arduino Ethernet est différente de des autres cartes car elle n a pas une puce pilote USB intégré-série, mais dispose d une interface Ethernet Wiznet. Ceci est l interface que l on retrouve sur le Ethernet sheild. Un lecteur de carte microsd intégré, qui peut être utilisé pour stocker des fichiers pour le service sur le réseau, est accessible par la Bibliothèque SD. Broche 10 est réservée à l interface Wiznet, SS pour la carte SD est sur la broche 4. L entête à 6 broches de programmation série est compatible avec l adaptateur USB de série et aussi avec les câbles USB FTDI ou avec Sparkfun et Adafruit FTDI USB de style de base-série planches en petits groupes. Figure 2 Adaptateur USB-série Adaptateur USB-série : Cette carte convertit une connexion USB à une série de 5 volts qui peut être connecter directement à l Arduino Ethernet 3
ou autres microcontrôleurs, ce qui leur permet de parler à l ordinateur. Il dispose d une Atmega8U2 programmé comme un convertisseur USB-série. 3 Problématique Arduino Ethernet Microcontroller ATmega328 Operating Voltage 5V Input Voltage (recommended) 7-12V Input Voltage (limits) 6-20V Digital I/O Pins 14 Analog Input Pins 6 DC Current per I/O Pin 40 ma DC Current for 3.3V Pin 50 ma Flash Memory 32 KB (ATmega328) SRAM 2 KB (ATmega328) EEPROM 1 KB (ATmega328) Clock Speed 16 MHz Le problème qui s oppose à la mise en œuvre d une authentification et d un chiffrement sur un Arduino est la gestion de mémoire. Comme on le voit dans le tableau précèdent le microcontrleur dispose d une capacité mémoire vive (1 Kbytes) assez limité, tandis que pour les fonctions de hachages et de chiffrement sont relativement gourmands en mémoire. une des solutions est d utiliser la mémoire fash (32 Kbytes) lors d exécution des calculs, pour cela on dispose d une bibliothéque pgmspace qui appartient à l ensemble de bibliothèques d avr et qui implémente des primitives pour l écriture et la lecture sur la mémoire flash. En utilisant le mot clé PROGMEM qui enregistre le contenu d une variable dans la mémoire flash et en gardant sa manipulation comme si c été sur la SRAM. 4 Authentification HMAC 4.1 HMAC HMAC : (hash-based message authentication code) est une construction pour calculer un code d authentification de message (MAC) comportant une fonction de hachage cryptographique en association avec une clé de chiffrement secrète. Comme avec n importe quel MAC, il peut être utilisé à la fois pour vérifier l intégrité des données et l authentification des messages. Toute fonction de hachage cryptographique, comme SHA-1 ou Keccak, peut être 4
utilisé dans le calcul d un HMAC. Le niveau de sécurité de HMAC dépend du niveau de sécurité de la fonction cryptographique de hachage utilisé, la taille de sa sortie de hachage est la même pour le HMAC. Figure 3 Authentification HMAC Figure 4 mécanise HMAC ( ( ) ) HMAC K (m) = h (K opad) h (K ipad) m 4.2 Keccak Keccak : est une fonction de hachage cryptographique conçu par Guido Bertoni, Joan Daemen, Michaël Peeters, et Gilles Van Assche. Le 2 Octobre 5
2012, Keccak a été sélectionné comme le gagnant de la compétition du NIST fonction de hachage. SHA-3 n est pas destiné à remplacer SHA-2, aucune attaque significative sur SHA-2 a été démontrée. En raison des attaques réussies sur MD5, SHA-0 et les attaques théoriques sur SHA-1, le NIST a perçu la nécessité d une fonction hachage cryptographique différent, qui est devenu SHA-3. Les auteurs affirment 12,5 cycles par octet sur un processeur Intel Core 2. Toutefois, dans les implémentations matérielles, il est nettement plus rapide que tous les autres finalistes. SHA-3 utilise la construction éponge dans lequel les blocs de message sont XORé dans les bits initiaux de l état et qui sont ensuite permutées. Dans la version utilisée dans SHA-3, l État se compose d un ensemble de 5 5 de 64 bits, 1600 bits au total. Fonction éponge : est une classe de fonctions permettant de construire entre autres des fonctions de hachage cryptographique. D un point de vue théorique, elles permettent aussi de construire des preuves de sécurité de ce type de fonction. Leur originalité est d accepter en entrée à la fois des chaînes de taille arbitraire et de permettre en sortie des chaîne de la taille que l on souhaite. Elles généralisent à la fois les fonctions de hachage et le chiffrement de flux. La construction de l éponge est une manière générique de construire une fonction f qui prend en paramètre une chaîne de n importe quelle taille et qui retourne une chaîne de la longueur qu on souhaite. Ses paramètres sont une permutation, ou plus généralement une transformation f opérant sur un nombre fixe b de bits, qu on appellera largeur, et une fonction de padding p. Figure 5 fonction éponge 6
Les routines de Keccak : 1. La routine θ a[i][j][k] a[i][j][k] parite(a[i 1][0..4][k]) parite(a[i+1][0..4][k 1]) 2. La routine ρ ( ) i j ( 3 2 1 0 ) t ( ) 0 1 a[i][j][k] a[i][j][k (t + 1)(t + 2)/2] 3. La routine π a[3i + 2j][i] = a[i][j] 4. La routine χ a[i][j][k] a[i][j][k] a[i + 1][j][k] AND a[i + 2][j][k] 5. La routine ι 0 m l, a[0][0][2 m 1] le bit m + 7n d une séquence LFSR. Figure 6 La routine π Figure 7 La routine ρ 7
5 mise en œuvre 5.1 Partie serveur : 1. keccak.cc :issu de la bibliothèque sphlib 3.0 2. sph_keccak.h 3. sph_types.h 4. hmac_keccak.cc 5. hmac_keccak.h 6. serveur-echo.cc : donné par l encadrant 7. lireecrire.cc 8. lireecrire.h 9. Makefile 5.2 Partie client : keccak 1. hmac_keccak.ino 2. keccak.cpp :issu de librairie AVR-cryptolib 3. keccak.h 4. rotate64.s 5. rotate64.h 6. memxor_c.cpp 7. memxor.h HMAC_keccak 1. hmac_ keccak.cpp 2. hmac_keccak.h 5.3 Partie importante du code : l authentification sur le serveur : 8
fd = accept(prise, (sockaddr *) &adr_connexion, &taille); char ligne[maxcar]; // Le buffer pour le calcul du HMAC en interne. unsigned char hmac[32]; // la clé const unsigned char key[16]={ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ; int i; if (fd < 0) { perror("accept"); exit(1); // si la connexion a été faite, on passe à l authentification else { // Le buffer pour la réception du message unsigned char buf_1[taille_msg]; // Le buffer pour la réception du HMAC unsigned char buf_2[32]; // La réception du message for(i=0;i<taile_msg;i++){ read(fd,buf_1+i,(size_t)1); // La réception du HMAC calculé par l Arduino for(i=0;i<32;i++){ read(fd, buf_2+i,(size_t)1); // calcul du HMAC hmac_keccak(hmac,key,16,buf_1,taille_msg); // comparaison entre les deux HMAC if(strncmp((const char*)buf_2,(const char*)hmac,(size_t)32 )!= 0) { strxfrm( ligne, "Authentification echoue",50); ecrire(fd, ligne, 22); shutdown(fd, 2); cout << "Authentification echoue\n"<< endl; strxfrm( ligne, "Authentification OK",50); ecrire(fd, ligne, 22); 9
#include <SPI.h> #include <Ethernet.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include "hmac_keccak.h" #include "keccak.h" byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED ; // L adresse local IPAddress ip(192,168,1,177); //L adresse serveur IPAddress server(192,168,1,170); EthernetClient client; void setup() { // ouverture de la connexion Ethernet.begin(mac, ip); Serial.begin(9600); delay(1000); Serial.println("connection..."); if (client.connect(server, 5000)) { Serial.println("connexion OK"); else { Serial.println("connexion echoue"); 10
void loop() { char message[7]={ m, e, s, s, a, g, e ; const unsigned char key[16]={ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,; unsigned char hmac[32]; // calcul du HMAC hmac_keccak(hmac,key,16,message,7); //envoi du message for (int i = 0; i < 7; i++){ client.println(message[i]); delay(500); //envoi du HMAC for (int i = 0; i < 32; i++){ client.println(hmac[i]); delay(500); delay(1); // intervalle de temps entre deux lecture if (client.available()) { char c = client.read(); Serial.print(c); while (Serial.available() > 0) { char inchar = Serial.read(); if (client.connected()) { client.print(inchar); if (!client.connected()) { Serial.println(); Serial.println("deconnection."); client.stop(); while(true); 11
void hmac_keccak(void* dest, const void* key, uint16_t keylength_b, const unsigned char* msg, uint32_t msglength_b){ sph_keccak256_context s; unsigned char hash_tmp[32]; uint8_t i; uint8_t buffer[keccak256_blocksize_b]; uint8_t buffer2[keccak256_blocksize_b+msglength_b]; //padding de la clé si < 1088 bits memset(buffer, 0, KECCAK256_BLOCKSIZE_B); // hash de la clé si > 1088bits if (keylength_b > KECCAK256_BLOCKSIZE){ sph_keccak256_init(&s); sph_keccak256(&s,key, keylength_b); sph_keccak256_close(&s,buffer); else { memcpy(buffer, key, (keylength_b+7)/8); //Xor avec ipad=0x36 for (i=0; i<keccak256_blocksize_b; ++i){ buffer[i] ^= IPAD; for(i=0;i<keccak256_blocksize_b;i++){ buffer2[i]=buffer[i]; for(i=32;i<keccak256_blocksize_b+msglength_b;i++){ buffer2[i]=msg[i]; //premier hash sph_keccak256_init(&s); sph_keccak256(&s,buffer2,keccak256_blocksize_b+msglength_b); sph_keccak256_close(&s,hash_tmp); //Xor avec opad=0x5c for (i=0; i< KECCAK256_BLOCKSIZE_B; ++i){ buffer2[i] ^= IPAD ^ OPAD; for (i=0; i< 32; ++i){ buffer2[keccak256_blocksize_b+i] =hash_tmp[i]; //deuxième hash sph_keccak256_init(&s); sph_keccak256(&s,buffer2,keccak256_blocksize_b+msglength_b); 12 sph_keccak256_close(&s,dest);