Symbian3/SDK/Source/GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita
changeset 8 ae94777fff8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita	Fri Jun 11 12:39:03 2010 +0100
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485" xml:lang="en"><title>Symmetric
+ciphers -- HowTo</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<ul>
+<li id="GUID-0B38AF7B-D5D7-5A06-865D-76F056634C2A"><p> <xref href="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita#GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485/GUID-119D039F-4624-5464-AA17-BBAB18A8D3CD">How do I use the symmetric cipher framework?</xref>  </p> </li>
+<li id="GUID-6B472E69-7101-5AC2-B91C-E6FB3FEA067E"><p> <xref href="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita#GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485/GUID-71CD8B41-219D-5D07-8C99-47D68668A880">Symmetric Modes</xref>  </p> </li>
+<li id="GUID-3D8DF8E4-8839-51DB-9223-99931F01A7EB"><p> <xref href="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita#GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485/GUID-86CD649D-3611-531A-8D9E-1FCC9728500B">Which symmetric cipher should I use?</xref>  </p> </li>
+<li id="GUID-24318339-1B08-5CAF-8EE6-C512DA548670"><p> <xref href="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita#GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485/GUID-3393A9D6-CB78-5740-B250-F9C1C26C59BD">How does buffering work within the symmetric cipher framework?</xref>  </p> </li>
+</ul>
+<section id="GUID-119D039F-4624-5464-AA17-BBAB18A8D3CD"><title>How do I use
+the symmetric cipher framework? </title> <ul>
+<li id="GUID-78AC1C88-612F-5D55-B357-497D637F20E1"><p> <xref href="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita#GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485/GUID-21BCC641-FEE9-55FA-84E9-FF1EE425309F">An introduction to the symmetric cipher framework</xref>  </p> </li>
+<li id="GUID-769B5855-9DA2-5E32-9270-B8F63D39366A"><p> <xref href="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita#GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485/GUID-DFE76D85-7AD6-5B96-906B-98B3F63B88B7"><apiname>CSymmetricCipher</apiname> interface basics</xref>  </p> </li>
+<li id="GUID-6EC9722D-DC7E-5DF8-A55F-D308C92DEC73"><p> <xref href="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita#GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485/GUID-2018AFFC-09D9-5F99-BACC-8C77504E5CC3">Example code for a symmetric factory class</xref>  </p> </li>
+</ul> <p id="GUID-21BCC641-FEE9-55FA-84E9-FF1EE425309F"><b> An introduction
+to the symmetric cipher framework </b> </p> <p>The symmetric cipher framework
+collates the behaviour of all symmetric ciphers under one interface: <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita"><apiname>CSymmetricCipher</apiname></xref>.
+This interface is intended to represent one direction of one instance of any
+symmetric cipher. One direction means either encryption or decryption, but
+not both. </p> <p id="GUID-DFE76D85-7AD6-5B96-906B-98B3F63B88B7"><b> CSymmetricCipher
+interface basics </b> </p> <ul>
+<li id="GUID-200B0A58-EA9D-5BC7-8EDF-625B2C43BE72"><p> <b> Block ciphers</b> --
+Here one must create an underlying transformation (<xref href="GUID-CFDA5321-EE13-3203-8DED-71E69D4469BD.dita"><apiname>CBlockTransformation</apiname></xref>)
+and create a <xref href="GUID-65F145BB-CE4B-3BCC-A9FC-5F9107F32488.dita"><apiname>CBufferedTransformation</apiname></xref> (which is an <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita"><apiname>CSymmetricCipher</apiname></xref>)
+from that. </p> </li>
+<li id="GUID-4D3532BB-58B1-5BF1-9253-B1FEE5917053"><p> <b> Stream ciphers</b> --
+These have no concept of buffering and are treated as specializations of <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita"><apiname>CSymmetricCipher</apiname></xref>.
+They require no intermediate container class. </p> </li>
+</ul> <p>The following code illustrates the creation of a buffered AES ECB
+encryptor and an ARC4 stream cipher. </p> <codeblock id="GUID-278C21E0-E3E1-5575-9C37-9530F08BB227" xml:space="preserve">
+CBlockTransformation* 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 -&gt; both owned by cipher
+</codeblock> <codeblock id="GUID-AC44907E-CD42-514A-AE39-D1981F3267FA" xml:space="preserve">
+CSymmetricCipher* cipher = new(ELeave)CARC4(aKey);
+CleanupStack::PushL(cipher):
+</codeblock> <p>After creation, both examples are usable through the <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita"><apiname>CSymmetricCipher</apiname></xref> interface.
+So, to encrypt with either of the above ciphers one could do: </p> <codeblock id="GUID-BF286466-ABBD-5810-801C-7C455CBE52FD" xml:space="preserve">
+HBufC8* output = HBufC8::NewLC(cipher-&gt;MaxOutputLength(input.Size()));
+cipher-&gt;Process(input, output);
+HBufC8* output2 = HBufC8::NewLC(cipher-&gt;MaxFinalOutputLength(input2.Size()));
+cipher-&gt;ProcessFinalL(input2, output2);
+</codeblock> <p>In this example, <codeph>input</codeph> and <codeph>input2</codeph> are
+two arbitrary, finite length descriptors. The derived implementations of <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita"><apiname>CSymmetricCipher</apiname></xref> (<xref href="GUID-8251F03D-D816-386E-A23A-947EEC6C8BC6.dita"><apiname>CBufferedEncryptor</apiname></xref> / <xref href="GUID-01CAF2BA-9120-304C-A488-5882CBD23EBC.dita"><apiname>CBufferedDecryptor</apiname></xref> and <xref href="GUID-40EFC716-0990-3C90-893E-43B3E6821C75.dita"><apiname>CStreamCipher</apiname></xref>)
+are responsible for handling what to do in each specific case. For example,
+in the case of an encrypting block cipher, <codeph>ProcessFinalL()</codeph> will
+call the underlying padding system, which will in turn ensure that the overall
+length of input plaintext is of a suitable length for encryption. For more
+information on how the values returned from <codeph>MaxOutputLength()</codeph> and <codeph>MaxFinalOutputLength()</codeph> are
+calculated see <xref href="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita#GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485/GUID-3393A9D6-CB78-5740-B250-F9C1C26C59BD">How
+does buffering work within the symmetric cipher framework?</xref>. </p> <p id="GUID-2018AFFC-09D9-5F99-BACC-8C77504E5CC3"><b>Example code for a symmetric
+factory class </b> </p> <p>To simplify the process of creating symmetric encryptors
+and decryptors, it is strongly recommended that applications create a factory
+that automates the process for them. The following code gives a sample factory
+that applications might like to use as a reference. It is not supplied as
+part of the framework as every application has different ways of identifying
+symmetric cipher suites. </p> <codeblock id="GUID-EF0D121A-1961-5EF7-BA04-5BCE5DC029D4" xml:space="preserve">
+CSymmetricCipher* CCipherFactory::BuildEncryptorL(
+    TSymmetricCipherType aType,const TDesC8&amp; aKey,const TDesC8&amp; aIV)
+    {
+    CSymmetricCipher* cipher = NULL;
+
+    if (aType==ERc4)
+        {
+        cipher = new(ELeave) CARC4(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;
+    }
+</codeblock> <p>Applications creating these factories need to supply an equivalent
+to the <codeph>TSymmetricCipherType</codeph> enum, which contains the list
+of identifiers representing the cipher, padding, and mode requirements of
+the application. </p> <p>Note that a similar <codeph>BuildDecryptorL()</codeph> will
+also have to be created. </p> <p>Good naming conventions dictate that applications
+should not pollute the global namespace and either use their own namespace
+or prefix their factory classes with identifiers that associated it with that
+specific application. </p> </section>
+<section id="GUID-71CD8B41-219D-5D07-8C99-47D68668A880"><title>Symmetric Modes </title> <p>When
+the amount of plaintext to be encrypted is larger than a single block, some
+method must be employed to specify how subsequent blocks are dependent on
+previous blocks. The simplest method, known as ECB (Electronic CodeBook),
+specifies that subsequent blocks are completely independent. Therefore, two
+identical blocks of plaintext will encrypt to two identical blocks of ciphertext.
+ECB has significant security drawbacks, thus most applications use more advanced
+modes in which subsequent blocks are dependent on the ciphertext of previous
+blocks. The symmetric framework handles these modes through the <xref href="GUID-436C3EBE-FC60-3760-A3BA-D8DF8FA5B8AF.dita"><apiname>CBlockChainingMode</apiname></xref> class,
+which is a specialization of <xref href="GUID-CFDA5321-EE13-3203-8DED-71E69D4469BD.dita"><apiname>CBlockTransformation</apiname></xref>. The
+idea is that one gives an implementation of a <xref href="GUID-436C3EBE-FC60-3760-A3BA-D8DF8FA5B8AF.dita"><apiname>CBlockChainingMode</apiname></xref> another <xref href="GUID-CFDA5321-EE13-3203-8DED-71E69D4469BD.dita"><apiname>CBlockTransformation</apiname></xref> (<xref href="GUID-AE1A9AC0-DB79-3C62-AA23-896812F25F14.dita"><apiname>CAESEncryptor</apiname></xref>, for instance) and then performs all operations on the <xref href="GUID-436C3EBE-FC60-3760-A3BA-D8DF8FA5B8AF.dita"><apiname>CBlockChainingMode</apiname></xref> instance.
+When <xref href="GUID-CFDA5321-EE13-3203-8DED-71E69D4469BD.dita#GUID-CFDA5321-EE13-3203-8DED-71E69D4469BD/GUID-A4F36BDB-5FB3-3082-B362-30A59D13B104"><apiname>CBlockTransformation::Transform()</apiname></xref> is called on the
+mode, it is responsible for calling <codeph>Transform()</codeph> on the underlying
+transformation that it owns and then applying its own chaining mode transformation. </p> <p>The
+following example shows how to create a buffered AES CBC encryptor. </p> <codeblock id="GUID-A3DFB7C2-D727-553C-9BF9-0E865417DBA3" xml:space="preserve">
+CBlockTransformation* basicAesBlock = 0;
+CBlockTransformation* cbcBlock = 0;
+basicAesBlock = CAESEncryptor::NewLC(aKey);
+cbcBlock = CModeCBCEncryptor::NewL(basicAesBlock, iv);
+CleanupStack::Pop(basicAesBlock); //owned by cbcBlock
+CleanupStack::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 -&gt; both owned by cipher
+</codeblock> </section>
+<section id="GUID-86CD649D-3611-531A-8D9E-1FCC9728500B"><title>Which symmetric
+cipher should I use? </title> <p>Generally, when implementing secure comms
+protocols, the cipher you use will be dictated by the protocol specification.
+However, if you are writing your own application, you should consider the
+use of AES (<xref href="GUID-AE1A9AC0-DB79-3C62-AA23-896812F25F14.dita"><apiname>CAESEncryptor</apiname></xref>); this is the cipher recommended
+by <xref href="http://csrc.nist.gov/cryptval/" scope="external">NIST</xref>. </p> </section>
+<section id="GUID-3393A9D6-CB78-5740-B250-F9C1C26C59BD"><title>How does buffering
+work within the symmetric cipher framework? </title> <ul>
+<li id="GUID-2A87BE74-9F27-5F0A-BA32-706FF5B1861B"><p> <b>Stream ciphers</b> consume
+all content they are given. That is, the value returned from <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita#GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B/GUID-31976831-1620-3396-8E91-BBF934D4167D"><apiname>CSymmetricCipher::MaxOutputLength()</apiname></xref> is
+always the same as the <codeph>aInputLength</codeph> parameter passed in. </p> </li>
+<li id="GUID-E63F6682-E96F-5AB7-9786-E7F210B321ED"><p> <b>Block ciphers</b> controlled
+through a <xref href="GUID-65F145BB-CE4B-3BCC-A9FC-5F9107F32488.dita"><apiname>CBufferedTransformation</apiname></xref> operate under the following
+rules: </p> <ul>
+<li id="GUID-3D963E44-1D4E-5505-9124-47DF2F145118"><p> <codeph>Process() </codeph>  </p> <ul id="GUID-943B86EF-01BD-53CB-B68F-507753850EC4">
+<li id="GUID-271426C1-8E3E-5C95-8D55-1C3F2F2FC771"><p>Any previously buffered
+data is (logically) prepended to <codeph>aInput</codeph>. </p> </li>
+<li id="GUID-84C9BDF7-6BE5-5D02-9F00-1386F175757F"><p>All whole blocks are
+transformed and appended to <codeph>aOutput</codeph>. </p> </li>
+<li id="GUID-80FB971C-FAE8-576D-95A8-2762343B2B74"><p>Any remaining partial
+blocks, orphaned by the above rule, are buffered. </p> </li>
+</ul> </li>
+<li id="GUID-93D49834-2716-5992-9B56-195813C3F4E0"><p> <codeph>ProcessFinalL()</codeph>  </p> <ul>
+<li id="GUID-B5B476B7-EAC3-594C-B613-88900BB99654"><p>Encryption </p> <ol id="GUID-FD8C1EAA-3C8F-5034-ABAA-F4DFB6B2493A">
+<li id="GUID-21579114-8456-573A-A79E-F8C84A7AFFCA"><p>Any previously buffered
+data is (logically) prepended to <codeph>aInput</codeph>. </p> </li>
+<li id="GUID-1C3199C1-41C1-5524-AD65-52D0F60816C1"><p>All whole block are
+transformed and appended to <codeph>aOutput</codeph>. </p> </li>
+<li id="GUID-7DF3B7AB-4C91-5C83-A963-5C18057AC8D3"><p>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). </p> </li>
+<li id="GUID-6709F044-F7D7-5BBD-8816-9829ECBD8F17"><p>The resulting block(s)
+are transformed and appended to <codeph>aOutput</codeph>. </p> </li>
+</ol> </li>
+<li id="GUID-1BD95B71-34F8-57D9-A882-9EE616A82512"><p>Decryption </p> <ol id="GUID-46984F1C-D4CA-5719-8235-CF22A3325B37">
+<li id="GUID-3F4DABA6-9CFB-5F05-8B98-6F14CB64EFC4"><p>The input <b>must</b> be
+a multiple of the block size. </p> </li>
+<li id="GUID-A555D9FE-3211-521A-903E-5E22FF017FCE"><p>Data is decrypted and
+unpadded using underlying padding system. </p> </li>
+<li id="GUID-57C20E84-CF6C-5699-ABF0-D5080D8517A4"><p>Decrypted, unpadded
+data is appended to <codeph>aOutput</codeph>. </p> </li>
+</ol> </li>
+</ul> </li>
+</ul> </li>
+</ul> <p>In all cases <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita#GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B/GUID-31976831-1620-3396-8E91-BBF934D4167D"><apiname>CSymmetricCipher::MaxOutputLength()</apiname></xref> returns
+as tight an upper bound as possible on the number of bytes that will be returned
+by a call to <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita#GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B/GUID-97E4F631-9CD5-3295-A22C-AAA5A4708FE9"><apiname>CSymmetricCipher::Process()</apiname></xref> with a specified
+number of input bytes. Correspondingly, <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita#GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B/GUID-3675861D-0520-3F85-BA2B-AA3CF1964483"><apiname>CSymmetricCipher::MaxFinalOutputLength()</apiname></xref> returns
+a similar bound but for a pending call to <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita#GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B/GUID-BE38C96D-F071-3385-8C7D-09BA4FC44432"><apiname>CSymmetricCipher::ProcessFinalL()</apiname></xref>. </p> </section>
+</conbody></concept>
\ No newline at end of file