Symbian3/SDK/Source/GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita
changeset 8 ae94777fff8f
equal deleted inserted replaced
7:51a74ef9ed63 8:ae94777fff8f
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485" xml:lang="en"><title>Symmetric
       
    13 ciphers -- HowTo</title><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <ul>
       
    15 <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>
       
    16 <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>
       
    17 <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>
       
    18 <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>
       
    19 </ul>
       
    20 <section id="GUID-119D039F-4624-5464-AA17-BBAB18A8D3CD"><title>How do I use
       
    21 the symmetric cipher framework? </title> <ul>
       
    22 <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>
       
    23 <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>
       
    24 <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>
       
    25 </ul> <p id="GUID-21BCC641-FEE9-55FA-84E9-FF1EE425309F"><b> An introduction
       
    26 to the symmetric cipher framework </b> </p> <p>The symmetric cipher framework
       
    27 collates the behaviour of all symmetric ciphers under one interface: <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita"><apiname>CSymmetricCipher</apiname></xref>.
       
    28 This interface is intended to represent one direction of one instance of any
       
    29 symmetric cipher. One direction means either encryption or decryption, but
       
    30 not both. </p> <p id="GUID-DFE76D85-7AD6-5B96-906B-98B3F63B88B7"><b> CSymmetricCipher
       
    31 interface basics </b> </p> <ul>
       
    32 <li id="GUID-200B0A58-EA9D-5BC7-8EDF-625B2C43BE72"><p> <b> Block ciphers</b> --
       
    33 Here one must create an underlying transformation (<xref href="GUID-CFDA5321-EE13-3203-8DED-71E69D4469BD.dita"><apiname>CBlockTransformation</apiname></xref>)
       
    34 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>)
       
    35 from that. </p> </li>
       
    36 <li id="GUID-4D3532BB-58B1-5BF1-9253-B1FEE5917053"><p> <b> Stream ciphers</b> --
       
    37 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>.
       
    38 They require no intermediate container class. </p> </li>
       
    39 </ul> <p>The following code illustrates the creation of a buffered AES ECB
       
    40 encryptor and an ARC4 stream cipher. </p> <codeblock id="GUID-278C21E0-E3E1-5575-9C37-9530F08BB227" xml:space="preserve">
       
    41 CBlockTransformation* block = 0;
       
    42 block = CAESEncryptor::NewLC(aKey);
       
    43 CPadding* padding = CPaddingSSLv3::NewLC(KAESBlockSize); //The blocksize of AES (16 bytes)
       
    44 CSymmetricCipher* cipher = CBufferedEncryptor::NewL(block, padding);
       
    45 CleanupStack::Pop(2, block); //padding, block -&gt; both owned by cipher
       
    46 </codeblock> <codeblock id="GUID-AC44907E-CD42-514A-AE39-D1981F3267FA" xml:space="preserve">
       
    47 CSymmetricCipher* cipher = new(ELeave)CARC4(aKey);
       
    48 CleanupStack::PushL(cipher):
       
    49 </codeblock> <p>After creation, both examples are usable through the <xref href="GUID-F4E08165-A654-3D32-8FED-7ED54BDAD88B.dita"><apiname>CSymmetricCipher</apiname></xref> interface.
       
    50 So, to encrypt with either of the above ciphers one could do: </p> <codeblock id="GUID-BF286466-ABBD-5810-801C-7C455CBE52FD" xml:space="preserve">
       
    51 HBufC8* output = HBufC8::NewLC(cipher-&gt;MaxOutputLength(input.Size()));
       
    52 cipher-&gt;Process(input, output);
       
    53 HBufC8* output2 = HBufC8::NewLC(cipher-&gt;MaxFinalOutputLength(input2.Size()));
       
    54 cipher-&gt;ProcessFinalL(input2, output2);
       
    55 </codeblock> <p>In this example, <codeph>input</codeph> and <codeph>input2</codeph> are
       
    56 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>)
       
    57 are responsible for handling what to do in each specific case. For example,
       
    58 in the case of an encrypting block cipher, <codeph>ProcessFinalL()</codeph> will
       
    59 call the underlying padding system, which will in turn ensure that the overall
       
    60 length of input plaintext is of a suitable length for encryption. For more
       
    61 information on how the values returned from <codeph>MaxOutputLength()</codeph> and <codeph>MaxFinalOutputLength()</codeph> are
       
    62 calculated see <xref href="GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485.dita#GUID-CFF1BCCA-5D07-5B8A-9363-AD11EEEAB485/GUID-3393A9D6-CB78-5740-B250-F9C1C26C59BD">How
       
    63 does buffering work within the symmetric cipher framework?</xref>. </p> <p id="GUID-2018AFFC-09D9-5F99-BACC-8C77504E5CC3"><b>Example code for a symmetric
       
    64 factory class </b> </p> <p>To simplify the process of creating symmetric encryptors
       
    65 and decryptors, it is strongly recommended that applications create a factory
       
    66 that automates the process for them. The following code gives a sample factory
       
    67 that applications might like to use as a reference. It is not supplied as
       
    68 part of the framework as every application has different ways of identifying
       
    69 symmetric cipher suites. </p> <codeblock id="GUID-EF0D121A-1961-5EF7-BA04-5BCE5DC029D4" xml:space="preserve">
       
    70 CSymmetricCipher* CCipherFactory::BuildEncryptorL(
       
    71     TSymmetricCipherType aType,const TDesC8&amp; aKey,const TDesC8&amp; aIV)
       
    72     {
       
    73     CSymmetricCipher* cipher = NULL;
       
    74 
       
    75     if (aType==ERc4)
       
    76         {
       
    77         cipher = new(ELeave) CARC4(aKey);
       
    78         }
       
    79     else
       
    80         {
       
    81         CBlockTransformation* bT = NULL;
       
    82         switch (aType)
       
    83             {
       
    84             case EDes_cbc:
       
    85                 bT = CDESEncryptor::NewL(aKey);
       
    86                 break;
       
    87             case EDes_ede3_cbc:
       
    88                 bT = C3DESEncryptor::NewL(aKey);
       
    89                 break;
       
    90             case ERc2_cbc:
       
    91                 bT = CRC2Encryptor::NewL(aKey);
       
    92                 break;
       
    93             default:
       
    94                 User::Leave(KErrNotSupported);
       
    95             };
       
    96         CleanupStack::PushL(bT);
       
    97         CBlockTransformation* mode = CModeCBCEncryptor::NewL(bT, aIV);
       
    98         CleanupStack::Pop(bT);    //    owned by mode
       
    99         CleanupStack::PushL(mode);
       
   100      
       
   101         CPadding* padding = CPaddingSSLv3::NewLC(KBlockSize); //All of these ciphers use 8 byte blocks
       
   102         cipher = CBufferedEncryptor::NewL(mode, padding);
       
   103         CleanupStack::Pop(2, mode);    //padding, mode    now owned by cipher
       
   104         }
       
   105     return cipher;
       
   106     }
       
   107 </codeblock> <p>Applications creating these factories need to supply an equivalent
       
   108 to the <codeph>TSymmetricCipherType</codeph> enum, which contains the list
       
   109 of identifiers representing the cipher, padding, and mode requirements of
       
   110 the application. </p> <p>Note that a similar <codeph>BuildDecryptorL()</codeph> will
       
   111 also have to be created. </p> <p>Good naming conventions dictate that applications
       
   112 should not pollute the global namespace and either use their own namespace
       
   113 or prefix their factory classes with identifiers that associated it with that
       
   114 specific application. </p> </section>
       
   115 <section id="GUID-71CD8B41-219D-5D07-8C99-47D68668A880"><title>Symmetric Modes </title> <p>When
       
   116 the amount of plaintext to be encrypted is larger than a single block, some
       
   117 method must be employed to specify how subsequent blocks are dependent on
       
   118 previous blocks. The simplest method, known as ECB (Electronic CodeBook),
       
   119 specifies that subsequent blocks are completely independent. Therefore, two
       
   120 identical blocks of plaintext will encrypt to two identical blocks of ciphertext.
       
   121 ECB has significant security drawbacks, thus most applications use more advanced
       
   122 modes in which subsequent blocks are dependent on the ciphertext of previous
       
   123 blocks. The symmetric framework handles these modes through the <xref href="GUID-436C3EBE-FC60-3760-A3BA-D8DF8FA5B8AF.dita"><apiname>CBlockChainingMode</apiname></xref> class,
       
   124 which is a specialization of <xref href="GUID-CFDA5321-EE13-3203-8DED-71E69D4469BD.dita"><apiname>CBlockTransformation</apiname></xref>. The
       
   125 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.
       
   126 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
       
   127 mode, it is responsible for calling <codeph>Transform()</codeph> on the underlying
       
   128 transformation that it owns and then applying its own chaining mode transformation. </p> <p>The
       
   129 following example shows how to create a buffered AES CBC encryptor. </p> <codeblock id="GUID-A3DFB7C2-D727-553C-9BF9-0E865417DBA3" xml:space="preserve">
       
   130 CBlockTransformation* basicAesBlock = 0;
       
   131 CBlockTransformation* cbcBlock = 0;
       
   132 basicAesBlock = CAESEncryptor::NewLC(aKey);
       
   133 cbcBlock = CModeCBCEncryptor::NewL(basicAesBlock, iv);
       
   134 CleanupStack::Pop(basicAesBlock); //owned by cbcBlock
       
   135 CleanupStack::PushL(cbcBlock);
       
   136 CPadding* padding = CPaddingSSLv3::NewLC(KAESBlockSize); //The blocksize of AES (16 bytes)
       
   137 CSymmetricCipher* cipher = CBufferedEncryptor::NewL(cbcBlock, padding);
       
   138 CleanupStack::Pop(2, cbcBlock); //padding, cbcBlock -&gt; both owned by cipher
       
   139 </codeblock> </section>
       
   140 <section id="GUID-86CD649D-3611-531A-8D9E-1FCC9728500B"><title>Which symmetric
       
   141 cipher should I use? </title> <p>Generally, when implementing secure comms
       
   142 protocols, the cipher you use will be dictated by the protocol specification.
       
   143 However, if you are writing your own application, you should consider the
       
   144 use of AES (<xref href="GUID-AE1A9AC0-DB79-3C62-AA23-896812F25F14.dita"><apiname>CAESEncryptor</apiname></xref>); this is the cipher recommended
       
   145 by <xref href="http://csrc.nist.gov/cryptval/" scope="external">NIST</xref>. </p> </section>
       
   146 <section id="GUID-3393A9D6-CB78-5740-B250-F9C1C26C59BD"><title>How does buffering
       
   147 work within the symmetric cipher framework? </title> <ul>
       
   148 <li id="GUID-2A87BE74-9F27-5F0A-BA32-706FF5B1861B"><p> <b>Stream ciphers</b> consume
       
   149 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
       
   150 always the same as the <codeph>aInputLength</codeph> parameter passed in. </p> </li>
       
   151 <li id="GUID-E63F6682-E96F-5AB7-9786-E7F210B321ED"><p> <b>Block ciphers</b> controlled
       
   152 through a <xref href="GUID-65F145BB-CE4B-3BCC-A9FC-5F9107F32488.dita"><apiname>CBufferedTransformation</apiname></xref> operate under the following
       
   153 rules: </p> <ul>
       
   154 <li id="GUID-3D963E44-1D4E-5505-9124-47DF2F145118"><p> <codeph>Process() </codeph>  </p> <ul id="GUID-943B86EF-01BD-53CB-B68F-507753850EC4">
       
   155 <li id="GUID-271426C1-8E3E-5C95-8D55-1C3F2F2FC771"><p>Any previously buffered
       
   156 data is (logically) prepended to <codeph>aInput</codeph>. </p> </li>
       
   157 <li id="GUID-84C9BDF7-6BE5-5D02-9F00-1386F175757F"><p>All whole blocks are
       
   158 transformed and appended to <codeph>aOutput</codeph>. </p> </li>
       
   159 <li id="GUID-80FB971C-FAE8-576D-95A8-2762343B2B74"><p>Any remaining partial
       
   160 blocks, orphaned by the above rule, are buffered. </p> </li>
       
   161 </ul> </li>
       
   162 <li id="GUID-93D49834-2716-5992-9B56-195813C3F4E0"><p> <codeph>ProcessFinalL()</codeph>  </p> <ul>
       
   163 <li id="GUID-B5B476B7-EAC3-594C-B613-88900BB99654"><p>Encryption </p> <ol id="GUID-FD8C1EAA-3C8F-5034-ABAA-F4DFB6B2493A">
       
   164 <li id="GUID-21579114-8456-573A-A79E-F8C84A7AFFCA"><p>Any previously buffered
       
   165 data is (logically) prepended to <codeph>aInput</codeph>. </p> </li>
       
   166 <li id="GUID-1C3199C1-41C1-5524-AD65-52D0F60816C1"><p>All whole block are
       
   167 transformed and appended to <codeph>aOutput</codeph>. </p> </li>
       
   168 <li id="GUID-7DF3B7AB-4C91-5C83-A963-5C18057AC8D3"><p>Any remaining partial
       
   169 blocks are padded with underlying padding system to be block aligned <i>to
       
   170 the padding block size</i>. (In the vast majority of cases, the padding block
       
   171 size is equal to the block cipher block size). </p> </li>
       
   172 <li id="GUID-6709F044-F7D7-5BBD-8816-9829ECBD8F17"><p>The resulting block(s)
       
   173 are transformed and appended to <codeph>aOutput</codeph>. </p> </li>
       
   174 </ol> </li>
       
   175 <li id="GUID-1BD95B71-34F8-57D9-A882-9EE616A82512"><p>Decryption </p> <ol id="GUID-46984F1C-D4CA-5719-8235-CF22A3325B37">
       
   176 <li id="GUID-3F4DABA6-9CFB-5F05-8B98-6F14CB64EFC4"><p>The input <b>must</b> be
       
   177 a multiple of the block size. </p> </li>
       
   178 <li id="GUID-A555D9FE-3211-521A-903E-5E22FF017FCE"><p>Data is decrypted and
       
   179 unpadded using underlying padding system. </p> </li>
       
   180 <li id="GUID-57C20E84-CF6C-5699-ABF0-D5080D8517A4"><p>Decrypted, unpadded
       
   181 data is appended to <codeph>aOutput</codeph>. </p> </li>
       
   182 </ol> </li>
       
   183 </ul> </li>
       
   184 </ul> </li>
       
   185 </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
       
   186 as tight an upper bound as possible on the number of bytes that will be returned
       
   187 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
       
   188 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
       
   189 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>
       
   190 </conbody></concept>