10 #include <sys/types.h>
13 #include "hash-sha1.h"
14 #include "hash-whirlpool.h"
18 static const char *hash
;
21 unsigned int block_size
; /* in bits */
22 unsigned int digest_size
; /* in bits */
23 void *(*init_context
)(void);
24 void (*fini_context
)(void *ctx
);
25 void (*update
)(void *ctx
, const uint8_t *m
);
26 void (*_update
)(void *ctx
, const uint8_t *m
, unsigned int len
);
27 void (*fini
)(void *ctx
);
28 void (*digest
)(void *ctx
, uint8_t *digest
);
31 static const struct hash_algo _hash_algo
[] = {
36 .init_context
= md5_init_context
,
37 .fini_context
= md5_fini_context
,
39 ._update
= _md5_update
,
47 .init_context
= sha1_init_context
,
48 .fini_context
= sha1_fini_context
,
49 .update
= sha1_update
,
50 ._update
= _sha1_update
,
52 .digest
= sha1_digest
,
58 .init_context
= whirlpool_init_context
,
59 .fini_context
= whirlpool_fini_context
,
60 .update
= whirlpool_update
,
61 ._update
= _whirlpool_update
,
62 .fini
= whirlpool_fini
,
63 .digest
= whirlpool_digest
,
67 static const struct hash_algo
*find_hash_algo(const char *name
)
71 for (i
= 0; i
< sizeof(_hash_algo
) / sizeof(_hash_algo
[0]); i
++) {
72 if (strcmp(name
, _hash_algo
[i
].name
) == 0)
73 return &_hash_algo
[i
];
78 static void _hash_file(const struct hash_algo
*hash_algo
, const uint8_t *m
, uintmax_t len
)
83 digest
= malloc(hash_algo
->digest_size
/ 8);
90 ctx
= hash_algo
->init_context();
97 while (len
>= hash_algo
->block_size
/ 8) {
98 hash_algo
->update(ctx
, m
);
99 m
+= hash_algo
->block_size
/ 8;
100 len
-= hash_algo
->block_size
/ 8;
102 hash_algo
->_update(ctx
, m
, len
);
103 hash_algo
->fini(ctx
);
104 hash_algo
->digest(ctx
, digest
);
105 hash_algo
->fini_context(ctx
);
109 for (i
= 0; i
< hash_algo
->digest_size
/ 8; i
++)
110 printf("%02x", digest
[i
]);
115 static void hash_file(const struct hash_algo
*hash_algo
, const char *filename
)
122 fd
= open(filename
, O_RDONLY
);
128 if (fstat(fd
, &st
) == -1) {
133 if (st
.st_size
< 0) {
134 fprintf(stderr
, "st_size %" PRIdMAX
"\n", (intmax_t)st
.st_size
);
139 len
= (uintmax_t)(intmax_t)st
.st_size
;
140 if (len
!= (uintmax_t)(size_t)len
) {
141 fprintf(stderr
, "st_size %" PRIuMAX
"\n", len
);
149 p
= mmap(NULL
, len
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
150 if (p
== MAP_FAILED
) {
156 (void)madvise(p
, len
, MADV_SEQUENTIAL
);
160 _hash_file(hash_algo
, p
, len
);
166 int main(int argc
, char *argv
[])
169 const struct hash_algo
*hash_algo
;
171 while ((ch
= getopt(argc
, argv
, "t:")) != -1) {
182 hash_algo
= find_hash_algo(hash
);
186 fprintf(stderr
, "unexpected hash algorithm '%s'\n", hash
);
187 fprintf(stderr
, "expected hash algorithms:");
188 for (i
= 0; i
< sizeof(_hash_algo
) / sizeof(_hash_algo
[0]); i
++)
189 fprintf(stderr
, " %s", _hash_algo
[i
].name
);
190 fprintf(stderr
, "\n");
194 fprintf(stderr
, "hash algorithm required (-t)\n");
199 while (optind
< argc
) {
200 hash_file(hash_algo
, argv
[optind
]);