summaryrefslogtreecommitdiff
path: root/src/md5sum.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2005-10-23 15:22:02 +0000
committerJim Meyering <jim@meyering.net>2005-10-23 15:22:02 +0000
commit61fa9f0cfe2e5f8d287776f4cd49e21b7ed540a8 (patch)
treef2e69881988934b100bc2dd3b443767ed5ccc951 /src/md5sum.c
parente849be6c8b7a91640a69e811e50184418e150497 (diff)
downloadcoreutils-61fa9f0cfe2e5f8d287776f4cd49e21b7ed540a8.tar.xz
Provide framework for computing sha-2 hashes.
Diffstat (limited to 'src/md5sum.c')
-rw-r--r--src/md5sum.c147
1 files changed, 101 insertions, 46 deletions
diff --git a/src/md5sum.c b/src/md5sum.c
index 5b7a8b00d..7cf2783e8 100644
--- a/src/md5sum.c
+++ b/src/md5sum.c
@@ -1,4 +1,4 @@
-/* Compute MD5 or SHA1 checksum of files or strings
+/* Compute MD5, SHA1, SHA224, SHA256, SHA384 or SHA512 checksum of files or strings
Copyright (C) 1995-2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -24,34 +24,85 @@
#include "system.h"
-#include "md5.h"
-#include "sha1.h"
-#include "checksum.h"
+#if HASH_ALGO_MD5
+# include "md5.h"
+#endif
+#if HASH_ALGO_SHA1
+# include "sha1.h"
+#endif
+#if HASH_ALGO_SHA256 || HASH_ALGO_SHA224
+# include "sha256.h"
+#endif
+#if HASH_ALGO_SHA512 || HASH_ALGO_SHA384
+# include "sha512.h"
+#endif
#include "getline.h"
#include "error.h"
#include "quote.h"
#include "stdio--.h"
/* The official name of this program (e.g., no `g' prefix). */
-#define PROGRAM_NAME (algorithm == ALG_MD5 ? "md5sum" : "sha1sum")
-
-#define AUTHORS "Ulrich Drepper", "Scott Miller"
-
-
-#define DIGEST_TYPE_STRING(Alg) ((Alg) == ALG_MD5 ? "MD5" : "SHA1")
-#define DIGEST_STREAM(Alg) ((Alg) == ALG_MD5 ? md5_stream : sha1_stream)
-
-#define DIGEST_BITS(Alg) ((Alg) == ALG_MD5 ? 128 : 160)
-#define DIGEST_HEX_BYTES(Alg) (DIGEST_BITS (Alg) / 4)
-#define DIGEST_BIN_BYTES(Alg) (DIGEST_BITS (Alg) / 8)
-
-#define MAX_DIGEST_BIN_BYTES MAX (DIGEST_BIN_BYTES (ALG_MD5), \
- DIGEST_BIN_BYTES (ALG_SHA1))
+#if HASH_ALGO_MD5
+# define PROGRAM_NAME "md5sum"
+# define DIGEST_TYPE_STRING "MD5"
+# define DIGEST_STREAM md5_stream
+# define DIGEST_BUFFER md5_buffer
+# define DIGEST_BITS 128
+# define DIGEST_REFERENCE "RFC 1321"
+# define DIGEST_ALIGN 4
+#elif HASH_ALGO_SHA1
+# define PROGRAM_NAME "sha1sum"
+# define DIGEST_TYPE_STRING "SHA1"
+# define DIGEST_STREAM sha1_stream
+# define DIGEST_BUFFER sha1_buffer
+# define DIGEST_BITS 160
+# define DIGEST_REFERENCE "FIPS-180-1"
+# define DIGEST_ALIGN 4
+#elif HASH_ALGO_SHA256
+# define PROGRAM_NAME "sha256sum"
+# define DIGEST_TYPE_STRING "SHA256"
+# define DIGEST_STREAM sha256_stream
+# define DIGEST_BUFFER sha256_buffer
+# define DIGEST_BITS 256
+# define DIGEST_REFERENCE "FIPS-180-2"
+# define DIGEST_ALIGN 4
+#elif HASH_ALGO_SHA224
+# define PROGRAM_NAME "sha224sum"
+# define DIGEST_TYPE_STRING "SHA224"
+# define DIGEST_STREAM sha224_stream
+# define DIGEST_BUFFER sha224_buffer
+# define DIGEST_BITS 224
+# define DIGEST_REFERENCE "RFC 3874"
+# define DIGEST_ALIGN 4
+#elif HASH_ALGO_SHA512
+# define PROGRAM_NAME "sha512sum"
+# define DIGEST_TYPE_STRING "SHA512"
+# define DIGEST_STREAM sha512_stream
+# define DIGEST_BUFFER sha512_buffer
+# define DIGEST_BITS 512
+# define DIGEST_REFERENCE "FIPS-180-2"
+# define DIGEST_ALIGN 8
+#elif HASH_ALGO_SHA384
+# define PROGRAM_NAME "sha384sum"
+# define DIGEST_TYPE_STRING "SHA384"
+# define DIGEST_STREAM sha384_stream
+# define DIGEST_BUFFER sha384_buffer
+# define DIGEST_BITS 384
+# define DIGEST_REFERENCE "FIPS-180-2"
+# define DIGEST_ALIGN 8
+#else
+# error "Can't decide which hash algorithm to compile."
+#endif
+
+#define DIGEST_HEX_BYTES (DIGEST_BITS / 4)
+#define DIGEST_BIN_BYTES (DIGEST_BITS / 8)
+
+#define AUTHORS "Ulrich Drepper", "Scott Miller", "David Madore"
/* The minimum length of a valid digest line. This length does
not include any newline character at the end of a line. */
-#define MIN_DIGEST_LINE_LENGTH(Alg) \
- (DIGEST_HEX_BYTES (Alg) /* length of hexadecimal message digest */ \
+#define MIN_DIGEST_LINE_LENGTH \
+ (DIGEST_HEX_BYTES /* length of hexadecimal message digest */ \
+ 2 /* blank and binary indicator */ \
+ 1 /* minimum filename length */ )
@@ -72,9 +123,6 @@ static bool status_only = false;
improperly formatted checksum line. */
static bool warn = false;
-/* Declared and set via one of the wrapper .c files. */
-/* int algorithm = ALG_UNSPECIFIED; */
-
/* The name this program was run with. */
char *program_name;
@@ -112,8 +160,8 @@ With no FILE, or when FILE is -, read standard input.\n\
\n\
"),
program_name,
- DIGEST_TYPE_STRING (algorithm),
- DIGEST_BITS (algorithm));
+ DIGEST_TYPE_STRING,
+ DIGEST_BITS);
if (O_BINARY)
fputs (_("\
-b, --binary read in binary mode (default unless reading tty stdin)\n\
@@ -124,7 +172,7 @@ With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
printf (_("\
-c, --check read %s sums from the FILEs and check them\n"),
- DIGEST_TYPE_STRING (algorithm));
+ DIGEST_TYPE_STRING);
if (O_BINARY)
fputs (_("\
-t, --text read in text mode (default if reading tty stdin)\n\
@@ -148,7 +196,7 @@ The sums are computed as described in %s. When checking, the input\n\
should be a former output of this program. The default mode is to print\n\
a line with checksum, a character indicating type (`*' for binary, ` ' for\n\
text), and name for each FILE.\n"),
- (algorithm == ALG_MD5 ? "RFC 1321" : "FIPS-180-1"));
+ DIGEST_REFERENCE);
printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
}
@@ -211,8 +259,8 @@ split_3 (char *s, size_t s_len,
++i;
/* Check for BSD-style checksum line. */
- algo_name_len = strlen (DIGEST_TYPE_STRING (algorithm));
- if (strncmp (s + i, DIGEST_TYPE_STRING (algorithm), algo_name_len) == 0)
+ algo_name_len = strlen (DIGEST_TYPE_STRING);
+ if (strncmp (s + i, DIGEST_TYPE_STRING, algo_name_len) == 0)
{
if (strncmp (s + i + algo_name_len, " (", 2) == 0)
{
@@ -313,8 +361,7 @@ hex_digits (unsigned char const *s)
return true;
}
-/* An interface to the function, DIGEST_STREAM,
- (either md5_stream or sha1_stream).
+/* An interface to the function, DIGEST_STREAM.
Operate on FILENAME (it may be "-").
*BINARY indicates whether the file is binary. BINARY < 0 means it
@@ -322,12 +369,11 @@ hex_digits (unsigned char const *s)
a terminal; in that case, clear *BINARY if the file was treated as
text because it was a terminal.
- Put the checksum in *BIN_RESULT.
+ Put the checksum in *BIN_RESULT, which must be properly aligned.
Return true if successful. */
static bool
-digest_file (const char *filename, int *binary, unsigned char *bin_result,
- int (*digest_stream) (FILE *, void *))
+digest_file (const char *filename, int *binary, unsigned char *bin_result)
{
FILE *fp;
int err;
@@ -355,7 +401,7 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result,
}
}
- err = (*digest_stream) (fp, bin_result);
+ err = DIGEST_STREAM (fp, bin_result);
if (err)
{
error (0, errno, "%s", filename);
@@ -374,18 +420,23 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result,
}
static bool
-digest_check (const char *checkfile_name, int (*digest_stream) (FILE *, void *))
+digest_check (const char *checkfile_name)
{
FILE *checkfile_stream;
uintmax_t n_properly_formatted_lines = 0;
uintmax_t n_mismatched_checksums = 0;
uintmax_t n_open_or_read_failures = 0;
- unsigned char bin_buffer[MAX_DIGEST_BIN_BYTES];
+ unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES+DIGEST_ALIGN];
+ unsigned char *bin_buffer;
uintmax_t line_number;
char *line;
size_t line_chars_allocated;
bool is_stdin = STREQ (checkfile_name, "-");
+ /* Make sure bin_buffer is properly aligned. */
+ bin_buffer = bin_buffer_unaligned
+ + ((unsigned)DIGEST_ALIGN - ((unsigned)bin_buffer_unaligned))%DIGEST_ALIGN;
+
if (is_stdin)
{
have_read_stdin = true;
@@ -439,7 +490,7 @@ digest_check (const char *checkfile_name, int (*digest_stream) (FILE *, void *))
_("%s: %" PRIuMAX
": improperly formatted %s checksum line"),
checkfile_name, line_number,
- DIGEST_TYPE_STRING (algorithm));
+ DIGEST_TYPE_STRING);
}
}
else
@@ -452,7 +503,7 @@ digest_check (const char *checkfile_name, int (*digest_stream) (FILE *, void *))
++n_properly_formatted_lines;
- ok = digest_file (filename, &binary, bin_buffer, digest_stream);
+ ok = digest_file (filename, &binary, bin_buffer);
if (!ok)
{
@@ -509,7 +560,7 @@ digest_check (const char *checkfile_name, int (*digest_stream) (FILE *, void *))
{
/* Warn if no tests are found. */
error (0, 0, _("%s: no properly formatted %s checksum lines found"),
- checkfile_name, DIGEST_TYPE_STRING (algorithm));
+ checkfile_name, DIGEST_TYPE_STRING);
}
else
{
@@ -547,7 +598,8 @@ digest_check (const char *checkfile_name, int (*digest_stream) (FILE *, void *))
int
main (int argc, char **argv)
{
- unsigned char bin_buffer[MAX_DIGEST_BIN_BYTES];
+ unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES+DIGEST_ALIGN];
+ unsigned char *bin_buffer;
bool do_check = false;
int opt;
bool ok = true;
@@ -588,8 +640,12 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- min_digest_line_length = MIN_DIGEST_LINE_LENGTH (algorithm);
- digest_hex_bytes = DIGEST_HEX_BYTES (algorithm);
+ min_digest_line_length = MIN_DIGEST_LINE_LENGTH;
+ digest_hex_bytes = DIGEST_HEX_BYTES;
+
+ /* Make sure bin_buffer is properly aligned. */
+ bin_buffer = bin_buffer_unaligned
+ + ((unsigned)DIGEST_ALIGN - ((unsigned)bin_buffer_unaligned))%DIGEST_ALIGN;
if (0 <= binary && do_check)
{
@@ -620,13 +676,12 @@ main (int argc, char **argv)
char *file = argv[optind];
if (do_check)
- ok &= digest_check (file, DIGEST_STREAM (algorithm));
+ ok &= digest_check (file);
else
{
int file_is_binary = binary;
- if (! digest_file (file, &file_is_binary, bin_buffer,
- DIGEST_STREAM (algorithm)))
+ if (! digest_file (file, &file_is_binary, bin_buffer))
ok = false;
else
{