10 #include <sys/types.h>
13 #include "hash-whirlpool.h"
17 static const char *hash
;
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
[] = {
35 .init_context
= md5_init_context
,
36 .fini_context
= md5_fini_context
,
38 ._update
= _md5_update
,
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
)
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
];
66 static void _hash_file(const struct hash_algo
*hash_algo
, const uint8_t *m
, uintmax_t len
)
71 digest
= malloc(hash_algo
->digest_size
/ 8);
78 ctx
= hash_algo
->init_context();
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
);
92 hash_algo
->digest(ctx
, digest
);
93 hash_algo
->fini_context(ctx
);
97 for (i
= 0; i
< hash_algo
->digest_size
/ 8; i
++)
98 printf("%02x", digest
[i
]);
103 static void hash_file(const struct hash_algo
*hash_algo
, const char *filename
)
110 fd
= open(filename
, O_RDONLY
);
116 if (fstat(fd
, &st
) == -1) {
121 if (st
.st_size
< 0) {
122 fprintf(stderr
, "st_size %" PRIdMAX
"\n", (intmax_t)st
.st_size
);
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
);
137 p
= mmap(NULL
, len
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
138 if (p
== MAP_FAILED
) {
147 _hash_file(hash_algo
, p
, len
);
152 int main(int argc
, char *argv
[])
155 const struct hash_algo
*hash_algo
;
157 while ((ch
= getopt(argc
, argv
, "t:")) != -1) {
168 hash_algo
= find_hash_algo(hash
);
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");
180 fprintf(stderr
, "hash algorithm required (-t)\n");
185 while (optind
< argc
) {
186 hash_file(hash_algo
, argv
[optind
]);