diff --git a/README.md b/README.md index f635054..767d6b8 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ Cryptographie - Outils et algorithmes - cm : [LFSR, Chiffrements par bloc, algorithmes à clefs symétriques](cours/crypto.pdf). - td : [Généralités, chiffrements par flot](td/td1.pdf) - tp : [Chiffrement ECB, lfsr, xtea](tp/tp1) + #### Semaine 2 - cm : [Algorithmes à clefs symétriques, Hachages](cours/crypto.pdf). - td : [Chiffrements symétriques par blocs et modes](td/td2.pdf) +- tp : [Substitution-Permutation-Network](tp/tp2) diff --git a/tp/tp2/README.md b/tp/tp2/README.md new file mode 100644 index 0000000..1ce7bfb --- /dev/null +++ b/tp/tp2/README.md @@ -0,0 +1,95 @@ +# TP2 + +> Dans ce tp, on implémente un algorithme de chiffrement par Blocs basé +> sur un réseau de permutation-substitution (SPN), en mode ECB. + + +### SPN + +
+ +
+ + + +Ces algorithmes utilisent en entrée une clé, et applique à chaque bloc +plusieurs tours constitués de boîtes de substitutions (S-Box) et de +boîtes de permutations (P-Box). + +- Une **S-Box** substitue à un ensemble de bits un autre ensembe de + bits (transormation bijective). +- Une **P-Box** est une permutation de bits. Elle prend la sortie + d'une S-Box, permutte les bits, et les transmet à une S-box au tour + d'après. +- A chaque tour, on combine le bloc avec la clé (ici un xor). + +#### implantation + + + +- la taille de bloc est 8 bits, +- le bloc est découpé en 2 sous-blocs de 4 bits chacun, +- la taille de la clef est 24 bits, +- la clef est décomposée en 3 sous-clefs de 8 bits chacun, +- le nombre de tours est égale à 2, +- les substitutions et les permutations sont les mêmes à chaque tour. + +Remarques + +On représentera dans le programme une substitution par un tableau +d'entiers (unsigned char) de taille 16. + +```c +unsigned char s[]={14,3,2,10,12,11,15,9,0,4,7,13,1,8,6,5} +``` + +Ainsi, le bloc binaire 0011, qui vaut 3, sera remplacé par 1010 car `s[3]=10` + +On représentera une permutation par un tableau d'entiers (`unisgned char`) de taille 16. + +``` +unsigned char perm[8]={5,0,4,6,7,1,2,3}; +``` + +Ainsi, le bit de poids faible (rang 0) est placé au rang 5. + +#### Votre travail + +1. Ecrivez les fonctions suivantes, qui implantent le spn décrit ci-dessus. + + ```c + #ifndef _SPN_H + #define _SPN_H + + unsigned char do_perm(unsigned char w,unsigned char perm[16]); + unsigned char do_subst(unsigned char w,unsigned char subst[16]); + + unsigned char encrypt( + unsigned short w, + unsigned int key, + unsigned char perm[8], + unsigned char subst[16] + ); + + unsigned char decrypt( + unsigned short w, + unsigned int key, + unsigned char perm[8], + unsigned char subst[16] + ); + + #endif + ``` + +2. Ecrivez des programmes spn-encrypt-file.c , spn-decrypt-file.c qui + implantent le SPN décrit ci-dessus. Les deux prennent sur la ligne de + commande : + + - "nom fichier codé" et "nom fichier décodé " + - la clef + + La permutation et la substitution seront codées en dur dans les programmes. + + Testez vos programmes sur un exemple à vous. + +3. Passez vos deux programmes en mode CBC. diff --git a/tp/tp2/img/SubstitutionPermutationNetwork2.png b/tp/tp2/img/SubstitutionPermutationNetwork2.png new file mode 100644 index 0000000..078e4d2 Binary files /dev/null and b/tp/tp2/img/SubstitutionPermutationNetwork2.png differ diff --git a/tp/tp2/img/spn.png b/tp/tp2/img/spn.png new file mode 100644 index 0000000..571ac89 Binary files /dev/null and b/tp/tp2/img/spn.png differ diff --git a/tp/tp2/src/Makefile b/tp/tp2/src/Makefile new file mode 100644 index 0000000..dabbccf --- /dev/null +++ b/tp/tp2/src/Makefile @@ -0,0 +1,17 @@ +all : spn-encrypt-file spn-decrypt-file + +spn-encrypt-file.o : spn-encrypt-file.c + gcc -c spn-encrypt-file.c + +spn-decrypt-file.o : spn-decrypt-file.c + gcc -c spn-decrypt-file.c + + +./lib/spn.o:./lib/spn.c + gcc -c ./lib/spn.c -o ./lib/spn.o + +spn-encrypt-file : ./lib/spn.o spn-encrypt-file.o + gcc -o spn-encrypt-file ./lib/spn.o spn-encrypt-file.o + +spn-decrypt-file : ./lib/spn.o spn-decrypt-file.o + gcc -o spn-decrypt-file ./lib/spn.o spn-decrypt-file.o diff --git a/tp/tp2/src/lib/spn.c b/tp/tp2/src/lib/spn.c new file mode 100644 index 0000000..4f5346e --- /dev/null +++ b/tp/tp2/src/lib/spn.c @@ -0,0 +1,66 @@ +#include "spn.h" + +void calc_inv_perm(unsigned char perm[8],unsigned char inv_perm[8]) +{ + // TODO +} + +void calc_inv_subst(unsigned char subst[16],unsigned char inv_subst[16]) +{ + // TODO +} + +unsigned char do_perm(unsigned char w,unsigned char perm[8]) +{ + unsigned char pw = 0; // permuted byte + int i; + unsigned char mask = 0x1; + unsigned char bit; + unsigned char place; + + for(i=0;i<8;i++){ + bit=w&mask; + place=perm[i]; + pw |= bit<>=1; + } + + return pw; +} + +unsigned char do_subst(unsigned char w,unsigned char subst[16]) +{ + unsigned char sw=0; + + // TODO + return sw; +} + +unsigned char encrypt( + unsigned char w, + unsigned key, + unsigned char perm[8], + unsigned char subst[16]) +{ + unsigned char k0=key&0xff; + unsigned char k1=(key>>8)&0xff; + unsigned char k2=(key>>16)&0xff; + + // TODO + + return w; +} +unsigned char decrypt( + unsigned char w, + unsigned short key, + unsigned char perm[8], + unsigned char subst[16]) +{ + unsigned char k0=key&0xff; + unsigned char k1=(key>>8)&0xff; + unsigned char k2=(key>>16)&0xff; + + // TODO + +} + diff --git a/tp/tp2/src/lib/spn.h b/tp/tp2/src/lib/spn.h new file mode 100644 index 0000000..ad0da20 --- /dev/null +++ b/tp/tp2/src/lib/spn.h @@ -0,0 +1,24 @@ +#ifndef _SPN_H +#define _SPN_H + +void calc_inv_perm(unsigned char perm[8],unsigned char inv_perm[8]); +void calc_inv_subst(unsigned char subst[16],unsigned char inv_subst[16]); + +unsigned char do_perm(unsigned char w,unsigned char perm[8]); +unsigned char do_subst(unsigned char w,unsigned char subst[16]); + +unsigned char encrypt( + unsigned char w, + unsigned int key, + unsigned char perm[8], + unsigned char subst[16] + ); + +unsigned char decrypt( + unsigned char w, + unsigned int key, + unsigned char perm[8], + unsigned char subst[16] + ); + +#endif diff --git a/tp/tp2/src/spn-decrypt-file.c b/tp/tp2/src/spn-decrypt-file.c new file mode 100644 index 0000000..4de2be8 --- /dev/null +++ b/tp/tp2/src/spn-decrypt-file.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include "./lib/spn.h" + +void randomize (unsigned char arr[], int n) +{ + unsigned char tmp; + for (int i = n - 1; i > 0; i--) + { + // Pick a random index from 0 to i + int j = rand() % (i + 1); + + // Swap arr[i] with the element + // at random index + // swap(&arr[i], &arr[j]); + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } +} + + +int main(int argc, char *argv[]) +{ + int fd_in,fd_out; + unsigned int key; + unsigned char perm[8] = {0,1,2,3,4,5,6,7}; + unsigned char subst[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + unsigned char inv_perm[8]; + unsigned char inv_subst[16]; + + unsigned char buf; + + assert(argc == 4); + + srand(0); + + randomize(perm,8); + randomize(subst,16); + calc_inv_perm(perm,inv_perm); + calc_inv_subst(subst,inv_subst); + + + + fd_in = open(argv[1],O_RDONLY); + fd_out = open(argv[2],O_WRONLY|O_TRUNC|O_CREAT,0600); + key = (unsigned int)strtol(argv[3],NULL,0); + + + while(1){ + ssize_t nb = read(fd_in, &buf, 1); + if (nb <=0) + break; + buf = decrypt(buf, key, inv_perm, inv_subst); + write(fd_out, &buf, 1); + } + close(fd_in); + close(fd_out); + + return 0; +} diff --git a/tp/tp2/src/spn-encrypt-file.c b/tp/tp2/src/spn-encrypt-file.c new file mode 100644 index 0000000..d3446af --- /dev/null +++ b/tp/tp2/src/spn-encrypt-file.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include "./lib/spn.h" + +void randomize (unsigned char arr[], int n) +{ + unsigned char tmp; + for (int i = n - 1; i > 0; i--) + { + // Pick a random index from 0 to i + int j = rand() % (i + 1); + + // Swap arr[i] with the element + // at random index + // swap(&arr[i], &arr[j]); + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } +} + + +int main(int argc, char *argv[]) +{ + int fd_in,fd_out; + unsigned int key; + unsigned char perm[8] = {0,1,2,3,4,5,6,7}; + unsigned char subst[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + unsigned char buf; + + assert(argc == 4); + + srand(0); + randomize(perm,8); + randomize(subst,16); + + + fd_in = open(argv[1],O_RDONLY); + fd_out = open(argv[2],O_WRONLY|O_TRUNC|O_CREAT,0600); + + key = (unsigned int)strtol(argv[3],NULL,0); + + while(1){ + ssize_t nb = read(fd_in, &buf, 1); + if (nb <=0) + break; + + buf = encrypt(buf, key, perm, subst); + write(fd_out, &buf, 1); + } + close(fd_in); + close(fd_out); + + return 0; +}