• Aucun résultat trouvé

6.2 Application partielle de contre-mesures

6.2.3 Masking partiel

Comme déjà mentionné, notre schéma de masking va appliquer, via XOR, un masque différent à chaque donnée sensible masquée. Pour cela, nous avons écrit un code C++ et avons tiré parti des mécanismes d’héritage et de sur-charge de méthodes, afin de rendre plus simple l’écriture de 17 codes (et donc 17 classes) différents (un code par nombre de bytes masqués, de 0 à 16 masques), puisqu’il ne fallait modifier que peu de méthodes d’une classe à l’autre. Les masques sont appliqués de manière séquentielle11, en suivant l’ordre des colonnes (par exemple, si 4 bytes sont masqués, il s’agira des bytes de STATE se trouvant dans la première colonne). Les masques sont reposition-nés au même endroit au début de chaque tour, l’opération de mixColumns se chargeant de les remettre à leur place et valeur initiale. Le fait de replacer les masques à la même position au début de chaque tour a été décidé pour des raisons de facilité de code, afin de ne pas devoir tenir compte de toutes les possibles positions des masques et pouvoir ainsi réutiliser les mêmes mé-thodes tout au long de l’exécution. La figure 6.3 permet de voir l’évolution des masques au cours d’un tour de chiffrement. De plus, cette décision n’aura aucune influence lors de l’évaluation de la sécurité, étant donnée l’approche choisie pour l’attaque, où nous attaquons le premier tour.

Notons enfin que chaque opération d’AES a été décomposée pour s’appliquer sur la plus petite partie de STATE qu’elle utilise, c’est-à-dire que les opéra-tions addRoundKey et subBytes sont remplacées par 16 méthodes, chacune, qui s’appliquent sur un byte prédéfini (et non reçu en paramètre). De même, les opérations de shiftRows et de mixColumns s’appliquent sur 4 bytes en même temps (4 bytes d’une même ligne pour shiftRows et 4 bytes d’une même colonne pour mixColumns) et donnent place à 4 méthodes chacune. Une mé-thode supplémentaire, pour retirer les masques, est exécutée à la fin de l’al-gorithme pour fournir le texte chiffré attendu. Pour l’opération de subBytes,

chaque SBox masquée reçoit en entrée une variable masquée (à l’aide d’un masque min, choisi aléatoirement12 au début de l’exécution) et produit une valeur masquée (à l’aide d’un masque mout, également choisi aléatoirement au début de l’exécution).

12. Comme discuté dans la section précédente, pour SchedAES, l’utilisation de l’aléatoire doit se faire de manière prudente pour éviter toute faille.

FIGURE6.3 – Évolution des masques au cours d’un tour de chiffrement m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16 m1' m2' m3' m4' m5' m6' m7' m8' m9' m10' m11' m12' m13' m14' m15' m16' m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16 m1' m2' m3' m4' m5' m6' m7' m8' m9' m10' m11' m12' m13' m14' m15' m16' m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16 AddRoundKey SubBytes ShiftRows MixColumns

Méthode d’évaluation

Nous avons réalisé une attaque à l’aide de traces simulées et non à l’aide de traces mesurées, afin de manipuler les valeurs cibles exactes (poids de Ham-ming sans bruit) et de savoir où se trouvent ces valeurs dans les traces. Nous avons utilisé le modèle du poids de Hamming comme modèle de consomma-tion d’énergie. Pour cette partie des expériences, les traces produites conte-naient, pour chaque instruction, un couple de valeurs (Tt(1), Tt(2)): le poids de Hamming de la sortie de l’opération (Tt(1)) et le poids de Hamming du masque appliqué à la valeur de sortie13 (Tt(2)), à l’image du modèle de consommation décrit par Standaert et al. dans [66]. Par exemple, pour les instructions de subBytes, la fuite d’information est le couple : (HW (SBox0i,j(si,j⊕ min(i,j)⊕ ki,j)), HW (mout)), où SBox0

i,j correspond à la SBox masquée utilisée pour le byte i, j de STATE, si,j un byte de STATE, ki,j le byte secret de la clé ajoutée lors de l’opération addRoundKey. Aucun bruit n’a été ajouté aux traces, afin d’obtenir une borne inférieure sur le nombre de traces requises lors de la phase d’attaque.

Pour l’attaque, nous avons choisi d’utiliser celle basée sur l’information mu-tuelle pour attaquer14 l’opération subBytes du premier tour. Ce choix se jus-tifie parce que l’information mutuelle gère facilement les dépendances entre plusieurs variables. Nous retenons donc, lors de l’attaque sur un byte k de la clé, la valeur estimée ˆkqui maximise :

ˆ

k = arg max

k

ITt(1), Tt(2),HW (SBox (d ⊕ k)) (6.1)

où Tt(1) est une valeur liée à la sortie d’une SBox masquée, Tt(2) une informa-tion relative au masque de sortie, d un byte du texte clair et I l’informainforma-tion mutuelle. Pour les bytes non-masqués, nous retenons la valeur estimée ˆk qui maximise :

ˆ

k = arg max

k

I (Tt,HW (SBox (d ⊕ k))) (6.2)

où Ttest une valeur liée à la sortie d’une SBox. Dans les deux cas, le maximum est obtenu en testant toutes les valeurs du byte de clé attaqué et en retenant la valeur qui donne le plus grand résultat.

13. Ceci permet de réaliser une attaque de second ordre, où l’attaquant dispose d’une infor-mation sur la valeur masquée et d’une inforinfor-mation sur le masque appliqué à la valeur masquée. 14. D’autres attaques pourraient donner des résultats différents. Notre but n’est pas de trou-ver la meilleure attaque, mais bien de comparer différents niveaux de protection.

Analyse du schéma

Pour cette expérience, nous avons fait varier le nombre de masques utilisés de 0 à 16. Lorsqu’une valeur n’est pas masquée, nous considérons que le masque utilisé est 0 (son poids de Hamming est également de 0).

Analyse du temps d’exécution

Nous avons exécuté 100 000 chiffrements15 en gardant la clé et le texte clair constants (afin de ne pas tenir compte du temps de génération des textes lors des mesures). Les masques utilisés étaient modifiés à chaque exécution (et donc générés lors de chaque exécution). La table 6.6 et la figure 6.4 nous permettent de voir, comme attendu, que plus le nombre de valeurs sensibles masquées augmente, plus le temps d’exécution augmente.

TABLE6.6 – Temps pour 100 000 chiffrements en fonction du nombre de bytes masqués. Nombre de masques 0 1 2 3 4 Temps 0.446s 0.571s 0.730s 0.807s 0.961s Nombre de masques 5 6 7 8 9 Temps 1.039s 1.215s 1.324s 1.434s 1.553s Nombre de masques 10 11 12 13 14 Temps 1.630s 1.766s 1.914s 2.016s 2.276s Nombre de masques 15 16 Temps 2.311s 2.370s

15. Ce nombre a été choisi pour permettre une précision suffisante (des variations « visibles » lors de la prise de mesure) lors des mesures de temps.

FIGURE 6.4 – Temps pour 100 000 chiffrements en fonction du nombre de bytes masqués.

Analyse du surcoût

Chaque valeur sensible masquée supplémentaire implique les calculs suivants : – 2 générations de nombres aléatoires de 8 bits,

– 256 calculs correspondant au calcul de la Sbox masquée supplémentaire, – 5 calculs pour replacer les masques pour le tour suivant, lors de mixColumns

(4 de ces calculs servent à annuler la propagation du masque issue du calcul de mixColumns et un calcul sert à placer le masque à sa position d’origine), – 1 calcul pour appliquer le masque supplémentaire à sa valeur sensible

dési-gnée,

– 1 calcul pour retirer le masque supplémentaire de sa valeur sensible dési-gnée.

En plus de devoir calculer la nouvelle Sbox masquée, il faut également la sto-cker en mémoire, ce qui implique de devoir stosto-cker 256 bytes (correspondant à la SBox) supplémentaires pour chaque valeur masquée supplémentaire. Néan-moins, ce surcoût est propre au schéma de masking choisi (masking booléen). D’autres schémas de masking n’auraient pas forcément eu un tel surcoût.

Analyse de la sécurité

La table 6.7 indique le nombre de traces nécessaires pour retrouver entière-ment la clé en fonction du nombre de bytes masqués. L’attaque a été conduite en gardant la clé fixe, mais en modifiant, à chaque exécution, le texte clair et les masques. Le nombre indiqué pour chaque scénario correspond au nombre

TABLE 6.7 – Nombre de traces nécessaires pour l’attaque en fonction du nombre de bytes masqués.

Nombre de masques 0 1 2 3 4

Nombre de traces nécessaires 10 72 76 82 76

Nombre de masques 5 6 7 8 9

Nombre de traces nécessaires 68 84 69 100 98

Nombre de masques 10 11 12 13 14

Nombre de traces nécessaires 88 92 85 91 99 Nombre de masques 15 16

Nombre de traces nécessaires 100 93

maximum de traces utilisées lors de l’attaque d’un des 16 bytes, les bytes étant attaqués de manière indépendante, mais en utilisant les mêmes traces. Ce nombre est relevant pour indiquer la quantité de traces nécessaires à l’atta-quant lors de la phase d’attaque. L’analyse de la table 6.7 et de la figure 6.5 montre que l’utilisation d’un masque supplémentaire n’augmente pas forcé-ment la sécurité (nombre de traces requises) de l’implantation. Les masques étant indépendants, les traces peuvent être réutilisées pour attaquer les bytes séparément. Néanmoins, si un faible nombre de bytes est masqué, l’attaquant peut facilement attaquer les bytes non-masqués (environ 10 traces) et réaliser une attaque par force brute pour attaquer les bytes restants.

FIGURE 6.5 – Nombre de traces nécessaires pour l’attaque en fonction du nombre de bytes masqués.