OSDN Git Service

Updated README file.
[slunkcrypt/SlunkCrypt.git] / README.md
index a1d5bc4..fd784e9 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 ---
-title: "![SlunkCrypt](etc/img/SlunkCrypt-Logo.png)"
+title: "![SlunkCrypt 🐔](etc/img/SlunkCrypt-Logo.png)"
 ---
 
 
@@ -22,15 +22,17 @@ System Requirements
 
 The SlunkCrypt library and the command-line application currently run on the following platforms:
 
-* **Microsoft Windows** (Windows XP SP-3, or later) — 32-Bit (i686) and 64-Bit (AMD64)
-* **Linux** (kernel version 3.17, or later) — 32-Bit (i686) and 64-Bit (AMD64)
-* **Various BSD flavors** (tested on NetBSD 9.2, FreeBSD 13.0 and OpenBSD 7.0) — 32-Bit (i686) and 64-Bit (AMD64)
-* **Solaris** (tested on Solaris 11.4 and OmniOS/illumos) — 32-Bit (i686) and 64-Bit (AMD64)
-* **Mac OS X** (tested on macOS 11 “Big Sur”) — Intel x86-64 (AMD64) and Apple Silicon (AArch64)
+* **Microsoft Windows** (Windows XP SP-3, or later) — i686, x86-64 and ARM64
+* **Linux** (kernel version 3.17, or later) — i686, x86-64, ARM64 and MIPS
+* **Various BSD flavors** (tested on NetBSD 9.2, FreeBSD 13.0 and OpenBSD 7.0) — i686 and x86-64
+* **Solaris** (tested on Solaris 11.4 and OmniOS/illumos) — i686 and x86-64
+* **GNU/Hurd** (tested on Debian GNU/Hurd 0.9) — i686
+* **Haiku** (tested on Haiku R1/b3) — i686 and x86-64
+* **Mac OS X** (tested on “Big Sur”) — x86-64 and ARM64
 
 The SlunkCrypt GUI application currently runs on the following platforms:
 
-* **Microsoft Windows** with .NET Framework 4.5 — can be installed on Windows Vista, or later
+* **Microsoft Windows** with .NET Framework 4.7.2 — can be installed on Windows 7 SP1, or later
 
 
 GUI Usage
@@ -43,10 +45,10 @@ This is how the graphical user interface (GUI) for SlunkCrypt looks on [Windows
 Prerequisites
 -------------
 
-Please be sure to install the **.NET Framework 4.5**, or any later *.NET Framework 4.x* version, before running the SlunkCrypt GUI application:  
+Please be sure to install the **.NET Framework 4.7.2**, or any later *.NET Framework 4.x* version, before running the SlunkCrypt **Windows GUI** application:  
 <https://dotnet.microsoft.com/download/dotnet-framework>
 
-***Note:*** If you are running Windows 8 or later, then almost certainly a suitable version of the .NET Framework is already installed &#128526;
+***Note:*** If you are running Windows 8.1 or later, then almost certainly a suitable version of the .NET Framework is already installed &#128526;
 
 Settings
 --------
@@ -130,6 +132,12 @@ The following environment variables may be used:
 - **`SLUNK_THREADS`**:  
   Specifies the number of worker threads to use. By default, SlunkCrypt detects the number of available processors and creates one thread for each processor.
 
+- **`SLUNK_LEGACY_COMPAT`**:  
+  If set to a *non-zero* value, enables "legacy" compatibility-mode, required to decrypt files encrypted with SlunkCrypt version 1.2.x or older.
+
+- **`SLUNK_DEBUG_LOGGING`**:  
+  If set to a *non-zero* value, enables additional logging output to the syslog (Unix-like) or to the debugger (Windows). This is intended for debugging purposes only!
+
 Examples
 --------
 
@@ -193,7 +201,14 @@ Here are some examples on how to use the SlunkCrypt command-line application:
 Encryption algorithm
 ====================
 
-The SlunkCrypt algorithm is based on core concepts of the well-known [**Enigma**](https://en.wikipedia.org/wiki/Enigma_machine) machine but with numerous improvements, largely inspired by R. Anderson's [***“A Modern Rotor Machine”***](https://rdcu.be/cBo8y):
+SlunkCrypt is based on concepts of the well-known [**Enigma**](https://en.wikipedia.org/wiki/Enigma_machine) machine, but with significant improvements, largely inspired by [***Ross Anderson &ndash; “A Modern Rotor Machine”***](https://rdcu.be/cBo8y).
+
+A great explanation and visualization of how the *original* Enigma machine works can be found in [***this***](https://www.youtube.com/watch?v=ybkkiGtJmkM) video.
+
+Overview
+--------
+
+This section summarizes the improvements that have been implemented in SlunkCrypt:
 
 - The original Enigma machine had only *three* (or, in some models, *four*) rotors, plus a static "reflector" wheel. In SlunkCrypt, we uses **256** simulated rotors for an improved security. Furthermore, the original Enigma machine supported only 26 distinct symbols, i.e. the letters `A` to `Z`. In SlunkCrypt, we use **256** distinct symbols, i.e. the byte values `0x00` to `0xFF`, which allows the encryption (and decryption) of arbitrary streams of bytes, rather than just plain text. Of course, SlunkCrypt can encrypt (and decrypt) text files as well.
 
@@ -201,9 +216,22 @@ The SlunkCrypt algorithm is based on core concepts of the well-known [**Enigma**
 
 - In the original Enigma machine, the rightmost rotor was moved, by one step, after every symbol. Meanwhile, all other rotors were moved, by one step, *only* when their right-hand neighbor had completed a full turn &ndash; much like the odometer in a car. The fact that most of the rotors remained in the same "static" position most of the time was an important weakness of the Enigma machine. Also, the sequence of the Enigma's rotor positions started to repeat after only 16,900 characters. SlunkCrypt employs an improved stepping algorithm, based on a ***linear-feedback shift register* (LSFR)**, ensuring that *all* rotors move frequently and in a "randomized" unpredictable pattern. The rotor positions of SlunkCrypt practically *never* repeat.
 
-- The internal wiring of each of the original Enigma machine's rotors was *fixed*. Each rotor "type" came with a different internal wiring (i.e. permutation). Some models had up to eight rotor "types" to choose from, but only three or four rotors were used at a time. Nonetheless, the internal wiring (i.e. permutation) of each of the supplied rotors was **not** modifiable. This severely restricted the key space of the Enigma machine, as far as the rotors are concerned, because *only* the order of the rotors and the initial position of each rotor could be varied. In SlunkCrypt, a fully *randomized* wiring (i.e. permutation) is generated from the password for each of the 256 simulated rotors. The initial rotor positions are *randomized* as well.
+- The internal wiring of each of the original Enigma machine's rotors was *fixed*. Each rotor "type" came with a different internal wiring (i.e. permutation). Some models had up to eight rotor "types" to choose from, but only three or four rotors were used at a time. Nonetheless, the internal wiring (i.e. permutation) of each of the supplied rotors was **not** modifiable. This severely restricted the key space of the Enigma machine, as far as the rotors are concerned, because *only* the order of the rotors and the initial position of each rotor could be varied. In SlunkCrypt, a fully *randomized* wiring (i.e. permutation) is generated from the passphrase for each of the 256 simulated rotors. The initial rotor positions are *randomized* as well.
+
+- SlunkCrypt does **not** currently implement the *plugboard* (“Steckerbrett”). Even though the plugboard significantly contributed to the key space of the original Engima machine, it was simply a *fixed* substitution cipher. SlunkCrypt already has a ***much*** bigger key space than that of the original Engine machine, because the number of rotors is substantially larger and because the internal wiring of these rotors is completely key-dependant. Therefore, adding a plugboard would *not* contribute notably to SlunkCrypt's cryptographic strength.
+
+Details
+-------
+
+This section explains some crucial implementation details of the SlunkCrypt library:
+
+* **DRBG:** The *deterministic random bit generator* (DRBG) employed by SlunkCrypt is called [*Xorwow*](https://en.wikipedia.org/wiki/Xorshift#xorwow), an enhanced variant of *Xorshift* , i.e. a form of *linear-feedback shift registers (LSFR)*.
 
-- SlunkCrypt does **not** currently implement the *plugboard* (“Steckerbrett”) of the original Enigma machine. That is because, even though the plugboard has a large key space, it is just a *fixed* substitution cipher that does *not* contribute much to the cryptographic strength of the Enigma machine. In fact, the plugboard could be "erased" by Welchman's [diagonal board](https://en.wikipedia.org/wiki/Bombe#Stecker_values).
+* **Initialization (key schedule):** In the initialization phase, the *pseudo-random* internal wiring (i.e. permutation) is generated &ndash; separately for each of the 256 rotors. For this purpose, the initial state of the DRBG is set up in a way that depends on the given *passphrase*, a message-specific *nonce* as well as the current *rotor index*. More specifically, the initial state of the DRBG is derived from a combination of all input parameters, by applying a <u>large</u> number of iterations of the *FNV&#8209;1a 128-Bit* hash function. The permutation for the current rotor is then created by the ***Fisher&#8209;Yates*** shuffle algorithm, using the DRBG as its randomness source. This produces a distinct "randomized" internal rotor wiring for each message to be encrypted. 
+
+* **Message processing:** During the encryption or decryption process, the individual offsets (positions) of the first 8 rotors are controlled by a 64-Bit counter, whereas the offsets of the remaining 248 rotors are continuously "randomized" by the DRBG. The initial counter value as well as the initial state of the DRBG are set up in a way that depends on the given *passphrase* and a message-specific *nonce*. Also, after each symbol that was processed, the counter is incremented by one and new *pseudo-random* offsets (rotor positions) are drawn.
+
+* **Checksum:** The message-length is padded to a multiple of 8 bytes and a 64-Bit [BLAKE2s](https://www.blake2.net/) hash is appended, *before* encryption. This "checksum" can be used to detect decryption errors.
 
 
 Programming Interface (API)
@@ -286,7 +314,9 @@ Create and initialize a new **``Encryptor``** instance. Also generated a new, ra
 
     Encryptor::Encryptor(
       const std::string &passwd,
-      const size_t thread_count = 0U
+      const size_t thread_count = 0U,
+      const bool legacy_compat = false,
+      const bool debug_logging = false
     );
 
 ***Parameters:***
@@ -299,6 +329,12 @@ Create and initialize a new **``Encryptor``** instance. Also generated a new, ra
   * `thread_count`  
     Specifies the number of worker threads to use (optional). By default, SlunkCrypt detects the number of available processors and creates one thread for each processor.
 
+  * `legacy_compat`  
+    Enables "legacy" compatibility-mode; required to encrypt messages in a way that allows decryption with SlunkCrypt version 1.2.x or earlier. Option is disabled by default.
+
+  * `debug_logging`  
+    Enables additional debug logging. Messages are written to the syslog (Unix-like) or to the debugger (Windows). Option is disabled by default.
+
 ***Exceptions:***
 
   * Throws `std::runtime_error`, if the nonce could not be generated, or if the SlunkCrypt context could not be allocated.
@@ -422,7 +458,9 @@ Create and initialize a new **``Decryptor``** instance.
     Decryptor::Decryptor(
       const std::string &passwd,
       const uint64_t nonce,
-      const size_t thread_count = 0U
+      const size_t thread_count = 0U,
+      const bool legacy_compat = false,
+      const bool debug_logging = false
     );
 
 ***Parameters:***
@@ -440,6 +478,12 @@ Create and initialize a new **``Decryptor``** instance.
   * `thread_count`  
     Specifies the number of worker threads to use (optional). By default, SlunkCrypt detects the number of available processors and creates one thread for each processor.
 
+  * `legacy_compat`  
+    Enables "legacy" compatibility-mode; required to decrypt messages that were encrypted with SlunkCrypt version 1.2.x or earlier. Option is disabled by default.
+
+  * `debug_logging`  
+    Enables additional debug logging. Messages are written to the syslog (Unix-like) or to the debugger (Windows). Option is disabled by default.
+
 ***Exceptions:***
 
   * Throws `std::runtime_error`, if the SlunkCrypt context could not be allocated.
@@ -799,7 +843,9 @@ Erase the contents of a byte array, by overwriting it with *zero* bytes. Compile
 The `slunkparam_t` struct is used to pass additional parameters that will be used for initializing the SlunkCrypt context. It contains the following fields:
 
 * `version` &ndash; The version of the parameter struct; **must** be set to *`SLUNKCRYPT_PARAM_VERSION`*.
-* `thread_count` &ndash; The number of worker threads to use. If this parameter is set to **0**, which is the *default* value, then SlunkCrypt automatically detects the number of available (logical) processors and creates one thread for each processor. Also, the number of threads is capped to a maximum of `MAX_THREADS` (currently defined as **16**).
+* `thread_count` &ndash; The number of worker threads to use. If this parameter is set to **0**, which is the *default* value, then SlunkCrypt automatically detects the number of available (logical) processors and creates one thread for each processor. Also, the number of threads is capped to a maximum of `MAX_THREADS` (currently defined as **32**).
+* `legacy_compat` &ndash; If set to *`SLUNKCRYPT_TRUE`*, enables "legacy" compatibility-mode; required to decrypt messages that were encrypted with SlunkCrypt version 1.2.x or earlier.
+* `debug_logging` &ndash; If set to *`SLUNKCRYPT_TRUE`*, enables additional debug logging; messages are written to the syslog (Unix-like) or to the debugger (Windows).
 
 ### Global variables
 
@@ -875,6 +921,66 @@ The following functions are "reentrant" and thus may safely be called by *any* t
 ***Note:*** If the same `slunkcrypt_t`, `Encryptor` or `Decryptor` instance needs to be shared across *multiple* threads (i.e. the same instance is accessed by *concurrent* threads), then the application **must** *serialize* any invocation of the above functions on that shared instance, by using a suitable synchronization mechanism! This can be achieved by using a [*mutex*](https://linux.die.net/man/3/pthread_mutex_lock).
 
 
+Source Code
+===========
+
+The latest SlunkCrypt source code is available from the official Git mirrors at:
+
+* <https://osdn.net/projects/slunkcrypt/scm/git/SlunkCrypt/>
+* <https://gitlab.com/lord_mulder/slunkcrypt/>
+* <https://bitbucket.org/muldersoft/slunkcrypt/>
+* <https://repo.or.cz/slunkcrypt.git>
+* <https://punkindrublic.mooo.com:3000/Muldersoft/SlunkCrypt>
+
+
+Build Instructions
+==================
+
+SlunkCrypt can be built from the sources on Microsoft Windows or any POSIX-compatible platform, using a C-compiler that supports the C99 standard.
+
+* **Microsoft Windows:**  
+  Project/solution files for [Visual Studio](https://visualstudio.microsoft.com/) are provided. These should work “out of the box” with Visual Studio 2017 or any later version.  
+  Just open the solution, select the “Release” configuration, choose the “x86” or “x64” platform, and finally press `F5`.  
+  Visual Studio also is the only way to build the SlunkCrypt GUI, which is based on Microsoft.NET and Windows Presentation Foundation (WPF).
+
+  Alternatively, SlunkCrypt can built using [Mingw-w64](https://www.mingw-w64.org/) (available via [MSYS2](https://www.msys2.org/)) or even [Cygwin](https://www.cygwin.com/) &ndash; see Linux instructions for details!
+
+* **Linux:**  
+  Please make sure that the *C compiler* (GCC or Clang) as well as *Make* are installed. Then simply run **`make -B`** from the project's base directory!
+
+  If not already installed, the required build tools can usually be installed via your distribution's package manager.  
+  For example, on Debian-based distributions, the command **`sudo apt install build-essential`** installs all the required build tools at once.
+
+  In order to create a *fully-static* binary of SlunkCrypt that runs on ***any*** Linux distribution from the last decade, you can use [musl libc](https://musl.libc.org/):  
+  `make -B CC=musl-gcc STATIC=1`
+
+* **BSD and Solaris:**  
+  SlunkCrypt can be built on various BSD flavors and Solaris, but the command **`gmake -B`** needs to be used here, since the native `make` doesn't work!  
+  GNU Make can be installed from the package manager. For example, use **`pkg install gmake`** on FreeBSD or **`pkg_add gmake`** on OpenBSD.
+
+* **Mac OS X:**  
+  Once you have managed to find a terminal (or even better, connect via SSH), Mac OS X almost works like a proper operating system.  
+  The Xcode command-line tools can be installed with the command **`xcode-select --install`**, if not present yet. Then just type **`make -B`** to build!
+
+  *Hint:* If you want to build with GCC, which produces faster code than Apple's Xcode compiler, you may install it on Mac OS X via [Homebrew](https://formulae.brew.sh/formula/gcc).
+
+
+Frequently Asked Questions
+==========================
+
+* **Why does the decryption of my file fail with a checksum error?**
+
+  If SlunkCrypt fails to decrypt a file and reports a “checksum mismatch” error, then this means that either the given file was *not* actually encrypted with SlunkCrypt, the file was corrupted in some kind of way (e.g. incomplete download), or you did *not* provide the correct passphrase for the file. There is, unfortuantely, *no* way to distinguish these three cases, as files encrypted with SlunkCrypt are indistingushable from random noise &ndash; only with the correct passphrase, some meaningful data can be restored from the encrypted file. Trying to decrypt the file with a *wrong* passphrase results in just "random" gibberish! However, the same also happens if the file was corrupted, or if the file was *not* encrypted with SlunkCrypt.
+
+  *Note:* If you are using SlunkCrypt 1.3.0 or later, then files that have been encrypted with SlunkCrypt 1.2.x or older can only be decrypted by enabling the “legacy” compatibility-mode!
+
+* **How can I recover the lost passphrase for my file?**
+
+  SlunkCrypt uses a combination of the given passphrase and the individual nonce to encrypt each file in a *unique* (pseudo-random) way. This means that *no* two files are encrypted in the same way. Consequently, the decryption of the file is *only* possible using the correct passphrase, i.e. the one which was used to encrypt the file. Trying to decrypt the file with a *wrong* passphrase results in just "random" gibberish. And, for good reasons, there is *no* way to recover the passphrase from an encrypted file, so take good care of your passphrase!
+
+  In theory, it is possible to “crack” the passphrase using the *brute-force* method, i.e. try out every possible passphrase (up to a certain length) until the correct one is found. However, provided that a sufficiently long and random passphrase was chosen &ndash; which is highly recommended &ndash; there are *way* too many combinations to try them all, in a reasonable time. For example, with a length of 12 characters (ASCII), there are 95<sup>12</sup> = 540,360,087,662,636,962,890,625 possible combinations! This renders *brute-force* attacks practically impossible.
+
+
 License
 =======
 
@@ -882,3 +988,46 @@ This work has been released under the **CC0 1.0 Universal** license.
 
 For details, please refer to:  
 <https://creativecommons.org/publicdomain/zero/1.0/legalcode>
+
+Acknowledgement
+---------------
+
+SlunkCrypt incorporates code from the following *third-party* software projects:
+
+* The "checksum" algorithm used by the SlunkCrypt command-line application was adapted from the **BLAKE2** reference C implementation.  
+  ```
+   BLAKE2 reference source code package - reference C implementations
+   Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
+   terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
+   your option.  The terms of these licenses can be found at:
+   - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+   - OpenSSL license   : https://www.openssl.org/source/license.html
+   - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
+
+   More information about the BLAKE2 hash function can be found at
+   https://blake2.net.
+   ```
+
+* ***Windows only:*** Builds of SlunkCypt that have multi-threading enabled use the **POSIX Threads for Windows (pthreads4w)** library.  
+  ```
+  Pthreads4w - POSIX Threads for Windows
+  Copyright 1998 John E. Bossom
+  Copyright 1999-2018, Pthreads4w contributors
+
+  Homepage: https://sourceforge.net/projects/pthreads4w/
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ```
+
+
+&marker;