diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-11-18 19:33:13 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-11-18 19:33:13 +0000 |
commit | aee0fd8320514627d8ea5306bd4666bcd74d9c46 (patch) | |
tree | 64a6424a602efdacdee5c543011c784efeda7f1b | |
parent | 303b7d83f0f791478d3ff79dfdf82c8e06a82ec6 (diff) | |
download | busybox-w32-aee0fd8320514627d8ea5306bd4666bcd74d9c46.tar.gz busybox-w32-aee0fd8320514627d8ea5306bd4666bcd74d9c46.tar.bz2 busybox-w32-aee0fd8320514627d8ea5306bd4666bcd74d9c46.zip |
Replaced by md5_sha1_sum.c
-rw-r--r-- | coreutils/sha1sum.c | 492 |
1 files changed, 0 insertions, 492 deletions
diff --git a/coreutils/sha1sum.c b/coreutils/sha1sum.c deleted file mode 100644 index 1148aac19..000000000 --- a/coreutils/sha1sum.c +++ /dev/null | |||
@@ -1,492 +0,0 @@ | |||
1 | /* | ||
2 | * Based on shasum from http://www.netsw.org/crypto/hash/ | ||
3 | * Majorly hacked up to use Dr Brian Gladman's sha1 code | ||
4 | * | ||
5 | * Copyright (C) 1999 Scott G. Miller | ||
6 | * Copyright (C) 2003 Glenn L. McGrath | ||
7 | * Copyright (C) 2003 Erik Andersen | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | */ | ||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <getopt.h> | ||
26 | #include <stdio.h> | ||
27 | #include <stdlib.h> | ||
28 | #include <string.h> | ||
29 | #include <limits.h> | ||
30 | #include <stdint.h> | ||
31 | #include <endian.h> | ||
32 | #include <byteswap.h> | ||
33 | #include "busybox.h" | ||
34 | |||
35 | |||
36 | /* | ||
37 | --------------------------------------------------------------------------- | ||
38 | Begin Dr. Gladman's sha1 code | ||
39 | --------------------------------------------------------------------------- | ||
40 | */ | ||
41 | |||
42 | /* | ||
43 | --------------------------------------------------------------------------- | ||
44 | Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. | ||
45 | All rights reserved. | ||
46 | |||
47 | LICENSE TERMS | ||
48 | |||
49 | The free distribution and use of this software in both source and binary | ||
50 | form is allowed (with or without changes) provided that: | ||
51 | |||
52 | 1. distributions of this source code include the above copyright | ||
53 | notice, this list of conditions and the following disclaimer; | ||
54 | |||
55 | 2. distributions in binary form include the above copyright | ||
56 | notice, this list of conditions and the following disclaimer | ||
57 | in the documentation and/or other associated materials; | ||
58 | |||
59 | 3. the copyright holder's name is not used to endorse products | ||
60 | built using this software without specific written permission. | ||
61 | |||
62 | ALTERNATIVELY, provided that this notice is retained in full, this product | ||
63 | may be distributed under the terms of the GNU General Public License (GPL), | ||
64 | in which case the provisions of the GPL apply INSTEAD OF those given above. | ||
65 | |||
66 | DISCLAIMER | ||
67 | |||
68 | This software is provided 'as is' with no explicit or implied warranties | ||
69 | in respect of its properties, including, but not limited to, correctness | ||
70 | and/or fitness for purpose. | ||
71 | --------------------------------------------------------------------------- | ||
72 | Issue Date: 10/11/2002 | ||
73 | |||
74 | This is a byte oriented version of SHA1 that operates on arrays of bytes | ||
75 | stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor | ||
76 | */ | ||
77 | |||
78 | #define SHA1_BLOCK_SIZE 64 | ||
79 | #define SHA1_DIGEST_SIZE 20 | ||
80 | #define SHA1_HASH_SIZE SHA1_DIGEST_SIZE | ||
81 | #define SHA2_GOOD 0 | ||
82 | #define SHA2_BAD 1 | ||
83 | |||
84 | /* type to hold the SHA1 context */ | ||
85 | typedef struct | ||
86 | { uint32_t count[2]; | ||
87 | uint32_t hash[5]; | ||
88 | uint32_t wbuf[16]; | ||
89 | } sha1_ctx; | ||
90 | |||
91 | #define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) | ||
92 | |||
93 | #if __BYTE_ORDER == __BIG_ENDIAN | ||
94 | # define swap_b32(x) (x) | ||
95 | #elif defined(bswap_32) | ||
96 | # define swap_b32(x) bswap_32(x) | ||
97 | #else | ||
98 | # define swap_b32(x) ((rotl32((x), 8) & 0x00ff00ff) | (rotl32((x), 24) & 0xff00ff00)) | ||
99 | #endif | ||
100 | |||
101 | #define SHA1_MASK (SHA1_BLOCK_SIZE - 1) | ||
102 | |||
103 | /* reverse byte order in 32-bit words */ | ||
104 | #define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) | ||
105 | #define parity(x,y,z) ((x) ^ (y) ^ (z)) | ||
106 | #define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | ||
107 | |||
108 | /* A normal version as set out in the FIPS. This version uses */ | ||
109 | /* partial loop unrolling and is optimised for the Pentium 4 */ | ||
110 | #define rnd(f,k) \ | ||
111 | t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \ | ||
112 | e = d; d = c; c = rotl32(b, 30); b = t | ||
113 | |||
114 | void sha1_compile(sha1_ctx ctx[1]) | ||
115 | { | ||
116 | uint32_t w[80], i, a, b, c, d, e, t; | ||
117 | |||
118 | /* note that words are compiled from the buffer into 32-bit */ | ||
119 | /* words in big-endian order so an order reversal is needed */ | ||
120 | /* here on little endian machines */ | ||
121 | for(i = 0; i < SHA1_BLOCK_SIZE / 4; ++i) | ||
122 | w[i] = swap_b32(ctx->wbuf[i]); | ||
123 | |||
124 | for(i = SHA1_BLOCK_SIZE / 4; i < 80; ++i) | ||
125 | w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); | ||
126 | |||
127 | a = ctx->hash[0]; | ||
128 | b = ctx->hash[1]; | ||
129 | c = ctx->hash[2]; | ||
130 | d = ctx->hash[3]; | ||
131 | e = ctx->hash[4]; | ||
132 | |||
133 | for(i = 0; i < 20; ++i) | ||
134 | { | ||
135 | rnd(ch, 0x5a827999); | ||
136 | } | ||
137 | |||
138 | for(i = 20; i < 40; ++i) | ||
139 | { | ||
140 | rnd(parity, 0x6ed9eba1); | ||
141 | } | ||
142 | |||
143 | for(i = 40; i < 60; ++i) | ||
144 | { | ||
145 | rnd(maj, 0x8f1bbcdc); | ||
146 | } | ||
147 | |||
148 | for(i = 60; i < 80; ++i) | ||
149 | { | ||
150 | rnd(parity, 0xca62c1d6); | ||
151 | } | ||
152 | |||
153 | ctx->hash[0] += a; | ||
154 | ctx->hash[1] += b; | ||
155 | ctx->hash[2] += c; | ||
156 | ctx->hash[3] += d; | ||
157 | ctx->hash[4] += e; | ||
158 | } | ||
159 | |||
160 | void sha1_begin(sha1_ctx ctx[1]) | ||
161 | { | ||
162 | ctx->count[0] = ctx->count[1] = 0; | ||
163 | ctx->hash[0] = 0x67452301; | ||
164 | ctx->hash[1] = 0xefcdab89; | ||
165 | ctx->hash[2] = 0x98badcfe; | ||
166 | ctx->hash[3] = 0x10325476; | ||
167 | ctx->hash[4] = 0xc3d2e1f0; | ||
168 | } | ||
169 | |||
170 | /* SHA1 hash data in an array of bytes into hash buffer and call the */ | ||
171 | /* hash_compile function as required. */ | ||
172 | void sha1_hash(const unsigned char data[], unsigned int len, sha1_ctx ctx[1]) | ||
173 | { | ||
174 | uint32_t pos = (uint32_t)(ctx->count[0] & SHA1_MASK), | ||
175 | freeb = SHA1_BLOCK_SIZE - pos; | ||
176 | const unsigned char *sp = data; | ||
177 | |||
178 | if((ctx->count[0] += len) < len) | ||
179 | ++(ctx->count[1]); | ||
180 | |||
181 | while(len >= freeb) /* tranfer whole blocks while possible */ | ||
182 | { | ||
183 | memcpy(((unsigned char*)ctx->wbuf) + pos, sp, freeb); | ||
184 | sp += freeb; len -= freeb; freeb = SHA1_BLOCK_SIZE; pos = 0; | ||
185 | sha1_compile(ctx); | ||
186 | } | ||
187 | |||
188 | memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); | ||
189 | } | ||
190 | |||
191 | /* SHA1 Final padding and digest calculation */ | ||
192 | #if __BYTE_ORDER == __LITTLE_ENDIAN | ||
193 | static uint32_t mask[4] = | ||
194 | { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff }; | ||
195 | static uint32_t bits[4] = | ||
196 | { 0x00000080, 0x00008000, 0x00800000, 0x80000000 }; | ||
197 | #else | ||
198 | static uint32_t mask[4] = | ||
199 | { 0x00000000, 0xff000000, 0xffff0000, 0xffffff00 }; | ||
200 | static uint32_t bits[4] = | ||
201 | { 0x80000000, 0x00800000, 0x00008000, 0x00000080 }; | ||
202 | #endif | ||
203 | |||
204 | void sha1_end(unsigned char hval[], sha1_ctx ctx[1]) | ||
205 | { | ||
206 | uint32_t i, cnt = (uint32_t)(ctx->count[0] & SHA1_MASK); | ||
207 | |||
208 | /* mask out the rest of any partial 32-bit word and then set */ | ||
209 | /* the next byte to 0x80. On big-endian machines any bytes in */ | ||
210 | /* the buffer will be at the top end of 32 bit words, on little */ | ||
211 | /* endian machines they will be at the bottom. Hence the AND */ | ||
212 | /* and OR masks above are reversed for little endian systems */ | ||
213 | ctx->wbuf[cnt >> 2] = (ctx->wbuf[cnt >> 2] & mask[cnt & 3]) | bits[cnt & 3]; | ||
214 | |||
215 | /* we need 9 or more empty positions, one for the padding byte */ | ||
216 | /* (above) and eight for the length count. If there is not */ | ||
217 | /* enough space pad and empty the buffer */ | ||
218 | if(cnt > SHA1_BLOCK_SIZE - 9) | ||
219 | { | ||
220 | if(cnt < 60) ctx->wbuf[15] = 0; | ||
221 | sha1_compile(ctx); | ||
222 | cnt = 0; | ||
223 | } | ||
224 | else /* compute a word index for the empty buffer positions */ | ||
225 | cnt = (cnt >> 2) + 1; | ||
226 | |||
227 | while(cnt < 14) /* and zero pad all but last two positions */ | ||
228 | ctx->wbuf[cnt++] = 0; | ||
229 | |||
230 | /* assemble the eight byte counter in the buffer in big-endian */ | ||
231 | /* format */ | ||
232 | |||
233 | ctx->wbuf[14] = swap_b32((ctx->count[1] << 3) | (ctx->count[0] >> 29)); | ||
234 | ctx->wbuf[15] = swap_b32(ctx->count[0] << 3); | ||
235 | |||
236 | sha1_compile(ctx); | ||
237 | |||
238 | /* extract the hash value as bytes in case the hash buffer is */ | ||
239 | /* misaligned for 32-bit words */ | ||
240 | |||
241 | for(i = 0; i < SHA1_DIGEST_SIZE; ++i) | ||
242 | hval[i] = (unsigned char)(ctx->hash[i >> 2] >> 8 * (~i & 3)); | ||
243 | } | ||
244 | |||
245 | #if 0 | ||
246 | void sha1(unsigned char hval[], const unsigned char data[], unsigned int len) | ||
247 | { sha1_ctx cx[1]; | ||
248 | |||
249 | sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx); | ||
250 | } | ||
251 | #endif | ||
252 | |||
253 | /* | ||
254 | --------------------------------------------------------------------------- | ||
255 | End of Dr. Gladman's sha1 code | ||
256 | --------------------------------------------------------------------------- | ||
257 | */ | ||
258 | |||
259 | /* Using a larger blocksize can make things _much_ faster | ||
260 | * by avoiding a zillion tiny little reads */ | ||
261 | #define BLOCKSIZE 65536 | ||
262 | /* Ensure that BLOCKSIZE is a multiple of 64. */ | ||
263 | #if BLOCKSIZE % SHA1_BLOCK_SIZE != 0 | ||
264 | # error "BLOCKSIZE not a multiple of 64" | ||
265 | #endif | ||
266 | |||
267 | static int sha1sum_stream(FILE *stream, unsigned char *hashval) | ||
268 | { | ||
269 | int result = 0; | ||
270 | sha1_ctx cx[1]; | ||
271 | size_t sum, n; | ||
272 | RESERVE_CONFIG_BUFFER(buffer, BLOCKSIZE + 72); | ||
273 | |||
274 | /* Initialize the computation context. */ | ||
275 | sha1_begin(cx); | ||
276 | |||
277 | /* Iterate over full file contents. */ | ||
278 | while (1) | ||
279 | { | ||
280 | /* We read the file in blocks of BLOCKSIZE bytes. One call of the | ||
281 | computation function processes the whole buffer so that with the | ||
282 | next round of the loop another block can be read. */ | ||
283 | sum = 0; | ||
284 | |||
285 | /* Read block. Take care for partial reads. */ | ||
286 | while (1) | ||
287 | { | ||
288 | n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); | ||
289 | sum += n; | ||
290 | |||
291 | if (sum == BLOCKSIZE) | ||
292 | break; | ||
293 | |||
294 | if (n == 0) { | ||
295 | /* Check for the error flag IFF N == 0, so that we don't | ||
296 | exit the loop after a partial read due to e.g., EAGAIN | ||
297 | or EWOULDBLOCK. */ | ||
298 | if (feof (stream)) { | ||
299 | sum = 0; | ||
300 | goto process_partial_block; | ||
301 | } | ||
302 | if (ferror (stream)) { | ||
303 | result++; | ||
304 | goto all_done; | ||
305 | } | ||
306 | goto process_partial_block; | ||
307 | } | ||
308 | |||
309 | /* We've read at least one byte, so ignore errors. But always | ||
310 | check for EOF, since feof may be true even though N > 0. | ||
311 | Otherwise, we could end up calling fread after EOF. */ | ||
312 | if (feof (stream)) | ||
313 | goto process_partial_block; | ||
314 | } | ||
315 | |||
316 | /* Process buffer */ | ||
317 | sha1_hash(buffer, BLOCKSIZE, cx); | ||
318 | } | ||
319 | |||
320 | process_partial_block: | ||
321 | |||
322 | /* Process any remaining bytes. */ | ||
323 | if (sum > 0) | ||
324 | sha1_hash(buffer, sum, cx); | ||
325 | |||
326 | /* Finalize and write the hash into our buffer. */ | ||
327 | sha1_end(hashval, cx); | ||
328 | |||
329 | all_done: | ||
330 | |||
331 | RELEASE_CONFIG_BUFFER(buffer); | ||
332 | return result; | ||
333 | } | ||
334 | |||
335 | #define FLAG_SILENT 1 | ||
336 | #define FLAG_CHECK 2 | ||
337 | #define FLAG_WARN 4 | ||
338 | |||
339 | static unsigned char *hash_bin_to_hex(unsigned char *hash_value, unsigned char hash_length) | ||
340 | { | ||
341 | int x, len, max; | ||
342 | unsigned char *hex_value; | ||
343 | |||
344 | max = (hash_length * 2) + 2; | ||
345 | hex_value = xmalloc(max); | ||
346 | for (x = len = 0; x < hash_length; x++) { | ||
347 | len += snprintf(hex_value+len, max-len, "%02x", hash_value[x]); | ||
348 | } | ||
349 | return(hex_value); | ||
350 | } | ||
351 | |||
352 | FILE *wfopen_file_or_stdin(const char *file_ptr) | ||
353 | { | ||
354 | FILE *stream; | ||
355 | |||
356 | if ((file_ptr[0] == '-') && (file_ptr[1] == '\0')) { | ||
357 | stream = stdin; | ||
358 | } else { | ||
359 | stream = bb_wfopen(file_ptr, "r"); | ||
360 | } | ||
361 | |||
362 | return(stream); | ||
363 | } | ||
364 | |||
365 | /* This could become a common function for md5 as well, by using md5_stream */ | ||
366 | extern int authenticate(int argc, char **argv, | ||
367 | int (*hash_ptr)(FILE *stream, unsigned char *hashval), | ||
368 | const unsigned char hash_length) | ||
369 | { | ||
370 | unsigned char hash_value[hash_length]; | ||
371 | unsigned int flags; | ||
372 | int return_value = EXIT_SUCCESS; | ||
373 | |||
374 | #ifdef CONFIG_FEATURE_SHA1SUM_CHECK | ||
375 | flags = bb_getopt_ulflags(argc, argv, "scw"); | ||
376 | #else | ||
377 | flags = bb_getopt_ulflags(argc, argv, "s"); | ||
378 | #endif | ||
379 | |||
380 | #ifdef CONFIG_FEATURE_SHA1SUM_CHECK | ||
381 | if (!(flags & FLAG_CHECK)) { | ||
382 | if (flags & FLAG_SILENT) { | ||
383 | bb_error_msg_and_die("the -s option is meaningful only when verifying checksums"); | ||
384 | } | ||
385 | else if (flags & FLAG_WARN) { | ||
386 | bb_error_msg_and_die("the -w option is meaningful only when verifying checksums"); | ||
387 | } | ||
388 | } | ||
389 | #endif | ||
390 | |||
391 | if (argc == optind) { | ||
392 | argv[argc++] = "-"; | ||
393 | } | ||
394 | |||
395 | #ifdef CONFIG_FEATURE_SHA1SUM_CHECK | ||
396 | if (flags & FLAG_CHECK) { | ||
397 | FILE *pre_computed_stream; | ||
398 | int count_total = 0; | ||
399 | int count_failed = 0; | ||
400 | unsigned char *file_ptr = argv[optind]; | ||
401 | |||
402 | if (optind + 1 != argc) { | ||
403 | bb_error_msg_and_die("only one argument may be specified when using -c"); | ||
404 | } | ||
405 | pre_computed_stream = wfopen_file_or_stdin(file_ptr); | ||
406 | while (!feof(pre_computed_stream) && !ferror(pre_computed_stream)) { | ||
407 | FILE *stream; | ||
408 | char *line; | ||
409 | char *line_ptr; | ||
410 | char *hex_value; | ||
411 | |||
412 | line = bb_get_chomped_line_from_file(pre_computed_stream); | ||
413 | if (line == NULL) { | ||
414 | break; | ||
415 | } | ||
416 | count_total++; | ||
417 | line_ptr = strchr(line, ' '); | ||
418 | if (line_ptr == NULL) { | ||
419 | if (flags & FLAG_WARN) { | ||
420 | bb_error_msg("Invalid format"); | ||
421 | } | ||
422 | free(line); | ||
423 | continue; | ||
424 | } | ||
425 | *line_ptr = '\0'; | ||
426 | line_ptr++; | ||
427 | if ((flags & FLAG_WARN) && (*line_ptr != ' ')) { | ||
428 | bb_error_msg("Invalid format"); | ||
429 | free(line); | ||
430 | continue; | ||
431 | } | ||
432 | line_ptr++; | ||
433 | stream = bb_wfopen(line_ptr, "r"); | ||
434 | if (hash_ptr(stream, hash_value) == EXIT_FAILURE) { | ||
435 | bb_perror_msg("%s", file_ptr); | ||
436 | return_value = EXIT_FAILURE; | ||
437 | } | ||
438 | if (fclose(stream) == EOF) { | ||
439 | bb_perror_msg("Couldnt close file %s", file_ptr); | ||
440 | } | ||
441 | hex_value = hash_bin_to_hex(hash_value, hash_length); | ||
442 | printf("%s: ", line_ptr); | ||
443 | if (strcmp(hex_value, line) != 0) { | ||
444 | puts("FAILED"); | ||
445 | count_failed++; | ||
446 | } else { | ||
447 | puts("ok"); | ||
448 | } | ||
449 | free(line); | ||
450 | } | ||
451 | if (count_failed) { | ||
452 | bb_error_msg("WARNING: %d of %d computed checksum did NOT match", count_failed, count_total); | ||
453 | } | ||
454 | if (bb_fclose_nonstdin(pre_computed_stream) == EOF) { | ||
455 | bb_perror_msg_and_die("Couldnt close file %s", file_ptr); | ||
456 | } | ||
457 | } else | ||
458 | #endif | ||
459 | while (optind < argc) { | ||
460 | FILE *stream; | ||
461 | unsigned char *file_ptr = argv[optind]; | ||
462 | |||
463 | optind++; | ||
464 | |||
465 | stream = wfopen_file_or_stdin(file_ptr); | ||
466 | if (stream == NULL) { | ||
467 | return_value = EXIT_FAILURE; | ||
468 | continue; | ||
469 | } | ||
470 | if (hash_ptr(stream, hash_value) == EXIT_FAILURE) { | ||
471 | bb_perror_msg("%s", file_ptr); | ||
472 | return_value = EXIT_FAILURE; | ||
473 | } | ||
474 | else if (!flags & FLAG_SILENT) { | ||
475 | char *hex_value = hash_bin_to_hex(hash_value, hash_length); | ||
476 | printf("%s %s\n", hex_value, file_ptr); | ||
477 | free(hex_value); | ||
478 | } | ||
479 | |||
480 | if (bb_fclose_nonstdin(stream) == EOF) { | ||
481 | bb_perror_msg("Couldnt close file %s", file_ptr); | ||
482 | return_value = EXIT_FAILURE; | ||
483 | } | ||
484 | } | ||
485 | |||
486 | return(return_value); | ||
487 | } | ||
488 | |||
489 | extern int sha1sum_main(int argc, char **argv) | ||
490 | { | ||
491 | return (authenticate(argc, argv, sha1sum_stream, SHA1_HASH_SIZE)); | ||
492 | } | ||