Skip to content
Snippets Groups Projects
Commit c2893d4a authored by Oleg Hahm's avatar Oleg Hahm
Browse files

sys: crypto: remove twofish and rc5

parent 9d44d6b0
No related branches found
No related tags found
No related merge requests found
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
* Riot supports the following block ciphers: * Riot supports the following block ciphers:
* * AES-128 * * AES-128
* * 3DES * * 3DES
* * Twofish
* * NULL * * NULL
* *
* You can use them directly by adding "crypto" to your USEMODULE-List. * You can use them directly by adding "crypto" to your USEMODULE-List.
...@@ -28,7 +27,6 @@ ...@@ -28,7 +27,6 @@
* Additionally you need to set a CFLAG for each cipher you want to use in your Makefile: * Additionally you need to set a CFLAG for each cipher you want to use in your Makefile:
* * AES-128: CFLAGS += -DCRYPTO_AES * * AES-128: CFLAGS += -DCRYPTO_AES
* * 3DES: CFLAGS += -DCRYPTO_THREEDES * * 3DES: CFLAGS += -DCRYPTO_THREEDES
* * Twofish: CFLAGS += -DCRYPTO_TWOFISH
* Setting the CFLAGS initializes a sufficient large buffer size of the cipher_context_t, * Setting the CFLAGS initializes a sufficient large buffer size of the cipher_context_t,
* used by the ciphers for en-/de-cryption operations. * used by the ciphers for en-/de-cryption operations.
* *
......
/*
* 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 RC5 cipher-algorithm
*
* @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
*/
static const cipher_interface_t rc5_interface = {
BLOCK_SIZE,
CIPHERS_MAX_KEY_SIZE,
rc5_init,
rc5_encrypt,
rc5_decrypt
};
const cipher_id_t CIPHER_RC5 = &rc5_interface;
int rc5_encrypt(const cipher_context_t *context, const uint8_t *block,
uint8_t *cipherBlock)
{
register uint32_t l;
register uint32_t r;
rc5_context_t *rc5_context = (rc5_context_t *) context->context;
register uint32_t *s = rc5_context->skey;
uint8_t i;
c2l(block, l);
block += 4;
c2l(block, r);
l += *s++;
r += *s++;
for (i = RC5_ROUNDS; i > 0; i--) {
l ^= r;
uint8_t 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(const cipher_context_t *context, const uint8_t *cipherBlock,
uint8_t *plainBlock)
{
register uint32_t l;
register uint32_t r;
rc5_context_t *rc5_context = (rc5_context_t *) context->context;
register uint32_t *s = rc5_context->skey + (2 * RC5_ROUNDS) + 1;
uint8_t i;
c2l(cipherBlock, l);
cipherBlock += 4;
c2l(cipherBlock, r);
for (i = RC5_ROUNDS; i > 0; i--) {
r -= *s--;
uint8_t 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_init(cipher_context_t *context, const uint8_t *key, uint8_t keySize)
{
(void) keySize;
uint32_t *L, l, A, B, *S;
uint8_t ii, jj;
int8_t i;
uint8_t tmp[8];
// Make sure that context is large enough. If this is not the case,
// you should build with -DRC5.
if(CIPHER_MAX_CONTEXT_SIZE < RC5_CONTEXT_SIZE) {
return 0;
}
rc5_context_t *rc5_context = (rc5_context_t *) context->context;
S = rc5_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->skey;
for (i = 3 * (2 * RC5_ROUNDS + 2) - 1; i >= 0; i--) {
uint32_t k = (*S + A + B)&RC5_32_MASK;
rotl32((k), (3));
A = *S = k;
S++;
uint8_t 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->skey;
}
jj ^= 4;
L = (uint32_t *)(&tmp[jj]);
}
return 1;
}
This diff is collapsed.
...@@ -35,7 +35,6 @@ extern "C" { ...@@ -35,7 +35,6 @@ extern "C" {
*/ */
// #define CRYPTO_THREEDES // #define CRYPTO_THREEDES
// #define CRYPTO_AES // #define CRYPTO_AES
// #define CRYPTO_TWOFISH
/** @brief the length of keys in bytes */ /** @brief the length of keys in bytes */
#define CIPHERS_MAX_KEY_SIZE 20 #define CIPHERS_MAX_KEY_SIZE 20
...@@ -48,14 +47,11 @@ extern "C" { ...@@ -48,14 +47,11 @@ extern "C" {
* *
* threedes needs 24 bytes <br> * threedes needs 24 bytes <br>
* aes needs CIPHERS_MAX_KEY_SIZE bytes <br> * aes needs CIPHERS_MAX_KEY_SIZE bytes <br>
* twofish needs CIPHERS_MAX_KEY_SIZE bytes <br>
*/ */
#if defined(CRYPTO_THREEDES) #if defined(CRYPTO_THREEDES)
#define CIPHER_MAX_CONTEXT_SIZE 24 #define CIPHER_MAX_CONTEXT_SIZE 24
#elif defined(CRYPTO_AES) #elif defined(CRYPTO_AES)
#define CIPHER_MAX_CONTEXT_SIZE CIPHERS_MAX_KEY_SIZE #define CIPHER_MAX_CONTEXT_SIZE CIPHERS_MAX_KEY_SIZE
#elif defined(CRYPTO_TWOFISH)
#define CIPHER_MAX_CONTEXT_SIZE CIPHERS_MAX_KEY_SIZE
#else #else
// 0 is not a possibility because 0-sized arrays are not allowed in ISO C // 0 is not a possibility because 0-sized arrays are not allowed in ISO C
#define CIPHER_MAX_CONTEXT_SIZE 1 #define CIPHER_MAX_CONTEXT_SIZE 1
...@@ -107,7 +103,6 @@ typedef const cipher_interface_t *cipher_id_t; ...@@ -107,7 +103,6 @@ typedef const cipher_interface_t *cipher_id_t;
extern const cipher_id_t CIPHER_3DES; extern const cipher_id_t CIPHER_3DES;
extern const cipher_id_t CIPHER_AES_128; extern const cipher_id_t CIPHER_AES_128;
extern const cipher_id_t CIPHER_TWOFISH;
/** /**
......
/*
* 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 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_
#ifdef __cplusplus
extern "C" {
#endif
#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
#define RC5_CONTEXT_SIZE (2 * (RC5_ROUNDS + 1))
/**
* @brief the cipher_context_t adapted for RC5
*/
typedef struct {
/** @cond INTERNAL */
uint32_t skey [RC5_CONTEXT_SIZE];
/** @endcond */
} rc5_context_t;
/**
* @brief Initialize the BlockCipher.
*
* @param context the cipher_context_t-struct to save the initialization
* of the cipher in
* @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 is not valid for the
* given cipher implementation.
*/
int rc5_init(cipher_context_t *context, const uint8_t *key, uint8_t keySize);
/**
* @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 plain_block a plaintext block of blockSize
* @param cipher_block the resulting ciphertext block of blockSize
*
* @return Whether the encryption was successful. Possible failure reasons
* include not calling init().
*/
int rc5_encrypt(const cipher_context_t *context, const uint8_t *plain_block, uint8_t *cipher_block);
/**
* @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(const cipher_context_t *context, const uint8_t *cipherBlock,
uint8_t *plainBlock);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* RC5_H_ */
/*
* 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 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_
#ifdef __cplusplus
extern "C" {
#endif
#define TWOFISH_BLOCK_SIZE 16
#define TWOFISH_KEY_SIZE 16 //only alternative is 32!
#define TWOFISH_CONTEXT_SIZE 20
/**
* 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) \
^ ((uint32_t)in[4 * (n) + 2] << 16) ^ ((uint32_t)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.
*
* Note that k[i] corresponds to what the Twofish paper calls K[i+8].
*/
typedef struct {
/** contains the key-dependent S-boxes composed with the MDS matrix */
uint32_t s[4][256],
/** contains the eight "whitening" subkeys, K[0] through K[7] */
w[8],
/** holds the remaining, "round" subkeys */
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 key_size key size in bytes
* @param key pointer to the key
*
* @return CIPHER_INIT_SUCCESS if the initialization was successful.
* The command may be unsuccessful if the key size is not valid.
* CIPHER_ERR_BAD_CONTEXT_SIZE if CIPHER_MAX_CONTEXT_SIZE has not been defined (which means that the cipher has not been included in the build)
*/
int twofish_init(cipher_context_t *context, const 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(const cipher_context_t *context, const 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(const cipher_context_t *context, const uint8_t *in, uint8_t *out);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* TWOFISH_H_ */
/*
* Copyright (C) 2015 Nico von Geyso
*
* 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.
*/
#include <limits.h>
#include "embUnit.h"
#include "crypto/twofish.h"
#include "tests-crypto.h"
static uint8_t TEST_0_KEY[] = {
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
};
static uint8_t TEST_0_INP[] = {
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
};
static uint8_t TEST_0_ENC[] = {
0x9F, 0xB6, 0x33, 0x37, 0x15, 0x1B, 0xE9, 0xC7,
0x13, 0x06, 0xD1, 0x59, 0xEA, 0x7A, 0xFA, 0xA4
};
static uint8_t TEST_1_KEY[] = {
0x23, 0xA0, 0x18, 0x53, 0xFA, 0xB3, 0x89, 0x23,
0x65, 0x89, 0x2A, 0xBC, 0x43, 0x99, 0xCC, 0x00
};
static uint8_t TEST_1_INP[] = {
0x11, 0x53, 0x81, 0xE2, 0x5F, 0x33, 0xE7, 0x41,
0xBB, 0x12, 0x67, 0x38, 0xE9, 0x12, 0x54, 0x23
};
static uint8_t TEST_1_ENC[] = {
0xEA, 0x27, 0x44, 0xBB, 0x15, 0x56, 0xDB, 0xF3,
0x33, 0xD4, 0x90, 0x09, 0x44, 0x7B, 0x83, 0x57
};
static void test_crypto_twofish_encrypt(void)
{
cipher_context_t ctx;
int err;
uint8_t data[TWOFISH_BLOCK_SIZE];
err = twofish_init(&ctx, TEST_0_KEY, TWOFISH_KEY_SIZE);
TEST_ASSERT_EQUAL_INT(1, err);
err = twofish_encrypt(&ctx, TEST_0_INP, data);
TEST_ASSERT_EQUAL_INT(1, err);
TEST_ASSERT_MESSAGE(1 == compare(TEST_0_ENC, data, TWOFISH_BLOCK_SIZE), "wrong ciphertext");
err = twofish_init(&ctx, TEST_1_KEY, TWOFISH_KEY_SIZE);
TEST_ASSERT_EQUAL_INT(1, err);
err = twofish_encrypt(&ctx, TEST_1_INP, data);
TEST_ASSERT_EQUAL_INT(1, err);
TEST_ASSERT_MESSAGE(1 == compare(TEST_1_ENC, data, TWOFISH_BLOCK_SIZE), "wrong ciphertext");
}
static void test_crypto_twofish_decrypt(void)
{
cipher_context_t ctx;
int err;
uint8_t data[TWOFISH_BLOCK_SIZE];
err = twofish_init(&ctx, TEST_0_KEY, TWOFISH_KEY_SIZE);
TEST_ASSERT_EQUAL_INT(1, err);
err = twofish_decrypt(&ctx, TEST_0_ENC, data);
TEST_ASSERT_EQUAL_INT(1, err);
TEST_ASSERT_MESSAGE(1 == compare(TEST_0_INP, data, TWOFISH_BLOCK_SIZE), "wrong plaintext");
err = twofish_init(&ctx, TEST_1_KEY, TWOFISH_KEY_SIZE);
TEST_ASSERT_EQUAL_INT(1, err);
err = twofish_decrypt(&ctx, TEST_1_ENC, data);
TEST_ASSERT_EQUAL_INT(1, err);
TEST_ASSERT_MESSAGE(1 == compare(TEST_1_INP, data, TWOFISH_BLOCK_SIZE), "wrong plaintext");
}
Test* tests_crypto_twofish_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_crypto_twofish_encrypt),
new_TestFixture(test_crypto_twofish_decrypt),
};
EMB_UNIT_TESTCALLER(crypto_twofish_tests, NULL, NULL, fixtures);
return (Test*)&crypto_twofish_tests;
}
...@@ -14,7 +14,6 @@ void tests_crypto(void) ...@@ -14,7 +14,6 @@ void tests_crypto(void)
TESTS_RUN(tests_crypto_chacha_tests()); TESTS_RUN(tests_crypto_chacha_tests());
TESTS_RUN(tests_crypto_aes_tests()); TESTS_RUN(tests_crypto_aes_tests());
TESTS_RUN(tests_crypto_3des_tests()); TESTS_RUN(tests_crypto_3des_tests());
TESTS_RUN(tests_crypto_twofish_tests());
TESTS_RUN(tests_crypto_cipher_tests()); TESTS_RUN(tests_crypto_cipher_tests());
TESTS_RUN(tests_crypto_modes_ccm_tests()); TESTS_RUN(tests_crypto_modes_ccm_tests());
TESTS_RUN(tests_crypto_modes_ecb_tests()); TESTS_RUN(tests_crypto_modes_ecb_tests());
......
...@@ -53,7 +53,6 @@ static inline int compare(uint8_t a[16], uint8_t b[16], uint8_t len) ...@@ -53,7 +53,6 @@ static inline int compare(uint8_t a[16], uint8_t b[16], uint8_t len)
Test* tests_crypto_aes_tests(void); Test* tests_crypto_aes_tests(void);
Test* tests_crypto_3des_tests(void); Test* tests_crypto_3des_tests(void);
Test* tests_crypto_twofish_tests(void);
Test* tests_crypto_cipher_tests(void); Test* tests_crypto_cipher_tests(void);
Test* tests_crypto_modes_ccm_tests(void); Test* tests_crypto_modes_ccm_tests(void);
Test* tests_crypto_modes_ecb_tests(void); Test* tests_crypto_modes_ecb_tests(void);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment