From daa7047bcb146f5dbcdd557e14f2e881642b7a15 Mon Sep 17 00:00:00 2001 From: Daniel Scharrer Date: Sat, 9 Jun 2018 04:23:43 +0200 Subject: [PATCH] Add an ARC4 implementation --- CMakeLists.txt | 13 +++++++- README.md | 1 + src/configure.hpp.in | 1 + src/crypto/arc4.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++ src/crypto/arc4.hpp | 62 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/crypto/arc4.cpp create mode 100644 src/crypto/arc4.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 12cab5a..cf8de73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,8 @@ macro(suboption _var _comment _type _default) endmacro() option(STRICT_USE "Abort if there are missing optional dependencies" OFF) -option(USE_LZMA "Build lzma decompression support" ON) +option(USE_ARC4 "Build ARC4 decryption support" ON) +option(USE_LZMA "Build LZMA decompression support" ON) set(WITH_CONV CACHE STRING "The library to use for charset conversions") option(DEBUG_EXTRA "Expensive debug options" OFF) option(SET_WARNING_FLAGS "Adjust compiler warning flags" ON) @@ -117,6 +118,10 @@ endif() unset(LIBRARIES) +if(USE_ARC4) + set(INNOEXTRACT_HAVE_ARC4 1) +endif() + if(USE_LZMA) find_package(LZMA REQUIRED) check_link_library(LZMA LZMA_LIBRARIES) @@ -298,6 +303,8 @@ set(INNOEXTRACT_SOURCES src/crypto/adler32.hpp src/crypto/adler32.cpp + src/crypto/arc4.hpp if INNOEXTRACT_HAVE_ARC4 + src/crypto/arc4.cpp if INNOEXTRACT_HAVE_ARC4 src/crypto/checksum.hpp src/crypto/checksum.cpp src/crypto/crc32.hpp @@ -446,6 +453,10 @@ elseif(NOT DEBUG AND NOT CMAKE_BUILD_TYPE STREQUAL "Release") set(BUILD_TYPE_SUFFIX "${BUILD_TYPE_SUFFIX} without debug output") endif() message(" - Build type: ${CMAKE_BUILD_TYPE}${BUILD_TYPE_SUFFIX}") +print_configuration("ARC4 decryption" FIRST + INNOEXTRACT_HAVE_ARC4 "enabled" + 1 "disabled" +) print_configuration("LZMA decompression" FIRST INNOEXTRACT_HAVE_LZMA "enabled" 1 "disabled" diff --git a/README.md b/README.md index 0b0ea1f..03c2fcf 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Build options: | Option | Default | Description | |:------------------------ |:---------:|:----------- | +| `USE_ARC4` | `ON` | Build ARC4 decryption support. | `USE_LZMA` | `ON` | Use `liblzma`. | `WITH_CONV` | *not set* | The charset conversion library to use. Valid values are `iconv`, `win32` and `builtin`^1. If not set, a library appropriate for the target platform will be chosen. | `CMAKE_BUILD_TYPE` | `Release` | Set to `Debug` to enable debug output. diff --git a/src/configure.hpp.in b/src/configure.hpp.in index 4821365..223adb6 100644 --- a/src/configure.hpp.in +++ b/src/configure.hpp.in @@ -33,6 +33,7 @@ #cmakedefine01 INNOEXTRACT_HAVE_STD_UNIQUE_PTR // Optional dependencies +#cmakedefine01 INNOEXTRACT_HAVE_ARC4 #cmakedefine01 INNOEXTRACT_HAVE_LZMA #cmakedefine01 INNOEXTRACT_HAVE_ICONV #cmakedefine01 INNOEXTRACT_HAVE_WIN32_CONV diff --git a/src/crypto/arc4.cpp b/src/crypto/arc4.cpp new file mode 100644 index 0000000..b9c5142 --- /dev/null +++ b/src/crypto/arc4.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2018 Daniel Scharrer + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the author(s) be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "crypto/arc4.hpp" + +#include + +#include "util/endian.hpp" + +namespace crypto { + +void arc4::init(const char * key, size_t length) { + + a = b = 0; + + for(size_t i = 0; i < sizeof(state); i++){ + state[i] = (unsigned char)i; + } + + size_t j = 0; + for(size_t i = 0; i < sizeof(state); i++) { + j = (j + state[i] + (unsigned char)key[i % length]) % sizeof(state); + std::swap(state[i], state[j]); + } + +} + +void arc4::update() { + + a = (a + 1) % sizeof(state); + b = (b + state[a]) % sizeof(state); + + std::swap(state[a], state[b]); + +} + +void arc4::discard(size_t length) { + + for(size_t i = 0; i < length; i++) { + update(); + } + +} + +void arc4::crypt(const char * in, char * out, size_t length) { + + for(size_t i = 0; i < length; i++) { + update(); + out[i] = char(state[size_t(state[a] + state[b]) % sizeof(state)] ^ (unsigned char)in[i]); + } + +} + +} // namespace crypto diff --git a/src/crypto/arc4.hpp b/src/crypto/arc4.hpp new file mode 100644 index 0000000..ea2da30 --- /dev/null +++ b/src/crypto/arc4.hpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2018 Daniel Scharrer + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the author(s) be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +/*! + * \file + * + * Alledged RC4 en-/decryption routines. + */ +#ifndef INNOEXTRACT_CRYPTO_ARC4_HPP +#define INNOEXTRACT_CRYPTO_ARC4_HPP + +#include + +#include + +#include "configure.hpp" + +#if INNOEXTRACT_HAVE_ARC4 + +namespace crypto { + +//! Alledged RC4 en-/decryption calculation +struct arc4 { + + void init(const char * key, size_t length); + + void discard(size_t length); + + void crypt(const char * in, char * out, size_t length); + +private: + + void update(); + + unsigned char state[256]; + size_t a, b; + +}; + +} // namespace crypto + +#endif // INNOEXTRACT_HAVE_ARC4 + +#endif // INNOEXTRACT_CRYPTO_ARC4_HPP +