Sophie

Sophie

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

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++: default.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>default.cpp</h1><pre class="fragment"><div>00001 <span class="comment">// default.cpp - written and placed in the public domain by Wei Dai</span>
00002 
00003 <span class="preprocessor">#include "pch.h"</span>
00004 <span class="preprocessor">#include "default.h"</span>
00005 <span class="preprocessor">#include "queue.h"</span>
00006 <span class="preprocessor">#include &lt;time.h&gt;</span>
00007 <span class="preprocessor">#include &lt;memory&gt;</span>
00008 
00009 NAMESPACE_BEGIN(CryptoPP)
00010 
00011 static const <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MASH_ITERATIONS = 200;
00012 static const <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SALTLENGTH = 8;
00013 static const <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BLOCKSIZE = <a class="code" href="class_d_e_s___e_d_e2.html">Default_BlockCipher</a>::Encryption::BLOCKSIZE;
00014 static const <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> KEYLENGTH = <a class="code" href="class_d_e_s___e_d_e2.html">Default_BlockCipher</a>::Encryption::DEFAULT_KEYLENGTH;
00015 
00016 <span class="comment">// The purpose of this function Mash() is to take an arbitrary length input</span>
00017 <span class="comment">// string and *deterministicly* produce an arbitrary length output string such</span>
00018 <span class="comment">// that (1) it looks random, (2) no information about the input is</span>
00019 <span class="comment">// deducible from it, and (3) it contains as much entropy as it can hold, or</span>
00020 <span class="comment">// the amount of entropy in the input string, whichever is smaller.</span>
00021 
00022 static <span class="keywordtype">void</span> Mash(const byte *in, word16 inLen, byte *out, word16 outLen, <span class="keywordtype">int</span> iterations)
00023 {
00024         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bufSize = (outLen-1+DefaultHashModule::DIGESTSIZE-((outLen-1)%DefaultHashModule::DIGESTSIZE));
00025 
00026         <span class="comment">// ASSERT: bufSize == (the smallest multiple of DIGESTSIZE that is &gt;= outLen)</span>
00027 
00028         byte b[2];
00029         <a class="code" href="class_sec_block.html">SecByteBlock</a> buf(bufSize);
00030         <a class="code" href="class_sec_block.html">SecByteBlock</a> outBuf(bufSize);
00031         <a class="code" href="class_s_h_a.html">DefaultHashModule</a> hash;
00032 
00033         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i;
00034         <span class="keywordflow">for</span>(i=0; i&lt;outLen; i+=DefaultHashModule::DIGESTSIZE)
00035         {
00036                 b[0] = (byte) i &gt;&gt; 8;
00037                 b[1] = (byte) i;
00038                 hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>(b, 2);
00039                 hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>(in, inLen);
00040                 hash.<a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea7">Final</a>(outBuf+i);
00041         }
00042 
00043         <span class="keywordflow">while</span> (iterations-- &gt; 1)
00044         {
00045                 memcpy(buf, outBuf, bufSize);
00046                 <span class="keywordflow">for</span> (i=0; i&lt;bufSize; i+=DefaultHashModule::DIGESTSIZE)
00047                 {
00048                         b[0] = (byte) i &gt;&gt; 8;
00049                         b[1] = (byte) i;
00050                         hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>(b, 2);
00051                         hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>(buf, bufSize);
00052                         hash.<a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea7">Final</a>(outBuf+i);
00053                 }
00054         }
00055 
00056         memcpy(out, outBuf, outLen);
00057 }
00058 
00059 <span class="keyword">static</span> <span class="keywordtype">void</span> GenerateKeyIV(<span class="keyword">const</span> byte *passphrase, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> passphraseLength, <span class="keyword">const</span> byte *salt, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> saltLength, byte *key, byte *IV)
00060 {
00061         <a class="code" href="class_sec_block.html">SecByteBlock</a> temp(passphraseLength+saltLength);
00062         memcpy(temp, passphrase, passphraseLength);
00063         memcpy(temp+passphraseLength, salt, saltLength);
00064         <a class="code" href="class_sec_block.html">SecByteBlock</a> keyIV(KEYLENGTH+BLOCKSIZE);
00065         Mash(temp, passphraseLength + saltLength, keyIV, KEYLENGTH+BLOCKSIZE, MASH_ITERATIONS);
00066         memcpy(key, keyIV, KEYLENGTH);
00067         memcpy(IV, keyIV+KEYLENGTH, BLOCKSIZE);
00068 }
00069 
00070 <span class="comment">// ********************************************************</span>
00071 
00072 DefaultEncryptor::DefaultEncryptor(<span class="keyword">const</span> <span class="keywordtype">char</span> *passphrase, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> *attachment)
00073         : <a class="code" href="class_proxy_filter.html">ProxyFilter</a>(NULL, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase))
00074 {
00075 }
00076 
00077 DefaultEncryptor::DefaultEncryptor(<span class="keyword">const</span> byte *passphrase, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> passphraseLength, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> *attachment)
00078         : <a class="code" href="class_proxy_filter.html">ProxyFilter</a>(NULL, 0, 0, attachment), m_passphrase(passphrase, passphraseLength)
00079 {
00080 }
00081 
00082 
00083 <span class="keywordtype">void</span> DefaultEncryptor::FirstPut(<span class="keyword">const</span> byte *)
00084 {
00085         <span class="comment">// VC60 workaround: __LINE__ expansion bug</span>
00086         CRYPTOPP_COMPILE_ASSERT_INSTANCE(SALTLENGTH &lt;= DefaultHashModule::DIGESTSIZE, 1);
00087         CRYPTOPP_COMPILE_ASSERT_INSTANCE(BLOCKSIZE &lt;= DefaultHashModule::DIGESTSIZE, 2);
00088 
00089         <a class="code" href="class_sec_block.html">SecByteBlock</a> salt(DefaultHashModule::DIGESTSIZE), keyCheck(DefaultHashModule::DIGESTSIZE);
00090         <a class="code" href="class_s_h_a.html">DefaultHashModule</a> hash;
00091 
00092         <span class="comment">// use hash(passphrase | time | clock) as salt</span>
00093         hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>(m_passphrase, m_passphrase.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
00094         time_t t=time(0);
00095         hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>((byte *)&amp;t, <span class="keyword">sizeof</span>(t));
00096         clock_t c=clock();
00097         hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>((byte *)&amp;c, <span class="keyword">sizeof</span>(c));
00098         hash.<a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea7">Final</a>(salt);
00099 
00100         <span class="comment">// use hash(passphrase | salt) as key check</span>
00101         hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>(m_passphrase, m_passphrase.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
00102         hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>(salt, SALTLENGTH);
00103         hash.<a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea7">Final</a>(keyCheck);
00104 
00105         <a class="code" href="class_filter.html#_zlib_decompressora8">AttachedTransformation</a>()-&gt;<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(salt, SALTLENGTH);
00106 
00107         <span class="comment">// mash passphrase and salt together into key and IV</span>
00108         <a class="code" href="class_sec_block.html">SecByteBlock</a> key(KEYLENGTH);
00109         <a class="code" href="class_sec_block.html">SecByteBlock</a> <a class="code" href="namespace_name.html#a4">IV</a>(BLOCKSIZE);
00110         GenerateKeyIV(m_passphrase, m_passphrase.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>(), salt, SALTLENGTH, key, <a class="code" href="namespace_name.html#a4">IV</a>);
00111 
00112         m_cipher.SetKeyWithIV(key, key.size(), <a class="code" href="namespace_name.html#a4">IV</a>);
00113         SetFilter(<span class="keyword">new</span> <a class="code" href="class_stream_transformation_filter.html">StreamTransformationFilter</a>(m_cipher));
00114 
00115         m_filter-&gt;Put(keyCheck, BLOCKSIZE);
00116 }
00117 
00118 <span class="keywordtype">void</span> DefaultEncryptor::LastPut(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
00119 {
00120         m_filter-&gt;MessageEnd();
00121 }
00122 
00123 <span class="comment">// ********************************************************</span>
00124 
00125 DefaultDecryptor::DefaultDecryptor(<span class="keyword">const</span> <span class="keywordtype">char</span> *p, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> *attachment, <span class="keywordtype">bool</span> throwException)
00126         : <a class="code" href="class_proxy_filter.html">ProxyFilter</a>(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
00127         , m_state(WAITING_FOR_KEYCHECK)
00128         , m_passphrase((const byte *)p, strlen(p))
00129         , m_throwException(throwException)
00130 {
00131 }
00132 
00133 DefaultDecryptor::DefaultDecryptor(<span class="keyword">const</span> byte *passphrase, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> passphraseLength, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> *attachment, <span class="keywordtype">bool</span> throwException)
00134         : <a class="code" href="class_proxy_filter.html">ProxyFilter</a>(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
00135         , m_state(WAITING_FOR_KEYCHECK)
00136         , m_passphrase(passphrase, passphraseLength)
00137         , m_throwException(throwException)
00138 {
00139 }
00140 
00141 <span class="keywordtype">void</span> DefaultDecryptor::FirstPut(<span class="keyword">const</span> byte *inString)
00142 {
00143         CheckKey(inString, inString+SALTLENGTH);
00144 }
00145 
00146 <span class="keywordtype">void</span> DefaultDecryptor::LastPut(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
00147 {
00148         <span class="keywordflow">if</span> (m_filter.get() == NULL)
00149         {
00150                 m_state = KEY_BAD;
00151                 <span class="keywordflow">if</span> (m_throwException)
00152                         <span class="keywordflow">throw</span> KeyBadErr();
00153         }
00154         <span class="keywordflow">else</span>
00155         {
00156                 m_filter-&gt;MessageEnd();
00157                 m_state = WAITING_FOR_KEYCHECK;
00158         }
00159 }
00160 
00161 <span class="keywordtype">void</span> DefaultDecryptor::CheckKey(<span class="keyword">const</span> byte *salt, <span class="keyword">const</span> byte *keyCheck)
00162 {
00163         <a class="code" href="class_sec_block.html">SecByteBlock</a> check(STDMAX((<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>)2*BLOCKSIZE, (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>)DefaultHashModule::DIGESTSIZE));
00164 
00165         <a class="code" href="class_s_h_a.html">DefaultHashModule</a> hash;
00166         hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>(m_passphrase, m_passphrase.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
00167         hash.<a class="code" href="class_iterated_hash_base.html#_iterated_hash_base2a4">Update</a>(salt, SALTLENGTH);
00168         hash.<a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea7">Final</a>(check);
00169 
00170         <a class="code" href="class_sec_block.html">SecByteBlock</a> key(KEYLENGTH);
00171         <a class="code" href="class_sec_block.html">SecByteBlock</a> <a class="code" href="namespace_name.html#a4">IV</a>(BLOCKSIZE);
00172         GenerateKeyIV(m_passphrase, m_passphrase.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>(), salt, SALTLENGTH, key, <a class="code" href="namespace_name.html#a4">IV</a>);
00173 
00174         m_cipher.SetKeyWithIV(key, key.size(), <a class="code" href="namespace_name.html#a4">IV</a>);
00175         std::auto_ptr&lt;StreamTransformationFilter&gt; decryptor(<span class="keyword">new</span> <a class="code" href="class_stream_transformation_filter.html">StreamTransformationFilter</a>(m_cipher));
00176 
00177         decryptor-&gt;Put(keyCheck, BLOCKSIZE);
00178         decryptor-&gt;ForceNextPut();
00179         decryptor-&gt;Get(check+BLOCKSIZE, BLOCKSIZE);
00180 
00181         SetFilter(decryptor.release());
00182 
00183         <span class="keywordflow">if</span> (memcmp(check, check+BLOCKSIZE, BLOCKSIZE))
00184         {
00185                 m_state = KEY_BAD;
00186                 <span class="keywordflow">if</span> (m_throwException)
00187                         <span class="keywordflow">throw</span> KeyBadErr();
00188         }
00189         <span class="keywordflow">else</span>
00190                 m_state = KEY_GOOD;
00191 }
00192 
00193 <span class="comment">// ********************************************************</span>
00194 
00195 <span class="keyword">static</span> <a class="code" href="class_h_m_a_c.html">DefaultMAC</a> * NewDefaultEncryptorMAC(<span class="keyword">const</span> byte *passphrase, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> passphraseLength)
00196 {
00197         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> macKeyLength = DefaultMAC::StaticGetValidKeyLength(16);
00198         <a class="code" href="class_sec_block.html">SecByteBlock</a> macKey(macKeyLength);
00199         <span class="comment">// since the MAC is encrypted there is no reason to mash the passphrase for many iterations</span>
00200         Mash(passphrase, passphraseLength, macKey, macKeyLength, 1);
00201         <span class="keywordflow">return</span> <span class="keyword">new</span> <a class="code" href="class_h_m_a_c.html">DefaultMAC</a>(macKey, macKeyLength);
00202 }
00203 
00204 DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(<span class="keyword">const</span> <span class="keywordtype">char</span> *passphrase, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> *attachment)
00205         : <a class="code" href="class_proxy_filter.html">ProxyFilter</a>(NULL, 0, 0, attachment)
00206         , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
00207 {
00208         SetFilter(<span class="keyword">new</span> <a class="code" href="class_hash_filter.html">HashFilter</a>(*m_mac, <span class="keyword">new</span> <a class="code" href="class_default_encryptor.html">DefaultEncryptor</a>(passphrase), <span class="keyword">true</span>));
00209 }
00210 
00211 DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(<span class="keyword">const</span> byte *passphrase, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> passphraseLength, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> *attachment)
00212         : <a class="code" href="class_proxy_filter.html">ProxyFilter</a>(NULL, 0, 0, attachment)
00213         , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
00214 {
00215         SetFilter(<span class="keyword">new</span> <a class="code" href="class_hash_filter.html">HashFilter</a>(*m_mac, <span class="keyword">new</span> <a class="code" href="class_default_encryptor.html">DefaultEncryptor</a>(passphrase, passphraseLength), <span class="keyword">true</span>));
00216 }
00217 
00218 <span class="keywordtype">void</span> DefaultEncryptorWithMAC::LastPut(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
00219 {
00220         m_filter-&gt;MessageEnd();
00221 }
00222 
00223 <span class="comment">// ********************************************************</span>
00224 
00225 DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(<span class="keyword">const</span> <span class="keywordtype">char</span> *passphrase, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> *attachment, <span class="keywordtype">bool</span> throwException)
00226         : <a class="code" href="class_proxy_filter.html">ProxyFilter</a>(NULL, 0, 0, attachment)
00227         , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
00228         , m_throwException(throwException)
00229 {
00230         SetFilter(<span class="keyword">new</span> <a class="code" href="class_default_decryptor.html">DefaultDecryptor</a>(passphrase, m_hashVerifier=<span class="keyword">new</span> <a class="code" href="class_hash_verification_filter.html">HashVerifier</a>(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException));
00231 }
00232 
00233 DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(<span class="keyword">const</span> byte *passphrase, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> passphraseLength, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> *attachment, <span class="keywordtype">bool</span> throwException)
00234         : <a class="code" href="class_proxy_filter.html">ProxyFilter</a>(NULL, 0, 0, attachment)
00235         , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
00236         , m_throwException(throwException)
00237 {
00238         SetFilter(<span class="keyword">new</span> <a class="code" href="class_default_decryptor.html">DefaultDecryptor</a>(passphrase, passphraseLength, m_hashVerifier=<span class="keyword">new</span> <a class="code" href="class_hash_verification_filter.html">HashVerifier</a>(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException));
00239 }
00240 
00241 DefaultDecryptor::State DefaultDecryptorWithMAC::CurrentState()<span class="keyword"> const</span>
00242 <span class="keyword"></span>{
00243         <span class="keywordflow">return</span> static_cast&lt;const DefaultDecryptor *&gt;(m_filter.get())-&gt;CurrentState();
00244 }
00245 
00246 <span class="keywordtype">bool</span> DefaultDecryptorWithMAC::CheckLastMAC()<span class="keyword"> const</span>
00247 <span class="keyword"></span>{
00248         <span class="keywordflow">return</span> m_hashVerifier-&gt;<a class="code" href="class_hash_verification_filter.html#_hash_verification_filtera1">GetLastResult</a>();
00249 }
00250 
00251 <span class="keywordtype">void</span> DefaultDecryptorWithMAC::LastPut(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
00252 {
00253         m_filter-&gt;MessageEnd();
00254         <span class="keywordflow">if</span> (m_throwException &amp;&amp; !CheckLastMAC())
00255                 <span class="keywordflow">throw</span> MACBadErr();
00256 }
00257 
00258 NAMESPACE_END
</div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:57 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>