diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f811134 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,74 @@ +name: Build and Release + +on: + push: + tags: + - 'v*' + +jobs: + build: + name: Build on ${{ matrix.os }} + runs-on: ubuntu-22.04 + strategy: + matrix: + include: + - os: linux + artifact_name: hash_extender + asset_name: hash_extender-linux-x86_64 + - os: windows + artifact_name: hash_extender.exe + asset_name: hash_extender-windows-x86_64.exe + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 1 + + - name: Setup for Windows cross-compilation + if: matrix.os == 'windows' + run: | + sudo apt-get update + sudo apt-get install -y mingw-w64 gcc-mingw-w64 mingw-w64-tools + + - name: Build for Linux + if: matrix.os == 'linux' + run: | + make + + - name: Build for Windows + if: matrix.os == 'windows' + run: | + make CC=x86_64-w64-mingw32-gcc + + - name: Rename artifact to asset_name + run: mv ${{ matrix.artifact_name }} ${{ matrix.asset_name }} + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.asset_name }} + path: ${{ matrix.asset_name }} + + release: + needs: build + runs-on: ubuntu-22.04 + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + + - name: List downloaded files (debug) + run: ls -R + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + files: | + hash_extender-linux-x86_64/hash_extender-linux-x86_64 + hash_extender-windows-x86_64.exe/hash_extender-windows-x86_64.exe + name: Release ${{ github.ref_name }} + draft: false + prerelease: false + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 7f54189..a215c33 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ hash_extender_test hash_extender +.vscode \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7b998dd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "openssl"] + path = openssl + url = https://github.com/openssl/openssl.git + branch = OpenSSL_1_1_1-stable diff --git a/Makefile b/Makefile index ce6d33d..d6f1cac 100644 --- a/Makefile +++ b/Makefile @@ -1,23 +1,17 @@ -# Checks if /usr/include/openssl/whrlpool.h exists, and set a define if it -# doesn't. -INCLUDE_OPENSSL := /usr/include/openssl -INCLUDE_WHIRLPOOL := whrlpool.h -ifneq ($(shell ls $(INCLUDE_OPENSSL)/$(INCLUDE_WHIRLPOOL) 2>/dev/null), $(INCLUDE_OPENSSL)/$(INCLUDE_WHIRLPOOL)) -WHIRLPOOL := -DDISABLE_WHIRLPOOL -endif +OPENSSL_SRC := $(CURDIR)/openssl +OPENSSL_BUILD := $(OPENSSL_SRC)/build +OPENSSL_INSTALL := $(OPENSSL_SRC)/install_dir +INCLUDE_OPENSSL := $(OPENSSL_INSTALL)/include +LIB_OPENSSL := $(OPENSSL_INSTALL)/lib # Capture the operating system name for use by the preprocessor. OS := $(shell uname | tr '/[[:lower:]]' '_[[:upper:]]') # These are the specifications of the toolchain CC := gcc -CFLAGS := -std=c89 -g -oS -Wall -Werror -Wno-deprecated-declarations -CPPFLAGS := -D_DEFAULT_SOURCE -D$(OS) $(WHIRLPOOL) -ifeq ($(OS),DARWIN) - LDFLAGS := -lssl -lcrypto -L/usr/local/opt/openssl/lib/ -else - LDFLAGS := -lssl -lcrypto -endif +CFLAGS := -std=c99 -g -oS -Wall -Werror -Wno-deprecated-declarations +CPPFLAGS := -I$(INCLUDE_OPENSSL) -D_DEFAULT_SOURCE +LDFLAGS := -L$(LIB_OPENSSL) -lssl -lcrypto $(if $(findstring mingw,$(shell $(CC) -dumpmachine)),-lws2_32) $(if $(findstring mingw,$(shell $(CC) -dumpmachine)),-lcrypt32) BIN_MAIN := hash_extender BIN_TEST := hash_extender_test @@ -28,24 +22,40 @@ OBJS := $(patsubst %.c,%.o,$(SRCS)) OBJS_MAIN := $(filter-out $(BIN_TEST).o,$(OBJS)) OBJS_TEST := $(filter-out $(BIN_MAIN).o,$(OBJS)) -all: $(BINS) +all: $(OPENSSL_INSTALL)/lib/libssl.a $(BINS) -$(BIN_MAIN): $(OBJS_MAIN) +# OpenSSL build and install +$(OPENSSL_INSTALL)/lib/libssl.a: $(OPENSSL_SRC)/Makefile + @echo "Building OpenSSL..." + +@cd $(OPENSSL_SRC) && \ + make && make install_sw + +$(OPENSSL_SRC)/Makefile: + @echo "Downloading and preparing OpenSSL source..." + @git submodule update --init --depth 1 --single-branch + @cd $(OPENSSL_SRC) && \ + $(if $(findstring mingw,$(shell $(CC) -dumpmachine)),/usr/bin/perl Configure $(if $(shell which x86_64-w64-mingw32-gcc),--cross-compile-prefix=x86_64-w64-mingw32-,) mingw64 "--prefix=$(if $(shell which cygpath),$(shell cygpath -m $(OPENSSL_INSTALL)),$(OPENSSL_INSTALL))" no-shared no-dso,./config --prefix=$(OPENSSL_INSTALL) no-shared no-dso) + +$(BIN_MAIN): $(OPENSSL_INSTALL)/lib/libssl.a $(OBJS_MAIN) @echo [LD] $@ @$(CC) $(CFLAGS) -o $(BIN_MAIN) $(OBJS_MAIN) $(LDFLAGS) -$(BIN_TEST): $(OBJS_TEST) +$(BIN_TEST): $(OPENSSL_INSTALL)/lib/libssl.a $(OBJS_TEST) @echo [LD] $@ @$(CC) $(CFLAGS) -o $(BIN_TEST) $(OBJS_TEST) $(LDFLAGS) -%.o: %.c +%.o: %.c | $(OPENSSL_INSTALL)/lib/libssl.a @echo [CC] $@ @$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< clean: - @echo [RM] \*.o + @echo [RM] *.o @rm -f $(OBJS) @echo [RM] $(BIN_MAIN) @rm -f $(BIN_MAIN) @echo [RM] $(BIN_TEST) @rm -f $(BIN_TEST) + @echo [RM] OpenSSL build and install + @make -C $(OPENSSL_SRC) clean + @rm -rf $(OPENSSL_BUILD) $(OPENSSL_INSTALL) + @rm $(OPENSSL_SRC)/Makefile $(OPENSSL_SRC)/configdata.pm \ No newline at end of file diff --git a/README.md b/README.md index 45dc654..72fcd96 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Now I'm gonna release the tool, and hope I didn't totally miss a good tool that - SHA-256 - SHA-512 - WHIRLPOOL +- SM3 I'm more than happy to extend this to cover other hashing algorithms as well, provided they are "vulnerable" to this attack -- MD2, SHA-224, and SHA-384 are not. Please contact me if you have other candidates and I'll add them ASAP! diff --git a/buffer.c b/buffer.c index b650b75..37ee9ad 100644 --- a/buffer.c +++ b/buffer.c @@ -11,7 +11,7 @@ #include #include -#ifdef WIN32 +#ifdef _WIN32 #include /* For htons/htonl. */ #else #include /* For htons/htonl. */ diff --git a/hash_extender.c b/hash_extender.c index 89ce959..b9ef94b 100644 --- a/hash_extender.c +++ b/hash_extender.c @@ -1,5 +1,21 @@ #include -#include + +#ifdef _WIN32 + #define err(eval, fmt, ...) \ + do { fprintf(stderr, fmt ": %s\n", ##__VA_ARGS__, strerror(errno)); exit(eval); } while (0) + + #define errx(eval, fmt, ...) \ + do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); exit(eval); } while (0) + + #define warn(fmt, ...) \ + fprintf(stderr, fmt ": %s\n", ##__VA_ARGS__, strerror(errno)) + + #define warnx(fmt, ...) \ + fprintf(stderr, fmt "\n", ##__VA_ARGS__) +#else + #include +#endif + #include #include "buffer.h" diff --git a/hash_extender_engine.c b/hash_extender_engine.c index 3a2b7aa..e191945 100644 --- a/hash_extender_engine.c +++ b/hash_extender_engine.c @@ -1,7 +1,11 @@ -#include +#ifdef _WIN32 + #include /* For htons/htonl. */ +#else + #include /* For htons/htonl. */ +#endif -#ifdef FREEBSD -#include +#ifdef __FREEBSD__ + #include #elif defined(__APPLE__) #include @@ -19,22 +23,50 @@ #define htole64(x) OSSwapHostToLittleInt64(x) #define be64toh(x) OSSwapBigToHostInt64(x) #define le64toh(x) OSSwapLittleToHostInt64(x) +#elif _WIN32 + // for htons, htonl, etc. + #include + // for _byteswap_uint64 + #include + // for uint64_t + #include + + // 16-bit + #define htobe16(x) htons(x) + #define htole16(x) (x) + #define be16toh(x) ntohs(x) + #define le16toh(x) (x) + + // 32-bit + #define htobe32(x) htonl(x) + #define htole32(x) (x) + #define be32toh(x) ntohl(x) + #define le32toh(x) (x) + + // 64-bit (Windows doesn't define htonll/ntohll, so define manually) + #if defined(_MSC_VER) + #define htobe64(x) _byteswap_uint64(x) + #define be64toh(x) _byteswap_uint64(x) + #else + static uint64_t htobe64(uint64_t x) { + return ((uint64_t)htonl((uint32_t)(x >> 32)) | + ((uint64_t)htonl((uint32_t)(x & 0xFFFFFFFF)) << 32)); + } +#endif +#define htole64(x) (x) +#define le64toh(x) (x) + #else #include #endif -#include -#include -#include -#include -#include -#include -#include -#include +#include "openssl/md4.h" +#include "openssl/md5.h" +#include "openssl/ripemd.h" +#include "openssl/sha.h" +#include "openssl/evp.h" #include "tiger.h" -#ifndef DISABLE_WHIRLPOOL -#include -#endif +#include "openssl/whrlpool.h" #include "hash_extender_engine.h" diff --git a/openssl b/openssl new file mode 160000 index 0000000..b372b1f --- /dev/null +++ b/openssl @@ -0,0 +1 @@ +Subproject commit b372b1f76450acdfed1e2301a39810146e28b02c diff --git a/util.h b/util.h index dbfae1c..c4d3981 100644 --- a/util.h +++ b/util.h @@ -1,7 +1,22 @@ #ifndef _UTIL_H_ #define _UTIL_H_ +#ifdef _WIN32 +#define err(eval, fmt, ...) \ + do { fprintf(stderr, fmt ": %s\n", ##__VA_ARGS__, strerror(errno)); exit(eval); } while (0) + +#define errx(eval, fmt, ...) \ + do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); exit(eval); } while (0) + +#define warn(fmt, ...) \ + fprintf(stderr, fmt ": %s\n", ##__VA_ARGS__, strerror(errno)) + +#define warnx(fmt, ...) \ + fprintf(stderr, fmt "\n", ##__VA_ARGS__) +#else #include +#endif + #include #include #include