diff --git a/sys/Makefile b/sys/Makefile
index d350ade174474a2745e5176300c465f6fde9308c..15aaa0f2b386dcacb4febe179438489999f168c8 100644
--- a/sys/Makefile
+++ b/sys/Makefile
@@ -76,8 +76,23 @@ endif
 ifneq (,$(findstring bloom,$(USEMODULE)))
     DIRS += bloom
 endif
-ifneq (,$(findstring crypto,$(USEMODULE)))
-    DIRS += crypto
+ifneq (,$(findstring crypto_3des,$(USEMODULE)))
+    DIRS += crypto/3des
+endif
+ifneq (,$(findstring crypto_aes,$(USEMODULE)))
+    DIRS += crypto/aes
+endif
+ifneq (,$(findstring crypto_rc5,$(USEMODULE)))
+    DIRS += crypto/rc5
+endif
+ifneq (,$(findstring crypto_sha256,$(USEMODULE)))
+    DIRS += crypto/sha256
+endif
+ifneq (,$(findstring crypto_skipjack,$(USEMODULE)))
+    DIRS += crypto/skipjack
+endif
+ifneq (,$(findstring crypto_twofish,$(USEMODULE)))
+    DIRS += crypto/twofish
 endif
 ifneq (,$(findstring random,$(USEMODULE)))
     DIRS += random
diff --git a/sys/crypto/3des/3des.c b/sys/crypto/3des/3des.c
new file mode 100644
index 0000000000000000000000000000000000000000..37a7ccaba13d7c33557f981c38f0ddfe2eeb261c
--- /dev/null
+++ b/sys/crypto/3des/3des.c
@@ -0,0 +1,532 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        3des.c
+ * @brief       implementation of the 3DES cipher-algorithm
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Tom St Denis <tomstdenis@gmail.com>, http://libtomcrypt.com
+ * @author      Dobes Vandermeer
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ *
+ * @date        18.09.2013 14:32:33
+ *
+ * @note        This implementation is based on a DES implementation included
+ *              in the LibTomCrypt modular cryptographic library.
+ *              The LibTomCrypt library provides various cryptographic
+ *              algorithms in a highly modular and flexible manner.
+ *              The library is free for all purposes without any express
+ *              guarantee it works.
+ *              Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
+ *              DES code submitted by Dobes Vandermeer
+ * @}
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "crypto/3des.h"
+#include "crypto/ciphers.h"
+
+/*************** GLOBALS ******************/
+/**
+ * @brief Interface to the 3DES cipher
+ */
+block_cipher_interface_t tripledes_interface = {
+    "3DES",
+    tripledes_init,
+    tripledes_encrypt,
+    tripledes_decrypt,
+    tripledes_setup_key,
+    tripledes_get_preferred_block_size
+};
+
+/**
+ * @brief struct for the 3DES key expansion
+ */
+struct des3_key_s {
+    uint32_t ek[3][32];         ///< encryption key
+    uint32_t dk[3][32];         ///< decryption key
+} des3_key_s;
+
+/************** PROTOTYPES ***************/
+static void cookey(const uint32_t *raw1, uint32_t *keyout);
+static void deskey(const uint8_t *key, int decrypt, uint32_t *keyout);
+static void desfunc(uint32_t *block, const uint32_t *keys);
+static uint8_t des3_key_setup(const uint8_t *key, struct des3_key_s *dkey);
+
+/*****************************************/
+
+
+/* Use the key schedule specific in the standard (ANSI X3.92-1981) */
+
+static const uint8_t pc1[56] = {
+    56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,
+    9,  1, 58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35,
+    62, 54, 46, 38, 30, 22, 14,  6, 61, 53, 45, 37, 29, 21,
+    13,  5, 60, 52, 44, 36, 28, 20, 12,  4, 27, 19, 11,  3
+};
+
+static const uint8_t totrot[16] = {
+    1,   2,  4,  6,
+    8,  10, 12, 14,
+    15, 17, 19, 21,
+    23, 25, 27, 28
+};
+
+static const uint8_t pc2[48] = {
+    13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
+    22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
+    40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+    43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
+};
+
+
+static const uint32_t SP1[64] = {
+    0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL,
+    0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL,
+    0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL,
+    0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL,
+    0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL,
+    0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL,
+    0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL,
+    0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL,
+    0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL,
+    0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL,
+    0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL,
+    0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL,
+    0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL,
+    0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL,
+    0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL,
+    0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL
+};
+
+static const uint32_t SP2[64] = {
+    0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL,
+    0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL,
+    0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL,
+    0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL,
+    0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL,
+    0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL,
+    0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL,
+    0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL,
+    0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL,
+    0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL,
+    0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL,
+    0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL,
+    0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL,
+    0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL,
+    0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL,
+    0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL
+};
+
+static const uint32_t SP3[64] = {
+    0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL,
+    0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL,
+    0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL,
+    0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL,
+    0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL,
+    0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL,
+    0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL,
+    0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL,
+    0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL,
+    0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL,
+    0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL,
+    0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL,
+    0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL,
+    0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL,
+    0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL,
+    0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL
+};
+
+static const uint32_t SP4[64] = {
+    0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
+    0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL,
+    0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL,
+    0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL,
+    0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL,
+    0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL,
+    0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL,
+    0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL,
+    0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL,
+    0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL,
+    0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL,
+    0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
+    0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL,
+    0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL,
+    0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL,
+    0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL
+};
+
+static const uint32_t SP5[64] = {
+    0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL,
+    0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL,
+    0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL,
+    0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL,
+    0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL,
+    0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL,
+    0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL,
+    0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL,
+    0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL,
+    0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL,
+    0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL,
+    0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL,
+    0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL,
+    0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL,
+    0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL,
+    0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL
+};
+
+static const uint32_t SP6[64] = {
+    0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL,
+    0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL,
+    0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL,
+    0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
+    0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL,
+    0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL,
+    0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL,
+    0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL,
+    0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL,
+    0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL,
+    0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
+    0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL,
+    0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL,
+    0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL,
+    0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL,
+    0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL
+};
+
+static const uint32_t SP7[64] = {
+    0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL,
+    0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL,
+    0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL,
+    0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL,
+    0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL,
+    0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL,
+    0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL,
+    0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL,
+    0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL,
+    0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL,
+    0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL,
+    0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL,
+    0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL,
+    0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL,
+    0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL,
+    0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL
+};
+
+static const uint32_t SP8[64] = {
+    0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL,
+    0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL,
+    0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL,
+    0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL,
+    0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL,
+    0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL,
+    0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL,
+    0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL,
+    0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL,
+    0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL,
+    0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL,
+    0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL,
+    0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL,
+    0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL,
+    0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL,
+    0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL
+};
+
+
+int tripledes_init(cipher_context_t *context, uint8_t blockSize, uint8_t keySize,
+                  uint8_t *key)
+{
+    uint8_t i;
+
+    //printf("%-40s: Entry\r\n", __FUNCTION__);
+    // 16 byte blocks only
+    if (blockSize != THREEDES_BLOCK_SIZE) {
+        printf("%-40s: blockSize != 3DES_BLOCK_SIZE...\r\n", __FUNCTION__);
+        return 0;
+    }
+
+    //key must be at least 24 Bytes long
+    if (keySize < 24) {
+        //fill up by concatenating key to as long as needed
+        for (i = 0; i < 24; i++) {
+            context->context[i] = key[(i % keySize)];
+        }
+    }
+    else {
+        for (i = 0; i < 24; i++) {
+            context->context[i] = key[i];
+        }
+    }
+
+    return 1;
+}
+
+int tripledes_setup_key(cipher_context_t *context, uint8_t *key,
+                                uint8_t keysize) //To change !!!
+{
+    return tripledes_init(context, tripledes_get_preferred_block_size(),
+                         keysize, key);
+}
+
+int tripledes_encrypt(cipher_context_t *context, uint8_t *plain, uint8_t *crypt)
+{
+    int res;
+    struct des3_key_s *key = malloc(sizeof(des3_key_s));
+    uint32_t work[2];
+
+    if (!key) {
+        printf("%-40s: [ERROR] Could NOT malloc space for the des3_key_s \
+                   struct.\r\n", __FUNCTION__);
+        return -1;
+    }
+
+    memset(key, 0, sizeof(des3_key_s));
+    res = des3_key_setup(context->context, key);
+
+    if (res < 0) {
+        printf("%-40s: [ERROR] des3_key_setup failed with Code %i\r\n",
+               __FUNCTION__, res);
+        free(key);
+        return -2;
+    }
+
+    work[0] = WPA_GET_BE32(plain);
+    work[1] = WPA_GET_BE32(plain + 4);
+    desfunc(work, key->ek[0]);
+    desfunc(work, key->ek[1]);
+    desfunc(work, key->ek[2]);
+    WPA_PUT_BE32(crypt, work[0]);
+    WPA_PUT_BE32(crypt + 4, work[1]);
+
+    free(key);
+    return 1;
+}
+
+
+int tripledes_decrypt(cipher_context_t *context, uint8_t *crypt, uint8_t *plain)
+{
+    int res;
+    struct des3_key_s *key = malloc(sizeof(des3_key_s));
+    uint32_t work[2];
+
+    if (!key) {
+        printf("%-40s: [ERROR] Could NOT malloc space for the des3_key_s \
+                        struct.\r\n", __FUNCTION__);
+        return -1;
+    }
+
+    memset(key, 0, sizeof(des3_key_s));
+    res = des3_key_setup(context->context, key);
+
+    if (res < 0) {
+        printf("%-40s: [ERROR] des3_key_setup failed with Code %i\r\n",
+               __FUNCTION__, res);
+        free(key);
+        return -2;
+    }
+
+    work[0] = WPA_GET_BE32(crypt);
+    work[1] = WPA_GET_BE32(crypt + 4);
+    desfunc(work, key->dk[0]);
+    desfunc(work, key->dk[1]);
+    desfunc(work, key->dk[2]);
+    WPA_PUT_BE32(plain, work[0]);
+    WPA_PUT_BE32(plain + 4, work[1]);
+
+    free(key);
+    return 1;
+}
+
+uint8_t tripledes_get_preferred_block_size()
+{
+    return THREEDES_BLOCK_SIZE;
+}
+
+static void cookey(const uint32_t *raw1, uint32_t *keyout)
+{
+    uint32_t *cook;
+    const uint32_t *raw0;
+    uint32_t dough[32];
+    int i;
+
+    cook = dough;
+
+    for (i = 0; i < 16; i++, raw1++) {
+        raw0 = raw1++;
+        *cook    = (*raw0 & 0x00fc0000L) << 6;
+        *cook   |= (*raw0 & 0x00000fc0L) << 10;
+        *cook   |= (*raw1 & 0x00fc0000L) >> 10;
+        *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
+        *cook    = (*raw0 & 0x0003f000L) << 12;
+        *cook   |= (*raw0 & 0x0000003fL) << 16;
+        *cook   |= (*raw1 & 0x0003f000L) >> 4;
+        *cook++ |= (*raw1 & 0x0000003fL);
+    }
+
+    memcpy(keyout, dough, sizeof(dough));
+}
+
+
+static void deskey(const uint8_t *key, int decrypt, uint32_t *keyout)
+{
+    uint32_t i, j, l, m, n, kn[32];
+    uint8_t pc1m[56], pcr[56];
+
+    for (j = 0; j < 56; j++) {
+        l = (uint32_t) pc1[j];
+        m = l & 7;
+        pc1m[j] = (uint8_t)
+                  ((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0);
+    }
+
+    for (i = 0; i < 16; i++) {
+        if (decrypt) {
+            m = (15 - i) << 1;
+        }
+        else {
+            m = i << 1;
+        }
+
+        n = m + 1;
+        kn[m] = kn[n] = 0L;
+
+        for (j = 0; j < 28; j++) {
+            l = j + (uint32_t) totrot[i];
+
+            if (l < 28) {
+                pcr[j] = pc1m[l];
+            }
+            else {
+                pcr[j] = pc1m[l - 28];
+            }
+        }
+
+        for (/* j = 28 */; j < 56; j++) {
+            l = j + (uint32_t) totrot[i];
+
+            if (l < 56) {
+                pcr[j] = pc1m[l];
+            }
+            else {
+                pcr[j] = pc1m[l - 28];
+            }
+        }
+
+        for (j = 0; j < 24; j++) {
+            if ((int) pcr[(int) pc2[j]] != 0) {
+                kn[m] |= bigbyte[j];
+            }
+
+            if ((int) pcr[(int) pc2[j + 24]] != 0) {
+                kn[n] |= bigbyte[j];
+            }
+        }
+    }
+
+    cookey(kn, keyout);
+}
+
+
+static void desfunc(uint32_t *block, const uint32_t *keys)
+{
+    uint32_t work, right, leftt;
+    int cur_round;
+
+    leftt = block[0];
+    right = block[1];
+
+    work = ((leftt >> 4)  ^ right) & 0x0f0f0f0fL;
+    right ^= work;
+    leftt ^= (work << 4);
+
+    work = ((leftt >> 16) ^ right) & 0x0000ffffL;
+    right ^= work;
+    leftt ^= (work << 16);
+
+    work = ((right >> 2)  ^ leftt) & 0x33333333L;
+    leftt ^= work;
+    right ^= (work << 2);
+
+    work = ((right >> 8)  ^ leftt) & 0x00ff00ffL;
+    leftt ^= work;
+    right ^= (work << 8);
+
+    right = ROLc(right, 1);
+    work = (leftt ^ right) & 0xaaaaaaaaL;
+
+    leftt ^= work;
+    right ^= work;
+    leftt = ROLc(leftt, 1);
+
+    for (cur_round = 0; cur_round < 8; cur_round++) {
+        work  = RORc(right, 4) ^ *keys++;
+        leftt ^= SP7[work        & 0x3fL]
+                 ^ SP5[(work >>  8) & 0x3fL]
+                 ^ SP3[(work >> 16) & 0x3fL]
+                 ^ SP1[(work >> 24) & 0x3fL];
+        work  = right ^ *keys++;
+        leftt ^= SP8[ work        & 0x3fL]
+                 ^  SP6[(work >>  8) & 0x3fL]
+                 ^  SP4[(work >> 16) & 0x3fL]
+                 ^  SP2[(work >> 24) & 0x3fL];
+
+        work = RORc(leftt, 4) ^ *keys++;
+        right ^= SP7[ work        & 0x3fL]
+                 ^  SP5[(work >>  8) & 0x3fL]
+                 ^  SP3[(work >> 16) & 0x3fL]
+                 ^  SP1[(work >> 24) & 0x3fL];
+        work  = leftt ^ *keys++;
+        right ^= SP8[ work        & 0x3fL]
+                 ^  SP6[(work >>  8) & 0x3fL]
+                 ^  SP4[(work >> 16) & 0x3fL]
+                 ^  SP2[(work >> 24) & 0x3fL];
+    }
+
+    right = RORc(right, 1);
+    work = (leftt ^ right) & 0xaaaaaaaaL;
+    leftt ^= work;
+    right ^= work;
+    leftt = RORc(leftt, 1);
+    work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
+    right ^= work;
+    leftt ^= (work << 8);
+    /* -- */
+    work = ((leftt >> 2) ^ right) & 0x33333333L;
+    right ^= work;
+    leftt ^= (work << 2);
+    work = ((right >> 16) ^ leftt) & 0x0000ffffL;
+    leftt ^= work;
+    right ^= (work << 16);
+    work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
+    leftt ^= work;
+    right ^= (work << 4);
+
+    block[0] = right;
+    block[1] = leftt;
+}
+
+static uint8_t des3_key_setup(const uint8_t *key, struct des3_key_s *dkey)
+{
+    deskey(key, 0, dkey->ek[0]);
+    deskey(key + 8, 1, dkey->ek[1]);
+    deskey(key + 16, 0, dkey->ek[2]);
+
+    deskey(key, 1, dkey->dk[2]);
+    deskey(key + 8, 0, dkey->dk[1]);
+    deskey(key + 16, 1, dkey->dk[0]);
+    return 1;
+}
+
diff --git a/sys/crypto/3des/Makefile b/sys/crypto/3des/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f44efaed998d6eae2cf985ee7b716a74fe90a65a
--- /dev/null
+++ b/sys/crypto/3des/Makefile
@@ -0,0 +1,9 @@
+SRC = 3des.c
+
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+MODULE = crypto_3des
+
+include $(RIOTBASE)/Makefile.base
+
diff --git a/sys/crypto/Makefile b/sys/crypto/Makefile
deleted file mode 100644
index 772db5ae6f44bb4a2cad2cbc14928eaf2740b476..0000000000000000000000000000000000000000
--- a/sys/crypto/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-INCLUDES = -I../include
-MODULE = crypto
-
-include $(RIOTBASE)/Makefile.base
-
-ifeq ($(strip $(BOARD)),msba2)
-$(warning sha256 produces wrong results on msba2 with our old toolchain)
-endif
-
diff --git a/sys/crypto/aes/Makefile b/sys/crypto/aes/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..867aaf1c28b199bfcd67e24a7d8ee1cb821ffe1c
--- /dev/null
+++ b/sys/crypto/aes/Makefile
@@ -0,0 +1,9 @@
+SRC = aes.c
+
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+MODULE = crypto_aes
+
+include $(RIOTBASE)/Makefile.base
+
diff --git a/sys/crypto/aes/aes.c b/sys/crypto/aes/aes.c
new file mode 100644
index 0000000000000000000000000000000000000000..c7aa8a2d3d44cf53b1f2f547d792b66bd2f0a8f8
--- /dev/null
+++ b/sys/crypto/aes/aes.c
@@ -0,0 +1,1467 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        aes.c
+ * @brief       implementation of the AES cipher-algorithm
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Fabrice Bellard
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ *
+ * @note        Integrated in QEMU by Fabrice Bellard from the OpenSSL project.
+ *              @version 3.0 (December 2000). Optimised ANSI C code for the
+ *              Rijndael cipher (now AES).
+ *
+ * @author      Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author      Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author      Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * @}
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "crypto/aes.h"
+#include "crypto/ciphers.h"
+
+/**
+ * Interface to the aes cipher
+ */
+block_cipher_interface_t aes_interface = {
+    "AES",
+    aes_init,
+    aes_encrypt,
+    aes_decrypt,
+    aes_setup_key,
+    aes_get_preferred_block_size
+};
+
+static const u32 Te0[256] = {
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+static const u32 Te4[256] = {
+    0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+    0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+    0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+    0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+    0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+    0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+    0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+    0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+    0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+    0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+    0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+    0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+    0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+    0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+    0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+    0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+    0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+    0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+    0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+    0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+    0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+    0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+    0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+    0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+    0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+    0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+    0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+    0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+    0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+    0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+    0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+    0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+    0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+    0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+    0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+    0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+    0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+    0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+    0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+    0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+    0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+    0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+    0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+    0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+    0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+    0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+    0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+    0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+    0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+    0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+    0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+    0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+    0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+    0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+    0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+    0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+    0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+    0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+    0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+    0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+    0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+    0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+    0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+    0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+static const u32 Td0[256] = {
+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const u32 Td1[256] = {
+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u32 Td4[256] = {
+    0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+    0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+    0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+    0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+    0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+    0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+    0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+    0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+    0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+    0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+    0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+    0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+    0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+    0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+    0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+    0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+    0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+    0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+    0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+    0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+    0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+    0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+    0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+    0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+    0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+    0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+    0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+    0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+    0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+    0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+    0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+    0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+    0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+    0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+    0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+    0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+    0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+    0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+    0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+    0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+    0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+    0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+    0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+    0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+    0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+    0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+    0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+    0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+    0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+    0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+    0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+    0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+    0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+    0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+    0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+    0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+    0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+    0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+    0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+    0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+    0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+    0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+    0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+    0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+
+/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+static const u32 rcon[] = {
+    0x01000000, 0x02000000, 0x04000000, 0x08000000,
+    0x10000000, 0x20000000, 0x40000000, 0x80000000,
+    0x1B000000, 0x36000000,
+};
+
+
+int aes_init(cipher_context_t *context, uint8_t blockSize, uint8_t keySize,
+             uint8_t *key)
+{
+    //printf("%-40s: Entry\r\n", __FUNCTION__);
+    // 16 byte blocks only
+    if (blockSize != AES_BLOCK_SIZE) {
+        printf("%-40s: blockSize != AES_BLOCK_SIZE...\r\n", __FUNCTION__);
+        return 0;
+    }
+
+    uint8_t i;
+
+    //key must be at least CIPHERS_KEYSIZE Bytes long
+    if (keySize < CIPHERS_KEYSIZE) {
+        //fill up by concatenating key to as long as needed
+        for (i = 0; i < CIPHERS_KEYSIZE; i++) {
+            context->context[i] = key[(i % keySize)];
+        }
+    }
+    else {
+        for (i = 0; i < CIPHERS_KEYSIZE; i++) {
+            context->context[i] = key[i];
+        }
+    }
+
+    return 1;
+}
+
+int aes_setup_key(cipher_context_t *context, uint8_t *key, uint8_t keysize)
+{
+    return aes_init(context, aes_get_preferred_block_size(), keysize, key);
+}
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+static int aes_set_encrypt_key(const unsigned char *userKey, const int bits,
+                               AES_KEY *key)
+{
+    u32 *rk;
+    int i = 0;
+    u32 temp;
+
+    if (!userKey || !key) {
+        return -1;
+    }
+
+    if (bits != 128 && bits != 192 && bits != 256) {
+        return -2;
+    }
+
+    rk = key->rd_key;
+
+    if (bits == 128) {
+        key->rounds = 10;
+    }
+    else if (bits == 192) {
+        key->rounds = 12;
+    }
+    else {
+        key->rounds = 14;
+    }
+
+    rk[0] = GETU32(userKey);
+    rk[1] = GETU32(userKey +  4);
+    rk[2] = GETU32(userKey +  8);
+    rk[3] = GETU32(userKey + 12);
+
+    if (bits == 128) {
+        while (1) {
+            temp  = rk[3];
+            rk[4] = rk[0] ^
+                    (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                    (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                    (Te4[(temp) & 0xff]       & 0x0000ff00) ^
+                    (Te4[(temp >> 24)       ] & 0x000000ff) ^
+                    rcon[i];
+            rk[5] = rk[1] ^ rk[4];
+            rk[6] = rk[2] ^ rk[5];
+            rk[7] = rk[3] ^ rk[6];
+
+            if (++i == 10) {
+                return 0;
+            }
+
+            rk += 4;
+        }
+    }
+
+    rk[4] = GETU32(userKey + 16);
+    rk[5] = GETU32(userKey + 20);
+
+    if (bits == 192) {
+        while (1) {
+            temp = rk[ 5];
+            rk[ 6] = rk[ 0] ^
+                     (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                     (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                     (Te4[(temp) & 0xff]       & 0x0000ff00) ^
+                     (Te4[(temp >> 24)       ] & 0x000000ff) ^
+                     rcon[i];
+            rk[ 7] = rk[ 1] ^ rk[ 6];
+            rk[ 8] = rk[ 2] ^ rk[ 7];
+            rk[ 9] = rk[ 3] ^ rk[ 8];
+
+            if (++i == 8) {
+                return 0;
+            }
+
+            rk[10] = rk[ 4] ^ rk[ 9];
+            rk[11] = rk[ 5] ^ rk[10];
+            rk += 6;
+        }
+    }
+
+    rk[6] = GETU32(userKey + 24);
+    rk[7] = GETU32(userKey + 28);
+
+    if (bits == 256) {
+        while (1) {
+            temp = rk[ 7];
+            rk[ 8] = rk[ 0] ^
+                     (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                     (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                     (Te4[(temp) & 0xff]       & 0x0000ff00) ^
+                     (Te4[(temp >> 24)       ] & 0x000000ff) ^
+                     rcon[i];
+            rk[ 9] = rk[ 1] ^ rk[ 8];
+            rk[10] = rk[ 2] ^ rk[ 9];
+            rk[11] = rk[ 3] ^ rk[10];
+
+            if (++i == 7) {
+                return 0;
+            }
+
+            temp = rk[11];
+            rk[12] = rk[ 4] ^
+                     (Te4[(temp >> 24)       ] & 0xff000000) ^
+                     (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+                     (Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
+                     (Te4[(temp) & 0xff]       & 0x000000ff);
+            rk[13] = rk[ 5] ^ rk[12];
+            rk[14] = rk[ 6] ^ rk[13];
+            rk[15] = rk[ 7] ^ rk[14];
+
+            rk += 8;
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+static int aes_set_decrypt_key(const unsigned char *userKey, const int bits,
+                               AES_KEY *key)
+{
+    u32 *rk;
+    int i, j;
+    u32 temp;
+
+    /* first, start with an encryption schedule */
+    int status;
+    status = aes_set_encrypt_key(userKey, bits, key);
+
+    if (status < 0) {
+        return status;
+    }
+
+    rk = key->rd_key;
+
+    /* invert the order of the round keys: */
+    for (i = 0, j = 4 * (key->rounds); i < j; i += 4, j -= 4) {
+        temp = rk[i    ];
+        rk[i    ] = rk[j    ];
+        rk[j    ] = temp;
+        temp = rk[i + 1];
+        rk[i + 1] = rk[j + 1];
+        rk[j + 1] = temp;
+        temp = rk[i + 2];
+        rk[i + 2] = rk[j + 2];
+        rk[j + 2] = temp;
+        temp = rk[i + 3];
+        rk[i + 3] = rk[j + 3];
+        rk[j + 3] = temp;
+    }
+
+    /*  apply the inverse MixColumn transform to all round keys but the first
+     *  and the last:
+     **/
+    for (i = 1; i < (key->rounds); i++) {
+        rk += 4;
+        rk[0] =
+            Td0[Te4[(rk[0] >> 24)       ] & 0xff] ^
+            Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+            Td2[Te4[(rk[0] >>  8) & 0xff] & 0xff] ^
+            Td3[Te4[(rk[0]) & 0xff]       & 0xff];
+        rk[1] =
+            Td0[Te4[(rk[1] >> 24)       ] & 0xff] ^
+            Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+            Td2[Te4[(rk[1] >>  8) & 0xff] & 0xff] ^
+            Td3[Te4[(rk[1]) & 0xff]       & 0xff];
+        rk[2] =
+            Td0[Te4[(rk[2] >> 24)       ] & 0xff] ^
+            Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+            Td2[Te4[(rk[2] >>  8) & 0xff] & 0xff] ^
+            Td3[Te4[(rk[2]) & 0xff]       & 0xff];
+        rk[3] =
+            Td0[Te4[(rk[3] >> 24)       ] & 0xff] ^
+            Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+            Td2[Te4[(rk[3] >>  8) & 0xff] & 0xff] ^
+            Td3[Te4[(rk[3]) & 0xff]       & 0xff];
+    }
+
+    return 0;
+}
+
+#ifndef AES_ASM
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+int aes_encrypt(cipher_context_t *context, uint8_t *plainBlock,
+                uint8_t *cipherBlock)
+{
+    //setup AES_KEY
+    int res;
+    AES_KEY aeskey;
+    const AES_KEY *key = &aeskey;
+    res = aes_set_encrypt_key((unsigned char *)context->context,
+                                   AES_KEY_SIZE * 8, &aeskey);
+    if (res < 0) {
+        return res;
+    }
+
+    const u32 *rk;
+    u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+    int r;
+#endif /* ?FULL_UNROLL */
+
+    //assert(plainBlock && cipherBlock && key);         is this really needed?
+    rk = key->rd_key;
+
+    /*
+     * map byte array block to cipher state
+     * and add initial round key:
+     */
+    s0 = GETU32(plainBlock) ^ rk[0];
+    s1 = GETU32(plainBlock +  4) ^ rk[1];
+    s2 = GETU32(plainBlock +  8) ^ rk[2];
+    s3 = GETU32(plainBlock + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+    /* round 1: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^
+         Te3[s3 & 0xff] ^ rk[ 4];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^
+         Te3[s0 & 0xff] ^ rk[ 5];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^
+         Te3[s1 & 0xff] ^ rk[ 6];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^
+         Te3[s2 & 0xff] ^ rk[ 7];
+    /* round 2: */
+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^
+         Te3[t3 & 0xff] ^ rk[ 8];
+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^
+         Te3[t0 & 0xff] ^ rk[ 9];
+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^
+         Te3[t1 & 0xff] ^ rk[10];
+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^
+         Te3[t2 & 0xff] ^ rk[11];
+    /* round 3: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^
+         Te3[s3 & 0xff] ^ rk[12];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^
+         Te3[s0 & 0xff] ^ rk[13];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^
+         Te3[s1 & 0xff] ^ rk[14];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^
+         Te3[s2 & 0xff] ^ rk[15];
+    /* round 4: */
+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^
+         Te3[t3 & 0xff] ^ rk[16];
+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^
+         Te3[t0 & 0xff] ^ rk[17];
+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^
+         Te3[t1 & 0xff] ^ rk[18];
+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^
+         Te3[t2 & 0xff] ^ rk[19];
+    /* round 5: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^
+         Te3[s3 & 0xff] ^ rk[20];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^
+         Te3[s0 & 0xff] ^ rk[21];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^
+         Te3[s1 & 0xff] ^ rk[22];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^
+         Te3[s2 & 0xff] ^ rk[23];
+    /* round 6: */
+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^
+         Te3[t3 & 0xff] ^ rk[24];
+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^
+         Te3[t0 & 0xff] ^ rk[25];
+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^
+         Te3[t1 & 0xff] ^ rk[26];
+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^
+         Te3[t2 & 0xff] ^ rk[27];
+    /* round 7: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^
+         Te3[s3 & 0xff] ^ rk[28];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^
+         Te3[s0 & 0xff] ^ rk[29];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^
+         Te3[s1 & 0xff] ^ rk[30];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^
+         Te3[s2 & 0xff] ^ rk[31];
+    /* round 8: */
+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^
+         Te3[t3 & 0xff] ^ rk[32];
+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^
+         Te3[t0 & 0xff] ^ rk[33];
+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^
+         Te3[t1 & 0xff] ^ rk[34];
+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^
+         Te3[t2 & 0xff] ^ rk[35];
+    /* round 9: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^
+         Te3[s3 & 0xff] ^ rk[36];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^
+         Te3[s0 & 0xff] ^ rk[37];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^
+         Te3[s1 & 0xff] ^ rk[38];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^
+         Te3[s2 & 0xff] ^ rk[39];
+
+    if (key->rounds > 10) {
+        /* round 10: */
+        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^
+             Te3[t3 & 0xff] ^ rk[40];
+        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^
+             Te3[t0 & 0xff] ^ rk[41];
+        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^
+             Te3[t1 & 0xff] ^ rk[42];
+        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^
+             Te3[t2 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^
+             Te3[s3 & 0xff] ^ rk[44];
+        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^
+             Te3[s0 & 0xff] ^ rk[45];
+        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^
+             Te3[s1 & 0xff] ^ rk[46];
+        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^
+             Te3[s2 & 0xff] ^ rk[47];
+
+        if (key->rounds > 12) {
+            /* round 12: */
+            s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) &
+                    0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+            s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) &
+                    0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+            s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) &
+                    0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+            s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) &
+                    0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) &
+                    0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+            t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) &
+                    0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+            t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) &
+                    0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+            t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) &
+                    0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+        }
+    }
+
+    rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+    r = key->rounds >> 1;
+
+    for (;;) {
+        t0 =
+            Te0[(s0 >> 24)       ] ^
+            Te1[(s1 >> 16) & 0xff] ^
+            Te2[(s2 >>  8) & 0xff] ^
+            Te3[(s3)       & 0xff] ^
+            rk[4];
+        t1 =
+            Te0[(s1 >> 24)       ] ^
+            Te1[(s2 >> 16) & 0xff] ^
+            Te2[(s3 >>  8) & 0xff] ^
+            Te3[(s0)       & 0xff] ^
+            rk[5];
+        t2 =
+            Te0[(s2 >> 24)       ] ^
+            Te1[(s3 >> 16) & 0xff] ^
+            Te2[(s0 >>  8) & 0xff] ^
+            Te3[(s1)       & 0xff] ^
+            rk[6];
+        t3 =
+            Te0[(s3 >> 24)       ] ^
+            Te1[(s0 >> 16) & 0xff] ^
+            Te2[(s1 >>  8) & 0xff] ^
+            Te3[(s2)       & 0xff] ^
+            rk[7];
+
+        rk += 8;
+
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Te0[(t0 >> 24)       ] ^
+            Te1[(t1 >> 16) & 0xff] ^
+            Te2[(t2 >>  8) & 0xff] ^
+            Te3[(t3)       & 0xff] ^
+            rk[0];
+        s1 =
+            Te0[(t1 >> 24)       ] ^
+            Te1[(t2 >> 16) & 0xff] ^
+            Te2[(t3 >>  8) & 0xff] ^
+            Te3[(t0)       & 0xff] ^
+            rk[1];
+        s2 =
+            Te0[(t2 >> 24)       ] ^
+            Te1[(t3 >> 16) & 0xff] ^
+            Te2[(t0 >>  8) & 0xff] ^
+            Te3[(t1)       & 0xff] ^
+            rk[2];
+        s3 =
+            Te0[(t3 >> 24)       ] ^
+            Te1[(t0 >> 16) & 0xff] ^
+            Te2[(t1 >>  8) & 0xff] ^
+            Te3[(t2)       & 0xff] ^
+            rk[3];
+    }
+
+#endif /* ?FULL_UNROLL */
+    /*
+         * apply last round and
+         * map cipher state to byte array block:
+         */
+    s0 =
+        (Te4[(t0 >> 24)       ] & 0xff000000) ^
+        (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+        (Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+        (Te4[(t3) & 0xff]       & 0x000000ff) ^
+        rk[0];
+    PUTU32(cipherBlock     , s0);
+    s1 =
+        (Te4[(t1 >> 24)       ] & 0xff000000) ^
+        (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+        (Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+        (Te4[(t0) & 0xff]       & 0x000000ff) ^
+        rk[1];
+    PUTU32(cipherBlock +  4, s1);
+    s2 =
+        (Te4[(t2 >> 24)       ] & 0xff000000) ^
+        (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+        (Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+        (Te4[(t1) & 0xff]       & 0x000000ff) ^
+        rk[2];
+    PUTU32(cipherBlock +  8, s2);
+    s3 =
+        (Te4[(t3 >> 24)       ] & 0xff000000) ^
+        (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+        (Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+        (Te4[(t2) & 0xff]       & 0x000000ff) ^
+        rk[3];
+    PUTU32(cipherBlock + 12, s3);
+    return 1;
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+int aes_decrypt(cipher_context_t *context, uint8_t *cipherBlock,
+                uint8_t *plainBlock)
+{
+    //setup AES_KEY
+    int res;
+    AES_KEY aeskey;
+    const AES_KEY *key = &aeskey;
+    res = aes_set_decrypt_key((unsigned char *)context->context,
+                              AES_KEY_SIZE * 8, &aeskey);
+
+    if (res < 0) {
+        return res;
+    }
+
+    const u32 *rk;
+    u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+    int r;
+#endif /* ?FULL_UNROLL */
+
+    // assert(cipherBlock && plainBlock && key);        // nedded? see above
+    rk = key->rd_key;
+
+    /*
+     * map byte array block to cipher state
+     * and add initial round key:
+     */
+    s0 = GETU32(cipherBlock) ^ rk[0];
+    s1 = GETU32(cipherBlock +  4) ^ rk[1];
+    s2 = GETU32(cipherBlock +  8) ^ rk[2];
+    s3 = GETU32(cipherBlock + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+    /* round 1: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^
+         Td3[s1 & 0xff] ^ rk[ 4];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^
+         Td3[s2 & 0xff] ^ rk[ 5];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^
+         Td3[s3 & 0xff] ^ rk[ 6];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^
+         Td3[s0 & 0xff] ^ rk[ 7];
+    /* round 2: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^
+         Td3[t1 & 0xff] ^ rk[ 8];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^
+         Td3[t2 & 0xff] ^ rk[ 9];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^
+         Td3[t3 & 0xff] ^ rk[10];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^
+         Td3[t0 & 0xff] ^ rk[11];
+    /* round 3: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^
+         Td3[s1 & 0xff] ^ rk[12];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^
+         Td3[s2 & 0xff] ^ rk[13];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^
+         Td3[s3 & 0xff] ^ rk[14];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^
+         Td3[s0 & 0xff] ^ rk[15];
+    /* round 4: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^
+         Td3[t1 & 0xff] ^ rk[16];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^
+         Td3[t2 & 0xff] ^ rk[17];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^
+         Td3[t3 & 0xff] ^ rk[18];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^
+         Td3[t0 & 0xff] ^ rk[19];
+    /* round 5: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^
+         Td3[s1 & 0xff] ^ rk[20];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^
+         Td3[s2 & 0xff] ^ rk[21];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^
+         Td3[s3 & 0xff] ^ rk[22];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^
+         Td3[s0 & 0xff] ^ rk[23];
+    /* round 6: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^
+         Td3[t1 & 0xff] ^ rk[24];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^
+         Td3[t2 & 0xff] ^ rk[25];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^
+         Td3[t3 & 0xff] ^ rk[26];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^
+         Td3[t0 & 0xff] ^ rk[27];
+    /* round 7: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^
+         Td3[s1 & 0xff] ^ rk[28];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^
+         Td3[s2 & 0xff] ^ rk[29];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^
+         Td3[s3 & 0xff] ^ rk[30];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^
+         Td3[s0 & 0xff] ^ rk[31];
+    /* round 8: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^
+         Td3[t1 & 0xff] ^ rk[32];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^
+         Td3[t2 & 0xff] ^ rk[33];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^
+         Td3[t3 & 0xff] ^ rk[34];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^
+         Td3[t0 & 0xff] ^ rk[35];
+    /* round 9: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^
+         Td3[s1 & 0xff] ^ rk[36];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^
+         Td3[s2 & 0xff] ^ rk[37];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^
+         Td3[s3 & 0xff] ^ rk[38];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^
+         Td3[s0 & 0xff] ^ rk[39];
+
+    if (key->rounds > 10) {
+        /* round 10: */
+        s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^
+             Td3[t1 & 0xff] ^ rk[40];
+        s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^
+             Td3[t2 & 0xff] ^ rk[41];
+        s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^
+             Td3[t3 & 0xff] ^ rk[42];
+        s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^
+             Td3[t0 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^
+             Td3[s1 & 0xff] ^ rk[44];
+        t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^
+             Td3[s2 & 0xff] ^ rk[45];
+        t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^
+             Td3[s3 & 0xff] ^ rk[46];
+        t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^
+             Td3[s0 & 0xff] ^ rk[47];
+
+        if (key->rounds > 12) {
+            /* round 12: */
+            s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff]
+                 ^ Td3[t1 & 0xff] ^ rk[48];
+            s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff]
+                 ^ Td3[t2 & 0xff] ^ rk[49];
+            s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff]
+                 ^ Td3[t3 & 0xff] ^ rk[50];
+            s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff]
+                 ^ Td3[t0 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff]
+                 ^ Td3[s1 & 0xff] ^ rk[52];
+            t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff]
+                 ^ Td3[s2 & 0xff] ^ rk[53];
+            t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff]
+                 ^ Td3[s3 & 0xff] ^ rk[54];
+            t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff]
+                 ^ Td3[s0 & 0xff] ^ rk[55];
+        }
+    }
+
+    rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+    r = key->rounds >> 1;
+
+    for (;;) {
+        t0 =
+            Td0[(s0 >> 24)       ] ^
+            Td1[(s3 >> 16) & 0xff] ^
+            Td2[(s2 >>  8) & 0xff] ^
+            Td3[(s1)       & 0xff] ^
+            rk[4];
+        t1 =
+            Td0[(s1 >> 24)       ] ^
+            Td1[(s0 >> 16) & 0xff] ^
+            Td2[(s3 >>  8) & 0xff] ^
+            Td3[(s2)       & 0xff] ^
+            rk[5];
+        t2 =
+            Td0[(s2 >> 24)       ] ^
+            Td1[(s1 >> 16) & 0xff] ^
+            Td2[(s0 >>  8) & 0xff] ^
+            Td3[(s3)       & 0xff] ^
+            rk[6];
+        t3 =
+            Td0[(s3 >> 24)       ] ^
+            Td1[(s2 >> 16) & 0xff] ^
+            Td2[(s1 >>  8) & 0xff] ^
+            Td3[(s0)       & 0xff] ^
+            rk[7];
+
+        rk += 8;
+
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Td0[(t0 >> 24)       ] ^
+            Td1[(t3 >> 16) & 0xff] ^
+            Td2[(t2 >>  8) & 0xff] ^
+            Td3[(t1)       & 0xff] ^
+            rk[0];
+        s1 =
+            Td0[(t1 >> 24)       ] ^
+            Td1[(t0 >> 16) & 0xff] ^
+            Td2[(t3 >>  8) & 0xff] ^
+            Td3[(t2) & 0xff] ^
+            rk[1];
+        s2 =
+            Td0[(t2 >> 24)       ] ^
+            Td1[(t1 >> 16) & 0xff] ^
+            Td2[(t0 >>  8) & 0xff] ^
+            Td3[(t3)       & 0xff] ^
+            rk[2];
+        s3 =
+            Td0[(t3 >> 24)       ] ^
+            Td1[(t2 >> 16) & 0xff] ^
+            Td2[(t1 >>  8) & 0xff] ^
+            Td3[(t0)       & 0xff] ^
+            rk[3];
+    }
+
+#endif /* ?FULL_UNROLL */
+    /*
+         * apply last round and
+         * map cipher state to byte array block:
+         */
+    s0 =
+        (Td4[(t0 >> 24)       ] & 0xff000000) ^
+        (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+        (Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+        (Td4[(t1) & 0xff]       & 0x000000ff) ^
+        rk[0];
+    PUTU32(plainBlock     , s0);
+    s1 =
+        (Td4[(t1 >> 24)       ] & 0xff000000) ^
+        (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+        (Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+        (Td4[(t2) & 0xff]       & 0x000000ff) ^
+        rk[1];
+    PUTU32(plainBlock +  4, s1);
+    s2 =
+        (Td4[(t2 >> 24)       ] & 0xff000000) ^
+        (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+        (Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+        (Td4[(t3) & 0xff]       & 0x000000ff) ^
+        rk[2];
+    PUTU32(plainBlock +  8, s2);
+    s3 =
+        (Td4[(t3 >> 24)       ] & 0xff000000) ^
+        (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+        (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+        (Td4[(t0) & 0xff]       & 0x000000ff) ^
+        rk[3];
+    PUTU32(plainBlock + 12, s3);
+    return 1;
+}
+
+uint8_t aes_get_preferred_block_size()
+{
+    return AES_BLOCK_SIZE;
+}
+
+#endif /* AES_ASM */
diff --git a/sys/crypto/doc.txt b/sys/crypto/doc.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9ee63f3d977cb318aa8256ac1302c685912a3a39
--- /dev/null
+++ b/sys/crypto/doc.txt
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin
+ *
+ * This file subject to the terms and conditions of the GNU Lesser General
+ * Public License. See the file LICENSE in the top level directory for more
+ * details.
+ */
+
+/**
+ * @defgroup    sys_crypto Crypto
+ * @brief       The crypto module is a lose collection of different crypto and hash algorithms
+ */
diff --git a/sys/crypto/rc5/Makefile b/sys/crypto/rc5/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3ae9c079bdb88e22eb5404d6cf9458767891873a
--- /dev/null
+++ b/sys/crypto/rc5/Makefile
@@ -0,0 +1,9 @@
+SRC = rc5.c
+
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+MODULE = crypto_rc5
+
+include $(RIOTBASE)/Makefile.base
+
diff --git a/sys/crypto/rc5/rc5.c b/sys/crypto/rc5/rc5.c
new file mode 100644
index 0000000000000000000000000000000000000000..aa7df7bbddee2537458f3964bcf3ebd182a28547
--- /dev/null
+++ b/sys/crypto/rc5/rc5.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        rc5.c
+ * @brief       implementation of the RC5 cipher-algorithm
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ * @author      Naveen Sastry
+ *
+ * @}
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "crypto/rc5.h"
+#include "crypto/ciphers.h"
+
+/**
+ * Define a fixed blocksize of 8 bytes
+ */
+#define BLOCK_SIZE      (8U)
+
+/**
+ * @brief Interface to the rc5 cipher
+ */
+block_cipher_interface_t rc5_interface = {
+    "RC5",
+    rc5_init,
+    rc5_encrypt,
+    rc5_decrypt,
+    rc5_setup_key,
+    rc5_get_preferred_block_size
+};
+
+
+int rc5_init(cipher_context_t *context, uint8_t blockSize, uint8_t keySize, uint8_t *key)
+{
+    (void)keySize;
+    // 8 byte blocks only
+    if (blockSize != BLOCK_SIZE) {
+        return 0;
+    }
+
+    return rc5_setup_key(context, key, 0);
+}
+
+
+int rc5_encrypt(cipher_context_t *context, uint8_t *block,
+                uint8_t *cipherBlock)
+{
+    register uint32_t l;
+    register uint32_t r;
+    register uint32_t *s = ((rc5_context_t *) context->context)->skey;
+    uint8_t i, tmp;
+    c2l(block, l);
+    block += 4;
+    c2l(block, r);
+    l += *s++;
+    r += *s++;
+
+    for (i = RC5_ROUNDS; i > 0; i--) {
+        l ^= r;
+        tmp = r;
+        tmp &= 0x1f;
+        rotl32(l, tmp);
+        l += *s++;
+        r ^= l;
+        tmp = l;
+        tmp &= 0x1f;
+        rotl32(r, tmp);
+        r += *s++;
+    }
+
+    l2c(l, cipherBlock);
+    cipherBlock += 4;
+    l2c(r, cipherBlock);
+    return 1;
+}
+
+int rc5_decrypt(cipher_context_t *context, uint8_t *cipherBlock,
+                uint8_t *plainBlock)
+{
+    register uint32_t l;
+    register uint32_t r;
+    register uint32_t *s = ((rc5_context_t *) context->context)->skey +
+                           (2 * RC5_ROUNDS) + 1;
+    uint8_t i, tmp;
+
+    c2l(cipherBlock, l);
+    cipherBlock += 4;
+    c2l(cipherBlock, r);
+
+    for (i = RC5_ROUNDS; i > 0; i--) {
+        r -= *s--;
+        tmp = l;
+        tmp &= 0x1f;
+        rotr32(r, tmp);
+        r ^= l;
+        l -= *s--;
+        tmp = r;
+        tmp &= 0x1f;
+        rotr32(l, tmp);
+        l ^= r;
+    }
+
+    r -= *s--;
+    l -= *s;
+    l2c(l, plainBlock);
+    plainBlock += 4;
+    l2c(r, plainBlock);
+    return 1;
+}
+
+int rc5_setup_key(cipher_context_t *context, uint8_t *key, uint8_t keysize)
+{
+    (void)keysize;
+    uint32_t *L, l, A, B, *S, k;
+    uint8_t ii, jj, m;
+    int8_t i;
+    uint8_t tmp[8];
+    S = ((rc5_context_t *)context->context)->skey;
+
+    //dumpBuffer ("RC5M:setupKey K", (uint8_t *)key, 8);
+    c2l(key, l);
+    L = (uint32_t *) tmp;
+    L[0] = l;
+    key += 4;
+    c2l(key, l);
+    L[1] = l;
+    S[0] = RC5_32_P;
+
+    //dumpBuffer ("RC5M:setupKey L", (uint8_t *)L, 8);
+    for (i = 1; i < 2 * RC5_ROUNDS + 2; i++) {
+        S[i] = (S[i - 1] + RC5_32_Q);
+        /* sum =(*S+RC5_32_Q)&RC5_32_MASK;
+         * S++;
+         * S = sum;
+         */
+    }
+
+    //dumpBuffer ("RC5M: setupKey S", (uint8_t *)S, 2 * (RC5_ROUNDS +1) * 4);
+    ii = jj = 0;
+    A = B = 0;
+    S = ((rc5_context_t *)context->context)->skey;
+
+    for (i = 3 * (2 * RC5_ROUNDS + 2) - 1; i >= 0; i--) {
+        k = (*S + A + B)&RC5_32_MASK;
+        rotl32((k), (3));
+        A = *S = k;
+        S++;
+        m = ((char)(A + B)) & 0x1f;
+        k = (*L + A + B)&RC5_32_MASK;
+        rotl32((k), (m));
+        B = *L = k;
+
+        if (++ii >= 2 * RC5_ROUNDS + 2) {
+            ii = 0;
+            S = ((rc5_context_t *)context->context)->skey;
+        }
+
+        jj ^= 4;
+        L = (uint32_t *)(&tmp[jj]);
+    }
+
+    return 1;
+}
+
+/**
+ * Returns the preferred block size that this cipher operates with. It is
+ * always safe to call this function before the init() call has been made.
+ *
+ * @return the preferred block size for this cipher. In the case where the
+ *         cipher operates with multiple block sizes, this will pick one
+ *         particular size (deterministically).
+ */
+uint8_t rc5_get_preferred_block_size()
+{
+    return BLOCK_SIZE;
+}
diff --git a/sys/crypto/sha256/Makefile b/sys/crypto/sha256/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3642252a8f5e4818d79639207bc8dc70b0007dd5
--- /dev/null
+++ b/sys/crypto/sha256/Makefile
@@ -0,0 +1,9 @@
+SRC = sha256.c
+
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+MODULE = crypto_sha256
+
+include $(RIOTBASE)/Makefile.base
+
diff --git a/sys/crypto/sha256.c b/sys/crypto/sha256/sha256.c
similarity index 89%
rename from sys/crypto/sha256.c
rename to sys/crypto/sha256/sha256.c
index 46b29b4b9cbb390c39c6754c49520ff10eacdd54..3bd2e5017e8d347062fd86dcd0c7c79437d4f988 100644
--- a/sys/crypto/sha256.c
+++ b/sys/crypto/sha256/sha256.c
@@ -27,9 +27,23 @@
  * $FreeBSD: src/lib/libmd/sha256c.c,v 1.2 2006/01/17 15:35:56 phk Exp $
  */
 
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        sha256.c
+ * @brief       SHA256 hash function implementation
+ *
+ * @author      Colin Percival
+ * @author      Christian Mehlis
+ * @author      Rene Kijewski
+ * 
+ * @}
+ */
+
 #include <string.h>
 
-#include "sha256.h"
+#include "crypto/sha256.h"
 
 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 /* Copy a vector of big-endian uint32_t into a vector of bytes */
@@ -94,7 +108,7 @@ static const uint32_t K[64] = {
  * SHA256 block compression function.  The 256-bit state is transformed via
  * the 512-bit input block to produce a new state.
  */
-static void SHA256_Transform(uint32_t *state, const unsigned char block[64])
+static void sha256_transform(uint32_t *state, const unsigned char block[64])
 {
     uint32_t W[64];
     uint32_t S[8];
@@ -136,7 +150,7 @@ static unsigned char PAD[64] = {
 };
 
 /* Add padding and terminating bit-count. */
-static void SHA256_Pad(SHA256_CTX *ctx)
+static void sha256_pad(sha256_context_t *ctx)
 {
     /*
      * Convert length to a vector of bytes -- we do this now rather
@@ -148,14 +162,14 @@ static void SHA256_Pad(SHA256_CTX *ctx)
     /* Add 1--64 bytes so that the resulting length is 56 mod 64 */
     uint32_t r = (ctx->count[1] >> 3) & 0x3f;
     uint32_t plen = (r < 56) ? (56 - r) : (120 - r);
-    SHA256_Update(ctx, PAD, (size_t) plen);
+    sha256_update(ctx, PAD, (size_t) plen);
 
     /* Add the terminating bit-count */
-    SHA256_Update(ctx, len, 8);
+    sha256_update(ctx, len, 8);
 }
 
 /* SHA-256 initialization.  Begins a SHA-256 operation. */
-void SHA256_Init(SHA256_CTX *ctx)
+void sha256_init(sha256_context_t *ctx)
 {
     /* Zero bits processed so far */
     ctx->count[0] = ctx->count[1] = 0;
@@ -172,7 +186,7 @@ void SHA256_Init(SHA256_CTX *ctx)
 }
 
 /* Add bytes into the hash */
-void SHA256_Update(SHA256_CTX *ctx, const void *in, size_t len)
+void sha256_update(sha256_context_t *ctx, const void *in, size_t len)
 {
     /* Number of bytes left in the buffer from previous updates */
     uint32_t r = (ctx->count[1] >> 3) & 0x3f;
@@ -198,13 +212,13 @@ void SHA256_Update(SHA256_CTX *ctx, const void *in, size_t len)
     const unsigned char *src = in;
 
     memcpy(&ctx->buf[r], src, 64 - r);
-    SHA256_Transform(ctx->state, ctx->buf);
+    sha256_transform(ctx->state, ctx->buf);
     src += 64 - r;
     len -= 64 - r;
 
     /* Perform complete blocks */
     while (len >= 64) {
-        SHA256_Transform(ctx->state, src);
+        sha256_transform(ctx->state, src);
         src += 64;
         len -= 64;
     }
@@ -217,10 +231,10 @@ void SHA256_Update(SHA256_CTX *ctx, const void *in, size_t len)
  * SHA-256 finalization.  Pads the input data, exports the hash value,
  * and clears the context state.
  */
-void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
+void sha256_final(unsigned char digest[32], sha256_context_t *ctx)
 {
     /* Add padding */
-    SHA256_Pad(ctx);
+    sha256_pad(ctx);
 
     /* Write the hash */
     be32enc_vect(digest, ctx->state, 32);
@@ -229,18 +243,18 @@ void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
     memset((void *) ctx, 0, sizeof(*ctx));
 }
 
-unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
+unsigned char *sha256(const unsigned char *d, size_t n, unsigned char *md)
 {
-    SHA256_CTX c;
+    sha256_context_t c;
     static unsigned char m[SHA256_DIGEST_LENGTH];
 
     if (md == NULL) {
         md = m;
     }
 
-    SHA256_Init(&c);
-    SHA256_Update(&c, d, n);
-    SHA256_Final(md, &c);
+    sha256_init(&c);
+    sha256_update(&c, d, n);
+    sha256_final(md, &c);
 
     return md;
 }
diff --git a/sys/crypto/skipjack/Makefile b/sys/crypto/skipjack/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f71e323691d3e5ddc30e7e70d3ab844041d34e3
--- /dev/null
+++ b/sys/crypto/skipjack/Makefile
@@ -0,0 +1,9 @@
+SRC = skipjack.c
+
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+MODULE = crypto_skipjack
+
+include $(RIOTBASE)/Makefile.base
+
diff --git a/sys/crypto/skipjack/skipjack.c b/sys/crypto/skipjack/skipjack.c
new file mode 100644
index 0000000000000000000000000000000000000000..5bb57f50eafad6d93f1f251a70996e68167ae98f
--- /dev/null
+++ b/sys/crypto/skipjack/skipjack.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        skipjack.c
+ * @brief       implementation of the SkipJack Cipher-Algorithm
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ * @author      Naveen Sastry
+ *
+ * @}
+ */
+
+/*
+ * From the NIST description of SkipJack.
+ */
+// our context: we just expand the key to 20 bytes.
+//
+// we have two options for the expansion:
+//   1. no expansion. advantage: 10byte context. disadvantage: mucks up
+//      the G box code with ifs / mods. Alternatively adds lots of code and
+//      muckiness.
+//   2. expand key to 128 bytes. Makes G boxes easy to write, and minimal
+//      code expansion. disadvantage: wasted memory
+//   3. expand key to 20 bytes.  G boxes still simple, the encode and decode
+//      functions are a little more complicated, but still more or less
+//      managable. this is what we've implemented.
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "crypto/ciphers.h"
+#include "crypto/skipjack.h"
+
+
+/**
+ * @brief Define a fixed block size of 8 bytes
+ */
+#define BLOCK_SIZE          (8U)
+
+/**
+ * @brief Interface to the skipjack cipher
+ */
+block_cipher_interface_t skipjack_interface = {
+    "SkipJack",
+    skipjack_init,
+    skipjack_encrypt,
+    skipjack_decrypt,
+    skipjack_setup_key,
+    skipjack_get_preferred_block_size
+};
+
+// F-BOX
+// It can live in either RAM (faster access) or program memory (save ram,
+// but slower access). The type CRYPTO_TABLE_TYPE, defined in crypto.h
+// defines where we drop the table and how we access it.  This is necessary
+// to compile for the PC target since it doesn't support tables in
+// program memory the same way.
+static const uint8_t SJ_F[] /*__attribute__((C))*/ = {
+    0xA3, 0xD7, 0x09, 0x83, 0xF8, 0x48, 0xF6, 0xF4, 0xB3, 0x21, 0x15, 0x78,
+    0x99, 0xB1, 0xAF, 0xF9, 0xE7, 0x2D, 0x4D, 0x8A, 0xCE, 0x4C, 0xCA, 0x2E,
+    0x52, 0x95, 0xD9, 0x1E, 0x4E, 0x38, 0x44, 0x28, 0x0A, 0xDF, 0x02, 0xA0,
+    0x17, 0xF1, 0x60, 0x68, 0x12, 0xB7, 0x7A, 0xC3, 0xE9, 0xFA, 0x3D, 0x53,
+    0x96, 0x84, 0x6B, 0xBA, 0xF2, 0x63, 0x9A, 0x19, 0x7C, 0xAE, 0xE5, 0xF5,
+    0xF7, 0x16, 0x6A, 0xA2, 0x39, 0xB6, 0x7B, 0x0F, 0xC1, 0x93, 0x81, 0x1B,
+    0xEE, 0xB4, 0x1A, 0xEA, 0xD0, 0x91, 0x2F, 0xB8, 0x55, 0xB9, 0xDA, 0x85,
+    0x3F, 0x41, 0xBF, 0xE0, 0x5A, 0x58, 0x80, 0x5F, 0x66, 0x0B, 0xD8, 0x90,
+    0x35, 0xD5, 0xC0, 0xA7, 0x33, 0x06, 0x65, 0x69, 0x45, 0x00, 0x94, 0x56,
+    0x6D, 0x98, 0x9B, 0x76, 0x97, 0xFC, 0xB2, 0xC2, 0xB0, 0xFE, 0xDB, 0x20,
+    0xE1, 0xEB, 0xD6, 0xE4, 0xDD, 0x47, 0x4A, 0x1D, 0x42, 0xED, 0x9E, 0x6E,
+    0x49, 0x3C, 0xCD, 0x43, 0x27, 0xD2, 0x07, 0xD4, 0xDE, 0xC7, 0x67, 0x18,
+    0x89, 0xCB, 0x30, 0x1F, 0x8D, 0xC6, 0x8F, 0xAA, 0xC8, 0x74, 0xDC, 0xC9,
+    0x5D, 0x5C, 0x31, 0xA4, 0x70, 0x88, 0x61, 0x2C, 0x9F, 0x0D, 0x2B, 0x87,
+    0x50, 0x82, 0x54, 0x64, 0x26, 0x7D, 0x03, 0x40, 0x34, 0x4B, 0x1C, 0x73,
+    0xD1, 0xC4, 0xFD, 0x3B, 0xCC, 0xFB, 0x7F, 0xAB, 0xE6, 0x3E, 0x5B, 0xA5,
+    0xAD, 0x04, 0x23, 0x9C, 0x14, 0x51, 0x22, 0xF0, 0x29, 0x79, 0x71, 0x7E,
+    0xFF, 0x8C, 0x0E, 0xE2, 0x0C, 0xEF, 0xBC, 0x72, 0x75, 0x6F, 0x37, 0xA1,
+    0xEC, 0xD3, 0x8E, 0x62, 0x8B, 0x86, 0x10, 0xE8, 0x08, 0x77, 0x11, 0xBE,
+    0x92, 0x4F, 0x24, 0xC5, 0x32, 0x36, 0x9D, 0xCF, 0xF3, 0xA6, 0xBB, 0xAC,
+    0x5E, 0x6C, 0xA9, 0x13, 0x57, 0x25, 0xB5, 0xE3, 0xBD, 0xA8, 0x3A, 0x01,
+    0x05, 0x59, 0x2A, 0x46
+};
+
+
+int skipjack_init(cipher_context_t *context, uint8_t blockSize, uint8_t keySize,
+                  uint8_t *key)
+{
+    // 8 byte blocks only
+    if (blockSize != BLOCK_SIZE) {
+        return 0;
+    }
+
+    return skipjack_setup_key(context, key, keySize);
+}
+
+/**
+ * @brief convert 2x uint8_t to uint16_t
+ *
+ * @param c     pointer to the 2x uint8_t input
+ * @param s     pointer to the resulting uint16_t
+ *
+ */
+static void c2sM(uint8_t *c, uint16_t *s)
+{
+    memcpy(s, c, sizeof(uint16_t));
+    return;
+}
+
+/**
+ * @brief convert one uint16_t to 2x uint8_t
+ *
+ * @param s pointer to the uint16_t input
+ * @param c pointer to the first resulting uint8_ts
+ */
+static void s2cM(uint16_t s, uint8_t *c)
+{
+    memcpy(c, &s, sizeof(uint16_t));
+    return;
+}
+
+
+int skipjack_encrypt(cipher_context_t *context, uint8_t *plainBlock,
+                     uint8_t *cipherBlock)
+{
+
+    // prologue 10 pushs = 20 cycles
+    /*register*/ uint8_t counter = 1;
+    /*register*/ uint8_t *skey  = ((skipjack_context_t *)context->context)->skey;
+    /*register*/ uint16_t w1, w2, w3, w4, tmp;
+    /*register*/ uint8_t bLeft, bRight;
+
+    //dumpBuffer("SkipJack.encrypt: plainBlock", plainBlock, 8);
+
+    c2sM(plainBlock, &w1);
+    plainBlock += 2;
+    c2sM(plainBlock, &w2);
+    plainBlock += 2;
+    c2sM(plainBlock, &w3);
+    plainBlock += 2;
+    c2sM(plainBlock, &w4);
+    plainBlock += 2;
+
+    /*
+     * code if we had expanded key to 128 bytes. this is what the code below
+     * does, but after every 5 operations, it resets the where we are
+     * in the key back to the beginning of the skey. so our loops end up
+     * looking a little funny.
+     *
+     *  while (counter < 9)
+     *   RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight );
+     *  while (counter < 17)
+     *   RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight );
+     *  while (counter < 25)
+     *   RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight );
+     *  while (counter < 33)
+     *   RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight );
+     */
+
+    while (counter < 6) { // 5x
+        RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey = ((skipjack_context_t *)context->context)->skey;
+
+    while (counter < 9) { // 3x
+        RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    while (counter < 11) { // 2x
+        RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey = ((skipjack_context_t *)context->context)->skey;
+
+    while (counter < 16) { // 5x
+        RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey = ((skipjack_context_t *)context->context)->skey;
+    // 1x
+    RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+
+    while (counter < 21) { // 4x
+        RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey = ((skipjack_context_t *)context->context)->skey;
+
+    while (counter < 25) { // 4x
+        RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    // 1x
+    RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    skey = ((skipjack_context_t *)context->context)->skey;
+
+    while (counter < 31) { // 5x
+        RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey = ((skipjack_context_t *)context->context)->skey;
+
+    while (counter < 33) { // 2x
+        RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    s2cM(w1, cipherBlock);
+    cipherBlock += 2;
+    s2cM(w2, cipherBlock);
+    cipherBlock += 2;
+    s2cM(w3, cipherBlock);
+    cipherBlock += 2;
+    s2cM(w4, cipherBlock);
+    cipherBlock += 2;
+
+    return 1;
+}
+
+
+int skipjack_decrypt(cipher_context_t *context, uint8_t *cipherBlock,
+                     uint8_t *plainBlock)
+{
+    /*register*/ uint8_t counter = 32;
+    /*register*/ uint8_t *skey  = ((skipjack_context_t *)context->context)->skey + 4;
+    /*register*/ uint16_t w1, w2, w3, w4, tmp;
+    /*register*/ uint8_t bLeft, bRight;
+
+    //dumpBuffer("SkipJack.decrypt: cipherBlock", cipherBlock, 8);
+
+    c2sM(cipherBlock, &w1);
+    cipherBlock += 2;
+    c2sM(cipherBlock, &w2);
+    cipherBlock += 2;
+    c2sM(cipherBlock, &w3);
+    cipherBlock += 2;
+    c2sM(cipherBlock, &w4);
+
+    /*
+      // code if we had expanded key to 128 bytes. this is what the code below
+      // does, but after every 5 operations, it resets the where we are
+      // in the key back to the beginning of the skey. so our loops end up
+      // looking a little funny.
+
+    while (counter > 24)
+      RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight );
+    while (counter > 16)
+      RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight );
+    while (counter > 8)
+      RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight );
+    while (counter > 0)
+      RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight );
+    */
+
+    while (counter > 30) { //2x
+        RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey  = ((skipjack_context_t *)context->context)->skey + 16;
+
+    while (counter > 25) { //5x
+        RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey  = ((skipjack_context_t *)context->context)->skey + 16;
+    //1x
+    RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+
+    while (counter > 20) { //4x
+        RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey  = ((skipjack_context_t *)context->context)->skey + 16;
+
+    while (counter > 16) { //4x
+        RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    //1x
+    RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    skey  = ((skipjack_context_t *)context->context)->skey + 16;
+
+    while (counter > 10) { //5x
+        RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey  = ((skipjack_context_t *)context->context)->skey + 16;
+
+    while (counter > 8) { // 2x
+        RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    while (counter > 5) { // 3x
+        RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    skey  = ((skipjack_context_t *)context->context)->skey + 16;
+
+    while (counter > 0) { // 5x
+        RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight);
+    }
+
+    s2cM(w1, plainBlock);
+    plainBlock += 2;
+    s2cM(w2, plainBlock);
+    plainBlock += 2;
+    s2cM(w3, plainBlock);
+    plainBlock += 2;
+    s2cM(w4, plainBlock);
+
+    return 1;
+}
+
+
+int skipjack_setup_key(cipher_context_t *context, uint8_t *key, uint8_t keysize)
+{
+    int i = 0;
+    uint8_t *skey = ((skipjack_context_t *)context->context)->skey;
+
+    // for keys which are smaller than 160 bits, concatenate until they reach
+    // 160 bits in size. Note that key expansion is just concatenation.
+    if (keysize < CIPHERS_KEYSIZE) {
+        //fill up by concatenating key to as long as needed
+        for (i = 0; i < CIPHERS_KEYSIZE; i++) {
+            skey[i] = key[(i % keysize)];
+        }
+    }
+    else {
+        for (i = 0; i < CIPHERS_KEYSIZE; i++) {
+            skey[i] = key[i];
+        }
+    }
+
+    return 1;
+}
+
+
+uint8_t skipjack_get_preferred_block_size()
+{
+    return BLOCK_SIZE;
+}
diff --git a/sys/crypto/twofish/Makefile b/sys/crypto/twofish/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..00cf5cccd8582535851e83cdd51e111eddd1ca38
--- /dev/null
+++ b/sys/crypto/twofish/Makefile
@@ -0,0 +1,9 @@
+SRC = twofish.c
+
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+MODULE = crypto_twofish
+
+include $(RIOTBASE)/Makefile.base
+
diff --git a/sys/crypto/twofish/twofish.c b/sys/crypto/twofish/twofish.c
new file mode 100644
index 0000000000000000000000000000000000000000..d5120b8cb4d9717004c30dac3b5ad0e9a7cba6df
--- /dev/null
+++ b/sys/crypto/twofish/twofish.c
@@ -0,0 +1,759 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        twofish.c
+ * @brief       implementation of the twofish cipher-algorithm
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ * @author      Matthew Skala <mskala@ansuz.sooke.bc.ca>
+ *
+ * @}
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "crypto/twofish.h"
+#include "crypto/ciphers.h"
+
+
+//prototype
+static int twofish_set_key(twofish_context_t *ctx, uint8_t *key, uint8_t keylen);
+
+// twofish interface
+block_cipher_interface_t twofish_interface = {
+    "TWOFISH",
+    twofish_init,
+    twofish_encrypt,
+    twofish_decrypt,
+    twofish_setup_key,
+    twofish_get_preferred_block_size
+};
+
+/* These two tables are the q0 and q1 permutations, exactly as described in
+ * the Twofish paper. */
+
+static const uint8_t q0[256] = {
+    0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
+    0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+    0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
+    0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+    0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
+    0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+    0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
+    0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+    0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
+    0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+    0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
+    0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+    0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
+    0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+    0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
+    0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+    0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
+    0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+    0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
+    0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+    0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
+    0x4A, 0x5E, 0xC1, 0xE0
+};
+
+static const uint8_t q1[256] = {
+    0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
+    0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+    0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
+    0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+    0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
+    0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+    0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
+    0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+    0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
+    0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+    0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
+    0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+    0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
+    0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+    0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
+    0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+    0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
+    0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+    0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
+    0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+    0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
+    0x55, 0x09, 0xBE, 0x91
+};
+
+/*
+ * These MDS tables are actually tables of MDS composed with q0 and q1,
+ * because it is only ever used that way and we can save some time by
+ * precomputing.  Of course the main saving comes from precomputing the
+ * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
+ * things up in these tables we reduce the matrix multiply to four lookups
+ * and three XORs.  Semi-formally, the definition of these tables is:
+ * mds[0][i] = MDS (q1[i] 0 0 0)^T  mds[1][i] = MDS (0 q0[i] 0 0)^T
+ * mds[2][i] = MDS (0 0 q1[i] 0)^T  mds[3][i] = MDS (0 0 0 q0[i])^T
+ * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
+ * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
+ * by Schneier et al, and I'm casually glossing over the byte/word
+ * conversion issues.
+ */
+
+static const uint32_t mds[4][256] = {
+    {
+        0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
+        0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
+        0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
+        0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+        0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
+        0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
+        0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
+        0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+        0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
+        0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
+        0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
+        0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+        0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
+        0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
+        0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
+        0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+        0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
+        0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
+        0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
+        0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+        0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
+        0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
+        0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
+        0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+        0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
+        0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
+        0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
+        0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+        0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
+        0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
+        0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
+        0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+        0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
+        0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
+        0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
+        0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+        0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
+        0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
+        0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
+        0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+        0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
+        0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
+        0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
+    },
+
+    {
+        0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
+        0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
+        0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
+        0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+        0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
+        0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
+        0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
+        0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+        0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
+        0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
+        0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
+        0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+        0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
+        0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
+        0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
+        0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+        0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
+        0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
+        0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
+        0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+        0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
+        0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
+        0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
+        0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+        0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
+        0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
+        0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
+        0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+        0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
+        0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
+        0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
+        0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+        0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
+        0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
+        0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
+        0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+        0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
+        0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
+        0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
+        0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+        0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
+        0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
+        0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
+    },
+
+    {
+        0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
+        0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
+        0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
+        0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+        0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
+        0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
+        0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
+        0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+        0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
+        0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
+        0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
+        0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+        0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
+        0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
+        0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
+        0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+        0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
+        0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
+        0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
+        0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+        0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
+        0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
+        0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
+        0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+        0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
+        0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
+        0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
+        0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+        0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
+        0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
+        0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
+        0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+        0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
+        0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
+        0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
+        0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+        0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
+        0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
+        0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
+        0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+        0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
+        0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
+        0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
+    },
+
+    {
+        0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
+        0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
+        0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
+        0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+        0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
+        0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
+        0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
+        0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+        0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
+        0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
+        0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
+        0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+        0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
+        0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
+        0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
+        0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+        0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
+        0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
+        0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
+        0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+        0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
+        0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
+        0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
+        0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+        0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
+        0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
+        0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
+        0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+        0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
+        0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
+        0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
+        0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+        0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
+        0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
+        0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
+        0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+        0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
+        0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
+        0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
+        0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+        0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
+        0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
+        0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
+    }
+};
+
+/* The exp_to_poly and poly_to_exp tables are used to perform efficient
+ * operations in GF(2^8) represented as GF(2)[x]/w(x) where
+ * w(x)=x^8+x^6+x^3+x^2+1.  We care about doing that because it's part of the
+ * definition of the RS matrix in the key schedule.  Elements of that field
+ * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
+ * which can be represented naturally by bytes (just substitute x=2). In that
+ * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
+ * multiplication is inefficient without hardware support.  To multiply
+ * faster, I make use of the fact x is a generator for the nonzero elements,
+ * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
+ * some n in 0..254.  Note that that caret is exponentiation in GF(2^8),
+ * *not* polynomial notation.  So if I want to compute pq where p and q are
+ * in GF(2^8), I can just say:
+ *    1. if p=0 or q=0 then pq=0
+ *    2. otherwise, find m and n such that p=x^m and q=x^n
+ *    3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
+ * The translations in steps 2 and 3 are looked up in the tables
+ * poly_to_exp (for step 2) and exp_to_poly (for step 3).  To see this
+ * in action, look at the CALC_S macro.  As additional wrinkles, note that
+ * one of my operands is always a constant, so the poly_to_exp lookup on it
+ * is done in advance; I included the original values in the comments so
+ * readers can have some chance of recognizing that this *is* the RS matrix
+ * from the Twofish paper.  I've only included the table entries I actually
+ * need; I never do a lookup on a variable input of zero and the biggest
+ * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
+ * never sum to more than 491.  I'm repeating part of the exp_to_poly table
+ * so that I don't have to do mod-255 reduction in the exponent arithmetic.
+ * Since I know my constant operands are never zero, I only have to worry
+ * about zero values in the variable operand, and I do it with a simple
+ * conditional branch.  I know conditionals are expensive, but I couldn't
+ * see a non-horrible way of avoiding them, and I did manage to group the
+ * statements so that each if covers four group multiplications.
+ */
+
+static const uint8_t poly_to_exp[255] = {
+    0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
+    0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
+    0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
+    0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
+    0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
+    0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
+    0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
+    0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
+    0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
+    0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
+    0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
+    0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
+    0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
+    0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
+    0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
+    0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
+    0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
+    0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
+    0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
+    0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
+    0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
+    0x85, 0xC8, 0xA1
+};
+
+static const uint8_t exp_to_poly[492] = {
+    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
+    0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
+    0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
+    0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
+    0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
+    0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
+    0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
+    0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
+    0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
+    0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
+    0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
+    0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
+    0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
+    0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
+    0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
+    0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
+    0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
+    0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
+    0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
+    0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
+    0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
+    0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
+    0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
+    0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
+    0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
+    0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
+    0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
+    0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
+    0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
+    0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
+    0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
+    0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
+    0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
+    0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
+    0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
+    0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
+    0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
+    0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
+    0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
+    0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
+    0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
+};
+
+
+/* The table constants are indices of
+ * S-box entries, preprocessed through q0 and q1. */
+static uint8_t calc_sb_tbl[512] = {
+    0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
+    0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
+    0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
+    0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
+    0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
+    0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
+    0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
+    0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
+    0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
+    0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
+    0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
+    0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
+    0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
+    0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
+    0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
+    0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
+    0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
+    0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
+    0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
+    0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
+    0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
+    0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
+    0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
+    0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
+    0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
+    0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
+    0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
+    0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
+    0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
+    0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
+    0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
+    0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
+    0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
+    0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
+    0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
+    0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
+    0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
+    0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
+    0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
+    0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
+    0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
+    0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
+    0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
+    0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
+    0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
+    0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
+    0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
+    0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
+    0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
+    0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
+    0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
+    0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
+    0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
+    0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
+    0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
+    0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
+    0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
+    0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
+    0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
+    0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
+    0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
+    0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
+    0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
+    0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
+};
+
+
+
+int twofish_init(cipher_context_t *context, uint8_t blockSize, uint8_t keySize,
+                 uint8_t *key)
+{
+    //printf("%-40s: Entry\r\n", __FUNCTION__);
+    // 16 byte blocks only
+    if (blockSize != TWOFISH_BLOCK_SIZE) {
+        printf("%-40s: blockSize != TWOFISH_BLOCK_SIZE...\r\n", __FUNCTION__);
+        return 0;
+    }
+
+    uint8_t i;
+
+    //key must be at least CIPHERS_KEYSIZE Bytes long
+    if (keySize < CIPHERS_KEYSIZE) {
+        //fill up by concatenating key to as long as needed
+        for (i = 0; i < CIPHERS_KEYSIZE; i++) {
+            context->context[i] = key[(i % keySize)];
+        }
+    }
+    else {
+        for (i = 0; i < CIPHERS_KEYSIZE; i++) {
+            context->context[i] = key[i];
+        }
+    }
+
+    return 1;
+}
+
+int twofish_setup_key(cipher_context_t *context, uint8_t *key, uint8_t keysize)
+{
+    return twofish_init(context, twofish_get_preferred_block_size(),
+                        keysize, key);
+}
+
+/**
+ * @brief Perform the key setup.
+ *        Note that this works only with 128- and 256-bit keys, despite the
+ *        API that looks like it might support other sizes.
+ *
+ * @param ctx       pointer to the context that the setup will be executed on
+ * @param key       pointer to the key
+ * @param keylen    length of the key in bytes
+ *
+ * @return  -1 if invalid key-length, 0 otherwise
+ */
+static int twofish_set_key(twofish_context_t *ctx, uint8_t *key, uint8_t keylen)
+{
+    int i, j, k;
+
+    /* Temporaries for CALC_K. */
+    uint32_t x, y;
+
+    /* The S vector used to key the S-boxes, split up into individual bytes.
+     * 128-bit keys use only sa through sh; 256-bit use all of them. */
+    uint8_t sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+    uint8_t si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
+
+    /* Temporary for CALC_S. */
+    uint8_t tmp;
+
+    /* Check key length. */
+    if (((keylen - 16) | 16) != 16) {
+        printf("%-40s: [ERROR] invalid key-length!\r\n", __FUNCTION__);
+        return -1;//GPG_ERR_INV_KEYLEN;
+    }
+
+
+    /* Compute the first two words of the S vector.  The magic numbers are
+     * the entries of the RS matrix, preprocessed through poly_to_exp. The
+     * numbers in the comments are the original (polynomial form) matrix
+     * entries. */
+    CALC_S(sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D);  /* 01 A4 02 A4 */
+    CALC_S(sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A);  /* A4 56 A1 55 */
+    CALC_S(sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1);  /* 55 82 FC 87 */
+    CALC_S(sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99);  /* 87 F3 C1 5A */
+    CALC_S(sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96);  /* 5A 1E 47 58 */
+    CALC_S(sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED);  /* 58 C6 AE DB */
+    CALC_S(sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0);  /* DB 68 3D 9E */
+    CALC_S(sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17);  /* 9E E5 19 03 */
+    CALC_S(se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D);  /* 01 A4 02 A4 */
+    CALC_S(se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A);  /* A4 56 A1 55 */
+    CALC_S(se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+    CALC_S(se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+    CALC_S(se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+    CALC_S(se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+    CALC_S(se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+    CALC_S(se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+    if (keylen == 32) { /* 256-bit key */
+        /* Calculate the remaining two words of the S vector */
+        CALC_S(si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D);  /* 01 A4 02 A4 */
+        CALC_S(si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A);  /* A4 56 A1 55 */
+        CALC_S(si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1);  /* 55 82 FC 87 */
+        CALC_S(si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99);  /* 87 F3 C1 5A */
+        CALC_S(si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96);  /* 5A 1E 47 58 */
+        CALC_S(si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED);  /* 58 C6 AE DB */
+        CALC_S(si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0);  /* DB 68 3D 9E */
+        CALC_S(si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17);  /* 9E E5 19 03 */
+        CALC_S(sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D);  /* 01 A4 02 A4 */
+        CALC_S(sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A);  /* A4 56 A1 55 */
+        CALC_S(sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1);  /* 55 82 FC 87 */
+        CALC_S(sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99);  /* 87 F3 C1 5A */
+        CALC_S(sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96);  /* 5A 1E 47 58 */
+        CALC_S(sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED);  /* 58 C6 AE DB */
+        CALC_S(sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0);  /* DB 68 3D 9E */
+        CALC_S(sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17);  /* 9E E5 19 03 */
+
+        /* Compute the S-boxes. */
+        for (i = j = 0, k = 1; i < 256; i++, j += 2, k += 2) {
+            CALC_SB256_2(i, calc_sb_tbl[j], calc_sb_tbl[k]);
+        }
+
+        /*
+         * Calculate whitening and round subkeys. The constants are
+         * indices of subkeys, preprocessed through q0 and q1.
+         *
+         **/
+        CALC_K256(w, 0, 0xA9, 0x75, 0x67, 0xF3);
+        CALC_K256(w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+        CALC_K256(w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+        CALC_K256(w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+        CALC_K256(k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+        CALC_K256(k, 2, 0x80, 0xE6, 0x78, 0x6B);
+        CALC_K256(k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+        CALC_K256(k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+        CALC_K256(k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+        CALC_K256(k, 10, 0x35, 0xD8, 0x98, 0xFD);
+        CALC_K256(k, 12, 0x18, 0x37, 0xF7, 0x71);
+        CALC_K256(k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+        CALC_K256(k, 16, 0x43, 0x30, 0x75, 0x0F);
+        CALC_K256(k, 18, 0x37, 0xF8, 0x26, 0x1B);
+        CALC_K256(k, 20, 0xFA, 0x87, 0x13, 0xFA);
+        CALC_K256(k, 22, 0x94, 0x06, 0x48, 0x3F);
+        CALC_K256(k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+        CALC_K256(k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+        CALC_K256(k, 28, 0x84, 0x8A, 0x54, 0x00);
+        CALC_K256(k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+    }
+    else {
+        /* Compute the S-boxes. */
+        for (i = j = 0, k = 1; i < 256; i++, j += 2, k += 2) {
+            CALC_SB_2(i, calc_sb_tbl[j], calc_sb_tbl[k]);
+        }
+
+        /*
+         * Calculate whitening and round subkeys. The constants are
+         * indices of subkeys, preprocessed through q0 and q1.
+         **/
+        CALC_K(w, 0, 0xA9, 0x75, 0x67, 0xF3);
+        CALC_K(w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+        CALC_K(w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+        CALC_K(w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+        CALC_K(k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+        CALC_K(k, 2, 0x80, 0xE6, 0x78, 0x6B);
+        CALC_K(k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+        CALC_K(k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+        CALC_K(k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+        CALC_K(k, 10, 0x35, 0xD8, 0x98, 0xFD);
+        CALC_K(k, 12, 0x18, 0x37, 0xF7, 0x71);
+        CALC_K(k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+        CALC_K(k, 16, 0x43, 0x30, 0x75, 0x0F);
+        CALC_K(k, 18, 0x37, 0xF8, 0x26, 0x1B);
+        CALC_K(k, 20, 0xFA, 0x87, 0x13, 0xFA);
+        CALC_K(k, 22, 0x94, 0x06, 0x48, 0x3F);
+        CALC_K(k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+        CALC_K(k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+        CALC_K(k, 28, 0x84, 0x8A, 0x54, 0x00);
+        CALC_K(k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+    }
+
+    return 0;
+}
+
+
+/* Encrypt one block.  in and out may be the same. */
+int twofish_encrypt(cipher_context_t *context, uint8_t *in, uint8_t *out)
+{
+    int res;
+    //setup the twofish-specific context
+    twofish_context_t *ctx = malloc(sizeof(twofish_context_t));
+
+    if (!ctx) {
+        printf("%-40s: [ERROR] Could NOT malloc space for the twofish_context_t \
+                struct.\r\n", __FUNCTION__);
+        return -1;
+    }
+
+    res = twofish_set_key(ctx, context->context, TWOFISH_KEY_SIZE);
+
+    if (res < 0) {
+        printf("%-40s: [ERROR] twofish_setKey failed with Code %i\r\n",
+               __FUNCTION__, res);
+        free(ctx);
+        return -2;
+    }
+
+    /* The four 32-bit chunks of the text. */
+    uint32_t a, b, c, d;
+
+    /* Temporaries used by the round function. */
+    uint32_t x, y;
+
+    /* Input whitening and packing. */
+    INPACK(0, a, 0);
+    INPACK(1, b, 1);
+    INPACK(2, c, 2);
+    INPACK(3, d, 3);
+
+    /* Encryption Feistel cycles. */
+    ENCCYCLE(0);
+    ENCCYCLE(1);
+    ENCCYCLE(2);
+    ENCCYCLE(3);
+    ENCCYCLE(4);
+    ENCCYCLE(5);
+    ENCCYCLE(6);
+    ENCCYCLE(7);
+
+    /* Output whitening and unpacking. */
+    OUTUNPACK(0, c, 4);
+    OUTUNPACK(1, d, 5);
+    OUTUNPACK(2, a, 6);
+    OUTUNPACK(3, b, 7);
+
+    free(ctx);
+    return 1;
+}
+
+/* Decrypt one block.  in and out may be the same. */
+int twofish_decrypt(cipher_context_t *context, uint8_t *in, uint8_t *out)
+{
+    int res;
+    twofish_context_t *ctx = malloc(sizeof(twofish_context_t));
+
+    if (!ctx) {
+        printf("%-40s: [ERROR] Could NOT malloc space for the twofish_context_t \
+                struct.\r\n", __FUNCTION__);
+        return -1;
+    }
+
+    res = twofish_set_key(ctx, context->context, TWOFISH_KEY_SIZE);
+
+    if (res < 0) {
+        printf("%-40s: [ERROR] twofish_setKey failed with Code %i\r\n",
+               __FUNCTION__, res);
+        free(ctx);
+        return -2;
+    }
+
+    /* The four 32-bit chunks of the text. */
+    uint32_t a, b, c, d;
+
+    /* Temporaries used by the round function. */
+    uint32_t x, y;
+
+    /* Input whitening and packing. */
+    INPACK(0, c, 4);
+    INPACK(1, d, 5);
+    INPACK(2, a, 6);
+    INPACK(3, b, 7);
+
+    /* Encryption Feistel cycles. */
+    DECCYCLE(7);
+    DECCYCLE(6);
+    DECCYCLE(5);
+    DECCYCLE(4);
+    DECCYCLE(3);
+    DECCYCLE(2);
+    DECCYCLE(1);
+    DECCYCLE(0);
+
+    /* Output whitening and unpacking. */
+    OUTUNPACK(0, a, 0);
+    OUTUNPACK(1, b, 1);
+    OUTUNPACK(2, c, 2);
+    OUTUNPACK(3, d, 3);
+
+    free(ctx);
+    return 1;
+}
+
+uint8_t twofish_get_preferred_block_size()
+{
+    return TWOFISH_BLOCK_SIZE;
+}
diff --git a/sys/include/crypto/3des.h b/sys/include/crypto/3des.h
new file mode 100644
index 0000000000000000000000000000000000000000..658110acb44a56ec8ec4a204d4efad40be522cf5
--- /dev/null
+++ b/sys/include/crypto/3des.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        3des.h
+ * @brief       Headers for the implementation of the 3DES cipher-algorithm
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics,
+ * @author      Nicolai Schmittberger (nicolai.schmittberger@fu-berlin.de)
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "assert.h"
+#include "crypto/ciphers.h"
+
+#ifndef THREEDES_H_
+#define THREEDES_H_
+
+#define THREEDES_BLOCK_SIZE    8
+#define THREEDES_KEY_SIZE      PARSEC_KEYSIZE
+
+#define ROLc(x, y) \
+        ((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \
+         (((unsigned long) (x) & 0xFFFFFFFFUL) >>               \
+           (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
+
+#define RORc(x, y) \
+        (((((unsigned long) (x) & 0xFFFFFFFFUL) >> \
+            (unsigned long) ((y) & 31)) | \
+           ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \
+                                  0xFFFFFFFFUL)
+
+//source: http://hostap.epitest.fi/wpa_supplicant/devel/common_8h.html
+#define WPA_GET_BE32(a) \
+                        ((((uint32_t) (a)[0]) << 24) | \
+                         (((uint32_t) (a)[1]) << 16) | \
+                         (((uint32_t) (a)[2]) << 8 ) |  ((uint32_t) (a)[3]))
+
+//source: http://hostap.epitest.fi/wpa_supplicant/devel/common_8h.html
+#define WPA_PUT_BE32(a, val)                                           \
+       do {                                                            \
+             (a)[0] = (uint8_t) ((((uint32_t) (val)) >> 24) & 0xff);   \
+             (a)[1] = (uint8_t) ((((uint32_t) (val)) >> 16) & 0xff);   \
+             (a)[2] = (uint8_t) ((((uint32_t) (val)) >> 8) & 0xff);    \
+             (a)[3] = (uint8_t) (((uint32_t)  (val)) & 0xff);          \
+        } while (0)
+
+
+
+
+static const uint32_t bytebit[8] = {0200, 0100, 040, 020, 010, 04, 02, 01};
+
+static const uint32_t bigbyte[24] = {
+    0x800000UL,  0x400000UL,  0x200000UL,  0x100000UL,
+    0x80000UL,   0x40000UL,   0x20000UL,   0x10000UL,
+    0x8000UL,    0x4000UL,    0x2000UL,    0x1000UL,
+    0x800UL,     0x400UL,     0x200UL,     0x100UL,
+    0x80UL,      0x40UL,      0x20UL,      0x10UL,
+    0x8UL,       0x4UL,       0x2UL,       0x1L
+};
+/**
+ * @brief   initializes the 3DES Cipher-algorithm with the passed
+ *          parameters
+ *
+ * @param   context     the cipher_context_t-struct to save the
+ *                      initialization of the cipher in
+ * @param   blockSize   the used blocksize - this must match
+ *                      the cipher-blocksize
+ * @param   keySize     the size of the key
+ * @param   key         a pointer to the key
+ *
+ * @return  0 if blocksize doesn't match else 1
+ */
+int tripledes_init(cipher_context_t *context, uint8_t blockSize, uint8_t keySize,
+                   uint8_t *key);
+
+/**
+ * @brief   updates the used key for this context after initialization has
+ *          already been done
+ *
+ * @param   context   the cipher_context_t-struct to save the updated key in
+ * @param   key       a pointer to the key
+ * @param   keysize   the length of the key
+ *
+ * @return  0 if initialized blocksize is wrong, 1 else
+ */
+int tripledes_setup_key(cipher_context_t *context, uint8_t *key, uint8_t keysize);
+
+/**
+ * @brief   encrypts one plain-block and saves the result in crypt.
+ *          encrypts one blocksize long block of plaintext pointed to by
+ *          plain to one blocksize long block of ciphertext which will be
+ *          written to the the memory-area pointed to by crypt
+ *
+ * @param   context   the cipher_context_t-struct to use for this
+ *                    encryption
+ * @param   plain     a pointer to the plaintext-block (of size
+ *                    blocksize)
+ * @param   crypt     a pointer to the place where the ciphertext will
+ *                    be stored
+ *
+ * @return  -1 if no space for the key could be malloced
+ *                      -2 if the key could not be setup correctly
+ *                       1 if encryption was successful
+ */
+int tripledes_encrypt(cipher_context_t *context, uint8_t *plain, uint8_t *crypt);
+
+/**
+ * @brief  decrypts one cipher-block and saves the plain-block in plain.
+ *         decrypts one blocksize long block of ciphertext pointed to by
+ *         crypt to one blocksize long block of plaintext and stores the
+ *         plaintext in the memory-area pointed to by plain
+ *
+ * @param   context   the cipher_context_t-struct to use for this
+ *                    decryption
+ * @param   crypt     a pointer to the ciphertext-block (of size blocksize)
+ *                    to be decrypted
+ * @param   plain     a pointer to the place where the decrypted plaintext
+ *                    will be stored
+ *
+ * @return  -1 if no space for the key could be malloced
+ *          -2 if the key could not be setup correctly
+ *           1 if decryption was successful
+ */
+int tripledes_decrypt(cipher_context_t *context, uint8_t *crypt, uint8_t *plain);
+
+/**
+ * @brief returns the blocksize of the 3DES algorithm
+ */
+uint8_t tripledes_get_preferred_block_size(void);
+
+/**
+ * Interface to access the functions
+ *
+ */
+extern block_cipher_interface_t tripledes_interface;
+
+/** @} */
+#endif /* THREEDES_H_ */
diff --git a/sys/include/crypto/aes.h b/sys/include/crypto/aes.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb58112a6bb751a7b9452833689b3111a450c334
--- /dev/null
+++ b/sys/include/crypto/aes.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ * 
+ * @file        aes.h
+ * @brief       Headers for the implementation of the AES cipher-algorithm
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Fabrice Bellard
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ */
+
+#ifndef AES_H
+#define AES_H
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "crypto/ciphers.h"
+
+
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+
+
+/* This controls loop-unrolling in aes_core.c */
+#undef FULL_UNROLL
+# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
+                             ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); \
+                              (ct)[1] = (u8)((st) >> 16); \
+                              (ct)[2] = (u8)((st) >>  8); \
+                              (ct)[3] = (u8)(st); }
+
+#define AES_MAXNR         14
+#define AES_BLOCK_SIZE    16
+#define AES_KEY_SIZE      16
+
+
+struct aes_key_st {
+    uint32_t rd_key[4 * (AES_MAXNR + 1)];
+    int rounds;
+};
+
+typedef struct aes_key_st AES_KEY;
+
+/**
+ * @brief the cipher_context_t-struct adapted for AES
+ */
+typedef struct {
+    uint32_t context[(4 * (AES_MAXNR + 1)) + 1];
+} aes_context_t;
+
+/**
+ * @brief   initializes the AES Cipher-algorithm with the passed parameters
+ *
+ * @param       context   the cipher_context_t-struct to save the initialization
+ *                        of the cipher in
+ * @param       blockSize the used blocksize - this must match the
+ *                        cipher-blocksize
+ * @param       keySize   the size of the key
+ * @param       key       a pointer to the key
+ *
+ * @return  0 if blocksize doesn't match else 1
+ */
+int aes_init(cipher_context_t *context, uint8_t blockSize, uint8_t keySize,
+             uint8_t *key);
+
+/**
+ * @brief   updates the used key for this context after initialization has
+ *          already been done
+ *
+ * @param       context   the cipher_context_t-struct to save the updated key
+ *                        in
+ * @param       key       a pointer to the key
+ * @param       keysize   the length of the key
+ *
+ * @return  0 if initialized blocksize is wrong, 1 else
+ */
+int aes_setup_key(cipher_context_t *context, uint8_t *key, uint8_t keysize);
+
+/**
+ * @brief   encrypts one plainBlock-block and saves the result in cipherblock.
+ *          encrypts one blocksize long block of plaintext pointed to by
+ *          plainBlock to one blocksize long block of ciphertext which will be
+ *          written to the the memory-area pointed to by cipherBlock
+ *
+ * @param       context      the cipher_context_t-struct to use for this
+ *                           encryption
+ * @param       plainBlock   a pointer to the plaintext-block (of size
+ *                           blocksize)
+ * @param       cipherBlock  a pointer to the place where the ciphertext will
+ *                           be stored
+ *
+ * @return  1 or result of aes_set_encrypt_key if it failed
+ */
+int aes_encrypt(cipher_context_t *context, uint8_t *plain_block,
+                uint8_t *cipher_block);
+
+/**
+ * @brief   decrypts one cipher-block and saves the plain-block in plainBlock.
+ *          decrypts one blocksize long block of ciphertext pointed to by
+ *          cipherBlock to one blocksize long block of plaintext and stores
+ *          the plaintext in the memory-area pointed to by plainBlock
+ *
+ * @param       context      the cipher_context_t-struct to use for this
+ *                           decryption
+ * @param       cipherBlock  a pointer to the ciphertext-block (of size
+ *                           blocksize) to be decrypted
+ * @param       plainBlock   a pointer to the place where the decrypted
+ *                           plaintext will be stored
+ *
+ * @return  1 or result of ::aes_set_decrypt_key if it failed
+ */
+int aes_decrypt(cipher_context_t *context, uint8_t *cipher_block,
+                uint8_t *plain_block);
+
+/**
+ * @brief returns the blocksize of the AES algorithm
+ */
+uint8_t aes_get_preferred_block_size(void);
+
+/**
+  * Interface to access the functions
+  *
+  */
+extern block_cipher_interface_t aes_inerface;
+
+/** @} */
+#endif /* AES_H */
diff --git a/sys/include/crypto/cbcmode.h b/sys/include/crypto/cbcmode.h
new file mode 100644
index 0000000000000000000000000000000000000000..088f1b6036e8d9452b9ef3ceede1f9cb6cf05d91
--- /dev/null
+++ b/sys/include/crypto/cbcmode.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ * 
+ * @file        cbcmode.h
+ * @brief       Headers of the implementation of the CBC Mode of Operation
+ *
+ * Implementation of the CBC Mode of Operation with Ciphertext-Stealing for encryption.
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics.
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifndef CBCMODE_H_
+#define CBCMODE_H_
+
+#include "crypto/ciphers.h"
+
+#define MIN(a, b) ( ((a) < (b)) ? (a) : (b))
+
+#define DBG_CRYPTO      1
+
+
+enum {
+    // we allocate some static buffers on the stack; they have to be less
+    // than this size
+    CBCMODE_MAX_BLOCK_SIZE      = 8,
+    CBCMODE_MAX_BLOCK_SIZE_AES  = 16
+};
+
+/*// We run a simple state machine in the incremental decrypt:
+  //
+  //    +--> ONE_BLOCK
+  //    |
+  // ---|
+  //    |
+  //    +--> GENERAL --+---> TWO_LEFT_A ----> TWO_LEFT_B
+  //            ^      |
+  //            |      |
+  //            +------+
+   */
+
+enum {
+    ONE_BLOCK,
+    GENERAL,
+    TWO_LEFT_A,
+    TWO_LEFT_B
+};
+
+#define FAIL 0
+#define SUCCESS 1
+
+
+/**
+ * @struct CBCModeContext CBCMode.c "CBCMode.c"
+ * @brief   The context for processing the en-/decryption in the CBC-Mode with
+ *          CTS
+ *
+ * @param   spill1  test1
+ */
+typedef struct CBCModeContext {
+        // Spill-Block 1 for temporary usage
+    uint8_t spill1 [CBCMODE_MAX_BLOCK_SIZE ];
+    // Spill-Block 2 for temporary usage
+    uint8_t spill2 [CBCMODE_MAX_BLOCK_SIZE ];
+    // the blocksize currently used
+    uint8_t bsize;
+    // how many more bytes of ciphertext do we need to recv
+    uint16_t remaining;
+    // how many bytes of plaintext we've deciphered.
+    uint16_t completed;
+    // TRUE iff spill1 is the accumulator and spill2 holds prev cipher text.
+    // false o.w.
+    uint8_t accum;
+    // into the accumulator
+    uint8_t offset;
+    // state enum
+    uint8_t state;
+} /*__attribute__ ((packed)) */ CBCModeContext;
+
+
+/*
+ * @brief   Initialize the Mode. It uses the underlying BlockCipher's
+ *          preferred block cipher mode, and passes the key and keySize
+ *          parameters to the underlying BlockCipher.
+ *
+ * @param   context   structure to hold the opaque data from this
+ *                    initialization call. It should be passed to future
+ *                    invocations of this module which use this particular key.
+ *                    It also contains the opaque context for the underlying
+ *                    BlockCipher as well.
+ * @param   keySize   key size in bytes
+ * @param   key       pointer to the key
+ *
+ * @return  Whether initialization was successful. The command may be
+ *          unsuccessful if the key size is not valid for the given cipher
+ *          implementation. It can also fail if the preferred block size of
+ *          the cipher does not agree with the preferred size of the mode.
+ */
+int block_cipher_mode_init(CipherModeContext *context, uint8_t key_size,
+                           uint8_t *key);
+
+/**
+ * @brief   same as BlockCipherMode_init but with the possibility to specify
+ *          the index of the cipher in the archive
+ *
+ * @param   context       structure to hold the opaque data from this
+ *                        initialization call. It should be passed to future
+ *                        invocations of this module which use this particular
+ *                        key. It also contains the opaque context for the
+ *                        underlying BlockCipher as well.
+ * @param   keySize       key size in bytes.
+ * @param   key           pointer to the key.
+ * @param   cipher_index  the index of the cipher-algorithm to init in the
+ *                        (cipher-)archive
+ *
+ * @return  Whether initialization was successful. The command may be
+ *          unsuccessful if the key size is not valid for the given cipher
+ *          implementation. It can also fail if the preferred block size of
+ *          the cipher does not agree with the preferred size of the mode.
+ */
+int block_cipher_mode_init0(CipherModeContext *context, uint8_t key_size,
+                            uint8_t *key, uint8_t cipher_index);
+
+/**
+ * @brief   prints the debug-messages passed by ::dumpBuffer
+ *
+ * @param   mode      the mode of the debug-message
+ * @param   format    pointer to the message
+ */
+void dbg(uint8_t mode, const char *format, ...);
+
+/**
+ * @brief   dumps the passed buffer to the console
+ *
+ * @param   bufName   pointer to the name of the buffer
+ * @param   buf       pointer to the buffer itself
+ * @param   size      the size of the buffer in bytes
+ */
+void dump_buffer(char *bufName, uint8_t *buf, uint8_t size);
+
+/**
+ * @brief   Encrypts num_bytes of plaintext blocks (each of size blockSize)
+ *          using the key from the init phase. The IV is a pointer to the
+ *          initialization vector (of size equal to the blockSize) which is
+ *          used to initialize the encryption.
+ *          In place encryption should work provided that the plain and and
+ *          cipher buffer are the same. (they may either be the same or
+ *          non-overlapping. partial overlaps are not supported).
+ *
+ * @param   plain_blocks  a plaintext block numBlocks, where each block is of
+ *                        blockSize bytes
+ * @param   cipher_blocks an array of numBlocks * blockSize bytes to hold the
+ *                        resulting cyphertext
+ * @param   num_bytes     number of data blocks to encrypt
+ * @param   IV            an array of the initialization vector. It should be
+ *                        of block size bytes
+ *
+ * @return  Whether the encryption was successful. Possible failure reasons
+ *          include not calling init().
+ */
+int block_cipher_mode_encrypt(CipherModeContext *context, uint8_t *plain_blocks,
+                              uint8_t *cipher_blocks, uint16_t num_bytes,
+                              uint8_t *IV);
+
+/**
+ * @brief   Decrypts num_bytes of ciphertext blocks (each of size blockSize)
+ *          using the key from the init phase. The IV is a pointer to the
+ *          initialization vector (of size equal to the blockSize) which is
+ *          used to initialize the decryption.
+ *          In place decryption should work provided that the plain and and
+ *          cipher buffer are the same. (they may either be the same or
+ *          non-overlapping. partial overlaps are not supported).
+ *
+ * @param   cipher_blocks  an array of num_bytes * blockSize bytes that holds
+ *                         the cipher text
+ * @param   plain_blocks   an array of num_bytes * blockSize bytes to hold the
+ *                         resulting plaintext.
+ * @param   num_bytes      number of data blocks to encrypt
+ * @param   IV             an array of the initialization vector. It should be
+ *                         of block size bytes
+ *
+ * @return  Whether the decryption was successful. Possible failure reasons
+ *          include not calling init().
+ */
+int block_cipher_mode_decrypt(CipherModeContext *context,
+                              uint8_t *cipher_blocks,
+                              uint8_t *plain_blocks,
+                              uint16_t num_bytes,
+                              uint8_t *IV);
+
+/** @} */
+#endif /* CBCMODE_H_ */
diff --git a/sys/include/crypto/ciphers.h b/sys/include/crypto/ciphers.h
new file mode 100644
index 0000000000000000000000000000000000000000..03b37ae0ad64074e5b162be53241dfa76a9772cf
--- /dev/null
+++ b/sys/include/crypto/ciphers.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        ciphers.h
+ * @brief       Headers for the packet encryption class. They are used to encrypt single packets.
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ * @author      Mark Essien <markessien@gmail.com>
+ */
+
+#ifndef __CIPHERS_H_
+#define __CIPHERS_H_
+
+/* Shared header file for all cipher algorithms */
+
+/* Set the algorithms that should be compiled in here. When these defines
+ * are set, then packets will be compiled 5 times.
+ *
+ * */
+#define AES
+// #define RC5
+// #define THREEDES
+// #define AES
+// #define TWOFISH
+// #define SKIPJACK
+
+/// the length of keys in bytes
+#define PARSEC_MAX_BLOCK_CIPHERS  5
+#define CIPHERS_KEYSIZE           20
+
+/**
+ * @brief   the context for cipher-operations
+ *          always order by number of bytes descending!!! <br>
+ * rc5          needs 104 bytes                           <br>
+ * threedes     needs 24  bytes                           <br>
+ * aes          needs PARSEC_KEYSIZE bytes                <br>
+ * twofish      needs PARSEC_KEYSIZE bytes                <br>
+ * skipjack     needs 20 bytes                            <br>
+ * identity     needs 1  byte                             <br>
+ */
+typedef struct {
+#if defined(RC5)
+    uint8_t context[104];             // supports RC5 and lower
+#elif defined(THREEDES)
+    uint8_t context[24];              // supports ThreeDES and lower
+#elif defined(AES)
+    uint8_t context[CIPHERS_KEYSIZE]; // supports AES and lower
+#elif defined(TWOFISH)
+    uint8_t context[CIPHERS_KEYSIZE]; // supports TwoFish and lower
+#elif defined(SKIPJACK)
+    uint8_t context[20];              // supports SkipJack and lower
+#endif
+} cipher_context_t;
+
+
+/**
+ * @struct BlockCipherInterface_t
+ * @brief   BlockCipher-Interface for the Cipher-Algorithms
+ * @typedef BlockCipherInterface_t
+ */
+typedef struct {
+    char name[10];
+    // the init function
+    int (*BlockCipher_init)(cipher_context_t *context, uint8_t blockSize,
+                            uint8_t keySize, uint8_t *key);
+    // the encrypt function
+    int (*BlockCipher_encrypt)(cipher_context_t *context, uint8_t *plainBlock,
+                               uint8_t *cipherBlock);
+    // the decrypt function
+    int (*BlockCipher_decrypt)(cipher_context_t *context, uint8_t *cipherBlock,
+                               uint8_t *plainBlock);
+    // the setupKey function
+    int (*setupKey)(cipher_context_t *context, uint8_t *key, uint8_t keysize);
+    // read the BlockSize of this Cipher
+    uint8_t (*BlockCipherInfo_getPreferredBlockSize)(void);
+} block_cipher_interface_t;
+
+
+typedef struct CipherModeContext {
+    cipher_context_t cc;            // CipherContext for the cipher-operations
+    uint8_t context[24];         // context for the block-cipher-modes'
+                                 // internal functions
+    //CBCModeContext* context;
+} CipherModeContext;
+
+
+/**
+ * @brief       struct for an archive of all available ciphers
+ * @struct      BlockCipher_Archive_t CipherManager.h "ciphers/CipherManager.h"
+ * @typedef     BlockCipher_Archive_t
+ */
+typedef struct {
+        // the number of available ciphers
+    uint8_t NoCiphers;
+    // the ciphers in form or BlockCipherInterface_ts
+    block_cipher_interface_t ciphers[PARSEC_MAX_BLOCK_CIPHERS];
+} block_cipher_archive_t;
+
+typedef struct {
+        // cipher_context_t for the cipher-operations
+    cipher_context_t cc;
+#if defined(AES) || defined (TWOFISH)
+    // supports 16-Byte blocksize
+    uint8_t context[20];
+#else
+    // supports 8-Byte blocksize
+    uint8_t context[12];
+#endif
+} cipher_mac_context_t;
+
+/** @} */
+#endif /* __CIPHERS_H_ */
diff --git a/sys/include/crypto/rc5.h b/sys/include/crypto/rc5.h
new file mode 100644
index 0000000000000000000000000000000000000000..dddfd3b8d7829eb839c576149735f58c0e0f5dab
--- /dev/null
+++ b/sys/include/crypto/rc5.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        rc5.h
+ * @brief       Headers for the implementation of the RC5 Cipher-Algorithm
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ */
+
+#include "crypto/ciphers.h"
+
+#ifndef RC5_H_
+#define RC5_H_
+
+
+#define RC5_32_P        0xB7E15163L
+#define RC5_32_Q        0x9E3779B9L
+#define RC5_32_MASK     0xffffffffL
+
+#define RC5_ROUNDS 12
+
+#define rotl32(a,b) fastrol32((a), (b))
+#define rotr32(a,b) fastror32((a), (b))
+#define rol32(a, n) ( a = (((a) << (n)) | ((a) >> (32-(n)))))
+#define ror32(a, n) ( a = (((a) >> (n)) | ((a) << (32-(n)))))
+#define fastrol32 rol32
+#define fastror32 ror32
+
+// convert a 4byte char array to a unsigned long
+// [assumes least significant byte of char array is first]
+#define c2l(c,l)  (l =((unsigned long)(*((c)))),        \
+                   l|=((unsigned long)(*((c+1))))<< 8L, \
+                   l|=((unsigned long)(*((c+2))))<<16L, \
+                   l|=((unsigned long)(*((c+3))))<<24L)
+
+// convert an unsigned long to a 4 byte char array
+// [assumes least significant byte of char array is first]
+#define l2c(l,c)  (*((c))  =(unsigned char)(((l)     )&0xff), \
+                   *((c+1))=(unsigned char)(((l)>> 8L)&0xff), \
+                   *((c+2))=(unsigned char)(((l)>>16L)&0xff), \
+                   *((c+3))=(unsigned char)(((l)>>24L)&0xff))
+
+// 2 * (ROUNDS +1) * 4
+// 2 * 13 * 4 = 104 bytes
+/**
+ * @brief the cipher_context_t adapted for RC5
+ */
+typedef struct {
+    uint32_t skey [2 * (RC5_ROUNDS + 1)];
+} rc5_context_t;
+
+/**
+* @brief    Initialize the BlockCipher.
+*
+* @param    context       the cipher_context_t-struct to save the initialization
+*                         of the cipher in
+* @param    blockSize     the used blocksize - this must match the
+*                         cipher-blocksize
+* @param    keySize       the size of the key
+* @param    key           a pointer to the key
+*
+* @return   Whether initialization was successful. The command may be
+*           unsuccessful if the key size or blockSize are not valid for the
+*           given cipher implementation.
+*/
+int rc5_init(cipher_context_t *context, uint8_t blockSize, uint8_t keySize,
+             uint8_t *key);
+
+/**
+ * @brief   Encrypts a single block (of blockSize) using the passed context.
+ *
+ * PROLOGUE: 24 cycles
+ * INIT:     48 cycles
+ * LOOP:   1680 cycles (12 + fastrol [= 42] + 16) * 2 * RC5_ROUNDS
+ * CLOSE:    24 cycles
+ * =====================
+ *         1776 cycles (avg case)
+ *
+ * @param   context       the cipher_context_t-struct to save the updated key in
+ * @param   plainBlock    a plaintext block of blockSize
+ * @param   cipherBlock   the resulting ciphertext block of blockSize
+ *
+ * @return  Whether the encryption was successful. Possible failure reasons
+ *          include not calling init().
+ */
+int rc5_encrypt(cipher_context_t *context, uint8_t *block, uint8_t *cipherBlock);
+
+/**
+ * @brief   Decrypts a single block (of blockSize) using the key and the
+ *          keySize.
+ *
+ * @param   context       the cipher_context_t-struct to use for this decryption
+ * @param   cipherBlock   a ciphertext block of blockSize
+ * @param   plainBlock    the resulting plaintext block of blockSize
+ *
+ * @return  Whether the decryption was successful. Possible failure reasons
+ *          include not calling init() or an unimplimented decrypt function.
+ */
+int rc5_decrypt(cipher_context_t *context, uint8_t *cipherBlock,
+                uint8_t *plainBlock);
+
+/**
+ * @brief   Sets up the key for usage with RC5
+ *          Performs the key expansion on the real secret.
+ *
+ * @param   context       the cipher_context_t-struct to save the updated key in
+ * @param   key           a pointer to the secret key
+ * @param   keysize       the length of the secret key
+ *
+ * @return  SUCCESS
+ */
+int rc5_setup_key(cipher_context_t *context, uint8_t *key, uint8_t keysize);
+
+/**
+ * @brief   Returns the preferred block size that this cipher operates with.
+ *          It is always safe to call this function before the init() call has
+ *          been made.
+ *
+ * @return  the preferred block size for this cipher.
+ */
+uint8_t rc5_get_preferred_block_size(void);
+
+/**
+ * Interface to access the functions
+ *
+ */
+extern block_cipher_interface_t rc5_interface;
+
+/** @} */
+#endif /* RC5_H_ */
diff --git a/sys/include/sha256.h b/sys/include/crypto/sha256.h
similarity index 78%
rename from sys/include/sha256.h
rename to sys/include/crypto/sha256.h
index 852dad4fcf9af750173a153f0804ea1b1a448e8b..3aa0ec8858b67739737c8ffc661c2eef6ffe781d 100644
--- a/sys/include/sha256.h
+++ b/sys/include/crypto/sha256.h
@@ -34,6 +34,18 @@
  * @brief       SHA264 hash generator
  */
 
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        sha256.h
+ * @brief       Header definitions for the SHA256 hash function
+ *
+ * @author      Colin Percival
+ * @author      Christian Mehlis
+ * @author      Rene Kijewski
+ */
+
 #ifndef _SHA256_H_
 #define _SHA256_H_
 
@@ -41,36 +53,36 @@
 
 #define SHA256_DIGEST_LENGTH 32
 
-typedef struct SHA256Context {
+typedef struct {
     uint32_t state[8];
     uint32_t count[2];
     unsigned char buf[64];
-} SHA256_CTX;
+} sha256_context_t;
 
 /**
  * @brief SHA-256 initialization.  Begins a SHA-256 operation.
  *
- * @param ctx  SHA256_CTX handle to init
+ * @param ctx  sha256_context_t handle to init
  */
-void SHA256_Init(SHA256_CTX *ctx);
+void sha256_init(sha256_context_t *ctx);
 
 /**
  * @brief Add bytes into the hash
  *
- * @param ctx  SHA256_CTX handle to use
+ * @param ctx  sha256_context_t handle to use
  * @param in   pointer to the input buffer
  * @param len  length of the buffer
  */
-void SHA256_Update(SHA256_CTX *ctx, const void *in, size_t len);
+void sha256_update(sha256_context_t *ctx, const void *in, size_t len);
 
 /**
  * @brief SHA-256 finalization.  Pads the input data, exports the hash value,
  * and clears the context state.
  *
  * @param digest resulting digest, this is the hash of all the bytes
- * @param ctx    SHA256_CTX handle to use
+ * @param ctx    sha256_context_t handle to use
  */
-void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx);
+void sha256_final(unsigned char digest[32], sha256_context_t *ctx);
 
 /**
  * @brief A wrapper function to simplify the generation of a hash, this is
@@ -82,6 +94,7 @@ void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx);
  *           SHA256_DIGEST_LENGTH
  *           if md == NULL, one static buffer is used
  */
-unsigned char *SHA256(const unsigned char *d, size_t n,unsigned char *md);
+unsigned char *sha256(const unsigned char *d, size_t n, unsigned char *md);
 
-#endif /* !_SHA256_H_ */
+/** @} */
+#endif /* _SHA256_H_ */
diff --git a/sys/include/crypto/skipjack.h b/sys/include/crypto/skipjack.h
new file mode 100644
index 0000000000000000000000000000000000000000..9191053241560a87c78c37465c664e35a13ba40e
--- /dev/null
+++ b/sys/include/crypto/skipjack.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ * 
+ * @file        skipjack.h
+ * @brief       Headers for the implementation of the SkipJack cipher-algorithm
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ */
+
+#ifndef SKIPJACK_H_
+#define SKIPJACK_H_
+
+#include "crypto/ciphers.h"
+
+#define F(addr) /*CRYPTO_TABLE_ACCESS( &SJ_F[addr])*/ (SJ_F[addr])
+
+// G-Permutation: 4 round feistel structure
+#define G(key, b, bLeft, bRight)     \
+     (                               \
+       bLeft   = b,                  \
+       bRight  = (b >> 8),           \
+       bLeft  ^= F(bRight ^ key[0]), \
+       bRight ^= F(bLeft  ^ key[1]), \
+       bLeft  ^= F(bRight ^ key[2]), \
+       bRight ^= F(bLeft  ^ key[3]), \
+       ((bRight << 8) | bLeft))
+
+#define G_INV(key, b, bLeft, bRight) \
+     ( bLeft   = b,                  \
+       bRight  = (b >> 8),           \
+       bRight ^= F(bLeft  ^ key[3]), \
+       bLeft  ^= F(bRight ^ key[2]), \
+       bRight ^= F(bLeft  ^ key[1]), \
+       bLeft  ^= F(bRight ^ key[0]), \
+       ((bRight << 8) | bLeft))
+
+// A-RULE:
+#define RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ) { \
+    tmp = w4;                                \
+    w4 = w3;                                 \
+    w3 = w2;                                 \
+    w2 = G(skey, w1, bLeft, bRight);         \
+    w1 = ((tmp ^ w2) ^ counter);             \
+    counter++;                               \
+    skey += 4; }
+
+#define RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight) { \
+    tmp = w4;                                \
+    w4 = (w1 ^ w2 ^ counter);                \
+    w1 = G_INV(skey, w2, bLeft, bRight);     \
+    w2 = w3;                                 \
+    w3 = tmp;                                \
+    counter--;                               \
+    skey -= 4; }                             \
+ 
+// B-RULE:
+#define RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ) { \
+    tmp = w1;                                \
+    w1 = w4;                                 \
+    w4 = w3;                                 \
+    w3 = (tmp ^ w2 ^ counter);               \
+    w2 = G(skey, tmp, bLeft, bRight);        \
+    counter++;                               \
+    skey += 4; }
+
+#define RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ) { \
+    tmp = w1;                                \
+    w1 = G_INV(skey, w2, bLeft, bRight);     \
+    w2 = (w1 ^ w3 ^ counter);                \
+    w3 = w4;                                 \
+    w4 = tmp;                                \
+    counter--;                               \
+    skey -= 4; }
+
+/**
+ * @brief The cipher_context_t adapted for SkipJack
+ * @typedef skipjack_context_t
+ */
+typedef struct {
+        // 2 times keysize. makes unrolling keystream easier / efficient
+    uint8_t skey [ 20 ];
+} skipjack_context_t;
+
+/**
+ * @brief   Initialize the SkipJack-BlockCipher context.
+ *
+ * @param   context     structure to hold the opaque data from this
+ *                      initialization call. It should be passed to future
+ *                      invocations of this module which use this particular
+ *                      key.
+ * @param   blockSize   size of the block in bytes.
+ * @param   keySize     key size in bytes
+ * @param   key         pointer to the key
+ *
+ * @return  Whether initialization was successful. The command may be
+ *          unsuccessful if the key size or blockSize are not valid.
+ */
+int skipjack_init(cipher_context_t *context, uint8_t blockSize, uint8_t keySize,
+                  uint8_t *key);
+
+/**
+ * @brief   Encrypts a single block (of blockSize) using the passed context.
+ *
+ * @param   context       holds the module specific opaque data related to the
+ *                        key (perhaps key expansions).
+ * @param   plainBlock    a plaintext block of blockSize
+ * @param   cipherBlock   the resulting ciphertext block of blockSize
+ *
+ * @return  Whether the encryption was successful. Possible failure reasons
+ *          include not calling init().
+ */
+int skipjack_encrypt(cipher_context_t *context, uint8_t *plainBlock,
+                     uint8_t *cipherBlock);
+
+/**
+ * @brief   Decrypts a single block (of blockSize) using the passed context.
+ *
+ * @param   context       holds the module specific opaque data related to the
+ *                        key (perhaps key expansions).
+ * @param   cipherBlock   a ciphertext block of blockSize
+ * @param   plainBlock    the resulting plaintext block of blockSize
+ *
+ * @return  Whether the decryption was successful. Possible failure reasons
+ *         include not calling init()
+ */
+int skipjack_decrypt(cipher_context_t *context, uint8_t *cipherBlock,
+                     uint8_t *plainBlock);
+
+/**
+ * @brief   Sets up the context to use the passed key for usage with SkipJack
+ *          Performs the key expansion on the real secret.
+ *
+ * @param   context       the cipher_context_t-struct to save the updated key in
+ * @param   key           a pointer to the secret key
+ * @param   keysize       the length of the secret key
+ *
+ * @return SUCCESS
+ */
+int skipjack_setup_key(cipher_context_t *context, uint8_t *key, uint8_t keysize);
+
+/**
+ * @brief   Returns the preferred block size that this cipher operates with.
+ *          It is always safe to call this function before the init() call has
+ *          been made.
+ *
+ * @return  the preferred block size for this cipher. In the case where the
+ *          cipher operates with multiple block sizes, this will pick one
+ *          particular size (deterministically).
+ */
+uint8_t skipjack_get_preferred_block_size(void);
+
+
+/**
+ * Interface to access the functions
+ *
+ */
+extern block_cipher_interface_t skipjack_interface;
+
+/** @} */
+#endif /* SKIPJACK_H_ */
diff --git a/sys/include/crypto/twofish.h b/sys/include/crypto/twofish.h
new file mode 100644
index 0000000000000000000000000000000000000000..4199802e9747ab9a32d05052495e02b24b8e88ef
--- /dev/null
+++ b/sys/include/crypto/twofish.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup     sys_crypto
+ * @{
+ *
+ * @file        twofish.h
+ * @brief       Headers for the implementation of the TwoFish Cipher-Algorithm
+ *
+ * @author      Freie Universitaet Berlin, Computer Systems & Telematics
+ * @author      Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de> *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "crypto/ciphers.h"
+
+#ifndef TWOFISH_H_
+#define TWOFISH_H_
+
+#define TWOFISH_BLOCK_SIZE      16
+#define TWOFISH_KEY_SIZE        16   //only alternative is 32!
+
+/**
+ * Macro to perform one column of the RS matrix multiplication.  The
+ * parameters a, b, c, and d are the four bytes of output; i is the index
+ * of the key bytes, and w, x, y, and z, are the column of constants from
+ * the RS matrix, preprocessed through the poly_to_exp table.
+ **/
+#define CALC_S(a, b, c, d, i, w, x, y, z) \
+   if (key[i]) { \
+      tmp = poly_to_exp[key[i] - 1]; \
+      (a) ^= exp_to_poly[tmp + (w)]; \
+      (b) ^= exp_to_poly[tmp + (x)]; \
+      (c) ^= exp_to_poly[tmp + (y)]; \
+      (d) ^= exp_to_poly[tmp + (z)]; \
+   }
+
+/**
+ * Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S.  CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively.  CALC_SB is simply a convenience to make the code shorter;
+ * it calls CALC_SB_2 four times with consecutive indices from i to i+3,
+ * using the remaining parameters two by two.
+ **/
+
+#define CALC_SB_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
+   ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
+   ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
+   ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
+
+#define CALC_SB(i, a, b, c, d, e, f, g, h) \
+   CALC_SB_2 (i, a, b); CALC_SB_2 ((i)+1, c, d); \
+   CALC_SB_2 ((i)+2, e, f); CALC_SB_2 ((i)+3, g, h)
+
+/* Macros exactly like CALC_SB and CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+   ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+   ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+   ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+#define CALC_SB256(i, a, b, c, d, e, f, g, h) \
+   CALC_SB256_2 (i, a, b); CALC_SB256_2 ((i)+1, c, d); \
+   CALC_SB256_2 ((i)+2, e, f); CALC_SB256_2 ((i)+3, g, h)
+
+/**
+ * Macros to calculate the whitening and round subkeys.  CALC_K_2 computes the
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages.  For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages.  j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
+ * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
+ * rotations.  Its parameters are: a, the array to write the results into,
+ * j, the index of the first output entry, k and l, the preprocessed indices
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K256_2 expands CALC_K_2 to handle 256-bit keys, by doing two
+ * additional lookup-and-XOR stages.  The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use.  CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2.
+ **/
+
+#define CALC_K_2(a, b, c, d, j) \
+     mds[0][q0[a ^ key[(j) + 8]] ^ key[j]]        \
+   ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]]  \
+   ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+   ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
+
+#define CALC_K(a, j, k, l, m, n) \
+   x = CALC_K_2 (k, l, k, l, 0); \
+   y = CALC_K_2 (m, n, m, n, 4); \
+   y = (y << 8) + (y >> 24);     \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+   CALC_K_2 (q0[q1[b ^ key[(j) + 24]] ^ key[(j) + 16]], \
+             q1[q1[a ^ key[(j) + 25]] ^ key[(j) + 17]], \
+             q0[q0[a ^ key[(j) + 26]] ^ key[(j) + 18]], \
+             q1[q0[b ^ key[(j) + 27]] ^ key[(j) + 19]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+   x = CALC_K256_2 (k, l, 0); \
+   y = CALC_K256_2 (m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+
+/**
+ * Macros to compute the g() function in the encryption and decryption
+ * rounds.  G1 is the straight g() function; G2 includes the 8-bit
+ * rotation for the high 32-bit word.
+ **/
+
+#define G1(a) \
+     (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
+   ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
+
+#define G2(b) \
+     (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
+   ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
+
+/**
+ * Encryption and decryption Feistel rounds.  Each one calls the two g()
+ * macros, does the PHT, and performs the XOR and the appropriate bit
+ * rotations.  The parameters are the round number (used to select subkeys),
+ * and the four 32-bit chunks of the text.
+ **/
+
+#define ENCROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x + ctx->k[2 * (n) + 1]; \
+   (c) ^= x + ctx->k[2 * (n)]; \
+   (c) = ((c) >> 1) + ((c) << 31); \
+   (d) = (((d) << 1)+((d) >> 31)) ^ y
+
+#define DECROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x; \
+   (d) ^= y + ctx->k[2 * (n) + 1]; \
+   (d) = ((d) >> 1) + ((d) << 31); \
+   (c) = (((c) << 1)+((c) >> 31)); \
+   (c) ^= (x + ctx->k[2 * (n)])
+
+/**
+ * Encryption and decryption cycles; each one is simply two Feistel rounds
+ * with the 32-bit chunks re-ordered to simulate the "swap"
+ **/
+
+#define ENCCYCLE(n) \
+   ENCROUND (2 * (n), a, b, c, d); \
+   ENCROUND (2 * (n) + 1, c, d, a, b)
+
+#define DECCYCLE(n) \
+   DECROUND (2 * (n) + 1, c, d, a, b); \
+   DECROUND (2 * (n), a, b, c, d)
+
+/**
+ * Macros to convert the input and output bytes into 32-bit words,
+ * and simultaneously perform the whitening step.  INPACK packs word
+ * number n into the variable named by x, using whitening subkey number m.
+ * OUTUNPACK unpacks word number n from the variable named by x, using
+ * whitening subkey number m.
+ **/
+
+#define INPACK(n, x, m) \
+   x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
+     ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+
+#define OUTUNPACK(n, x, m) \
+   x ^= ctx->w[m]; \
+   out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
+   out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+
+
+/**
+ * @brief  Structure for an expanded Twofish key.
+ *
+ * @param   s   contains the key-dependent S-boxes composed with the MDS
+ *              matrix;
+ * @param   w   contains the eight "whitening" subkeys, K[0] through K[7].
+ * @param   k   holds the remaining, "round" subkeys.
+ *
+ * Note that k[i] corresponds to what the Twofish paper calls K[i+8].
+ */
+typedef struct {
+    uint32_t s[4][256], w[8], k[32];
+} twofish_context_t;
+
+
+/**
+ * @brief   Initialize the TwoFish-BlockCipher context.
+ *
+ * @param   context     structure to hold the opaque data from this
+ *                      initialization
+ *                      call. It should be passed to future invocations of
+ *                      this module
+ *                      which use this particular key.
+ * @param   blockSize   size of the block in bytes.
+ * @param   keySize     key size in bytes
+ * @param   key         pointer to the key
+ *
+ * @return  Whether initialization was successful. The command may be
+ *         unsuccessful if the key size or blockSize are not valid.
+ */
+int twofish_init(cipher_context_t *context, uint8_t block_size, uint8_t key_size, uint8_t *key);
+
+/**
+ * @brief   Sets up the context to use the passed key for usage with TwoFish
+ *          Performs the key expansion on the real secret.
+ *
+ * @param   context     the CipherContext-struct to save the updated key in
+ * @param   key         a pointer to the secret key
+ * @param   keysize     the length of the secret key
+ *
+ * @return SUCCESS
+ */
+int twofish_setup_key(cipher_context_t *context, uint8_t *key, uint8_t key_size);
+
+/**
+ * @brief   Encrypts a single block (of blockSize) using the passed context.
+ *
+ * @param   context   holds the module specific opaque data related to the
+ *                    key (perhaps key expansions).
+ * @param   in        a plaintext block of blockSize
+ * @param   out       the resulting ciphertext block of blockSize
+ *
+ * @return  Whether the encryption was successful. Possible failure reasons
+ *          include not calling init().
+ */
+int twofish_encrypt(cipher_context_t *context, uint8_t *in, uint8_t *out);
+
+/**
+ * @brief   Decrypts a single block (of blockSize) using the passed context.
+ *
+ * @param   context   holds the module specific opaque data related to the
+ *                    key (perhaps key expansions).
+ * @param   in        a ciphertext block of blockSize
+ * @param   out       the resulting plaintext block of blockSize
+ *
+ * @return  Whether the decryption was successful. Possible failure reasons
+ *          include not calling init()
+ */
+int twofish_decrypt(cipher_context_t *context, uint8_t *in, uint8_t *out);
+
+/**
+ * @brief   Returns the preferred block size that this cipher operates with.
+ *          It is always safe to call this function before the init() call has
+ *          been made.
+ *
+ * @return  the preferred block size for this cipher. In the case where the
+ *          cipher operates with multiple block sizes, this will pick one
+ *          particular size (deterministically).
+ */
+uint8_t twofish_get_preferred_block_size(void);
+
+/**
+ * Interface to access the functions
+ *
+ */
+extern block_cipher_interface_t twofish_interface;
+
+/** @} */
+#endif /* TWOFISH_H_ */