aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2006-02-21 06:44:43 +0000
committerRob Landley <rob@landley.net>2006-02-21 06:44:43 +0000
commit5cf7c2df668d25c41a05670edd08558226f0bfdf (patch)
tree3c3a7b2aa31dd4105f15f435a5894c91c941686e
parenta7e3d0520856db27744b4a33e786123d44bf5b2a (diff)
downloadbusybox-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.in1
-rw-r--r--coreutils/Config.in15
-rw-r--r--coreutils/md5_sha1_sum.c77
-rw-r--r--include/libbb.h26
-rw-r--r--include/platform.h15
-rw-r--r--libbb/Config.in22
-rw-r--r--libbb/md5.c (renamed from libbb/hash_fd.c)425
-rw-r--r--libbb/sha1.c200
8 files changed, 356 insertions, 425 deletions
diff --git a/Config.in b/Config.in
index 070085b94..e1d5020a7 100644
--- a/Config.in
+++ b/Config.in
@@ -322,6 +322,7 @@ source networking/Config.in
322source procps/Config.in 322source procps/Config.in
323source shell/Config.in 323source shell/Config.in
324source sysklogd/Config.in 324source sysklogd/Config.in
325source libbb/Config.in
325 326
326menu 'Debugging Options' 327menu '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
318config 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
333config CONFIG_MKDIR 318config 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
18typedef 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
38static uint8_t *hash_file(const char *filename, uint8_t hash_algo) 39static 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 */
58static int hash_files(int argc, char **argv, const uint8_t hash_algo) 93static 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,
464extern int get_terminal_width_height(int fd, int *width, int *height); 464extern int get_terminal_width_height(int fd, int *width, int *height);
465extern unsigned long get_ug_id(const char *s, long (*__bb_getxxnam)(const char *)); 465extern unsigned long get_ug_id(const char *s, long (*__bb_getxxnam)(const char *));
466 466
467#define HASH_SHA1 1 467typedef struct _sha1_ctx_t_ {
468#define HASH_MD5 2 468 uint32_t count[2];
469extern 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
473void sha1_begin(sha1_ctx_t *ctx);
474void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx);
475void *sha1_end(void *resbuf, sha1_ctx_t *ctx);
476
477typedef 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
487void md5_begin(md5_ctx_t *ctx);
488void md5_hash(const void *data, size_t length, md5_ctx_t *ctx);
489void *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
6menu "Busybox Library Tuning"
7
8config 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
22endmenu
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 */
97struct sha1_ctx_t {
98 uint32_t count[2];
99 uint32_t hash[5];
100 uint32_t wbuf[16];
101};
102
103static 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
145static 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. */
157static 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
181static uint32_t mask[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
182static uint32_t bits[4] = { 0x00000080, 0x00008000, 0x00800000, 0x80000000 };
183# else
184static uint32_t mask[4] = { 0x00000000, 0xff000000, 0xffff0000, 0xffffff00 };
185static uint32_t bits[4] = { 0x80000000, 0x00800000, 0x00008000, 0x00000080 };
186# endif /* __BYTE_ORDER */
187
188static 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) */
280static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; 42static 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. */
284struct 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 */
297static void md5_begin(struct md5_ctx_t *ctx) 48void 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 */
323static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx) 74void 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
664static void md5_hash_bytes(const void *buffer, size_t len, struct md5_ctx_t *ctx) 415static 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
701static void md5_hash(const void *buffer, size_t length, void *md5_ctx) 452void 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 */
718static void *md5_end(void *resbuf, struct md5_ctx_t *ctx) 469void *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
764extern 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
72static 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
114void 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. */
126void 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
147void *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