Sophie

Sophie

distrib > Mandriva > 10.2 > i586 > media > contrib > by-pkgid > 7457b841ac8136d3a1a9d3d960c5252e > files > 1320

libcryptopp-doc-5.2.1-2mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Crypto++: modes.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.7 -->
<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical&nbsp;List</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="namespacemembers.html">Namespace&nbsp;Members</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="globals.html">File&nbsp;Members</a></div>
<h1>modes.cpp</h1><pre class="fragment"><div>00001 <span class="comment">// modes.cpp - written and placed in the public domain by Wei Dai</span>
00002 
00003 <span class="preprocessor">#include "pch.h"</span>
00004 
00005 <span class="preprocessor">#ifndef CRYPTOPP_IMPORTS</span>
00006 <span class="preprocessor"></span>
00007 <span class="preprocessor">#include "<a class="code" href="modes_8h.html">modes.h</a>"</span>
00008 
00009 <span class="preprocessor">#ifndef NDEBUG</span>
00010 <span class="preprocessor"></span><span class="preprocessor">#include "<a class="code" href="des_8h.html">des.h</a>"</span>
00011 <span class="preprocessor">#endif</span>
00012 <span class="preprocessor"></span>
00013 NAMESPACE_BEGIN(CryptoPP)
00014 
00015 #ifndef NDEBUG
00016 <span class="keywordtype">void</span> Modes_TestInstantiations()
00017 {
00018         <a class="code" href="struct_c_f_b___mode.html">CFB_Mode&lt;DES&gt;</a>::Encryption m0;
00019         <a class="code" href="struct_c_f_b___mode.html">CFB_Mode&lt;DES&gt;</a>::Decryption m1;
00020         <a class="code" href="struct_o_f_b___mode.html">OFB_Mode&lt;DES&gt;</a>::Encryption m2;
00021         <a class="code" href="struct_c_t_r___mode.html">CTR_Mode&lt;DES&gt;</a>::Encryption m3;
00022         <a class="code" href="struct_e_c_b___mode.html">ECB_Mode&lt;DES&gt;</a>::Encryption m4;
00023         <a class="code" href="struct_c_b_c___mode.html">CBC_Mode&lt;DES&gt;</a>::Encryption m5;
00024 }
00025 <span class="preprocessor">#endif</span>
00026 <span class="preprocessor"></span>
00027 <span class="keywordtype">void</span> CipherModeBase::SetKey(<span class="keyword">const</span> byte *key, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &amp;params)
00028 {
00029         UncheckedSetKey(params, key, length, GetIVAndThrowIfInvalid(params));   <span class="comment">// the underlying cipher will check the key length</span>
00030 }
00031 
00032 <span class="keywordtype">void</span> CipherModeBase::GetNextIV(byte *IV)
00033 {
00034         <span class="keywordflow">if</span> (!IsForwardTransformation())
00035                 <span class="keywordflow">throw</span> <a class="code" href="class_not_implemented.html">NotImplemented</a>(<span class="stringliteral">"CipherModeBase: GetNextIV() must be called on an encryption object"</span>);
00036 
00037         m_cipher-&gt;ProcessBlock(m_register);
00038         memcpy(IV, m_register, <a class="code" href="namespace_name.html#a9">BlockSize</a>());
00039 }
00040 
00041 <span class="keywordtype">void</span> CTR_ModePolicy::SeekToIteration(lword iterationCount)
00042 {
00043         <span class="keywordtype">int</span> carry=0;
00044         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i=<a class="code" href="namespace_name.html#a9">BlockSize</a>()-1; i&gt;=0; i--)
00045         {
00046                 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> sum = m_register[i] + byte(iterationCount) + carry;
00047                 m_counterArray[i] = (byte) sum;
00048                 carry = sum &gt;&gt; 8;
00049                 iterationCount &gt;&gt;= 8;
00050         }
00051 }
00052 
00053 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> IncrementCounterByOne(byte *inout, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> s)
00054 {
00055         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i=s-1, carry=1; i&gt;=0 &amp;&amp; carry; i--)
00056                 carry = !++inout[i];
00057 }
00058 
00059 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> IncrementCounterByOne(byte *output, <span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> s)
00060 {
00061         <span class="keywordtype">int</span> i, carry;
00062         <span class="keywordflow">for</span> (i=s-1, carry=1; i&gt;=0 &amp;&amp; carry; i--)
00063                 carry = !(output[i] = input[i]+1);
00064         memcpy(output, input, i+1);
00065 }
00066 
00067 <span class="keywordtype">void</span> CTR_ModePolicy::GetNextIV(byte *IV)
00068 {
00069         IncrementCounterByOne(IV, m_counterArray, <a class="code" href="namespace_name.html#a9">BlockSize</a>());
00070 }
00071 
00072 <span class="keyword">inline</span> <span class="keywordtype">void</span> CTR_ModePolicy::ProcessMultipleBlocks(byte *output, <span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n)
00073 {
00074         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> s = <a class="code" href="namespace_name.html#a9">BlockSize</a>(), j = 0;
00075         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=1; i&lt;n; i++, j+=s)
00076                 IncrementCounterByOne(m_counterArray + j + s, m_counterArray + j, s);
00077         m_cipher-&gt;ProcessAndXorMultipleBlocks(m_counterArray, input, output, n);
00078         IncrementCounterByOne(m_counterArray, m_counterArray + s*(n-1), s);
00079 }
00080 
00081 <span class="keywordtype">void</span> CTR_ModePolicy::OperateKeystream(KeystreamOperation operation, byte *output, <span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> iterationCount)
00082 {
00083         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> maxBlocks = m_cipher-&gt;OptimalNumberOfParallelBlocks();
00084         <span class="keywordflow">if</span> (maxBlocks == 1)
00085         {
00086                 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> sizeIncrement = <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00087                 <span class="keywordflow">while</span> (iterationCount)
00088                 {
00089                         m_cipher-&gt;ProcessAndXorBlock(m_counterArray, input, output);
00090                         IncrementCounterByOne(m_counterArray, sizeIncrement);
00091                         output += sizeIncrement;
00092                         input += sizeIncrement;
00093                         iterationCount -= 1;
00094                 }
00095         }
00096         <span class="keywordflow">else</span>
00097         {
00098                 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> sizeIncrement = maxBlocks * <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00099                 <span class="keywordflow">while</span> (iterationCount &gt;= maxBlocks)
00100                 {
00101                         ProcessMultipleBlocks(output, input, maxBlocks);
00102                         output += sizeIncrement;
00103                         input += sizeIncrement;
00104                         iterationCount -= maxBlocks;
00105                 }
00106                 <span class="keywordflow">if</span> (iterationCount &gt; 0)
00107                         ProcessMultipleBlocks(output, input, iterationCount);
00108         }
00109 }
00110 
00111 <span class="keywordtype">void</span> CTR_ModePolicy::CipherResynchronize(byte *keystreamBuffer, <span class="keyword">const</span> byte *iv)
00112 {
00113         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> s = <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00114         CopyOrZero(m_register, iv, s);
00115         m_counterArray.New(s * m_cipher-&gt;OptimalNumberOfParallelBlocks());
00116         CopyOrZero(m_counterArray, iv, s);
00117 }
00118 
00119 <span class="keywordtype">void</span> BlockOrientedCipherModeBase::UncheckedSetKey(<span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &amp;params, <span class="keyword">const</span> byte *key, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keyword">const</span> byte *iv)
00120 {
00121         m_cipher-&gt;SetKey(key, length, params);
00122         ResizeBuffers();
00123         <span class="keywordflow">if</span> (IsResynchronizable())
00124                 Resynchronize(iv);
00125 }
00126 
00127 <span class="keywordtype">void</span> BlockOrientedCipherModeBase::ProcessData(byte *outString, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
00128 {
00129         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> s = <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00130         assert(length % s == 0);
00131         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> alignment = m_cipher-&gt;BlockAlignment();
00132         <span class="keywordtype">bool</span> inputAlignmentOk = !RequireAlignedInput() || IsAlignedOn(inString, alignment);
00133 
00134         <span class="keywordflow">if</span> (IsAlignedOn(outString, alignment))
00135         {
00136                 <span class="keywordflow">if</span> (inputAlignmentOk)
00137                         ProcessBlocks(outString, inString, length / s);
00138                 <span class="keywordflow">else</span>
00139                 {
00140                         memcpy(outString, inString, length);
00141                         ProcessBlocks(outString, outString, length / s);
00142                 }
00143         }
00144         <span class="keywordflow">else</span>
00145         {
00146                 <span class="keywordflow">while</span> (length)
00147                 {
00148                         <span class="keywordflow">if</span> (inputAlignmentOk)
00149                                 ProcessBlocks(m_buffer, inString, 1);
00150                         <span class="keywordflow">else</span>
00151                         {
00152                                 memcpy(m_buffer, inString, s);
00153                                 ProcessBlocks(m_buffer, m_buffer, 1);
00154                         }
00155                         memcpy(outString, m_buffer, s);
00156                         inString += s;
00157                         outString += s;
00158                         length -= s;
00159                 }
00160         }
00161 }
00162 
00163 <span class="keywordtype">void</span> CBC_Encryption::ProcessBlocks(byte *outString, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> numberOfBlocks)
00164 {
00165         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockSize = <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00166         <span class="keywordflow">while</span> (numberOfBlocks--)
00167         {
00168                 xorbuf(m_register, inString, blockSize);
00169                 m_cipher-&gt;ProcessBlock(m_register);
00170                 memcpy(outString, m_register, blockSize);
00171                 inString += blockSize;
00172                 outString += blockSize;
00173         }
00174 }
00175 
00176 <span class="keywordtype">void</span> CBC_CTS_Encryption::ProcessLastBlock(byte *outString, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
00177 {
00178         <span class="keywordflow">if</span> (length &lt;= <a class="code" href="namespace_name.html#a9">BlockSize</a>())
00179         {
00180                 <span class="keywordflow">if</span> (!m_stolenIV)
00181                         <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"CBC_Encryption: message is too short for ciphertext stealing"</span>);
00182 
00183                 <span class="comment">// steal from IV</span>
00184                 memcpy(outString, m_register, length);
00185                 outString = m_stolenIV;
00186         }
00187         <span class="keywordflow">else</span>
00188         {
00189                 <span class="comment">// steal from next to last block</span>
00190                 xorbuf(m_register, inString, <a class="code" href="namespace_name.html#a9">BlockSize</a>());
00191                 m_cipher-&gt;ProcessBlock(m_register);
00192                 inString += <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00193                 length -= <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00194                 memcpy(outString+<a class="code" href="namespace_name.html#a9">BlockSize</a>(), m_register, length);
00195         }
00196 
00197         <span class="comment">// output last full ciphertext block</span>
00198         xorbuf(m_register, inString, length);
00199         m_cipher-&gt;ProcessBlock(m_register);
00200         memcpy(outString, m_register, <a class="code" href="namespace_name.html#a9">BlockSize</a>());
00201 }
00202 
00203 <span class="keywordtype">void</span> CBC_Decryption::ProcessBlocks(byte *outString, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> numberOfBlocks)
00204 {
00205         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockSize = <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00206         <span class="keywordflow">while</span> (numberOfBlocks--)
00207         {
00208                 memcpy(m_temp, inString, blockSize);
00209                 m_cipher-&gt;ProcessBlock(m_temp, outString);
00210                 xorbuf(outString, m_register, blockSize);
00211                 m_register.swap(m_temp);
00212                 inString += blockSize;
00213                 outString += blockSize;
00214         }
00215 }
00216 
00217 <span class="keywordtype">void</span> CBC_CTS_Decryption::ProcessLastBlock(byte *outString, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
00218 {
00219         <span class="keyword">const</span> byte *pn, *pn1;
00220         <span class="keywordtype">bool</span> stealIV = length &lt;= <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00221 
00222         <span class="keywordflow">if</span> (stealIV)
00223         {
00224                 pn = inString;
00225                 pn1 = m_register;
00226         }
00227         <span class="keywordflow">else</span>
00228         {
00229                 pn = inString + <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00230                 pn1 = inString;
00231                 length -= <a class="code" href="namespace_name.html#a9">BlockSize</a>();
00232         }
00233 
00234         <span class="comment">// decrypt last partial plaintext block</span>
00235         memcpy(m_temp, pn1, <a class="code" href="namespace_name.html#a9">BlockSize</a>());
00236         m_cipher-&gt;ProcessBlock(m_temp);
00237         xorbuf(m_temp, pn, length);
00238 
00239         <span class="keywordflow">if</span> (stealIV)
00240                 memcpy(outString, m_temp, length);
00241         <span class="keywordflow">else</span>
00242         {
00243                 memcpy(outString+<a class="code" href="namespace_name.html#a9">BlockSize</a>(), m_temp, length);
00244                 <span class="comment">// decrypt next to last plaintext block</span>
00245                 memcpy(m_temp, pn, length);
00246                 m_cipher-&gt;ProcessBlock(m_temp);
00247                 xorbuf(outString, m_temp, m_register, <a class="code" href="namespace_name.html#a9">BlockSize</a>());
00248         }
00249 }
00250 
00251 NAMESPACE_END
00252 
00253 <span class="preprocessor">#endif</span>
</div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:58 2004 for Crypto++ by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 ></a> 1.3.7 </small></address>
</body>
</html>