Crypt::CFB Operation Simulation

A tutorial Perl example is provided to show how to use Crypt::Blowfish module to simulate the CFB operation mode. The simulation result does no match the result from the Crypt::CFB module, which has an incorrect code logic on calculating the block size.

In previous tutorials, we learned that Crypt::CFB uses 0x0000000000000000 as the default IV value, and does not do any padding. Now I want to verify its accuracy by compare its ciphertext with a CFB simulation process.

Here is my example Perl script, Crypt-CFB-Blowfish-Simulation.pl, that simulates the CFB operation by calling Crypt::Blowfish one block at time. It also verifies the ciphertext by calling the Crypt::CFB module directly.

#- Crypt-CFB-Blowfish-Simulation.pl
#- Copyright (c) 2015, HerongYang.com, All Rights Reserved.
#-
   use Crypt::CFB;
   use Crypt::Blowfish;
   my ($keyHex, $ivHex, $plainHex) = @ARGV;

   print("Crypt::CFB Blowfish Simulation - output in Hex:\n");
   $keyHex = "0000000000000000" unless $keyHex;
   $ivHex = "0000000000000000" unless $ivHex;
   $plainHex = "0000000000000000" unless $plainHex;
   $keyStr = pack("H*", $keyHex);
   $ivStr = pack("H*", $ivHex);
   $plainStr = pack("H*", $plainHex);
   print("   Secret Key      ($keyHex)\n");
   print("   IV              ($ivHex)\n");
   print("   Plaintext       ($plainHex)\n");

   print("Creating Crypt::Blowfish Object ...\n");
   $blowfish = new Crypt::Blowfish($keyStr);
   
   $count = 0;
   $cipherHexPrev = $ivHex;
   while ($plainHex) {
      $count++;
      $plainHexBlock = substr($plainHex,0,16);
      $plainHex = substr($plainHex,16);
      print("Simulating CFB on block $count...\n");
      print("   Prev ciphertext ($cipherHexPrev)\n");
      print("   Plaintext       ($plainHexBlock)\n");
      
      $cipherStrPrev = pack("H*", $cipherHexPrev);
      $plainStrBlock = pack("H*", $plainHexBlock);
      $tempStrBlock = $blowfish->encrypt($cipherStrPrev);
      $tempHexBlock = unpack("H*", $tempStrBlock);
      print("   Temp Ciphertext ($tempHexBlock)\n");

      $cipherStrBlock = $tempStrBlock ^ $plainStrBlock;
      $cipherHexBlock = unpack("H*", $cipherStrBlock);
      print("   Ciphertext      ($cipherHexBlock)\n");

      $cipherHexPrev = $cipherHexBlock;
   }

   print("Creating Crypt::CFB Object ...\n");
   $cipher = Crypt::CFB->new($keyStr, 'Crypt::Blowfish', $ivStr);
   
   print("Encrypting entire plaintext with Crypt::CFB...\n");
   $cipherStr = $cipher->encrypt($plainStr);
   $cipherHex = unpack("H*", $cipherStr);
   print("   Ciphertext      ($cipherHex)\n");

When running this example script with a simple set of inputs, I got this output:

C:\herong>perl Crypt-CFB-Blowfish-Simulation.pl 
   0000000000000000 0000000000000000 0000000000000000

Crypt::CFB Blowfish Simulation - output in Hex:
   Secret Key      (0000000000000000)
   IV              (0000000000000000)
   Plaintext       (0000000000000000)
Creating Crypt::Blowfish Object ...
Simulating CFB on block 1...
   Prev ciphertext (0000000000000000)
   Plaintext       (0000000000000000)
   Temp Ciphertext (4ef997456198dd78)
   Ciphertext      (4ef997456198dd78)
Creating Crypt::CFB Object ...
Encrypting entire plaintext with Crypt::CFB...
   Ciphertext      (7822d975f85d126d)

As you can see from the output, we have a problem here. The ciphertext generated from my CFB simulation process does not match with the Crypt::CFB module.

If we double check the ciphertext result from my simulation process, the result 0x4ef997456198dd78 is correct. You can use the following steps to verify:

   C[1] = P[1] XOR E(K, IV)           : Based on CFB algorithm
        = P[1] XOR 0x4ef997456198dd78 : Based on Test Vector table
        = 0x0000000000000000 XOR 0x4ef997456198dd78
        = 0x4ef997456198dd78

I think that the Crypt::CFB module has a problem with the Crypt::Blowfish module. What do you think?

I looked at the Crypt::CFB source code as C:\local\Perl\site\lib\Crypt\CFB.pm and noticed that it has incorrect logic for determining the block size of the Crypt::Blowfish module. The source code is using block size of 1 byte and it should be 8 bytes.

Conclusion: Crypt::CFB gives incorrect result for Blowfish encryption operations.

Last update: 2015.

Table of Contents

 About This Book

 Blowfish Cipher Algorithm

 Perl Crypt::Blowfish Module

 Perl Crypt::ECB Perl Module

 Perl Crypt::CBC Module

Perl Crypt::CFB Perl Module

 What is Crypt::CFB?

 Installing Crypt::CFB 0.02 with ActivePerl

 Crypt::CFB with Default IV

 Crypt::CFB Not Requiring Padding

Crypt::CFB Operation Simulation

 OpenSSL "enc -bf-ecb" for Blowfish/ECB Encryption

 OpenSSL "enc -bf-cbc" for Blowfish/CBC Encryption

 OpenSSL "enc -bf-cfb" for Blowfish/CFB Encryption

 OpenSSL "enc -bf-ofb" for Blowfish/OFB Encryption

 References

 PDF Printing Version