crhash: whirlpool: remove C[][] definition -- unused
[crhash.git] / main.c
bloba33d787c5e5ea7d5ff918c680cf61bba936eba63
1 #include <fcntl.h>
2 #include <getopt.h>
3 #include <inttypes.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/mman.h>
9 #include <sys/stat.h>
10 #include <sys/types.h>
12 #include "hash-md5.h"
13 #include "hash-whirlpool.h"
15 static int rv;
17 static const char *hash;
18 struct hash_algo {
19 const char *name;
20 unsigned int block_size; /* in bits */
21 unsigned int digest_size; /* in bits */
22 void *(*init_context)(void);
23 void (*fini_context)(void *ctx);
24 void (*update)(void *ctx, const uint8_t *m);
25 void (*_update)(void *ctx, const uint8_t *m, unsigned int len);
26 void (*fini)(void *ctx);
27 void (*digest)(void *ctx, uint8_t *digest);
30 static const struct hash_algo _hash_algo[] = {
32 .name = "md5",
33 .block_size = 512,
34 .digest_size = 128,
35 .init_context = md5_init_context,
36 .fini_context = md5_fini_context,
37 .update = md5_update,
38 ._update = _md5_update,
39 .fini = md5_fini,
40 .digest = md5_digest,
43 .name = "whirlpool",
44 .block_size = 512,
45 .digest_size = 512,
46 .init_context = whirlpool_init_context,
47 .fini_context = whirlpool_fini_context,
48 .update = whirlpool_update,
49 ._update = _whirlpool_update,
50 .fini = whirlpool_fini,
51 .digest = whirlpool_digest,
55 static const struct hash_algo *find_hash_algo(const char *name)
57 int i;
59 for (i = 0; i < sizeof(_hash_algo) / sizeof(_hash_algo[0]); i++) {
60 if (strcmp(name, _hash_algo[i].name) == 0)
61 return &_hash_algo[i];
63 return NULL;
66 static void _hash_file(const struct hash_algo *hash_algo, const uint8_t *m, uintmax_t len)
68 uint8_t *digest;
69 void *ctx;
71 digest = malloc(hash_algo->digest_size / 8);
72 if (!digest) {
73 perror("malloc");
74 rv = EXIT_FAILURE;
75 return;
78 ctx = hash_algo->init_context();
79 if (!ctx) {
80 perror("->init");
81 free(digest);
82 rv = EXIT_FAILURE;
83 return;
85 while (len >= hash_algo->block_size / 8) {
86 hash_algo->update(ctx, m);
87 m += hash_algo->block_size / 8;
88 len -= hash_algo->block_size / 8;
90 hash_algo->_update(ctx, m, len);
91 hash_algo->fini(ctx);
92 hash_algo->digest(ctx, digest);
93 hash_algo->fini_context(ctx);
95 int i;
97 for (i = 0; i < hash_algo->digest_size / 8; i++)
98 printf("%02x", digest[i]);
99 printf("\n");
103 static void hash_file(const struct hash_algo *hash_algo, const char *filename)
105 int fd;
106 struct stat st;
107 uintmax_t len;
108 uint8_t *p;
110 fd = open(filename, O_RDONLY);
111 if (fd == -1) {
112 perror(filename);
113 rv = EXIT_FAILURE;
114 return;
116 if (fstat(fd, &st) == -1) {
117 perror(filename);
118 rv = EXIT_FAILURE;
119 return;
121 if (st.st_size < 0) {
122 fprintf(stderr, "st_size %" PRIdMAX "\n", (intmax_t)st.st_size);
123 rv = EXIT_FAILURE;
124 close(fd);
125 return;
127 len = (uintmax_t)(intmax_t)st.st_size;
128 if (len != (uintmax_t)(size_t)len) {
129 fprintf(stderr, "st_size %" PRIuMAX "\n", len);
130 rv = EXIT_FAILURE;
131 close(fd);
132 return;
134 if (len == 0) {
135 p = NULL;
136 } else {
137 p = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
138 if (p == MAP_FAILED) {
139 perror("mmap");
140 rv = EXIT_FAILURE;
141 close(fd);
142 return;
145 close(fd);
147 _hash_file(hash_algo, p, len);
149 munmap(p, len);
152 int main(int argc, char *argv[])
154 int ch;
155 const struct hash_algo *hash_algo;
157 while ((ch = getopt(argc, argv, "t:")) != -1) {
158 switch (ch) {
159 case 't':
160 hash = optarg;
161 break;
162 default:
163 return EXIT_FAILURE;
167 if (hash) {
168 hash_algo = find_hash_algo(hash);
169 if (!hash_algo) {
170 int i;
172 fprintf(stderr, "unexpected hash algorithm '%s'\n", hash);
173 fprintf(stderr, "expected hash algorithms:");
174 for (i = 0; i < sizeof(_hash_algo) / sizeof(_hash_algo[0]); i++)
175 fprintf(stderr, " %s", _hash_algo[i].name);
176 fprintf(stderr, "\n");
177 exit(EXIT_FAILURE);
179 } else {
180 fprintf(stderr, "hash algorithm required (-t)\n");
181 exit(EXIT_FAILURE);
184 rv = EXIT_SUCCESS;
185 while (optind < argc) {
186 hash_file(hash_algo, argv[optind]);
187 optind++;
189 return rv;