aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-01-13 14:42:13 +0000
committerChristian Grothoff <christian@grothoff.org>2010-01-13 14:42:13 +0000
commit7e93648c27b64f01990b7f4ff10ce48d2b397c39 (patch)
tree92b6e5a4771e16471fedfb7f26213e5d6f3d92c7
parent2579fff926e019060d22f2adeb78b3bc7fe50f51 (diff)
downloadlibextractor-7e93648c27b64f01990b7f4ff10ce48d2b397c39.tar.gz
libextractor-7e93648c27b64f01990b7f4ff10ce48d2b397c39.zip
bye bye hash
-rw-r--r--src/plugins/hash/Makefile.am23
-rw-r--r--src/plugins/hash/README2
-rw-r--r--src/plugins/hash/md5extractor.c455
-rw-r--r--src/plugins/hash/rmd160extractor.c625
-rw-r--r--src/plugins/hash/sha1extractor.c475
5 files changed, 0 insertions, 1580 deletions
diff --git a/src/plugins/hash/Makefile.am b/src/plugins/hash/Makefile.am
deleted file mode 100644
index b7f28e5..0000000
--- a/src/plugins/hash/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
1include ../Makefile-plugins.am
2
3SUBDIRS = .
4
5plugin_LTLIBRARIES = \
6 libextractor_hash_md5.la \
7 libextractor_hash_sha1.la \
8 libextractor_hash_rmd160.la
9
10libextractor_hash_md5_la_SOURCES = \
11 md5extractor.c
12libextractor_hash_md5_la_LDFLAGS = \
13 $(PLUGINFLAGS) $(retaincommand)
14
15libextractor_hash_sha1_la_SOURCES = \
16 sha1extractor.c
17libextractor_hash_sha1_la_LDFLAGS = \
18 $(PLUGINFLAGS) $(retaincommand)
19
20libextractor_hash_rmd160_la_SOURCES = \
21 rmd160extractor.c
22libextractor_hash_rmd160_la_LDFLAGS = \
23 $(PLUGINFLAGS) $(retaincommand)
diff --git a/src/plugins/hash/README b/src/plugins/hash/README
deleted file mode 100644
index 97310a9..0000000
--- a/src/plugins/hash/README
+++ /dev/null
@@ -1,2 +0,0 @@
1This code is based on code from md5sum (GNU coreutils / textutils) and
2http://rmd160.slashusr.org/ (both GPL).
diff --git a/src/plugins/hash/md5extractor.c b/src/plugins/hash/md5extractor.c
deleted file mode 100644
index f96beac..0000000
--- a/src/plugins/hash/md5extractor.c
+++ /dev/null
@@ -1,455 +0,0 @@
1/*
2 This file is part of libextractor.
3 (C) 2004, 2005 Vidyut Samanta and Christian Grothoff
4
5 Copyright (C) 1995, 1996, 1999, 2000, 2003 Free Software Foundation, Inc.
6 NOTE: The canonical source of the MD5 code from this file is maintained
7 with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
8
9 libextractor is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 2, or (at your
12 option) any later version.
13
14 libextractor is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with libextractor; see the file COPYING. If not, write to the
21 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
23
24#include "platform.h"
25#include "extractor.h"
26#include <stdio.h>
27#include <limits.h>
28
29#ifdef _LIBC
30#include <stdint.h>
31typedef uint32_t md5_uint32;
32typedef uintptr_t md5_uintptr;
33#else
34# define UINT_MAX_32_BITS 4294967295U
35
36# if UINT_MAX == UINT_MAX_32_BITS
37typedef unsigned int md5_uint32;
38# else
39# if USHRT_MAX == UINT_MAX_32_BITS
40typedef unsigned short md5_uint32;
41# else
42# if ULONG_MAX == UINT_MAX_32_BITS
43typedef unsigned long md5_uint32;
44# else
45 /* The following line is intended to evoke an error.
46 Using #error is not portable enough. */
47"Cannot determine unsigned 32-bit data type."
48# endif
49# endif
50# endif
51/* We have to make a guess about the integer type equivalent in size
52 to pointers which should always be correct. */
53typedef unsigned long int md5_uintptr;
54#endif
55
56/* Structure to save state of computation between the single steps. */
57struct md5_ctx
58{
59 md5_uint32 A;
60 md5_uint32 B;
61 md5_uint32 C;
62 md5_uint32 D;
63
64 md5_uint32 total[2];
65 md5_uint32 buflen;
66 char buffer[128];
67};
68
69#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
70
71#if __BYTE_ORDER == __BIG_ENDIAN
72#define WORDS_BIGENDIAN 1
73#endif
74
75#ifdef WORDS_BIGENDIAN
76# define SWAP(n) \
77 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
78#else
79# define SWAP(n) (n)
80#endif
81
82#define BLOCKSIZE 4096
83/* Ensure that BLOCKSIZE is a multiple of 64. */
84#if BLOCKSIZE % 64 != 0
85#error "invalid BLOCKSIZE"
86#endif
87
88/* This array contains the bytes used to pad the buffer to the next
89 64-byte boundary. (RFC 1321, 3.1: Step 1) */
90static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
91
92
93
94
95/* These are the four functions used in the four steps of the MD5 algorithm
96 and defined in the RFC 1321. The first function is a little bit optimized
97 (as found in Colin Plumbs public domain implementation). */
98/* #define FF(b, c, d) ((b & c) | (~b & d)) */
99#define FF(b, c, d) (d ^ (b & (c ^ d)))
100#define FG(b, c, d) FF (d, b, c)
101#define FH(b, c, d) (b ^ c ^ d)
102#define FI(b, c, d) (c ^ (b | ~d))
103
104/* Process LEN bytes of BUFFER, accumulating context into CTX.
105 It is assumed that LEN % 64 == 0. */
106
107static void
108md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
109{
110 md5_uint32 correct_words[16];
111 const md5_uint32 *words = buffer;
112 size_t nwords = len / sizeof (md5_uint32);
113 const md5_uint32 *endp = words + nwords;
114 md5_uint32 A = ctx->A;
115 md5_uint32 B = ctx->B;
116 md5_uint32 C = ctx->C;
117 md5_uint32 D = ctx->D;
118
119 /* First increment the byte count. RFC 1321 specifies the possible
120 length of the file up to 2^64 bits. Here we only compute the
121 number of bytes. Do a double word increment. */
122 ctx->total[0] += len;
123 if (ctx->total[0] < len)
124 ++ctx->total[1];
125
126 /* Process all bytes in the buffer with 64 bytes in each round of
127 the loop. */
128 while (words < endp)
129 {
130 md5_uint32 *cwp = correct_words;
131 md5_uint32 A_save = A;
132 md5_uint32 B_save = B;
133 md5_uint32 C_save = C;
134 md5_uint32 D_save = D;
135
136 /* First round: using the given function, the context and a constant
137 the next context is computed. Because the algorithms processing
138 unit is a 32-bit word and it is determined to work on words in
139 little endian byte order we perhaps have to change the byte order
140 before the computation. To reduce the work for the next steps
141 we store the swapped words in the array CORRECT_WORDS. */
142
143#define OP(a, b, c, d, s, T) \
144 do \
145 { \
146 a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
147 ++words; \
148 a = rol (a, s); \
149 a += b; \
150 } \
151 while (0)
152
153 /* Before we start, one word to the strange constants.
154 They are defined in RFC 1321 as
155
156 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or
157 perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
158 */
159
160 /* Round 1. */
161 OP (A, B, C, D, 7, 0xd76aa478);
162 OP (D, A, B, C, 12, 0xe8c7b756);
163 OP (C, D, A, B, 17, 0x242070db);
164 OP (B, C, D, A, 22, 0xc1bdceee);
165 OP (A, B, C, D, 7, 0xf57c0faf);
166 OP (D, A, B, C, 12, 0x4787c62a);
167 OP (C, D, A, B, 17, 0xa8304613);
168 OP (B, C, D, A, 22, 0xfd469501);
169 OP (A, B, C, D, 7, 0x698098d8);
170 OP (D, A, B, C, 12, 0x8b44f7af);
171 OP (C, D, A, B, 17, 0xffff5bb1);
172 OP (B, C, D, A, 22, 0x895cd7be);
173 OP (A, B, C, D, 7, 0x6b901122);
174 OP (D, A, B, C, 12, 0xfd987193);
175 OP (C, D, A, B, 17, 0xa679438e);
176 OP (B, C, D, A, 22, 0x49b40821);
177
178 /* For the second to fourth round we have the possibly swapped words
179 in CORRECT_WORDS. Redefine the macro to take an additional first
180 argument specifying the function to use. */
181#undef OP
182#define OP(f, a, b, c, d, k, s, T) \
183 do \
184 { \
185 a += f (b, c, d) + correct_words[k] + T; \
186 a = rol (a, s); \
187 a += b; \
188 } \
189 while (0)
190
191 /* Round 2. */
192 OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
193 OP (FG, D, A, B, C, 6, 9, 0xc040b340);
194 OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
195 OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
196 OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
197 OP (FG, D, A, B, C, 10, 9, 0x02441453);
198 OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
199 OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
200 OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
201 OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
202 OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
203 OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
204 OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
205 OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
206 OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
207 OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
208
209 /* Round 3. */
210 OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
211 OP (FH, D, A, B, C, 8, 11, 0x8771f681);
212 OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
213 OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
214 OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
215 OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
216 OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
217 OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
218 OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
219 OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
220 OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
221 OP (FH, B, C, D, A, 6, 23, 0x04881d05);
222 OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
223 OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
224 OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
225 OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
226
227 /* Round 4. */
228 OP (FI, A, B, C, D, 0, 6, 0xf4292244);
229 OP (FI, D, A, B, C, 7, 10, 0x432aff97);
230 OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
231 OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
232 OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
233 OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
234 OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
235 OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
236 OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
237 OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
238 OP (FI, C, D, A, B, 6, 15, 0xa3014314);
239 OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
240 OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
241 OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
242 OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
243 OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
244
245 /* Add the starting values of the context. */
246 A += A_save;
247 B += B_save;
248 C += C_save;
249 D += D_save;
250 }
251
252 /* Put checksum in context given as argument. */
253 ctx->A = A;
254 ctx->B = B;
255 ctx->C = C;
256 ctx->D = D;
257}
258
259
260static void
261md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
262{
263 /* When we already have some bits in our internal buffer concatenate
264 both inputs first. */
265 if (ctx->buflen != 0)
266 {
267 size_t left_over = ctx->buflen;
268 size_t add = 128 - left_over > len ? len : 128 - left_over;
269
270 memcpy (&ctx->buffer[left_over], buffer, add);
271 ctx->buflen += add;
272
273 if (ctx->buflen > 64)
274 {
275 md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
276
277 ctx->buflen &= 63;
278 /* The regions in the following copy operation cannot overlap. */
279 memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
280 ctx->buflen);
281 }
282
283 buffer = (const char *) buffer + add;
284 len -= add;
285 }
286
287 /* Process available complete blocks. */
288 if (len >= 64)
289 {
290#if !_STRING_ARCH_unaligned
291/* To check alignment gcc has an appropriate operator. Other
292 compilers don't. */
293# if __GNUC__ >= 2
294# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
295# else
296# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
297# endif
298 if (UNALIGNED_P (buffer))
299 while (len > 64)
300 {
301 md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
302 buffer = (const char *) buffer + 64;
303 len -= 64;
304 }
305 else
306#endif
307 {
308 md5_process_block (buffer, len & ~63, ctx);
309 buffer = (const char *) buffer + (len & ~63);
310 len &= 63;
311 }
312 }
313
314 /* Move remaining bytes in internal buffer. */
315 if (len > 0)
316 {
317 size_t left_over = ctx->buflen;
318
319 memcpy (&ctx->buffer[left_over], buffer, len);
320 left_over += len;
321 if (left_over >= 64)
322 {
323 md5_process_block (ctx->buffer, 64, ctx);
324 left_over -= 64;
325 memcpy (ctx->buffer, &ctx->buffer[64], left_over);
326 }
327 ctx->buflen = left_over;
328 }
329}
330
331
332/* Initialize structure containing state of computation.
333 (RFC 1321, 3.3: Step 3) */
334static void
335md5_init_ctx (struct md5_ctx *ctx)
336{
337 ctx->A = 0x67452301;
338 ctx->B = 0xefcdab89;
339 ctx->C = 0x98badcfe;
340 ctx->D = 0x10325476;
341
342 ctx->total[0] = ctx->total[1] = 0;
343 ctx->buflen = 0;
344}
345
346/* Put result from CTX in first 16 bytes following RESBUF. The result
347 must be in little endian byte order.
348
349 IMPORTANT: On some systems it is required that RESBUF is correctly
350 aligned for a 32 bits value. */
351static void *
352md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
353{
354 ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
355 ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
356 ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
357 ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
358
359 return resbuf;
360}
361
362/* Process the remaining bytes in the internal buffer and the usual
363 prolog according to the standard and write the result to RESBUF.
364
365 IMPORTANT: On some systems it is required that RESBUF is correctly
366 aligned for a 32 bits value. */
367static void *
368md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
369{
370 /* Take yet unprocessed bytes into account. */
371 md5_uint32 bytes = ctx->buflen;
372 size_t pad;
373
374 /* Now count remaining bytes. */
375 ctx->total[0] += bytes;
376 if (ctx->total[0] < bytes)
377 ++ctx->total[1];
378
379 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
380 memcpy (&ctx->buffer[bytes], fillbuf, pad);
381
382 /* Put the 64-bit file length in *bits* at the end of the buffer. */
383 *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
384 *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] =
385 SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
386
387 /* Process last bytes. */
388 md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
389
390 return md5_read_ctx (ctx, resbuf);
391}
392
393/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
394 result is always in little endian byte order, so that a byte-wise
395 output yields to the wanted ASCII representation of the message
396 digest. */
397static void *
398md5_buffer (const char *buffer, size_t len, void *resblock)
399{
400 struct md5_ctx ctx;
401
402 /* Initialize the computation context. */
403 md5_init_ctx (&ctx);
404
405 /* Process whole buffer but last len % 64 bytes. */
406 md5_process_bytes (buffer, len, &ctx);
407
408 /* Put result in desired memory area. */
409 return md5_finish_ctx (&ctx, resblock);
410}
411
412
413
414
415static struct EXTRACTOR_Keywords *
416addKeyword (EXTRACTOR_KeywordList * oldhead,
417 const char *phrase, EXTRACTOR_KeywordType type)
418{
419
420 EXTRACTOR_KeywordList *keyword;
421 keyword = (EXTRACTOR_KeywordList *) malloc (sizeof (EXTRACTOR_KeywordList));
422 keyword->next = oldhead;
423 keyword->keyword = strdup (phrase);
424 keyword->keywordType = type;
425 return keyword;
426}
427
428
429
430#define DIGEST_BITS 128
431#define DIGEST_HEX_BYTES (DIGEST_BITS / 4)
432#define DIGEST_BIN_BYTES (DIGEST_BITS / 8)
433#define MAX_DIGEST_BIN_BYTES DIGEST_BIN_BYTES
434
435struct EXTRACTOR_Keywords *
436libextractor_hash_md5_extract (const char *filename,
437 const char *data,
438 size_t size, struct EXTRACTOR_Keywords *prev)
439{
440 unsigned char bin_buffer[MAX_DIGEST_BIN_BYTES];
441 char hash[8 * MAX_DIGEST_BIN_BYTES];
442 char buf[16];
443 int i;
444
445 md5_buffer (data, size, bin_buffer);
446 hash[0] = '\0';
447 for (i = 0; i < DIGEST_HEX_BYTES / 2; i++)
448 {
449 snprintf (buf, 16, "%02x", bin_buffer[i]);
450 strcat (hash, buf);
451 }
452 prev = addKeyword (prev, hash, EXTRACTOR_HASH_MD5);
453
454 return prev;
455}
diff --git a/src/plugins/hash/rmd160extractor.c b/src/plugins/hash/rmd160extractor.c
deleted file mode 100644
index f0fef3d..0000000
--- a/src/plugins/hash/rmd160extractor.c
+++ /dev/null
@@ -1,625 +0,0 @@
1/*
2 This file is part of libextractor.
3 (C) 2004 Vidyut Samanta and Christian Grothoff
4 Copyright © 1999 - Philip Howard
5
6 libextractor is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2, or (at your
9 option) any later version.
10
11 libextractor is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with libextractor; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20
21 RMD code:
22 package rmd160
23 version 1.2.1
24 homepage http://phil.ipal.org/freeware/rmd160/
25
26 author Philip Howard
27 email phil@ipal.org
28 homepage http://phil.ipal.org/
29
30 */
31
32#include "platform.h"
33#include "extractor.h"
34
35#if ULONG_MAX>4294967295U
36#if UINT_MAX>4294967295U
37#if USHRT_MAX>4294967295U
38#if UCHAR_MAX>=4294967295U
39typedef unsigned char rmd160uint32;
40#else
41typedef unsigned short rmd160uint32;
42#endif /*UCHAR_MAX */
43#else
44typedef unsigned int rmd160uint32;
45#endif /*USHRT_MAX */
46#else
47typedef unsigned long rmd160uint32;
48#endif /*UINT_MAX */
49#else
50typedef unsigned long rmd160uint32;
51#endif
52
53struct rmd160_object
54{
55 rmd160uint32 data[16];
56 rmd160uint32 state[5];
57 rmd160uint32 len[2];
58 rmd160uint32 *wptr;
59 rmd160uint32 *wend;
60 unsigned int bpos;
61};
62typedef struct rmd160_object *RMD160;
63
64#define RMD160_OK 0
65#define RMD160_ERR_INVALID_ARG 1
66#define RMD160_ERR_READ 2
67
68
69#define RMD160_BUFSIZ 1024
70
71#define RMD160_INIT0 0x67452301UL
72#define RMD160_INIT1 0xefcdab89UL
73#define RMD160_INIT2 0x98badcfeUL
74#define RMD160_INIT3 0x10325476UL
75#define RMD160_INIT4 0xc3d2e1f0UL
76
77static int
78_rmd160_calc (rmd160uint32 * state, rmd160uint32 * data)
79{
80 rmd160uint32 x0, x1, x2, x3, x4;
81 rmd160uint32 y0, y1, y2, y3, y4;
82
83 x0 = y0 = state[0];
84 x1 = y1 = state[1];
85 x2 = y2 = state[2];
86 x3 = y3 = state[3];
87 x4 = y4 = state[4];
88
89
90#define RL(x,n) (((x) << (n)) | ((x) >> (32-(n))))
91
92#define F1(x,y,z) ((x) ^ (y) ^ (z))
93#define F2(x,y,z) (((x) & (y)) | (~(x) & (z)))
94#define F3(x,y,z) (((x) | ~(y)) ^ (z))
95#define F4(x,y,z) (((x) & (z)) | ((y) & ~(z)))
96#define F5(x,y,z) ((x) ^ ((y) | ~(z)))
97
98#define T1(a,b,c,d,e,x,s) { \
99 (a) += F1((b),(c),(d)) + (x); \
100 (a) = RL((a),(s)) + (e); \
101 (c) = RL((c),10);}
102#define T2(a,b,c,d,e,x,s) { \
103 (a) += F2((b),(c),(d)) + (x) + 0x5a827999UL; \
104 (a) = RL((a),(s)) + (e); \
105 (c) = RL((c),10);}
106#define T3(a,b,c,d,e,x,s) { \
107 (a) += F3((b),(c),(d)) + (x) + 0x6ed9eba1UL; \
108 (a) = RL((a),(s)) + (e); \
109 (c) = RL((c),10);}
110#define T4(a,b,c,d,e,x,s) { \
111 (a) += F4((b),(c),(d)) + (x) + 0x8f1bbcdcUL; \
112 (a) = RL((a),(s)) + (e); \
113 (c) = RL((c),10);}
114#define T5(a,b,c,d,e,x,s) { \
115 (a) += F5((b),(c),(d)) + (x) + 0xa953fd4eUL; \
116 (a) = RL((a),(s)) + (e); \
117 (c) = RL((c),10);}
118
119#define S1(a,b,c,d,e,x,s) { \
120 (a) += F1((b),(c),(d)) + (x); \
121 (a) = RL((a),(s)) + (e); \
122 (c) = RL((c),10);}
123#define S2(a,b,c,d,e,x,s) { \
124 (a) += F2((b),(c),(d)) + (x) + 0x7a6d76e9UL; \
125 (a) = RL((a),(s)) + (e); \
126 (c) = RL((c),10);}
127#define S3(a,b,c,d,e,x,s) { \
128 (a) += F3((b),(c),(d)) + (x) + 0x6d703ef3UL; \
129 (a) = RL((a),(s)) + (e); \
130 (c) = RL((c),10);}
131#define S4(a,b,c,d,e,x,s) { \
132 (a) += F4((b),(c),(d)) + (x) + 0x5c4dd124UL; \
133 (a) = RL((a),(s)) + (e); \
134 (c) = RL((c),10);}
135#define S5(a,b,c,d,e,x,s) { \
136 (a) += F5((b),(c),(d)) + (x) + 0x50a28be6UL; \
137 (a) = RL((a),(s)) + (e); \
138 (c) = RL((c),10);}
139
140 T1 (x0, x1, x2, x3, x4, data[0], 11);
141 T1 (x4, x0, x1, x2, x3, data[1], 14);
142 T1 (x3, x4, x0, x1, x2, data[2], 15);
143 T1 (x2, x3, x4, x0, x1, data[3], 12);
144 T1 (x1, x2, x3, x4, x0, data[4], 5);
145 T1 (x0, x1, x2, x3, x4, data[5], 8);
146 T1 (x4, x0, x1, x2, x3, data[6], 7);
147 T1 (x3, x4, x0, x1, x2, data[7], 9);
148 T1 (x2, x3, x4, x0, x1, data[8], 11);
149 T1 (x1, x2, x3, x4, x0, data[9], 13);
150 T1 (x0, x1, x2, x3, x4, data[10], 14);
151 T1 (x4, x0, x1, x2, x3, data[11], 15);
152 T1 (x3, x4, x0, x1, x2, data[12], 6);
153 T1 (x2, x3, x4, x0, x1, data[13], 7);
154 T1 (x1, x2, x3, x4, x0, data[14], 9);
155 T1 (x0, x1, x2, x3, x4, data[15], 8);
156
157 T2 (x4, x0, x1, x2, x3, data[7], 7);
158 T2 (x3, x4, x0, x1, x2, data[4], 6);
159 T2 (x2, x3, x4, x0, x1, data[13], 8);
160 T2 (x1, x2, x3, x4, x0, data[1], 13);
161 T2 (x0, x1, x2, x3, x4, data[10], 11);
162 T2 (x4, x0, x1, x2, x3, data[6], 9);
163 T2 (x3, x4, x0, x1, x2, data[15], 7);
164 T2 (x2, x3, x4, x0, x1, data[3], 15);
165 T2 (x1, x2, x3, x4, x0, data[12], 7);
166 T2 (x0, x1, x2, x3, x4, data[0], 12);
167 T2 (x4, x0, x1, x2, x3, data[9], 15);
168 T2 (x3, x4, x0, x1, x2, data[5], 9);
169 T2 (x2, x3, x4, x0, x1, data[2], 11);
170 T2 (x1, x2, x3, x4, x0, data[14], 7);
171 T2 (x0, x1, x2, x3, x4, data[11], 13);
172 T2 (x4, x0, x1, x2, x3, data[8], 12);
173
174 T3 (x3, x4, x0, x1, x2, data[3], 11);
175 T3 (x2, x3, x4, x0, x1, data[10], 13);
176 T3 (x1, x2, x3, x4, x0, data[14], 6);
177 T3 (x0, x1, x2, x3, x4, data[4], 7);
178 T3 (x4, x0, x1, x2, x3, data[9], 14);
179 T3 (x3, x4, x0, x1, x2, data[15], 9);
180 T3 (x2, x3, x4, x0, x1, data[8], 13);
181 T3 (x1, x2, x3, x4, x0, data[1], 15);
182 T3 (x0, x1, x2, x3, x4, data[2], 14);
183 T3 (x4, x0, x1, x2, x3, data[7], 8);
184 T3 (x3, x4, x0, x1, x2, data[0], 13);
185 T3 (x2, x3, x4, x0, x1, data[6], 6);
186 T3 (x1, x2, x3, x4, x0, data[13], 5);
187 T3 (x0, x1, x2, x3, x4, data[11], 12);
188 T3 (x4, x0, x1, x2, x3, data[5], 7);
189 T3 (x3, x4, x0, x1, x2, data[12], 5);
190
191 T4 (x2, x3, x4, x0, x1, data[1], 11);
192 T4 (x1, x2, x3, x4, x0, data[9], 12);
193 T4 (x0, x1, x2, x3, x4, data[11], 14);
194 T4 (x4, x0, x1, x2, x3, data[10], 15);
195 T4 (x3, x4, x0, x1, x2, data[0], 14);
196 T4 (x2, x3, x4, x0, x1, data[8], 15);
197 T4 (x1, x2, x3, x4, x0, data[12], 9);
198 T4 (x0, x1, x2, x3, x4, data[4], 8);
199 T4 (x4, x0, x1, x2, x3, data[13], 9);
200 T4 (x3, x4, x0, x1, x2, data[3], 14);
201 T4 (x2, x3, x4, x0, x1, data[7], 5);
202 T4 (x1, x2, x3, x4, x0, data[15], 6);
203 T4 (x0, x1, x2, x3, x4, data[14], 8);
204 T4 (x4, x0, x1, x2, x3, data[5], 6);
205 T4 (x3, x4, x0, x1, x2, data[6], 5);
206 T4 (x2, x3, x4, x0, x1, data[2], 12);
207
208 T5 (x1, x2, x3, x4, x0, data[4], 9);
209 T5 (x0, x1, x2, x3, x4, data[0], 15);
210 T5 (x4, x0, x1, x2, x3, data[5], 5);
211 T5 (x3, x4, x0, x1, x2, data[9], 11);
212 T5 (x2, x3, x4, x0, x1, data[7], 6);
213 T5 (x1, x2, x3, x4, x0, data[12], 8);
214 T5 (x0, x1, x2, x3, x4, data[2], 13);
215 T5 (x4, x0, x1, x2, x3, data[10], 12);
216 T5 (x3, x4, x0, x1, x2, data[14], 5);
217 T5 (x2, x3, x4, x0, x1, data[1], 12);
218 T5 (x1, x2, x3, x4, x0, data[3], 13);
219 T5 (x0, x1, x2, x3, x4, data[8], 14);
220 T5 (x4, x0, x1, x2, x3, data[11], 11);
221 T5 (x3, x4, x0, x1, x2, data[6], 8);
222 T5 (x2, x3, x4, x0, x1, data[15], 5);
223 T5 (x1, x2, x3, x4, x0, data[13], 6);
224
225 S5 (y0, y1, y2, y3, y4, data[5], 8);
226 S5 (y4, y0, y1, y2, y3, data[14], 9);
227 S5 (y3, y4, y0, y1, y2, data[7], 9);
228 S5 (y2, y3, y4, y0, y1, data[0], 11);
229 S5 (y1, y2, y3, y4, y0, data[9], 13);
230 S5 (y0, y1, y2, y3, y4, data[2], 15);
231 S5 (y4, y0, y1, y2, y3, data[11], 15);
232 S5 (y3, y4, y0, y1, y2, data[4], 5);
233 S5 (y2, y3, y4, y0, y1, data[13], 7);
234 S5 (y1, y2, y3, y4, y0, data[6], 7);
235 S5 (y0, y1, y2, y3, y4, data[15], 8);
236 S5 (y4, y0, y1, y2, y3, data[8], 11);
237 S5 (y3, y4, y0, y1, y2, data[1], 14);
238 S5 (y2, y3, y4, y0, y1, data[10], 14);
239 S5 (y1, y2, y3, y4, y0, data[3], 12);
240 S5 (y0, y1, y2, y3, y4, data[12], 6);
241
242 S4 (y4, y0, y1, y2, y3, data[6], 9);
243 S4 (y3, y4, y0, y1, y2, data[11], 13);
244 S4 (y2, y3, y4, y0, y1, data[3], 15);
245 S4 (y1, y2, y3, y4, y0, data[7], 7);
246 S4 (y0, y1, y2, y3, y4, data[0], 12);
247 S4 (y4, y0, y1, y2, y3, data[13], 8);
248 S4 (y3, y4, y0, y1, y2, data[5], 9);
249 S4 (y2, y3, y4, y0, y1, data[10], 11);
250 S4 (y1, y2, y3, y4, y0, data[14], 7);
251 S4 (y0, y1, y2, y3, y4, data[15], 7);
252 S4 (y4, y0, y1, y2, y3, data[8], 12);
253 S4 (y3, y4, y0, y1, y2, data[12], 7);
254 S4 (y2, y3, y4, y0, y1, data[4], 6);
255 S4 (y1, y2, y3, y4, y0, data[9], 15);
256 S4 (y0, y1, y2, y3, y4, data[1], 13);
257 S4 (y4, y0, y1, y2, y3, data[2], 11);
258
259 S3 (y3, y4, y0, y1, y2, data[15], 9);
260 S3 (y2, y3, y4, y0, y1, data[5], 7);
261 S3 (y1, y2, y3, y4, y0, data[1], 15);
262 S3 (y0, y1, y2, y3, y4, data[3], 11);
263 S3 (y4, y0, y1, y2, y3, data[7], 8);
264 S3 (y3, y4, y0, y1, y2, data[14], 6);
265 S3 (y2, y3, y4, y0, y1, data[6], 6);
266 S3 (y1, y2, y3, y4, y0, data[9], 14);
267 S3 (y0, y1, y2, y3, y4, data[11], 12);
268 S3 (y4, y0, y1, y2, y3, data[8], 13);
269 S3 (y3, y4, y0, y1, y2, data[12], 5);
270 S3 (y2, y3, y4, y0, y1, data[2], 14);
271 S3 (y1, y2, y3, y4, y0, data[10], 13);
272 S3 (y0, y1, y2, y3, y4, data[0], 13);
273 S3 (y4, y0, y1, y2, y3, data[4], 7);
274 S3 (y3, y4, y0, y1, y2, data[13], 5);
275
276 S2 (y2, y3, y4, y0, y1, data[8], 15);
277 S2 (y1, y2, y3, y4, y0, data[6], 5);
278 S2 (y0, y1, y2, y3, y4, data[4], 8);
279 S2 (y4, y0, y1, y2, y3, data[1], 11);
280 S2 (y3, y4, y0, y1, y2, data[3], 14);
281 S2 (y2, y3, y4, y0, y1, data[11], 14);
282 S2 (y1, y2, y3, y4, y0, data[15], 6);
283 S2 (y0, y1, y2, y3, y4, data[0], 14);
284 S2 (y4, y0, y1, y2, y3, data[5], 6);
285 S2 (y3, y4, y0, y1, y2, data[12], 9);
286 S2 (y2, y3, y4, y0, y1, data[2], 12);
287 S2 (y1, y2, y3, y4, y0, data[13], 9);
288 S2 (y0, y1, y2, y3, y4, data[9], 12);
289 S2 (y4, y0, y1, y2, y3, data[7], 5);
290 S2 (y3, y4, y0, y1, y2, data[10], 15);
291 S2 (y2, y3, y4, y0, y1, data[14], 8);
292
293 S1 (y1, y2, y3, y4, y0, data[12], 8);
294 S1 (y0, y1, y2, y3, y4, data[15], 5);
295 S1 (y4, y0, y1, y2, y3, data[10], 12);
296 S1 (y3, y4, y0, y1, y2, data[4], 9);
297 S1 (y2, y3, y4, y0, y1, data[1], 12);
298 S1 (y1, y2, y3, y4, y0, data[5], 5);
299 S1 (y0, y1, y2, y3, y4, data[8], 14);
300 S1 (y4, y0, y1, y2, y3, data[7], 6);
301 S1 (y3, y4, y0, y1, y2, data[6], 8);
302 S1 (y2, y3, y4, y0, y1, data[2], 13);
303 S1 (y1, y2, y3, y4, y0, data[13], 6);
304 S1 (y0, y1, y2, y3, y4, data[14], 5);
305 S1 (y4, y0, y1, y2, y3, data[0], 15);
306 S1 (y3, y4, y0, y1, y2, data[3], 13);
307 S1 (y2, y3, y4, y0, y1, data[9], 11);
308 S1 (y1, y2, y3, y4, y0, data[11], 11);
309
310 y3 += x2 + state[1];
311 state[1] = state[2] + x3 + y4;
312 state[2] = state[3] + x4 + y0;
313 state[3] = state[4] + x0 + y1;
314 state[4] = state[0] + x1 + y2;
315 state[0] = y3;
316
317 return RMD160_OK;
318}
319
320
321static int
322rmd160_append (RMD160 arg_obj, size_t arg_len, const unsigned char *arg_data)
323{
324 size_t alen;
325
326 rmd160uint32 *wend;
327 rmd160uint32 *wptr;
328
329 unsigned int bpos;
330
331
332 if (!arg_obj)
333 return RMD160_ERR_INVALID_ARG;
334
335 if (arg_len == 0)
336 return RMD160_OK;
337 if (!arg_data)
338 return RMD160_ERR_INVALID_ARG;
339
340 alen = arg_len;
341 wend = arg_obj->wend;
342 wptr = arg_obj->wptr;
343 bpos = arg_obj->bpos;
344
345 if (bpos)
346 {
347 register rmd160uint32 w;
348 w = *wptr;
349 if (bpos == 1)
350 {
351 w |= ((rmd160uint32) (0xff & *(arg_data++))) << 8;
352 --alen;
353 ++bpos;
354 }
355 if (bpos == 2 && alen)
356 {
357 w |= ((rmd160uint32) (0xff & *(arg_data++))) << 16;
358 --alen;
359 ++bpos;
360 }
361 if (bpos == 3 && alen)
362 {
363 w |= ((rmd160uint32) (0xff & *(arg_data++))) << 24;
364 --alen;
365 ++bpos;
366 }
367 *wptr = w;
368 if (!alen)
369 {
370 arg_obj->wptr = wptr;
371 arg_obj->bpos = bpos;
372 if ((arg_obj->len[0] = arg_len + arg_obj->len[0]) < arg_len)
373 {
374 arg_obj->len[1]++;
375 }
376 return RMD160_OK;
377 }
378 bpos = 0;
379 ++wptr;
380 }
381
382 for (;;)
383 {
384 while (alen >= 4 && wptr < wend)
385 {
386
387#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
388 *wptr = *(const rmd160uint32 *) arg_data;
389#else
390 *wptr =
391 ((rmd160uint32) (0xff & arg_data[0])) |
392 ((rmd160uint32) (0xff & arg_data[1])) << 8 |
393 ((rmd160uint32) (0xff & arg_data[2])) << 16 |
394 ((rmd160uint32) (0xff & arg_data[3])) << 24;
395#endif
396
397 ++wptr;
398 arg_data += 4;
399 alen -= 4;
400 }
401 if (wptr < wend)
402 break;
403 _rmd160_calc (arg_obj->state, arg_obj->data);
404 wptr = arg_obj->data;
405 }
406
407 if (alen)
408 {
409 rmd160uint32 w;
410 w = ((rmd160uint32) (0xff & *(arg_data++)));
411 if (alen >= 2)
412 {
413 w |= ((rmd160uint32) (0xff & *(arg_data++))) << 8;
414 if (alen >= 3)
415 {
416 w |= ((rmd160uint32) (0xff & *(arg_data++))) << 16;
417 }
418 }
419 bpos = alen;
420 *wptr = w;
421 }
422
423 arg_obj->wptr = wptr;
424 arg_obj->bpos = bpos;
425 if ((arg_obj->len[0] = arg_len + arg_obj->len[0]) < arg_len)
426 {
427 arg_obj->len[1]++;
428 }
429 return RMD160_OK;
430
431}
432
433
434static int
435rmd160_destroy (RMD160 ptr)
436{
437 if (!ptr)
438 {
439 return RMD160_ERR_INVALID_ARG;
440 }
441 free (ptr);
442 return RMD160_OK;
443}
444
445
446
447static RMD160
448rmd160_copy (RMD160 target_p, RMD160 source_p)
449{
450 if (!target_p)
451 {
452 if (!
453 (target_p =
454 (struct rmd160_object *) malloc (sizeof (struct rmd160_object))))
455 {
456 return NULL;
457 }
458 }
459
460 if (source_p)
461 {
462 target_p->state[0] = source_p->state[0];
463 target_p->state[1] = source_p->state[1];
464 target_p->state[2] = source_p->state[2];
465 target_p->state[3] = source_p->state[3];
466 target_p->state[4] = source_p->state[4];
467 {
468 int i;
469 for (i = 0; i < 16; ++i)
470 {
471 target_p->data[i] = source_p->data[i];
472 }
473 }
474 target_p->len[0] = source_p->len[0];
475 target_p->len[1] = source_p->len[1];
476 target_p->bpos = source_p->bpos;
477 target_p->wptr = source_p->wptr - source_p->data + target_p->data;
478 target_p->wend = 16 + target_p->data;
479 }
480 else
481 {
482 target_p->state[0] = RMD160_INIT0;
483 target_p->state[1] = RMD160_INIT1;
484 target_p->state[2] = RMD160_INIT2;
485 target_p->state[3] = RMD160_INIT3;
486 target_p->state[4] = RMD160_INIT4;
487 {
488 int i;
489 for (i = 0; i < 16; ++i)
490 {
491 target_p->data[i] = 0U;
492 }
493 }
494 target_p->len[0] = 0U;
495 target_p->len[1] = 0U;
496 target_p->bpos = 0;
497 target_p->wptr = target_p->data;
498 target_p->wend = 16 + target_p->data;
499 }
500
501 return target_p;
502}
503
504
505
506static rmd160uint32 *
507rmd160_sum_words (RMD160 arg_handle, rmd160uint32 * arg_result_p)
508{
509 struct rmd160_object work;
510
511
512 if (!arg_handle)
513 return NULL;
514
515 if (!arg_result_p
516 && !(arg_result_p =
517 (rmd160uint32 *) malloc (5 * sizeof (rmd160uint32))))
518 {
519 return NULL;
520 }
521
522 rmd160_copy (&work, arg_handle);
523
524 {
525 rmd160uint32 *p;
526 p = work.wptr;
527 if (work.bpos)
528 ++p;
529 while (p < work.wend)
530 *(p++) = 0U;
531 }
532 *(work.wptr) |= ((rmd160uint32) 0x80) << (work.bpos << 3);
533
534 if ((work.wend - work.wptr) <= 2)
535 {
536 _rmd160_calc (work.state, work.data);
537
538 memset (work.data, 0U, 14 * sizeof (rmd160uint32));
539 }
540
541 work.data[14] = work.len[0] << 3;
542 work.data[15] = (work.len[1] << 3) | (work.len[0] >> 29);
543
544 _rmd160_calc (work.state, work.data);
545
546 memcpy (arg_result_p, work.state, 5 * sizeof (rmd160uint32));
547
548 return arg_result_p;
549
550}
551
552
553
554static void
555rmd160_sum_bytes (RMD160 arg_handle, unsigned char *result_p)
556{
557 rmd160uint32 temp[5];
558 rmd160uint32 *ptemp;
559
560 if (!rmd160_sum_words (arg_handle, temp))
561 return;
562
563 ptemp = temp;
564 {
565 int i;
566 for (i = 0; i < 5; ++i)
567 {
568 rmd160uint32 w;
569 *(result_p++) = 0xff & (w = *ptemp);
570 *(result_p++) = 0xff & (w >> 8);
571 *(result_p++) = 0xff & (w >> 16);
572 *(result_p++) = 0xff & (w >> 24);
573 ++ptemp;
574 }
575 }
576}
577
578
579
580static struct EXTRACTOR_Keywords *
581addKeyword (EXTRACTOR_KeywordList * oldhead,
582 const char *phrase, EXTRACTOR_KeywordType type)
583{
584
585 EXTRACTOR_KeywordList *keyword;
586 keyword = malloc (sizeof (EXTRACTOR_KeywordList));
587 keyword->next = oldhead;
588 keyword->keyword = strdup (phrase);
589 keyword->keywordType = type;
590 return keyword;
591}
592
593#define DIGEST_BITS 160
594#define DIGEST_HEX_BYTES (DIGEST_BITS / 4)
595#define DIGEST_BIN_BYTES (DIGEST_BITS / 8)
596#define MAX_DIGEST_BIN_BYTES DIGEST_BIN_BYTES
597#define rmd160_init(t) rmd160_copy((t),NULL)
598#define rmd160_new() rmd160_copy(NULL,NULL)
599
600
601struct EXTRACTOR_Keywords *
602libextractor_hash_rmd160_extract (const char *filename,
603 const unsigned char *data,
604 size_t size,
605 struct EXTRACTOR_Keywords *prev)
606{
607 unsigned char bin_buffer[MAX_DIGEST_BIN_BYTES];
608 char hash[8 * MAX_DIGEST_BIN_BYTES];
609 char buf[16];
610 RMD160 ptr;
611 int i;
612
613 ptr = rmd160_new ();
614 rmd160_append (ptr, size, data);
615 rmd160_sum_bytes (ptr, bin_buffer);
616 rmd160_destroy (ptr);
617 hash[0] = '\0';
618 for (i = 0; i < DIGEST_HEX_BYTES / 2; i++)
619 {
620 snprintf (buf, 16, "%02x", bin_buffer[i]);
621 strcat (hash, buf);
622 }
623 prev = addKeyword (prev, hash, EXTRACTOR_HASH_RMD160);
624 return prev;
625}
diff --git a/src/plugins/hash/sha1extractor.c b/src/plugins/hash/sha1extractor.c
deleted file mode 100644
index 5e899fd..0000000
--- a/src/plugins/hash/sha1extractor.c
+++ /dev/null
@@ -1,475 +0,0 @@
1/*
2 This file is part of libextractor.
3 (C) 2004 Vidyut Samanta and Christian Grothoff
4
5 libextractor is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libextractor is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libextractor; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21#include "platform.h"
22#include "extractor.h"
23
24/* sha.c - Functions to compute SHA1 message digest of files or
25 memory blocks according to the NIST specification FIPS-180-1.
26
27 Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
28
29 This program is free software; you can redistribute it and/or modify it
30 under the terms of the GNU General Public License as published by the
31 Free Software Foundation; either version 2, or (at your option) any
32 later version.
33
34 This program is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software Foundation,
41 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
42
43/* Written by Scott G. Miller
44 Credits:
45 Robert Klep <robert@ilse.nl> -- Expansion function fix
46*/
47
48#ifdef _LIBC
49#include <stdint.h>
50typedef uint32_t md5_uint32;
51typedef uintptr_t md5_uintptr;
52#else
53# define UINT_MAX_32_BITS 4294967295U
54
55# if UINT_MAX == UINT_MAX_32_BITS
56typedef unsigned int md5_uint32;
57# else
58# if USHRT_MAX == UINT_MAX_32_BITS
59typedef unsigned short md5_uint32;
60# else
61# if ULONG_MAX == UINT_MAX_32_BITS
62typedef unsigned long md5_uint32;
63# else
64 /* The following line is intended to evoke an error.
65 Using #error is not portable enough. */
66"Cannot determine unsigned 32-bit data type."
67# endif
68# endif
69# endif
70/* We have to make a guess about the integer type equivalent in size
71 to pointers which should always be correct. */
72typedef unsigned long int md5_uintptr;
73#endif
74
75
76/* Structure to save state of computation between the single steps. */
77struct sha_ctx
78{
79 md5_uint32 A;
80 md5_uint32 B;
81 md5_uint32 C;
82 md5_uint32 D;
83 md5_uint32 E;
84
85 md5_uint32 total[2];
86 md5_uint32 buflen;
87 char buffer[128];
88};
89
90
91/* --- Code below is the primary difference between md5.c and sha.c --- */
92
93/* SHA1 round constants */
94#define K1 0x5a827999L
95#define K2 0x6ed9eba1L
96#define K3 0x8f1bbcdcL
97#define K4 0xca62c1d6L
98
99/* Round functions. Note that F2 is the same as F4. */
100#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
101#define F2(B,C,D) (B ^ C ^ D)
102#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
103#define F4(B,C,D) (B ^ C ^ D)
104
105#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
106
107/*
108 Not-swap is a macro that does an endian swap on architectures that are
109 big-endian, as SHA needs some data in a little-endian format
110*/
111
112#ifdef WORDS_BIGENDIAN
113# define NOTSWAP(n) (n)
114# define SWAP(n) \
115 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
116#else
117# define NOTSWAP(n) \
118 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
119# define SWAP(n) (n)
120#endif
121
122#define BLOCKSIZE 4096
123/* Ensure that BLOCKSIZE is a multiple of 64. */
124#if BLOCKSIZE % 64 != 0
125/* FIXME-someday (soon?): use #error instead of this kludge. */
126"invalid BLOCKSIZE"
127#endif
128/* This array contains the bytes used to pad the buffer to the next
129 64-byte boundary. (RFC 1321, 3.1: Step 1) */
130static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
131
132
133
134/* Process LEN bytes of BUFFER, accumulating context into CTX.
135 It is assumed that LEN % 64 == 0.
136 Most of this code comes from GnuPG's cipher/sha1.c. */
137
138static void
139sha_process_block (const void *buffer, size_t len, struct sha_ctx *ctx)
140{
141 const md5_uint32 *words = buffer;
142 size_t nwords = len / sizeof (md5_uint32);
143 const md5_uint32 *endp = words + nwords;
144 md5_uint32 x[16];
145 md5_uint32 a = ctx->A;
146 md5_uint32 b = ctx->B;
147 md5_uint32 c = ctx->C;
148 md5_uint32 d = ctx->D;
149 md5_uint32 e = ctx->E;
150
151 /* First increment the byte count. RFC 1321 specifies the possible
152 length of the file up to 2^64 bits. Here we only compute the
153 number of bytes. Do a double word increment. */
154 ctx->total[0] += len;
155 if (ctx->total[0] < len)
156 ++ctx->total[1];
157
158#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \
159 ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \
160 , (x[I&0x0f] = rol(tm, 1)) )
161
162#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \
163 + F( B, C, D ) \
164 + K \
165 + M; \
166 B = rol( B, 30 ); \
167 } while(0)
168
169 while (words < endp)
170 {
171 md5_uint32 tm;
172 int t;
173 /* FIXME: see sha1.c for a better implementation. */
174 for (t = 0; t < 16; t++)
175 {
176 x[t] = NOTSWAP (*words);
177 words++;
178 }
179
180 R (a, b, c, d, e, F1, K1, x[0]);
181 R (e, a, b, c, d, F1, K1, x[1]);
182 R (d, e, a, b, c, F1, K1, x[2]);
183 R (c, d, e, a, b, F1, K1, x[3]);
184 R (b, c, d, e, a, F1, K1, x[4]);
185 R (a, b, c, d, e, F1, K1, x[5]);
186 R (e, a, b, c, d, F1, K1, x[6]);
187 R (d, e, a, b, c, F1, K1, x[7]);
188 R (c, d, e, a, b, F1, K1, x[8]);
189 R (b, c, d, e, a, F1, K1, x[9]);
190 R (a, b, c, d, e, F1, K1, x[10]);
191 R (e, a, b, c, d, F1, K1, x[11]);
192 R (d, e, a, b, c, F1, K1, x[12]);
193 R (c, d, e, a, b, F1, K1, x[13]);
194 R (b, c, d, e, a, F1, K1, x[14]);
195 R (a, b, c, d, e, F1, K1, x[15]);
196 R (e, a, b, c, d, F1, K1, M (16));
197 R (d, e, a, b, c, F1, K1, M (17));
198 R (c, d, e, a, b, F1, K1, M (18));
199 R (b, c, d, e, a, F1, K1, M (19));
200 R (a, b, c, d, e, F2, K2, M (20));
201 R (e, a, b, c, d, F2, K2, M (21));
202 R (d, e, a, b, c, F2, K2, M (22));
203 R (c, d, e, a, b, F2, K2, M (23));
204 R (b, c, d, e, a, F2, K2, M (24));
205 R (a, b, c, d, e, F2, K2, M (25));
206 R (e, a, b, c, d, F2, K2, M (26));
207 R (d, e, a, b, c, F2, K2, M (27));
208 R (c, d, e, a, b, F2, K2, M (28));
209 R (b, c, d, e, a, F2, K2, M (29));
210 R (a, b, c, d, e, F2, K2, M (30));
211 R (e, a, b, c, d, F2, K2, M (31));
212 R (d, e, a, b, c, F2, K2, M (32));
213 R (c, d, e, a, b, F2, K2, M (33));
214 R (b, c, d, e, a, F2, K2, M (34));
215 R (a, b, c, d, e, F2, K2, M (35));
216 R (e, a, b, c, d, F2, K2, M (36));
217 R (d, e, a, b, c, F2, K2, M (37));
218 R (c, d, e, a, b, F2, K2, M (38));
219 R (b, c, d, e, a, F2, K2, M (39));
220 R (a, b, c, d, e, F3, K3, M (40));
221 R (e, a, b, c, d, F3, K3, M (41));
222 R (d, e, a, b, c, F3, K3, M (42));
223 R (c, d, e, a, b, F3, K3, M (43));
224 R (b, c, d, e, a, F3, K3, M (44));
225 R (a, b, c, d, e, F3, K3, M (45));
226 R (e, a, b, c, d, F3, K3, M (46));
227 R (d, e, a, b, c, F3, K3, M (47));
228 R (c, d, e, a, b, F3, K3, M (48));
229 R (b, c, d, e, a, F3, K3, M (49));
230 R (a, b, c, d, e, F3, K3, M (50));
231 R (e, a, b, c, d, F3, K3, M (51));
232 R (d, e, a, b, c, F3, K3, M (52));
233 R (c, d, e, a, b, F3, K3, M (53));
234 R (b, c, d, e, a, F3, K3, M (54));
235 R (a, b, c, d, e, F3, K3, M (55));
236 R (e, a, b, c, d, F3, K3, M (56));
237 R (d, e, a, b, c, F3, K3, M (57));
238 R (c, d, e, a, b, F3, K3, M (58));
239 R (b, c, d, e, a, F3, K3, M (59));
240 R (a, b, c, d, e, F4, K4, M (60));
241 R (e, a, b, c, d, F4, K4, M (61));
242 R (d, e, a, b, c, F4, K4, M (62));
243 R (c, d, e, a, b, F4, K4, M (63));
244 R (b, c, d, e, a, F4, K4, M (64));
245 R (a, b, c, d, e, F4, K4, M (65));
246 R (e, a, b, c, d, F4, K4, M (66));
247 R (d, e, a, b, c, F4, K4, M (67));
248 R (c, d, e, a, b, F4, K4, M (68));
249 R (b, c, d, e, a, F4, K4, M (69));
250 R (a, b, c, d, e, F4, K4, M (70));
251 R (e, a, b, c, d, F4, K4, M (71));
252 R (d, e, a, b, c, F4, K4, M (72));
253 R (c, d, e, a, b, F4, K4, M (73));
254 R (b, c, d, e, a, F4, K4, M (74));
255 R (a, b, c, d, e, F4, K4, M (75));
256 R (e, a, b, c, d, F4, K4, M (76));
257 R (d, e, a, b, c, F4, K4, M (77));
258 R (c, d, e, a, b, F4, K4, M (78));
259 R (b, c, d, e, a, F4, K4, M (79));
260
261 a = ctx->A += a;
262 b = ctx->B += b;
263 c = ctx->C += c;
264 d = ctx->D += d;
265 e = ctx->E += e;
266 }
267}
268
269
270
271static void
272sha_process_bytes (const void *buffer, size_t len, struct sha_ctx *ctx)
273{
274 /* When we already have some bits in our internal buffer concatenate
275 both inputs first. */
276 if (ctx->buflen != 0)
277 {
278 size_t left_over = ctx->buflen;
279 size_t add = 128 - left_over > len ? len : 128 - left_over;
280
281 memcpy (&ctx->buffer[left_over], buffer, add);
282 ctx->buflen += add;
283
284 if (ctx->buflen > 64)
285 {
286 sha_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
287
288 ctx->buflen &= 63;
289 /* The regions in the following copy operation cannot overlap. */
290 memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
291 ctx->buflen);
292 }
293
294 buffer = (const char *) buffer + add;
295 len -= add;
296 }
297
298 /* Process available complete blocks. */
299 if (len >= 64)
300 {
301#if !_STRING_ARCH_unaligned
302/* To check alignment gcc has an appropriate operator. Other
303 compilers don't. */
304# if __GNUC__ >= 2
305# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
306# else
307# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
308# endif
309 if (UNALIGNED_P (buffer))
310 while (len > 64)
311 {
312 sha_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
313 buffer = (const char *) buffer + 64;
314 len -= 64;
315 }
316 else
317#endif
318 {
319 sha_process_block (buffer, len & ~63, ctx);
320 buffer = (const char *) buffer + (len & ~63);
321 len &= 63;
322 }
323 }
324
325 /* Move remaining bytes in internal buffer. */
326 if (len > 0)
327 {
328 size_t left_over = ctx->buflen;
329
330 memcpy (&ctx->buffer[left_over], buffer, len);
331 left_over += len;
332 if (left_over >= 64)
333 {
334 sha_process_block (ctx->buffer, 64, ctx);
335 left_over -= 64;
336 memcpy (ctx->buffer, &ctx->buffer[64], left_over);
337 }
338 ctx->buflen = left_over;
339 }
340}
341
342
343/*
344 Takes a pointer to a 160 bit block of data (five 32 bit ints) and
345 intializes it to the start constants of the SHA1 algorithm. This
346 must be called before using hash in the call to sha_hash
347*/
348static void
349sha_init_ctx (struct sha_ctx *ctx)
350{
351 ctx->A = 0x67452301;
352 ctx->B = 0xefcdab89;
353 ctx->C = 0x98badcfe;
354 ctx->D = 0x10325476;
355 ctx->E = 0xc3d2e1f0;
356
357 ctx->total[0] = ctx->total[1] = 0;
358 ctx->buflen = 0;
359}
360
361/* Put result from CTX in first 20 bytes following RESBUF. The result
362 must be in little endian byte order.
363
364 IMPORTANT: On some systems it is required that RESBUF is correctly
365 aligned for a 32 bits value. */
366static void *
367sha_read_ctx (const struct sha_ctx *ctx, void *resbuf)
368{
369 ((md5_uint32 *) resbuf)[0] = NOTSWAP (ctx->A);
370 ((md5_uint32 *) resbuf)[1] = NOTSWAP (ctx->B);
371 ((md5_uint32 *) resbuf)[2] = NOTSWAP (ctx->C);
372 ((md5_uint32 *) resbuf)[3] = NOTSWAP (ctx->D);
373 ((md5_uint32 *) resbuf)[4] = NOTSWAP (ctx->E);
374
375 return resbuf;
376}
377
378/* Process the remaining bytes in the internal buffer and the usual
379 prolog according to the standard and write the result to RESBUF.
380
381 IMPORTANT: On some systems it is required that RESBUF is correctly
382 aligned for a 32 bits value. */
383static void *
384sha_finish_ctx (struct sha_ctx *ctx, void *resbuf)
385{
386 /* Take yet unprocessed bytes into account. */
387 md5_uint32 bytes = ctx->buflen;
388 size_t pad;
389
390 /* Now count remaining bytes. */
391 ctx->total[0] += bytes;
392 if (ctx->total[0] < bytes)
393 ++ctx->total[1];
394
395 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
396 memcpy (&ctx->buffer[bytes], fillbuf, pad);
397
398 /* Put the 64-bit file length in *bits* at the end of the buffer. */
399 *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] =
400 NOTSWAP (ctx->total[0] << 3);
401 *(md5_uint32 *) & ctx->buffer[bytes + pad] =
402 NOTSWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
403
404 /* Process last bytes. */
405 sha_process_block (ctx->buffer, bytes + pad + 8, ctx);
406
407 return sha_read_ctx (ctx, resbuf);
408}
409
410
411/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
412 result is always in little endian byte order, so that a byte-wise
413 output yields to the wanted ASCII representation of the message
414 digest. */
415static void *
416sha_buffer (const char *buffer, size_t len, void *resblock)
417{
418 struct sha_ctx ctx;
419
420 /* Initialize the computation context. */
421 sha_init_ctx (&ctx);
422
423 /* Process whole buffer but last len % 64 bytes. */
424 sha_process_bytes (buffer, len, &ctx);
425
426 /* Put result in desired memory area. */
427 return sha_finish_ctx (&ctx, resblock);
428}
429
430
431
432
433
434
435
436static struct EXTRACTOR_Keywords *
437addKeyword (EXTRACTOR_KeywordList * oldhead,
438 const char *phrase, EXTRACTOR_KeywordType type)
439{
440
441 EXTRACTOR_KeywordList *keyword;
442 keyword = (EXTRACTOR_KeywordList *) malloc (sizeof (EXTRACTOR_KeywordList));
443 keyword->next = oldhead;
444 keyword->keyword = strdup (phrase);
445 keyword->keywordType = type;
446 return keyword;
447}
448
449#define DIGEST_BITS 160
450#define DIGEST_HEX_BYTES (DIGEST_BITS / 4)
451#define DIGEST_BIN_BYTES (DIGEST_BITS / 8)
452
453#define MAX_DIGEST_BIN_BYTES DIGEST_BIN_BYTES
454
455struct EXTRACTOR_Keywords *
456libextractor_hash_sha1_extract (const char *filename,
457 char *data,
458 size_t size, struct EXTRACTOR_Keywords *prev)
459{
460 unsigned char bin_buffer[MAX_DIGEST_BIN_BYTES];
461 char hash[8 * MAX_DIGEST_BIN_BYTES];
462 char buf[16];
463 int i;
464
465 sha_buffer (data, size, bin_buffer);
466
467 hash[0] = '\0';
468 for (i = 0; i < DIGEST_HEX_BYTES / 2; i++)
469 {
470 snprintf (buf, 16, "%02x", bin_buffer[i]);
471 strcat (hash, buf);
472 }
473 prev = addKeyword (prev, hash, EXTRACTOR_HASH_SHA1);
474 return prev;
475}