Live Journal about blowfish |

Blowfish Encryption and Twofish Encryption

Blowfish is symmetric block cipher encryption algorithm designed by the famous IT security technologist, BT Chief Security Technology Officer, and author Bruce ‘Almighty’ Schneier in 1993. The Blowfish encryption algorithm operates on 64-bit bit blocks of plaintext and supports variable key lengths ranging from 32 up to 448 bits; the default key length is 128 bits.

The technicalities of the Blowfish algorithm are quite complex and involve Feistel ciphers using large key-dependent S-boxes. As there is no successful cryptanalysis attacks known a Blowfish secured message can only be cracked using brute-force. This, in turn, can be prevented by using 256-bit keys for example.

Please find in Bright Hub’s article Can AES Encryption be Cracked? why attempts of cracking Blowfish used in conjunction with a reasonable lenght key by means of brute force can be ruled out (The underlying maths principles have been translated in easy-to-understand language).

The benefits of Blowfish include that the algorithm is unpatented and royalty-free, without any licensing requirements. The same is true for Twofish, an AES finalists designed by Schneier et al’s Counterpane Labs, gradually replacing Blowfish encryption. Twofish, first published in 1998, is a symmetric key block cipher algorithm using a block size of 128 bits .

Twofish uses key lengths of 128 bit, 192 bit or 256-bit. The Twofish algorithm is similar to the Blowfish algorithm and applies 16 rounds of encryption to 64-bit bit blocks plaintext input. More about block ciphers and stream ciphers can be found in Bright Hub’s article Types of Encryption.

Depending on on the key length as well as whether Twofish is used for hardware based or software based encryption Twofish may outperform AES in terms of speed. Many people believe Rijndael has just become more popular than Twofish because it received more attention since it was chosen for Advanced Encryption Standard (AES) by NIST in 2001.


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;
}