Dans un premier temps, la clé est expansée de la sorte à atteindre 4*NbIterations+4
octets avec :
Taille de la clé. | Nombre d'itérations. |
16. | 10. |
24. | 12. |
32. | 14. |
Dans un second temps, le flux est crypté par bloc de seize octets en réalisant des opérations sur leurs bits avec la clé expansée.
Le cryptage se base sur une algèbre polynomiale particulière, non détaillée dans cette fichie, pour laquelle il existe une opération d'addition et de multiplication :
^
.
Variable
/******/
NbIterations : Entier;
TableEtats : Tableau[4] De Nul Ou Tableau[4] De Nul OuOctet;
W : Tableau[240] De Nul Ou Octet;
TableS : Tableau[240] De Nul Ou Octet;
TableSInv : Tableau[240] De Nul Ou Octet;
TableS=
{
TableSInv=
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
}
{
0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
}
Variable
/******/
TailleCle : Entier;
I : Entier;
IMax : Entier;
J : Entier;
K : Entier;
Temp : Tableau[4] De Nul Ou Octet;
Rcon : Octet;
Selon TailleCle Faire
Cas Pour 16 Faire
Fin Selon
NbIterations=10;
Fin Cas
Cas Pour 24 Faire
NbIterations=12;
Fin Cas
Cas Pour 32 Faire
NbIterations=14;
Fin Cas
/* Debut de l'expansion de la cle dans W. */
W=Cle;
J=TailleCle;
/* Suite de l'expansion de la cle dans W. */
IMax=4*(NbIterations+1);
K=0;
Rcon=0x01;
Pour I=J/4 JusquA IMax-1 Faire
Temp[0]=W[J-4];
Fin Pour
Temp[1]=W[J-3];
Temp[2]=W[J-2];
Temp[3]=W[J-1];
Si Non i%TailleCle Alors
/* Temp=RotWord(Temp). */
SinonSi TailleCle>6 Et I%TailleCle==4 Alors
Octet=Temp[0];
Temp[0]=Temp[1];
Temp[1]=Temp[2];
Temp[3]=Octet;
/* Temp=SubWord(Temp). */
Temp[0]=TableS[Temp[0]];
Temp[1]=TableS[Temp[1]];
Temp[2]=TableS[Temp[2]];
Temp[3]=TableS[Temp[3]];
/* Temp^=Rcon[i/TailleCle] avec Rcon[z]=0x02^(z-1). */
Rcon=MultiplicationAes(Rcon,0x02);
Temp[0]^=Rcon;
/* Temp=SubWord(Temp). */
Fin Si
Temp[0]=TableS[Temp[0]];
Temp[1]=TableS[Temp[1]];
Temp[2]=TableS[Temp[2]];
Temp[3]=TableS[Temp[3]];
W[J++]=W[K++]^Temp[0];
W[J++]=W[K++]^Temp[1];
W[J++]=W[K++]^Temp[2];
W[J++]=W[K++]^Temp[3];
/****************************************************************/
Procedure Crypter(BufferEntree : Binaire, BufferSortie : Binaire)
/* Objet : Crypte un binaire de 16 octets. */
/****************************************************************/
Variable
/******/
I : Entier;
J : Entier;
K : Entier;
L : Entier;
O : Octet;
O2 : Octet;
Colonne : Tableau[4] De Nul Ou Octet;
Debut
/* Copie des octets d'entree dans S. */
K=0;
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
TableEtats[J][I]=BufferEntree[K++];
Fin Pour
Fin Pour
/* Transformation AddRoundKey. */
L=0;
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
TableEtats[J][I]^=W[L++];
Fin Pour
Fin Pour
/* Iterations. */
Pour K=1 JusquA NbIterations Faire
/* Transformation SubBytes. */
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
TableEtats[J][I]=TableS[TableEtats[J][I]];
Fin Pour
Fin Pour
/* Transformation ShiftRows. */
O=TableEtats[1][0];
TableEtats[1][0]=TableEtats[1][1];
TableEtats[1][1]=TableEtats[1][2];
TableEtats[1][2]=TableEtats[1][3];
TableEtats[1][3]=O;
O=TableEtats[2][0];
O2=TableEtats[2][1];
TableEtats[2][0]=TableEtats[2][2];
TableEtats[2][1]=TableEtats[2][3];
TableEtats[2][2]=O;
TableEtats[2][3]=O2;
O=TableEtats[3][3];
TableEtats[3][3]=TableEtats[3][2];
TableEtats[3][2]=TableEtats[3][1];
TableEtats[3][1]=TableEtats[3][0];
TableEtats[3][0]=O;
Si K<NbIterations Alors
/* Transformation MixColumns. */
Pour J=0 JusquA 3 Faire
Colonne[0]=MultiplicationAes(0x02,TableEtats[j][0])
^MultiplicationAes(0x03,TableEtats[j][1])
^TableEtats[j][2]
^TableEtats[j][3];
Colonne[1]=TableEtats[j][0]
^MultiplicationAes(0x02,TableEtats[j][1])
^MultiplicationAes(0x03,TableEtats[j][2])
^TableEtats[j][3];
Colonne[2]=TableEtats[j][0]
^TableEtats[j][1]
^MultiplicationAes(0x02,TableEtats[j][2])
^MultiplicationAes(0x03,TableEtats[j][3]);
Colonne[3]=MultiplicationAes(0x03,TableEtats[j][0])
^TableEtats[j][1]
^TableEtats[j][2]
^MultiplicationAes(0x02,TableEtats[j][3]);
TableEtats[j][0]=Colonne[0];
TableEtats[j][1]=Colonne[1];
TableEtats[j][2]=Colonne[2];
TableEtats[j][3]=Colonne[3];
Fin Pour
Fin Si
/* Transformation AddRoundKey. */
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
TableEtats[J][I]^=W[L++];
Fin Pour
Fin Pour
Fin Pour
Fin Pour
/* Copie des octets S dans la sortie. */
K=0;
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
BufferSortie[K++]=TableEtats[J][I];
Fin Pour
Fin Pour
Fin Procedure
/****************************************************************/
Procedure Decrypter(BufferEntree : Binaire, BufferSortie : Binaire)
/* Objet : Decrypte un binaire de 16 octets. */
/****************************************************************/
Variable
/******/
I : Entier;
J : Entier;
K : Entier;
L : Entier;
O : Octet;
O2 : Octet;
Colonne : Tableau[4] De Nul Ou Octet;
Debut
/* Copie des octets d'entree dans S. */
K=0;
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
TableEtats[J][I]=BufferEntree[K++];
Fin Pour
Fin Pour
/* Transformation AddRoundKey. */
L=16*NbIterations;
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
TableEtats[J][I]^=W[L++];
Fin Pour
Fin Pour
L-=32;
/* Iterations. */
Pour K=NbIterations JusquA 1 Faire
/* Transformation InvShiftRows. */
O=TableEtats[1][3];
TableEtats[1][3]=TableEtats[1][2];
TableEtats[1][2]=TableEtats[1][1];
TableEtats[1][1]=TableEtats[1][0];
TableEtats[1][0]=O;
O=TableEtats[2][2];
O2=TableEtats[2][3];
TableEtats[2][3]=TableEtats[2][1];
TableEtats[2][2]=TableEtats[2][0];
TableEtats[2][1]=O2;
TableEtats[2][0]=O;
O=TableEtats[3][0];
TableEtats[3][0]=TableEtats[3][1];
TableEtats[3][1]=TableEtats[3][2];
TableEtats[3][2]=TableEtats[3][3];
TableEtats[3][3]=O;
/* Transformation SubBytes. */
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
TableEtats[J][I]=TableS[TableEtats[J][I]];
Fin Pour
Fin Pour
/* Transformation AddRoundKey. */
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
TableEtats[J][I]^=W[L++];
Fin Pour
Fin Pour
Fin Pour
L-=32;
Si K>1 Alors
/* Transformation MixColumns. */
Pour J=0 JusquA 3 Faire
Colonne[0]=MultiplicationAes(0x0e,TableEtats[j][0])
^MultiplicationAes(0x0b,TableEtats[j][1])
^MultiplicationAes(0x0d,TableEtats[j][2])
^MultiplicationAes(0x09,TableEtats[j][3]);
Colonne[1]=MultiplicationAes(0x09,TableEtats[j][0])
^MultiplicationAes(0x0e,TableEtats[j][1])
^MultiplicationAes(0x0b,TableEtats[j][2])
^MultiplicationAes(0x0d,TableEtats[j][3]);
Colonne[2]=MultiplicationAes(0x0d,TableEtats[j][0])
^MultiplicationAes(0x09,TableEtats[j][1])
^MultiplicationAes(0x0e,TableEtats[j][2])
^MultiplicationAes(0x0b,TableEtats[j][3]);
Colonne[3]=MultiplicationAes(0x0b,TableEtats[j][0])
^MultiplicationAes(0x0d,TableEtats[j][1])
^MultiplicationAes(0x09,TableEtats[j][2])
^MultiplicationAes(0x0e,TableEtats[j][3]);
TableEtats[j][0]=Colonne[0];
TableEtats[j][1]=Colonne[1];
TableEtats[j][2]=Colonne[2];
TableEtats[j][3]=Colonne[3];
Fin Pour
Fin Si
Fin Pour
/* Copie des octets S dans la sortie. */
K=0;
Pour I=0 JusquA 3 Faire
Pour J=0 JusquA 3 Faire
BufferSortie[K++]=TableEtats[J][I];
Fin Pour
Fin Pour
Fin Procedure
/****************************************************************/
Fonction MultiplicationAes(A : Octet, B : Octet) Retourner Octet
/* Objet : Multiplication AES. */
/****************************************************************/
Variable
/******/
Resultat : Octet;
Resultat2 : Octet;
I : Entier;
Masque : Octet;
Debut
Resultat=0;
Resultat2=0;
Masque=0x01;
Pour I=0 JusquA 7 Faire
/* X^i. */
Fin Pour
Si I!=0 Alors
Resultat2<<<=1;
Sinon
Resultat2=A;
Fin Si
Si Resultat2>0x1B Alors
Resultat2^=0x1B;
Fin Si
Si B&Masque!=0 Alors
Resultat^=Resultat2;
Fin Si
Masque<:<=1;
Retourner Resultat;
Fin Fonction