Bonjour à tous,

A titre expérimental, j'ai envie de tester la mise au point d'un protocole sécurisé "maison" entre petites cartes électroniques.

L'objectif est plus pédagogique que d'arriver à un produit ou une installation effective.

Je touche un peu à tout en électronique et en informatique (sur PC programmation en .NET, c#, c++, sur embarqué programmation en 8051 et AVR, pas mal de bricolages en électronique analogique)

Dans le cadre de mon activité professionnelle je m'intéresse à la sécurité des machines mais vis à vis des opérateurs (arrêts d'urgence, carters de protections...) c'est de la sécurité mais rien à voir avec la sécurité "informatique", même si les machines utilisent beaucoup d'informatique industrielle (automates de sécurité, ...)

Le cryptage est un domaine intéressant car il y a plein de fausses bonnes idées et c'est un sujet très prisé des "mathématiques amusantes" et autres casses-têtes

Le contexte :

Deux cartes électroniques avec petits microcontroleurs échangent des informations entre elles.
Chaque carte peut envoyer un message à l'autre.
La carte qui reçoit un message va en envoyer un autre message en réponse (accusé de réception, retour d'informations demandées...)

Le canal de communication est "public", c'est à dire qu'il peut être écouté, par exemple :
- liaison infrarouge "longue portée"
- liaison radio sur fréquences radioamateur
- ...

Les pirates peuvent avoir connaissance des algorithmes utilisés, mais pas des clefs.

Les pirates peuvent écouter toutes les communications
Les pirates peuvent émettre des communications.
Les pirates peuvent faire des attaques "man in the middle" : intercepter une communication, empêcher la carte destinataire de le recevoir, et émettre une réponse à la place de la carte destinataire légitime.

Première analyse :

Les données doivent être cryptés, c'est évident.

Mais ce n'est pas suffisant.

Les pirates peuvent attaquer le système par répétition, simplement en renvoyant un des messages précédemment écouté.
Le protocole devra être protégé contre ce type d'attaque.

Les pirates peuvent aussi attaquer le système en envoyant n'importe quoi, la carte destinataire va décrypter le message et se retrouver à exécuter des ordres incohérents.
Le protocole devra être protégé contre ce type d'attaque.

Le protocole

Chaque carte possède :
- une clef secrete en mémoire, qui est connue de l'autre carte.
- un identifiant secret en mémoire, de 6 octets, qui est connu de l'autre carte.
- une horloge
- une entrée analogique reliée à un générateur de bruit blanc pour générer des nombres aléatoires

La clef est composée de plusieurs parties :
- KA et KB : deux clefs utilisées pour faire un XOR sur les données
- PA et PB : deux tableau de permutation ; concrètement on a DonneesPeremutees[i] = DonneesOriginales[ P[i] ]

Voici comment fonctionne le cryptage :

D'abord les données à envoyer sont écrites dans un buffer, lui-même composé de différents éléments :
- RB : un octet choisi aléatoirement
- RA : un octet choisi aléatoirement
- MSG : le message utile
- DATE : le nombre de millisecondes depuis une date choisie comme référence sur 6 octets
- ID : l'identifiant de l'expéditeur sur 6 octets
- CRC : un octet de CRC permettant de vérifier l'absence d'erreur de transmission, c'est un XOR tout bête entre l'ensemble des octets précédents du buffer

KA, KB et PB font la même longueur que les données (RB + RA + MSG + DATE + ID + CRC = 15 octets + nombre d'octets de MSG)
PA la même longueur moins 1.

Etape n°1 :

On fait une translation circulaire d'une valeur de RA octets des données MSG + DATE + ID + CRC
RB et RA restent au début du Buffer.

Exemple si RA est égal à 4 :
Buffer avant translation circulaire : RB RA 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Buffer après translation circulaire : RB RA 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4

Etape n°2 :

On fait un XOR sur le buffer avec la clef KA

Etape n°3 :

On fait une permutation sur le buffer avec le tableau PA sur toutes les données sauf la première position (occupée par RB le XOR avec le premier octets de KA)

Etape n°4 :

On fait une translation circulaire d'une valeur de RB de tous les octets du buffer sauf le premier (RB XOR KA[0] reste en première position)

Etape n°5 :

On fait une permutation sur le buffer avec le tableau PB sur toutes les données du buffer

Etape n°6 :

On fait un XOR sur le buffer avec la clef KB

Les données sont envoyées au destinataire

Décryptage et vérification par le destinataire :

Le décryptage fonctionne en faisant les opérations réciproques dans l'ordre inverse :
- XOR avec KB sur tout le buffer
- permutation inverse avec PB sur tout le buffer
- on retrouve RB en faisant un XOR du premier octet avec KA[0]
- on fait la translation circulaire de -RB
- permutation inverse avec PA sur tout le buffer sauf le 1ier octet
- XOR avec KA sur tout le buffer
- on retrouve RA qui est en position 2 dans le buffer
- on fait la translation circulaire de -RA

Il reste la vérification :
- valeur du CRC correcte
- valeur de ID correspondant à celle attendue (on évite ainsi que le système interprete des messages aléatoires ou faux)
- RA et RB qui doivent être différents des valeurs utilisées précédemment
- DATE qui doit être plus récente que la date utilisée précédemment

En cas de succès, le destinataire envoie sa réponse selon le même principe, avec son ID, sa DATE actualisée, sa clefs

En cas d'échec, le destinataire envoie une réponse selon le même principe, avec son ID, sa DATE actualisée, sa clefs, mais avec un message MSG d'erreur :
- le premier octet de MSG a une valeur spéciale qui signifie "erreur"
- les autres octets de MSG sont aléatoires pour éviter que les messages d'erreur soient facilement reconnaissables d'une part et utilisables pour casser le code d'autre part.

Que pensez vous de mon protocole ?

Sera-t-il facile à casser ?

Quelles sont les bonnes et les mauvaises idées ?

A bientôt