Coverage Report

Created: 2023-09-25 06:34

/src/botan/src/lib/hash/whirlpool/whirlpool.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Whirlpool
3
* (C) 1999-2007,2020 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/internal/whirlpool.h>
9
10
#include <botan/internal/loadstor.h>
11
#include <botan/internal/rotate.h>
12
13
namespace Botan {
14
15
namespace {
16
17
alignas(256) const uint64_t WHIRL_S[256] = {
18
   0x18186018C07830D8, 0x23238C2305AF4626, 0xC6C63FC67EF991B8, 0xE8E887E8136FCDFB, 0x878726874CA113CB,
19
   0xB8B8DAB8A9626D11, 0x0101040108050209, 0x4F4F214F426E9E0D, 0x3636D836ADEE6C9B, 0xA6A6A2A6590451FF,
20
   0xD2D26FD2DEBDB90C, 0xF5F5F3F5FB06F70E, 0x7979F979EF80F296, 0x6F6FA16F5FCEDE30, 0x91917E91FCEF3F6D,
21
   0x52525552AA07A4F8, 0x60609D6027FDC047, 0xBCBCCABC89766535, 0x9B9B569BACCD2B37, 0x8E8E028E048C018A,
22
   0xA3A3B6A371155BD2, 0x0C0C300C603C186C, 0x7B7BF17BFF8AF684, 0x3535D435B5E16A80, 0x1D1D741DE8693AF5,
23
   0xE0E0A7E05347DDB3, 0xD7D77BD7F6ACB321, 0xC2C22FC25EED999C, 0x2E2EB82E6D965C43, 0x4B4B314B627A9629,
24
   0xFEFEDFFEA321E15D, 0x575741578216AED5, 0x15155415A8412ABD, 0x7777C1779FB6EEE8, 0x3737DC37A5EB6E92,
25
   0xE5E5B3E57B56D79E, 0x9F9F469F8CD92313, 0xF0F0E7F0D317FD23, 0x4A4A354A6A7F9420, 0xDADA4FDA9E95A944,
26
   0x58587D58FA25B0A2, 0xC9C903C906CA8FCF, 0x2929A429558D527C, 0x0A0A280A5022145A, 0xB1B1FEB1E14F7F50,
27
   0xA0A0BAA0691A5DC9, 0x6B6BB16B7FDAD614, 0x85852E855CAB17D9, 0xBDBDCEBD8173673C, 0x5D5D695DD234BA8F,
28
   0x1010401080502090, 0xF4F4F7F4F303F507, 0xCBCB0BCB16C08BDD, 0x3E3EF83EEDC67CD3, 0x0505140528110A2D,
29
   0x676781671FE6CE78, 0xE4E4B7E47353D597, 0x27279C2725BB4E02, 0x4141194132588273, 0x8B8B168B2C9D0BA7,
30
   0xA7A7A6A7510153F6, 0x7D7DE97DCF94FAB2, 0x95956E95DCFB3749, 0xD8D847D88E9FAD56, 0xFBFBCBFB8B30EB70,
31
   0xEEEE9FEE2371C1CD, 0x7C7CED7CC791F8BB, 0x6666856617E3CC71, 0xDDDD53DDA68EA77B, 0x17175C17B84B2EAF,
32
   0x4747014702468E45, 0x9E9E429E84DC211A, 0xCACA0FCA1EC589D4, 0x2D2DB42D75995A58, 0xBFBFC6BF9179632E,
33
   0x07071C07381B0E3F, 0xADAD8EAD012347AC, 0x5A5A755AEA2FB4B0, 0x838336836CB51BEF, 0x3333CC3385FF66B6,
34
   0x636391633FF2C65C, 0x02020802100A0412, 0xAAAA92AA39384993, 0x7171D971AFA8E2DE, 0xC8C807C80ECF8DC6,
35
   0x19196419C87D32D1, 0x494939497270923B, 0xD9D943D9869AAF5F, 0xF2F2EFF2C31DF931, 0xE3E3ABE34B48DBA8,
36
   0x5B5B715BE22AB6B9, 0x88881A8834920DBC, 0x9A9A529AA4C8293E, 0x262698262DBE4C0B, 0x3232C8328DFA64BF,
37
   0xB0B0FAB0E94A7D59, 0xE9E983E91B6ACFF2, 0x0F0F3C0F78331E77, 0xD5D573D5E6A6B733, 0x80803A8074BA1DF4,
38
   0xBEBEC2BE997C6127, 0xCDCD13CD26DE87EB, 0x3434D034BDE46889, 0x48483D487A759032, 0xFFFFDBFFAB24E354,
39
   0x7A7AF57AF78FF48D, 0x90907A90F4EA3D64, 0x5F5F615FC23EBE9D, 0x202080201DA0403D, 0x6868BD6867D5D00F,
40
   0x1A1A681AD07234CA, 0xAEAE82AE192C41B7, 0xB4B4EAB4C95E757D, 0x54544D549A19A8CE, 0x93937693ECE53B7F,
41
   0x222288220DAA442F, 0x64648D6407E9C863, 0xF1F1E3F1DB12FF2A, 0x7373D173BFA2E6CC, 0x12124812905A2482,
42
   0x40401D403A5D807A, 0x0808200840281048, 0xC3C32BC356E89B95, 0xECEC97EC337BC5DF, 0xDBDB4BDB9690AB4D,
43
   0xA1A1BEA1611F5FC0, 0x8D8D0E8D1C830791, 0x3D3DF43DF5C97AC8, 0x97976697CCF1335B, 0x0000000000000000,
44
   0xCFCF1BCF36D483F9, 0x2B2BAC2B4587566E, 0x7676C57697B3ECE1, 0x8282328264B019E6, 0xD6D67FD6FEA9B128,
45
   0x1B1B6C1BD87736C3, 0xB5B5EEB5C15B7774, 0xAFAF86AF112943BE, 0x6A6AB56A77DFD41D, 0x50505D50BA0DA0EA,
46
   0x45450945124C8A57, 0xF3F3EBF3CB18FB38, 0x3030C0309DF060AD, 0xEFEF9BEF2B74C3C4, 0x3F3FFC3FE5C37EDA,
47
   0x55554955921CAAC7, 0xA2A2B2A2791059DB, 0xEAEA8FEA0365C9E9, 0x656589650FECCA6A, 0xBABAD2BAB9686903,
48
   0x2F2FBC2F65935E4A, 0xC0C027C04EE79D8E, 0xDEDE5FDEBE81A160, 0x1C1C701CE06C38FC, 0xFDFDD3FDBB2EE746,
49
   0x4D4D294D52649A1F, 0x92927292E4E03976, 0x7575C9758FBCEAFA, 0x06061806301E0C36, 0x8A8A128A249809AE,
50
   0xB2B2F2B2F940794B, 0xE6E6BFE66359D185, 0x0E0E380E70361C7E, 0x1F1F7C1FF8633EE7, 0x6262956237F7C455,
51
   0xD4D477D4EEA3B53A, 0xA8A89AA829324D81, 0x96966296C4F43152, 0xF9F9C3F99B3AEF62, 0xC5C533C566F697A3,
52
   0x2525942535B14A10, 0x59597959F220B2AB, 0x84842A8454AE15D0, 0x7272D572B7A7E4C5, 0x3939E439D5DD72EC,
53
   0x4C4C2D4C5A619816, 0x5E5E655ECA3BBC94, 0x7878FD78E785F09F, 0x3838E038DDD870E5, 0x8C8C0A8C14860598,
54
   0xD1D163D1C6B2BF17, 0xA5A5AEA5410B57E4, 0xE2E2AFE2434DD9A1, 0x616199612FF8C24E, 0xB3B3F6B3F1457B42,
55
   0x2121842115A54234, 0x9C9C4A9C94D62508, 0x1E1E781EF0663CEE, 0x4343114322528661, 0xC7C73BC776FC93B1,
56
   0xFCFCD7FCB32BE54F, 0x0404100420140824, 0x51515951B208A2E3, 0x99995E99BCC72F25, 0x6D6DA96D4FC4DA22,
57
   0x0D0D340D68391A65, 0xFAFACFFA8335E979, 0xDFDF5BDFB684A369, 0x7E7EE57ED79BFCA9, 0x242490243DB44819,
58
   0x3B3BEC3BC5D776FE, 0xABAB96AB313D4B9A, 0xCECE1FCE3ED181F0, 0x1111441188552299, 0x8F8F068F0C890383,
59
   0x4E4E254E4A6B9C04, 0xB7B7E6B7D1517366, 0xEBEB8BEB0B60CBE0, 0x3C3CF03CFDCC78C1, 0x81813E817CBF1FFD,
60
   0x94946A94D4FE3540, 0xF7F7FBF7EB0CF31C, 0xB9B9DEB9A1676F18, 0x13134C13985F268B, 0x2C2CB02C7D9C5851,
61
   0xD3D36BD3D6B8BB05, 0xE7E7BBE76B5CD38C, 0x6E6EA56E57CBDC39, 0xC4C437C46EF395AA, 0x03030C03180F061B,
62
   0x565645568A13ACDC, 0x44440D441A49885E, 0x7F7FE17FDF9EFEA0, 0xA9A99EA921374F88, 0x2A2AA82A4D825467,
63
   0xBBBBD6BBB16D6B0A, 0xC1C123C146E29F87, 0x53535153A202A6F1, 0xDCDC57DCAE8BA572, 0x0B0B2C0B58271653,
64
   0x9D9D4E9D9CD32701, 0x6C6CAD6C47C1D82B, 0x3131C43195F562A4, 0x7474CD7487B9E8F3, 0xF6F6FFF6E309F115,
65
   0x464605460A438C4C, 0xACAC8AAC092645A5, 0x89891E893C970FB5, 0x14145014A04428B4, 0xE1E1A3E15B42DFBA,
66
   0x16165816B04E2CA6, 0x3A3AE83ACDD274F7, 0x6969B9696FD0D206, 0x09092409482D1241, 0x7070DD70A7ADE0D7,
67
   0xB6B6E2B6D954716F, 0xD0D067D0CEB7BD1E, 0xEDED93ED3B7EC7D6, 0xCCCC17CC2EDB85E2, 0x424215422A578468,
68
   0x98985A98B4C22D2C, 0xA4A4AAA4490E55ED, 0x2828A0285D885075, 0x5C5C6D5CDA31B886, 0xF8F8C7F8933FED6B,
69
   0x8686228644A411C2};
70
71
17.1M
uint64_t whirl(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7) {
72
17.1M
   const uint64_t s0 = WHIRL_S[get_byte<0>(x0)];
73
17.1M
   const uint64_t s1 = WHIRL_S[get_byte<1>(x1)];
74
17.1M
   const uint64_t s2 = WHIRL_S[get_byte<2>(x2)];
75
17.1M
   const uint64_t s3 = WHIRL_S[get_byte<3>(x3)];
76
17.1M
   const uint64_t s4 = WHIRL_S[get_byte<4>(x4)];
77
17.1M
   const uint64_t s5 = WHIRL_S[get_byte<5>(x5)];
78
17.1M
   const uint64_t s6 = WHIRL_S[get_byte<6>(x6)];
79
17.1M
   const uint64_t s7 = WHIRL_S[get_byte<7>(x7)];
80
81
17.1M
   return s0 ^ rotr<8>(s1) ^ rotr<16>(s2) ^ rotr<24>(s3) ^ rotr<32>(s4) ^ rotr<40>(s5) ^ rotr<48>(s6) ^ rotr<56>(s7);
82
17.1M
}
83
84
}  // namespace
85
86
/*
87
* Whirlpool Compression Function
88
*/
89
106k
void Whirlpool::compress_n(const uint8_t in[], size_t blocks) {
90
106k
   static const uint64_t RC[10] = {0x1823C6E887B8014F,
91
106k
                                   0x36A6D2F5796F9152,
92
106k
                                   0x60BC9B8EA30C7B35,
93
106k
                                   0x1DE0D7C22E4BFE57,
94
106k
                                   0x157737E59FF04ADA,
95
106k
                                   0x58C9290AB1A06B85,
96
106k
                                   0xBD5D10F4CB3E0567,
97
106k
                                   0xE427418BA77D95D8,
98
106k
                                   0xFBEE7C66DD17479E,
99
106k
                                   0xCA2DBF07AD5A8333};
100
101
213k
   for(size_t i = 0; i != blocks; ++i) {
102
107k
      uint64_t K[11 * 8] = {0};
103
104
107k
      K[0] = m_digest[0];
105
107k
      K[1] = m_digest[1];
106
107k
      K[2] = m_digest[2];
107
107k
      K[3] = m_digest[3];
108
107k
      K[4] = m_digest[4];
109
107k
      K[5] = m_digest[5];
110
107k
      K[6] = m_digest[6];
111
107k
      K[7] = m_digest[7];
112
113
      // Whirlpool key schedule:
114
1.17M
      for(size_t r = 1; r != 11; ++r) {
115
1.07M
         const uint64_t PK0 = K[8 * (r - 1) + 0];
116
1.07M
         const uint64_t PK1 = K[8 * (r - 1) + 1];
117
1.07M
         const uint64_t PK2 = K[8 * (r - 1) + 2];
118
1.07M
         const uint64_t PK3 = K[8 * (r - 1) + 3];
119
1.07M
         const uint64_t PK4 = K[8 * (r - 1) + 4];
120
1.07M
         const uint64_t PK5 = K[8 * (r - 1) + 5];
121
1.07M
         const uint64_t PK6 = K[8 * (r - 1) + 6];
122
1.07M
         const uint64_t PK7 = K[8 * (r - 1) + 7];
123
124
1.07M
         K[8 * r + 0] = whirl(PK0, PK7, PK6, PK5, PK4, PK3, PK2, PK1) ^ RC[r - 1];
125
1.07M
         K[8 * r + 1] = whirl(PK1, PK0, PK7, PK6, PK5, PK4, PK3, PK2);
126
1.07M
         K[8 * r + 2] = whirl(PK2, PK1, PK0, PK7, PK6, PK5, PK4, PK3);
127
1.07M
         K[8 * r + 3] = whirl(PK3, PK2, PK1, PK0, PK7, PK6, PK5, PK4);
128
1.07M
         K[8 * r + 4] = whirl(PK4, PK3, PK2, PK1, PK0, PK7, PK6, PK5);
129
1.07M
         K[8 * r + 5] = whirl(PK5, PK4, PK3, PK2, PK1, PK0, PK7, PK6);
130
1.07M
         K[8 * r + 6] = whirl(PK6, PK5, PK4, PK3, PK2, PK1, PK0, PK7);
131
1.07M
         K[8 * r + 7] = whirl(PK7, PK6, PK5, PK4, PK3, PK2, PK1, PK0);
132
1.07M
      }
133
134
107k
      uint64_t M[8] = {0};
135
107k
      load_be(M, in, 8);
136
137
      // First round (key masking)
138
107k
      uint64_t B0 = M[0] ^ K[0];
139
107k
      uint64_t B1 = M[1] ^ K[1];
140
107k
      uint64_t B2 = M[2] ^ K[2];
141
107k
      uint64_t B3 = M[3] ^ K[3];
142
107k
      uint64_t B4 = M[4] ^ K[4];
143
107k
      uint64_t B5 = M[5] ^ K[5];
144
107k
      uint64_t B6 = M[6] ^ K[6];
145
107k
      uint64_t B7 = M[7] ^ K[7];
146
147
1.17M
      for(size_t r = 1; r != 11; ++r) {
148
1.07M
         uint64_t T0 = whirl(B0, B7, B6, B5, B4, B3, B2, B1) ^ K[8 * r + 0];
149
1.07M
         uint64_t T1 = whirl(B1, B0, B7, B6, B5, B4, B3, B2) ^ K[8 * r + 1];
150
1.07M
         uint64_t T2 = whirl(B2, B1, B0, B7, B6, B5, B4, B3) ^ K[8 * r + 2];
151
1.07M
         uint64_t T3 = whirl(B3, B2, B1, B0, B7, B6, B5, B4) ^ K[8 * r + 3];
152
1.07M
         uint64_t T4 = whirl(B4, B3, B2, B1, B0, B7, B6, B5) ^ K[8 * r + 4];
153
1.07M
         uint64_t T5 = whirl(B5, B4, B3, B2, B1, B0, B7, B6) ^ K[8 * r + 5];
154
1.07M
         uint64_t T6 = whirl(B6, B5, B4, B3, B2, B1, B0, B7) ^ K[8 * r + 6];
155
1.07M
         uint64_t T7 = whirl(B7, B6, B5, B4, B3, B2, B1, B0) ^ K[8 * r + 7];
156
157
1.07M
         B0 = T0;
158
1.07M
         B1 = T1;
159
1.07M
         B2 = T2;
160
1.07M
         B3 = T3;
161
1.07M
         B4 = T4;
162
1.07M
         B5 = T5;
163
1.07M
         B6 = T6;
164
1.07M
         B7 = T7;
165
1.07M
      }
166
167
107k
      m_digest[0] ^= B0 ^ M[0];
168
107k
      m_digest[1] ^= B1 ^ M[1];
169
107k
      m_digest[2] ^= B2 ^ M[2];
170
107k
      m_digest[3] ^= B3 ^ M[3];
171
107k
      m_digest[4] ^= B4 ^ M[4];
172
107k
      m_digest[5] ^= B5 ^ M[5];
173
107k
      m_digest[6] ^= B6 ^ M[6];
174
107k
      m_digest[7] ^= B7 ^ M[7];
175
176
107k
      in += hash_block_size();
177
107k
   }
178
106k
}
179
180
/*
181
* Copy out the digest
182
*/
183
32.4k
void Whirlpool::copy_out(uint8_t output[]) {
184
32.4k
   copy_out_vec_be(output, output_length(), m_digest);
185
32.4k
}
186
187
0
std::unique_ptr<HashFunction> Whirlpool::copy_state() const {
188
0
   return std::make_unique<Whirlpool>(*this);
189
0
}
190
191
/*
192
* Clear memory of sensitive data
193
*/
194
33.0k
void Whirlpool::clear() {
195
33.0k
   MDx_HashFunction::clear();
196
33.0k
   zeroise(m_digest);
197
33.0k
}
198
199
}  // namespace Botan