1 /*
2 * SHA-3
3 * (C) 2010,2016 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/sha3.h>
9 #include <botan/loadstor.h>
10 #include <botan/rotate.h>
11 #include <botan/exceptn.h>
12 #include <botan/cpuid.h>
13 
14 namespace Botan {
15 
16 namespace {
17 
SHA3_round(uint64_t T[25],const uint64_t A[25],uint64_t RC)18 inline void SHA3_round(uint64_t T[25], const uint64_t A[25], uint64_t RC)
19    {
20    const uint64_t C0 = A[0] ^ A[5] ^ A[10] ^ A[15] ^ A[20];
21    const uint64_t C1 = A[1] ^ A[6] ^ A[11] ^ A[16] ^ A[21];
22    const uint64_t C2 = A[2] ^ A[7] ^ A[12] ^ A[17] ^ A[22];
23    const uint64_t C3 = A[3] ^ A[8] ^ A[13] ^ A[18] ^ A[23];
24    const uint64_t C4 = A[4] ^ A[9] ^ A[14] ^ A[19] ^ A[24];
25 
26    const uint64_t D0 = rotl<1>(C0) ^ C3;
27    const uint64_t D1 = rotl<1>(C1) ^ C4;
28    const uint64_t D2 = rotl<1>(C2) ^ C0;
29    const uint64_t D3 = rotl<1>(C3) ^ C1;
30    const uint64_t D4 = rotl<1>(C4) ^ C2;
31 
32    const uint64_t B00 =          A[ 0] ^ D1;
33    const uint64_t B01 = rotl<44>(A[ 6] ^ D2);
34    const uint64_t B02 = rotl<43>(A[12] ^ D3);
35    const uint64_t B03 = rotl<21>(A[18] ^ D4);
36    const uint64_t B04 = rotl<14>(A[24] ^ D0);
37    T[ 0] = B00 ^ (~B01 & B02) ^ RC;
38    T[ 1] = B01 ^ (~B02 & B03);
39    T[ 2] = B02 ^ (~B03 & B04);
40    T[ 3] = B03 ^ (~B04 & B00);
41    T[ 4] = B04 ^ (~B00 & B01);
42 
43    const uint64_t B05 = rotl<28>(A[ 3] ^ D4);
44    const uint64_t B06 = rotl<20>(A[ 9] ^ D0);
45    const uint64_t B07 = rotl< 3>(A[10] ^ D1);
46    const uint64_t B08 = rotl<45>(A[16] ^ D2);
47    const uint64_t B09 = rotl<61>(A[22] ^ D3);
48    T[ 5] = B05 ^ (~B06 & B07);
49    T[ 6] = B06 ^ (~B07 & B08);
50    T[ 7] = B07 ^ (~B08 & B09);
51    T[ 8] = B08 ^ (~B09 & B05);
52    T[ 9] = B09 ^ (~B05 & B06);
53 
54    const uint64_t B10 = rotl< 1>(A[ 1] ^ D2);
55    const uint64_t B11 = rotl< 6>(A[ 7] ^ D3);
56    const uint64_t B12 = rotl<25>(A[13] ^ D4);
57    const uint64_t B13 = rotl< 8>(A[19] ^ D0);
58    const uint64_t B14 = rotl<18>(A[20] ^ D1);
59    T[10] = B10 ^ (~B11 & B12);
60    T[11] = B11 ^ (~B12 & B13);
61    T[12] = B12 ^ (~B13 & B14);
62    T[13] = B13 ^ (~B14 & B10);
63    T[14] = B14 ^ (~B10 & B11);
64 
65    const uint64_t B15 = rotl<27>(A[ 4] ^ D0);
66    const uint64_t B16 = rotl<36>(A[ 5] ^ D1);
67    const uint64_t B17 = rotl<10>(A[11] ^ D2);
68    const uint64_t B18 = rotl<15>(A[17] ^ D3);
69    const uint64_t B19 = rotl<56>(A[23] ^ D4);
70    T[15] = B15 ^ (~B16 & B17);
71    T[16] = B16 ^ (~B17 & B18);
72    T[17] = B17 ^ (~B18 & B19);
73    T[18] = B18 ^ (~B19 & B15);
74    T[19] = B19 ^ (~B15 & B16);
75 
76    const uint64_t B20 = rotl<62>(A[ 2] ^ D3);
77    const uint64_t B21 = rotl<55>(A[ 8] ^ D4);
78    const uint64_t B22 = rotl<39>(A[14] ^ D0);
79    const uint64_t B23 = rotl<41>(A[15] ^ D1);
80    const uint64_t B24 = rotl< 2>(A[21] ^ D2);
81    T[20] = B20 ^ (~B21 & B22);
82    T[21] = B21 ^ (~B22 & B23);
83    T[22] = B22 ^ (~B23 & B24);
84    T[23] = B23 ^ (~B24 & B20);
85    T[24] = B24 ^ (~B20 & B21);
86    }
87 
88 }
89 
90 //static
permute(uint64_t A[25])91 void SHA_3::permute(uint64_t A[25])
92    {
93 #if defined(BOTAN_HAS_SHA3_BMI2)
94    if(CPUID::has_bmi2())
95       {
96       return permute_bmi2(A);
97       }
98 #endif
99 
100    static const uint64_t RC[24] = {
101       0x0000000000000001, 0x0000000000008082, 0x800000000000808A,
102       0x8000000080008000, 0x000000000000808B, 0x0000000080000001,
103       0x8000000080008081, 0x8000000000008009, 0x000000000000008A,
104       0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
105       0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
106       0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
107       0x000000000000800A, 0x800000008000000A, 0x8000000080008081,
108       0x8000000000008080, 0x0000000080000001, 0x8000000080008008
109    };
110 
111    uint64_t T[25];
112 
113    for(size_t i = 0; i != 24; i += 2)
114       {
115       SHA3_round(T, A, RC[i+0]);
116       SHA3_round(A, T, RC[i+1]);
117       }
118    }
119 
120 //static
absorb(size_t bitrate,secure_vector<uint64_t> & S,size_t S_pos,const uint8_t input[],size_t length)121 size_t SHA_3::absorb(size_t bitrate,
122                      secure_vector<uint64_t>& S, size_t S_pos,
123                      const uint8_t input[], size_t length)
124    {
125    while(length > 0)
126       {
127       size_t to_take = std::min(length, bitrate / 8 - S_pos);
128 
129       length -= to_take;
130 
131       while(to_take && S_pos % 8)
132          {
133          S[S_pos / 8] ^= static_cast<uint64_t>(input[0]) << (8 * (S_pos % 8));
134 
135          ++S_pos;
136          ++input;
137          --to_take;
138          }
139 
140       while(to_take && to_take % 8 == 0)
141          {
142          S[S_pos / 8] ^= load_le<uint64_t>(input, 0);
143          S_pos += 8;
144          input += 8;
145          to_take -= 8;
146          }
147 
148       while(to_take)
149          {
150          S[S_pos / 8] ^= static_cast<uint64_t>(input[0]) << (8 * (S_pos % 8));
151 
152          ++S_pos;
153          ++input;
154          --to_take;
155          }
156 
157       if(S_pos == bitrate / 8)
158          {
159          SHA_3::permute(S.data());
160          S_pos = 0;
161          }
162       }
163 
164    return S_pos;
165    }
166 
167 //static
finish(size_t bitrate,secure_vector<uint64_t> & S,size_t S_pos,uint8_t init_pad,uint8_t fini_pad)168 void SHA_3::finish(size_t bitrate,
169                    secure_vector<uint64_t>& S, size_t S_pos,
170                    uint8_t init_pad, uint8_t fini_pad)
171    {
172    BOTAN_ARG_CHECK(bitrate % 64 == 0, "SHA-3 bitrate must be multiple of 64");
173 
174    S[S_pos / 8] ^= static_cast<uint64_t>(init_pad) << (8 * (S_pos % 8));
175    S[(bitrate / 64) - 1] ^= static_cast<uint64_t>(fini_pad) << 56;
176    SHA_3::permute(S.data());
177    }
178 
179 //static
expand(size_t bitrate,secure_vector<uint64_t> & S,uint8_t output[],size_t output_length)180 void SHA_3::expand(size_t bitrate,
181                    secure_vector<uint64_t>& S,
182                    uint8_t output[], size_t output_length)
183    {
184    BOTAN_ARG_CHECK(bitrate % 64 == 0, "SHA-3 bitrate must be multiple of 64");
185 
186    const size_t byterate = bitrate / 8;
187 
188    while(output_length > 0)
189       {
190       const size_t copying = std::min(byterate, output_length);
191 
192       copy_out_vec_le(output, copying, S);
193 
194       output += copying;
195       output_length -= copying;
196 
197       if(output_length > 0)
198          {
199          SHA_3::permute(S.data());
200          }
201       }
202    }
203 
SHA_3(size_t output_bits)204 SHA_3::SHA_3(size_t output_bits) :
205    m_output_bits(output_bits),
206    m_bitrate(1600 - 2*output_bits),
207    m_S(25),
208    m_S_pos(0)
209    {
210    // We only support the parameters for SHA-3 in this constructor
211 
212    if(output_bits != 224 && output_bits != 256 &&
213       output_bits != 384 && output_bits != 512)
214       throw Invalid_Argument("SHA_3: Invalid output length " +
215                              std::to_string(output_bits));
216    }
217 
name() const218 std::string SHA_3::name() const
219    {
220    return "SHA-3(" + std::to_string(m_output_bits) + ")";
221    }
222 
provider() const223 std::string SHA_3::provider() const
224    {
225 #if defined(BOTAN_HAS_SHA3_BMI2)
226    if(CPUID::has_bmi2())
227       {
228       return "bmi2";
229       }
230 #endif
231 
232    return "base";
233    }
234 
copy_state() const235 std::unique_ptr<HashFunction> SHA_3::copy_state() const
236    {
237    return std::unique_ptr<HashFunction>(new SHA_3(*this));
238    }
239 
clone() const240 HashFunction* SHA_3::clone() const
241    {
242    return new SHA_3(m_output_bits);
243    }
244 
clear()245 void SHA_3::clear()
246    {
247    zeroise(m_S);
248    m_S_pos = 0;
249    }
250 
add_data(const uint8_t input[],size_t length)251 void SHA_3::add_data(const uint8_t input[], size_t length)
252    {
253    m_S_pos = SHA_3::absorb(m_bitrate, m_S, m_S_pos, input, length);
254    }
255 
final_result(uint8_t output[])256 void SHA_3::final_result(uint8_t output[])
257    {
258    SHA_3::finish(m_bitrate, m_S, m_S_pos, 0x06, 0x80);
259 
260    /*
261    * We never have to run the permutation again because we only support
262    * limited output lengths
263    */
264    copy_out_vec_le(output, m_output_bits/8, m_S);
265 
266    clear();
267    }
268 
269 }
270