Merge pull request #203 from libtom/improve/crypt

Improve hashsum
This commit is contained in:
Steffen Jaeckel 2017-05-04 16:03:57 +02:00 committed by GitHub
commit 87be6d3d70
4 changed files with 250 additions and 55 deletions

View File

@ -32,7 +32,7 @@ fi
./sizes ./sizes
./constants ./constants
for i in $(./hashsum | tail -n +3 | awk '{print $1}' | sort); do echo -n "$i: " && ./hashsum $i testprof/test.key ; done > hashsum_tv.txt for i in $(for j in $(echo $(./hashsum -h | tail -n +3)); do echo $j; done | sort); do echo -n "$i: " && ./hashsum -a $i testprof/test.key ; done > hashsum_tv.txt
difftroubles=$(diff -i -w -B hashsum_tv.txt notes/hashsum_tv.txt | grep '^<') || true difftroubles=$(diff -i -w -B hashsum_tv.txt notes/hashsum_tv.txt | grep '^<') || true
if [ -n "$difftroubles" ]; then if [ -n "$difftroubles" ]; then
echo "FAILURE: hashsum_tv.tx" echo "FAILURE: hashsum_tv.tx"

View File

@ -9,37 +9,232 @@
#include <tomcrypt.h> #include <tomcrypt.h>
int errno; #if _POSIX_C_SOURCE >= 200112L
#include <libgen.h>
#else
#define basename(x) x
#endif
void register_algs(void); /* thanks http://stackoverflow.com/a/8198009 */
#define _base(x) ((x >= '0' && x <= '9') ? '0' : \
(x >= 'a' && x <= 'f') ? 'a' - 10 : \
(x >= 'A' && x <= 'F') ? 'A' - 10 : \
'\255')
#define HEXOF(x) (x - _base(x))
int main(int argc, char **argv) static void register_algs(void);
static char* hashsum;
static void die(int status)
{ {
int idx, z;
unsigned long w, x; unsigned long w, x;
unsigned char hash_buffer[MAXBLOCKSIZE]; FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
fprintf(o, "usage: %s -a algorithm [-c] [file...]\n", hashsum);
/* You need to register algorithms before using them */ fprintf(o, "Algorithms:\n");
register_algs(); w = 0;
if (argc < 2) {
printf("usage: ./hash algorithm file [file ...]\n");
printf("Algorithms:\n");
for (x = 0; hash_descriptor[x].name != NULL; x++) { for (x = 0; hash_descriptor[x].name != NULL; x++) {
printf(" %s (%d)\n", hash_descriptor[x].name, hash_descriptor[x].ID); w += fprintf(o, "%-14s", hash_descriptor[x].name);
if (w >= 70) {
fprintf(o, "\n");
w = 0;
}
}
if (w != 0) fprintf(o, "\n");
free(hashsum);
exit(status);
}
static void printf_hex(unsigned char* hash_buffer, unsigned long w)
{
unsigned long x;
for (x = 0; x < w; x++) {
printf("%02x",hash_buffer[x]);
}
}
static void check_file(int argn, int argc, char **argv)
{
int err, failed, invalid;
unsigned char is_buffer[MAXBLOCKSIZE], should_buffer[MAXBLOCKSIZE];
char buf[PATH_MAX + (MAXBLOCKSIZE * 3)];
/* iterate through all files */
while(argn < argc) {
char* s;
FILE* f = fopen(argv[argn], "rb");
if(f == NULL) {
int n = snprintf(buf, sizeof(buf), "%s: %s", hashsum, argv[argn]);
if (n > 0 && n < (int)sizeof(buf))
perror(buf);
else
perror(argv[argn]);
exit(EXIT_FAILURE);
}
failed = 0;
invalid = 0;
/* read the file line by line */
while((s = fgets(buf, sizeof(buf), f)) != NULL)
{
int tries, n;
unsigned long hash_len, w, x;
char* space = strstr(s, " ");
if (space == NULL) {
fprintf(stderr, "%s: no properly formatted checksum lines found\n", hashsum);
goto ERR;
}
hash_len = space - s;
hash_len /= 2;
/* convert the hex-string back to binary */
for (x = 0; x < hash_len; ++x) {
should_buffer[x] = HEXOF(s[x*2]) << 4 | HEXOF(s[x*2 + 1]);
}
space++;
if (*space != '*') {
fprintf(stderr, "%s: unsupported input mode '%c'\n", hashsum, *space);
goto ERR;
}
space++;
for (n = 0; n < (buf + sizeof(buf)) - space; ++n) {
if(iscntrl(space[n])) {
space[n] = '\0';
break;
}
}
/* try all hash algorithms that have the appropriate hash size */
tries = 0;
for (x = 0; hash_descriptor[x].name != NULL; ++x) {
if (hash_descriptor[x].hashsize == hash_len) {
tries++;
w = sizeof(is_buffer);
if ((err = hash_file(x, space, is_buffer, &w)) != CRYPT_OK) {
fprintf(stderr, "%s: File hash error: %s: %s\n", hashsum, space, error_to_string(err));
ERR:
fclose(f);
exit(EXIT_FAILURE);
}
if(XMEMCMP(should_buffer, is_buffer, w) == 0) {
printf("%s: OK\n", space);
break;
}
}
} /* for */
if (hash_descriptor[x].name == NULL) {
if(tries > 0) {
printf("%s: FAILED\n", space);
failed++;
}
else {
invalid++;
}
}
} /* while */
fclose(f);
if(invalid) {
fprintf(stderr, "%s: WARNING: %d %s is improperly formatted\n", hashsum, invalid, invalid > 1?"lines":"line");
}
if(failed) {
fprintf(stderr, "%s: WARNING: %d computed %s did NOT match\n", hashsum, failed, failed > 1?"checksums":"checksum");
}
argn++;
} }
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
idx = find_hash(argv[1]); int main(int argc, char **argv)
if (idx == -1) { {
fprintf(stderr, "\nInvalid hash specified on command line.\n"); int idx, check, z, err, argn;
return -1; unsigned long w, x;
unsigned char hash_buffer[MAXBLOCKSIZE];
hashsum = strdup(basename(argv[0]));
/* You need to register algorithms before using them */
register_algs();
if (argc > 1 && (strcmp("-h", argv[1]) == 0 || strcmp("--help", argv[1]) == 0)) {
die(EXIT_SUCCESS);
}
if (argc < 3) {
die(EXIT_FAILURE);
} }
if (argc == 2) { argn = 1;
check = 0;
idx = -2;
while(argn < argc){
if(strcmp("-a", argv[argn]) == 0) {
argn++;
if(argn < argc) {
idx = find_hash(argv[argn]);
if (idx == -1) {
struct {
const char* is;
const char* should;
} shasum_compat[] =
{
#ifdef LTC_SHA1
{ "1", sha1_desc.name },
#endif
#ifdef LTC_SHA224
{ "224", sha224_desc.name },
#endif
#ifdef LTC_SHA256
{ "256", sha256_desc.name },
#endif
#ifdef LTC_SHA384
{ "384", sha384_desc.name },
#endif
#ifdef LTC_SHA512
{ "512", sha512_desc.name },
#endif
#ifdef LTC_SHA512_224
{ "512224", sha512_224_desc.name },
#endif
#ifdef LTC_SHA512_256
{ "512256", sha512_256_desc.name },
#endif
{ NULL, NULL }
};
for (x = 0; shasum_compat[x].is != NULL; ++x) {
if(XSTRCMP(shasum_compat[x].is, argv[argn]) == 0) {
idx = find_hash(shasum_compat[x].should);
break;
}
}
}
if (idx == -1) {
fprintf(stderr, "%s: Unrecognized algorithm\n", hashsum);
die(EXIT_FAILURE);
}
argn++;
continue;
}
else {
die(EXIT_FAILURE);
}
}
if(strcmp("-c", argv[argn]) == 0) {
check = 1;
argn++;
continue;
}
break;
}
if (check == 1) {
check_file(argn, argc, argv);
}
if (argc == argn) {
w = sizeof(hash_buffer); w = sizeof(hash_buffer);
if ((errno = hash_filehandle(idx, stdin, hash_buffer, &w)) != CRYPT_OK) { if ((err = hash_filehandle(idx, stdin, hash_buffer, &w)) != CRYPT_OK) {
printf("File hash error: %s\n", error_to_string(errno)); fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err));
return EXIT_FAILURE;
} else { } else {
for (x = 0; x < w; x++) { for (x = 0; x < w; x++) {
printf("%02x",hash_buffer[x]); printf("%02x",hash_buffer[x]);
@ -47,14 +242,13 @@ int main(int argc, char **argv)
printf(" *-\n"); printf(" *-\n");
} }
} else { } else {
for (z = 2; z < argc; z++) { for (z = 3; z < argc; z++) {
w = sizeof(hash_buffer); w = sizeof(hash_buffer);
if ((errno = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) { if ((err = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) {
printf("File hash error: %s\n", error_to_string(errno)); fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err));
return EXIT_FAILURE;
} else { } else {
for (x = 0; x < w; x++) { printf_hex(hash_buffer, w);
printf("%02x",hash_buffer[x]);
}
printf(" *%s\n", argv[z]); printf(" *%s\n", argv[z]);
} }
} }
@ -62,7 +256,7 @@ int main(int argc, char **argv)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
void register_algs(void) static void register_algs(void)
{ {
int err; int err;
LTC_UNUSED_PARAM(err); LTC_UNUSED_PARAM(err);

View File

@ -52,14 +52,15 @@ int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outle
goto LBL_ERR; goto LBL_ERR;
} }
*outlen = hash_descriptor[hash].hashsize;
do { do {
x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = hash_descriptor[hash].process(&md, buf, (unsigned long)x)) != CRYPT_OK) { if ((err = hash_descriptor[hash].process(&md, buf, (unsigned long)x)) != CRYPT_OK) {
goto LBL_CLEANBUF; goto LBL_CLEANBUF;
} }
} while (x == LTC_FILE_READ_BUFSIZE); } while (x == LTC_FILE_READ_BUFSIZE);
err = hash_descriptor[hash].done(&md, out); if ((err = hash_descriptor[hash].done(&md, out)) == CRYPT_OK) {
*outlen = hash_descriptor[hash].hashsize;
}
LBL_CLEANBUF: LBL_CLEANBUF:
zeromem(buf, LTC_FILE_READ_BUFSIZE); zeromem(buf, LTC_FILE_READ_BUFSIZE);