From e74113b0e1a6ca1c047667218b089362372aa0f0 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 12 Mar 2020 16:06:12 +0100 Subject: [PATCH] Introduce hash2 (sha256). This adds a second hash function which will replace sha1. Both openssl and libgcrypt support sha256, so it is easy to do. There are no users of the new functions so far, so this patch has no effect yet. --- crypt.h | 39 +++++++++++++++++++++++++++++++++++++++ crypt_common.c | 25 +++++++++++++++++++++++++ gcrypt.c | 16 ++++++++++++++++ openssl.c | 8 ++++++++ 4 files changed, 88 insertions(+) diff --git a/crypt.h b/crypt.h index 9623a003..5ca6a541 100644 --- a/crypt.h +++ b/crypt.h @@ -200,3 +200,42 @@ void hash_to_asc(const unsigned char *hash, char *asc); * less than or equal to h2, respectively. */ int hash_compare(const unsigned char *h1, const unsigned char *h2); + +/** Size of the hash value in bytes. */ +#define HASH2_SIZE 32 + +/** + * Compute the hash2 of the given input data. + * + * \param data Pointer to the data to compute the hash value from. + * \param len The length of \a data in bytes. + * \param hash Result pointer. + * + * \a hash must point to an area at least \p HASH2_SIZE bytes large. + * + * \sa sha(3), openssl(1). + * */ +void hash2_function(const char *data, unsigned long len, unsigned char *hash); + +/** + * Convert a hash2 value to ascii format. + * + * \param hash the hash value. + * \param asc Result pointer. + * + * \a asc must point to an area of at least 2 * \p HASH2_SIZE + 1 bytes which + * will be filled by the function with the ascii representation of the hash + * value given by \a hash, and a terminating \p NULL byte. + */ +void hash2_to_asc(const unsigned char *hash, char *asc); + +/** + * Compare two version 2 hashes. + * + * \param h1 Pointer to the first hash value. + * \param h2 Pointer to the second hash value. + * + * \return 1, -1, or zero, depending on whether \a h1 is greater than, + * less than or equal to h2, respectively. + */ +int hash2_compare(const unsigned char *h1, const unsigned char *h2); diff --git a/crypt_common.c b/crypt_common.c index ff24e356..3a44dbdd 100644 --- a/crypt_common.c +++ b/crypt_common.c @@ -160,6 +160,31 @@ int hash_compare(const unsigned char *h1, const unsigned char *h2) return 0; } +void hash2_to_asc(const unsigned char *hash, char *asc) +{ + int i; + const char hexchar[] = "0123456789abcdef"; + + for (i = 0; i < HASH2_SIZE; i++) { + asc[2 * i] = hexchar[hash[i] >> 4]; + asc[2 * i + 1] = hexchar[hash[i] & 0xf]; + } + asc[2 * HASH2_SIZE] = '\0'; +} + +int hash2_compare(const unsigned char *h1, const unsigned char *h2) +{ + int i; + + for (i = 0; i < HASH2_SIZE; i++) { + if (h1[i] < h2[i]) + return -1; + if (h1[i] > h2[i]) + return 1; + } + return 0; +} + /** * Check header of an openssh private key and compute bignum offset. * diff --git a/gcrypt.c b/gcrypt.c index dbe49008..506f0bb8 100644 --- a/gcrypt.c +++ b/gcrypt.c @@ -46,6 +46,22 @@ void hash_function(const char *data, unsigned long len, unsigned char *hash) gcry_md_close(handle); } +void hash2_function(const char *data, unsigned long len, unsigned char *hash) +{ + gcry_error_t gret; + gcry_md_hd_t handle; + unsigned char *md; + + gret = gcry_md_open(&handle, GCRY_MD_SHA256, 0); + assert(gret == 0); + gcry_md_write(handle, data, (size_t)len); + gcry_md_final(handle); + md = gcry_md_read(handle, GCRY_MD_SHA256); + assert(md); + memcpy(hash, md, HASH2_SIZE); + gcry_md_close(handle); +} + void get_random_bytes_or_die(unsigned char *buf, int num) { gcry_randomize(buf, (size_t)num, GCRY_STRONG_RANDOM); diff --git a/openssl.c b/openssl.c index 0ad9d7db..32891cbb 100644 --- a/openssl.c +++ b/openssl.c @@ -414,3 +414,11 @@ void hash_function(const char *data, unsigned long len, unsigned char *hash) SHA1_Update(&c, data, len); SHA1_Final(hash, &c); } + +void hash2_function(const char *data, unsigned long len, unsigned char *hash) +{ + SHA256_CTX c; + SHA256_Init(&c); + SHA256_Update(&c, data, len); + SHA256_Final(hash, &c); +} -- 2.39.2