OFB Mode
Documentation |
#include <cryptopp/modes.h>
|
OFB mode is output feedback mode. The mode 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 places an integrity assurance over the encrpyted data.
OFB mode uses an initialization vector (IV), and the plain text does not be padded to the block size of the cipher. For additional information on this mode, see Block Cipher Modes of Operation.
Crypto++ offers several modes of operation, including ECB, CBC, OFB, CFB, CBC-CTS, CTR, XTS, CCM, EAX, GCM and OCB.
Crypto++ does not provide a way to retrieve the current IV or counter used for encryption or decryption. If you need the current IV or counter then you need to manage it yourself. Some ciphers allow you to seek a number of bytes or blocks in the stream.
If you are used to working in languages like Java or libraries like OpenSSL, then you might want to visit the Init-Update-Final wiki page. Crypto++ provides the transformation model, but its not obvious because its often shrouded behind Pipelines.
Note: 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 consider using an algorithm or mode like CCM, GCM, EAX or ChaCha20Poly1305.
Sample Program
There are three sample programs for OFB mode. The samples use filters in a pipeline). Pipelining is a high level abstraction and it handles buffering input, buffering output and padding for you. The first sample shows the basic use of a pipeline. The second sample shows how to change padding. The third shows how to manually insert into a filter.
If you are benchmarking then you may want to visit Benchmarks | Sample Program . It shows you how to use StreamTransformation
and its ProcessString
method to process multiple blocks at a time. ProcessString
eventually calls BlockTransformation
and ProcessBlock
. Calling a cipher's ProcessString
or ProcessBlock
eventually call ProcessAndXorBlock
or AdvancedProcessBlocks
, and they are the lowest level API you can use.
AutoSeededRandomPool prng; byte key[ AES::DEFAULT_KEYLENGTH ]; prng.GenerateBlock( key, sizeof(key) ); byte iv[ AES::BLOCKSIZE ]; prng.GenerateBlock( iv, sizeof(iv) ); string plain = "OFB Mode Test"; string cipher, encoded, recovered; /*********************************\ \*********************************/ try { cout << "plain text: " << plain << endl; OFB_Mode< AES >::Encryption e; d.SetKeyWithIV( key, sizeof(key), iv ); // OFB 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 { OFB_Mode< AES >::Decryption d; d.SetKeyWithIV( key, sizeof(key), iv ); 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: 2EDCA4AAB6B51AB3EABEC97B2BA74D4E iv: EEA37DEE36032EB1EF0F1AE0E514A75E plain text: OFB Mode Test cipher text: C1ECE8ABABF8DD92E86BD56742 recovered text: OFB Mode Test
Downloads
AES-OFB-Filter.zip - Demonstrates encryption and decryption using AES in OFB mode with filters