aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--LICENSE21
-rw-r--r--Makefile16
-rw-r--r--README45
-rw-r--r--aesscan.c496
-rwxr-xr-xtest/encrypt.sh10
-rw-r--r--test/encrypted-txt-1.binbin0 -> 880 bytes
-rw-r--r--test/encrypted-txt-2.binbin0 -> 944 bytes
-rw-r--r--test/encrypted-txt-3.binbin0 -> 736 bytes
-rw-r--r--test/encrypted-txt-with-iv-1.binbin0 -> 896 bytes
-rw-r--r--test/encrypted-txt-with-iv-2.binbin0 -> 960 bytes
-rw-r--r--test/encrypted-txt-with-iv-3.binbin0 -> 752 bytes
-rw-r--r--test/encrypted-txt-with-iv.bin2
-rw-r--r--test/encrypted-txt.bin1
-rw-r--r--test/key.bin2
-rw-r--r--test/keyandjunk.binbin0 -> 137088 bytes
-rw-r--r--test/plaintext-1.txt12
-rw-r--r--test/plaintext-2.txt11
-rw-r--r--test/plaintext-3.txt8
-rw-r--r--test/plaintext.txt3
20 files changed, 629 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..44746e7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.o
+aesscan
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..b77733f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright © 2014 Samuel Lidén Borell <samuel@kodafritt.se>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c93324b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,16 @@
+CFLAGS += -Wall -Wextra -ansi
+LDFLAGS += -lnettle
+
+all: aesscan
+
+aesscan: aesscan.o
+
+clean:
+ -rm -f aesscan aesscan.o
+
+# Should show "109992: found key (decrypted data = 4 text, 0 binary)"
+test: aesscan
+ ./aesscan -s test/keyandjunk.bin test/encrypted-txt-with-iv.bin test/encrypted-txt-with-iv-1.bin test/encrypted-txt-with-iv-2.bin test/encrypted-txt-with-iv-3.bin
+
+
+.PHONY: all clean test
diff --git a/README b/README
new file mode 100644
index 0000000..94927b2
--- /dev/null
+++ b/README
@@ -0,0 +1,45 @@
+AESScan
+-------
+
+This is a command line utility to search binary data for possible AES keys.
+You will need one or more ciphertexts encrypted using the key that is
+suspected to appear in the binary file. The ciphertexts are used to attempt
+decryption, and check if the resulting plaintext makes any sense. The
+plaintext is assumed to contain either a large number of zero bytes (typical
+for binary data) or a very small number of uncommon control characters
+(typical for text files). So it's not possible to use this tool on random data
+that has been encrypted, or data that has been encrypted multiple times.
+
+The command line syntax is:
+
+ aesscan -s binary.bin [options] ciphertext1.bin ciphertext2.bin ...
+
+Where binary.bin is the file to search for keys in. Supported options are:
+
+ -c CIPHER Set the cipher to use:
+ 0 AES128 with CBC (default)
+ 1 AES128 with ECB
+ 2 AES256 with CBC
+ 3 AES256 with ECB
+ -p PADDING Set the padding to use:
+ 0 PKCS#5 (default)
+ 1 Simply throw away the last block
+ 2 No padding
+ -l LEN Try to decrypt only up to LEN bytes in the FILES
+ -o OFFSET Start from the given byte offset in the FILES
+
+The -o and -l options are parsed from left to right. An -o or -l option must
+occur before the ciphertext file(s) it should to apply to.
+
+AES is typically used with a block mode and a padding. CBC and PKCS#7
+is the most common block mode and padding, so these are the defaults.
+When the padding type is unknown, it is useful to use "throw away" option
+(number 1) which will simply skip the last encrypted block. This option will
+obviously only work if the data is more than 16 bytes, which is the block
+size of AES (regardless of key size).
+
+For block modes other than ECB, this tool will assume that the first 16 bytes
+is the Initialization Vector (IV) for the following data. This is the most
+common way of encoding encrypted AES data.
+
+
diff --git a/aesscan.c b/aesscan.c
new file mode 100644
index 0000000..b9c9e95
--- /dev/null
+++ b/aesscan.c
@@ -0,0 +1,496 @@
+/*
+
+ aesscan.c -- Utility to scan for AES keys in binaries
+
+ Copyright © 2014 Samuel Lidén Borell <samuel@kodafritt.se>
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <nettle/aes.h>
+#include <nettle/cbc.h>
+
+#define READSIZE 1024
+
+struct fileentry {
+ char *name;
+ long datalen;
+ unsigned char *data;
+};
+
+enum ciphermode {
+ AES128_CBC = 0,
+ AES128_ECB,
+ AES256_CBC,
+ AES256_ECB
+};
+
+static const char ciphermodes[][11] = {
+ "AES128_CBC",
+ "AES128_ECB",
+ "AES256_CBC",
+ "AES256_ECB"
+};
+
+
+static const int cipher_iv_size[] = {
+ AES_BLOCK_SIZE,
+ 0,
+ AES_BLOCK_SIZE,
+ 0
+};
+
+static const size_t cipher_key_size[] = {
+ 128/8, /* TODO upgrade libnettle and use AES128_KEY_SIZE */
+ 128/8,
+ 256/8,
+ 256/8
+};
+
+enum padding {
+ PKCS7,
+ THROW_AWAY, /* throw away last block */
+ NO_PADDING
+};
+
+static const char paddings[][11] = {
+ "PKCS#7",
+ "THROW_AWAY",
+ "NONE"
+};
+
+
+static long offset;
+static long maxlength;
+static long numfiles;
+static struct fileentry *files;
+static char *scanfilename;
+static FILE *scanfile;
+static unsigned char *decryptbuff;
+static enum ciphermode ciphermode;
+static enum padding padding;
+
+static union {
+ struct aes_ctx aesctx;
+ /*struct CBC_CTX(struct aes_ctx, 128/8) aes128cbc;*/
+} keyctx;
+
+
+enum typeofdata {
+ JUNK = 0,
+ TEXT = 1,
+ BINARY = 2
+};
+
+/*
+ No strange control characters = OK, probably text
+ High number of zeros = OK, probably binary data
+*/
+enum typeofdata checkdata(const unsigned char *data, long len)
+{
+ long numzeros = 0;
+ long numcontrol = 0;
+ float rzero, rctrl;
+ const unsigned char *p = data;
+ const unsigned char *end = data+len;
+
+ int i;
+ char padsize = end[-1];
+ if (padding == PKCS7) {
+ if (padsize > AES_BLOCK_SIZE || padsize < 0) {
+ return JUNK;
+ }
+ for (i = 0; i < padsize; i++) {
+ if (end <= p || *--end != padsize) return JUNK;
+ }
+ } else if (padding == THROW_AWAY) {
+ end -= AES_BLOCK_SIZE;
+ }
+
+ while (p < end) {
+ unsigned char c = *(p++);
+ if (c == '\0') {
+ numzeros++;
+ } else if (c >= '\x01' && c <= '\x1F' &&
+ c != '\x09' && c != '\x08' && c != '\x0A' && c != '\x0D') {
+ numcontrol++;
+ }
+ }
+
+ rzero = (float)numzeros / (float)len;
+ rctrl = (float)numcontrol / (float)len;
+
+ if (rzero >= 0.02) { /* >> 1/256 */
+ return BINARY;
+ } else if (rctrl <= 0.03) { /* << (32-4) / 256 */
+ return TEXT;
+ } else if (padding == PKCS7 && padsize >= 4) {
+ return BINARY;
+ } else {
+ return JUNK;
+ }
+}
+
+void decrypt(unsigned char *encrypted, long len, const unsigned char *key,
+ unsigned char *decrypted)
+{
+ unsigned char iv[AES_BLOCK_SIZE];
+ /* TODO use nettle-meta.h */
+ switch (ciphermode) {
+ case AES128_CBC:
+ if (len < AES_BLOCK_SIZE) { abort(); }
+ memcpy(iv, encrypted, AES_BLOCK_SIZE);
+ aes_set_decrypt_key(&keyctx.aesctx, 128/8, key);
+ cbc_decrypt(&keyctx.aesctx, (nettle_crypt_func *)aes_decrypt, AES_BLOCK_SIZE, iv,
+ len-AES_BLOCK_SIZE, decrypted, encrypted+AES_BLOCK_SIZE);
+ break;
+ case AES128_ECB:
+ aes_set_decrypt_key(&keyctx.aesctx, 128/8, key);
+ aes_decrypt(&keyctx.aesctx, len, decrypted, encrypted);
+ break;
+ case AES256_CBC:
+ if (len < AES_BLOCK_SIZE) { abort(); }
+ memcpy(iv, encrypted, AES_BLOCK_SIZE);
+ aes_set_decrypt_key(&keyctx.aesctx, 256/8, key);
+ cbc_decrypt(&keyctx.aesctx, (nettle_crypt_func *)aes_decrypt, AES_BLOCK_SIZE, iv,
+ len-AES_BLOCK_SIZE, decrypted, encrypted+AES_BLOCK_SIZE);
+ break;
+ case AES256_ECB:
+ aes_set_decrypt_key(&keyctx.aesctx, 256/8, key);
+ aes_decrypt(&keyctx.aesctx, len, decrypted, encrypted);
+ break;
+ default:
+ abort();
+ }
+ /*putchar(key[128/8-1]);*/
+}
+
+int try_decrypt(long scan_offset, unsigned char *key)
+{
+ long files_text = 0, files_bin = 0;
+ long i;
+
+ for (i = 0; i < numfiles; i++) {
+ const struct fileentry *entry = &files[i];
+ enum typeofdata result;
+ const long decryptlen = entry->datalen - cipher_iv_size[ciphermode];
+
+/*if (*key == 0x4B && key[1] == 0x45 && key[2] == 0x59) {
+fprintf(stderr, "found key at %ld\n", scan_offset);
+fprintf(stderr, "file = %hhx %hhx %hhx %hhx\n", entry->data[0], entry->data[1], entry->data[2], entry->data[3]);
+}*/
+ decrypt(entry->data, entry->datalen, key, decryptbuff);
+/*if (*key == 0x4B && key[1] == 0x45 && key[2] == 0x59) {
+fprintf(stderr, "data = %.*s\n", decryptlen, decryptbuff);
+}*/
+
+/*result = 0;
+if (*key == 0x4B && key[1] == 0x45 && key[2] == 0x59) {*/
+ result = checkdata(decryptbuff, decryptlen);
+/*fprintf(stderr, "result = %d\n", result);
+}*/
+
+ if (result == JUNK) return 0;
+
+ if (result == BINARY) files_bin++;
+ else files_text++;
+ }
+
+ printf("%ld: found key (decrypted data = %ld text, %ld binary)\n",
+ scan_offset, files_text, files_bin);
+ return 0;
+}
+
+void do_scan_file()
+{
+ unsigned char keybuff[2*READSIZE];
+ unsigned long scan_offset = 0;
+ const unsigned long keysize = cipher_key_size[ciphermode];
+
+ size_t numbytes = fread(keybuff, 1, READSIZE, scanfile);
+ if (numbytes != READSIZE && ferror(scanfile)) {
+ perror("scan file too short");
+ exit(1);
+ }
+
+ /* Scan the first half of the buffer and move in more data.
+ This is done so we can handle keys that overlap a READSIZE
+ boundary. */
+ while (!feof(scanfile)) {
+ unsigned long keyoffs = 0;
+ int nonzeros = keysize;
+
+ if ((scan_offset & 0xFFFFFL) == 0) {
+ fprintf(stderr, "Scanned %ld bytes\n", scan_offset);
+ }
+
+ numbytes += fread(keybuff+READSIZE, 1, READSIZE, scanfile);
+ while (numbytes > READSIZE) {
+ if (keybuff[keyoffs+keysize]) {
+ nonzeros = keysize;
+ }
+
+ if (nonzeros) {
+ try_decrypt(scan_offset, &keybuff[keyoffs]);
+ }
+ numbytes--;
+ scan_offset++;
+ keyoffs++;
+ if (nonzeros) nonzeros--;
+ }
+ memcpy(keybuff, keybuff+READSIZE, READSIZE);
+ }
+
+ /* Scan the remaining data */
+ {
+ unsigned long keyoffs = 0;
+ while (numbytes > keysize) {
+ try_decrypt(scan_offset, &keybuff[keyoffs]);
+ numbytes--;
+ scan_offset++;
+ keyoffs++;
+ }
+ fprintf(stderr, "Scanned %ld bytes\n", scan_offset);
+ }
+}
+
+void show_usage(const char *arg0)
+{
+ printf("usage: %s -s FILE_TO_SCAN [-o OFFSET] [-l LEN] FILES...\n"
+ "\n"
+ "Tries to decrypt the given FILES with AES-128/256 using all 128/256-bit\n"
+ "substrings in FILE_TO_SCAN.\n"
+ "\n"
+ "Options:\n"
+ " -c CIPHER Set the cipher to use:\n"
+ " 0 AES128 with CBC (default)\n"
+ " 1 AES128 with ECB\n"
+ " 2 AES256 with CBC\n"
+ " 3 AES256 with ECB\n"
+ " -p PADDING Set the padding to use:\n"
+ " 0 PKCS#5 (default)\n"
+ " 1 Simply throw away the last block\n"
+ " 2 No padding\n"
+ " -l LEN Try to decrypt only up to LEN bytes in the FILES\n"
+ " -o OFFSET Start from the given byte offset in the FILES\n"
+ "\n"
+ "Note: The -o and -l options are parsed from left to right. An -o\n"
+ "or -l option must occur before the file(s) it should to apply to.\n"
+ "\n",
+ arg0);
+}
+
+long get_num(int argc, char **argv, int *idxp)
+{
+ int i = *idxp;
+ long value;
+ char *s, *endp;
+
+ if (i+1 >= argc) {
+ fprintf(stderr, "%s: option requires an argument\n", argv[i]);
+ exit(2);
+ }
+
+ s = argv[i+1];
+ value = strtol(s, &endp, 10);
+ if (*s == '\0' || *endp != '\0' || value < 0) {
+ fprintf(stderr, "%s: invalid number\n", s);
+ exit(2);
+ }
+
+ *idxp = i+1;
+ return value;
+}
+
+char *get_str(int argc, char **argv, int *idxp)
+{
+ int i = *idxp;
+
+ if (i+1 >= argc) {
+ fprintf(stderr, "%s: option requires an argument\n", argv[i]);
+ exit(2);
+ }
+
+ *idxp = i+1;
+ return argv[i+1];
+}
+
+int main(int argc, char **argv)
+{
+ int parsing_opts = 1, error = 0;
+ int i;
+ long maxdatalen;
+ for (i = 1; i < argc; i++) {
+ char *const arg = argv[i];
+ if (arg[0] == '-' && parsing_opts) {
+ /* Option */
+ if (arg[1] == '-' && arg[2] == '\0') {
+ /* "--" = stop parsing arguments */
+ parsing_opts = 0;
+ continue;
+ }
+ if (arg[1] != '\0' && arg[2] == '\0') {
+ switch (arg[1]) {
+ case 'c': /*{
+ const char *s = get_str(argc, argv, &i);
+ if (strcmp
+ break; }*/
+ ciphermode = get_num(argc, argv, &i);
+ if (ciphermode > AES256_ECB) {
+ fprintf(stderr, "%s: invalid cipher type %d\n",
+ argv[0], ciphermode);
+ error = 1;
+ }
+ break;
+ case 'h':
+ show_usage(argv[0]);
+ return 0;
+ case 'l':
+ maxlength = get_num(argc, argv, &i);
+ break;
+ case 'o':
+ offset = get_num(argc, argv, &i);
+ break;
+ case 'p':
+ padding = get_num(argc, argv, &i);
+ if (padding > NO_PADDING) {
+ fprintf(stderr, "%s: invalid paddig type %d\n",
+ argv[0], padding);
+ error = 1;
+ }
+ break;
+ case 's':
+ scanfilename = get_str(argc, argv, &i);
+ break;
+ }
+ }
+ } else {
+ /* Filename */
+ unsigned char *data;
+ long datalen;
+ struct fileentry *entry;
+ FILE *file = fopen(arg, "rb");
+ if (!file) {
+ perror(arg);
+ error = 1;
+ continue;
+ }
+
+ if (offset) {
+ if (fseek(file, offset, SEEK_SET) == -1) {
+ perror(arg);
+ exit(1);
+ }
+ }
+
+ if (!maxlength) {
+ /* Read the whole file */
+ if (fseek(file, 0, SEEK_END) == -1) {
+ perror(arg);
+ exit(1);
+ }
+
+ datalen = ftell(file) - offset;
+ if (datalen < 0) {
+ perror("ftell");
+ exit(1);
+ }
+
+ data = malloc(datalen);
+ if (!data) {
+ perror("allocating memory for file");
+ exit(1);
+ }
+
+ if (fseek(file, offset, SEEK_SET) == -1) {
+ perror(arg);
+ exit(1);
+ }
+ }
+
+ if (fread(data, 1, datalen, file) != (size_t)datalen) {
+ perror(arg);
+ exit(1);
+ }
+
+ fclose(file);
+
+ if (datalen == 0) {
+ fprintf(stderr, "%s: File is empty\n", arg);
+ exit(1);
+ }
+
+ numfiles++;
+ files = realloc(files, sizeof(struct fileentry)*numfiles);
+ if (!files) {
+ perror("realloc");
+ exit(1);
+ }
+ entry = &files[numfiles-1];
+ entry->name = arg;
+ entry->data = data;
+ entry->datalen = datalen;
+ }
+ }
+
+ if (error) {
+ return 1;
+ }
+
+ if (!numfiles) {
+ fprintf(stderr, "%s: no files specified\n", argv[0]);
+ show_usage(argv[0]);
+ return 2;
+ }
+
+ if (!scanfilename) {
+ fprintf(stderr, "%s: no scan file specified\n", argv[0]);
+ return 2;
+ }
+
+ /* Allocate buffer for decryption */
+ maxdatalen = 0;
+ for (i = 0; i < numfiles; i++) {
+ if (files[i].datalen > maxdatalen) {
+ maxdatalen = files[i].datalen;
+ }
+ }
+ decryptbuff = malloc(maxdatalen);
+
+ fprintf(stderr, "Using %s cipher and mode, with padding %s\n",
+ ciphermodes[ciphermode], paddings[padding]);
+
+ /* Start scanning the file for keys */
+ scanfile = fopen(scanfilename, "rb");
+ if (!scanfile) {
+ perror(scanfilename);
+ exit(1);
+ }
+
+ do_scan_file();
+
+ fclose(scanfile);
+
+ return 0;
+}
+
diff --git a/test/encrypt.sh b/test/encrypt.sh
new file mode 100755
index 0000000..1c8753a
--- /dev/null
+++ b/test/encrypt.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+key=4B4559030405060708090A0B0C0D0E0F
+
+iv=495612131415161718191A1B1C1D1E1F
+num=1
+
+openssl enc -aes-128-cbc -e -in plaintext-$num.txt -out encrypted-txt-$num.bin -iv $iv -K $key
+echo $iv | xxd -ps -r > encrypted-txt-with-iv-$num.bin
+cat encrypted-txt-$num.bin >> encrypted-txt-with-iv-$num.bin
diff --git a/test/encrypted-txt-1.bin b/test/encrypted-txt-1.bin
new file mode 100644
index 0000000..faf8ade
--- /dev/null
+++ b/test/encrypted-txt-1.bin
Binary files differ
diff --git a/test/encrypted-txt-2.bin b/test/encrypted-txt-2.bin
new file mode 100644
index 0000000..7243e66
--- /dev/null
+++ b/test/encrypted-txt-2.bin
Binary files differ
diff --git a/test/encrypted-txt-3.bin b/test/encrypted-txt-3.bin
new file mode 100644
index 0000000..6770364
--- /dev/null
+++ b/test/encrypted-txt-3.bin
Binary files differ
diff --git a/test/encrypted-txt-with-iv-1.bin b/test/encrypted-txt-with-iv-1.bin
new file mode 100644
index 0000000..f0dc33b
--- /dev/null
+++ b/test/encrypted-txt-with-iv-1.bin
Binary files differ
diff --git a/test/encrypted-txt-with-iv-2.bin b/test/encrypted-txt-with-iv-2.bin
new file mode 100644
index 0000000..9584632
--- /dev/null
+++ b/test/encrypted-txt-with-iv-2.bin
Binary files differ
diff --git a/test/encrypted-txt-with-iv-3.bin b/test/encrypted-txt-with-iv-3.bin
new file mode 100644
index 0000000..133b959
--- /dev/null
+++ b/test/encrypted-txt-with-iv-3.bin
Binary files differ
diff --git a/test/encrypted-txt-with-iv.bin b/test/encrypted-txt-with-iv.bin
new file mode 100644
index 0000000..5382c1e
--- /dev/null
+++ b/test/encrypted-txt-with-iv.bin
@@ -0,0 +1,2 @@
+IV
+ 顐DA~"︍VʹΞHY92@ fk@YA[T H:5P&y[98<i!_HBXB}}mHÙזaw@8r㶡 \ No newline at end of file
diff --git a/test/encrypted-txt.bin b/test/encrypted-txt.bin
new file mode 100644
index 0000000..432a764
--- /dev/null
+++ b/test/encrypted-txt.bin
@@ -0,0 +1 @@
+顐DA~"︍VʹΞHY92@ fk@YA[T H:5P&y[98<i!_HBXB}}mHÙזaw@8r㶡 \ No newline at end of file
diff --git a/test/key.bin b/test/key.bin
new file mode 100644
index 0000000..0364907
--- /dev/null
+++ b/test/key.bin
@@ -0,0 +1,2 @@
+KEY
+  \ No newline at end of file
diff --git a/test/keyandjunk.bin b/test/keyandjunk.bin
new file mode 100644
index 0000000..1d50def
--- /dev/null
+++ b/test/keyandjunk.bin
Binary files differ
diff --git a/test/plaintext-1.txt b/test/plaintext-1.txt
new file mode 100644
index 0000000..7ad3603
--- /dev/null
+++ b/test/plaintext-1.txt
@@ -0,0 +1,12 @@
+Hej blablabla
+sdfdsdsfdsfsdhjfsdfjksd jsdfsd sdfjksd hsdkhdjskdsjkf jksakrwiczjhkfhdkdkfdfd
+sdf dslfjd lkjsdlkfjsdlkrdjfldsjf ilsdjldskdsfj dsk jkfjfdkfdjskdsjfksjksdfj
+sd fkfjdslkjlksdj fld jfkldj lksdfjlksdjf lkdj flkdjflkdj flkdjlkjlkfjldk
+ kdjflkdsjkflsdjdslk fjlkdsfj lkdsj kdsjfkldsjlfkj dlkfjdslkf jdslk jfdslkjfd
+ dkfdlkjf lkjlkdfjlkjfdkljlkdsfjslkdfjlksdjkljdskldj flkdsj lkdjklfdjlkdfd jllk
+ kldsfj sdklfj lksdj flksdj flkdsjf klsdj fklj lkdj klfjsdlkfjskdl jkdlfj l
+dskljdslkf jlsdkfj lkdj kjd lkfdj flkdj flksdj klj dlkj lkj lkfjd lkd jlkfdj
+ksdjfkldsjf lkdslfdslk djsklfj dlksdj k jsljfkj fklfjslkf sj lksj kljfsdkljlk
+w oit wifjewlifjeljesseli jlisej leijli jliesjfliejliejf liejflis ifs jilse
+mv,f ,vnkvkz z zv,nzv,nzsj,vnd,z vnzdfzsd,n zis iej fwjfijweifjls sljf l jflse fjl
+ ilsjifjlew ifjlwj93fjl4fo slfjslf kdf lsdfj dlsifjiwljfo9w3fjsliejliesjlf
diff --git a/test/plaintext-2.txt b/test/plaintext-2.txt
new file mode 100644
index 0000000..1b1c63c
--- /dev/null
+++ b/test/plaintext-2.txt
@@ -0,0 +1,11 @@
+kvojidsfmkaJIVKLAGKDSFL SJFLDSJFLDSKOSDKFLSDKLDSFKLDSKFLDSK Lkllf dlk df lsdk lfk
+sdlk flksjfLJlsdf klsd flkdF LKD KFJLSDJLKSDJF LSKDjdlkjdlk fjsklfjdkf jdkldjflsefs
+sdlkjf sdlkjf lior3lwifjwl9rw3lorijsflisjkx,nvkjzljzlflzeivijlizfkszkjkzjjscljik hkseh fk
+sd fdsfoijsif ejilejrifdzjkiej lifhkifheihjhke zil esf idf difjdslifj sdfdksjfsfsddfd
+ior3ijowejihujoirweilse5945943085435 3453435 43543545435 34543 345435435435436436
+434593580284795724857943757439574389578439 789437 89437598 73895743985798457435
+43859435843850934890 83904830498590389038904389058908908b09 890 843908904 940859085
+438 90850984305984359 89304 8530958 9038590348 5903485903485 904385 90348590348 905830
+98508593 8340958 3049 85904385 9034859034859043859085094389504385908435904385049350
+439058904843058 93048 5903 8903458 9043 8903485 904385 49038 59038 908 90438 590438 50
+stir tjlirjtlirjtilwetiowutoiueoituwe oiruweoiuweioruiowrui ou iouweoiuroiwe uoieru
diff --git a/test/plaintext-3.txt b/test/plaintext-3.txt
new file mode 100644
index 0000000..6021538
--- /dev/null
+++ b/test/plaintext-3.txt
@@ -0,0 +1,8 @@
+jrilejd fklsjdlJLIJILJESLIFJSLIFsdfkofksdkldsldflksdklsdjkljklsdjlkfjsdlkfsjdfkljlkslksdj
+dsf sdjklfjsdkljsdkl jfdlsjfklsdfj sd jfklsdjfkdsjk lsdjlkdsjflkdj kldsj kldsjfkldsjfkldsj
+sdfj dlskjfdskl jfdslkjfdkljfdsklfjsdlkjfsdkljslkfjsdkljfdslk jdslk jfsdlkjfsdlkfjsdlkjgds
+ewrt532532532 23423 423423423 523tk lklgfkljfdklgj fdklgjfdlkjgkjfidjocjiovjxoivjixocvjo
+oicxjvoixcjviocicoxioxcuvcoiuxoiuvoicxuvoixuoicuvxcoiuvoixcuvioxc ucio vuoi ucoi uvoicxu o
+iuvoi cxuviocu voixcuvoixcu voiuvioxcuviocuvoifeoiduou3ofieuzouoi ueoiucoi3jceljilfjcielo
+kjgijweofjsielfjlijlkfosekfelskflisejflijelsjielsfjielieilejoeriqoriqwiwqriqwpowqporwqpo
+xzcmzxbxzmvxznmvzxn zxnmnmvnmnmzxxzcxzczxczxcvdsvreofdijcnvmgoriuhfnjet9prkfjirit4woiejf
diff --git a/test/plaintext.txt b/test/plaintext.txt
new file mode 100644
index 0000000..4f19b42
--- /dev/null
+++ b/test/plaintext.txt
@@ -0,0 +1,3 @@
+Hello, this is a test file. Bla bla bla. 123456789 bla bla bla bla abcdefghijklmnopqrstuvwxyz
+Bla bla bla bla bla.
+Test test test test test test.