Code cleaning + report.
[crypto_lab1.git] / rapport / main.tex
index 16b8e6c..5e157a7 100644 (file)
@@ -31,10 +31,97 @@ Nous utiliseront \emph{AES-256} en mode \emph{CBC} pour chiffrer les données ai
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Simulation du protocole}
 
-\subsection{Utilisation du code}
+\subsection{Utilisation du programme}
+
+Le code est écrit en langage Rust \footnote{\url{http://www.rust-lang.org}} et utilise le système de build \emph{Cargo} qui est livré en standard. Il est conseillé d'installer la version \emph{nightly} disponible ici : \url{http://www.rust-lang.org/install.html}.
+
+Pour construire et lancer l'application il faut se trouver dans le dossier contenant le fichier \emph{Cargo.toml} et lancer la commande suivante.
+
+\begin{lstlisting}
+$> cargo run -- <args>
+\end{lstlisting}
+
+Où \emph{<args>} peut valoir :
+
+\begin{itemize}
+   \item \emph{genkey} : génère une clef de 256 bits. Utilisé initialement pour définir la clef d'authentification $K_{a}$ et la clef de chiffrement $K_{c}$ ;
+   \item \emph{tests} : effectue un certain nombre de tests pour vérifier le comportement du serveur vis-à-vis du protocole ;
+   \item \emph{oracle-weak} : effectue une attaque sur la première version du serveur ;
+   \item \emph{oracle-fixed} : effectue une attaque sur la version corrigé du serveur.
+\end{itemize}
+
 
 \subsection{Structure du code}
 
+Le code est découpé en quatre modules :
+
+\begin{itemize}
+   \item \emph{crypto} : fournit les primitives de chiffrement, déchiffrement, calcul du MAC. Utilise un binding \emph{Rust} vers \emph{OpenSSL} ;
+   \item \emph{packet} : définit le format des paquets et permet leur sérialisation et dé-sérialisation ;
+   \item \emph{end\_point} : permet la création de serveurs et de clients et gère la communication sur \emph{TCP/IP} ;
+   \item \emph{oracle\_machine} : implémente l'attaque par padding-oracle.
+\end{itemize}
+
+\subsection{Tests du protocole}
+\begin{sloppypar}
+Un certain nombre de tests sont implémenté dans la fonction \texttt{end\_point::Client::start\_tests(..)}. Il est possible de les exécuter à l'aide de la commande suivante.
+\end{sloppypar}
+
+\begin{lstlisting}
+$> cargo run -- tests
+\end{lstlisting}
+
+La sortie de cette commande est la suivante.
+
+\begin{lstlisting}[breaklines, basicstyle=\small]
+$> cargo run -- tests
+   Compiling lab1_rust v0.0.1 (file:///home/gburri/Documents/Master/ICR/lab1/lab1_rust)
+     Running `target/lab1_rust tests`
+Starting server on [::1]:4221...
+Server started
+===== Test case #1:
+Sending a valid packet...
+[Client] time: 0. Sending: Command { id: 154, payload(29): "ba57cb4a9cc83c9b9027bca2cf9c46f25d0c1608a4044dc878bd474bbd" }
+[Server] time: 2. Valid command received: Packet { t: Command { id: 154, payload(29): "ba57cb4a9cc83c9b9027bca2cf9c46f25d0c1608a4044dc878bd474bbd" }, timestamp: 1 }
+[Server] time: 3. Answer sent: Answer { id: 125, payload(31): "a88ffbd4758e17d0130cd11c1749149bc33cc818c42edec5fb6edb29352f83" }
+[Client] time: 4. Command transmitted correctly, answer: Packet { t: Answer { id: 125, payload(31): "a88ffbd4758e17d0130cd11c1749149bc33cc818c42edec5fb6edb29352f83" }, timestamp: 3 }
+===== Test passed
+===== Test case #2:
+[Server] time: 3. Connection closed: EOF
+Sending a packet with an unknown type...
+[Server] time: 0. Error or invalid packet: Err(UnknownPacketTypeError)
+===== Test passed
+[Server] time: 0. Connection closed: EOF
+===== Test case #3:
+Sending a packet with an old timestamp...
+Error, timestamp mismatch, current timestamp: 0, packet received: Packet { t: Command { id: 154, payload(29): "ba57cb4a9cc83c9b9027bca2cf9c46f25d0c1608a4044dc878bd474bbd" }, timestamp: 0 }
+[Server] time: 0. Error or invalid packet: Err(InvalidTimestampError)
+===== Test passed
+[Server] time: 0. Connection closed: EOF
+===== Test case #4:
+Sending a packet with altered crypted data (do not alter the padding)...
+[Server] time: 2. Error or invalid packet: Err(MACMismatchError)
+===== Test passed
+[Server] time: 2. Connection closed: EOF
+===== Test case #5:
+Sending a packet with too small data...
+[Server] time: 0. Error or invalid packet: Err(UnconsistentDataSizeError)
+===== Test passed
+[Server] time: 0. Connection closed: EOF
+===== Test case #6:
+Sending a packet with too large data...
+[Server] time: 0. Error or invalid packet: Err(UnconsistentDataSizeError)
+===== Test passed
+[Server] time: 0. Connection closed: EOF
+===== Test case #7:
+Sending a packet with wrong padding (all 0)...
+[Server] time: 2. Error or invalid packet: Err(PaddingError)
+===== Test passed
+All tests passed
+[Server] time: 2. Connection closed: EOF
+\end{lstlisting}
+
+
 \subsection{Quelle est la stratégie recommandée en pratique parmi les trois listées ci après ?}
 
 \begin{itemize}
@@ -43,6 +130,9 @@ Nous utiliseront \emph{AES-256} en mode \emph{CBC} pour chiffrer les données ai
    \item \emph{Encrypt-then-MAC} : $Enc(M)|MAC(Enc(M))$.
 \end{itemize}
 
+D'après \cite{wiki-authentication-encryption} la stratégie \emph{Encrypt-then-MAC} est la plus sûre dans le cadre de chiffrage authentifié. L'article de \emph{M. Bellare and C. Namprempre} \cite{authenticated-encryption-bellare-namprempre} évalue ces trois stratégies.
+
+
 \subsubsection{Quelle stratégie est utilisée par \emph{TLS} ?}
 
 \emph{TSL} utilise la deuxième version (\emph{MAC-then-Encrypt}). À noté que le \emph{MAC} est optionnel.
@@ -68,12 +158,12 @@ Via une \emph{replay attack} en modifiant le \emph{timestamp} pour qu'il soit va
 
 \subsection{À la place d'utiliser un \emph{IV} aléatoire, le mode \emph{CBC} implémente une approche basée sur un \emph{nonce}. Que peut-on dire de sa sécurité ?}
 
-TODO
+
 
 
 \subsection{Remarques concernant la sécurité de notre protocole}
 
-TODO
+A priori nous n'avons pas choisi la stratégie la plus recommandée en terme de sécurité. Comme nous le verrons par la suite, ce protocole est vulnérable à une attaque de type \emph{padding-oracle}.
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -81,14 +171,19 @@ TODO
 
 \subsection{Historique de l'attaque par oracle à l'aide du remplissage}
 
-TODO
+L'attaque original a été publié en 2002 par \emph{Serge Vaudenay}. En 2010, cette attaque a été mise en pratique contre plusieurs frameworks web tel que \emph{JavaServer Faces}, \emph{Ruby on Rails} et \emph{ASP.NET}. En 2012, il a été montré qu'elle est efficace contre certain appareils hardware.
 
+Il existe une nouvelle variante, publiée en 2013, nommée \emph{the Lucky Thirteen attack}, permettant d'attaquer des implémentations ayant été corrigées. En février 2013, les personnes en charge des implémentations de \emph{TLS} travaillaient à la réalisation d'un correctif à cette attaque.
+
+L'attaque la plus récente utilisant un \emph{padding-oracle} est \emph{POODLE} \footnote{\url{http://en.wikipedia.org/wiki/POODLE}} qui a été dévoilée en septembre 2014.
+
+Cette section est largement inspirée de l'article de \emph{Wikipedia} sur la \emph{padding-oracle attack} \cite{wiki-padding-oracle-attack}.
 
 \subsection{Explication de l'attaque pour notre cas}
 
-Le but est de faire décoder tout ou une partie d'un message chiffré intercepté par un oracle. Le décryptage se fait par bloc de 16 octets et nécessite le bloc chiffré le précédant ou l'\emph{IV} dans le cas du premier bloc. Pour notre test nous partons du principe que l'attaquant a intercepté un paquet chiffré, qu'il en a compris la structure et qu'il a deviné que l'\emph{IV} correspondait au \emph{timestamp}.
+Le but est de faire décoder par un oracle tout ou une partie d'un message chiffré intercepté. Le décryptage se fait par bloc de 16 octets et nécessite le bloc chiffré le précédant ou l'\emph{IV} dans le cas du premier bloc. Pour notre test nous partons du principe que l'attaquant a intercepté un paquet chiffré, qu'il en a compris la structure et qu'il a deviné que l'\emph{IV} correspondait au \emph{timestamp}.
 
-Nous utilisons une attaque basé sur l'information renvoyé par l'oracle concernant la présence d'un bourrage valide. D'après le protocole un \emph{MAC} est calculé à partir des données non-bourrées puis le bourrage est ajouté pour obtenir une taille multiple de 16 et finalement les données et le bourrage sont chiffrés. Lors du déchiffrement par l'oracle, les données sont d'abord déchiffrées puis le bourrage est contrôlé, s'il n'est pas valide un paquet d'erreur et renvoyé au client (\emph{CryptError}). Si le bourrage est correct alors celui ci est retiré et les données restantes sont authentifiée à l'aide de la \emph{MAC}, si l'authentification échoue alors un paquet d'erreur et renvoyé au client (\emph{AuthError}).
+Nous utilisons une attaque basé sur l'information renvoyé par l'oracle concernant la présence d'un bourrage valide. D'après le protocole un \emph{MAC} est calculé à partir des données non-bourrées puis le bourrage est ajouté pour obtenir une taille multiple de 16 et finalement les données et le bourrage sont chiffrés. Lors du traitement par l'oracle, les données sont d'abord déchiffrées puis le bourrage est contrôlé, s'il n'est pas valide un paquet d'erreur et renvoyé au client (\emph{CryptError}). Si le bourrage est correct alors celui ci est retiré et les données restantes sont authentifiée à l'aide de la \emph{MAC}, si l'authentification échoue alors un paquet d'erreur et renvoyé au client (\emph{AuthError}).
 
 La valeur des octets du bourrage correspond à sa taille, par exemple un bourrage de longueur trois est représenté par \emph{[0x03, 0x03, 0x03]}. Si les données avant bourrage sont déjà multiple de 16 alors un bourrage de longueur 16 est ajouté de sorte qu'un bourrage soit toujours présent.
 
@@ -108,12 +203,18 @@ Dès qu'un paquet d'erreur \emph{AuthError} est reçu alors nous pouvons calcule
 
 Une subtilité existe pour la recherche du premier octet, il est possible que le paquet d'erreur \emph{AuthError} correspond, avec une faible probabilité, à un autre bourrage que \emph{[0x01]}. Pour prévenir ce cas il faut, pour ce premier octet, envoyer un paquet de commande pour toutes les valeurs de $F_{1}$ et compter le nombre de paquet d'erreur \emph{AuthError} reçu. Si ce nombre est égal à 1 alors on peut passer à $b'$, sinon il faut recommencer en modifiant $F_{2} = (F_{2} + 1) mod 256$.
 
+Le code correspondant à cette attaque peut être exécuté par la commande suivante :
+
+\begin{lstlisting}
+$> cargo run --release -- oracle-weak
+\end{lstlisting}
+
 
 \subsection{Calcul de la complexité moyenne de l'attaque en terme de nombre de requête effectué auprès de l'oracle}
 
 Sans prendre en compte la particularité du premier octet illustré à la section précédente, la complexité moyenne pour le décryptage d'un bloc de 16 octets est de $16 * 256 / 2 = 2048$ requêtes.
 
-Dans le cas présenté dans le code, le nombre de requête est de 1795.
+Dans l'exemple présenté dans le code, le nombre de requête est de 2099. La durée d'exécution est de ~180 ms, cette relative longue durée est certainement dû à un overhead engendré par les couches réseau \emph{TCP/IP}.
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -121,14 +222,24 @@ Dans le cas présenté dans le code, le nombre de requête est de 1795.
 
 \subsection{Description}
 
+Le correctif proposé consiste à authentifier également le bourrage et non-plus que les données. Cela a pour conséquence de vérifier en premier l'authenticité du contenu avant de procéder à la validité du padding. Les deux messages d'erreur, \emph{CryptError} et \emph{AuthError}, font toujours partis du protocole.
+
+Le code correspondant à ce correctif peut être exécuté par la commande suivante :
+
+\begin{lstlisting}
+$> cargo run --release -- oracle-fixed
+\end{lstlisting}
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Conclusion}
 
+TODO
+
+
+
+
 
-%http://crypto.stackexchange.com/a/205
-%https://en.wikipedia.org/wiki/Malleability_%28cryptography%29
 
 \bibliographystyle{plain}
 \bibliography{main}