diff --git a/sys/crypto/doc.txt b/sys/crypto/doc.txt index 73173eb83..e2195001d 100644 --- a/sys/crypto/doc.txt +++ b/sys/crypto/doc.txt @@ -19,7 +19,6 @@ * * AES-128 * * 3DES * * Twofish - * * Skipjack * * NULL * * You can use them directly by adding "crypto" to your USEMODULE-List. diff --git a/sys/crypto/skipjack.c b/sys/crypto/skipjack.c deleted file mode 100644 index 83df59cad..000000000 --- a/sys/crypto/skipjack.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @ingroup sys_crypto - * @{ - * - * @file - * @brief implementation of the SkipJack Cipher-Algorithm - * - * @author Freie Universitaet Berlin, Computer Systems & Telematics - * @author Nicolai Schmittberger - * @author Zakaria Kasmi - * @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 -#include -#include -#include -#include -#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 - */ -static const cipher_interface_t skipjack_interface = { - BLOCK_SIZE, - CIPHERS_MAX_KEY_SIZE, - skipjack_init, - skipjack_encrypt, - skipjack_decrypt -}; -const cipher_id_t CIPHER_SKIPJACK = &skipjack_interface; - -// 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 -}; - - -/** - * @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(const 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(const uint16_t s, uint8_t *c) -{ - memcpy(c, &s, sizeof(uint16_t)); - return; -} - - -int skipjack_encrypt(const cipher_context_t *context, const uint8_t *plainBlock, - uint8_t *cipherBlock) -{ - - // prologue 10 pushs = 20 cycles - /*register*/ uint8_t counter = 1; - cipher_context_t *skipjack_context = (cipher_context_t *)context->context; - /*register*/ uint8_t *skey = skipjack_context->context; - - /*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->context; - - 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->context; - - while (counter < 16) { // 5x - RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight); - } - - skey = skipjack_context->context; - // 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->context; - - 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->context; - - while (counter < 31) { // 5x - RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight); - } - - skey = skipjack_context->context; - - 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); - /* cppcheck: may introduce timing bias if left out */ - /* cppcheck-suppress uselessAssignmentPtrArg */ - cipherBlock += 2; - - return 1; -} - - -int skipjack_decrypt(const cipher_context_t *context, const uint8_t *cipherBlock, - uint8_t *plainBlock) -{ - /*register*/ uint8_t counter = 32; - cipher_context_t *skipjack_context = (cipher_context_t *)context->context; - /*register*/ uint8_t *skey = skipjack_context->context + 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->context + 16; - - while (counter > 25) { //5x - RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight); - } - - skey = skipjack_context->context + 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->context + 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->context + 16; - - while (counter > 10) { //5x - RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight); - } - - skey = skipjack_context->context + 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->context + 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_init(cipher_context_t *context, const uint8_t *key, uint8_t keysize) -{ - int i = 0; - - // Make sure that context is large enough. If this is not the case, - // you should build with -DSKIPJACK. - if(CIPHER_MAX_CONTEXT_SIZE < SKIPJACK_CONTEXT_SIZE) { - return 0; - } - - cipher_context_t *skipjack_context = (cipher_context_t *)context->context; - uint8_t *skey = skipjack_context->context; - - // 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_MAX_KEY_SIZE) { - //fill up by concatenating key to as long as needed - for (i = 0; i < CIPHERS_MAX_KEY_SIZE; i++) { - skey[i] = key[(i % keysize)]; - } - } - else { - for (i = 0; i < CIPHERS_MAX_KEY_SIZE; i++) { - skey[i] = key[i]; - } - } - - return 1; -} diff --git a/sys/include/crypto/ciphers.h b/sys/include/crypto/ciphers.h index e8581ea7d..1e3c8bd9c 100644 --- a/sys/include/crypto/ciphers.h +++ b/sys/include/crypto/ciphers.h @@ -36,7 +36,6 @@ extern "C" { // #define CRYPTO_THREEDES // #define CRYPTO_AES // #define CRYPTO_TWOFISH -// #define CRYPTO_SKIPJACK /** @brief the length of keys in bytes */ #define CIPHERS_MAX_KEY_SIZE 20 @@ -50,7 +49,6 @@ extern "C" { * threedes needs 24 bytes
* aes needs CIPHERS_MAX_KEY_SIZE bytes
* twofish needs CIPHERS_MAX_KEY_SIZE bytes
- * skipjack needs 20 bytes */ #if defined(CRYPTO_THREEDES) #define CIPHER_MAX_CONTEXT_SIZE 24 @@ -58,8 +56,6 @@ extern "C" { #define CIPHER_MAX_CONTEXT_SIZE CIPHERS_MAX_KEY_SIZE #elif defined(CRYPTO_TWOFISH) #define CIPHER_MAX_CONTEXT_SIZE CIPHERS_MAX_KEY_SIZE -#elif defined(CRYPTO_SKIPJACK) - #define CIPHER_MAX_CONTEXT_SIZE 20 #else // 0 is not a possibility because 0-sized arrays are not allowed in ISO C #define CIPHER_MAX_CONTEXT_SIZE 1 @@ -109,7 +105,6 @@ typedef const cipher_interface_t *cipher_id_t; extern const cipher_id_t CIPHER_3DES; extern const cipher_id_t CIPHER_AES_128; extern const cipher_id_t CIPHER_TWOFISH; -extern const cipher_id_t CIPHER_SKIPJACK; /** diff --git a/sys/include/crypto/skipjack.h b/sys/include/crypto/skipjack.h deleted file mode 100644 index 1ad9d05b1..000000000 --- a/sys/include/crypto/skipjack.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @ingroup sys_crypto - * @{ - * - * @file - * @brief Headers for the implementation of the SkipJack cipher-algorithm - * - * @author Freie Universitaet Berlin, Computer Systems & Telematics - * @author Nicolai Schmittberger - * @author Zakaria Kasmi - */ - -#ifndef SKIPJACK_H_ -#define SKIPJACK_H_ - -#include "crypto/ciphers.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#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; } - -/** 2 times keysize. makes unrolling keystream easier / efficient */ -#define SKIPJACK_CONTEXT_SIZE 20 - -/** - * @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 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. - */ -int skipjack_init(cipher_context_t *context, const uint8_t *key, uint8_t keySize); - -/** - * @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(const cipher_context_t *context, const 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(const cipher_context_t *context, const uint8_t *cipherBlock, - uint8_t *plainBlock); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* SKIPJACK_H_ */