2 * shs1file - new NIST Secure Hash Standard-1 (SHS1)
4 * @(#) $Revision: 13.3 $
5 * @(#) $Id: shs1io.c,v 13.3 2006/08/14 11:25:24 chongo Exp $
6 * @(#) $Source: /usr/local/src/cmd/hash/RCS/shs1io.c,v $
8 * This file was written by Landon Curt Noll.
10 * This code has been placed in the public domain. Please do not
11 * copyright this code.
13 * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO
14 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MER-
15 * CHANTABILITY AND FITNESS. IN NO EVENT SHALL LANDON CURT
16 * NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
17 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
19 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * chongo (was here) /\oo/\
23 * http://www.isthe.com/chongo/index.html
25 * Share and enjoy! :-)
27 * See shs1drvr.c for version and modification history.
35 #include <sys/resource.h>
39 /* global variables */
40 ULONG shs1_zero
[SHS1_CHUNKWORDS
]; /* block of zeros */
44 * shs1Stream - digest a open file stream
47 * pre_str data prefix or NULL
48 * pre_len length of pre_str
49 * stream the stream to process
53 shs1Stream(BYTE
*pre_str
, UINT pre_len
, FILE *stream
, SHS1_INFO
*dig
)
55 BYTE data
[SHS1_READSIZE
]; /* our read buffer */
56 unsigned int bytes
; /* bytes last read */
57 int ret
; /* partial fread return value */
60 * pre-process prefix if needed
62 if (pre_str
!= NULL
&& pre_len
> 0) {
63 shs1Update(dig
, pre_str
, pre_len
);
67 * Try to read as much as we can (up to SHS_READSIZE bytes). If there
68 * is data in the hash buffer already, try to read so that we can
69 * perform as many full hash operations as possible.
75 /* determine what we have so far */
78 /* try to read what we need to fill the chunk */
79 while (!feof(stream
) && bytes
< SHS1_READSIZE
) {
81 /* try to read what we need */
84 fprintf(stderr
, "DEBUG: have: %u will try to read: %u\n",
85 bytes
, SHS1_READSIZE
-bytes
);
88 ret
= fread(data
+bytes
, 1, SHS1_READSIZE
-bytes
, stream
);
91 fprintf(stderr
, "DEBUG: fread returrned: %d\n", ret
);
95 /* look read for errors */
96 if (ret
< 0 || ferror(stream
)) {
97 /* error processing */
98 fprintf(stderr
, "%s: ", program
);
99 perror("shs1 read error");
103 /* note that we have more bytes */
107 /* process whatever new data we have in the buffer */
108 if (bytes
> dig
->datalen
) {
109 shs1Update(dig
, data
+dig
->datalen
, bytes
-dig
->datalen
);
111 } while (ret
> 0 && !feof(stream
));
117 * shs1File - digest a file
120 * pre_str string prefix or NULL
121 * pre_len length of pre_str
122 * filename the filename to process
123 * inode 1 => process inode & filename
127 shs1File(BYTE
*pre_str
, UINT pre_len
, char *filename
,
128 int inode
, SHS1_INFO
*dig
)
130 FILE *inFile
; /* the open file stream */
131 struct stat buf
; /* stat or lstat of file */
132 struct shs1_stat hashbuf
; /* stat data to digest */
133 struct shs1_stat hashlbuf
; /* lstat data to digest */
134 ULONG filename_len
; /* length of the filename */
139 inFile
= fopen(filename
, "rb");
140 if (inFile
== NULL
) {
141 fprintf(stderr
, "%s: cannot open %s: ", program
, filename
);
147 * pre-process prefix if needed
149 if (pre_str
== NULL
) {
151 filename_len
= strlen(filename
);
152 shs1Update(dig
, (BYTE
*)filename
, filename_len
);
156 "DEBUG: filename_len:%lu octets:%llu\n",
157 (unsigned long)filename_len
, dig
->octets
);
163 shs1Update(dig
, pre_str
, pre_len
);
164 filename_len
= strlen(filename
);
165 shs1Update(dig
, (BYTE
*)filename
, filename_len
);
169 "DEBUG: pre_len:%lu filename_len:%lu octets:%lld\n",
170 (unsigned long)pre_len
,
171 (unsigned long)filename_len
, dig
->octets
);
175 shs1Update(dig
, pre_str
, pre_len
);
180 * digest file stat and lstat
183 if (fstat(fileno(inFile
), &buf
) < 0) {
184 printf("%s can't be stated.\n", filename
);
187 hashbuf
.stat_dev
= buf
.st_dev
;
188 hashbuf
.stat_ino
= buf
.st_ino
;
189 hashbuf
.stat_mode
= buf
.st_mode
;
190 hashbuf
.stat_nlink
= buf
.st_nlink
;
191 hashbuf
.stat_uid
= buf
.st_uid
;
192 hashbuf
.stat_gid
= buf
.st_gid
;
193 hashbuf
.stat_size
= buf
.st_size
;
194 hashbuf
.stat_mtime
= buf
.st_mtime
;
195 hashbuf
.stat_ctime
= buf
.st_ctime
;
199 "DEBUG: dev:%ld ino:%ld mode:%o nlink:%d uid:%d gid:%d\n",
200 (unsigned long)hashbuf
.stat_dev
,
201 (unsigned long)hashbuf
.stat_ino
,
202 hashbuf
.stat_mode
, hashbuf
.stat_nlink
,
203 hashbuf
.stat_uid
, hashbuf
.stat_gid
);
205 "DEBUG: size:%llu mtime:%llu ctime:%llu\n",
206 (unsigned long long)hashbuf
.stat_size
,
207 (unsigned long long)hashbuf
.stat_mtime
,
208 (unsigned long long)hashbuf
.stat_ctime
);
211 shs1Update(dig
, (BYTE
*)&hashbuf
, sizeof(hashbuf
));
212 if (lstat(filename
, &buf
) < 0) {
213 printf("%s can't be lstated.\n", filename
);
216 hashlbuf
.stat_dev
= buf
.st_dev
;
217 hashlbuf
.stat_ino
= buf
.st_ino
;
218 hashlbuf
.stat_mode
= buf
.st_mode
;
219 hashlbuf
.stat_nlink
= buf
.st_nlink
;
220 hashlbuf
.stat_uid
= buf
.st_uid
;
221 hashlbuf
.stat_gid
= buf
.st_gid
;
222 hashlbuf
.stat_size
= buf
.st_size
;
223 hashlbuf
.stat_mtime
= buf
.st_mtime
;
224 hashlbuf
.stat_ctime
= buf
.st_ctime
;
228 "DEBUG: ldev:%ld lino:%ld mode:%o lnlink:%d luid:%d lgid:%d\n",
229 (unsigned long)hashbuf
.stat_dev
,
230 (unsigned long)hashbuf
.stat_ino
,
231 hashlbuf
.stat_mode
, hashlbuf
.stat_nlink
,
232 hashlbuf
.stat_uid
, hashlbuf
.stat_gid
);
234 "DEBUG: lsize:%llu lmtime:%llu lctime:%llu\n",
235 (unsigned long long)hashlbuf
.stat_size
,
236 (unsigned long long)hashlbuf
.stat_mtime
,
237 (unsigned long long)hashbuf
.stat_ctime
);
240 shs1Update(dig
, (BYTE
*)&hashlbuf
, sizeof(hashlbuf
));
243 * pad with zeros to process file data faster
245 if (dig
->datalen
> 0) {
249 "DEBUG: pad_len:%lu\n",
250 (unsigned long)(SHS1_CHUNKSIZE
- dig
->datalen
));
253 shs1Update(dig
, (BYTE
*)shs1_zero
, SHS1_CHUNKSIZE
- dig
->datalen
);
257 fprintf(stderr
, "DEBUG: datalen:%lu count:%llu\n",
258 (unsigned long)dig
->datalen
, dig
->octets
);
264 * process the data stream
266 shs1Stream(NULL
, 0, inFile
, dig
);