Méthodes formelles
et protocoles cryptographiques

Jean Goubault-Larrecq
G.I.E. Dyade, INRIA




Méthodes formelles

But : assurer qu'un programme est correct.

Idée de base : vérifier que le programme satisfait une propriété mathématique (appelée spécification).






Un exemple-jouet, le tri par fusion (en ML)


Un exemple-jouet, le tri par fusion (en C)




Spécification: qu'est-ce qu'un tri ?

Intuitivement, les deux programmes précédents font la même chose (trier), mais il y a des différences : lesquelles ? (regardez bien, le 2ème est faux...corrigez-le.)

À l'opposé, qu'y a-t-il de commun entre ces deux programmes ? Et avec le suivant ?




Spécification informelle du tri

``Un tri prend une liste l en entrée et retourne la liste des mêmes éléments en ordre croissant.''

Les comportements suivants de ma fonction sort3 sont-ils acceptables, selon vous ?


Spécifications formelles

Par exemple, on modélise le fait que sort3 (l) retourne l' par une relation binaire R (l, l'), on veut donc vérifier :
    " l : int list, l' : int list · R (l, l') Þ tri (l, l')     (1)
    " l : int list · $ l' : int list · R (l, l')     (2)
sous les hypothèses (définitions, ici) :
   
" l : int list, l' : int list ·
     tri (l, l') Û (memes_elements (l, l') Ù ordre_croissant (l'))
    (3)
   
" l : int list, l' : int list ·
     memes_elements (l, l') Û sous_liste (l, l') Ù sous_liste (l', l)
    (4)
   
" l : int list, l' : int list ·
     sous_liste (l, l') Û (" i : N ·
          0 £ i Ù i < len (l) Þ
               $ j : N · 0 £ j Ù j < len (l') Ù sub (l, i) = sub (l', j))
    (5)
   
" l : int list ·
     ordre_croissant (l) Û (" i : N, j : N ·
          0 £ i Ù i£ j Ù j < len (l) Þ sub (l, i) £ sub (l, j)
    (6)
   
len ([]) = 0
    (7)
   
" l : int list, x : int · len (x::l) = len (l) + 1
    (8)
   
" l : int list, x : int · sub (x::l, 0) = x
    (9)
   
" l : int list, x : int, i : int · sub (x :: l, i+1) = sub (l, i)
    (10)



Est-ce la spécification que vous souhaitiez ?

Une autre (en logique d'ordre 2); remplacer (4) et (5) par :
" l : int list, l' : int list ·
     memes_elements (l, l') Û $ p : N ® N ·
          (" j : N · $! i : N · p (i) = j) Ù
          (" i : N · 0£ i Ù i < len (l) Þ
               0£ p (i) Ù p (i) < len (l') Ù sub (l', p (i)) = sub (l, i))



Comment s'assurer que sort3 est correct ?

Dépend du niveau de confiance que l'on veut atteindre :


Autres méthodes formelles




Applications aux protocoles cryptographiques




Compromis (à l'heure actuelle)




Le pionnier : la BAN (Burrows-Abadi-Needham)

Modèle très simple de données :
m ::= K clés
  | D autres messages de base
  | mK chiffrement
  | m, m couples
  | ...  

Bizarrerie : messages º formules. Logique modale avec opérateurs ``croit'', ``voit'', ``a dit'', ``a juridiction sur'', ``est frais'', ``est un secret entre'', etc.


Ambitions et défauts de la BAN




Règles

``Si P croit P «K Q, et P voit XK, alors P croit que Q a dit X.''

``Si P croit Y secret entre P et Q, et P voit X, Y, alors P croit que Q a dit X.''

``Si P croit X frais, et que Q a dit X, alors P croit que Q croit X.''

``P croit X,Y ssi P croit X et P croit Y.''

``Si P croit que Q a dit X,Y, alors P croit que Q a dit X (resp. Y).''

``Si P voit X,Y, alors P voit X (resp. Y).''

``Si P croit P «K Q et P voit XK, alors P voit X.''

``Si P croit X (resp. Y) frais, alors P croit X, Y frais.''


Exemple : Needham-Schroeder à clés symétriques

1. A ® S : A, B, Na
2. S ® A
: {Na, B, Kab, {Kab, A}
 
Kbs
}
 
Kas
     
3. A ® B
: {Kab, A}
 
Kbs
     
4. B ® A
: {Nb}
 
Kab
     
5. A ® B
: {Nb-1}
 
Kab
     



Needham-Schroeder idéalisé

1. A ® S :
2. S ® A :
   
{Na, A «Kab B, A «Kab B frais , {A «Kab B}
 
Kbs
}
 
Kas
3. A ® B :
   
{A «Kab B}
 
Kbs
4. B ® A :
   
{Nb, A «Kab B }
 
Kab
5. A ® B :
   
{Nb, A «Kab B }
 
Kab



Needham-Schroeder analysé

Sous les hypothèses :

``A croit A «Kas S, B croit B «Kas S.''

``S croit A «Kab B.''

``A croit que S a juridiction sur A «K B, " K.''

...

``B croit A «K B frais, " K.''     (*)

On déduit ``B (resp. A, A croit que B, B croit que A) croit A «Kab B.'' (Sans (*), seulement ``B croit que S a dit A «Kab B.'')


Le spi-calcul

Termes :
m ::= n noms
  | x variables
  | 0  
  | S (m) données de base
  |
{m1}
 
m2
chiffrement
  | (m1, m2) couples

Processus :
P ::=

m1
 
á m2 ñ . P
émission
  | m1 (x) . P réception
  | P1 | P2 parallèle
  | (n n) P restriction
  | !P réplication
  | [m1 is m2] P test d'égalité
  | 0 nil
  | let (x,y) = m in P décomposition
  | case m1 of 0:P S(x):Q analyse de cas
  |
case m1 of {x}
 
m2
in P
déchiffrement

Pas de logique, ce n'est qu'un langage de programmation.


Règles de calcul

   
(

m
 
á m' ñ . P) | (m (x) . Q) ® P | (Q[m'/x])
    (11)
    case 0 of 0:P S (x):Q ® P     (12)
    case S (m) of 0:P S (x):Q ® Q [m/x]     (13)
    case {m}m' of {x}m' in P ® P[m/x]     (14)
etc.




Needham-Schroeder en spi-calcul

A (F, Kas) =
   /* 1. A ® S */
   (n Na)

c
 
AS á idA, idB, Na ñ .
   /* 2. */
   cSA (x) .
   case x of {x'}
 
Kas
in
   let (x
 
Na
, xB, xK, x'')
          =x' in
   [x
 
Na
is Na] [xB is idB]
   /* 3. A ® B */
  

c
 
AB á x'' ñ .
   /* 4. */
   cBA (x''') .
   case x''' of {x
 
Nb
}K in
   /* 5. A ® B */
  

c
 
AB á {x
 
Nb
-1}K ñ . F (K)
B (G, Kbs) =
   /* 3. */
   cAB (z) .
   case z of {z'}
 
Kbs
in
   let (K, zA) = z' in
   [zA is idA]
   /* 4. B ® A */
   (n Nb)

c
 
BA á {Nb}K ñ .
   /* 5. */
   cAB (z'') .
   case z'' of {z'''}K in
   [z''' is Nb-1] G (K)
S (Kas, Kbs) =
   /* 1. */
   cAS (yA, yB, y
 
Na
) .
   /* 2. S® A */
   (n Kab)

c
 
SA á {y
 
Na
, yB, Kab,
              {Kab, yA}
 
Kbs
             }
 
Kas
ñ .



Spécifications en spi-calcul

Inst (F, G) = (n Kas) (n Kbs)
    (A (F, Kas) | B (G, Kbs) | !S (Kas, Kbs))     (15)
FM (x) =

c
 
AB á {M}x ñ .
    (16)
G (z) = cAB (z') . case z' of {y}z in H (y)     (17)

Équivalence observationnelle : P Q ssi P et Q sont indistingables dans tout contexte.

K garantit une communication secrète ssi, pour tout H, pour tous M, M' tels que H(M) H(M'), Inst (FM, G) Inst (FM', G).


Authentification

Inst (F, G) = (n Kas) (n Kbs)
    (A (F, Kas) | B (G, Kbs) | !S (Kas, Kbs))
FM (x) =

c
 
AB á {M}x ñ .
GM (z) = cAB (z') . case z' of {y}z in H (M)     (18)

K garantit l'authenticité des messages ssi, pour tout H, pour tout M, Inst (FM, G) Inst (FM, GM).


L'approche de Dominique Bolignano

Attitude inverse du spi-calcul : on n'a plus que des formules (en logique du premier ordre). La sémantique du programme est décrite sous forme d'un ensemble de formules, exécutables par Prolog.

L'exécution du protocole est un automate infini.

La méthode est paramétrable par divers modèles de sécurités (des axiomes).

Dérivation de preuves formelles (à l'heure actuelle en Coq).


Le rôle de A en tant qu'automate




Modélisation du protocole

Le système (A | B | S | I, où I est l'intrus) est modélisé comme un automate produit; chaque état s est un quadruplet (sA, sB, sS, E).

Pour ce qui est des propriétés de sécurité, on peut supposer que l'on est dans le pire des cas : tous les principaux parlent à l'intrus, reçoivent leurs messages de l'intrus. À tout instant, l'intrus possède un ensemble E de messages (espionnés sur les canaux), et ne peut fabriquer que des messages m tels que known_in (E, m).


Le prédicat known_in

...est défini inductivement par :
known_in (E È {m}, m)
   
known_in (E, m) Ù known_in (E, K) known_in (E, mK) Ù known_in (E, K-1)
Þ known_in (E, mK) Þ known_in (E, m)
   
known_in (E, m1) Ù known_in (E, m2) known_in (E, (m1, m2))
Þ known_in (E, (m1, m2)) Þ known_in (E, mi)



Modélisation de la relation de transition

Écriture d'un prédicat P (état-avant, transition, message, état-après).

P (s, l, m, s') = (l=émission-1. Ù P_emission_1 (s, m, s'))
  Ú (l=réception-1. Ù P_reception_1 (s, m, s'))
  Ú ...
P_emission_1 ((sA, sB, sS, E), m, (s'A, s'B, s'S, E') =
     sA = 1a(Na) Ù s'A = 2a(Na) Ù s'B = sB Ù s'S = sS
     Ù E' = E È {m}Ù m = (idA, idB, Na) Ù ¬ known_in (E, Na)
P_reception_1 ((sA, sB, sS, E), m, (s'A, s'B, s'S, E') =
     sS = 1s () Ù s'S = 2s (xA, xB, x
 
Na
) Ù s'A = sA Ù s'B = sB
     Ù E' = E Ù m = (xA, xB, x
 
Na
) Ù known_in (E, m)



Modélisation du protocole

Exécution :
Exec (s, s)      P (s,l,m,s') Ù Exec (s',s'') Þ Exec (s,s'')

Hypothèses de départ :
¬ known_in (E0, Kas)      ¬ known_in (E0, Kbs)
Exec ((sA0, sB0, sS0, E0), (sAfin, sBfin, sSfin, Efin))

Montrer :
¬ known_in (Efin, Kab)
¬ known_in (Efin, Kas)
¬ known_in (Efin, Kbs)



Quelques remarques

Souple : on peut changer le modèle de sécurité (ici, pour simplifier, on avait confiance en A, B et S, et S était en mono-session).

S'étend à de gros protocoles cryptographiques, y compris de commerce électronique.

L'exécution Prolog retourne soit ``non'', soit une attaque. Dans le premier cas, la trace Prolog fournit l'argument de preuve.

This document was translated from LATEX by HEVEA.