/**@page symmetric_ciphers Symmetric Cipher- @ref symmetricWhat- @ref symmetricHow- @ref symmetricModes- @ref symmetricWhich- @ref symmetricBuffering<hr>@section symmetricWhat What are symmetric ciphers?In an informal setting, symmetric ciphers can be thought of as a mapping of someplaintext to ciphertext, via some well-known transformation function, dependenton a secret key. There are two basic types of symmetric ciphers: - Stream ciphers -- These map an n-bit stream of plaintext to a n-bit stream of ciphertext. - Block ciphers -- These map m n-bit blocks of plaintext to m n-bit blocks of ciphertext. Because the base unit of transformation is the n-bit block, messages that are not exactly divisible by n must be padded (\c CPadding) to allow for their encryption. Optionally, instead of padding out a plaintext message to fit in a block, block ciphers allow buffering of partial input blocks until the remainder of the block is given as input. (@ref symmetricBuffering). Finally, block ciphers have a concept of modes (@ref symmetricModes) that provide a mechanism for making subsequent blocks dependent on some number of previous blocks.<hr>@section symmetricHow How do I use the symmetric cipher framework?- @ref symmetricHowIntro- @ref symmetricHowInterface- @ref symmetricHowFactory@subsection symmetricHowIntro An introduction to the symmetric cipher framework.The symmetric cipher framework collates the behaviour of all symmetric ciphersunder one interface: \c CSymmetricCipher. This interface is intended to representone direction of one instance of any symmetric cipher. One direction meanseither encryption or decryption, but not both.@subsection symmetricHowInterface CSymmetricCipher interface basics.- Block ciphers -- Here one must create an underlying transformation (\c CBlockTransformation) and create a \c CBufferedTransformation (which is an \c CSymmetricCipher) from that. - Stream ciphers -- These have no concept of buffering and are treated as specialisations of \c CSymmetricCipher. They require no intermediate container class. The following code illustrates the creation of a buffered AES ECB encryptor and anARC4 stream cipher. @codeCBlockTransformation* block = 0;block = CAESEncryptor::NewLC(aKey);CPadding* padding = CPaddingSSLv3::NewLC(KAESBlockSize); //The blocksize of AES (16 bytes)CSymmetricCipher* cipher = CBufferedEncryptor::NewL(block, padding);CleanupStack::Pop(2, block); //padding, block -> both owned by cipher@endcode@codeCSymmetricCipher* cipher = new(ELeave)TARC4(aKey);CleanupStack::PushL(cipher):@endcodeAfter creation, both examples are usable through the \c CSymmetricCipher interface.So, to encrypt with either of the above ciphers one could do:@codeHBufC8* output = HBufC8::NewLC(cipher->MaxOutputLength(input.Size()));cipher->Process(input, output);HBufC8* output2 = HBufC8::NewLC(cipher->MaxFinalOutputLength(input2.Size()));cipher->ProcessFinalL(input2, output2);@endcodeIn this example, \c input and \c input2 are two arbitrary, finite length descriptors.The derived implementations of \c CSymmetricCipher (\c CBufferedEncryptor / \c CBufferedDecryptorand \c CStreamCipher) are responsible for handling what to do in each specificcase. For example, in the case of an encrypting block cipher, \c ProcessFinalL()will call the underlying padding system, which will in turn ensure that theoverall length of input plaintext is of a suitable length for encryption. For moreinformation on how the values returned from \c MaxOutputLength() and\c MaxFinalOutputLength() are calculated see @ref symmetricBuffering.@subsection symmetricHowFactory Example code for a symmetric factory class.To simplify the process of creating symmetric encryptors and decryptors, it isstrongly recommended that applications create a factory that automates theprocess for them. The following code gives a sample factory that applicationsmight like to use as a reference. It is not supplied as part of the frameworkas every application has different ways of identifying symmetric cipher suites.@codeCSymmetricCipher* CCipherFactory::BuildEncryptorL( TSymmetricCipherType aType,const TDesC8& aKey,const TDesC8& aIV) { CSymmetricCipher* cipher = NULL; if (aType==ERc4) { cipher = new(ELeave) TARC4(aKey); } else { CBlockTransformation* bT = NULL; switch (aType) { case EDes_cbc: bT = CDESEncryptor::NewL(aKey); break; case EDes_ede3_cbc: bT = C3DESEncryptor::NewL(aKey); break; case ERc2_cbc: bT = CRC2Encryptor::NewL(aKey); break; default: User::Leave(KErrNotSupported); }; CleanupStack::PushL(bT); CBlockTransformation* mode = CModeCBCEncryptor::NewL(bT, aIV); CleanupStack::Pop(bT); // owned by mode CleanupStack::PushL(mode); CPadding* padding = CPaddingSSLv3::NewLC(KBlockSize); //All of these ciphers use 8 byte blocks cipher = CBufferedEncryptor::NewL(mode, padding); CleanupStack::Pop(2, mode); //padding, mode now owned by cipher } return cipher; }@endcodeApplications creating these factories need to supply an equivalent to the\c TSymmetricCipherType enum which contains the list of identifiers representingthe cipher, padding, and mode requirements of the application. Note that a similar \c BuildDecryptorL() will also have to be created.Good naming conventions dictate that applications should not pollute theglobal namespace and either use their own namespace or prefix their factoryclasses with identifiers that associated it with that specific application.<hr>@section symmetricModes Symmetric ModesWhen the amount of plaintext to be encrypted is larger than a single block, somemethod must be employed to specify how subsequent blocks are dependent onprevious blocks. The simplest method, known as ECB (Electronic CodeBook),specifies that subsequent blocks are completely independent. Therefore, twoidentical blocks of plaintext will encrypt to two identical blocks ofciphertext. ECB has significant security drawbacks, thus most applications usemore advanced modes in which subsequent blocks are dependent on the ciphertextof previous blocks. The symmetric framework handles these modes through the\c CBlockChainingMode class, which is a specialisation of \c CBlockTransformation.The idea is that one gives an implementation of a \c CBlockChainingMode another\c CBlockTransformation (\c CAESEncryptor, for instance) and then performs alloperations on the \c CBlockChainingMode instance. When<code>CBlockTransformation::Transform()</code> is called on the mode it is responsible forcalling \c Transform() on the underlying transformation that it owns and thenapplying its own chaining mode transformation.The following example shows how to create a buffered AES CBC encryptor.@codeCBlockTransformation* basicAesBlock = 0;CBlockTransformation* cbcBlock = 0;basicAesBlock = CAESEncryptor::NewLC(aKey);cbcBlock = CModeCBCEncryptor::NewL(basicAesBlock, iv);CleanupStack::Pop(basicAesBlock); //owned by cbcBlockCleanupStack::PushL(cbcBlock);CPadding* padding = CPaddingSSLv3::NewLC(KAESBlockSize); //The blocksize of AES (16 bytes)CSymmetricCipher* cipher = CBufferedEncryptor::NewL(cbcBlock, padding);CleanupStack::Pop(2, cbcBlock); //padding, cbcBlock -> both owned by cipher@endcode<hr>@section symmetricWhich Which symmetric cipher should I use? Generally, when implementing secure comms protocols, the cipher you use will bedictated by the protocol specification. However, if you are writing your ownapplication you should consider the use of AES (CAESEncryptor). This is thecipher recommended by <A HREF="http://csrc.nist.gov/cryptval/">NIST</A>.<hr>@section symmetricBuffering How does buffering work within the symmetric cipher framework? - Stream ciphers consume all content they are given. That is, the value returned from <code>CSymmetricCipher::MaxOutputLength()</code> is always the same as the \c aInputLength parameter passed in.- Block ciphers controlled through a \c CBufferedTransformation operate under the following rules: - \c Process() -# Any previously buffered data is (logically) prepended to \c aInput. -# All whole blocks are transformed and appended to \c aOutput. -# Any remaining partial blocks, orphaned by the the above rule, are buffered. - \c ProcessFinalL() - Encryption -# Any previously buffered data is (logically) prepended to \c aInput. -# All whole block are transformed and appended to \c aOutput. -# Any remaining partial blocks are padded with underlying padding system to be block aligned <I>to the padding block size</I>. (In the vast majority of cases, the padding block size is equal to the block cipher block size). -# The resulting block(s) are transformed and appended to \c aOutput. - Decryption -# The input <b>must</b> be a multiple of the block size. -# Data is decrypted and unpadded using underlying padding system. -# Decrypted, unpadded data is appended to \c aOutput.In all cases <code>CSymmetricCipher::MaxOutputLength()</code> returns as tight an upper boundas possible on the number of bytes that will be returned by a call to<code>CSymmetricCipher::Process()</code> with a specified number of input bytes.Correspondingly, <code>CSymmetricCipher::MaxFinalOutputLength()</code> returns a similarbound but for a pending call to <code>CSymmetricCipher::ProcessFinalL()</code>.*/