From 25651556f0bbe54f6f4b5d6b4862d1a9a674c62c Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Thu, 1 Jun 2023 12:32:17 +0000 Subject: [PATCH] Cleanup: Removed legacy digest.[ch] --- src/Makefile.am | 2 - src/digest.c | 617 --------------------------------------------- src/digest.h | 41 --- src/icecasttypes.h | 7 - src/prng.c | 1 - 5 files changed, 668 deletions(-) delete mode 100644 src/digest.c delete mode 100644 src/digest.h diff --git a/src/Makefile.am b/src/Makefile.am index 2be43133..3229c5de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,7 +30,6 @@ noinst_HEADERS = \ fserve.h \ xslt.h \ yp.h \ - digest.h \ prng.h \ matchfile.h \ tls.h \ @@ -84,7 +83,6 @@ icecast_SOURCES = \ fserve.c \ admin.c \ resourcematch.c \ - digest.c \ prng.c \ matchfile.c \ tls.c \ diff --git a/src/digest.c b/src/digest.c deleted file mode 100644 index f2bcc18d..00000000 --- a/src/digest.c +++ /dev/null @@ -1,617 +0,0 @@ -/* Icecast - * - * This program is distributed under the GNU General Public License, version 2. - * A copy of this license is included with this source. - * - * Copyright 2020, Philipp "ph3-der-loewe" Schafft - * - * The SHA3 implementation is based on rhash: - * 2013 by Aleksey Kravchenko - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "digest.h" - -#include "logging.h" -#define CATMODULE "digest" - -struct digest_tag { - /* base object */ - refobject_base_t __base; - - /* metadata */ - digest_algo_t algo; - - /* state */ - int done; - union { - struct { - /* 1600 bits algorithm hashing state */ - uint64_t hash[25]; - /* 1536-bit buffer for leftovers */ - char message[24*8]; - /* count of bytes in the message[] buffer */ - size_t rest; - /* size of a message block processed at once */ - size_t block_size; - } sha3; - } state; -}; - - -struct hmac_tag { - /* base object */ - refobject_base_t __base; - - digest_algo_t algo; - char *key; - size_t key_len; - digest_t * inner; -}; - -static void __hmac_free(refobject_t self, void **userdata) -{ - hmac_t *hmac = REFOBJECT_TO_TYPE(self, hmac_t *); - free(hmac->key); - refobject_unref(hmac->inner); -} - -REFOBJECT_DEFINE_TYPE(digest_t); -REFOBJECT_DEFINE_TYPE(hmac_t, - REFOBJECT_DEFINE_TYPE_FREE(__hmac_free) - ); - -#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n)))) - -#ifdef WORDS_BIGENDIAN -// TODO: Improve this. -static inline uint64_t digest_letoh64(uint64_t x) -{ - union { - uint64_t num; - char b[8]; - } in, out; - int i; - - in.num = x; - for (i = 0; i < 8; i++) - out.b[i] = in.b[7 - i]; - return out.num; -} -#else -#define digest_letoh64(x) (x) -#endif - -/* SHA3 (Keccak) constants for 24 rounds */ -static uint64_t keccak_round_constants[] = { - 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL, 0x8000000080008000ULL, - 0x000000000000808BULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, - 0x000000000000008AULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL, - 0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL, 0x8000000000008003ULL, - 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800AULL, 0x800000008000000AULL, - 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL -}; - -static inline void sha3_init(digest_t *digest, unsigned int bits) -{ - /* The Keccak capacity parameter = bits * 2 */ - unsigned int rate = 1600 - bits * 2; - - digest->state.sha3.block_size = rate / 8; -} - -#define XORED_A(i) A[(i)] ^ A[(i) + 5] ^ A[(i) + 10] ^ A[(i) + 15] ^ A[(i) + 20] -#define THETA_STEP(i) \ - A[(i)] ^= D[(i)]; \ - A[(i) + 5] ^= D[(i)]; \ - A[(i) + 10] ^= D[(i)]; \ - A[(i) + 15] ^= D[(i)]; \ - A[(i) + 20] ^= D[(i)] - -/* Keccak theta() transformation */ -static inline void keccak_theta(uint64_t *A) -{ - uint64_t D[5]; - D[0] = ROTL64(XORED_A(1), 1) ^ XORED_A(4); - D[1] = ROTL64(XORED_A(2), 1) ^ XORED_A(0); - D[2] = ROTL64(XORED_A(3), 1) ^ XORED_A(1); - D[3] = ROTL64(XORED_A(4), 1) ^ XORED_A(2); - D[4] = ROTL64(XORED_A(0), 1) ^ XORED_A(3); - THETA_STEP(0); - THETA_STEP(1); - THETA_STEP(2); - THETA_STEP(3); - THETA_STEP(4); -} - -/* Keccak pi() transformation */ -static inline void keccak_pi(uint64_t *A) -{ - uint64_t A1; - A1 = A[1]; - A[ 1] = A[ 6]; - A[ 6] = A[ 9]; - A[ 9] = A[22]; - A[22] = A[14]; - A[14] = A[20]; - A[20] = A[ 2]; - A[ 2] = A[12]; - A[12] = A[13]; - A[13] = A[19]; - A[19] = A[23]; - A[23] = A[15]; - A[15] = A[ 4]; - A[ 4] = A[24]; - A[24] = A[21]; - A[21] = A[ 8]; - A[ 8] = A[16]; - A[16] = A[ 5]; - A[ 5] = A[ 3]; - A[ 3] = A[18]; - A[18] = A[17]; - A[17] = A[11]; - A[11] = A[ 7]; - A[ 7] = A[10]; - A[10] = A1; - /* note: A[ 0] is left as is */ -} - -#define CHI_STEP(i) \ - A0 = A[0 + (i)]; \ - A1 = A[1 + (i)]; \ - A[0 + (i)] ^= ~A1 & A[2 + (i)]; \ - A[1 + (i)] ^= ~A[2 + (i)] & A[3 + (i)]; \ - A[2 + (i)] ^= ~A[3 + (i)] & A[4 + (i)]; \ - A[3 + (i)] ^= ~A[4 + (i)] & A0; \ - A[4 + (i)] ^= ~A0 & A1 - -/* Keccak chi() transformation */ -static inline void keccak_chi(uint64_t *A) -{ - uint64_t A0, A1; - CHI_STEP(0); - CHI_STEP(5); - CHI_STEP(10); - CHI_STEP(15); - CHI_STEP(20); -} - -/** - * The core transformation. Process the specified block of data. - * - * @param hash the algorithm state - * @param block the message block to process - * @param block_size the size of the processed block in bytes - */ -static inline void sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size) -{ - size_t round; - - /* expanded loop */ - hash[ 0] ^= digest_letoh64(block[ 0]); - hash[ 1] ^= digest_letoh64(block[ 1]); - hash[ 2] ^= digest_letoh64(block[ 2]); - hash[ 3] ^= digest_letoh64(block[ 3]); - hash[ 4] ^= digest_letoh64(block[ 4]); - hash[ 5] ^= digest_letoh64(block[ 5]); - hash[ 6] ^= digest_letoh64(block[ 6]); - hash[ 7] ^= digest_letoh64(block[ 7]); - hash[ 8] ^= digest_letoh64(block[ 8]); - /* if not sha3-512 */ - if (block_size > 72) { - hash[ 9] ^= digest_letoh64(block[ 9]); - hash[10] ^= digest_letoh64(block[10]); - hash[11] ^= digest_letoh64(block[11]); - hash[12] ^= digest_letoh64(block[12]); - /* if not sha3-384 */ - if (block_size > 104) { - hash[13] ^= digest_letoh64(block[13]); - hash[14] ^= digest_letoh64(block[14]); - hash[15] ^= digest_letoh64(block[15]); - hash[16] ^= digest_letoh64(block[16]); - /* if not sha3-256 */ - if (block_size > 136) { - hash[17] ^= digest_letoh64(block[17]); - } - } - } - - /* make a permutation of the hash */ - for (round = 0; round < (sizeof(keccak_round_constants)/sizeof(*keccak_round_constants)); round++) { - keccak_theta(hash); - - /* apply Keccak rho() transformation */ - hash[ 1] = ROTL64(hash[ 1], 1); - hash[ 2] = ROTL64(hash[ 2], 62); - hash[ 3] = ROTL64(hash[ 3], 28); - hash[ 4] = ROTL64(hash[ 4], 27); - hash[ 5] = ROTL64(hash[ 5], 36); - hash[ 6] = ROTL64(hash[ 6], 44); - hash[ 7] = ROTL64(hash[ 7], 6); - hash[ 8] = ROTL64(hash[ 8], 55); - hash[ 9] = ROTL64(hash[ 9], 20); - hash[10] = ROTL64(hash[10], 3); - hash[11] = ROTL64(hash[11], 10); - hash[12] = ROTL64(hash[12], 43); - hash[13] = ROTL64(hash[13], 25); - hash[14] = ROTL64(hash[14], 39); - hash[15] = ROTL64(hash[15], 41); - hash[16] = ROTL64(hash[16], 45); - hash[17] = ROTL64(hash[17], 15); - hash[18] = ROTL64(hash[18], 21); - hash[19] = ROTL64(hash[19], 8); - hash[20] = ROTL64(hash[20], 18); - hash[21] = ROTL64(hash[21], 2); - hash[22] = ROTL64(hash[22], 61); - hash[23] = ROTL64(hash[23], 56); - hash[24] = ROTL64(hash[24], 14); - - keccak_pi(hash); - keccak_chi(hash); - - /* apply iota(hash, round) */ - *hash ^= keccak_round_constants[round]; - } -} - -void sha3_write(digest_t *digest, const char *msg, size_t size) -{ - size_t rest = digest->state.sha3.rest; - size_t block_size = digest->state.sha3.block_size; - - digest->state.sha3.rest = (rest + size) % block_size; - - /* fill partial block */ - if (rest) { - size_t left = block_size - rest; - memcpy(digest->state.sha3.message + rest, msg, (size < left ? size : left)); - if (size < left) return; - - /* process partial block */ - sha3_process_block(digest->state.sha3.hash, (uint64_t*)digest->state.sha3.message, block_size); - msg += left; - size -= left; - } - while (size >= block_size) { - const char *aligned_message_block; - - if (((intptr_t)(void*)msg) & 7) { - memcpy(digest->state.sha3.message, msg, block_size); - aligned_message_block = digest->state.sha3.message; - } else { - aligned_message_block = msg; - } - - sha3_process_block(digest->state.sha3.hash, (uint64_t*)aligned_message_block, block_size); - msg += block_size; - size -= block_size; - } - - if (size) - memcpy(digest->state.sha3.message, msg, size); /* save leftovers */ -} - -static inline size_t sha3_read(digest_t *digest, void *buf, size_t len) -{ - const size_t block_size = digest->state.sha3.block_size; - - memset(digest->state.sha3.message + digest->state.sha3.rest, 0, block_size - digest->state.sha3.rest); - digest->state.sha3.message[digest->state.sha3.rest] |= 0x06; - digest->state.sha3.message[block_size - 1] |= 0x80; - - sha3_process_block(digest->state.sha3.hash, (uint64_t*)digest->state.sha3.message, block_size); - -#ifdef WORDS_BIGENDIAN - do { - size_t i; - for (i = 0; i < (sizeof(digest->state.sha3.hash)/sizeof(*digest->state.sha3.hash)); i++) - digest->state.sha3.hash[i] = digest_htole64(digest->state.sha3.hash[i]); - } while (0); -#endif - - if (len > (100 - digest->state.sha3.block_size / 2)) - len = 100 - digest->state.sha3.block_size / 2; - memcpy(buf, digest->state.sha3.hash, len); - return len; -} - - -const char *digest_algo_id2str(digest_algo_t algo) -{ - switch (algo) { - - case DIGEST_ALGO_SHA3_224: - return "SHA3-224"; - break; - case DIGEST_ALGO_SHA3_256: - return "SHA3-256"; - break; - case DIGEST_ALGO_SHA3_384: - return "SHA3-384"; - break; - case DIGEST_ALGO_SHA3_512: - return "SHA3-512"; - break; - } - - return NULL; -} -ssize_t digest_algo_length_bytes(digest_algo_t algo) -{ - switch (algo) { - case DIGEST_ALGO_SHA3_224: - return 224/8; - break; - case DIGEST_ALGO_SHA3_256: - return 256/8; - break; - case DIGEST_ALGO_SHA3_384: - return 384/8; - break; - case DIGEST_ALGO_SHA3_512: - return 512/8; - break; - } - - return -1; -} - -digest_t * digest_new(digest_algo_t algo) -{ - digest_t *digest = refobject_new__new(digest_t, NULL, NULL, NULL); - - if (!digest) - return NULL; - - digest->algo = algo; - switch (algo) { - case DIGEST_ALGO_SHA3_224: - sha3_init(digest, 224); - break; - case DIGEST_ALGO_SHA3_256: - sha3_init(digest, 256); - break; - case DIGEST_ALGO_SHA3_384: - sha3_init(digest, 384); - break; - case DIGEST_ALGO_SHA3_512: - sha3_init(digest, 512); - break; - default: - refobject_unref(digest); - return NULL; - break; - } - - return digest; -} - -digest_t * digest_copy(digest_t *digest) -{ - digest_t *n; - - if (!digest) - return NULL; - - n = refobject_new__new(digest_t, NULL, NULL, NULL); - n->algo = digest->algo; - n->done = digest->done; - n->state = digest->state; - - return n; -} - -ssize_t digest_write(digest_t *digest, const void *data, size_t len) -{ - if (!digest || !data) - return -1; - - if (digest->done) - return -1; - - switch (digest->algo) { - case DIGEST_ALGO_SHA3_224: - case DIGEST_ALGO_SHA3_256: - case DIGEST_ALGO_SHA3_384: - case DIGEST_ALGO_SHA3_512: - sha3_write(digest, data, len); - return len; - break; - default: - return -1; - break; - } -} - -ssize_t digest_read(digest_t *digest, void *buf, size_t len) -{ - if (!digest || !buf) - return -1; - - if (digest->done) - return -1; - - digest->done = 1; - - switch (digest->algo) { - case DIGEST_ALGO_SHA3_224: - case DIGEST_ALGO_SHA3_256: - case DIGEST_ALGO_SHA3_384: - case DIGEST_ALGO_SHA3_512: - return sha3_read(digest, buf, len); - break; - default: - return -1; - break; - } -} - -ssize_t digest_length_bytes(digest_t *digest) -{ - if (!digest) - return -1; - - return digest_algo_length_bytes(digest->algo); -} - - -static size_t __digest_algo_blocklength(digest_algo_t algo) -{ - switch (algo) { - case DIGEST_ALGO_SHA3_224: return 144; break; - case DIGEST_ALGO_SHA3_256: return 136; break; - case DIGEST_ALGO_SHA3_384: return 104; break; - case DIGEST_ALGO_SHA3_512: return 72; break; - } - - return 0; -} - -hmac_t * hmac_new(digest_algo_t algo, const void *key, size_t keylen) -{ - hmac_t *hmac; - size_t blocklen = __digest_algo_blocklength(algo); - char *keycopy = calloc(1, blocklen); - size_t i; - - if (!blocklen) - return NULL; - - if (keylen > blocklen) { - size_t digestlen = digest_algo_length_bytes(algo); - digest_t *digest = digest_new(algo); - - if (!digest) { - free(keycopy); - return NULL; - } - if (digest_write(digest, key, keylen) != (ssize_t)keylen) { - refobject_unref(digest); - free(keycopy); - return NULL; - } - if (digest_read(digest, keycopy, digestlen) != (ssize_t)digestlen) { - refobject_unref(digest); - free(keycopy); - return NULL; - } - refobject_unref(digest); - } else { - memcpy(keycopy, key, keylen); - } - - hmac = refobject_new__new(hmac_t, NULL, NULL, NULL); - if (!hmac) - return NULL; - - hmac->algo = algo; - hmac->key = keycopy; - hmac->key_len = blocklen; - hmac->inner = digest_new(algo); - - if (!hmac->inner) { - refobject_unref(hmac); - return NULL; - } - - for (i = 0; i < blocklen; i++) { - char x = keycopy[i] ^ 0x36; - if (digest_write(hmac->inner, &x, 1) != 1) { - refobject_unref(hmac); - return NULL; - } - } - - return hmac; -} - -hmac_t * hmac_copy(hmac_t *hmac) -{ - hmac_t *n; - - if (!hmac) - return NULL; - - n = refobject_new__new(hmac_t, NULL, NULL, NULL); - n->algo = hmac->algo; - n->key = malloc(n->key_len); - if (!n->key) { - refobject_unref(n); - return NULL; - } - memcpy(n->key, hmac->key, hmac->key_len); - n->key_len = hmac->key_len; - n->inner = digest_copy(hmac->inner); - if (!n->inner) { - refobject_unref(n); - return NULL; - } - - return n; -} - -ssize_t hmac_write(hmac_t *hmac, const void *data, size_t len) -{ - if (!hmac) - return -1; - - return digest_write(hmac->inner, data, len); -} - -ssize_t hmac_read(hmac_t *hmac, void *buf, size_t len) -{ - size_t digestlen; - digest_t *digest; - char *res; - size_t i; - ssize_t ret; - - if (!hmac) - return -1; - - digestlen = digest_algo_length_bytes(hmac->algo); - - digest = digest_new(hmac->algo); - if (!digest) - return -1; - - res = malloc(digestlen); - if (!res) { - refobject_unref(digest); - return -1; - } - - for (i = 0; i < hmac->key_len; i++) { - char x = hmac->key[i] ^ 0x5C; - if (digest_write(digest, &x, 1) != 1) { - free(res); - refobject_unref(digest); - return -1; - } - } - - if (digest_read(hmac->inner, res, digestlen) != (ssize_t)digestlen) { - free(res); - refobject_unref(digest); - return -1; - } - - if (digest_write(digest, res, digestlen) != (ssize_t)digestlen) { - free(res); - refobject_unref(digest); - return -1; - } - - ret = digest_read(digest, buf, len); - - free(res); - refobject_unref(digest); - - return ret; -} diff --git a/src/digest.h b/src/digest.h deleted file mode 100644 index 9b3d6894..00000000 --- a/src/digest.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Icecast - * - * This program is distributed under the GNU General Public License, version 2. - * A copy of this license is included with this source. - * - * Copyright 2020, Philipp "ph3-der-loewe" Schafft - */ - -#ifndef __DIGEST_H__ -#define __DIGEST_H__ - -#include "refobject.h" - -REFOBJECT_FORWARD_TYPE(digest_t); -REFOBJECT_FORWARD_TYPE(hmac_t); - -typedef enum { - DIGEST_ALGO_SHA3_224, - DIGEST_ALGO_SHA3_256, - DIGEST_ALGO_SHA3_384, - DIGEST_ALGO_SHA3_512 -} digest_algo_t; - -const char *digest_algo_id2str(digest_algo_t algo); -ssize_t digest_algo_length_bytes(digest_algo_t algo); - -digest_t * digest_new(digest_algo_t algo); -digest_t * digest_copy(digest_t *digest); -ssize_t digest_write(digest_t *digest, const void *data, size_t len); -ssize_t digest_read(digest_t *digest, void *buf, size_t len); - -/* Returns the digest size in bytes */ -ssize_t digest_length_bytes(digest_t *digest); - - -hmac_t * hmac_new(digest_algo_t algo, const void *key, size_t keylen); -hmac_t * hmac_copy(hmac_t *hmac); -ssize_t hmac_write(hmac_t *hmac, const void *data, size_t len); -ssize_t hmac_read(hmac_t *hmac, void *buf, size_t len); - -#endif diff --git a/src/icecasttypes.h b/src/icecasttypes.h index 739b4ad1..87bd5400 100644 --- a/src/icecasttypes.h +++ b/src/icecasttypes.h @@ -126,11 +126,6 @@ typedef struct reportxml_database_tag reportxml_database_t; typedef struct listensocket_container_tag listensocket_container_t; typedef struct listensocket_tag listensocket_t; -/* ---[ digest.[ch] ]--- */ - -typedef struct digest_tag digest_t; -typedef struct hmac_tag hmac_t; - /* ---[ navigation.[ch] ]--- */ typedef struct mount_identifier_tag mount_identifier_t; @@ -156,8 +151,6 @@ typedef union __attribute__ ((__transparent_union__)) { reportxml_database_t *reportxml_database; listensocket_container_t *listensocket_container; listensocket_t *listensocket; - digest_t *digest; - hmac_t *hmac; mount_identifier_t *mount_identifier; } refobject_t; #else diff --git a/src/prng.c b/src/prng.c index b181ed90..0b7f26da 100644 --- a/src/prng.c +++ b/src/prng.c @@ -32,7 +32,6 @@ #include "prng.h" #include "global.h" -#include "digest.h" #include "cfgfile.h" #include "logging.h"