FCSC 2023 - RSA Secure Dev
Enonce
Poursuivons notre lancée sur RSA. Ici nous allons nous intéresser aux mécanismes permettant de calculer une signature avec de bonnes performances et avec un code sûr.
En effet comme mentionné dans le précédent post nous allons devoir non plus mettre en place mais résister à une attaque par fautes.
Cette série de 3 challenges avait pour particularité de faire partie des 5 challenges utilisant la machine virtuelle du FCSC.
- machine.py : le fichier Python évaluant les instructions de cette machine.
- assembly.py : un assembleur décrit plus bas.
- rsa_keygeneraton.py : un générateur de clés aléatoire
- challenge.py : le fichier du challenge
Ce dernier contenait notamment une vérification de notre bytecode
|
|
Nous devions implémenter un compilateur pour traduire les problèmes avec le langage assembleur fourni (proche d’ARM) en bytecode:
|
|
Méthode(s) naïve(s)
On peut penser à exploiter l’instruction POW
déjà présente. Cependant la contrainte de performance n’est pas vérifiée:
Oubliez tout de suite l’ exponentiation rapide "maison"
, les performances sont désastreuses:
POW
était donc bien nécessaire mais comment faire mieux?
Optimisation avec iq
En faisant une recherche, curieux de disposer dans les registres de iq, dp et dq
on tombe sur ceci: https://www.cosade.org/cosade19/cosade14/presentations/session2_b.pdf
On peut découper le travail en calculant l’exponentiation sur p et q de tailles bien plus petites.
Tout ceci tient au théorème des restes chinois
:
Le déchiffrement RSA avec le Théorème des Restes Chinois (CRT) est une méthode optimisée pour chiffrer et déchiffrer un message. Ce processus implique le calcul de $m$ à partir des valeurs intermédiaires $c_p$ et $c_q$, où $c_p = c^{d_p} \ (\mathrm{mod} \ p)$ et $c_q = c^{d_q} \ (\mathrm{mod} \ q)$.
Étapes :
Calcul des coefficients d’inversion :
- Calculer $q_{inv}$ tel que $q_{inv} \equiv q^{-1} \ (\mathrm{mod} \ p)$, c’est-à-dire que $q \cdot q_{inv} \equiv 1 \ (\mathrm{mod} \ p)$.
Calcul des composantes CRT :
- Calculer $m_p = c_q \cdot q_{inv} \ (\mathrm{mod} \ p)$.
- Calculer $m_q = c_p \cdot p_{inv} \ (\mathrm{mod} \ q)$, où $p_{inv}$ est le coefficient d’inversion de $p$ modulo $q$.
Calcul de la solution $m$ :
- Calculer $h = q_{inv} \cdot (m_p - m_q) \ (\mathrm{mod} \ p)$.
- Calculer $m = m_q + h \cdot q$.
Le résultat $m$ correspond au message déchiffré.
Ce processus profite de la propriété du Théorème des Restes Chinois (CRT) pour optimiser le calcul en divisant les opérations modulo $N$ en opérations modulo $p$ et modulo $q$, ce qui accélère le déchiffrement RSA.
Attention à certaines spécifités:
RD
doit contenir le modulo de l’opération (MOD ou POW) ,RC
: l’exposant (d, p ou q)MUL
ne peut opérer que surR[0-7]
|
|
Congrats! Here is the easy flag: FCSC{06de1084d295f2a016f79485f2a47744bfb9ed3e30e9312121665559df9447de}
RSA 2/3
Ainsi nous avons implémenté dans un premier temps RSA - CRT: https://www.di-mgt.com.au/crt_rsa.html . Toutefois notre implémentation sera vulnérable aux attaques comme vu dans le précédent post.
Ceci ne marche donc pas pour le 2nd test.
Résolution
On reprend cette doc : https://www.cosade.org/cosade19/cosade14/presentations/session2_b.pdf
L’idée est d’utiliser un facteur aléatoire dans la signature RSA. On teste en python voir si ça marche:
|
|
Vient l’implémentation en asm …:
|
|
Ce code est correct, performant mais ne résiste pas à l’attaque.
Principe du verrou
Il existe en effet de nombreuses façons d’injecter une telle faute:
- corrompre en mémoire,
- sauter une instruction dans l’exponentiation,
- corrompre le résultat de l’exponentiation,
- corrompre le message à signer
Comme vu précédemment, une signature erronée + une signature valide permettent de retrouver la clé privée …
En notant s
et s'
respectivement la signature attendue et erronnée (à cause de l’attaque), nous devions vérifier que s = pow(m,e,n)
(sans utiliser R0 jusque là) et écraser les registres sinon.
|
|
Ce qui peut s’implémentee comme ceci :
|
|
Ce code permettait de résoudre le problème:
|
|
Congrats! Here is the medium flag: FCSC{3704721831edcd9f4cd231eb45a4880ea7af6962c358af355130d6881c155479}
RSA 3
Apparemment, il fallait éviter d’utiliser R0, une des fautes consistait à insérer un code STP après chaque instruction possible …
Conclusion
Cette série était très intéressante et m’a permis de me familiariser à l’assembleur avec une petite nuit de débug, ainsi que de me sensibiliser aux attaques par fautes sur RSA - CRT, aussi bien du côté de l’attaquant que du défenseur sur cette partie.