KWallet

sha1.cc
1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2001 George Staikos <staikos@kde.org>
4
5 Based heavily on SHA1 code from GPG 1.0.3:
6 SPDX-FileCopyrightText: 1998 FSF
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9*/
10
11#include "sha1.h"
12
13#include <config-kwalletbackend.h>
14
15// DO NOT INCLUDE THIS. IT BREAKS KWALLET.
16// We need to live with -Wundef until someone really figures out the problem.
17//#include <QtCore/qglobal.h> // for Q_BYTE_ORDER and friends
18// Workaround for -Wundef
19#define Q_BIG_ENDIAN 1
20#define Q_BYTE_ORDER Q_BIG_ENDIAN
21
22#include <sys/types.h>
23#if HAVE_SYS_BITYPES_H
24#include <sys/bitypes.h> /* For uintXX_t on Tru64 */
25#endif
26#if HAVE_STDINT_H
27#include <stdint.h>
28#endif
29
30#include <string.h>
31
32// clang-format off
33// FIXME: this can be optimized to one instruction on most cpus.
34#define rol(x,y) ((x << y) | (x >> (32-y)))
35
36#define K1 0x5a827999L
37#define K2 0x6ed9eba1L
38#define K3 0x8f1bbcdcL
39#define K4 0xca62c1d6L
40#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
41#define F2(x,y,z) ( x ^ y ^ z )
42#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
43#define F4(x,y,z) ( x ^ y ^ z )
44
45#define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] \
46 ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \
47 , (x[i&0x0f] = (tm << 1) | (tm >> 31)))
48
49#define R(a,b,c,d,e,f,k,m) do { e += rol(a, 5) \
50 + f(b, c, d) \
51 + k \
52 + m; \
53 b = rol(b, 30); \
54} while(0)
55// clang-format on
56
57SHA1::SHA1()
58{
59 _hashlen = 160;
60 _init = false;
61 reset();
62}
63
64int SHA1::reset()
65{
66 _h0 = 0x67452301;
67 _h1 = 0xefcdab89;
68 _h2 = 0x98badcfe;
69 _h3 = 0x10325476;
70 _h4 = 0xc3d2e1f0;
71 _nblocks = 0;
72 _count = 0;
73 memset(_buf, 0, 56); // clear the buffer
74
75 _init = true;
76 return 0;
77}
78
79int SHA1::size() const
80{
81 return _hashlen;
82}
83
84SHA1::~SHA1()
85{
86
87}
88
89void SHA1::transform(void *data)
90{
91 unsigned int a;
92 unsigned int b;
93 unsigned int c;
94 unsigned int d;
95 unsigned int e;
96 unsigned int tm;
97 unsigned int x[16];
98 unsigned char *_data = (unsigned char *)data;
99
100 a = _h0;
101 b = _h1;
102 c = _h2;
103 d = _h3;
104 e = _h4;
105
106#if Q_BYTE_ORDER == Q_BIG_ENDIAN
107 memcpy(x, _data, 64);
108#else
109 int i;
110 unsigned char *p2;
111 for (i = 0, p2 = (unsigned char *)x;
112 i < 16; i++, p2 += 4) {
113 p2[3] = *_data++;
114 p2[2] = *_data++;
115 p2[1] = *_data++;
116 p2[0] = *_data++;
117 }
118#endif
119
120 R(a, b, c, d, e, F1, K1, x[ 0]);
121 R(e, a, b, c, d, F1, K1, x[ 1]);
122 R(d, e, a, b, c, F1, K1, x[ 2]);
123 R(c, d, e, a, b, F1, K1, x[ 3]);
124 R(b, c, d, e, a, F1, K1, x[ 4]);
125 R(a, b, c, d, e, F1, K1, x[ 5]);
126 R(e, a, b, c, d, F1, K1, x[ 6]);
127 R(d, e, a, b, c, F1, K1, x[ 7]);
128 R(c, d, e, a, b, F1, K1, x[ 8]);
129 R(b, c, d, e, a, F1, K1, x[ 9]);
130 R(a, b, c, d, e, F1, K1, x[10]);
131 R(e, a, b, c, d, F1, K1, x[11]);
132 R(d, e, a, b, c, F1, K1, x[12]);
133 R(c, d, e, a, b, F1, K1, x[13]);
134 R(b, c, d, e, a, F1, K1, x[14]);
135 R(a, b, c, d, e, F1, K1, x[15]);
136 R(e, a, b, c, d, F1, K1, M(16));
137 R(d, e, a, b, c, F1, K1, M(17));
138 R(c, d, e, a, b, F1, K1, M(18));
139 R(b, c, d, e, a, F1, K1, M(19));
140 R(a, b, c, d, e, F2, K2, M(20));
141 R(e, a, b, c, d, F2, K2, M(21));
142 R(d, e, a, b, c, F2, K2, M(22));
143 R(c, d, e, a, b, F2, K2, M(23));
144 R(b, c, d, e, a, F2, K2, M(24));
145 R(a, b, c, d, e, F2, K2, M(25));
146 R(e, a, b, c, d, F2, K2, M(26));
147 R(d, e, a, b, c, F2, K2, M(27));
148 R(c, d, e, a, b, F2, K2, M(28));
149 R(b, c, d, e, a, F2, K2, M(29));
150 R(a, b, c, d, e, F2, K2, M(30));
151 R(e, a, b, c, d, F2, K2, M(31));
152 R(d, e, a, b, c, F2, K2, M(32));
153 R(c, d, e, a, b, F2, K2, M(33));
154 R(b, c, d, e, a, F2, K2, M(34));
155 R(a, b, c, d, e, F2, K2, M(35));
156 R(e, a, b, c, d, F2, K2, M(36));
157 R(d, e, a, b, c, F2, K2, M(37));
158 R(c, d, e, a, b, F2, K2, M(38));
159 R(b, c, d, e, a, F2, K2, M(39));
160 R(a, b, c, d, e, F3, K3, M(40));
161 R(e, a, b, c, d, F3, K3, M(41));
162 R(d, e, a, b, c, F3, K3, M(42));
163 R(c, d, e, a, b, F3, K3, M(43));
164 R(b, c, d, e, a, F3, K3, M(44));
165 R(a, b, c, d, e, F3, K3, M(45));
166 R(e, a, b, c, d, F3, K3, M(46));
167 R(d, e, a, b, c, F3, K3, M(47));
168 R(c, d, e, a, b, F3, K3, M(48));
169 R(b, c, d, e, a, F3, K3, M(49));
170 R(a, b, c, d, e, F3, K3, M(50));
171 R(e, a, b, c, d, F3, K3, M(51));
172 R(d, e, a, b, c, F3, K3, M(52));
173 R(c, d, e, a, b, F3, K3, M(53));
174 R(b, c, d, e, a, F3, K3, M(54));
175 R(a, b, c, d, e, F3, K3, M(55));
176 R(e, a, b, c, d, F3, K3, M(56));
177 R(d, e, a, b, c, F3, K3, M(57));
178 R(c, d, e, a, b, F3, K3, M(58));
179 R(b, c, d, e, a, F3, K3, M(59));
180 R(a, b, c, d, e, F4, K4, M(60));
181 R(e, a, b, c, d, F4, K4, M(61));
182 R(d, e, a, b, c, F4, K4, M(62));
183 R(c, d, e, a, b, F4, K4, M(63));
184 R(b, c, d, e, a, F4, K4, M(64));
185 R(a, b, c, d, e, F4, K4, M(65));
186 R(e, a, b, c, d, F4, K4, M(66));
187 R(d, e, a, b, c, F4, K4, M(67));
188 R(c, d, e, a, b, F4, K4, M(68));
189 R(b, c, d, e, a, F4, K4, M(69));
190 R(a, b, c, d, e, F4, K4, M(70));
191 R(e, a, b, c, d, F4, K4, M(71));
192 R(d, e, a, b, c, F4, K4, M(72));
193 R(c, d, e, a, b, F4, K4, M(73));
194 R(b, c, d, e, a, F4, K4, M(74));
195 R(a, b, c, d, e, F4, K4, M(75));
196 R(e, a, b, c, d, F4, K4, M(76));
197 R(d, e, a, b, c, F4, K4, M(77));
198 R(c, d, e, a, b, F4, K4, M(78));
199 R(b, c, d, e, a, F4, K4, M(79));
200
201 _h0 += a;
202 _h1 += b;
203 _h2 += c;
204 _h3 += d;
205 _h4 += e;
206
207}
208
209bool SHA1::readyToGo() const
210{
211 return _init;
212}
213
214int SHA1::process(const void *block, int len)
215{
216 if (!_init) {
217 return -1;
218 }
219
220 unsigned char *_block = (unsigned char *)block;
221
222 int cnt = 0;
223 // Flush the buffer before proceeding
224 if (_count == 64) {
225 transform(_buf);
226 _count = 0;
227 _nblocks++;
228 }
229
230 if (!_block) {
231 return 0;
232 }
233
234 if (_count) {
235 for (; len && _count < 64; --len, ++cnt) {
236 _buf[_count++] = *_block++;
237 }
238 process(nullptr, 0); // flush the buffer if necessary
239 if (!len) {
240 return cnt;
241 }
242 }
243
244 while (len >= 64) {
245 transform(_block);
246 _count = 0;
247 _nblocks++;
248 len -= 64;
249 cnt += 64;
250 _block += 64;
251 }
252
253 for (; len && _count < 64; --len, ++cnt) {
254 _buf[_count++] = *_block++;
255 }
256
257 return cnt;
258}
259
260const unsigned char *SHA1::hash()
261{
262 unsigned int t;
263 unsigned int msb;
264 unsigned int lsb;
265 unsigned char *p;
266
267 if (!_init) {
268 return (unsigned char *)_buf;
269 }
270
271 process(nullptr, 0);
272
273 msb = 0;
274 t = _nblocks;
275
276 if ((lsb = t << 6) < t) {
277 msb++;
278 }
279
280 msb += t >> 26;
281 t = lsb;
282
283 if ((lsb = t + _count) < t) {
284 msb++;
285 }
286
287 t = lsb;
288
289 if ((lsb = t << 3) < t) {
290 msb++;
291 }
292
293 msb += t >> 29;
294
295 _buf[_count++] = 0x80;
296
297 if (_count < 56) {
298 while (_count < 56) {
299 _buf[_count++] = 0;
300 }
301 } else {
302 while (_count < 64) {
303 _buf[_count++] = 0;
304 }
305 process(nullptr, 0);
306 memset(_buf, 0, 56);
307 }
308
309 _buf[56] = msb >> 24;
310 _buf[57] = msb >> 16;
311 _buf[58] = msb >> 8;
312 _buf[59] = msb;
313 _buf[60] = lsb >> 24;
314 _buf[61] = lsb >> 16;
315 _buf[62] = lsb >> 8;
316 _buf[63] = lsb;
317
318 transform(_buf);
319
320 p = _buf;
321// clang-format off
322#if Q_BYTE_ORDER == Q_BIG_ENDIAN
323#define X(a) do { *(uint32_t *)p = _h##a; p += 4; } while (0)
324#else
325#define X(a) do { *p++ = _h##a >> 24; *p++ = _h##a >> 16; \
326 *p++ = _h##a >> 8; *p++ = _h##a; } while (0)
327#endif
328// clang-format on
329
330 X(0);
331 X(1);
332 X(2);
333 X(3);
334 X(4);
335
336#undef X
337
338 _init = false;
339
340 return (unsigned char *)_buf;
341}
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:16:05 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.