Live Journal about blowfish |

What is AES Encryption?

Here’s all you want to know about AES Encryption, the Advanced Encryption Standard which implements symmetric cryptography by means Rijndael algorithm in key lengths of 128, 192 and 256 bits.

AES, short for Advanced Encryption Standard, is a widely adopted symmetric encryption scheme used, for instance, to secure electronic communication and messages. AES – as its name implies – has been the outcome of standardization and evaluation process which took years to select from the best encryption algorithms. Finally, in 2001, the Rijndael algorithm has been chosen as winner by the US National Institute of Standards and Technology (NIST) to be implemented as underlying security algorithm of the AES standard which as of the these days has largely replaced its predecessor and derivates of DES (Data Encryption Standard) which is longer considered secure due to its small 56-bit key length for example.

The Rijndael algorithm, invented by two cryptographers Vincent Rijmen and Joan Daemen, implements the mathematical operations substitution, transposition, as well as permutation to plaintext, the term used to describe input in the cryptography domain. The AES Advanced Encryption Standard uses 10 rounds of these algebraic operations in a complex scheme to produce encrypted output, or cipher text as it is called in expert terms. AES-192 and AES-256 have 12 and 14 rounds, respectively.

In the AES implementation of Rijndael the algorithm operates on 128 bits block ciphers, and comprises key lengths of 128, 192 and 256 bits. It is common to refer to the symmetric key AES encryption standard as AES-128, AES-192 and AES-256 depending on the key strength. More about encryption can also be found in Bright Hub’s article Types of Encryption which explains the difference between asymmetric and symmetric encryption also shedding a light on stream and block ciphers.

Whereas cryptography aims at securing plain text does cryptanalysis try to break the key or underlying algorithm of an encryption scheme, Rijndael in the case of AES here. Cracking a 256-bit key is computationally infeasible but cryptanalysts who are aware of the inner working of Rijndael and who apply much more sophisticated methods than brute-force believe that the security margin is narrowing. Check out our article Can AES Encryption be Cracked? which takes into account the latest news about the security or strength of AES.


The Encryption routine

The encryption routine takes two parameters – the file descriptors of input file and the output file to which the encrypted data is to be saved. It is always a good idea to zero-fill your buffers using the memset or bzero commands before using the buffers with data. This is especially important if you plan to reuse the buffers. In the program below, the input data is being encrypted in blocks of 1K each.

The steps for encryption are as follows :-

  1. Create a cipher context
  2. Initialize the cipher context with the values of Key and IV
  3. Call EVP_EncryptUpdate to encrypt successive blocks of 1k eack
  4. Call EVP_EncryptFinal to encrypt “leftover” data
  5. Finally call EVP_CIPHER_CTX_cleanup to discard all the sensitive information from memory

You may be wondering what “leftover” data is? As mentioned earlier, Blowfish encrypts information in blocks of 64-bit each. Sometimes we may not have 64 bits to make up a block. This may happen if the buffer size in the program below or the file/input data size is not a integral multiple of 8 bytes(64-bits).So accordingly the data is padded and then the partial block is encrypted using EVP_EncryptFinal. The length of the encoded data block is stored in the variable tlen and added to the final length.

int
encrypt (int infd, int outfd)
{
        unsigned char outbuf[OP_SIZE];
        int olen, tlen, n;
        char inbuff[IP_SIZE];
        EVP_CIPHER_CTX ctx;
        EVP_CIPHER_CTX_init (& ctx);
        EVP_EncryptInit (& ctx, EVP_bf_cbc (), key, iv);

        for (;;)
          {
                 bzero (& inbuff, IP_SIZE);

                 if ((n = read (infd, inbuff, IP_SIZE)) == -1)
                   {
                           perror ("read error");
                           break;
                   }
                 else if (n == 0)
                         break;

                 if (EVP_EncryptUpdate (& ctx, outbuf, & olen, inbuff, n) != 1)
                   {
                           printf ("error in encrypt update\n");
                           return 0;
                   }

                 if (EVP_EncryptFinal (& ctx, outbuf + olen, & tlen) != 1)
                   {
                           printf ("error in encrypt final\n");
                           return 0;
                   }
                 olen += tlen;
                 if ((n = write (outfd, outbuf, olen)) == -1)
                         perror ("write error");
          }
        EVP_CIPHER_CTX_cleanup (& ctx);
        return 1;
}