CFB Mode

From Crypto++ Wiki
Jump to: navigation, search
CFB Mode
Documentation
#include <cryptopp/modes.h>

CFB Mode is cipher feedback. CFB was originally specified by NIST in FIPS 81. The standard, issued in 1980, only offers confidentiality. Other modes, such as CCM and GCM, offer authenticated encryption which includes an integrity assurance over the encrpyted data.

CFB does not require the plain text be padded to the block size of the cipher. For additional information on this mode, see Block Cipher Modes of Operation.


If your project is using encryption alone to secure your data, encryption alone is usually not enough. Please take a moment to read Authenticated Encryption and understand why you should prefer to use CCM, GCM, or EAX over other modes, such as CBC or CTR.

Sample Program

The sample program below demonstrates AES in CFB mode using filters (see pipelining). Though the key is declared on the stack, a SecByteBlock is used to ensure the sensitive material is zeroized. Similar could be used for both plain text and recovered text.

AutoSeededRandomPool prng;

SecByteBlock key(AES::DEFAULT_KEYLENGTH);
prng.GenerateBlock( key, key.size() );

byte iv[ AES::BLOCKSIZE ];
prng.GenerateBlock( iv, sizeof(iv) );

string plain = "CFB Mode Test";
string cipher, encoded, recovered;

/*********************************\
\*********************************/

try
{
    cout << "plain text: " << plain << endl;

    CFB_Mode< AES >::Encryption e;
    d.SetKeyWithIV( key, key.size(), iv );

    // CFB mode must not use padding. Specifying
    //  a scheme will result in an exception
    StringSource ss1( plain, true, 
        new StreamTransformationFilter( e,
            new StringSink( cipher )
        ) // StreamTransformationFilter      
    ); // StringSource
}
catch( CryptoPP::Exception& e )
{
    cerr << e.what() << endl;
    exit(1);
}

/*********************************\
\*********************************/

// Pretty print cipher text
StringSource ss2( cipher, true,
    new HexEncoder(
        new StringSink( encoded )
    ) // HexEncoder
); // StringSource
cout << "cipher text: " << encoded << endl;

/*********************************\
\*********************************/

try
{
    CFB_Mode< AES >::Decryption d;
    d.SetKeyWithIV( key, key.size(), iv );

    // The StreamTransformationFilter removes
    //  padding as required.
    StringSource ss3( cipher, true, 
        new StreamTransformationFilter( d,
            new StringSink( recovered )
        ) // StreamTransformationFilter
    ); // StringSource

    cout << "recovered text: " << recovered << endl;
}
catch( CryptoPP::Exception& e )
{
    cerr << e.what() << endl;
    exit(1);
}

A typical output is shown below. Note that each run will produce different results because the key and initialization vector are randomly generated.

$ ./Driver.exe 
key: CC8CC446D001133ED4E0729F12AE0A5F
iv: 52941361970066391CD17C50408ECB0E
plain text: CFB Mode Test
cipher text: 5E01512F851B3D3B6562B59B34
recovered text: CFB Mode Test

Downloads

AES-CFB-Filter.zip - Demonstrates encryption and decryption using AES in CFB mode with filters