/*
- * sha1.c
+ * sha1.c - implementation of the Secure Hash Algorithm version 1 (FIPS 180-1)
*
- * Implementation of the Secure Hash Algorithm version 1 (FIPS 180-1).
+ * The following copying information applies to this specific source code file:
*
- * Author: Eric Biggers
- * Year: 2014
+ * Written in 2014-2015 by Eric Biggers <ebiggers3@gmail.com>
*
- * The default SHA-1 transform is based on public domain code by Steve Reid.
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide via the Creative Commons Zero 1.0 Universal Public Domain
+ * Dedication (the "CC0").
*
- * The author dedicates this file to the public domain.
- * You can do whatever you want with this file.
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the CC0 for more details.
+ *
+ * You should have received a copy of the CC0 along with this software; if not
+ * see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#ifdef HAVE_CONFIG_H
#include "wimlib/endianness.h"
#include "wimlib/sha1.h"
+#include "wimlib/unaligned.h"
/* Dummy SHA-1 message digest of all 0's. This is used in the WIM format to
* mean "SHA-1 not specified". */
const u8 zero_hash[20];
+/*
+ * Builds a hexadecimal string representation of a SHA-1 message digest.
+ *
+ * The output buffer must be at least 41 characters.
+ */
+void
+sprint_hash(const u8 hash[SHA1_HASH_SIZE], tchar strbuf[SHA1_HASH_SIZE * 2 + 1])
+{
+ int i;
+ u8 high, low;
+
+ for (i = 0; i < SHA1_HASH_SIZE; i++) {
+ high = hash[i] >> 4;
+ low = hash[i] & 0xF;
+ strbuf[i * 2 + 0] = (high < 10 ? high + '0' : high - 10 + 'a');
+ strbuf[i * 2 + 1] = (low < 10 ? low + '0' : low - 10 + 'a');
+ }
+ strbuf[i * 2] = 0;
+}
+
/* If we use libcrypto (e.g. OpenSSL) then we get all the SHA-1 functions for
* free. Otherwise we need to implement them ourselves. */
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-#define blk0(i) (tmp[i] = be32_to_cpu(((const be32 *)block)[i]))
+#define blk0(i) (tmp[i] = be32_to_cpu(load_be32_unaligned(&(block)[(i) * 4])))
#define blk(i) (tmp[i & 15] = rol(tmp[(i + 13) & 15] ^ \
tmp[(i + 8) & 15] ^ \
* final length is a multiple of the block size. */
static const u8 padding[64] = {0x80, };
be64 finalcount = cpu_to_be64(ctx->bytecount << 3);
- be32 *out = (be32 *)md;
sha1_update(ctx, padding, 64 - ((ctx->bytecount + 8) & 63));
sha1_update(ctx, &finalcount, 8);
for (int i = 0; i < 5; i++)
- out[i] = cpu_to_be32(ctx->state[i]);
+ store_be32_unaligned(cpu_to_be32(ctx->state[i]), &md[i * 4]);
}
/* Calculate the SHA-1 message digest of the specified buffer.