1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd: (C) 2002-2008 InspIRCd Development Team
6 * See: http://www.inspircd.org/wiki/index.php/Credits
8 * This program is free but copyrighted software; see
9 * the file COPYING for details.
11 * ---------------------------------------------------
16 * AUTHOR: Antoon Bosselaers, ESAT-COSIC
20 * Copyright (c) Katholieke Universiteit Leuven
21 * 1996, All Rights Reserved
23 * Conditions for use of the RIPEMD-160 Software
25 * The RIPEMD-160 software is freely available for use under the terms and
26 * conditions described hereunder, which shall be deemed to be accepted by
27 * any user of the software and applicable on any use of the software:
29 * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
30 * all purposes be considered the owner of the RIPEMD-160 software and of
31 * all copyright, trade secret, patent or other intellectual property
33 * 2. The RIPEMD-160 software is provided on an "as is" basis without
34 * warranty of any sort, express or implied. K.U.Leuven makes no
35 * representation that the use of the software will not infringe any
36 * patent or proprietary right of third parties. User will indemnify
37 * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
38 * which may arise as a result of its use of the software. In no
39 * circumstances K.U.Leuven R&D will be held liable for any deficiency,
40 * fault or other mishappening with regard to the use or performance of
42 * 3. User agrees to give due credit to K.U.Leuven in scientific publications
43 * or communications in relation with the use of the RIPEMD-160 software
44 * as follows: RIPEMD-160 software written by Antoon Bosselaers,
45 * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
50 /* $ModDesc: Allows for RIPEMD-160 encrypted oper passwords */
51 /* $ModDep: m_hash.h */
53 /* macro definitions */
64 typedef unsigned char byte;
65 typedef unsigned int dword;
68 typedef uint32_t dword;
71 /* collect four bytes into one word: */
72 #define BYTES_TO_DWORD(strptr) \
73 (((dword) *((strptr)+3) << 24) | \
74 ((dword) *((strptr)+2) << 16) | \
75 ((dword) *((strptr)+1) << 8) | \
78 /* ROL(x, n) cyclically rotates x over n bits to the left */
79 /* x must be of an unsigned 32 bits type and 0 <= n < 32. */
80 #define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
82 /* the five basic functions F(), G() and H() */
83 #define F(x, y, z) ((x) ^ (y) ^ (z))
84 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
85 #define H(x, y, z) (((x) | ~(y)) ^ (z))
86 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
87 #define J(x, y, z) ((x) ^ ((y) | ~(z)))
89 /* the ten basic operations FF() through III() */
91 #define FF(a, b, c, d, e, x, s) {\
92 (a) += F((b), (c), (d)) + (x);\
93 (a) = ROL((a), (s)) + (e);\
97 #define GG(a, b, c, d, e, x, s) {\
98 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
99 (a) = ROL((a), (s)) + (e);\
103 #define HH(a, b, c, d, e, x, s) {\
104 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
105 (a) = ROL((a), (s)) + (e);\
109 #define II(a, b, c, d, e, x, s) {\
110 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
111 (a) = ROL((a), (s)) + (e);\
115 #define JJ(a, b, c, d, e, x, s) {\
116 (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
117 (a) = ROL((a), (s)) + (e);\
121 #define FFF(a, b, c, d, e, x, s) {\
122 (a) += F((b), (c), (d)) + (x);\
123 (a) = ROL((a), (s)) + (e);\
127 #define GGG(a, b, c, d, e, x, s) {\
128 (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
129 (a) = ROL((a), (s)) + (e);\
133 #define HHH(a, b, c, d, e, x, s) {\
134 (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
135 (a) = ROL((a), (s)) + (e);\
139 #define III(a, b, c, d, e, x, s) {\
140 (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
141 (a) = ROL((a), (s)) + (e);\
145 #define JJJ(a, b, c, d, e, x, s) {\
146 (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
147 (a) = ROL((a), (s)) + (e);\
152 class ModuleRIPEMD160 : public Module
155 void MDinit(dword *MDbuf, unsigned int* key)
159 ServerInstance->Logs->Log("m_ripemd160.so", DEBUG, "initialize with custom mdbuf");
168 ServerInstance->Logs->Log("m_ripemd160.so", DEBUG, "initialize with default mdbuf");
169 MDbuf[0] = 0x67452301UL;
170 MDbuf[1] = 0xefcdab89UL;
171 MDbuf[2] = 0x98badcfeUL;
172 MDbuf[3] = 0x10325476UL;
173 MDbuf[4] = 0xc3d2e1f0UL;
179 void compress(dword *MDbuf, dword *X)
181 dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
182 dd = MDbuf[3], ee = MDbuf[4];
183 dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
184 ddd = MDbuf[3], eee = MDbuf[4];
187 FF(aa, bb, cc, dd, ee, X[ 0], 11);
188 FF(ee, aa, bb, cc, dd, X[ 1], 14);
189 FF(dd, ee, aa, bb, cc, X[ 2], 15);
190 FF(cc, dd, ee, aa, bb, X[ 3], 12);
191 FF(bb, cc, dd, ee, aa, X[ 4], 5);
192 FF(aa, bb, cc, dd, ee, X[ 5], 8);
193 FF(ee, aa, bb, cc, dd, X[ 6], 7);
194 FF(dd, ee, aa, bb, cc, X[ 7], 9);
195 FF(cc, dd, ee, aa, bb, X[ 8], 11);
196 FF(bb, cc, dd, ee, aa, X[ 9], 13);
197 FF(aa, bb, cc, dd, ee, X[10], 14);
198 FF(ee, aa, bb, cc, dd, X[11], 15);
199 FF(dd, ee, aa, bb, cc, X[12], 6);
200 FF(cc, dd, ee, aa, bb, X[13], 7);
201 FF(bb, cc, dd, ee, aa, X[14], 9);
202 FF(aa, bb, cc, dd, ee, X[15], 8);
205 GG(ee, aa, bb, cc, dd, X[ 7], 7);
206 GG(dd, ee, aa, bb, cc, X[ 4], 6);
207 GG(cc, dd, ee, aa, bb, X[13], 8);
208 GG(bb, cc, dd, ee, aa, X[ 1], 13);
209 GG(aa, bb, cc, dd, ee, X[10], 11);
210 GG(ee, aa, bb, cc, dd, X[ 6], 9);
211 GG(dd, ee, aa, bb, cc, X[15], 7);
212 GG(cc, dd, ee, aa, bb, X[ 3], 15);
213 GG(bb, cc, dd, ee, aa, X[12], 7);
214 GG(aa, bb, cc, dd, ee, X[ 0], 12);
215 GG(ee, aa, bb, cc, dd, X[ 9], 15);
216 GG(dd, ee, aa, bb, cc, X[ 5], 9);
217 GG(cc, dd, ee, aa, bb, X[ 2], 11);
218 GG(bb, cc, dd, ee, aa, X[14], 7);
219 GG(aa, bb, cc, dd, ee, X[11], 13);
220 GG(ee, aa, bb, cc, dd, X[ 8], 12);
223 HH(dd, ee, aa, bb, cc, X[ 3], 11);
224 HH(cc, dd, ee, aa, bb, X[10], 13);
225 HH(bb, cc, dd, ee, aa, X[14], 6);
226 HH(aa, bb, cc, dd, ee, X[ 4], 7);
227 HH(ee, aa, bb, cc, dd, X[ 9], 14);
228 HH(dd, ee, aa, bb, cc, X[15], 9);
229 HH(cc, dd, ee, aa, bb, X[ 8], 13);
230 HH(bb, cc, dd, ee, aa, X[ 1], 15);
231 HH(aa, bb, cc, dd, ee, X[ 2], 14);
232 HH(ee, aa, bb, cc, dd, X[ 7], 8);
233 HH(dd, ee, aa, bb, cc, X[ 0], 13);
234 HH(cc, dd, ee, aa, bb, X[ 6], 6);
235 HH(bb, cc, dd, ee, aa, X[13], 5);
236 HH(aa, bb, cc, dd, ee, X[11], 12);
237 HH(ee, aa, bb, cc, dd, X[ 5], 7);
238 HH(dd, ee, aa, bb, cc, X[12], 5);
241 II(cc, dd, ee, aa, bb, X[ 1], 11);
242 II(bb, cc, dd, ee, aa, X[ 9], 12);
243 II(aa, bb, cc, dd, ee, X[11], 14);
244 II(ee, aa, bb, cc, dd, X[10], 15);
245 II(dd, ee, aa, bb, cc, X[ 0], 14);
246 II(cc, dd, ee, aa, bb, X[ 8], 15);
247 II(bb, cc, dd, ee, aa, X[12], 9);
248 II(aa, bb, cc, dd, ee, X[ 4], 8);
249 II(ee, aa, bb, cc, dd, X[13], 9);
250 II(dd, ee, aa, bb, cc, X[ 3], 14);
251 II(cc, dd, ee, aa, bb, X[ 7], 5);
252 II(bb, cc, dd, ee, aa, X[15], 6);
253 II(aa, bb, cc, dd, ee, X[14], 8);
254 II(ee, aa, bb, cc, dd, X[ 5], 6);
255 II(dd, ee, aa, bb, cc, X[ 6], 5);
256 II(cc, dd, ee, aa, bb, X[ 2], 12);
259 JJ(bb, cc, dd, ee, aa, X[ 4], 9);
260 JJ(aa, bb, cc, dd, ee, X[ 0], 15);
261 JJ(ee, aa, bb, cc, dd, X[ 5], 5);
262 JJ(dd, ee, aa, bb, cc, X[ 9], 11);
263 JJ(cc, dd, ee, aa, bb, X[ 7], 6);
264 JJ(bb, cc, dd, ee, aa, X[12], 8);
265 JJ(aa, bb, cc, dd, ee, X[ 2], 13);
266 JJ(ee, aa, bb, cc, dd, X[10], 12);
267 JJ(dd, ee, aa, bb, cc, X[14], 5);
268 JJ(cc, dd, ee, aa, bb, X[ 1], 12);
269 JJ(bb, cc, dd, ee, aa, X[ 3], 13);
270 JJ(aa, bb, cc, dd, ee, X[ 8], 14);
271 JJ(ee, aa, bb, cc, dd, X[11], 11);
272 JJ(dd, ee, aa, bb, cc, X[ 6], 8);
273 JJ(cc, dd, ee, aa, bb, X[15], 5);
274 JJ(bb, cc, dd, ee, aa, X[13], 6);
276 /* parallel round 1 */
277 JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
278 JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
279 JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
280 JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
281 JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
282 JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
283 JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
284 JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
285 JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
286 JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
287 JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
288 JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
289 JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
290 JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
291 JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
292 JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
294 /* parallel round 2 */
295 III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
296 III(ddd, eee, aaa, bbb, ccc, X[11], 13);
297 III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
298 III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
299 III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
300 III(eee, aaa, bbb, ccc, ddd, X[13], 8);
301 III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
302 III(ccc, ddd, eee, aaa, bbb, X[10], 11);
303 III(bbb, ccc, ddd, eee, aaa, X[14], 7);
304 III(aaa, bbb, ccc, ddd, eee, X[15], 7);
305 III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
306 III(ddd, eee, aaa, bbb, ccc, X[12], 7);
307 III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
308 III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
309 III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
310 III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
312 /* parallel round 3 */
313 HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
314 HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
315 HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
316 HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
317 HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
318 HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
319 HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
320 HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
321 HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
322 HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
323 HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
324 HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
325 HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
326 HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
327 HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
328 HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
330 /* parallel round 4 */
331 GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
332 GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
333 GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
334 GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
335 GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
336 GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
337 GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
338 GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
339 GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
340 GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
341 GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
342 GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
343 GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
344 GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
345 GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
346 GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
348 /* parallel round 5 */
349 FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
350 FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
351 FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
352 FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
353 FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
354 FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
355 FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
356 FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
357 FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
358 FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
359 FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
360 FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
361 FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
362 FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
363 FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
364 FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
366 /* combine results */
367 ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
368 MDbuf[1] = MDbuf[2] + dd + eee;
369 MDbuf[2] = MDbuf[3] + ee + aaa;
370 MDbuf[3] = MDbuf[4] + aa + bbb;
371 MDbuf[4] = MDbuf[0] + bb + ccc;
377 void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)
379 unsigned int i; /* counter */
380 dword X[16]; /* message words */
382 memset(X, 0, 16*sizeof(dword));
384 /* put bytes from strptr into X */
385 for (i=0; i<(lswlen&63); i++) {
386 /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
387 X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
390 /* append the bit m_n == 1 */
391 X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
393 if ((lswlen & 63) > 55) {
394 /* length goes to next block */
396 memset(X, 0, 16*sizeof(dword));
399 /* append length in bits*/
401 X[15] = (lswlen >> 29) | (mswlen << 3);
407 byte *RMD(byte *message, dword length, unsigned int* key)
409 ServerInstance->Logs->Log("m_ripemd160", DEBUG, "RMD: '%s' length=%u", (const char*)message, length);
410 dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */
411 static byte hashcode[RMDsize/8]; /* for final hash-value */
412 dword X[16]; /* current 16-word chunk */
413 unsigned int i; /* counter */
414 dword nbytes; /* # of bytes not yet processed */
419 /* process message in 16-word chunks */
420 for (nbytes=length; nbytes > 63; nbytes-=64) {
421 for (i=0; i<16; i++) {
422 X[i] = BYTES_TO_DWORD(message);
426 } /* length mod 64 bytes left */
428 MDfinish(MDbuf, message, length, 0);
430 for (i=0; i<RMDsize/8; i+=4) {
431 hashcode[i] = MDbuf[i>>2]; /* implicit cast to byte */
432 hashcode[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */
433 hashcode[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */
434 hashcode[i+3] = (MDbuf[i>>2] >> 24);
437 return (byte *)hashcode;
440 unsigned int* currkey;
445 ModuleRIPEMD160(InspIRCd* Me) : Module(Me), currkey(NULL), chars("0123456789abcdef")
447 ServerInstance->Modules->PublishInterface("HashRequest", this);
448 Implementation eventlist[] = { I_OnRequest };
449 ServerInstance->Modules->Attach(eventlist, this, 1);
452 virtual ~ModuleRIPEMD160()
454 ServerInstance->Modules->UnpublishInterface("HashRequest", this);
458 virtual const char* OnRequest(Request* request)
460 HashRequest* SHA = (HashRequest*)request;
461 if (strcmp("KEY", request->GetId()) == 0)
463 this->currkey = (unsigned int*)SHA->GetKeyData();
465 else if (strcmp("HEX", request->GetId()) == 0)
467 this->chars = SHA->GetOutputs();
469 else if (strcmp("SUM", request->GetId()) == 0)
471 static char output[MAXBUF];
472 unsigned char* data = (unsigned char*)RMD((byte *)SHA->GetHashData().data(),SHA->GetHashData().length(), currkey);
474 for (int i = 0; i < RMDsize / 8; i++)
476 output[j++] = chars[data[i] / 16];
477 output[j++] = chars[data[i] % 16];
478 ServerInstance->Logs->Log("m_ripemd160", DEBUG, "Hash: %02x", data[i]);
483 else if (strcmp("NAME", request->GetId()) == 0)
487 else if (strcmp("RESET", request->GetId()) == 0)
489 this->chars = "0123456789abcdef";
490 this->currkey = NULL;
495 virtual Version GetVersion()
497 return Version(1, 2, 0, 1, VF_VENDOR|VF_SERVICEPROVIDER, API_VERSION);
502 MODULE_INIT(ModuleRIPEMD160)