📄 xormac_8h-source.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"><title>Crypto++: xormac.h Source File</title><link href="doxygen.css" rel="stylesheet" type="text/css"></head><body><!-- Generated by Doxygen 1.3.2 --><div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical List</a> | <a class="qindex" href="annotated.html">Compound List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="namespacemembers.html">Namespace Members</a> | <a class="qindex" href="functions.html">Compound Members</a> | <a class="qindex" href="globals.html">File Members</a></div><h1>xormac.h</h1><div class="fragment"><pre>00001 <span class="comment">// xormac.h - written and placed in the public domain by Wei Dai</span>00002 00003 <span class="preprocessor">#ifndef CRYPTOPP_XORMAC_H</span>00004 <span class="preprocessor"></span><span class="preprocessor">#define CRYPTOPP_XORMAC_H</span>00005 <span class="preprocessor"></span>00006 <span class="preprocessor">#include "iterhash.h"</span>00007 <span class="preprocessor">#include "argnames.h"</span>00008 00009 NAMESPACE_BEGIN(CryptoPP)00010 00011 <span class="keyword">template</span> <<span class="keyword">class</span> T> <span class="keyword">struct </span>DigestSizeSubtract4Workaround {<span class="keyword">enum</span> {RESULT = T::DIGESTSIZE-4};}; <span class="comment">// VC60 workaround</span>00012 00013 <span class="keyword">template</span> <<span class="keyword">class</span> T>00014 <span class="keyword">class </span>XMACC_Base : <span class="keyword">public</span> <a class="code" href="class_fixed_key_length.html">FixedKeyLength</a><DigestSizeSubtract4Workaround<T>::RESULT, SimpleKeyingInterface::INTERNALLY_GENERATED_IV>, 00015 <span class="keyword">public</span> <a class="code" href="class_iterated_hash.html">IteratedHash</a><typename T::HashWordType, typename T::ByteOrderClass, T::BLOCKSIZE, MessageAuthenticationCode>00016 {00017 <span class="keyword">public</span>:00018 <span class="keyword">static</span> std::string StaticAlgorithmName() {<span class="keywordflow">return</span> std::string(<span class="stringliteral">"XMAC("</span>) + T::StaticAlgorithmName() + <span class="stringliteral">")"</span>;}00019 <span class="keyword">enum</span> {DIGESTSIZE = 4+T::DIGESTSIZE};00020 <span class="keyword">typedef</span> <span class="keyword">typename</span> T::HashWordType HashWordType;00021 00022 XMACC_Base() : <a class="code" href="class_iterated_hash.html">IteratedHash</a><HashWordType, CPP_TYPENAME T::ByteOrderClass, T::BLOCKSIZE, <a class="code" href="class_message_authentication_code.html">MessageAuthenticationCode</a>>(T::DIGESTSIZE) {}00023 00024 <span class="keywordtype">void</span> CheckedSetKey(<span class="keywordtype">void</span> *, Empty empty, <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> &params);00025 <span class="keywordtype">void</span> Resynchronize(<span class="keyword">const</span> byte *IV)00026 {00027 GetWord(<span class="keyword">false</span>, BIG_ENDIAN_ORDER, m_counter, IV);00028 Restart();00029 }00030 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> IVSize()<span class="keyword"> const</span>00031 <span class="keyword"> </span>{<span class="keywordflow">return</span> 4;}00032 <span class="keywordtype">void</span> GetNextIV(byte *IV)00033 {00034 <span class="keywordflow">if</span> (m_counter == 0xffffffff)00035 <span class="keywordflow">throw</span> <a class="code" href="class_not_implemented.html">NotImplemented</a>(<span class="stringliteral">"XMACC: must have a valid counter to get next IV"</span>);00036 PutWord(<span class="keyword">false</span>, BIG_ENDIAN_ORDER, IV, m_counter+1);00037 }00038 00039 word32 CurrentCounter()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_counter;}00040 00041 <span class="keywordtype">void</span> TruncatedFinal(byte *mac, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size);00042 <span class="keywordtype">bool</span> TruncatedVerify(<span class="keyword">const</span> byte *mac, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length);00043 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> DigestSize()<span class="keyword"> const </span>{<span class="keywordflow">return</span> DIGESTSIZE;} <span class="comment">// need to override this</span>00044 00045 <span class="keyword">private</span>:00046 <span class="keywordtype">void</span> Init();00047 <span class="keyword">static</span> <span class="keywordtype">void</span> WriteWord32(byte *output, word32 value);00048 <span class="keyword">static</span> <span class="keywordtype">void</span> XorDigest(HashWordType *digest, <span class="keyword">const</span> HashWordType *buffer);00049 <span class="keywordtype">void</span> vTransform(<span class="keyword">const</span> HashWordType *data);00050 00051 FixedSizeSecBlock<byte, DigestSizeSubtract4Workaround<T>::RESULT> m_key;00052 <span class="keyword">enum</span> {BUFFER_SIZE = ((T::DIGESTSIZE) / <span class="keyword">sizeof</span>(HashWordType))}; <span class="comment">// VC60 workaround</span>00053 FixedSizeSecBlock<HashWordType, BUFFER_SIZE> m_buffer;00054 word32 m_counter, m_index;00055 };00056 <span class="comment"></span>00057 <span class="comment">//! <a href="http://www.weidai.com/scan-mirror/mac.html#XMAC">XMAC</a></span>00058 <span class="comment"></span><span class="comment">/*! If you need to generate MACs with XMACC (instead of just verifying them),</span>00059 <span class="comment"> you must save the counter before destroying an XMACC object</span>00060 <span class="comment"> and reinitialize it the next time you create an XMACC with the same key.</span>00061 <span class="comment"> Start counter at 0 when using a key for the first time. */</span>00062 <span class="keyword">template</span> <<span class="keyword">class</span> T><a name="l00063"></a><a class="code" href="class_x_m_a_c_c.html">00063</a> <span class="keyword">class </span><a class="code" href="class_x_m_a_c_c.html">XMACC</a> : <span class="keyword">public</span> <a class="code" href="class_message_authentication_code_final_template.html">MessageAuthenticationCodeFinalTemplate</a><XMACC_Base<T> >00064 {00065 <span class="keyword">public</span>:00066 <a class="code" href="class_x_m_a_c_c.html">XMACC</a>() {}00067 <a class="code" href="class_x_m_a_c_c.html">XMACC</a>(<span class="keyword">const</span> byte *key, word32 counter = 0xffffffff)00068 {<a class="code" href="class_message_authentication_code_final_template.html#_message_authentication_code_final_templatea3">SetKey</a>(key, KEYLENGTH, MakeParameters(Name::XMACC_Counter(), counter));}00069 };00070 00071 <span class="keyword">template</span> <<span class="keyword">class</span> T> <span class="keywordtype">void</span> XMACC_Base<T>::CheckedSetKey(<span class="keywordtype">void</span> *, Empty empty, <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> &params)00072 {00073 ThrowIfInvalidKeyLength(length);00074 m_counter = 0xffffffff;00075 <span class="keyword">const</span> byte *iv = NULL;00076 <span class="keywordflow">if</span> (params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha39">GetValue</a>(Name::IV(), iv))00077 GetWord(<span class="keyword">false</span>, BIG_ENDIAN_ORDER, m_counter, iv);00078 <span class="keywordflow">else</span>00079 params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha39">GetValue</a>(Name::XMACC_Counter(), m_counter);00080 memcpy(m_key, key, KEYLENGTH);00081 Init();00082 }00083 00084 <span class="keyword">template</span> <<span class="keyword">class</span> T> <span class="keywordtype">void</span> XMACC_Base<T>::Init()00085 {00086 m_index = 0x80000000;00087 memset(m_digest, 0, T::DIGESTSIZE);00088 }00089 00090 <span class="keyword">template</span> <<span class="keyword">class</span> T> <span class="keyword">inline</span> <span class="keywordtype">void</span> XMACC_Base<T>::WriteWord32(byte *output, word32 value)00091 {00092 output[0] = byte(value >> 24);00093 output[1] = byte(value >> 16);00094 output[2] = byte(value >> 8);00095 output[3] = byte(value);00096 }00097 00098 <span class="keyword">template</span> <<span class="keyword">class</span> T> <span class="keyword">inline</span> <span class="keywordtype">void</span> XMACC_Base<T>::XorDigest(HashWordType *digest, <span class="keyword">const</span> HashWordType *buffer)00099 {00100 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=0; i<(T::DIGESTSIZE/<span class="keyword">sizeof</span>(HashWordType)); i++)00101 digest[i] ^= buffer[i];00102 }00103 00104 <span class="keyword">template</span> <<span class="keyword">class</span> T> <span class="keywordtype">void</span> XMACC_Base<T>::vTransform(<span class="keyword">const</span> HashWordType *input)00105 {00106 memcpy(m_buffer, m_key, KEYLENGTH);00107 WriteWord32((byte *)m_buffer.begin()+KEYLENGTH, ++m_index);00108 T::CorrectEndianess(m_buffer, m_buffer, T::DIGESTSIZE);00109 T::Transform(m_buffer, input);00110 XorDigest(m_digest, m_buffer);00111 }00112 00113 <span class="keyword">template</span> <<span class="keyword">class</span> T> <span class="keywordtype">void</span> XMACC_Base<T>::TruncatedFinal(byte *mac, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size)00114 {00115 ThrowIfInvalidTruncatedSize(size);00116 <span class="keywordflow">if</span> (size < 4)00117 <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"XMACC: truncating the MAC to less than 4 bytes will cause it to be unverifiable"</span>);00118 <span class="keywordflow">if</span> (m_counter == 0xffffffff)00119 <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"XMACC: the counter must be initialized to a valid value for MAC generation"</span>);00120 00121 PadLastBlock(BLOCKSIZE - 2*<span class="keyword">sizeof</span>(HashWordType));00122 CorrectEndianess(m_data, m_data, BLOCKSIZE - 2*<span class="keyword">sizeof</span>(HashWordType));00123 m_data[m_data.size()-2] = ByteReverse(GetBitCountHi()); <span class="comment">// byteReverse for backwards compatibility</span>00124 m_data[m_data.size()-1] = ByteReverse(GetBitCountLo());00125 vTransform(m_data);00126 00127 memcpy(m_buffer, m_key, KEYLENGTH);00128 WriteWord32((byte *)m_buffer.begin()+KEYLENGTH, 0);00129 memset(m_data, 0, BLOCKSIZE-4);00130 WriteWord32((byte *)m_data.begin()+BLOCKSIZE-4, ++m_counter);00131 T::CorrectEndianess(m_buffer, m_buffer, T::DIGESTSIZE);00132 T::CorrectEndianess(m_data, m_data, BLOCKSIZE);00133 T::Transform(m_buffer, m_data);00134 XorDigest(m_digest, m_buffer);00135 00136 WriteWord32(mac, m_counter);00137 T::CorrectEndianess(m_digest, m_digest, T::DIGESTSIZE);00138 memcpy(mac+4, m_digest, size-4);00139 00140 <a class="code" href="class_hash_transformation.html#_x_m_a_c_ca8">Restart</a>(); <span class="comment">// reinit for next use</span>00141 }00142 00143 <span class="keyword">template</span> <<span class="keyword">class</span> T> <span class="keywordtype">bool</span> XMACC_Base<T>::TruncatedVerify(<span class="keyword">const</span> byte *mac, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size)00144 {00145 assert(4 <= size && size <= DIGESTSIZE);00146 00147 PadLastBlock(BLOCKSIZE - 2*<span class="keyword">sizeof</span>(HashWordType));00148 CorrectEndianess(m_data, m_data, BLOCKSIZE - 2*<span class="keyword">sizeof</span>(HashWordType));00149 m_data[m_data.size()-2] = ByteReverse(GetBitCountHi()); <span class="comment">// byteReverse for backwards compatibility</span>00150 m_data[m_data.size()-1] = ByteReverse(GetBitCountLo());00151 vTransform(m_data);00152 00153 memcpy(m_buffer, m_key, KEYLENGTH);00154 WriteWord32((byte *)m_buffer.begin()+KEYLENGTH, 0);00155 memset(m_data, 0, BLOCKSIZE-4);00156 memcpy((byte *)m_data.begin()+BLOCKSIZE-4, mac, 4);00157 T::CorrectEndianess(m_buffer, m_buffer, T::DIGESTSIZE);00158 T::CorrectEndianess(m_data, m_data, BLOCKSIZE);00159 T::Transform(m_buffer, m_data);00160 XorDigest(m_digest, m_buffer);00161 00162 T::CorrectEndianess(m_digest, m_digest, T::DIGESTSIZE);00163 <span class="keywordtype">bool</span> macValid = (memcmp(mac+4, m_digest, size-4) == 0);00164 <a class="code" href="class_hash_transformation.html#_x_m_a_c_ca8">Restart</a>(); <span class="comment">// reinit for next use</span>00165 <span class="keywordflow">return</span> macValid;00166 }00167 00168 NAMESPACE_END00169 00170 <span class="preprocessor">#endif</span></pre></div><hr size="1"><address style="align: right;"><small>Generated on Tue Jul 8 23:34:28 2003 for Crypto++ by<a href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border=0 > </a>1.3.2 </small></address></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -