crypto/weakcrypto/docs/symmetric.dox
changeset 0 2c201484c85f
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /**
       
     2 @page symmetric_ciphers Symmetric Cipher
       
     3 
       
     4 - @ref symmetricWhat
       
     5 - @ref symmetricHow
       
     6 - @ref symmetricModes
       
     7 - @ref symmetricWhich
       
     8 - @ref symmetricBuffering
       
     9 
       
    10 <hr>
       
    11 
       
    12 @section symmetricWhat What are symmetric ciphers?
       
    13 
       
    14 In an informal setting, symmetric ciphers can be thought of as a mapping of some
       
    15 plaintext to ciphertext, via some well-known transformation function, dependent
       
    16 on a secret key.  There are two basic types of symmetric ciphers:
       
    17 	- Stream ciphers -- These map an n-bit stream of plaintext to a n-bit stream of 
       
    18 	  ciphertext.
       
    19 	- Block ciphers -- These map m n-bit blocks of plaintext to m n-bit blocks
       
    20 	  of ciphertext.  Because the base unit of transformation is the n-bit
       
    21 	  block, messages that are not exactly divisible by n must be padded (\c CPadding) 
       
    22 	  to allow for their encryption.  Optionally, instead of padding out a
       
    23 	  plaintext message to fit in a block, block ciphers allow buffering of
       
    24 	  partial input blocks until the remainder of the block is given as input.
       
    25 	  (@ref symmetricBuffering).  Finally, block ciphers have a concept of modes
       
    26 	  (@ref symmetricModes) that provide a mechanism for making subsequent
       
    27 	  blocks dependent on some number of previous blocks.
       
    28 
       
    29 <hr>
       
    30 @section symmetricHow How do I use the symmetric cipher framework?
       
    31 
       
    32 - @ref symmetricHowIntro
       
    33 - @ref symmetricHowInterface
       
    34 - @ref symmetricHowFactory
       
    35 
       
    36 @subsection symmetricHowIntro An introduction to the symmetric cipher framework.
       
    37 The symmetric cipher framework collates the behaviour of all symmetric ciphers
       
    38 under one interface: \c CSymmetricCipher.  This interface is intended to represent
       
    39 one direction of one instance of any symmetric cipher.  One direction means
       
    40 either encryption or decryption, but not both.
       
    41 	  
       
    42 @subsection symmetricHowInterface CSymmetricCipher interface basics.
       
    43 - Block ciphers -- Here one must create an underlying transformation (\c
       
    44   CBlockTransformation) and create a \c CBufferedTransformation (which is an
       
    45   \c CSymmetricCipher) from that.  
       
    46 - Stream ciphers -- These have no concept of buffering and are treated as
       
    47   specialisations of \c CSymmetricCipher.  They require no intermediate container
       
    48   class.  
       
    49 	  
       
    50 The following code illustrates the creation of a buffered AES ECB encryptor and an
       
    51 ARC4 stream cipher.  
       
    52 
       
    53 @code
       
    54 CBlockTransformation* block = 0;
       
    55 block = CAESEncryptor::NewLC(aKey);
       
    56 CPadding* padding = CPaddingSSLv3::NewLC(KAESBlockSize); //The blocksize of AES (16 bytes)
       
    57 CSymmetricCipher* cipher = CBufferedEncryptor::NewL(block, padding);
       
    58 CleanupStack::Pop(2, block); //padding, block -> both owned by cipher
       
    59 @endcode
       
    60 
       
    61 @code
       
    62 CSymmetricCipher* cipher = new(ELeave)TARC4(aKey);
       
    63 CleanupStack::PushL(cipher):
       
    64 @endcode
       
    65 
       
    66 After creation, both examples are usable through the \c CSymmetricCipher interface.
       
    67 So, to encrypt with either of the above ciphers one could do:
       
    68 
       
    69 @code
       
    70 HBufC8* output = HBufC8::NewLC(cipher->MaxOutputLength(input.Size()));
       
    71 cipher->Process(input, output);
       
    72 HBufC8* output2 = HBufC8::NewLC(cipher->MaxFinalOutputLength(input2.Size()));
       
    73 cipher->ProcessFinalL(input2, output2);
       
    74 @endcode
       
    75 
       
    76 In this example, \c input and \c input2 are two arbitrary, finite length descriptors.
       
    77 The derived implementations of \c CSymmetricCipher (\c CBufferedEncryptor / \c CBufferedDecryptor
       
    78 and \c CStreamCipher) are responsible for handling what to do in each specific
       
    79 case.  For example, in the case of an encrypting block cipher, \c ProcessFinalL()
       
    80 will call the underlying padding system, which will in turn ensure that the
       
    81 overall length of input plaintext is of a suitable length for encryption. For more
       
    82 information on how the values returned from \c MaxOutputLength() and
       
    83 \c MaxFinalOutputLength() are calculated see @ref symmetricBuffering.
       
    84 
       
    85 @subsection symmetricHowFactory Example code for a symmetric factory class.
       
    86 
       
    87 To simplify the process of creating symmetric encryptors and decryptors, it is
       
    88 strongly recommended that applications create a factory that automates the
       
    89 process for them.  The following code gives a sample factory that applications
       
    90 might like to use as a reference.  It is not supplied as part of the framework
       
    91 as every application has different ways of identifying symmetric cipher suites.
       
    92 
       
    93 @code
       
    94 CSymmetricCipher* CCipherFactory::BuildEncryptorL(
       
    95 	TSymmetricCipherType aType,const TDesC8& aKey,const TDesC8& aIV)
       
    96 	{
       
    97 	CSymmetricCipher* cipher = NULL;
       
    98 
       
    99 	if (aType==ERc4)
       
   100 		{
       
   101 		cipher = new(ELeave) TARC4(aKey);
       
   102 		}
       
   103 	else
       
   104 		{
       
   105 		CBlockTransformation* bT = NULL;
       
   106 		switch (aType)
       
   107 			{
       
   108 			case EDes_cbc:
       
   109 				bT = CDESEncryptor::NewL(aKey);
       
   110 				break;
       
   111 			case EDes_ede3_cbc:
       
   112 				bT = C3DESEncryptor::NewL(aKey);
       
   113 				break;
       
   114 			case ERc2_cbc:
       
   115 				bT = CRC2Encryptor::NewL(aKey);
       
   116 				break;
       
   117 			default:
       
   118 				User::Leave(KErrNotSupported);
       
   119 			};
       
   120 		CleanupStack::PushL(bT);
       
   121 		CBlockTransformation* mode = CModeCBCEncryptor::NewL(bT, aIV);
       
   122 		CleanupStack::Pop(bT);	//	owned by mode
       
   123 		CleanupStack::PushL(mode);
       
   124 	 
       
   125 		CPadding* padding = CPaddingSSLv3::NewLC(KBlockSize); //All of these ciphers use 8 byte blocks
       
   126 		cipher = CBufferedEncryptor::NewL(mode, padding);
       
   127 		CleanupStack::Pop(2, mode);	//padding, mode	now owned by cipher
       
   128 		}
       
   129 	return cipher;
       
   130 	}
       
   131 @endcode
       
   132 
       
   133 Applications creating these factories need to supply an equivalent to the
       
   134 \c TSymmetricCipherType enum which contains the list of identifiers representing
       
   135 the cipher, padding, and mode requirements of the application.  
       
   136 
       
   137 Note that a similar \c BuildDecryptorL() will also have to be created.
       
   138 
       
   139 Good naming conventions dictate that applications should not pollute the
       
   140 global namespace and either use their own namespace or prefix their factory
       
   141 classes with identifiers that associated it with that specific application.
       
   142 	 
       
   143 <hr>
       
   144 @section symmetricModes Symmetric Modes
       
   145 
       
   146 When the amount of plaintext to be encrypted is larger than a single block, some
       
   147 method must be employed to specify how subsequent blocks are dependent on
       
   148 previous blocks.  The simplest method, known as ECB (Electronic CodeBook),
       
   149 specifies that subsequent blocks are completely independent.  Therefore, two
       
   150 identical blocks of plaintext will encrypt to two identical blocks of
       
   151 ciphertext.  ECB has significant security drawbacks, thus most applications use
       
   152 more advanced modes in which subsequent blocks are dependent on the ciphertext
       
   153 of previous blocks.  The symmetric framework handles these modes through the
       
   154 \c CBlockChainingMode class, which is a specialisation of \c CBlockTransformation.
       
   155 The idea is that one gives an implementation of a \c CBlockChainingMode another
       
   156 \c CBlockTransformation (\c CAESEncryptor, for instance) and then performs all
       
   157 operations on the \c CBlockChainingMode instance.  When
       
   158 <code>CBlockTransformation::Transform()</code> is called on the mode it is responsible for
       
   159 calling \c Transform() on the underlying transformation that it owns and then
       
   160 applying its own chaining mode transformation.
       
   161 
       
   162 The following example shows how to create a buffered AES CBC encryptor.
       
   163 
       
   164 @code
       
   165 CBlockTransformation* basicAesBlock = 0;
       
   166 CBlockTransformation* cbcBlock = 0;
       
   167 basicAesBlock = CAESEncryptor::NewLC(aKey);
       
   168 cbcBlock = CModeCBCEncryptor::NewL(basicAesBlock, iv);
       
   169 CleanupStack::Pop(basicAesBlock); //owned by cbcBlock
       
   170 CleanupStack::PushL(cbcBlock);
       
   171 CPadding* padding = CPaddingSSLv3::NewLC(KAESBlockSize); //The blocksize of AES (16 bytes)
       
   172 CSymmetricCipher* cipher = CBufferedEncryptor::NewL(cbcBlock, padding);
       
   173 CleanupStack::Pop(2, cbcBlock); //padding, cbcBlock -> both owned by cipher
       
   174 @endcode
       
   175 
       
   176 <hr>
       
   177 @section symmetricWhich Which symmetric cipher should I use?  
       
   178 Generally, when implementing secure comms protocols, the cipher you use will be
       
   179 dictated by the protocol specification.  However, if you are writing your own
       
   180 application you should consider the use of AES (CAESEncryptor).  This is the
       
   181 cipher recommended by <A HREF="http://csrc.nist.gov/cryptval/">NIST</A>.
       
   182 
       
   183 <hr>
       
   184 @section symmetricBuffering How does buffering work within the symmetric cipher framework?  
       
   185 
       
   186 - Stream ciphers consume all content they are given.  That is, the value
       
   187   returned from <code>CSymmetricCipher::MaxOutputLength()</code> is always the same as the
       
   188   \c aInputLength parameter passed in.
       
   189 - Block ciphers controlled through a \c CBufferedTransformation operate under the
       
   190   following rules:
       
   191   	- \c Process()
       
   192 		-# Any previously buffered data is (logically) prepended to \c aInput.
       
   193 		-# All whole blocks are transformed and appended to \c aOutput.
       
   194 		-# Any remaining partial blocks, orphaned by the the above rule, are
       
   195 		buffered.
       
   196 	- \c ProcessFinalL()
       
   197 		- Encryption
       
   198 			-# Any previously buffered data is (logically) prepended to \c aInput.
       
   199 			-# All whole block are transformed and appended to \c aOutput.
       
   200 			-# Any remaining partial blocks are padded with underlying padding
       
   201 			system to be block aligned <I>to the padding block size</I>. (In the
       
   202 			vast majority of cases, the padding block size is equal to the
       
   203 			block cipher block size).
       
   204 			-# The resulting block(s) are transformed and appended to \c aOutput.
       
   205 		- Decryption
       
   206 			-# The input <b>must</b> be a multiple of the block size.
       
   207 			-# Data is decrypted and unpadded using underlying padding system.
       
   208 			-# Decrypted, unpadded data is appended to \c aOutput.
       
   209 
       
   210 In all cases <code>CSymmetricCipher::MaxOutputLength()</code> returns as tight an upper bound
       
   211 as possible on the number of bytes that will be returned by a call to
       
   212 <code>CSymmetricCipher::Process()</code> with a specified number of input bytes.
       
   213 Correspondingly, <code>CSymmetricCipher::MaxFinalOutputLength()</code> returns a similar
       
   214 bound but for a pending call to <code>CSymmetricCipher::ProcessFinalL()</code>.
       
   215 */