diff options
author | Rob Landley <rob@landley.net> | 2006-02-21 06:44:43 +0000 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2006-02-21 06:44:43 +0000 |
commit | 5cf7c2df668d25c41a05670edd08558226f0bfdf (patch) | |
tree | 3c3a7b2aa31dd4105f15f435a5894c91c941686e | |
parent | a7e3d0520856db27744b4a33e786123d44bf5b2a (diff) | |
download | busybox-w32-5cf7c2df668d25c41a05670edd08558226f0bfdf.tar.gz busybox-w32-5cf7c2df668d25c41a05670edd08558226f0bfdf.tar.bz2 busybox-w32-5cf7c2df668d25c41a05670edd08558226f0bfdf.zip |
Patch from Devin Bayer to split up hash_fd.c into md5.c and sha1.c. (I tweaked
md5_sha1_sum.c to convert some #ifdef CONFIG to if(ENABLE).)
-rw-r--r-- | Config.in | 1 | ||||
-rw-r--r-- | coreutils/Config.in | 15 | ||||
-rw-r--r-- | coreutils/md5_sha1_sum.c | 77 | ||||
-rw-r--r-- | include/libbb.h | 26 | ||||
-rw-r--r-- | include/platform.h | 15 | ||||
-rw-r--r-- | libbb/Config.in | 22 | ||||
-rw-r--r-- | libbb/md5.c (renamed from libbb/hash_fd.c) | 425 | ||||
-rw-r--r-- | libbb/sha1.c | 200 |
8 files changed, 356 insertions, 425 deletions
@@ -322,6 +322,7 @@ source networking/Config.in | |||
322 | source procps/Config.in | 322 | source procps/Config.in |
323 | source shell/Config.in | 323 | source shell/Config.in |
324 | source sysklogd/Config.in | 324 | source sysklogd/Config.in |
325 | source libbb/Config.in | ||
325 | 326 | ||
326 | menu 'Debugging Options' | 327 | menu 'Debugging Options' |
327 | 328 | ||
diff --git a/coreutils/Config.in b/coreutils/Config.in index ffdc11ced..cd45cc077 100644 --- a/coreutils/Config.in +++ b/coreutils/Config.in | |||
@@ -315,21 +315,6 @@ config CONFIG_MD5SUM | |||
315 | help | 315 | help |
316 | md5sum is used to print or check MD5 checksums. | 316 | md5sum is used to print or check MD5 checksums. |
317 | 317 | ||
318 | config CONFIG_MD5SUM_SIZE_VS_SPEED | ||
319 | int " Trade Bytes for Speed" | ||
320 | default 2 | ||
321 | range 0 3 | ||
322 | depends on CONFIG_MD5SUM | ||
323 | help | ||
324 | Trade binary size versus speed for the md5sum algorithm. | ||
325 | Approximate values running uClibc and hashing | ||
326 | linux-2.4.4.tar.bz2 were: | ||
327 | user times (sec) text size (386) | ||
328 | 0 (fastest) 1.1 6144 | ||
329 | 1 1.4 5392 | ||
330 | 2 3.0 5088 | ||
331 | 3 (smallest) 5.1 4912 | ||
332 | |||
333 | config CONFIG_MKDIR | 318 | config CONFIG_MKDIR |
334 | bool "mkdir" | 319 | bool "mkdir" |
335 | default n | 320 | default n |
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index 287c2f524..626dcee56 100644 --- a/coreutils/md5_sha1_sum.c +++ b/coreutils/md5_sha1_sum.c | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include "busybox.h" | 16 | #include "busybox.h" |
17 | 17 | ||
18 | typedef enum { HASH_SHA1, HASH_MD5 } hash_algo_t; | ||
18 | 19 | ||
19 | #define FLAG_SILENT 1 | 20 | #define FLAG_SILENT 1 |
20 | #define FLAG_CHECK 2 | 21 | #define FLAG_CHECK 2 |
@@ -35,39 +36,70 @@ static unsigned char *hash_bin_to_hex(unsigned char *hash_value, | |||
35 | return (hex_value); | 36 | return (hex_value); |
36 | } | 37 | } |
37 | 38 | ||
38 | static uint8_t *hash_file(const char *filename, uint8_t hash_algo) | 39 | static uint8_t *hash_file(const char *filename, hash_algo_t hash_algo) |
39 | { | 40 | { |
40 | int src_fd = strcmp(filename, "-") == 0 ? STDIN_FILENO : | 41 | int src_fd, hash_len, count; |
41 | open(filename, O_RDONLY); | 42 | union _ctx_ { |
42 | if (src_fd == -1) { | 43 | sha1_ctx_t sha1; |
44 | md5_ctx_t md5; | ||
45 | } context; | ||
46 | uint8_t *hash_value = NULL; | ||
47 | RESERVE_CONFIG_UBUFFER(in_buf, 4096); | ||
48 | void (*update)(const void*, size_t, void*); | ||
49 | void (*final)(void*, void*); | ||
50 | |||
51 | if(strcmp(filename, "-") == 0) { | ||
52 | src_fd = STDIN_FILENO; | ||
53 | } else if(0 > (src_fd = open(filename, O_RDONLY))) { | ||
43 | bb_perror_msg("%s", filename); | 54 | bb_perror_msg("%s", filename); |
44 | return NULL; | 55 | return NULL; |
56 | } | ||
57 | |||
58 | // figure specific hash algorithims | ||
59 | if(ENABLE_MD5SUM && hash_algo==HASH_MD5) { | ||
60 | md5_begin(&context.md5); | ||
61 | update = (void (*)(const void*, size_t, void*))md5_hash; | ||
62 | final = (void (*)(void*, void*))md5_end; | ||
63 | hash_len = 16; | ||
64 | } else if(ENABLE_SHA1SUM && hash_algo==HASH_SHA1) { | ||
65 | sha1_begin(&context.sha1); | ||
66 | update = (void (*)(const void*, size_t, void*))sha1_hash; | ||
67 | final = (void (*)(void*, void*))sha1_end; | ||
68 | hash_len = 20; | ||
45 | } else { | 69 | } else { |
46 | uint8_t *hash_value; | 70 | bb_error_msg_and_die("algotithm not supported"); |
47 | RESERVE_CONFIG_UBUFFER(hash_value_bin, 20); | 71 | } |
48 | hash_value = hash_fd(src_fd, -1, hash_algo, hash_value_bin) != -2 ? | 72 | |
49 | hash_bin_to_hex(hash_value_bin, hash_algo == HASH_MD5 ? 16 : 20) : | 73 | |
50 | NULL; | 74 | while(0 < (count = read(src_fd, in_buf, sizeof in_buf))) { |
51 | RELEASE_CONFIG_BUFFER(hash_value_bin); | 75 | update(in_buf, count, &context); |
76 | } | ||
77 | |||
78 | if(count == 0) { | ||
79 | final(in_buf, &context); | ||
80 | hash_value = hash_bin_to_hex(in_buf, hash_len); | ||
81 | } | ||
82 | |||
83 | RELEASE_CONFIG_BUFFER(in_buf); | ||
84 | |||
85 | if(src_fd != STDIN_FILENO) { | ||
52 | close(src_fd); | 86 | close(src_fd); |
53 | return hash_value; | ||
54 | } | 87 | } |
88 | |||
89 | return hash_value; | ||
55 | } | 90 | } |
56 | 91 | ||
57 | /* This could become a common function for md5 as well, by using md5_stream */ | 92 | /* This could become a common function for md5 as well, by using md5_stream */ |
58 | static int hash_files(int argc, char **argv, const uint8_t hash_algo) | 93 | static int hash_files(int argc, char **argv, hash_algo_t hash_algo) |
59 | { | 94 | { |
60 | int return_value = EXIT_SUCCESS; | 95 | int return_value = EXIT_SUCCESS; |
61 | uint8_t *hash_value; | 96 | uint8_t *hash_value; |
62 | |||
63 | #ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK | ||
64 | unsigned int flags; | 97 | unsigned int flags; |
65 | 98 | ||
66 | flags = bb_getopt_ulflags(argc, argv, "scw"); | 99 | if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) |
67 | #endif | 100 | flags = bb_getopt_ulflags(argc, argv, "scw"); |
68 | 101 | ||
69 | #ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK | 102 | if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) { |
70 | if (!(flags & FLAG_CHECK)) { | ||
71 | if (flags & FLAG_SILENT) { | 103 | if (flags & FLAG_SILENT) { |
72 | bb_error_msg_and_die | 104 | bb_error_msg_and_die |
73 | ("the -s option is meaningful only when verifying checksums"); | 105 | ("the -s option is meaningful only when verifying checksums"); |
@@ -76,13 +108,12 @@ static int hash_files(int argc, char **argv, const uint8_t hash_algo) | |||
76 | ("the -w option is meaningful only when verifying checksums"); | 108 | ("the -w option is meaningful only when verifying checksums"); |
77 | } | 109 | } |
78 | } | 110 | } |
79 | #endif | ||
80 | 111 | ||
81 | if (argc == optind) { | 112 | if (argc == optind) { |
82 | argv[argc++] = "-"; | 113 | argv[argc++] = "-"; |
83 | } | 114 | } |
84 | #ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK | 115 | |
85 | if (flags & FLAG_CHECK) { | 116 | if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && flags & FLAG_CHECK) { |
86 | FILE *pre_computed_stream; | 117 | FILE *pre_computed_stream; |
87 | int count_total = 0; | 118 | int count_total = 0; |
88 | int count_failed = 0; | 119 | int count_failed = 0; |
@@ -139,9 +170,7 @@ static int hash_files(int argc, char **argv, const uint8_t hash_algo) | |||
139 | if (bb_fclose_nonstdin(pre_computed_stream) == EOF) { | 170 | if (bb_fclose_nonstdin(pre_computed_stream) == EOF) { |
140 | bb_perror_msg_and_die("Couldnt close file %s", file_ptr); | 171 | bb_perror_msg_and_die("Couldnt close file %s", file_ptr); |
141 | } | 172 | } |
142 | } else | 173 | } else { |
143 | #endif | ||
144 | { | ||
145 | while (optind < argc) { | 174 | while (optind < argc) { |
146 | char *file_ptr = argv[optind++]; | 175 | char *file_ptr = argv[optind++]; |
147 | 176 | ||
diff --git a/include/libbb.h b/include/libbb.h index 9f0c85b03..0ede812a9 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -464,9 +464,29 @@ extern void vfork_daemon_rexec(int nochdir, int noclose, | |||
464 | extern int get_terminal_width_height(int fd, int *width, int *height); | 464 | extern int get_terminal_width_height(int fd, int *width, int *height); |
465 | extern unsigned long get_ug_id(const char *s, long (*__bb_getxxnam)(const char *)); | 465 | extern unsigned long get_ug_id(const char *s, long (*__bb_getxxnam)(const char *)); |
466 | 466 | ||
467 | #define HASH_SHA1 1 | 467 | typedef struct _sha1_ctx_t_ { |
468 | #define HASH_MD5 2 | 468 | uint32_t count[2]; |
469 | extern int hash_fd(int fd, const size_t size, const uint8_t hash_algo, uint8_t *hashval); | 469 | uint32_t hash[5]; |
470 | uint32_t wbuf[16]; | ||
471 | } sha1_ctx_t; | ||
472 | |||
473 | void sha1_begin(sha1_ctx_t *ctx); | ||
474 | void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx); | ||
475 | void *sha1_end(void *resbuf, sha1_ctx_t *ctx); | ||
476 | |||
477 | typedef struct _md5_ctx_t_ { | ||
478 | uint32_t A; | ||
479 | uint32_t B; | ||
480 | uint32_t C; | ||
481 | uint32_t D; | ||
482 | uint32_t total[2]; | ||
483 | uint32_t buflen; | ||
484 | char buffer[128]; | ||
485 | } md5_ctx_t; | ||
486 | |||
487 | void md5_begin(md5_ctx_t *ctx); | ||
488 | void md5_hash(const void *data, size_t length, md5_ctx_t *ctx); | ||
489 | void *md5_end(void *resbuf, md5_ctx_t *ctx); | ||
470 | 490 | ||
471 | /* busybox.h will include dmalloc later for us, else include it here. */ | 491 | /* busybox.h will include dmalloc later for us, else include it here. */ |
472 | #if !defined _BB_INTERNAL_H_ && defined DMALLOC | 492 | #if !defined _BB_INTERNAL_H_ && defined DMALLOC |
diff --git a/include/platform.h b/include/platform.h index 68c7abbc6..b19621af1 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -78,4 +78,19 @@ | |||
78 | # endif | 78 | # endif |
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | /* ---- Endian Detection ------------------------------------ */ | ||
82 | #ifndef __APPLE__ | ||
83 | #include <byteswap.h> | ||
84 | #include <endian.h> | ||
85 | #endif | ||
86 | |||
87 | #ifdef __BIG_ENDIAN__ | ||
88 | #define BB_BIG_ENDIAN 1 | ||
89 | #elif __BYTE_ORDER == __BIG_ENDIAN | ||
90 | #define BB_BIG_ENDIAN 1 | ||
91 | #else | ||
92 | #define BB_BIG_ENDIAN 0 | ||
93 | #endif | ||
94 | |||
95 | |||
81 | #endif /* platform.h */ | 96 | #endif /* platform.h */ |
diff --git a/libbb/Config.in b/libbb/Config.in new file mode 100644 index 000000000..3ddb7d96c --- /dev/null +++ b/libbb/Config.in | |||
@@ -0,0 +1,22 @@ | |||
1 | # | ||
2 | # For a description of the syntax of this configuration file, | ||
3 | # see scripts/kbuild/config-language.txt. | ||
4 | # | ||
5 | |||
6 | menu "Busybox Library Tuning" | ||
7 | |||
8 | config CONFIG_MD5_SIZE_VS_SPEED | ||
9 | int " MD5: Trade Bytes for Speed" | ||
10 | default 2 | ||
11 | range 0 3 | ||
12 | help | ||
13 | Trade binary size versus speed for the md5sum algorithm. | ||
14 | Approximate values running uClibc and hashing | ||
15 | linux-2.4.4.tar.bz2 were: | ||
16 | user times (sec) text size (386) | ||
17 | 0 (fastest) 1.1 6144 | ||
18 | 1 1.4 5392 | ||
19 | 2 3.0 5088 | ||
20 | 3 (smallest) 5.1 4912 | ||
21 | |||
22 | endmenu | ||
diff --git a/libbb/hash_fd.c b/libbb/md5.c index 39825b378..8cec88535 100644 --- a/libbb/hash_fd.c +++ b/libbb/md5.c | |||
@@ -1,15 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * Based on shasum from http://www.netsw.org/crypto/hash/ | 2 | * md5.c - Compute MD5 checksum of strings according to the |
3 | * Majorly hacked up to use Dr Brian Gladman's sha1 code | 3 | * definition of MD5 in RFC 1321 from April 1992. |
4 | * | 4 | * |
5 | * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. | ||
6 | * | ||
7 | * Copyright (C) 1995-1999 Free Software Foundation, Inc. | ||
8 | * Copyright (C) 2001 Manuel Novoa III | ||
5 | * Copyright (C) 2003 Glenn L. McGrath | 9 | * Copyright (C) 2003 Glenn L. McGrath |
6 | * Copyright (C) 2003 Erik Andersen | 10 | * Copyright (C) 2003 Erik Andersen |
7 | * | 11 | * |
8 | * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. | 12 | * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
9 | */ | 13 | */ |
10 | |||
11 | #include <byteswap.h> | ||
12 | #include <endian.h> | ||
13 | #include <fcntl.h> | 14 | #include <fcntl.h> |
14 | #include <limits.h> | 15 | #include <limits.h> |
15 | #include <stdio.h> | 16 | #include <stdio.h> |
@@ -20,253 +21,14 @@ | |||
20 | 21 | ||
21 | #include "busybox.h" | 22 | #include "busybox.h" |
22 | 23 | ||
23 | 24 | # if CONFIG_MD5_SIZE_VS_SPEED < 0 || CONFIG_MD5_SIZE_VS_SPEED > 3 | |
24 | #ifdef CONFIG_SHA1SUM | 25 | # define MD5_SIZE_VS_SPEED 2 |
25 | /* | ||
26 | --------------------------------------------------------------------------- | ||
27 | Begin Dr. Gladman's sha1 code | ||
28 | --------------------------------------------------------------------------- | ||
29 | */ | ||
30 | |||
31 | /* | ||
32 | --------------------------------------------------------------------------- | ||
33 | Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. | ||
34 | All rights reserved. | ||
35 | |||
36 | LICENSE TERMS | ||
37 | |||
38 | The free distribution and use of this software in both source and binary | ||
39 | form is allowed (with or without changes) provided that: | ||
40 | |||
41 | 1. distributions of this source code include the above copyright | ||
42 | notice, this list of conditions and the following disclaimer; | ||
43 | |||
44 | 2. distributions in binary form include the above copyright | ||
45 | notice, this list of conditions and the following disclaimer | ||
46 | in the documentation and/or other associated materials; | ||
47 | |||
48 | 3. the copyright holder's name is not used to endorse products | ||
49 | built using this software without specific written permission. | ||
50 | |||
51 | ALTERNATIVELY, provided that this notice is retained in full, this product | ||
52 | may be distributed under the terms of the GNU General Public License (GPL), | ||
53 | in which case the provisions of the GPL apply INSTEAD OF those given above. | ||
54 | |||
55 | DISCLAIMER | ||
56 | |||
57 | This software is provided 'as is' with no explicit or implied warranties | ||
58 | in respect of its properties, including, but not limited to, correctness | ||
59 | and/or fitness for purpose. | ||
60 | --------------------------------------------------------------------------- | ||
61 | Issue Date: 10/11/2002 | ||
62 | |||
63 | This is a byte oriented version of SHA1 that operates on arrays of bytes | ||
64 | stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor | ||
65 | */ | ||
66 | |||
67 | # define SHA1_BLOCK_SIZE 64 | ||
68 | # define SHA1_DIGEST_SIZE 20 | ||
69 | # define SHA1_HASH_SIZE SHA1_DIGEST_SIZE | ||
70 | # define SHA2_GOOD 0 | ||
71 | # define SHA2_BAD 1 | ||
72 | |||
73 | # define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) | ||
74 | |||
75 | # if __BYTE_ORDER == __BIG_ENDIAN | ||
76 | # define swap_b32(x) (x) | ||
77 | # elif defined(bswap_32) | ||
78 | # define swap_b32(x) bswap_32(x) | ||
79 | # else | 26 | # else |
80 | # define swap_b32(x) ((rotl32((x), 8) & 0x00ff00ff) | (rotl32((x), 24) & 0xff00ff00)) | 27 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED |
81 | # endif /* __BYTE_ORDER */ | ||
82 | |||
83 | # define SHA1_MASK (SHA1_BLOCK_SIZE - 1) | ||
84 | |||
85 | /* reverse byte order in 32-bit words */ | ||
86 | #define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) | ||
87 | #define parity(x,y,z) ((x) ^ (y) ^ (z)) | ||
88 | #define maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) | ||
89 | |||
90 | /* A normal version as set out in the FIPS. This version uses */ | ||
91 | /* partial loop unrolling and is optimised for the Pentium 4 */ | ||
92 | # define rnd(f,k) \ | ||
93 | t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \ | ||
94 | e = d; d = c; c = rotl32(b, 30); b = t | ||
95 | |||
96 | /* type to hold the SHA1 context */ | ||
97 | struct sha1_ctx_t { | ||
98 | uint32_t count[2]; | ||
99 | uint32_t hash[5]; | ||
100 | uint32_t wbuf[16]; | ||
101 | }; | ||
102 | |||
103 | static void sha1_compile(struct sha1_ctx_t *ctx) | ||
104 | { | ||
105 | uint32_t w[80], i, a, b, c, d, e, t; | ||
106 | |||
107 | /* note that words are compiled from the buffer into 32-bit */ | ||
108 | /* words in big-endian order so an order reversal is needed */ | ||
109 | /* here on little endian machines */ | ||
110 | for (i = 0; i < SHA1_BLOCK_SIZE / 4; ++i) | ||
111 | w[i] = swap_b32(ctx->wbuf[i]); | ||
112 | |||
113 | for (i = SHA1_BLOCK_SIZE / 4; i < 80; ++i) | ||
114 | w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); | ||
115 | |||
116 | a = ctx->hash[0]; | ||
117 | b = ctx->hash[1]; | ||
118 | c = ctx->hash[2]; | ||
119 | d = ctx->hash[3]; | ||
120 | e = ctx->hash[4]; | ||
121 | |||
122 | for (i = 0; i < 20; ++i) { | ||
123 | rnd(ch, 0x5a827999); | ||
124 | } | ||
125 | |||
126 | for (i = 20; i < 40; ++i) { | ||
127 | rnd(parity, 0x6ed9eba1); | ||
128 | } | ||
129 | |||
130 | for (i = 40; i < 60; ++i) { | ||
131 | rnd(maj, 0x8f1bbcdc); | ||
132 | } | ||
133 | |||
134 | for (i = 60; i < 80; ++i) { | ||
135 | rnd(parity, 0xca62c1d6); | ||
136 | } | ||
137 | |||
138 | ctx->hash[0] += a; | ||
139 | ctx->hash[1] += b; | ||
140 | ctx->hash[2] += c; | ||
141 | ctx->hash[3] += d; | ||
142 | ctx->hash[4] += e; | ||
143 | } | ||
144 | |||
145 | static void sha1_begin(struct sha1_ctx_t *ctx) | ||
146 | { | ||
147 | ctx->count[0] = ctx->count[1] = 0; | ||
148 | ctx->hash[0] = 0x67452301; | ||
149 | ctx->hash[1] = 0xefcdab89; | ||
150 | ctx->hash[2] = 0x98badcfe; | ||
151 | ctx->hash[3] = 0x10325476; | ||
152 | ctx->hash[4] = 0xc3d2e1f0; | ||
153 | } | ||
154 | |||
155 | /* SHA1 hash data in an array of bytes into hash buffer and call the */ | ||
156 | /* hash_compile function as required. */ | ||
157 | static void sha1_hash(const void *data, size_t len, void *ctx_v) | ||
158 | { | ||
159 | struct sha1_ctx_t *ctx = (struct sha1_ctx_t *) ctx_v; | ||
160 | uint32_t pos = (uint32_t) (ctx->count[0] & SHA1_MASK); | ||
161 | uint32_t freeb = SHA1_BLOCK_SIZE - pos; | ||
162 | const unsigned char *sp = data; | ||
163 | |||
164 | if ((ctx->count[0] += len) < len) | ||
165 | ++(ctx->count[1]); | ||
166 | |||
167 | while (len >= freeb) { /* tranfer whole blocks while possible */ | ||
168 | memcpy(((unsigned char *) ctx->wbuf) + pos, sp, freeb); | ||
169 | sp += freeb; | ||
170 | len -= freeb; | ||
171 | freeb = SHA1_BLOCK_SIZE; | ||
172 | pos = 0; | ||
173 | sha1_compile(ctx); | ||
174 | } | ||
175 | |||
176 | memcpy(((unsigned char *) ctx->wbuf) + pos, sp, len); | ||
177 | } | ||
178 | |||
179 | /* SHA1 Final padding and digest calculation */ | ||
180 | # if __BYTE_ORDER == __LITTLE_ENDIAN | ||
181 | static uint32_t mask[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff }; | ||
182 | static uint32_t bits[4] = { 0x00000080, 0x00008000, 0x00800000, 0x80000000 }; | ||
183 | # else | ||
184 | static uint32_t mask[4] = { 0x00000000, 0xff000000, 0xffff0000, 0xffffff00 }; | ||
185 | static uint32_t bits[4] = { 0x80000000, 0x00800000, 0x00008000, 0x00000080 }; | ||
186 | # endif /* __BYTE_ORDER */ | ||
187 | |||
188 | static void sha1_end(unsigned char hval[], struct sha1_ctx_t *ctx) | ||
189 | { | ||
190 | uint32_t i, cnt = (uint32_t) (ctx->count[0] & SHA1_MASK); | ||
191 | |||
192 | /* mask out the rest of any partial 32-bit word and then set */ | ||
193 | /* the next byte to 0x80. On big-endian machines any bytes in */ | ||
194 | /* the buffer will be at the top end of 32 bit words, on little */ | ||
195 | /* endian machines they will be at the bottom. Hence the AND */ | ||
196 | /* and OR masks above are reversed for little endian systems */ | ||
197 | ctx->wbuf[cnt >> 2] = | ||
198 | (ctx->wbuf[cnt >> 2] & mask[cnt & 3]) | bits[cnt & 3]; | ||
199 | |||
200 | /* we need 9 or more empty positions, one for the padding byte */ | ||
201 | /* (above) and eight for the length count. If there is not */ | ||
202 | /* enough space pad and empty the buffer */ | ||
203 | if (cnt > SHA1_BLOCK_SIZE - 9) { | ||
204 | if (cnt < 60) | ||
205 | ctx->wbuf[15] = 0; | ||
206 | sha1_compile(ctx); | ||
207 | cnt = 0; | ||
208 | } else /* compute a word index for the empty buffer positions */ | ||
209 | cnt = (cnt >> 2) + 1; | ||
210 | |||
211 | while (cnt < 14) /* and zero pad all but last two positions */ | ||
212 | ctx->wbuf[cnt++] = 0; | ||
213 | |||
214 | /* assemble the eight byte counter in the buffer in big-endian */ | ||
215 | /* format */ | ||
216 | |||
217 | ctx->wbuf[14] = swap_b32((ctx->count[1] << 3) | (ctx->count[0] >> 29)); | ||
218 | ctx->wbuf[15] = swap_b32(ctx->count[0] << 3); | ||
219 | |||
220 | sha1_compile(ctx); | ||
221 | |||
222 | /* extract the hash value as bytes in case the hash buffer is */ | ||
223 | /* misaligned for 32-bit words */ | ||
224 | |||
225 | for (i = 0; i < SHA1_DIGEST_SIZE; ++i) | ||
226 | hval[i] = (unsigned char) (ctx->hash[i >> 2] >> 8 * (~i & 3)); | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | --------------------------------------------------------------------------- | ||
231 | End of Dr. Gladman's sha1 code | ||
232 | --------------------------------------------------------------------------- | ||
233 | */ | ||
234 | #endif /* CONFIG_SHA1 */ | ||
235 | |||
236 | |||
237 | |||
238 | |||
239 | |||
240 | #ifdef CONFIG_MD5SUM | ||
241 | /* | ||
242 | * md5sum.c - Compute MD5 checksum of files or strings according to the | ||
243 | * definition of MD5 in RFC 1321 from April 1992. | ||
244 | * | ||
245 | * Copyright (C) 1995-1999 Free Software Foundation, Inc. | ||
246 | * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. | ||
247 | * | ||
248 | * | ||
249 | * June 29, 2001 Manuel Novoa III | ||
250 | * | ||
251 | * Added MD5SUM_SIZE_VS_SPEED configuration option. | ||
252 | * | ||
253 | * Current valid values, with data from my system for comparison, are: | ||
254 | * (using uClibc and running on linux-2.4.4.tar.bz2) | ||
255 | * user times (sec) text size (386) | ||
256 | * 0 (fastest) 1.1 6144 | ||
257 | * 1 1.4 5392 | ||
258 | * 2 3.0 5088 | ||
259 | * 3 (smallest) 5.1 4912 | ||
260 | */ | ||
261 | |||
262 | # if CONFIG_MD5SUM_SIZE_VS_SPEED < 0 || CONFIG_MD5SUM_SIZE_VS_SPEED > 3 | ||
263 | # define MD5SUM_SIZE_VS_SPEED 2 | ||
264 | # else | ||
265 | # define MD5SUM_SIZE_VS_SPEED CONFIG_MD5SUM_SIZE_VS_SPEED | ||
266 | # endif | 28 | # endif |
267 | 29 | ||
268 | /* Handle endian-ness */ | 30 | /* Handle endian-ness */ |
269 | # if __BYTE_ORDER == __LITTLE_ENDIAN | 31 | # if !BB_BIG_ENDIAN |
270 | # define SWAP(n) (n) | 32 | # define SWAP(n) (n) |
271 | # elif defined(bswap_32) | 33 | # elif defined(bswap_32) |
272 | # define SWAP(n) bswap_32(n) | 34 | # define SWAP(n) bswap_32(n) |
@@ -274,27 +36,16 @@ static void sha1_end(unsigned char hval[], struct sha1_ctx_t *ctx) | |||
274 | # define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24)) | 36 | # define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24)) |
275 | # endif | 37 | # endif |
276 | 38 | ||
277 | # if MD5SUM_SIZE_VS_SPEED == 0 | 39 | # if MD5_SIZE_VS_SPEED == 0 |
278 | /* This array contains the bytes used to pad the buffer to the next | 40 | /* This array contains the bytes used to pad the buffer to the next |
279 | 64-byte boundary. (RFC 1321, 3.1: Step 1) */ | 41 | 64-byte boundary. (RFC 1321, 3.1: Step 1) */ |
280 | static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; | 42 | static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; |
281 | # endif /* MD5SUM_SIZE_VS_SPEED == 0 */ | 43 | # endif /* MD5_SIZE_VS_SPEED == 0 */ |
282 | |||
283 | /* Structure to save state of computation between the single steps. */ | ||
284 | struct md5_ctx_t { | ||
285 | uint32_t A; | ||
286 | uint32_t B; | ||
287 | uint32_t C; | ||
288 | uint32_t D; | ||
289 | uint32_t total[2]; | ||
290 | uint32_t buflen; | ||
291 | char buffer[128]; | ||
292 | }; | ||
293 | 44 | ||
294 | /* Initialize structure containing state of computation. | 45 | /* Initialize structure containing state of computation. |
295 | * (RFC 1321, 3.3: Step 3) | 46 | * (RFC 1321, 3.3: Step 3) |
296 | */ | 47 | */ |
297 | static void md5_begin(struct md5_ctx_t *ctx) | 48 | void md5_begin(md5_ctx_t *ctx) |
298 | { | 49 | { |
299 | ctx->A = 0x67452301; | 50 | ctx->A = 0x67452301; |
300 | ctx->B = 0xefcdab89; | 51 | ctx->B = 0xefcdab89; |
@@ -320,14 +71,14 @@ static void md5_begin(struct md5_ctx_t *ctx) | |||
320 | * starting at BUFFER. | 71 | * starting at BUFFER. |
321 | * It is necessary that LEN is a multiple of 64!!! | 72 | * It is necessary that LEN is a multiple of 64!!! |
322 | */ | 73 | */ |
323 | static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx) | 74 | void md5_hash_block(const void *buffer, size_t len, md5_ctx_t *ctx) |
324 | { | 75 | { |
325 | uint32_t correct_words[16]; | 76 | uint32_t correct_words[16]; |
326 | const uint32_t *words = buffer; | 77 | const uint32_t *words = buffer; |
327 | size_t nwords = len / sizeof(uint32_t); | 78 | size_t nwords = len / sizeof(uint32_t); |
328 | const uint32_t *endp = words + nwords; | 79 | const uint32_t *endp = words + nwords; |
329 | 80 | ||
330 | # if MD5SUM_SIZE_VS_SPEED > 0 | 81 | # if MD5_SIZE_VS_SPEED > 0 |
331 | static const uint32_t C_array[] = { | 82 | static const uint32_t C_array[] = { |
332 | /* round 1 */ | 83 | /* round 1 */ |
333 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, | 84 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, |
@@ -352,22 +103,22 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
352 | }; | 103 | }; |
353 | 104 | ||
354 | static const char P_array[] = { | 105 | static const char P_array[] = { |
355 | # if MD5SUM_SIZE_VS_SPEED > 1 | 106 | # if MD5_SIZE_VS_SPEED > 1 |
356 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ | 107 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ |
357 | # endif /* MD5SUM_SIZE_VS_SPEED > 1 */ | 108 | # endif /* MD5_SIZE_VS_SPEED > 1 */ |
358 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ | 109 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ |
359 | 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ | 110 | 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ |
360 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ | 111 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ |
361 | }; | 112 | }; |
362 | 113 | ||
363 | # if MD5SUM_SIZE_VS_SPEED > 1 | 114 | # if MD5_SIZE_VS_SPEED > 1 |
364 | static const char S_array[] = { | 115 | static const char S_array[] = { |
365 | 7, 12, 17, 22, | 116 | 7, 12, 17, 22, |
366 | 5, 9, 14, 20, | 117 | 5, 9, 14, 20, |
367 | 4, 11, 16, 23, | 118 | 4, 11, 16, 23, |
368 | 6, 10, 15, 21 | 119 | 6, 10, 15, 21 |
369 | }; | 120 | }; |
370 | # endif /* MD5SUM_SIZE_VS_SPEED > 1 */ | 121 | # endif /* MD5_SIZE_VS_SPEED > 1 */ |
371 | # endif | 122 | # endif |
372 | 123 | ||
373 | uint32_t A = ctx->A; | 124 | uint32_t A = ctx->A; |
@@ -391,7 +142,7 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
391 | uint32_t C_save = C; | 142 | uint32_t C_save = C; |
392 | uint32_t D_save = D; | 143 | uint32_t D_save = D; |
393 | 144 | ||
394 | # if MD5SUM_SIZE_VS_SPEED > 1 | 145 | # if MD5_SIZE_VS_SPEED > 1 |
395 | # define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) | 146 | # define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) |
396 | 147 | ||
397 | const uint32_t *pc; | 148 | const uint32_t *pc; |
@@ -405,7 +156,7 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
405 | } | 156 | } |
406 | words += 16; | 157 | words += 16; |
407 | 158 | ||
408 | # if MD5SUM_SIZE_VS_SPEED > 2 | 159 | # if MD5_SIZE_VS_SPEED > 2 |
409 | pc = C_array; | 160 | pc = C_array; |
410 | pp = P_array; | 161 | pp = P_array; |
411 | ps = S_array - 4; | 162 | ps = S_array - 4; |
@@ -481,7 +232,7 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
481 | B = temp; | 232 | B = temp; |
482 | } | 233 | } |
483 | 234 | ||
484 | # endif /* MD5SUM_SIZE_VS_SPEED > 2 */ | 235 | # endif /* MD5_SIZE_VS_SPEED > 2 */ |
485 | # else | 236 | # else |
486 | /* First round: using the given function, the context and a constant | 237 | /* First round: using the given function, the context and a constant |
487 | the next context is computed. Because the algorithms processing | 238 | the next context is computed. Because the algorithms processing |
@@ -511,14 +262,14 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
511 | T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 | 262 | T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 |
512 | */ | 263 | */ |
513 | 264 | ||
514 | # if MD5SUM_SIZE_VS_SPEED == 1 | 265 | # if MD5_SIZE_VS_SPEED == 1 |
515 | const uint32_t *pc; | 266 | const uint32_t *pc; |
516 | const char *pp; | 267 | const char *pp; |
517 | int i; | 268 | int i; |
518 | # endif /* MD5SUM_SIZE_VS_SPEED */ | 269 | # endif /* MD5_SIZE_VS_SPEED */ |
519 | 270 | ||
520 | /* Round 1. */ | 271 | /* Round 1. */ |
521 | # if MD5SUM_SIZE_VS_SPEED == 1 | 272 | # if MD5_SIZE_VS_SPEED == 1 |
522 | pc = C_array; | 273 | pc = C_array; |
523 | for (i = 0; i < 4; i++) { | 274 | for (i = 0; i < 4; i++) { |
524 | OP(A, B, C, D, 7, *pc++); | 275 | OP(A, B, C, D, 7, *pc++); |
@@ -543,7 +294,7 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
543 | OP(D, A, B, C, 12, 0xfd987193); | 294 | OP(D, A, B, C, 12, 0xfd987193); |
544 | OP(C, D, A, B, 17, 0xa679438e); | 295 | OP(C, D, A, B, 17, 0xa679438e); |
545 | OP(B, C, D, A, 22, 0x49b40821); | 296 | OP(B, C, D, A, 22, 0x49b40821); |
546 | # endif /* MD5SUM_SIZE_VS_SPEED == 1 */ | 297 | # endif /* MD5_SIZE_VS_SPEED == 1 */ |
547 | 298 | ||
548 | /* For the second to fourth round we have the possibly swapped words | 299 | /* For the second to fourth round we have the possibly swapped words |
549 | in CORRECT_WORDS. Redefine the macro to take an additional first | 300 | in CORRECT_WORDS. Redefine the macro to take an additional first |
@@ -559,7 +310,7 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
559 | while (0) | 310 | while (0) |
560 | 311 | ||
561 | /* Round 2. */ | 312 | /* Round 2. */ |
562 | # if MD5SUM_SIZE_VS_SPEED == 1 | 313 | # if MD5_SIZE_VS_SPEED == 1 |
563 | pp = P_array; | 314 | pp = P_array; |
564 | for (i = 0; i < 4; i++) { | 315 | for (i = 0; i < 4; i++) { |
565 | OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++); | 316 | OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++); |
@@ -584,10 +335,10 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
584 | OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); | 335 | OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); |
585 | OP(FG, C, D, A, B, 7, 14, 0x676f02d9); | 336 | OP(FG, C, D, A, B, 7, 14, 0x676f02d9); |
586 | OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); | 337 | OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); |
587 | # endif /* MD5SUM_SIZE_VS_SPEED == 1 */ | 338 | # endif /* MD5_SIZE_VS_SPEED == 1 */ |
588 | 339 | ||
589 | /* Round 3. */ | 340 | /* Round 3. */ |
590 | # if MD5SUM_SIZE_VS_SPEED == 1 | 341 | # if MD5_SIZE_VS_SPEED == 1 |
591 | for (i = 0; i < 4; i++) { | 342 | for (i = 0; i < 4; i++) { |
592 | OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); | 343 | OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); |
593 | OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++); | 344 | OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++); |
@@ -611,10 +362,10 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
611 | OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); | 362 | OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); |
612 | OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); | 363 | OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); |
613 | OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); | 364 | OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); |
614 | # endif /* MD5SUM_SIZE_VS_SPEED == 1 */ | 365 | # endif /* MD5_SIZE_VS_SPEED == 1 */ |
615 | 366 | ||
616 | /* Round 4. */ | 367 | /* Round 4. */ |
617 | # if MD5SUM_SIZE_VS_SPEED == 1 | 368 | # if MD5_SIZE_VS_SPEED == 1 |
618 | for (i = 0; i < 4; i++) { | 369 | for (i = 0; i < 4; i++) { |
619 | OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); | 370 | OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); |
620 | OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++); | 371 | OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++); |
@@ -638,8 +389,8 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
638 | OP(FI, D, A, B, C, 11, 10, 0xbd3af235); | 389 | OP(FI, D, A, B, C, 11, 10, 0xbd3af235); |
639 | OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); | 390 | OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); |
640 | OP(FI, B, C, D, A, 9, 21, 0xeb86d391); | 391 | OP(FI, B, C, D, A, 9, 21, 0xeb86d391); |
641 | # endif /* MD5SUM_SIZE_VS_SPEED == 1 */ | 392 | # endif /* MD5_SIZE_VS_SPEED == 1 */ |
642 | # endif /* MD5SUM_SIZE_VS_SPEED > 1 */ | 393 | # endif /* MD5_SIZE_VS_SPEED > 1 */ |
643 | 394 | ||
644 | /* Add the starting values of the context. */ | 395 | /* Add the starting values of the context. */ |
645 | A += A_save; | 396 | A += A_save; |
@@ -661,7 +412,7 @@ static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
661 | * It is NOT required that LEN is a multiple of 64. | 412 | * It is NOT required that LEN is a multiple of 64. |
662 | */ | 413 | */ |
663 | 414 | ||
664 | static void md5_hash_bytes(const void *buffer, size_t len, struct md5_ctx_t *ctx) | 415 | static void md5_hash_bytes(const void *buffer, size_t len, md5_ctx_t *ctx) |
665 | { | 416 | { |
666 | /* When we already have some bits in our internal buffer concatenate | 417 | /* When we already have some bits in our internal buffer concatenate |
667 | both inputs first. */ | 418 | both inputs first. */ |
@@ -698,12 +449,12 @@ static void md5_hash_bytes(const void *buffer, size_t len, struct md5_ctx_t *ctx | |||
698 | } | 449 | } |
699 | } | 450 | } |
700 | 451 | ||
701 | static void md5_hash(const void *buffer, size_t length, void *md5_ctx) | 452 | void md5_hash(const void *data, size_t length, md5_ctx_t *ctx) |
702 | { | 453 | { |
703 | if (length % 64 == 0) { | 454 | if (length % 64 == 0) { |
704 | md5_hash_block(buffer, length, md5_ctx); | 455 | md5_hash_block(data, length, ctx); |
705 | } else { | 456 | } else { |
706 | md5_hash_bytes(buffer, length, md5_ctx); | 457 | md5_hash_bytes(data, length, ctx); |
707 | } | 458 | } |
708 | } | 459 | } |
709 | 460 | ||
@@ -715,7 +466,7 @@ static void md5_hash(const void *buffer, size_t length, void *md5_ctx) | |||
715 | * IMPORTANT: On some systems it is required that RESBUF is correctly | 466 | * IMPORTANT: On some systems it is required that RESBUF is correctly |
716 | * aligned for a 32 bits value. | 467 | * aligned for a 32 bits value. |
717 | */ | 468 | */ |
718 | static void *md5_end(void *resbuf, struct md5_ctx_t *ctx) | 469 | void *md5_end(void *resbuf, md5_ctx_t *ctx) |
719 | { | 470 | { |
720 | /* Take yet unprocessed bytes into account. */ | 471 | /* Take yet unprocessed bytes into account. */ |
721 | uint32_t bytes = ctx->buflen; | 472 | uint32_t bytes = ctx->buflen; |
@@ -727,12 +478,12 @@ static void *md5_end(void *resbuf, struct md5_ctx_t *ctx) | |||
727 | ++ctx->total[1]; | 478 | ++ctx->total[1]; |
728 | 479 | ||
729 | pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; | 480 | pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; |
730 | # if MD5SUM_SIZE_VS_SPEED > 0 | 481 | # if MD5_SIZE_VS_SPEED > 0 |
731 | memset(&ctx->buffer[bytes], 0, pad); | 482 | memset(&ctx->buffer[bytes], 0, pad); |
732 | ctx->buffer[bytes] = 0x80; | 483 | ctx->buffer[bytes] = 0x80; |
733 | # else | 484 | # else |
734 | memcpy(&ctx->buffer[bytes], fillbuf, pad); | 485 | memcpy(&ctx->buffer[bytes], fillbuf, pad); |
735 | # endif /* MD5SUM_SIZE_VS_SPEED > 0 */ | 486 | # endif /* MD5_SIZE_VS_SPEED > 0 */ |
736 | 487 | ||
737 | /* Put the 64-bit file length in *bits* at the end of the buffer. */ | 488 | /* Put the 64-bit file length in *bits* at the end of the buffer. */ |
738 | *(uint32_t *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3); | 489 | *(uint32_t *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3); |
@@ -756,96 +507,4 @@ static void *md5_end(void *resbuf, struct md5_ctx_t *ctx) | |||
756 | 507 | ||
757 | return resbuf; | 508 | return resbuf; |
758 | } | 509 | } |
759 | #endif /* CONFIG_MD5SUM */ | ||
760 | |||
761 | |||
762 | |||
763 | |||
764 | extern int hash_fd(int src_fd, const size_t size, const uint8_t hash_algo, | ||
765 | uint8_t * hashval) | ||
766 | { | ||
767 | int result = EXIT_SUCCESS; | ||
768 | // size_t hashed_count = 0; | ||
769 | size_t blocksize = 0; | ||
770 | size_t remaining = size; | ||
771 | unsigned char *buffer = NULL; | ||
772 | void (*hash_fn_ptr)(const void *, size_t, void *) = NULL; | ||
773 | void *cx = NULL; | ||
774 | |||
775 | #ifdef CONFIG_SHA1SUM | ||
776 | struct sha1_ctx_t sha1_cx; | ||
777 | #endif | ||
778 | #ifdef CONFIG_MD5SUM | ||
779 | struct md5_ctx_t md5_cx; | ||
780 | #endif | ||
781 | |||
782 | |||
783 | #ifdef CONFIG_SHA1SUM | ||
784 | if (hash_algo == HASH_SHA1) { | ||
785 | /* Ensure that BLOCKSIZE is a multiple of 64. */ | ||
786 | blocksize = 65536; | ||
787 | buffer = xmalloc(blocksize); | ||
788 | hash_fn_ptr = sha1_hash; | ||
789 | cx = &sha1_cx; | ||
790 | } | ||
791 | #endif | ||
792 | #ifdef CONFIG_MD5SUM | ||
793 | if (hash_algo == HASH_MD5) { | ||
794 | blocksize = 4096; | ||
795 | buffer = xmalloc(blocksize + 72); | ||
796 | hash_fn_ptr = md5_hash; | ||
797 | cx = &md5_cx; | ||
798 | } | ||
799 | #endif | ||
800 | |||
801 | /* Initialize the computation context. */ | ||
802 | #ifdef CONFIG_SHA1SUM | ||
803 | if (hash_algo == HASH_SHA1) { | ||
804 | sha1_begin(&sha1_cx); | ||
805 | } | ||
806 | #endif | ||
807 | #ifdef CONFIG_MD5SUM | ||
808 | if (hash_algo == HASH_MD5) { | ||
809 | md5_begin(&md5_cx); | ||
810 | } | ||
811 | #endif | ||
812 | /* Iterate over full file contents. */ | ||
813 | while ((remaining == (size_t) -1) || (remaining > 0)) { | ||
814 | size_t read_try; | ||
815 | ssize_t read_got; | ||
816 | |||
817 | if (remaining > blocksize) { | ||
818 | read_try = blocksize; | ||
819 | } else { | ||
820 | read_try = remaining; | ||
821 | } | ||
822 | read_got = bb_full_read(src_fd, buffer, read_try); | ||
823 | if (read_got < 1) { | ||
824 | /* count == 0 means short read | ||
825 | * count == -1 means read error */ | ||
826 | result = read_got - 1; | ||
827 | break; | ||
828 | } | ||
829 | if (remaining != (size_t) -1) { | ||
830 | remaining -= read_got; | ||
831 | } | ||
832 | |||
833 | /* Process buffer */ | ||
834 | hash_fn_ptr(buffer, read_got, cx); | ||
835 | } | ||
836 | 510 | ||
837 | /* Finalize and write the hash into our buffer. */ | ||
838 | #ifdef CONFIG_SHA1SUM | ||
839 | if (hash_algo == HASH_SHA1) { | ||
840 | sha1_end(hashval, &sha1_cx); | ||
841 | } | ||
842 | #endif | ||
843 | #ifdef CONFIG_MD5SUM | ||
844 | if (hash_algo == HASH_MD5) { | ||
845 | md5_end(hashval, &md5_cx); | ||
846 | } | ||
847 | #endif | ||
848 | |||
849 | free(buffer); | ||
850 | return result; | ||
851 | } | ||
diff --git a/libbb/sha1.c b/libbb/sha1.c new file mode 100644 index 000000000..f0d952f84 --- /dev/null +++ b/libbb/sha1.c | |||
@@ -0,0 +1,200 @@ | |||
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) 2002 Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. | ||
6 | * Copyright (C) 2003 Glenn L. McGrath | ||
7 | * Copyright (C) 2003 Erik Andersen | ||
8 | * | ||
9 | * LICENSE TERMS | ||
10 | * | ||
11 | * The free distribution and use of this software in both source and binary | ||
12 | * form is allowed (with or without changes) provided that: | ||
13 | * | ||
14 | * 1. distributions of this source code include the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer; | ||
16 | * | ||
17 | * 2. distributions in binary form include the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer | ||
19 | * in the documentation and/or other associated materials; | ||
20 | * | ||
21 | * 3. the copyright holder's name is not used to endorse products | ||
22 | * built using this software without specific written permission. | ||
23 | * | ||
24 | * ALTERNATIVELY, provided that this notice is retained in full, this product | ||
25 | * may be distributed under the terms of the GNU General Public License (GPL), | ||
26 | * in which case the provisions of the GPL apply INSTEAD OF those given above. | ||
27 | * | ||
28 | * DISCLAIMER | ||
29 | * | ||
30 | * This software is provided 'as is' with no explicit or implied warranties | ||
31 | * in respect of its properties, including, but not limited to, correctness | ||
32 | * and/or fitness for purpose. | ||
33 | * --------------------------------------------------------------------------- | ||
34 | * Issue Date: 10/11/2002 | ||
35 | * | ||
36 | * This is a byte oriented version of SHA1 that operates on arrays of bytes | ||
37 | * stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor | ||
38 | */ | ||
39 | |||
40 | #include <fcntl.h> | ||
41 | #include <limits.h> | ||
42 | #include <stdio.h> | ||
43 | #include <stdint.h> | ||
44 | #include <stdlib.h> | ||
45 | #include <string.h> | ||
46 | #include <unistd.h> | ||
47 | |||
48 | #include "busybox.h" | ||
49 | |||
50 | # define SHA1_BLOCK_SIZE 64 | ||
51 | # define SHA1_DIGEST_SIZE 20 | ||
52 | # define SHA1_HASH_SIZE SHA1_DIGEST_SIZE | ||
53 | # define SHA2_GOOD 0 | ||
54 | # define SHA2_BAD 1 | ||
55 | |||
56 | # define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) | ||
57 | |||
58 | # define SHA1_MASK (SHA1_BLOCK_SIZE - 1) | ||
59 | |||
60 | /* reverse byte order in 32-bit words */ | ||
61 | #define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) | ||
62 | #define parity(x,y,z) ((x) ^ (y) ^ (z)) | ||
63 | #define maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) | ||
64 | |||
65 | /* A normal version as set out in the FIPS. This version uses */ | ||
66 | /* partial loop unrolling and is optimised for the Pentium 4 */ | ||
67 | # define rnd(f,k) \ | ||
68 | t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \ | ||
69 | e = d; d = c; c = rotl32(b, 30); b = t | ||
70 | |||
71 | |||
72 | static void sha1_compile(sha1_ctx_t *ctx) | ||
73 | { | ||
74 | uint32_t w[80], i, a, b, c, d, e, t; | ||
75 | |||
76 | /* note that words are compiled from the buffer into 32-bit */ | ||
77 | /* words in big-endian order so an order reversal is needed */ | ||
78 | /* here on little endian machines */ | ||
79 | for (i = 0; i < SHA1_BLOCK_SIZE / 4; ++i) | ||
80 | w[i] = htonl(ctx->wbuf[i]); | ||
81 | |||
82 | for (i = SHA1_BLOCK_SIZE / 4; i < 80; ++i) | ||
83 | w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); | ||
84 | |||
85 | a = ctx->hash[0]; | ||
86 | b = ctx->hash[1]; | ||
87 | c = ctx->hash[2]; | ||
88 | d = ctx->hash[3]; | ||
89 | e = ctx->hash[4]; | ||
90 | |||
91 | for (i = 0; i < 20; ++i) { | ||
92 | rnd(ch, 0x5a827999); | ||
93 | } | ||
94 | |||
95 | for (i = 20; i < 40; ++i) { | ||
96 | rnd(parity, 0x6ed9eba1); | ||
97 | } | ||
98 | |||
99 | for (i = 40; i < 60; ++i) { | ||
100 | rnd(maj, 0x8f1bbcdc); | ||
101 | } | ||
102 | |||
103 | for (i = 60; i < 80; ++i) { | ||
104 | rnd(parity, 0xca62c1d6); | ||
105 | } | ||
106 | |||
107 | ctx->hash[0] += a; | ||
108 | ctx->hash[1] += b; | ||
109 | ctx->hash[2] += c; | ||
110 | ctx->hash[3] += d; | ||
111 | ctx->hash[4] += e; | ||
112 | } | ||
113 | |||
114 | void sha1_begin(sha1_ctx_t *ctx) | ||
115 | { | ||
116 | ctx->count[0] = ctx->count[1] = 0; | ||
117 | ctx->hash[0] = 0x67452301; | ||
118 | ctx->hash[1] = 0xefcdab89; | ||
119 | ctx->hash[2] = 0x98badcfe; | ||
120 | ctx->hash[3] = 0x10325476; | ||
121 | ctx->hash[4] = 0xc3d2e1f0; | ||
122 | } | ||
123 | |||
124 | /* SHA1 hash data in an array of bytes into hash buffer and call the */ | ||
125 | /* hash_compile function as required. */ | ||
126 | void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) | ||
127 | { | ||
128 | uint32_t pos = (uint32_t) (ctx->count[0] & SHA1_MASK); | ||
129 | uint32_t freeb = SHA1_BLOCK_SIZE - pos; | ||
130 | const unsigned char *sp = data; | ||
131 | |||
132 | if ((ctx->count[0] += length) < length) | ||
133 | ++(ctx->count[1]); | ||
134 | |||
135 | while (length >= freeb) { /* tranfer whole blocks while possible */ | ||
136 | memcpy(((unsigned char *) ctx->wbuf) + pos, sp, freeb); | ||
137 | sp += freeb; | ||
138 | length -= freeb; | ||
139 | freeb = SHA1_BLOCK_SIZE; | ||
140 | pos = 0; | ||
141 | sha1_compile(ctx); | ||
142 | } | ||
143 | |||
144 | memcpy(((unsigned char *) ctx->wbuf) + pos, sp, length); | ||
145 | } | ||
146 | |||
147 | void *sha1_end(void *resbuf, sha1_ctx_t *ctx) | ||
148 | { | ||
149 | /* SHA1 Final padding and digest calculation */ | ||
150 | #if BB_BIG_ENDIAN | ||
151 | static uint32_t mask[4] = { 0x00000000, 0xff000000, 0xffff0000, 0xffffff00 }; | ||
152 | static uint32_t bits[4] = { 0x80000000, 0x00800000, 0x00008000, 0x00000080 }; | ||
153 | #else | ||
154 | static uint32_t mask[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff }; | ||
155 | static uint32_t bits[4] = { 0x00000080, 0x00008000, 0x00800000, 0x80000000 }; | ||
156 | #endif /* __BYTE_ORDER */ | ||
157 | |||
158 | uint8_t *hval = resbuf; | ||
159 | uint32_t i, cnt = (uint32_t) (ctx->count[0] & SHA1_MASK); | ||
160 | |||
161 | /* mask out the rest of any partial 32-bit word and then set */ | ||
162 | /* the next byte to 0x80. On big-endian machines any bytes in */ | ||
163 | /* the buffer will be at the top end of 32 bit words, on little */ | ||
164 | /* endian machines they will be at the bottom. Hence the AND */ | ||
165 | /* and OR masks above are reversed for little endian systems */ | ||
166 | ctx->wbuf[cnt >> 2] = | ||
167 | (ctx->wbuf[cnt >> 2] & mask[cnt & 3]) | bits[cnt & 3]; | ||
168 | |||
169 | /* we need 9 or more empty positions, one for the padding byte */ | ||
170 | /* (above) and eight for the length count. If there is not */ | ||
171 | /* enough space pad and empty the buffer */ | ||
172 | if (cnt > SHA1_BLOCK_SIZE - 9) { | ||
173 | if (cnt < 60) | ||
174 | ctx->wbuf[15] = 0; | ||
175 | sha1_compile(ctx); | ||
176 | cnt = 0; | ||
177 | } else /* compute a word index for the empty buffer positions */ | ||
178 | cnt = (cnt >> 2) + 1; | ||
179 | |||
180 | while (cnt < 14) /* and zero pad all but last two positions */ | ||
181 | ctx->wbuf[cnt++] = 0; | ||
182 | |||
183 | /* assemble the eight byte counter in the buffer in big-endian */ | ||
184 | /* format */ | ||
185 | |||
186 | ctx->wbuf[14] = htonl((ctx->count[1] << 3) | (ctx->count[0] >> 29)); | ||
187 | ctx->wbuf[15] = htonl(ctx->count[0] << 3); | ||
188 | |||
189 | sha1_compile(ctx); | ||
190 | |||
191 | /* extract the hash value as bytes in case the hash buffer is */ | ||
192 | /* misaligned for 32-bit words */ | ||
193 | |||
194 | for (i = 0; i < SHA1_DIGEST_SIZE; ++i) | ||
195 | hval[i] = (unsigned char) (ctx->hash[i >> 2] >> 8 * (~i & 3)); | ||
196 | |||
197 | return resbuf; | ||
198 | } | ||
199 | |||
200 | |||