3 * General hashing tool. */
5 /* nettle, low-level cryptographics library
7 * Copyright (C) 2011 Niels Möller
9 * The nettle library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or (at your
12 * option) any later version.
14 * The nettle library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the nettle library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
34 #include "nettle-meta.h"
43 list_algorithms (void)
46 const struct nettle_hash
*alg
;
47 printf ("%10s digestsize (internal block size), in units of octets\n", "name");
49 for (i
= 0; (alg
= nettle_hashes
[i
]); i
++)
50 printf ("%10s %d (%d)\n",
51 alg
->name
, alg
->digest_size
, alg
->block_size
);
54 static const struct nettle_hash
*
55 find_algorithm (const char *name
)
57 const struct nettle_hash
*alg
;
60 for (i
= 0; (alg
= nettle_hashes
[i
]); i
++)
61 if (!strcmp(name
, alg
->name
))
67 /* Also in examples/io.c */
69 hash_file(const struct nettle_hash
*hash
, void *ctx
, FILE *f
)
74 size_t res
= fread(buffer
, 1, sizeof(buffer
), f
);
78 hash
->update(ctx
, res
, buffer
);
85 digest_file(const struct nettle_hash
*alg
,
86 unsigned digest_length
, int raw
,
91 ctx
= xalloc(alg
->context_size
);
95 if (!hash_file (alg
, ctx
, f
))
101 digest
= xalloc(digest_length
);
102 alg
->digest(ctx
, digest_length
, digest
);
106 fwrite (digest
, digest_length
, 1, stdout
);
111 char *hex
= xalloc(BASE16_ENCODE_LENGTH(8) + 1);
112 for (i
= 0; i
+ 8 < digest_length
; i
+= 8)
114 base16_encode_update(hex
, 8, digest
+ i
);
115 hex
[BASE16_ENCODE_LENGTH(8)] = 0;
118 base16_encode_update(hex
, digest_length
- i
, digest
+ i
);
119 hex
[BASE16_ENCODE_LENGTH(digest_length
- i
)] = 0;
120 printf("%s %s\n", hex
, alg
->name
);
129 /* FIXME: Be more compatible with md5sum and sha1sum. Options -c
130 (check), -b (binary), -t (text), and output format with hex hash
131 sum, optional star (meaning binary mode), and file name. */
133 main (int argc
, char **argv
)
135 const char *alg_name
= NULL
;
136 const struct nettle_hash
*alg
;
141 enum { OPT_HELP
= 0x300, OPT_RAW
, OPT_LIST
};
142 static const struct option options
[] =
144 /* Name, args, flag, val */
145 { "help", no_argument
, NULL
, OPT_HELP
},
146 { "version", no_argument
, NULL
, 'V' },
147 { "algorithm", required_argument
, NULL
, 'a' },
148 { "length", required_argument
, NULL
, 'l' },
149 { "list", no_argument
, NULL
, OPT_LIST
},
150 { "raw", no_argument
, NULL
, OPT_RAW
},
155 while ( (c
= getopt_long(argc
, argv
, "Va:l:", options
, NULL
)) != -1)
161 printf("nettle-hash -a ALGORITHM [OPTIONS] [FILE ...]\n"
163 " --help Show this help.\n"
164 " -V, --version Show version information.\n"
165 " --list List supported hash algorithms.\n"
166 " -a, --algorithm=ALG Hash algorithm to use.\n"
167 " -l, --length=LENGTH Desired digest length (octets)\n"
168 " --raw Raw binary output.\n");
171 printf("nettle-hash (" PACKAGE_STRING
")\n");
181 die ("Invalid length argument: `%s'\n", optarg
);
194 die("Algorithm argument (-a option) is mandatory.\n"
195 "See nettle-hash --help for further information.\n");
197 alg
= find_algorithm (alg_name
);
199 die("Hash algorithm `%s' not supported or .\n"
200 "Use nettle-hash --list to list available algorithms.\n",
204 length
= alg
->digest_size
;
205 else if (length
> alg
->digest_size
)
206 die ("Length argument %d too large for selected algorithm.\n",
213 digest_file (alg
, length
, raw
, stdin
);
217 for (i
= 0; i
< argc
; i
++)
219 FILE *f
= fopen (argv
[i
], "rb");
221 die ("Cannot open `%s': %s\n", argv
[i
], STRERROR(errno
));
222 printf("%s: ", argv
[i
]);
223 if (!digest_file (alg
, length
, raw
, f
))
224 die("Reading `%s' failed: %s\n", argv
[i
], STRERROR(errno
));
228 if (fflush(stdout
) != 0 )
229 die("Write failed: %s\n", STRERROR(errno
));