2
* hash.cpp - hashing functions for SHA1 and MD5
3
* Copyright (C) 2003 Justin Karneges
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
static bool bigEndian;
27
static bool haveEndian = false;
29
static void ensureEndian()
34
qSysInfo(&wordSize, &bigEndian);
38
//----------------------------------------------------------------------------
40
//----------------------------------------------------------------------------
42
/* NOTE: the following code was modified to not need BYTE_ORDER -- Justin */
45
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
47
This software is provided 'as-is', without any express or implied
48
warranty. In no event will the authors be held liable for any damages
49
arising from the use of this software.
51
Permission is granted to anyone to use this software for any purpose,
52
including commercial applications, and to alter it and redistribute it
53
freely, subject to the following restrictions:
55
1. The origin of this software must not be misrepresented; you must not
56
claim that you wrote the original software. If you use this software
57
in a product, an acknowledgment in the product documentation would be
58
appreciated but is not required.
59
2. Altered source versions must be plainly marked as such, and must not be
60
misrepresented as being the original software.
61
3. This notice may not be removed or altered from any source distribution.
67
/* $Id: hash.cpp,v 1.2 2003/11/09 12:32:04 justin Exp $ */
69
Independent implementation of MD5 (RFC 1321).
71
This code implements the MD5 Algorithm defined in RFC 1321, whose
73
http://www.ietf.org/rfc/rfc1321.txt
74
The code is derived from the text of the RFC, including the test suite
75
(section A.5) but excluding the rest of Appendix A. It does not include
76
any code or documentation that is identified in the RFC as being
79
The original and principal author of md5.c is L. Peter Deutsch
80
<ghost@aladdin.com>. Other authors are noted in the change history
81
that follows (in reverse chronological order):
83
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
84
either statically or dynamically; added missing #include <string.h>
86
2002-03-11 lpd Corrected argument list for main(), and added int return
87
type, in test program and T value program.
88
2002-02-21 lpd Added missing #include <stdio.h> in test program.
89
2000-07-03 lpd Patched to eliminate warnings about "constant is
90
unsigned in ANSI C, signed in traditional"; made test program
92
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
93
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
94
1999-05-03 lpd Original version.
98
* This package supports both compile-time and run-time determination of CPU
99
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
100
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
101
* defined as non-zero, the code will be compiled to run only on big-endian
102
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
103
* run on either big- or little-endian CPUs, but will run slightly less
104
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
107
typedef Q_UINT8 md5_byte_t; /* 8-bit byte */
108
typedef Q_UINT32 md5_word_t; /* 32-bit word */
110
/* Define the state of the MD5 Algorithm. */
111
typedef struct md5_state_s {
112
md5_word_t count[2]; /* message length in bits, lsw first */
113
md5_word_t abcd[4]; /* digest buffer */
114
md5_byte_t buf[64]; /* accumulate block */
117
/* Initialize the algorithm. */
118
void md5_init(md5_state_t *pms);
120
/* Append a string to the message. */
121
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
123
/* Finish the message and return the digest. */
124
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
126
#define T_MASK ((md5_word_t)~0)
127
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
128
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
129
#define T3 0x242070db
130
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
131
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
132
#define T6 0x4787c62a
133
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
134
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
135
#define T9 0x698098d8
136
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
137
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
138
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
139
#define T13 0x6b901122
140
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
141
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
142
#define T16 0x49b40821
143
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
144
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
145
#define T19 0x265e5a51
146
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
147
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
148
#define T22 0x02441453
149
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
150
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
151
#define T25 0x21e1cde6
152
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
153
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
154
#define T28 0x455a14ed
155
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
156
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
157
#define T31 0x676f02d9
158
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
159
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
160
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
161
#define T35 0x6d9d6122
162
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
163
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
164
#define T38 0x4bdecfa9
165
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
166
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
167
#define T41 0x289b7ec6
168
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
169
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
170
#define T44 0x04881d05
171
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
172
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
173
#define T47 0x1fa27cf8
174
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
175
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
176
#define T50 0x432aff97
177
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
178
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
179
#define T53 0x655b59c3
180
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
181
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
182
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
183
#define T57 0x6fa87e4f
184
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
185
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
186
#define T60 0x4e0811a1
187
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
188
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
189
#define T63 0x2ad7d2bb
190
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
194
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
197
a = pms->abcd[0], b = pms->abcd[1],
198
c = pms->abcd[2], d = pms->abcd[3];
201
/* Define storage for little-endian or both types of CPUs. */
209
* On big-endian machines, we must arrange the bytes in the
212
const md5_byte_t *xp = data;
215
X = xbuf; /* (dynamic only) */
217
for (i = 0; i < 16; ++i, xp += 4)
218
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
220
else /* dynamic big-endian */
223
* On little-endian machines, we can process properly aligned
224
* data without copying it.
226
if (!((data - (const md5_byte_t *)0) & 3)) {
227
/* data are properly aligned */
228
X = (const md5_word_t *)data;
231
memcpy(xbuf, data, 64);
237
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
240
/* Let [abcd k s i] denote the operation
241
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
242
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
243
#define SET(a, b, c, d, k, s, Ti)\
244
t = a + F(b,c,d) + X[k] + Ti;\
245
a = ROTATE_LEFT(t, s) + b
246
/* Do the following 16 operations. */
247
SET(a, b, c, d, 0, 7, T1);
248
SET(d, a, b, c, 1, 12, T2);
249
SET(c, d, a, b, 2, 17, T3);
250
SET(b, c, d, a, 3, 22, T4);
251
SET(a, b, c, d, 4, 7, T5);
252
SET(d, a, b, c, 5, 12, T6);
253
SET(c, d, a, b, 6, 17, T7);
254
SET(b, c, d, a, 7, 22, T8);
255
SET(a, b, c, d, 8, 7, T9);
256
SET(d, a, b, c, 9, 12, T10);
257
SET(c, d, a, b, 10, 17, T11);
258
SET(b, c, d, a, 11, 22, T12);
259
SET(a, b, c, d, 12, 7, T13);
260
SET(d, a, b, c, 13, 12, T14);
261
SET(c, d, a, b, 14, 17, T15);
262
SET(b, c, d, a, 15, 22, T16);
266
/* Let [abcd k s i] denote the operation
267
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
268
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
269
#define SET(a, b, c, d, k, s, Ti)\
270
t = a + G(b,c,d) + X[k] + Ti;\
271
a = ROTATE_LEFT(t, s) + b
272
/* Do the following 16 operations. */
273
SET(a, b, c, d, 1, 5, T17);
274
SET(d, a, b, c, 6, 9, T18);
275
SET(c, d, a, b, 11, 14, T19);
276
SET(b, c, d, a, 0, 20, T20);
277
SET(a, b, c, d, 5, 5, T21);
278
SET(d, a, b, c, 10, 9, T22);
279
SET(c, d, a, b, 15, 14, T23);
280
SET(b, c, d, a, 4, 20, T24);
281
SET(a, b, c, d, 9, 5, T25);
282
SET(d, a, b, c, 14, 9, T26);
283
SET(c, d, a, b, 3, 14, T27);
284
SET(b, c, d, a, 8, 20, T28);
285
SET(a, b, c, d, 13, 5, T29);
286
SET(d, a, b, c, 2, 9, T30);
287
SET(c, d, a, b, 7, 14, T31);
288
SET(b, c, d, a, 12, 20, T32);
292
/* Let [abcd k s t] denote the operation
293
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
294
#define H(x, y, z) ((x) ^ (y) ^ (z))
295
#define SET(a, b, c, d, k, s, Ti)\
296
t = a + H(b,c,d) + X[k] + Ti;\
297
a = ROTATE_LEFT(t, s) + b
298
/* Do the following 16 operations. */
299
SET(a, b, c, d, 5, 4, T33);
300
SET(d, a, b, c, 8, 11, T34);
301
SET(c, d, a, b, 11, 16, T35);
302
SET(b, c, d, a, 14, 23, T36);
303
SET(a, b, c, d, 1, 4, T37);
304
SET(d, a, b, c, 4, 11, T38);
305
SET(c, d, a, b, 7, 16, T39);
306
SET(b, c, d, a, 10, 23, T40);
307
SET(a, b, c, d, 13, 4, T41);
308
SET(d, a, b, c, 0, 11, T42);
309
SET(c, d, a, b, 3, 16, T43);
310
SET(b, c, d, a, 6, 23, T44);
311
SET(a, b, c, d, 9, 4, T45);
312
SET(d, a, b, c, 12, 11, T46);
313
SET(c, d, a, b, 15, 16, T47);
314
SET(b, c, d, a, 2, 23, T48);
318
/* Let [abcd k s t] denote the operation
319
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
320
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
321
#define SET(a, b, c, d, k, s, Ti)\
322
t = a + I(b,c,d) + X[k] + Ti;\
323
a = ROTATE_LEFT(t, s) + b
324
/* Do the following 16 operations. */
325
SET(a, b, c, d, 0, 6, T49);
326
SET(d, a, b, c, 7, 10, T50);
327
SET(c, d, a, b, 14, 15, T51);
328
SET(b, c, d, a, 5, 21, T52);
329
SET(a, b, c, d, 12, 6, T53);
330
SET(d, a, b, c, 3, 10, T54);
331
SET(c, d, a, b, 10, 15, T55);
332
SET(b, c, d, a, 1, 21, T56);
333
SET(a, b, c, d, 8, 6, T57);
334
SET(d, a, b, c, 15, 10, T58);
335
SET(c, d, a, b, 6, 15, T59);
336
SET(b, c, d, a, 13, 21, T60);
337
SET(a, b, c, d, 4, 6, T61);
338
SET(d, a, b, c, 11, 10, T62);
339
SET(c, d, a, b, 2, 15, T63);
340
SET(b, c, d, a, 9, 21, T64);
343
/* Then perform the following additions. (That is increment each
344
of the four registers by the value it had before this block
353
md5_init(md5_state_t *pms)
355
pms->count[0] = pms->count[1] = 0;
356
pms->abcd[0] = 0x67452301;
357
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
358
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
359
pms->abcd[3] = 0x10325476;
363
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
365
const md5_byte_t *p = data;
367
int offset = (pms->count[0] >> 3) & 63;
368
md5_word_t nbits = (md5_word_t)(nbytes << 3);
373
/* Update the message length. */
374
pms->count[1] += nbytes >> 29;
375
pms->count[0] += nbits;
376
if (pms->count[0] < nbits)
379
/* Process an initial partial block. */
381
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
383
memcpy(pms->buf + offset, p, copy);
384
if (offset + copy < 64)
388
md5_process(pms, pms->buf);
391
/* Process full blocks. */
392
for (; left >= 64; p += 64, left -= 64)
395
/* Process a final partial block. */
397
memcpy(pms->buf, p, left);
401
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
403
static const md5_byte_t pad[64] = {
404
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
405
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
406
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
407
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
412
/* Save the length before padding. */
413
for (i = 0; i < 8; ++i)
414
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
415
/* Pad to 56 bytes mod 64. */
416
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
417
/* Append the length. */
418
md5_append(pms, data, 8);
419
for (i = 0; i < 16; ++i)
420
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
424
//----------------------------------------------------------------------------
425
// SHA1 - from a public domain implementation by Steve Reid (steve@edmweb.com)
426
//----------------------------------------------------------------------------
428
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
429
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15]^block->l[(i+2)&15]^block->l[i&15],1))
431
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
432
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
433
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
434
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
435
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
436
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
442
unsigned char buffer[64];
450
class SHA1Context : public QCA_HashContext
453
SHA1_CONTEXT _context;
461
QCA_HashContext *clone()
463
return new SHA1Context(*this);
468
sha1_init(&_context);
471
void update(const char *in, unsigned int len)
473
sha1_update(&_context, (unsigned char *)in, (unsigned int)len);
476
void final(QByteArray *out)
479
sha1_final((unsigned char *)b.data(), &_context);
483
unsigned long blk0(Q_UINT32 i)
488
return (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) | (rol(block->l[i],8)&0x00FF00FF));
491
// Hash a single 512-bit block. This is the core of the algorithm.
492
void transform(Q_UINT32 state[5], unsigned char buffer[64])
494
Q_UINT32 a, b, c, d, e;
496
block = (CHAR64LONG16*)buffer;
498
// Copy context->state[] to working vars
505
// 4 rounds of 20 operations each. Loop unrolled.
506
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
507
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
508
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
509
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
510
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
511
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
512
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
513
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
514
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
515
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
516
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
517
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
518
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
519
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
520
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
521
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
522
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
523
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
524
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
525
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
527
// Add the working vars back into context.state[]
535
a = b = c = d = e = 0;
538
// SHA1Init - Initialize new context
539
void sha1_init(SHA1_CONTEXT* context)
541
// SHA1 initialization constants
542
context->state[0] = 0x67452301;
543
context->state[1] = 0xEFCDAB89;
544
context->state[2] = 0x98BADCFE;
545
context->state[3] = 0x10325476;
546
context->state[4] = 0xC3D2E1F0;
547
context->count[0] = context->count[1] = 0;
550
// Run your data through this
551
void sha1_update(SHA1_CONTEXT* context, unsigned char* data, Q_UINT32 len)
555
j = (context->count[0] >> 3) & 63;
556
if((context->count[0] += len << 3) < (len << 3))
559
context->count[1] += (len >> 29);
562
memcpy(&context->buffer[j], data, (i = 64-j));
563
transform(context->state, context->buffer);
564
for ( ; i + 63 < len; i += 64) {
565
transform(context->state, &data[i]);
570
memcpy(&context->buffer[j], &data[i], len - i);
573
// Add padding and return the message digest
574
void sha1_final(unsigned char digest[20], SHA1_CONTEXT* context)
577
unsigned char finalcount[8];
579
for (i = 0; i < 8; i++) {
580
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
581
>> ((3-(i & 3)) * 8) ) & 255); // Endian independent
583
sha1_update(context, (unsigned char *)"\200", 1);
584
while ((context->count[0] & 504) != 448) {
585
sha1_update(context, (unsigned char *)"\0", 1);
587
sha1_update(context, finalcount, 8); // Should cause a transform()
588
for (i = 0; i < 20; i++) {
589
digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
594
memset(context->buffer, 0, 64);
595
memset(context->state, 0, 20);
596
memset(context->count, 0, 8);
597
memset(&finalcount, 0, 8);
601
class MD5Context : public QCA_HashContext
609
QCA_HashContext *clone()
611
return new MD5Context(*this);
619
void update(const char *in, unsigned int len)
621
md5_append(&md5, (const md5_byte_t *)in, len);
624
void final(QByteArray *out)
627
md5_finish(&md5, (md5_byte_t *)b.data());
634
class HashProvider : public QCAProvider
645
int qcaVersion() const
647
return QCA_PLUGIN_VERSION;
650
int capabilities() const
652
return (QCA::CAP_SHA1 | QCA::CAP_MD5);
655
void *context(int cap)
657
if(cap == QCA::CAP_SHA1)
658
return new SHA1Context;
659
if(cap == QCA::CAP_MD5)
660
return new MD5Context;
665
QCAProvider *createProviderHash()
667
return (new HashProvider);