Advanced Encryption Standard

Introducción

A menudo necesitamos seguridad en nuestros datos y por eso necesitamos algoritmos que encripten dichos datos. Este algoritmo es el último estándar en seguridad también denominado AES.
El algoritmo que se presenta a continuación es un algoritmo de cifrado en bloque, es decir, coge un bloque de información de tamaño determinado y devuelve ese bloque encriptado según una llave.

Funcionamiento

Para poder usar este código será necesario instanciar un objeto de esta clase y empezar a utilizar la interfaz que nos proporciona.
El primer paso que debemos realizar es la introducción de la llave. Esta llave será usada para encryptar el bloque de información que nosotros pasemos al objeto. Del mismo modo, esta llave también servirá para desencriptar el bloque una vez encriptado.
Podemos insertar 3 longitudes de llave distintas, estas son de 16 bytes, 24 bytes o 32 bytes. A más longitud de llave, mayor será la robustez de la encriptación. Debemos elegir una longitud y pasarle a esa función un array de caracteres con los caracteres que formaran la llave.

El segundo paso es encriptar el bloque de información propiamente dicho. Este bloque siempre tiene la misma medida, y son 16 bytes de longitud. Para poder realizar el proceso, es necesario pasarle dos punteros a la función Encrypt(…), el primer puntero es un puntero a un array del cual se leerán los 16 primeros bytes. El segundo puntero es un puntero de un array en el que se depositarán los 16 bytes encriptados una vez realizado el proceso. Como podéis observar, el primer puntero es de entrada y el segundo de salida.

El proceso de desencriptar un mensaje es igual pero a la inversa, es decir, se llama a la función Decrypt(…) con el bloque encriptado en el primer puntero, y un array vacio en el segundo puntero para recibir el mensaje en claro.
A continuación se muestra el código para esta clase que implementa el algoritmo de encriptación AES.

Código

Código *.h

#ifndef _CAES_H_
#define _CAES_H_
 
#define AES_NB 4  
#define xtime(x)   ((x<<1) ^ (((x>>7) & 1) * 0x1b))  
#define Multiply(x,y) (((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) ^ ((y>>2 & 1) * xtime(xtime(x))) ^ ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))))  
 
class CAes
{
    private:
 
                                unsigned int    m_iNr;  
                                unsigned int    m_iNk; 
 
                                unsigned char    m_vIn[16];
                                unsigned char    m_vOut[16];
                                unsigned char    m_vState[4][4];
                                unsigned char    m_vRoundKey[240];
                                unsigned char    *m_vKey;
 
                            static    unsigned int    m_vSbox[256];
                            static    unsigned int    m_vRcon[255];
                            static    unsigned int    m_vSboxInv[256];
 
    protected:
 
                        void    KeyExpansion        (); 
                        void    AddRoundKey        (unsigned int inRound); 
                        void    SubBytes            ();
                        void    InvSubBytes        ();
                        void    ShiftRows            ();
                        void    InvShiftRows        ();
                        void    MixColumns            ();
                        void    InvMixColumns        ();
 
    public:
 
                                CAes            ();        
                                ~CAes        ();
 
                        void    Encrypt            (unsigned char *inText, unsigned char *outText);
                        void    Decrypt            (unsigned char *inText, unsigned char *outText);
 
                        void    SetKey16            (unsigned char *inKey);
                        void    SetKey24            (unsigned char *inKey);
                        void    SetKey32            (unsigned char *inKey);
 
};
#endif

Código *.cpp

#include "CAes.h"
 
unsigned int CAes::m_vSbox[] =    {  
                //0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F  
                0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0  
                0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1  
                0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2  
                0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3  
                0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4  
                0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5  
                0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6  
                0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7  
                0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8  
                0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9  
                0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A  
                0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B  
                0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C  
                0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D  
                0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E  
                0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16  //F
                };   
 
unsigned int CAes::m_vRcon[] =    {  
                0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,   
                0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,   
                0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,   
                0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,   
                0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,   
                0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,   
                0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,   
                0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,   
                0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,   
                0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,   
                0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,   
                0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,   
                0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,   
                0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,   
                0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,   
                0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb  
                };
 
unsigned int CAes::m_vSboxInv[] = {  
                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
                };  
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Constructor de la clase
//---------------------------------------------------------------------------------------------------------------
CAes::CAes()
{
    m_iNr = 0;
    m_iNk = 0;
 
    m_vKey = new unsigned char[32];
}
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Destructor de la clase
//---------------------------------------------------------------------------------------------------------------
CAes::~CAes()
{
    delete m_vKey;
}
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Funcion que hace una expansion a las llaves
//---------------------------------------------------------------------------------------------------------------
void CAes::KeyExpansion()
{
    unsigned int i,j;  
    unsigned char temp[4],k;  
 
    // The first round key is the key itself.  
    for(i = 0; i < m_iNk; i++)  
    {  
        m_vRoundKey[i*4]    = m_vKey[i*4];  
        m_vRoundKey[i*4+1]    = m_vKey[i*4+1];  
        m_vRoundKey[i*4+2]    = m_vKey[i*4+2];  
        m_vRoundKey[i*4+3]    = m_vKey[i*4+3];  
    }  
 
    // All other round keys are found from the previous round keys.  
    while (i < (AES_NB * (m_iNr + 1)))  
    {  
        for(j = 0; j < 4; j++)  
        {  
            temp[j] = m_vRoundKey[(i-1) * 4 + j];  
        }  
        if (i % m_iNk == 0)  
        {  
            // This function rotates the 4 bytes in a word to the left once.  
            // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]  
 
            // Function RotWord()  
            {  
                k = temp[0];  
                temp[0] = temp[1];  
                temp[1] = temp[2];  
                temp[2] = temp[3];  
                temp[3] = k;  
            }  
 
            // SubWord() is a function that takes a four-byte input word and   
            // applies the S-box to each of the four bytes to produce an output word.  
 
            // Function Subword()  
            {  
                temp[0] = m_vSbox[temp[0]];  
                temp[1] = m_vSbox[temp[1]];  
                temp[2] = m_vSbox[temp[2]];  
                temp[3] = m_vSbox[temp[3]];  
            }  
 
            temp[0] =  temp[0] ^ m_vRcon[i / m_iNk];  
        }  
        else if (m_iNk > 6 && i % m_iNk == 4)  
        {  
            // Function Subword()  
            {  
                temp[0] = m_vSbox[temp[0]];  
                temp[1] = m_vSbox[temp[1]];  
                temp[2] = m_vSbox[temp[2]];  
                temp[3] = m_vSbox[temp[3]];  
            }  
        }  
        m_vRoundKey[i*4+0] = m_vRoundKey[(i - m_iNk)*4+0] ^ temp[0];  
        m_vRoundKey[i*4+1] = m_vRoundKey[(i - m_iNk)*4+1] ^ temp[1];  
        m_vRoundKey[i*4+2] = m_vRoundKey[(i - m_iNk)*4+2] ^ temp[2];  
        m_vRoundKey[i*4+3] = m_vRoundKey[(i - m_iNk)*4+3] ^ temp[3];  
        i++;  
    }  
}
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Añade la ronda de la llave al estado mediante una operacion XOR
/// \param inRound Indice de la ronda
//---------------------------------------------------------------------------------------------------------------
void CAes::AddRoundKey(unsigned int inRound)   
{  
    for(unsigned int i=0;i<4;i++)  
    {  
        for(unsigned int j=0;j<4;j++)  
        {  
            m_vState[j][i] ^= m_vRoundKey[inRound * AES_NB * 4 + i * AES_NB + j];  
        }  
    }  
}  
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Substituye los valores de la matriz de estado por los de la SBOX
//---------------------------------------------------------------------------------------------------------------
void CAes::SubBytes()   
{
    for(unsigned int i = 0; i < 4; i++)  
    {  
        for(unsigned int j = 0; j < 4; j++)  
        {  
            m_vState[i][j] = m_vSbox[m_vState[i][j]];  
        }  
    }  
}
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Substituye los valores de la matriz de estado por los de la SBOX en modo inverso
//---------------------------------------------------------------------------------------------------------------
void CAes::InvSubBytes()  
{   
    for(unsigned int i = 0; i < 4; i++)  
    {  
        for(unsigned int j = 0; j < 4; j++)  
        {  
            m_vState[i][j] = m_vSboxInv[m_vState[i][j]];  
        }  
    }  
}  
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Shifta las filas dentro del estado hacia la izquierda, cada fila es shiftada
///        con un ofset diferente, Offset = Row Number, la primera fila no es shiftada
//---------------------------------------------------------------------------------------------------------------
void CAes::ShiftRows()  
{  
    unsigned char temp;  
 
    // Rotate first row 1 columns to left      
    temp = m_vState[1][0];  
    m_vState[1][0] = m_vState[1][1];  
    m_vState[1][1] = m_vState[1][2];  
    m_vState[1][2] = m_vState[1][3];  
    m_vState[1][3] = temp;  
 
    // Rotate second row 2 columns to left      
    temp = m_vState[2][0];  
    m_vState[2][0] = m_vState[2][2];  
    m_vState[2][2] = temp;  
 
    temp = m_vState[2][1];  
    m_vState[2][1] = m_vState[2][3];  
    m_vState[2][3] = temp;  
 
    // Rotate third row 3 columns to left  
    temp = m_vState[3][0];  
    m_vState[3][0] = m_vState[3][3];  
    m_vState[3][3] = m_vState[3][2];  
    m_vState[3][2] = m_vState[3][1];  
    m_vState[3][1] = temp;  
}  
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Shifta las filas dentro del estado hacia la izquierda, cada fila es shiftada
///        con un ofset diferente, Offset = Row Number, la primera fila no es shiftada
//---------------------------------------------------------------------------------------------------------------
void CAes::InvShiftRows()  
{  
    unsigned char temp;  
 
    // Rotate first row 1 columns to right     
    temp = m_vState[1][3];  
    m_vState[1][3] = m_vState[1][2];  
    m_vState[1][2] = m_vState[1][1];  
    m_vState[1][1] = m_vState[1][0];  
    m_vState[1][0] = temp;  
 
    // Rotate second row 2 columns to right     
    temp = m_vState[2][0];  
    m_vState[2][0] = m_vState[2][2];  
    m_vState[2][2] = temp;  
 
    temp = m_vState[2][1];  
    m_vState[2][1] = m_vState[2][3];  
    m_vState[2][3] = temp;  
 
    // Rotate third row 3 columns to right  
    temp = m_vState[3][0];  
    m_vState[3][0] = m_vState[3][1];  
    m_vState[3][1] = m_vState[3][2];  
    m_vState[3][2] = m_vState[3][3];  
    m_vState[3][3] = temp;  
}  
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Mezcla las columnas de la matriz de estado
//---------------------------------------------------------------------------------------------------------------
void CAes::MixColumns()  
{  
    unsigned char Tmp,Tm,t;  
    for(unsigned int i = 0; i < 4; i++)  
    {      
        t = m_vState[0][i];  
        Tmp = m_vState[0][i] ^ m_vState[1][i] ^ m_vState[2][i] ^ m_vState[3][i] ;  
        Tm = m_vState[0][i] ^ m_vState[1][i] ; Tm = xtime(Tm); m_vState[0][i] ^= Tm ^ Tmp ;  
        Tm = m_vState[1][i] ^ m_vState[2][i] ; Tm = xtime(Tm); m_vState[1][i] ^= Tm ^ Tmp ;  
        Tm = m_vState[2][i] ^ m_vState[3][i] ; Tm = xtime(Tm); m_vState[2][i] ^= Tm ^ Tmp ;  
        Tm = m_vState[3][i] ^ t ; Tm = xtime(Tm); m_vState[3][i] ^= Tm ^ Tmp ;  
    }  
}
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Mezcla las columnas de la matriz de estado en orden inverso
//---------------------------------------------------------------------------------------------------------------
void CAes::InvMixColumns()  
{  
    unsigned char a,b,c,d;  
    for(unsigned int i = 0; i < 4; i++)  
    {     
        a = m_vState[0][i];  
        b = m_vState[1][i];  
        c = m_vState[2][i];  
        d = m_vState[3][i];  
 
        m_vState[0][i] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);  
        m_vState[1][i] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);  
        m_vState[2][i] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);  
        m_vState[3][i] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);  
    }  
}  
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Encrypta el texto de entrada y lo diposita en el texto de salida
/// \param[in] inText Puntero al texto de entrada, 16 caracteres de longitud
/// \param[out] outText Puntero al texto de salida, 16 caracteres de longitud
//---------------------------------------------------------------------------------------------------------------
void CAes::Encrypt(unsigned char *inText, unsigned char *outText)  
{
    //Copy the input PlainText to state array.  
    for(unsigned int i = 0; i < 4; i++)  
    {  
        for(unsigned int j = 0; j < 4; j++)  
        {  
            m_vState[j][i] = inText[i * 4 + j];  
        }  
    }  
 
    // Add the First round key to the state before starting the rounds.  
    AddRoundKey(0);   
 
    // There will be Nr rounds.  
    // The first Nr-1 rounds are identical.  
    // These Nr-1 rounds are executed in the loop below.  
    for(unsigned int round = 1; round < m_iNr; round++)  
    {  
        SubBytes();  
        ShiftRows();  
        MixColumns();  
        AddRoundKey(round);  
    }  
 
    // The last round is given below.  
    // The MixColumns function is not here in the last round.  
    SubBytes();  
    ShiftRows();  
    AddRoundKey(m_iNr);  
 
    // The encryption process is over.  
    // Copy the state array to output array.  
    for(unsigned int i=0; i < 4; i++)  
    {  
        for(unsigned int j = 0; j < 4; j++)  
        {  
            outText[i * 4 + j] = m_vState[j][i];  
        }  
    }  
}
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Desencrypta el texto de entrada y lo diposita en el texto de salida
/// \param[in] inText Puntero al texto de entrada, 16 caracteres de longitud
/// \param[out] outText Puntero al texto de salida, 16 caracteres de longitud
//---------------------------------------------------------------------------------------------------------------
void CAes::Decrypt(unsigned char *inText, unsigned char *outText)  
{  
    //Copy the input CipherText to state array.  
    for(unsigned int i = 0; i < 4; i++)  
    {  
        for(unsigned int j = 0; j < 4; j++)  
        {  
            m_vState[j][i] = inText[i*4 + j];  
        }  
    }  
 
    // Add the First round key to the state before starting the rounds.  
    AddRoundKey(m_iNr);  
 
    // There will be Nr rounds.  
    // The first Nr-1 rounds are identical.  
    // These Nr-1 rounds are executed in the loop below.  
    for(unsigned int round = m_iNr - 1; round > 0; round--)  
    {  
        InvShiftRows();  
        InvSubBytes();  
        AddRoundKey(round);  
        InvMixColumns();  
    }  
 
    // The last round is given below.  
    // The MixColumns function is not here in the last round.  
    InvShiftRows();  
    InvSubBytes();  
    AddRoundKey(0);  
 
    // The decryption process is over.  
    // Copy the state array to output array.  
    for(unsigned int i = 0; i < 4; i++)  
    {  
        for(unsigned int j = 0; j < 4; j++)  
        {  
            outText[i*4+j] = m_vState[j][i];  
        }  
    }  
}
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Introduce la llave del algoritmo
/// \param[in] inKey Puntero al texto de la llave de entrada
//---------------------------------------------------------------------------------------------------------------
void CAes::SetKey16(unsigned char *inKey)  
{
    m_iNk = 128 / 32;  
    m_iNr = m_iNk + 6;
 
    for(unsigned int i = 0; i < m_iNk * 4; i++)
    {
        m_vKey[i] = inKey[i];
    }
}
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Introduce la llave del algoritmo
/// \param[in] inKey Puntero al texto de la llave de entrada
//---------------------------------------------------------------------------------------------------------------
void CAes::SetKey24(unsigned char *inKey)  
{
    m_iNk = 192 / 32;  
    m_iNr = m_iNk + 6;
 
    for(unsigned int i = 0; i < m_iNk * 4; i++)
    {
        m_vKey[i] = inKey[i];
    }
}
 
//---------------------------------------------------------------------------------------------------------------
/// \brief Introduce la llave del algoritmo
/// \param[in] inKey Puntero al texto de la llave de entrada
//---------------------------------------------------------------------------------------------------------------
void CAes::SetKey32(unsigned char *inKey)  
{
    m_iNk = 256 / 32;  
    m_iNr = m_iNk + 6;
 
    for(unsigned int i = 0; i < m_iNk * 4; i++)
    {
        m_vKey[i] = inKey[i];
    }
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License