Botan
1.11.15
|
00001 /* 00002 * GOST 34.11 00003 * (C) 2009 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/hash_utils.h> 00009 #include <botan/gost_3411.h> 00010 #include <botan/internal/xor_buf.h> 00011 00012 namespace Botan { 00013 00014 BOTAN_REGISTER_HASH_NAMED_NOARGS(GOST_34_11, "GOST-R-34.11-94"); 00015 00016 /** 00017 * GOST 34.11 Constructor 00018 */ 00019 GOST_34_11::GOST_34_11() : 00020 cipher(GOST_28147_89_Params("R3411_CryptoPro")), 00021 buffer(32), 00022 sum(32), 00023 hash(32) 00024 { 00025 count = 0; 00026 position = 0; 00027 } 00028 00029 void GOST_34_11::clear() 00030 { 00031 cipher.clear(); 00032 zeroise(sum); 00033 zeroise(hash); 00034 count = 0; 00035 position = 0; 00036 } 00037 00038 /** 00039 * Hash additional inputs 00040 */ 00041 void GOST_34_11::add_data(const byte input[], size_t length) 00042 { 00043 count += length; 00044 00045 if(position) 00046 { 00047 buffer_insert(buffer, position, input, length); 00048 00049 if(position + length >= hash_block_size()) 00050 { 00051 compress_n(&buffer[0], 1); 00052 input += (hash_block_size() - position); 00053 length -= (hash_block_size() - position); 00054 position = 0; 00055 } 00056 } 00057 00058 const size_t full_blocks = length / hash_block_size(); 00059 const size_t remaining = length % hash_block_size(); 00060 00061 if(full_blocks) 00062 compress_n(input, full_blocks); 00063 00064 buffer_insert(buffer, position, input + full_blocks * hash_block_size(), remaining); 00065 position += remaining; 00066 } 00067 00068 /** 00069 * The GOST 34.11 compression function 00070 */ 00071 void GOST_34_11::compress_n(const byte input[], size_t blocks) 00072 { 00073 for(size_t i = 0; i != blocks; ++i) 00074 { 00075 for(u16bit j = 0, carry = 0; j != 32; ++j) 00076 { 00077 u16bit s = sum[j] + input[32*i+j] + carry; 00078 carry = get_byte(0, s); 00079 sum[j] = get_byte(1, s); 00080 } 00081 00082 byte S[32] = { 0 }; 00083 00084 u64bit U[4], V[4]; 00085 load_be(U, &hash[0], 4); 00086 load_be(V, input + 32*i, 4); 00087 00088 for(size_t j = 0; j != 4; ++j) 00089 { 00090 byte key[32] = { 0 }; 00091 00092 // P transformation 00093 for(size_t k = 0; k != 4; ++k) 00094 for(size_t l = 0; l != 8; ++l) 00095 key[4*l+k] = get_byte(l, U[k]) ^ get_byte(l, V[k]); 00096 00097 cipher.set_key(key, 32); 00098 cipher.encrypt(&hash[8*j], S + 8*j); 00099 00100 if(j == 3) 00101 break; 00102 00103 // A(x) 00104 u64bit A_U = U[0]; 00105 U[0] = U[1]; 00106 U[1] = U[2]; 00107 U[2] = U[3]; 00108 U[3] = U[0] ^ A_U; 00109 00110 if(j == 1) // C_3 00111 { 00112 U[0] ^= 0x00FF00FF00FF00FF; 00113 U[1] ^= 0xFF00FF00FF00FF00; 00114 U[2] ^= 0x00FFFF00FF0000FF; 00115 U[3] ^= 0xFF000000FFFF00FF; 00116 } 00117 00118 // A(A(x)) 00119 u64bit AA_V_1 = V[0] ^ V[1]; 00120 u64bit AA_V_2 = V[1] ^ V[2]; 00121 V[0] = V[2]; 00122 V[1] = V[3]; 00123 V[2] = AA_V_1; 00124 V[3] = AA_V_2; 00125 } 00126 00127 byte S2[32] = { 0 }; 00128 00129 // 12 rounds of psi 00130 S2[ 0] = S[24]; 00131 S2[ 1] = S[25]; 00132 S2[ 2] = S[26]; 00133 S2[ 3] = S[27]; 00134 S2[ 4] = S[28]; 00135 S2[ 5] = S[29]; 00136 S2[ 6] = S[30]; 00137 S2[ 7] = S[31]; 00138 S2[ 8] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[ 6] ^ S[24] ^ S[30]; 00139 S2[ 9] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[ 7] ^ S[25] ^ S[31]; 00140 S2[10] = S[ 0] ^ S[ 8] ^ S[24] ^ S[26] ^ S[30]; 00141 S2[11] = S[ 1] ^ S[ 9] ^ S[25] ^ S[27] ^ S[31]; 00142 S2[12] = S[ 0] ^ S[ 4] ^ S[ 6] ^ S[10] ^ S[24] ^ S[26] ^ S[28] ^ S[30]; 00143 S2[13] = S[ 1] ^ S[ 5] ^ S[ 7] ^ S[11] ^ S[25] ^ S[27] ^ S[29] ^ S[31]; 00144 S2[14] = S[ 0] ^ S[ 4] ^ S[ 8] ^ S[12] ^ S[24] ^ S[26] ^ S[28]; 00145 S2[15] = S[ 1] ^ S[ 5] ^ S[ 9] ^ S[13] ^ S[25] ^ S[27] ^ S[29]; 00146 S2[16] = S[ 2] ^ S[ 6] ^ S[10] ^ S[14] ^ S[26] ^ S[28] ^ S[30]; 00147 S2[17] = S[ 3] ^ S[ 7] ^ S[11] ^ S[15] ^ S[27] ^ S[29] ^ S[31]; 00148 S2[18] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[12] ^ S[16] ^ S[24] ^ S[28]; 00149 S2[19] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[13] ^ S[17] ^ S[25] ^ S[29]; 00150 S2[20] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[14] ^ S[18] ^ S[26] ^ S[30]; 00151 S2[21] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[15] ^ S[19] ^ S[27] ^ S[31]; 00152 S2[22] = S[ 0] ^ S[ 2] ^ S[10] ^ S[12] ^ S[16] ^ S[20] ^ S[24] ^ S[28] ^ S[30]; 00153 S2[23] = S[ 1] ^ S[ 3] ^ S[11] ^ S[13] ^ S[17] ^ S[21] ^ S[25] ^ S[29] ^ S[31]; 00154 S2[24] = S[ 0] ^ S[ 6] ^ S[12] ^ S[14] ^ S[18] ^ S[22] ^ S[24] ^ S[26]; 00155 S2[25] = S[ 1] ^ S[ 7] ^ S[13] ^ S[15] ^ S[19] ^ S[23] ^ S[25] ^ S[27]; 00156 S2[26] = S[ 2] ^ S[ 8] ^ S[14] ^ S[16] ^ S[20] ^ S[24] ^ S[26] ^ S[28]; 00157 S2[27] = S[ 3] ^ S[ 9] ^ S[15] ^ S[17] ^ S[21] ^ S[25] ^ S[27] ^ S[29]; 00158 S2[28] = S[ 4] ^ S[10] ^ S[16] ^ S[18] ^ S[22] ^ S[26] ^ S[28] ^ S[30]; 00159 S2[29] = S[ 5] ^ S[11] ^ S[17] ^ S[19] ^ S[23] ^ S[27] ^ S[29] ^ S[31]; 00160 S2[30] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[12] ^ S[18] ^ S[20] ^ S[28]; 00161 S2[31] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[13] ^ S[19] ^ S[21] ^ S[29]; 00162 00163 xor_buf(S, S2, input + 32*i, 32); 00164 00165 S2[0] = S[0] ^ S[2] ^ S[4] ^ S[6] ^ S[24] ^ S[30]; 00166 S2[1] = S[1] ^ S[3] ^ S[5] ^ S[7] ^ S[25] ^ S[31]; 00167 00168 copy_mem(S, S+2, 30); 00169 S[30] = S2[0]; 00170 S[31] = S2[1]; 00171 00172 xor_buf(S, &hash[0], 32); 00173 00174 // 61 rounds of psi 00175 S2[ 0] = S[ 2] ^ S[ 6] ^ S[14] ^ S[20] ^ S[22] ^ S[26] ^ S[28] ^ S[30]; 00176 S2[ 1] = S[ 3] ^ S[ 7] ^ S[15] ^ S[21] ^ S[23] ^ S[27] ^ S[29] ^ S[31]; 00177 S2[ 2] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[16] ^ S[22] ^ S[28]; 00178 S2[ 3] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[17] ^ S[23] ^ S[29]; 00179 S2[ 4] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[18] ^ S[24] ^ S[30]; 00180 S2[ 5] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[19] ^ S[25] ^ S[31]; 00181 S2[ 6] = S[ 0] ^ S[ 2] ^ S[10] ^ S[12] ^ S[20] ^ S[24] ^ S[26] ^ S[30]; 00182 S2[ 7] = S[ 1] ^ S[ 3] ^ S[11] ^ S[13] ^ S[21] ^ S[25] ^ S[27] ^ S[31]; 00183 S2[ 8] = S[ 0] ^ S[ 6] ^ S[12] ^ S[14] ^ S[22] ^ S[24] ^ S[26] ^ S[28] ^ S[30]; 00184 S2[ 9] = S[ 1] ^ S[ 7] ^ S[13] ^ S[15] ^ S[23] ^ S[25] ^ S[27] ^ S[29] ^ S[31]; 00185 S2[10] = S[ 0] ^ S[ 4] ^ S[ 6] ^ S[ 8] ^ S[14] ^ S[16] ^ S[26] ^ S[28]; 00186 S2[11] = S[ 1] ^ S[ 5] ^ S[ 7] ^ S[ 9] ^ S[15] ^ S[17] ^ S[27] ^ S[29]; 00187 S2[12] = S[ 2] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[16] ^ S[18] ^ S[28] ^ S[30]; 00188 S2[13] = S[ 3] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[17] ^ S[19] ^ S[29] ^ S[31]; 00189 S2[14] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[12] ^ S[18] ^ S[20] ^ S[24]; 00190 S2[15] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[13] ^ S[19] ^ S[21] ^ S[25]; 00191 S2[16] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[12] ^ S[14] ^ S[20] ^ S[22] ^ S[26]; 00192 S2[17] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[13] ^ S[15] ^ S[21] ^ S[23] ^ S[27]; 00193 S2[18] = S[ 4] ^ S[ 6] ^ S[10] ^ S[12] ^ S[14] ^ S[16] ^ S[22] ^ S[24] ^ S[28]; 00194 S2[19] = S[ 5] ^ S[ 7] ^ S[11] ^ S[13] ^ S[15] ^ S[17] ^ S[23] ^ S[25] ^ S[29]; 00195 S2[20] = S[ 6] ^ S[ 8] ^ S[12] ^ S[14] ^ S[16] ^ S[18] ^ S[24] ^ S[26] ^ S[30]; 00196 S2[21] = S[ 7] ^ S[ 9] ^ S[13] ^ S[15] ^ S[17] ^ S[19] ^ S[25] ^ S[27] ^ S[31]; 00197 S2[22] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[14] ^ S[16] ^ 00198 S[18] ^ S[20] ^ S[24] ^ S[26] ^ S[28] ^ S[30]; 00199 S2[23] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[15] ^ S[17] ^ 00200 S[19] ^ S[21] ^ S[25] ^ S[27] ^ S[29] ^ S[31]; 00201 S2[24] = S[ 0] ^ S[ 8] ^ S[10] ^ S[12] ^ S[16] ^ S[18] ^ S[20] ^ S[22] ^ 00202 S[24] ^ S[26] ^ S[28]; 00203 S2[25] = S[ 1] ^ S[ 9] ^ S[11] ^ S[13] ^ S[17] ^ S[19] ^ S[21] ^ S[23] ^ 00204 S[25] ^ S[27] ^ S[29]; 00205 S2[26] = S[ 2] ^ S[10] ^ S[12] ^ S[14] ^ S[18] ^ S[20] ^ S[22] ^ S[24] ^ 00206 S[26] ^ S[28] ^ S[30]; 00207 S2[27] = S[ 3] ^ S[11] ^ S[13] ^ S[15] ^ S[19] ^ S[21] ^ S[23] ^ S[25] ^ 00208 S[27] ^ S[29] ^ S[31]; 00209 S2[28] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[12] ^ S[14] ^ S[16] ^ S[20] ^ S[22] ^ S[26] ^ S[28]; 00210 S2[29] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[13] ^ S[15] ^ S[17] ^ S[21] ^ S[23] ^ S[27] ^ S[29]; 00211 S2[30] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[14] ^ S[16] ^ S[18] ^ S[22] ^ S[24] ^ S[28] ^ S[30]; 00212 S2[31] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[15] ^ S[17] ^ S[19] ^ S[23] ^ S[25] ^ S[29] ^ S[31]; 00213 00214 copy_mem(&hash[0], &S2[0], 32); 00215 } 00216 } 00217 00218 /** 00219 * Produce the final GOST 34.11 output 00220 */ 00221 void GOST_34_11::final_result(byte out[]) 00222 { 00223 if(position) 00224 { 00225 clear_mem(&buffer[0] + position, buffer.size() - position); 00226 compress_n(&buffer[0], 1); 00227 } 00228 00229 secure_vector<byte> length_buf(32); 00230 const u64bit bit_count = count * 8; 00231 store_le(bit_count, &length_buf[0]); 00232 00233 secure_vector<byte> sum_buf = sum; 00234 00235 compress_n(&length_buf[0], 1); 00236 compress_n(&sum_buf[0], 1); 00237 00238 copy_mem(out, &hash[0], 32); 00239 00240 clear(); 00241 } 00242 00243 }