1 /* $NetBSD: digest.c,v 1.14 2007/09/14 08:12:29 joerg Exp $ */
4 * Copyright (c) 2001-2005 Alistair G. Crooks. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Alistair G. Crooks.
17 * 4. The name of the author may not be used to endorse or promote
18 * products derived from this software without specific prior written
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 __COPYRIGHT("@(#) Copyright (c) 2001-2005 \
39 The NetBSD Foundation, Inc. All rights reserved.");
40 __RCSID("$NetBSD: digest.c,v 1.14 2007/09/14 08:12:29 joerg Exp $");
58 #include <whirlpool.h>
63 typedef void (*HASH_init
)(void *);
64 typedef void (*HASH_update
)(void *, const uint8_t *, size_t);
65 typedef char *(*HASH_end
)(void *, char *);
66 typedef char *(*HASH_file
)(char *, char *);
68 /* this struct defines a message digest algorithm */
69 typedef struct alg_t
{
73 HASH_update hash_update
;
83 tiger_context_t tiger
;
84 whirlpool_context_t whirlpool
;
85 } hash_ctx
, hash_ctx2
;
88 /* list of supported message digest algorithms */
89 static alg_t algorithms
[] = {
91 (HASH_init
) MD5Init
, (HASH_update
) MD5Update
,
92 (HASH_end
) MD5End
, (HASH_file
) MD5File
},
94 (HASH_init
) RMD160Init
, (HASH_update
) RMD160Update
,
95 (HASH_end
) RMD160End
, (HASH_file
) RMD160File
},
97 (HASH_init
) SHA1Init
, (HASH_update
) SHA1Update
,
98 (HASH_end
) SHA1End
, (HASH_file
) SHA1File
},
99 { "SHA256", SHA256_DIGEST_LENGTH
,
100 (HASH_init
) SHA256_Init
, (HASH_update
) SHA256_Update
,
101 (HASH_end
) SHA256_End
, (HASH_file
) SHA256_File
},
102 { "SHA384", SHA384_DIGEST_LENGTH
,
103 (HASH_init
) SHA384_Init
, (HASH_update
) SHA384_Update
,
104 (HASH_end
) SHA384_End
, (HASH_file
) SHA384_File
},
105 { "SHA512", SHA512_DIGEST_LENGTH
,
106 (HASH_init
) SHA512_Init
, (HASH_update
) SHA512_Update
,
107 (HASH_end
) SHA512_End
, (HASH_file
) SHA512_File
},
109 (HASH_init
) TIGERInit
, (HASH_update
) TIGERUpdate
,
110 (HASH_end
) TIGEREnd
, (HASH_file
) TIGERFile
},
111 { "WHIRLPOOL", WHIRLPOOL_DIGEST_BYTES
,
112 (HASH_init
) whirlpool_init
, (HASH_update
) whirlpool_update
,
113 (HASH_end
) whirlpool_end
, (HASH_file
) whirlpool_file
},
117 /* find an algorithm, given a name */
119 find_algorithm(const char *a
)
123 for (alg
= algorithms
; alg
->name
&& strcasecmp(alg
->name
, a
) != 0 ; alg
++) {
125 return (alg
->name
) ? alg
: NULL
;
128 /* compute a digest, and print the results if successful */
130 digest_file(char *fn
, alg_t
*alg
)
132 char in
[BUFSIZ
* 20];
136 digest
= malloc(alg
->hash_len
* 2 + 1);
139 (*alg
->hash_init
)(&alg
->hash_ctx
);
140 while ((cc
= read(STDIN_FILENO
, in
, sizeof(in
))) > 0) {
141 (*alg
->hash_update
)(&alg
->hash_ctx
, (uint8_t *)in
,
144 (void) printf("%s\n", (*alg
->hash_end
)(&alg
->hash_ctx
, digest
));
147 if ((*alg
->hash_file
)(fn
, digest
) == NULL
) {
150 (void) printf("%s (%s) = %s\n", alg
->name
, fn
, digest
);
161 main(int argc
, char **argv
)
167 #ifdef HAVE_SETLOCALE
168 (void) setlocale(LC_ALL
, "");
170 while ((i
= getopt(argc
, argv
, "V")) != -1) {
173 printf("%s\n", VERSION
);
181 (void) fprintf(stderr
, "Usage: %s algorithm [file...]\n",
185 if ((alg
= find_algorithm(argv
[0])) == NULL
) {
186 (void) fprintf(stderr
, "No such algorithm `%s'\n", argv
[0]);
193 if (!digest_file(NULL
, alg
)) {
194 (void) fprintf(stderr
, "stdin\n");
198 for (i
= 0 ; i
< argc
; i
++) {
199 if (!digest_file(argv
[i
], alg
)) {
200 (void) fprintf(stderr
, "%s\n", argv
[i
]);