This commit is contained in:
biosvos
2026-08-07 17:38:18 +09:00
commit 873193a243
9613 changed files with 2755992 additions and 0 deletions
@@ -0,0 +1,351 @@
/********************************************************************\
* *
* C specification of the threeway block cipher *
* *
* found in ftp://ftp.funet.fi/pub/crypt/ *
\********************************************************************/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: 3-way.c,v 1.12 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "3-way.h"
#define STRT_E 0x0b0b /* round constant of first encryption round */
#define STRT_D 0xb1b1 /* round constant of first decryption round */
#define NMBR 11 /* number of rounds is 11 */
#define _mcrypt_set_key threeway_LTX__mcrypt_set_key
#define _mcrypt_encrypt threeway_LTX__mcrypt_encrypt
#define _mcrypt_decrypt threeway_LTX__mcrypt_decrypt
#define _mcrypt_get_size threeway_LTX__mcrypt_get_size
#define _mcrypt_get_block_size threeway_LTX__mcrypt_get_block_size
#define _is_block_algorithm threeway_LTX__is_block_algorithm
#define _mcrypt_get_key_size threeway_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes threeway_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name threeway_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test threeway_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version threeway_LTX__mcrypt_algorithm_version
WIN32DLL_DEFINE
int _mcrypt_set_key(word32 * k, word32 * input_key, int len)
{
k[0] = 0;
k[2] = 0;
k[1] = 0;
memmove(k, input_key, len);
return 0;
}
void mu(word32 * a)
{ /* inverts the order of the bits of a */
int i;
word32 b[3];
b[0] = b[1] = b[2] = 0;
for (i = 0; i < 32; i++) {
b[0] <<= 1;
b[1] <<= 1;
b[2] <<= 1;
if (a[0] & 1)
b[2] |= 1;
if (a[1] & 1)
b[1] |= 1;
if (a[2] & 1)
b[0] |= 1;
a[0] >>= 1;
a[1] >>= 1;
a[2] >>= 1;
}
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
}
void gamma(word32 * a)
{ /* the nonlinear step */
word32 b[3];
b[0] = a[0] ^ (a[1] | (~a[2]));
b[1] = a[1] ^ (a[2] | (~a[0]));
b[2] = a[2] ^ (a[0] | (~a[1]));
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
}
void theta(word32 * a)
{ /* the linear step */
word32 b[3];
b[0] =
a[0] ^ (a[0] >> 16) ^ (a[1] << 16) ^ (a[1] >> 16) ^ (a[2] <<
16) ^
(a[1] >> 24) ^ (a[2] << 8) ^ (a[2] >> 8) ^ (a[0] << 24) ^ (a[2]
>>
16)
^ (a[0] << 16) ^ (a[2] >> 24) ^ (a[0] << 8);
b[1] =
a[1] ^ (a[1] >> 16) ^ (a[2] << 16) ^ (a[2] >> 16) ^ (a[0] <<
16) ^
(a[2] >> 24) ^ (a[0] << 8) ^ (a[0] >> 8) ^ (a[1] << 24) ^ (a[0]
>>
16)
^ (a[1] << 16) ^ (a[0] >> 24) ^ (a[1] << 8);
b[2] =
a[2] ^ (a[2] >> 16) ^ (a[0] << 16) ^ (a[0] >> 16) ^ (a[1] <<
16) ^
(a[0] >> 24) ^ (a[1] << 8) ^ (a[1] >> 8) ^ (a[2] << 24) ^ (a[1]
>>
16)
^ (a[2] << 16) ^ (a[1] >> 24) ^ (a[2] << 8);
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
}
void pi_1(word32 * a)
{
a[0] = (a[0] >> 10) ^ (a[0] << 22);
a[2] = (a[2] << 1) ^ (a[2] >> 31);
}
void pi_2(word32 * a)
{
a[0] = (a[0] << 1) ^ (a[0] >> 31);
a[2] = (a[2] >> 10) ^ (a[2] << 22);
}
void rho(word32 * a)
{ /* the round function */
theta(a);
pi_1(a);
gamma(a);
pi_2(a);
}
void rndcon_gen(word32 strt, word32 * rtab)
{ /* generates the round constants */
int i;
for (i = 0; i <= NMBR; i++) {
rtab[i] = strt;
strt <<= 1;
if (strt & 0x10000)
strt ^= 0x11011;
}
}
WIN32DLL_DEFINE void _mcrypt_encrypt(word32 * tk, word32 * ta)
{
int i;
word32 rcon[NMBR + 1];
word32 a[3], k[3];
/* Added to make it compatible with bigendian machines
* --nikos
*/
#ifndef WORDS_BIGENDIAN
a[0] = byteswap32(ta[0]);
a[1] = byteswap32(ta[1]);
a[2] = byteswap32(ta[2]);
k[0] = byteswap32(tk[0]);
k[1] = byteswap32(tk[1]);
k[2] = byteswap32(tk[2]);
#else
a[0] = ta[0];
a[1] = ta[1];
a[2] = ta[2];
k[0] = (tk[0]);
k[1] = (tk[1]);
k[2] = (tk[2]);
#endif
rndcon_gen(STRT_E, rcon);
for (i = 0; i < NMBR; i++) {
a[0] ^= k[0] ^ (rcon[i] << 16);
a[1] ^= k[1];
a[2] ^= k[2] ^ rcon[i];
rho(a);
}
a[0] ^= k[0] ^ (rcon[NMBR] << 16);
a[1] ^= k[1];
a[2] ^= k[2] ^ rcon[NMBR];
theta(a);
#ifndef WORDS_BIGENDIAN
ta[0] = byteswap32(a[0]);
ta[1] = byteswap32(a[1]);
ta[2] = byteswap32(a[2]);
#else
ta[0] = a[0];
ta[1] = a[1];
ta[2] = a[2];
#endif
}
WIN32DLL_DEFINE void _mcrypt_decrypt(word32 * k, word32 * ta)
{
int i;
word32 ki[3]; /* the `inverse' key */
word32 rcon[NMBR + 1]; /* the `inverse' round constants */
word32 a[3];
#ifndef WORDS_BIGENDIAN
a[0] = byteswap32(ta[0]);
a[1] = byteswap32(ta[1]);
a[2] = byteswap32(ta[2]);
ki[0] = byteswap32(k[0]);
ki[1] = byteswap32(k[1]);
ki[2] = byteswap32(k[2]);
#else
a[0] = ta[0];
a[1] = ta[1];
a[2] = ta[2];
ki[0] = k[0];
ki[1] = k[1];
ki[2] = k[2];
#endif
theta(ki);
mu(ki);
rndcon_gen(STRT_D, rcon);
mu(a);
for (i = 0; i < NMBR; i++) {
a[0] ^= ki[0] ^ (rcon[i] << 16);
a[1] ^= ki[1];
a[2] ^= ki[2] ^ rcon[i];
rho(a);
}
a[0] ^= ki[0] ^ (rcon[NMBR] << 16);
a[1] ^= ki[1];
a[2] ^= ki[2] ^ rcon[NMBR];
theta(a);
mu(a);
#ifndef WORDS_BIGENDIAN
ta[0] = byteswap32(a[0]);
ta[1] = byteswap32(a[1]);
ta[2] = byteswap32(a[2]);
#else
ta[0] = a[0];
ta[1] = a[1];
ta[2] = a[2];
#endif
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return 3 * sizeof(word32);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 12;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 12;
}
static const int key_sizes[] = { 12 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "3-WAY";
}
#define CIPHER "46823287358d68f6e034ca62"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,66 @@
## Process this file with automake to produce Makefile.in
DEFS = @DEFS@
INCLUDES = -I. -I../.. $(INCLTDL) -I../../lib
EXTRA_DIST = twofish.h saferplus.h rijndael.h \
rc2.h serpent.h cast-256.h blowfish.h \
cast-128.h cast-128_sboxes.h des.h tripledes.h \
3-way.h enigma.h arcfour.h wake.h \
safer.h xtea.h panama.h
pkglib_LTLIBRARIES = @INSTALL_ALGORITHM_MODULES@
EXTRA_LTLIBRARIES = twofish.la rijndael-128.la \
rijndael-192.la rijndael-256.la saferplus.la rc2.la xtea.la \
serpent.la safer-sk64.la safer-sk128.la cast-256.la loki97.la \
gost.la threeway.la cast-128.la blowfish.la des.la blowfish-compat.la \
tripledes.la enigma.la arcfour.la panama.la wake.la
noinst_LTLIBRARIES = @NOINSTALL_ALGORITHM_MODULES@
twofish_la_SOURCES = twofish.c
twofish_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
wake_la_SOURCES = wake.c
wake_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
panama_la_SOURCES = panama.c
panama_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
rijndael_128_la_SOURCES = rijndael-128.c
rijndael_128_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
rijndael_192_la_SOURCES = rijndael-192.c
rijndael_192_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
rijndael_256_la_SOURCES = rijndael-256.c
rijndael_256_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
saferplus_la_SOURCES = saferplus.c
saferplus_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
serpent_la_SOURCES = serpent.c
serpent_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
xtea_la_SOURCES = xtea.c
xtea_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
rc2_la_SOURCES = rc2.c
rc2_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
safer_sk64_la_SOURCES = safer64.c
safer_sk64_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
safer_sk128_la_SOURCES = safer128.c
safer_sk128_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
cast_256_la_SOURCES = cast-256.c
cast_256_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
loki97_la_SOURCES = loki97.c
loki97_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
gost_la_SOURCES = gost.c
gost_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
threeway_la_SOURCES = 3-way.c
threeway_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
blowfish_la_SOURCES = blowfish.c
blowfish_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
blowfish_compat_la_SOURCES = blowfish-compat.c
blowfish_compat_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
cast_128_la_SOURCES = cast-128.c
cast_128_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
des_la_SOURCES = des.c
des_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
tripledes_la_SOURCES = tripledes.c
tripledes_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
enigma_la_SOURCES = enigma.c
enigma_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
arcfour_la_SOURCES = arcfour.c
arcfour_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
@@ -0,0 +1,673 @@
# Makefile.in generated by automake 1.7.2 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXTRA_ALGOS = @EXTRA_ALGOS@
EXTRA_OBJECTS = @EXTRA_OBJECTS@
INCLTDL = @INCLTDL@
INSTALL_ALGORITHM_MODULES = @INSTALL_ALGORITHM_MODULES@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_MODE_MODULES = @INSTALL_MODE_MODULES@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBLTDL = @LIBLTDL@
LIBLTDL_DIR = @LIBLTDL_DIR@
LIBMCRYPT_CFLAGS = @LIBMCRYPT_CFLAGS@
LIBMCRYPT_CURRENT_INTERFACE_IMPLEMENTATION_NUMBER = @LIBMCRYPT_CURRENT_INTERFACE_IMPLEMENTATION_NUMBER@
LIBMCRYPT_LIBS = @LIBMCRYPT_LIBS@
LIBMCRYPT_MAJOR_VERSION = @LIBMCRYPT_MAJOR_VERSION@
LIBMCRYPT_MICRO_VERSION = @LIBMCRYPT_MICRO_VERSION@
LIBMCRYPT_MINOR_VERSION = @LIBMCRYPT_MINOR_VERSION@
LIBMCRYPT_MOST_RECENT_INTERFACE = @LIBMCRYPT_MOST_RECENT_INTERFACE@
LIBMCRYPT_OLDEST_INTERFACE = @LIBMCRYPT_OLDEST_INTERFACE@
LIBMCRYPT_VERSION = @LIBMCRYPT_VERSION@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_AGE = @LT_AGE@
LT_CURRENT = @LT_CURRENT@
LT_REVISION = @LT_REVISION@
MAKEINFO = @MAKEINFO@
NOINSTALL_ALGORITHM_MODULES = @NOINSTALL_ALGORITHM_MODULES@
NOINSTALL_MODE_MODULES = @NOINSTALL_MODE_MODULES@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
INCLUDES = -I. -I../.. $(INCLTDL) -I../../lib
EXTRA_DIST = twofish.h saferplus.h rijndael.h \
rc2.h serpent.h cast-256.h blowfish.h \
cast-128.h cast-128_sboxes.h des.h tripledes.h \
3-way.h enigma.h arcfour.h wake.h \
safer.h xtea.h panama.h
pkglib_LTLIBRARIES = @INSTALL_ALGORITHM_MODULES@
EXTRA_LTLIBRARIES = twofish.la rijndael-128.la \
rijndael-192.la rijndael-256.la saferplus.la rc2.la xtea.la \
serpent.la safer-sk64.la safer-sk128.la cast-256.la loki97.la \
gost.la threeway.la cast-128.la blowfish.la des.la blowfish-compat.la \
tripledes.la enigma.la arcfour.la panama.la wake.la
noinst_LTLIBRARIES = @NOINSTALL_ALGORITHM_MODULES@
twofish_la_SOURCES = twofish.c
twofish_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
wake_la_SOURCES = wake.c
wake_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
panama_la_SOURCES = panama.c
panama_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
rijndael_128_la_SOURCES = rijndael-128.c
rijndael_128_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
rijndael_192_la_SOURCES = rijndael-192.c
rijndael_192_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
rijndael_256_la_SOURCES = rijndael-256.c
rijndael_256_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
saferplus_la_SOURCES = saferplus.c
saferplus_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
serpent_la_SOURCES = serpent.c
serpent_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
xtea_la_SOURCES = xtea.c
xtea_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
rc2_la_SOURCES = rc2.c
rc2_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
safer_sk64_la_SOURCES = safer64.c
safer_sk64_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
safer_sk128_la_SOURCES = safer128.c
safer_sk128_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
cast_256_la_SOURCES = cast-256.c
cast_256_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
loki97_la_SOURCES = loki97.c
loki97_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
gost_la_SOURCES = gost.c
gost_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
threeway_la_SOURCES = 3-way.c
threeway_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
blowfish_la_SOURCES = blowfish.c
blowfish_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
blowfish_compat_la_SOURCES = blowfish-compat.c
blowfish_compat_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
cast_128_la_SOURCES = cast-128.c
cast_128_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
des_la_SOURCES = des.c
des_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
tripledes_la_SOURCES = tripledes.c
tripledes_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
enigma_la_SOURCES = enigma.c
enigma_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
arcfour_la_SOURCES = arcfour.c
arcfour_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir)
subdir = modules/algorithms
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES)
arcfour_la_LIBADD =
am_arcfour_la_OBJECTS = arcfour.lo
arcfour_la_OBJECTS = $(am_arcfour_la_OBJECTS)
blowfish_compat_la_LIBADD =
am_blowfish_compat_la_OBJECTS = blowfish-compat.lo
blowfish_compat_la_OBJECTS = $(am_blowfish_compat_la_OBJECTS)
blowfish_la_LIBADD =
am_blowfish_la_OBJECTS = blowfish.lo
blowfish_la_OBJECTS = $(am_blowfish_la_OBJECTS)
cast_128_la_LIBADD =
am_cast_128_la_OBJECTS = cast-128.lo
cast_128_la_OBJECTS = $(am_cast_128_la_OBJECTS)
cast_256_la_LIBADD =
am_cast_256_la_OBJECTS = cast-256.lo
cast_256_la_OBJECTS = $(am_cast_256_la_OBJECTS)
des_la_LIBADD =
am_des_la_OBJECTS = des.lo
des_la_OBJECTS = $(am_des_la_OBJECTS)
enigma_la_LIBADD =
am_enigma_la_OBJECTS = enigma.lo
enigma_la_OBJECTS = $(am_enigma_la_OBJECTS)
gost_la_LIBADD =
am_gost_la_OBJECTS = gost.lo
gost_la_OBJECTS = $(am_gost_la_OBJECTS)
loki97_la_LIBADD =
am_loki97_la_OBJECTS = loki97.lo
loki97_la_OBJECTS = $(am_loki97_la_OBJECTS)
panama_la_LIBADD =
am_panama_la_OBJECTS = panama.lo
panama_la_OBJECTS = $(am_panama_la_OBJECTS)
rc2_la_LIBADD =
am_rc2_la_OBJECTS = rc2.lo
rc2_la_OBJECTS = $(am_rc2_la_OBJECTS)
rijndael_128_la_LIBADD =
am_rijndael_128_la_OBJECTS = rijndael-128.lo
rijndael_128_la_OBJECTS = $(am_rijndael_128_la_OBJECTS)
rijndael_192_la_LIBADD =
am_rijndael_192_la_OBJECTS = rijndael-192.lo
rijndael_192_la_OBJECTS = $(am_rijndael_192_la_OBJECTS)
rijndael_256_la_LIBADD =
am_rijndael_256_la_OBJECTS = rijndael-256.lo
rijndael_256_la_OBJECTS = $(am_rijndael_256_la_OBJECTS)
safer_sk128_la_LIBADD =
am_safer_sk128_la_OBJECTS = safer128.lo
safer_sk128_la_OBJECTS = $(am_safer_sk128_la_OBJECTS)
safer_sk64_la_LIBADD =
am_safer_sk64_la_OBJECTS = safer64.lo
safer_sk64_la_OBJECTS = $(am_safer_sk64_la_OBJECTS)
saferplus_la_LIBADD =
am_saferplus_la_OBJECTS = saferplus.lo
saferplus_la_OBJECTS = $(am_saferplus_la_OBJECTS)
serpent_la_LIBADD =
am_serpent_la_OBJECTS = serpent.lo
serpent_la_OBJECTS = $(am_serpent_la_OBJECTS)
threeway_la_LIBADD =
am_threeway_la_OBJECTS = 3-way.lo
threeway_la_OBJECTS = $(am_threeway_la_OBJECTS)
tripledes_la_LIBADD =
am_tripledes_la_OBJECTS = tripledes.lo
tripledes_la_OBJECTS = $(am_tripledes_la_OBJECTS)
twofish_la_LIBADD =
am_twofish_la_OBJECTS = twofish.lo
twofish_la_OBJECTS = $(am_twofish_la_OBJECTS)
wake_la_LIBADD =
am_wake_la_OBJECTS = wake.lo
wake_la_OBJECTS = $(am_wake_la_OBJECTS)
xtea_la_LIBADD =
am_xtea_la_OBJECTS = xtea.lo
xtea_la_OBJECTS = $(am_xtea_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/3-way.Plo ./$(DEPDIR)/arcfour.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/blowfish-compat.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/blowfish.Plo ./$(DEPDIR)/cast-128.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/cast-256.Plo ./$(DEPDIR)/des.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/enigma.Plo ./$(DEPDIR)/gost.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/loki97.Plo ./$(DEPDIR)/panama.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/rc2.Plo ./$(DEPDIR)/rijndael-128.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/rijndael-192.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/rijndael-256.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/safer128.Plo ./$(DEPDIR)/safer64.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/saferplus.Plo ./$(DEPDIR)/serpent.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/tripledes.Plo ./$(DEPDIR)/twofish.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/wake.Plo ./$(DEPDIR)/xtea.Plo
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(arcfour_la_SOURCES) $(blowfish_compat_la_SOURCES) \
$(blowfish_la_SOURCES) $(cast_128_la_SOURCES) \
$(cast_256_la_SOURCES) $(des_la_SOURCES) $(enigma_la_SOURCES) \
$(gost_la_SOURCES) $(loki97_la_SOURCES) $(panama_la_SOURCES) \
$(rc2_la_SOURCES) $(rijndael_128_la_SOURCES) \
$(rijndael_192_la_SOURCES) $(rijndael_256_la_SOURCES) \
$(safer_sk128_la_SOURCES) $(safer_sk64_la_SOURCES) \
$(saferplus_la_SOURCES) $(serpent_la_SOURCES) \
$(threeway_la_SOURCES) $(tripledes_la_SOURCES) \
$(twofish_la_SOURCES) $(wake_la_SOURCES) $(xtea_la_SOURCES)
DIST_COMMON = Makefile.am Makefile.in
SOURCES = $(arcfour_la_SOURCES) $(blowfish_compat_la_SOURCES) $(blowfish_la_SOURCES) $(cast_128_la_SOURCES) $(cast_256_la_SOURCES) $(des_la_SOURCES) $(enigma_la_SOURCES) $(gost_la_SOURCES) $(loki97_la_SOURCES) $(panama_la_SOURCES) $(rc2_la_SOURCES) $(rijndael_128_la_SOURCES) $(rijndael_192_la_SOURCES) $(rijndael_256_la_SOURCES) $(safer_sk128_la_SOURCES) $(safer_sk64_la_SOURCES) $(saferplus_la_SOURCES) $(serpent_la_SOURCES) $(threeway_la_SOURCES) $(tripledes_la_SOURCES) $(twofish_la_SOURCES) $(wake_la_SOURCES) $(xtea_la_SOURCES)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign modules/algorithms/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
pkglibLTLIBRARIES_INSTALL = $(INSTALL)
install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(pkglibdir)
@list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(LIBTOOL) --mode=install $(pkglibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(pkglibdir)/$$f"; \
$(LIBTOOL) --mode=install $(pkglibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(pkglibdir)/$$f; \
else :; fi; \
done
uninstall-pkglibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
p="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p"; \
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
clean-pkglibLTLIBRARIES:
-test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
@list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
arcfour.la: $(arcfour_la_OBJECTS) $(arcfour_la_DEPENDENCIES)
$(LINK) $(arcfour_la_LDFLAGS) $(arcfour_la_OBJECTS) $(arcfour_la_LIBADD) $(LIBS)
blowfish-compat.la: $(blowfish_compat_la_OBJECTS) $(blowfish_compat_la_DEPENDENCIES)
$(LINK) $(blowfish_compat_la_LDFLAGS) $(blowfish_compat_la_OBJECTS) $(blowfish_compat_la_LIBADD) $(LIBS)
blowfish.la: $(blowfish_la_OBJECTS) $(blowfish_la_DEPENDENCIES)
$(LINK) $(blowfish_la_LDFLAGS) $(blowfish_la_OBJECTS) $(blowfish_la_LIBADD) $(LIBS)
cast-128.la: $(cast_128_la_OBJECTS) $(cast_128_la_DEPENDENCIES)
$(LINK) $(cast_128_la_LDFLAGS) $(cast_128_la_OBJECTS) $(cast_128_la_LIBADD) $(LIBS)
cast-256.la: $(cast_256_la_OBJECTS) $(cast_256_la_DEPENDENCIES)
$(LINK) $(cast_256_la_LDFLAGS) $(cast_256_la_OBJECTS) $(cast_256_la_LIBADD) $(LIBS)
des.la: $(des_la_OBJECTS) $(des_la_DEPENDENCIES)
$(LINK) $(des_la_LDFLAGS) $(des_la_OBJECTS) $(des_la_LIBADD) $(LIBS)
enigma.la: $(enigma_la_OBJECTS) $(enigma_la_DEPENDENCIES)
$(LINK) $(enigma_la_LDFLAGS) $(enigma_la_OBJECTS) $(enigma_la_LIBADD) $(LIBS)
gost.la: $(gost_la_OBJECTS) $(gost_la_DEPENDENCIES)
$(LINK) $(gost_la_LDFLAGS) $(gost_la_OBJECTS) $(gost_la_LIBADD) $(LIBS)
loki97.la: $(loki97_la_OBJECTS) $(loki97_la_DEPENDENCIES)
$(LINK) $(loki97_la_LDFLAGS) $(loki97_la_OBJECTS) $(loki97_la_LIBADD) $(LIBS)
panama.la: $(panama_la_OBJECTS) $(panama_la_DEPENDENCIES)
$(LINK) $(panama_la_LDFLAGS) $(panama_la_OBJECTS) $(panama_la_LIBADD) $(LIBS)
rc2.la: $(rc2_la_OBJECTS) $(rc2_la_DEPENDENCIES)
$(LINK) $(rc2_la_LDFLAGS) $(rc2_la_OBJECTS) $(rc2_la_LIBADD) $(LIBS)
rijndael-128.la: $(rijndael_128_la_OBJECTS) $(rijndael_128_la_DEPENDENCIES)
$(LINK) $(rijndael_128_la_LDFLAGS) $(rijndael_128_la_OBJECTS) $(rijndael_128_la_LIBADD) $(LIBS)
rijndael-192.la: $(rijndael_192_la_OBJECTS) $(rijndael_192_la_DEPENDENCIES)
$(LINK) $(rijndael_192_la_LDFLAGS) $(rijndael_192_la_OBJECTS) $(rijndael_192_la_LIBADD) $(LIBS)
rijndael-256.la: $(rijndael_256_la_OBJECTS) $(rijndael_256_la_DEPENDENCIES)
$(LINK) $(rijndael_256_la_LDFLAGS) $(rijndael_256_la_OBJECTS) $(rijndael_256_la_LIBADD) $(LIBS)
safer-sk128.la: $(safer_sk128_la_OBJECTS) $(safer_sk128_la_DEPENDENCIES)
$(LINK) $(safer_sk128_la_LDFLAGS) $(safer_sk128_la_OBJECTS) $(safer_sk128_la_LIBADD) $(LIBS)
safer-sk64.la: $(safer_sk64_la_OBJECTS) $(safer_sk64_la_DEPENDENCIES)
$(LINK) $(safer_sk64_la_LDFLAGS) $(safer_sk64_la_OBJECTS) $(safer_sk64_la_LIBADD) $(LIBS)
saferplus.la: $(saferplus_la_OBJECTS) $(saferplus_la_DEPENDENCIES)
$(LINK) $(saferplus_la_LDFLAGS) $(saferplus_la_OBJECTS) $(saferplus_la_LIBADD) $(LIBS)
serpent.la: $(serpent_la_OBJECTS) $(serpent_la_DEPENDENCIES)
$(LINK) $(serpent_la_LDFLAGS) $(serpent_la_OBJECTS) $(serpent_la_LIBADD) $(LIBS)
threeway.la: $(threeway_la_OBJECTS) $(threeway_la_DEPENDENCIES)
$(LINK) $(threeway_la_LDFLAGS) $(threeway_la_OBJECTS) $(threeway_la_LIBADD) $(LIBS)
tripledes.la: $(tripledes_la_OBJECTS) $(tripledes_la_DEPENDENCIES)
$(LINK) $(tripledes_la_LDFLAGS) $(tripledes_la_OBJECTS) $(tripledes_la_LIBADD) $(LIBS)
twofish.la: $(twofish_la_OBJECTS) $(twofish_la_DEPENDENCIES)
$(LINK) $(twofish_la_LDFLAGS) $(twofish_la_OBJECTS) $(twofish_la_LIBADD) $(LIBS)
wake.la: $(wake_la_OBJECTS) $(wake_la_DEPENDENCIES)
$(LINK) $(wake_la_LDFLAGS) $(wake_la_OBJECTS) $(wake_la_LIBADD) $(LIBS)
xtea.la: $(xtea_la_OBJECTS) $(xtea_la_DEPENDENCIES)
$(LINK) $(xtea_la_LDFLAGS) $(xtea_la_OBJECTS) $(xtea_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/3-way.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arcfour.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish-compat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast-128.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast-256.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enigma.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gost.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loki97.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/panama.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rc2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-128.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-192.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-256.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safer128.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safer64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saferplus.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tripledes.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wake.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtea.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCC_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCC_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.c.lo:
@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCC_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(pkglibdir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
clean-pkglibLTLIBRARIES mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am: install-pkglibLTLIBRARIES
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-pkglibLTLIBRARIES
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES \
ctags distclean distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-pkglibLTLIBRARIES \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool pdf \
pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am \
uninstall-pkglibLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
@@ -0,0 +1,219 @@
/*
* Copyright (C) 1998,1999,2000,2001 Nikos Mavroyanopoulos
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <lib/libdefs.h>
#include <lib/mcrypt_modules.h>
#include <stdlib.h>
#include "arcfour.h"
#define _mcrypt_set_key arcfour_LTX__mcrypt_set_key
#define _mcrypt_encrypt arcfour_LTX__mcrypt_encrypt
#define _mcrypt_decrypt arcfour_LTX__mcrypt_decrypt
#define _mcrypt_get_size arcfour_LTX__mcrypt_get_size
#define _mcrypt_get_block_size arcfour_LTX__mcrypt_get_block_size
#define _is_block_algorithm arcfour_LTX__is_block_algorithm
#define _mcrypt_get_key_size arcfour_LTX__mcrypt_get_key_size
#define _mcrypt_get_algo_iv_size arcfour_LTX__mcrypt_get_algo_iv_size
#define _mcrypt_get_supported_key_sizes arcfour_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name arcfour_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test arcfour_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version arcfour_LTX__mcrypt_algorithm_version
#define swap_byte(x,y) tmp = (x); (x) = (y); (y) = tmp
/* #define USE_IV */
/* IV was an mcrypt extension */
void _mcrypt_encrypt(arcfour_key * key, byte * buffer_ptr, int buffer_len);
/* key is the state that should be allocated by the caller */
#define STATE key->state
#define I key->i
#define J key->j
WIN32DLL_DEFINE
int _mcrypt_set_key(arcfour_key * key, byte * key_data, int key_len,
char *IV, int iv_len)
{
register int tmp, j, i;
byte *state = STATE;
int ivindex;
for (i = 0; i < 256; i++)
state[i] = i;
I = 0;
J = 0;
ivindex = 0;
for (j = i = 0; i < 256; i++) {
j += state[i] + key_data[i % key_len];
#ifdef USE_IV
if (iv_len > 0 && IV != NULL)
j += IV[ivindex];
#endif
j &= 0xff;
swap_byte(state[i], state[j]);
#ifdef USE_IV
if (iv_len > 0)
ivindex = (ivindex + 1) % iv_len;
#endif
}
return 0;
}
WIN32DLL_DEFINE
void _mcrypt_encrypt(arcfour_key * key, byte * buffer_ptr,
int buffer_len)
{
register int tmp;
register int counter;
register int i = I, j = J;
byte *state = STATE;
for (counter = 0; counter < buffer_len; counter++) {
i++;
i &= 0xff;
j += state[i];
j &= 0xff;
/* swap state[i] and state[j] */
swap_byte(state[i], state[j]);
buffer_ptr[counter] ^= state[(state[i] + tmp) & 0xff];
}
J = j;
I = i;
}
/* this is the same with mcrypt_encrypt */
WIN32DLL_DEFINE
void _mcrypt_decrypt(arcfour_key * key, byte * buffer_ptr,
int buffer_len)
{
_mcrypt_encrypt(key, buffer_ptr, buffer_len);
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(arcfour_key);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_algo_iv_size()
{
#ifdef USE_IV
return 32;
#else
return 0;
#endif
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 0;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 256;
}
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = 0;
return NULL;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "RC4";
}
#define CIPHER "3abaa03a286e24c4196d292ab72934d6854c3eee"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[20];
unsigned char ciphertext[20];
int blocksize = 20, j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size(),
NULL, 0);
_mcrypt_encrypt(key, (void *) ciphertext, blocksize);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(keyword);
free(key);
return -1;
}
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size(),
NULL, 0);
_mcrypt_decrypt(key, (void *) ciphertext, blocksize);
free(keyword);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20020610;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,7 @@
typedef struct arcfour_key
{
byte state[256];
byte i;
byte j;
} arcfour_key;
@@ -0,0 +1,666 @@
/* The blowfish algorithm
* As described in the Schneier's book. Minor changes only
* Changed to conform to the "new" blowfish posted in 30 Oct 1994
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: blowfish-compat.c,v 1.11 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "blowfish.h"
#define _mcrypt_set_key blowfish_compat_LTX__mcrypt_set_key
#define _mcrypt_encrypt blowfish_compat_LTX__mcrypt_encrypt
#define _mcrypt_decrypt blowfish_compat_LTX__mcrypt_decrypt
#define _mcrypt_get_size blowfish_compat_LTX__mcrypt_get_size
#define _mcrypt_get_block_size blowfish_compat_LTX__mcrypt_get_block_size
#define _is_block_algorithm blowfish_compat_LTX__is_block_algorithm
#define _mcrypt_get_key_size blowfish_compat_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes blowfish_compat_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name blowfish_compat_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test blowfish_compat_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version blowfish_compat_LTX__mcrypt_algorithm_version
/*
typedef struct {
word32 S[4][256],P[18];
} blf_ctx;
*/
#define MAXKEYBYTES 56 /* 448 bits */
#define BF_N 16
#define KEYBYTES 8
#define F(bc, x) ( ((bc->S[0][(x >> 24) & 0xff] + bc->S[1][(x >> 16) & 0xff]) ^ bc->S[2][(x >> 8) & 0xff]) + bc->S[3][x & 0xff] )
/* x should be a 64 bit integer */
WIN32DLL_DEFINE void _mcrypt_encrypt(blf_ctx * c, word32 * x)
{
word32 Xl;
word32 Xr, temp;
short i;
#ifndef WORDS_BIGENDIAN
Xl = x[0];
Xr = x[1];
#else
Xl = byteswap32(x[0]);
Xr = byteswap32(x[1]);
#endif
for (i = 0; i < BF_N; ++i) {
Xl ^= c->P[i];
Xr ^= F(c, Xl);
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr ^= c->P[BF_N];
Xl ^= c->P[BF_N + 1];
#ifndef WORDS_BIGENDIAN
x[0] = Xl;
x[1] = Xr;
#else
x[0] = byteswap32(Xl);
x[1] = byteswap32(Xr);
#endif
}
/* x should be a 64 bit integer */
static void enblf_noswap(blf_ctx * c, word32 * x)
{ /* Used internally */
word32 Xl;
word32 Xr, temp;
short i;
Xl = x[0];
Xr = x[1];
for (i = 0; i < BF_N; ++i) {
Xl ^= c->P[i];
Xr ^= F(c, Xl);
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr ^= c->P[BF_N];
Xl ^= c->P[BF_N + 1];
x[0] = Xl;
x[1] = Xr;
}
WIN32DLL_DEFINE void _mcrypt_decrypt(blf_ctx * c, word32 * x)
{
word32 Xl, Xr, temp;
short i;
#ifndef WORDS_BIGENDIAN
Xl = x[0];
Xr = x[1];
#else
Xl = byteswap32(x[0]);
Xr = byteswap32(x[1]);
#endif
for (i = BF_N + 1; i > 1; --i) {
Xl ^= c->P[i];
Xr ^= F(c, Xl);
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr ^= c->P[1];
Xl ^= c->P[0];
#ifndef WORDS_BIGENDIAN
x[0] = Xl;
x[1] = Xr;
#else
x[0] = byteswap32(Xl);
x[1] = byteswap32(Xr);
#endif
}
static short initialize_blowfish(blf_ctx * c, byte key[], short keybytes)
{
short i, j;
word32 data, datarl[2];
word32 ks0[] = {
0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L,
0xb8e1afedL, 0x6a267e96L,
0xba7c9045L, 0xf12c7f99L, 0x24a19947L, 0xb3916cf7L,
0x0801f2e2L, 0x858efc16L,
0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL,
0x0d95748fL, 0x728eb658L,
0x718bcd58L, 0x82154aeeL, 0x7b54a41dL, 0xc25a59b5L,
0x9c30d539L, 0x2af26013L,
0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL,
0x8e79dcb0L, 0x603a180eL,
0x6c9e0e8bL, 0xb01e8a3eL, 0xd71577c1L, 0xbd314b27L,
0x78af2fdaL, 0x55605c60L,
0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L,
0x55ca396aL, 0x2aab10b6L,
0xb4cc5c34L, 0x1141e8ceL, 0xa15486afL, 0x7c72e993L,
0xb3ee1411L, 0x636fbc2aL,
0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL,
0xafd6ba33L, 0x6c24cf5cL,
0x7a325381L, 0x28958677L, 0x3b8f4898L, 0x6b4bb9afL,
0xc4bfe81bL, 0x66282193L,
0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L,
0xef845d5dL, 0xe98575b1L,
0xdc262302L, 0xeb651b88L, 0x23893e81L, 0xd396acc5L,
0x0f6d6ff3L, 0x83f44239L,
0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL,
0x21c66842L, 0xf6e96c9aL,
0x670c9c61L, 0xabd388f0L, 0x6a51a0d2L, 0xd8542f68L,
0x960fa728L, 0xab5133a3L,
0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L,
0xa1f1651dL, 0x39af0176L,
0x66ca593eL, 0x82430e88L, 0x8cee8619L, 0x456f9fb4L,
0x7d84a5c3L, 0x3b8b5ebeL,
0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L,
0x4ed3aa62L, 0x363f7706L,
0x1bfedf72L, 0x429b023dL, 0x37d0d724L, 0xd00a1248L,
0xdb0fead3L, 0x49f1c09bL,
0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L,
0xe3fe501aL, 0xb6794c3bL,
0x976ce0bdL, 0x04c006baL, 0xc1a94fb6L, 0x409f60c4L,
0x5e5c9ec2L, 0x196a2463L,
0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL,
0x6dfc511fL, 0x9b30952cL,
0xcc814544L, 0xaf5ebd09L, 0xbee3d004L, 0xde334afdL,
0x660f2807L, 0x192e4bb3L,
0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL,
0x5579c0bdL, 0x1a60320aL,
0xd6a100c6L, 0x402c7279L, 0x679f25feL, 0xfb1fa3ccL,
0x8ea5e9f8L, 0xdb3222f8L,
0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL,
0x323db5faL, 0xfd238760L,
0x53317b48L, 0x3e00df82L, 0x9e5c57bbL, 0xca6f8ca0L,
0x1a87562eL, 0xdf1769dbL,
0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L,
0x695b27b0L, 0xbbca58c8L,
0xe1ffa35dL, 0xb8f011a0L, 0x10fa3d98L, 0xfd2183b8L,
0x4afcb56cL, 0x2dd1d35bL,
0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L,
0xe1ddf2daL, 0xa4cb7e33L,
0x62fb1341L, 0xcee4c6e8L, 0xef20cadaL, 0x36774c01L,
0xd07e9efeL, 0x2bf11fb4L,
0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L,
0xd08ed1d0L, 0xafc725e0L,
0x8e3c5b2fL, 0x8e7594b7L, 0x8ff6e2fbL, 0xf2122b64L,
0x8888b812L, 0x900df01cL,
0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL,
0x2f2f2218L, 0xbe0e1777L,
0xea752dfeL, 0x8b021fa1L, 0xe5a0cc0fL, 0xb56f74e8L,
0x18acf3d6L, 0xce89e299L,
0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L,
0x165fa266L, 0x80957705L,
0x93cc7314L, 0x211a1477L, 0xe6ad2065L, 0x77b5fa86L,
0xc75442f5L, 0xfb9d35cfL,
0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L,
0x00250e2dL, 0x2071b35eL,
0x226800bbL, 0x57b8e0afL, 0x2464369bL, 0xf009b91eL,
0x5563911dL, 0x59dfa6aaL,
0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L,
0x83260376L, 0x6295cfa9L,
0x11c81968L, 0x4e734a41L, 0xb3472dcaL, 0x7b14a94aL,
0x1b510052L, 0x9a532915L,
0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L,
0x08ba6fb5L, 0x571be91fL,
0xf296ec6bL, 0x2a0dd915L, 0xb6636521L, 0xe7b9f9b6L,
0xff34052eL, 0xc5855664L,
0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL
};
word32 ks1[] = {
0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L,
0xad6ea6b0L, 0x49a7df7dL,
0x9cee60b8L, 0x8fedb266L, 0xecaa8c71L, 0x699a17ffL,
0x5664526cL, 0xc2b19ee1L,
0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL,
0x3f54989aL, 0x5b429d65L,
0x6b8fe4d6L, 0x99f73fd6L, 0xa1d29c07L, 0xefe830f5L,
0x4d2d38e6L, 0xf0255dc1L,
0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL,
0x09686b3fL, 0x3ebaefc9L,
0x3c971814L, 0x6b6a70a1L, 0x687f3584L, 0x52a0e286L,
0xb79c5305L, 0xaa500737L,
0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L,
0xb03ada37L, 0xf0500c0dL,
0xf01c1f04L, 0x0200b3ffL, 0xae0cf51aL, 0x3cb574b2L,
0x25837a58L, 0xdc0921bdL,
0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L,
0x3ae5e581L, 0x37c2dadcL,
0xc8b57634L, 0x9af3dda7L, 0xa9446146L, 0x0fd0030eL,
0xecc8c73eL, 0xa4751e41L,
0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L,
0x4e548b38L, 0x4f6db908L,
0x6f420d03L, 0xf60a04bfL, 0x2cb81290L, 0x24977c79L,
0x5679b072L, 0xbcaf89afL,
0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL,
0x5512721fL, 0x2e6b7124L,
0x501adde6L, 0x9f84cd87L, 0x7a584718L, 0x7408da17L,
0xbc9f9abcL, 0xe94b7d8cL,
0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L,
0xef1c1847L, 0x3215d908L,
0xdd433b37L, 0x24c2ba16L, 0x12a14d43L, 0x2a65c451L,
0x50940002L, 0x133ae4ddL,
0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL,
0x043556f1L, 0xd7a3c76bL,
0x3c11183bL, 0x5924a509L, 0xf28fe6edL, 0x97f1fbfaL,
0x9ebabf2cL, 0x1e153c6eL,
0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L,
0x771fe71cL, 0x4e3d06faL,
0x2965dcb9L, 0x99e71d0fL, 0x803e89d6L, 0x5266c825L,
0x2e4cc978L, 0x9c10b36aL,
0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L,
0xf2f74ea7L, 0x361d2b3dL,
0x1939260fL, 0x19c27960L, 0x5223a708L, 0xf71312b6L,
0xebadfe6eL, 0xeac31f66L,
0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L,
0xc332ddefL, 0xbe6c5aa5L,
0x65582185L, 0x68ab9802L, 0xeecea50fL, 0xdb2f953bL,
0x2aef7dadL, 0x5b6e2f84L,
0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L,
0x13cca830L, 0xeb61bd96L,
0x0334fe1eL, 0xaa0363cfL, 0xb5735c90L, 0x4c70a239L,
0xd59e9e0bL, 0xcbaade14L,
0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL,
0x648b1eafL, 0x19bdf0caL,
0xa02369b9L, 0x655abb50L, 0x40685a32L, 0x3c2ab4b3L,
0x319ee9d5L, 0xc021b8f7L,
0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L,
0xf837889aL, 0x97e32d77L,
0x11ed935fL, 0x16681281L, 0x0e358829L, 0xc7e61fd6L,
0x96dedfa1L, 0x7858ba99L,
0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L,
0xcdb30aebL, 0x532e3054L,
0x8fd948e4L, 0x6dbc3128L, 0x58ebf2efL, 0x34c6ffeaL,
0xfe28ed61L, 0xee7c3c73L,
0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L,
0x45eee2b6L, 0xa3aaabeaL,
0xdb6c4f15L, 0xfacb4fd0L, 0xc742f442L, 0xef6abbb5L,
0x654f3b1dL, 0x41cd2105L,
0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L,
0xcf62a1f2L, 0x5b8d2646L,
0xfc8883a0L, 0xc1c7b6a3L, 0x7f1524c3L, 0x69cb7492L,
0x47848a0bL, 0x5692b285L,
0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L,
0x58428d2aL, 0x0c55f5eaL,
0x1dadf43eL, 0x233f7061L, 0x3372f092L, 0x8d937e41L,
0xd65fecf1L, 0x6c223bdbL,
0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL,
0xa6078084L, 0x19f8509eL,
0xe8efd855L, 0x61d99735L, 0xa969a7aaL, 0xc50c06c2L,
0x5a04abfcL, 0x800bcadcL,
0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L,
0xdb73dbd3L, 0x105588cdL,
0x675fda79L, 0xe3674340L, 0xc5c43465L, 0x713e38d8L,
0x3d28f89eL, 0xf16dff20L,
0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L
};
word32 ks2[] = {
0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L,
0x411520f7L, 0x7602d4f7L,
0xbcf46b2eL, 0xd4a20068L, 0xd4082471L, 0x3320f46aL,
0x43b7d4b7L, 0x500061afL,
0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L,
0x4d95fc1dL, 0x96b591afL,
0x70f4ddd3L, 0x66a02f45L, 0xbfbc09ecL, 0x03bd9785L,
0x7fac6dd0L, 0x31cb8504L,
0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL,
0x28507825L, 0x530429f4L,
0x0a2c86daL, 0xe9b66dfbL, 0x68dc1462L, 0xd7486900L,
0x680ec0a4L, 0x27a18deeL,
0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L,
0xaace1e7cL, 0xd3375fecL,
0xce78a399L, 0x406b2a42L, 0x20fe9e35L, 0xd9f385b9L,
0xee39d7abL, 0x3b124e8bL,
0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L,
0x3a6efa74L, 0xdd5b4332L,
0x6841e7f7L, 0xca7820fbL, 0xfb0af54eL, 0xd8feb397L,
0x454056acL, 0xba489527L,
0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL,
0x55a867bcL, 0xa1159a58L,
0xcca92963L, 0x99e1db33L, 0xa62a4a56L, 0x3f3125f9L,
0x5ef47e1cL, 0x9029317cL,
0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L,
0x95c11548L, 0xe4c66d22L,
0x48c1133fL, 0xc70f86dcL, 0x07f9c9eeL, 0x41041f0fL,
0x404779a4L, 0x5d886e17L,
0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L,
0x257b7834L, 0x602a9c60L,
0xdff8e8a3L, 0x1f636c1bL, 0x0e12b4c2L, 0x02e1329eL,
0xaf664fd1L, 0xcad18115L,
0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L,
0x85b2a20eL, 0xe6ba0d99L,
0xde720c8cL, 0x2da2f728L, 0xd0127845L, 0x95b794fdL,
0x647d0862L, 0xe7ccf5f0L,
0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL,
0x0a476341L, 0x992eff74L,
0x3a6f6eabL, 0xf4f8fd37L, 0xa812dc60L, 0xa1ebddf8L,
0x991be14cL, 0xdb6e6b0dL,
0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L,
0xf1290dc7L, 0xcc00ffa3L,
0xb5390f92L, 0x690fed0bL, 0x667b9ffbL, 0xcedb7d9cL,
0xa091cf0bL, 0xd9155ea3L,
0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL,
0x37392eb3L, 0xcc115979L,
0x8026e297L, 0xf42e312dL, 0x6842ada7L, 0xc66a2b3bL,
0x12754cccL, 0x782ef11cL,
0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L,
0x1a6b1018L, 0x11caedfaL,
0x3d25bdd8L, 0xe2e1c3c9L, 0x44421659L, 0x0a121386L,
0xd90cec6eL, 0xd5abea2aL,
0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL,
0x9dbc8057L, 0xf0f7c086L,
0x60787bf8L, 0x6003604dL, 0xd1fd8346L, 0xf6381fb0L,
0x7745ae04L, 0xd736fcccL,
0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL,
0x77a057beL, 0xbde8ae24L,
0x55464299L, 0xbf582e61L, 0x4e58f48fL, 0xf2ddfda2L,
0xf474ef38L, 0x8789bdc2L,
0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L,
0x7aeb2661L, 0x8b1ddf84L,
0x846a0e79L, 0x915f95e2L, 0x466e598eL, 0x20b45770L,
0x8cd55591L, 0xc902de4cL,
0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL,
0xb77f19b6L, 0xe0a9dc09L,
0x662d09a1L, 0xc4324633L, 0xe85a1f02L, 0x09f0be8cL,
0x4a99a025L, 0x1d6efe10L,
0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L,
0xdcb7da83L, 0x573906feL,
0xa1e2ce9bL, 0x4fcd7f52L, 0x50115e01L, 0xa70683faL,
0xa002b5c4L, 0x0de6d027L,
0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L,
0xf0177a28L, 0xc0f586e0L,
0x006058aaL, 0x30dc7d62L, 0x11e69ed7L, 0x2338ea63L,
0x53c2dd94L, 0xc2c21634L,
0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L,
0x6f05e409L, 0x4b7c0188L,
0x39720a3dL, 0x7c927c24L, 0x86e3725fL, 0x724d9db9L,
0x1ac15bb4L, 0xd39eb8fcL,
0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L,
0x1e50ef5eL, 0xb161e6f8L,
0xa28514d9L, 0x6c51133cL, 0x6fd5c7e7L, 0x56e14ec4L,
0x362abfceL, 0xddc6c837L,
0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L
};
word32 ks3[] = {
0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL,
0x5cb0679eL, 0x4fa33742L,
0xd3822740L, 0x99bc9bbeL, 0xd5118e9dL, 0xbf0f7315L,
0xd62d1c7eL, 0xc700c47bL,
0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L,
0x5748ab2fL, 0xbc946e79L,
0xc6a376d2L, 0x6549c2c8L, 0x530ff8eeL, 0x468dde7dL,
0xd5730a1dL, 0x4cd04dc6L,
0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L,
0xa1fad5f0L, 0x6a2d519aL,
0x63ef8ce2L, 0x9a86ee22L, 0xc089c2b8L, 0x43242ef6L,
0xa51e03aaL, 0x9cf2d0a4L,
0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L,
0x2826a2f9L, 0xa73a3ae1L,
0x4ba99586L, 0xef5562e9L, 0xc72fefd3L, 0xf752f7daL,
0x3f046f69L, 0x77fa0a59L,
0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L,
0xe990fd5aL, 0x9e34d797L,
0x2cf0b7d9L, 0x022b8b51L, 0x96d5ac3aL, 0x017da67dL,
0xd1cf3ed6L, 0x7c7d2d28L,
0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL,
0xe029ac71L, 0xe019a5e6L,
0x47b0acfdL, 0xed93fa9bL, 0xe8d3c48dL, 0x283b57ccL,
0xf8d56629L, 0x79132e28L,
0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL,
0x15056dd4L, 0x88f46dbaL,
0x03a16125L, 0x0564f0bdL, 0xc3eb9e15L, 0x3c9057a2L,
0x97271aecL, 0xa93a072aL,
0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L,
0x7533d928L, 0xb155fdf5L,
0x03563482L, 0x8aba3cbbL, 0x28517711L, 0xc20ad9f8L,
0xabcc5167L, 0xccad925fL,
0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L,
0xea7a90c2L, 0xfb3e7bceL,
0x5121ce64L, 0x774fbe32L, 0xa8b6e37eL, 0xc3293d46L,
0x48de5369L, 0x6413e680L,
0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L,
0xb39a460aL, 0x6445c0ddL,
0x586cdecfL, 0x1c20c8aeL, 0x5bbef7ddL, 0x1b588d40L,
0xccd2017fL, 0x6bb4e3bbL,
0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L,
0x72eacea8L, 0xfa6484bbL,
0x8d6612aeL, 0xbf3c6f47L, 0xd29be463L, 0x542f5d9eL,
0xaec2771bL, 0xf64e6370L,
0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL,
0x4040cb08L, 0x4eb4e2ccL,
0x34d2466aL, 0x0115af84L, 0xe1b00428L, 0x95983a1dL,
0x06b89fb4L, 0xce6ea048L,
0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L,
0x611560b1L, 0xe7933fdcL,
0xbb3a792bL, 0x344525bdL, 0xa08839e1L, 0x51ce794bL,
0x2f32c9b7L, 0xa01fbac9L,
0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L,
0x1a908749L, 0xd44fbd9aL,
0xd0dadecbL, 0xd50ada38L, 0x0339c32aL, 0xc6913667L,
0x8df9317cL, 0xe0b12b4fL,
0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL,
0xbf97222cL, 0x15e6fc2aL,
0x0f91fc71L, 0x9b941525L, 0xfae59361L, 0xceb69cebL,
0xc2a86459L, 0x12baa8d1L,
0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L,
0xe0ec6e0eL, 0x1698db3bL,
0x4c98a0beL, 0x3278e964L, 0x9f1f9532L, 0xe0d392dfL,
0xd3a0342bL, 0x8971f21eL,
0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L,
0xdf359f8dL, 0x9b992f2eL,
0xe60b6f47L, 0x0fe3f11dL, 0xe54cda54L, 0x1edad891L,
0xce6279cfL, 0xcd3e7e6fL,
0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L,
0xf523f357L, 0xa6327623L,
0x93a83531L, 0x56cccd02L, 0xacf08162L, 0x5a75ebb5L,
0x6e163697L, 0x88d273ccL,
0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L,
0xe6c6c7bdL, 0x327a140aL,
0x45e1d006L, 0xc3f27b9aL, 0xc9aa53fdL, 0x62a80f00L,
0xbb25bfe2L, 0x35bdd2f6L,
0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL,
0x53113ec0L, 0x1640e3d3L,
0x38abbd60L, 0x2547adf0L, 0xba38209cL, 0xf746ce76L,
0x77afa1c5L, 0x20756060L,
0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL,
0x1948c25cL, 0x02fb8a8cL,
0x01c36ae4L, 0xd6ebe1f9L, 0x90d4f869L, 0xa65cdea0L,
0x3f09252dL, 0xc208e69fL,
0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L
};
word32 pi[] = {
0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L,
0xa4093822L, 0x299f31d0L,
0x082efa98L, 0xec4e6c89L, 0x452821e6L, 0x38d01377L,
0xbe5466cfL, 0x34e90c6cL,
0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L,
0x9216d5d9L, 0x8979fb1bL
};
/* Initialize s-boxes without file read. */
for (i = 0; i < 256; i++) {
c->S[0][i] = ks0[i];
c->S[1][i] = ks1[i];
c->S[2][i] = ks2[i];
c->S[3][i] = ks3[i];
}
/* P-boxes */
for (i = 0; i < 18; i++) {
c->P[i] = pi[i];
}
j = 0;
for (i = 0; i < BF_N + 2; ++i) {
data = 0x00000000;
data = (data << 8) | key[(j) % keybytes];
data = (data << 8) | key[(j + 1) % keybytes];
data = (data << 8) | key[(j + 2) % keybytes];
data = (data << 8) | key[(j + 3) % keybytes];
c->P[i] ^= data;
j = (j + 4) % keybytes;
}
datarl[0] = 0x000000000;
datarl[1] = 0x000000000;
for (i = 0; i < BF_N + 2; i += 2) {
enblf_noswap(c, datarl);
c->P[i] = datarl[0];
c->P[i + 1] = datarl[1];
}
for (i = 0; i < 4; ++i) {
for (j = 0; j < 256; j += 2) {
enblf_noswap(c, datarl);
c->S[i][j] = datarl[0];
c->S[i][j + 1] = datarl[1];
}
}
return 0;
}
WIN32DLL_DEFINE int _mcrypt_set_key(blf_ctx * c, char *k, int len)
{
initialize_blowfish(c, k, len);
return 0;
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(blf_ctx);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 56;
}
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = 0;
return NULL;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "Blowfish";
}
#define CIPHER "de8e9a3a9cd44280"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,575 @@
/* The blowfish algorithm
* As described in the Schneier's book. Minor changes only
* Changed to conform to the "new" blowfish posted in 30 Oct 1994
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: blowfish.c,v 1.22 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "blowfish.h"
#define _mcrypt_set_key blowfish_LTX__mcrypt_set_key
#define _mcrypt_encrypt blowfish_LTX__mcrypt_encrypt
#define _mcrypt_decrypt blowfish_LTX__mcrypt_decrypt
#define _mcrypt_get_size blowfish_LTX__mcrypt_get_size
#define _mcrypt_get_block_size blowfish_LTX__mcrypt_get_block_size
#define _is_block_algorithm blowfish_LTX__is_block_algorithm
#define _mcrypt_get_key_size blowfish_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes blowfish_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name blowfish_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test blowfish_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version blowfish_LTX__mcrypt_algorithm_version
#define MAXKEYBYTES 56 /* 448 bits */
#define BF_N 16
#define KEYBYTES 8
#define F(bc, x) ( ((bc->S[0][(x >> 24) & 0xff] + bc->S[1][(x >> 16) & 0xff]) ^ bc->S[2][(x >> 8) & 0xff]) + bc->S[3][x & 0xff] )
/* x should be a 64 bit integer */
WIN32DLL_DEFINE void _mcrypt_encrypt(blf_ctx * c, word32 * x)
{
register word32 Xl;
register word32 Xr, temp;
short i;
#ifdef WORDS_BIGENDIAN
Xl = x[0];
Xr = x[1];
#else
Xl = byteswap32(x[0]);
Xr = byteswap32(x[1]);
#endif
for (i = 0; i < BF_N; ++i) {
Xl ^= c->P[i];
Xr ^= F(c, Xl);
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr ^= c->P[BF_N];
Xl ^= c->P[BF_N + 1];
#ifdef WORDS_BIGENDIAN
x[0] = Xl;
x[1] = Xr;
#else
x[0] = byteswap32(Xl);
x[1] = byteswap32(Xr);
#endif
}
/* x should be a 64 bit integer */
static void enblf_noswap(blf_ctx * c, word32 * x)
{ /* Used internally */
register word32 Xl;
register word32 Xr, temp;
short i;
Xl = x[0];
Xr = x[1];
for (i = 0; i < BF_N; ++i) {
Xl ^= c->P[i];
Xr ^= F(c, Xl);
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr ^= c->P[BF_N];
Xl ^= c->P[BF_N + 1];
x[0] = Xl;
x[1] = Xr;
}
WIN32DLL_DEFINE void _mcrypt_decrypt(blf_ctx * c, word32 * x)
{
register word32 Xl, Xr, temp;
register short i;
#ifdef WORDS_BIGENDIAN
Xl = x[0];
Xr = x[1];
#else
Xl = byteswap32(x[0]);
Xr = byteswap32(x[1]);
#endif
for (i = BF_N + 1; i > 1; --i) {
Xl ^= c->P[i];
Xr ^= F(c, Xl);
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr ^= c->P[1];
Xl ^= c->P[0];
#ifdef WORDS_BIGENDIAN
x[0] = Xl;
x[1] = Xr;
#else
x[0] = byteswap32(Xl);
x[1] = byteswap32(Xr);
#endif
}
static const word32 ks0[] = {
0xd1310ba6UL, 0x98dfb5acUL, 0x2ffd72dbUL, 0xd01adfb7UL,
0xb8e1afedUL, 0x6a267e96UL, 0xba7c9045UL, 0xf12c7f99UL,
0x24a19947UL, 0xb3916cf7UL, 0x0801f2e2UL, 0x858efc16UL,
0x636920d8UL, 0x71574e69UL, 0xa458fea3UL, 0xf4933d7eUL,
0x0d95748fUL, 0x728eb658UL, 0x718bcd58UL, 0x82154aeeUL,
0x7b54a41dUL, 0xc25a59b5UL, 0x9c30d539UL, 0x2af26013UL,
0xc5d1b023UL, 0x286085f0UL, 0xca417918UL, 0xb8db38efUL,
0x8e79dcb0UL, 0x603a180eUL, 0x6c9e0e8bUL, 0xb01e8a3eUL,
0xd71577c1UL, 0xbd314b27UL, 0x78af2fdaUL, 0x55605c60UL,
0xe65525f3UL, 0xaa55ab94UL, 0x57489862UL, 0x63e81440UL,
0x55ca396aUL, 0x2aab10b6UL, 0xb4cc5c34UL, 0x1141e8ceUL,
0xa15486afUL, 0x7c72e993UL, 0xb3ee1411UL, 0x636fbc2aUL,
0x2ba9c55dUL, 0x741831f6UL, 0xce5c3e16UL, 0x9b87931eUL,
0xafd6ba33UL, 0x6c24cf5cUL, 0x7a325381UL, 0x28958677UL,
0x3b8f4898UL, 0x6b4bb9afUL, 0xc4bfe81bUL, 0x66282193UL,
0x61d809ccUL, 0xfb21a991UL, 0x487cac60UL, 0x5dec8032UL,
0xef845d5dUL, 0xe98575b1UL, 0xdc262302UL, 0xeb651b88UL,
0x23893e81UL, 0xd396acc5UL, 0x0f6d6ff3UL, 0x83f44239UL,
0x2e0b4482UL, 0xa4842004UL, 0x69c8f04aUL, 0x9e1f9b5eUL,
0x21c66842UL, 0xf6e96c9aUL, 0x670c9c61UL, 0xabd388f0UL,
0x6a51a0d2UL, 0xd8542f68UL, 0x960fa728UL, 0xab5133a3UL,
0x6eef0b6cUL, 0x137a3be4UL, 0xba3bf050UL, 0x7efb2a98UL,
0xa1f1651dUL, 0x39af0176UL, 0x66ca593eUL, 0x82430e88UL,
0x8cee8619UL, 0x456f9fb4UL, 0x7d84a5c3UL, 0x3b8b5ebeUL,
0xe06f75d8UL, 0x85c12073UL, 0x401a449fUL, 0x56c16aa6UL,
0x4ed3aa62UL, 0x363f7706UL, 0x1bfedf72UL, 0x429b023dUL,
0x37d0d724UL, 0xd00a1248UL, 0xdb0fead3UL, 0x49f1c09bUL,
0x075372c9UL, 0x80991b7bUL, 0x25d479d8UL, 0xf6e8def7UL,
0xe3fe501aUL, 0xb6794c3bUL, 0x976ce0bdUL, 0x04c006baUL,
0xc1a94fb6UL, 0x409f60c4UL, 0x5e5c9ec2UL, 0x196a2463UL,
0x68fb6fafUL, 0x3e6c53b5UL, 0x1339b2ebUL, 0x3b52ec6fUL,
0x6dfc511fUL, 0x9b30952cUL, 0xcc814544UL, 0xaf5ebd09UL,
0xbee3d004UL, 0xde334afdUL, 0x660f2807UL, 0x192e4bb3UL,
0xc0cba857UL, 0x45c8740fUL, 0xd20b5f39UL, 0xb9d3fbdbUL,
0x5579c0bdUL, 0x1a60320aUL, 0xd6a100c6UL, 0x402c7279UL,
0x679f25feUL, 0xfb1fa3ccUL, 0x8ea5e9f8UL, 0xdb3222f8UL,
0x3c7516dfUL, 0xfd616b15UL, 0x2f501ec8UL, 0xad0552abUL,
0x323db5faUL, 0xfd238760UL, 0x53317b48UL, 0x3e00df82UL,
0x9e5c57bbUL, 0xca6f8ca0UL, 0x1a87562eUL, 0xdf1769dbUL,
0xd542a8f6UL, 0x287effc3UL, 0xac6732c6UL, 0x8c4f5573UL,
0x695b27b0UL, 0xbbca58c8UL, 0xe1ffa35dUL, 0xb8f011a0UL,
0x10fa3d98UL, 0xfd2183b8UL, 0x4afcb56cUL, 0x2dd1d35bUL,
0x9a53e479UL, 0xb6f84565UL, 0xd28e49bcUL, 0x4bfb9790UL,
0xe1ddf2daUL, 0xa4cb7e33UL, 0x62fb1341UL, 0xcee4c6e8UL,
0xef20cadaUL, 0x36774c01UL, 0xd07e9efeUL, 0x2bf11fb4UL,
0x95dbda4dUL, 0xae909198UL, 0xeaad8e71UL, 0x6b93d5a0UL,
0xd08ed1d0UL, 0xafc725e0UL, 0x8e3c5b2fUL, 0x8e7594b7UL,
0x8ff6e2fbUL, 0xf2122b64UL, 0x8888b812UL, 0x900df01cUL,
0x4fad5ea0UL, 0x688fc31cUL, 0xd1cff191UL, 0xb3a8c1adUL,
0x2f2f2218UL, 0xbe0e1777UL, 0xea752dfeUL, 0x8b021fa1UL,
0xe5a0cc0fUL, 0xb56f74e8UL, 0x18acf3d6UL, 0xce89e299UL,
0xb4a84fe0UL, 0xfd13e0b7UL, 0x7cc43b81UL, 0xd2ada8d9UL,
0x165fa266UL, 0x80957705UL, 0x93cc7314UL, 0x211a1477UL,
0xe6ad2065UL, 0x77b5fa86UL, 0xc75442f5UL, 0xfb9d35cfUL,
0xebcdaf0cUL, 0x7b3e89a0UL, 0xd6411bd3UL, 0xae1e7e49UL,
0x00250e2dUL, 0x2071b35eUL, 0x226800bbUL, 0x57b8e0afUL,
0x2464369bUL, 0xf009b91eUL, 0x5563911dUL, 0x59dfa6aaUL,
0x78c14389UL, 0xd95a537fUL, 0x207d5ba2UL, 0x02e5b9c5UL,
0x83260376UL, 0x6295cfa9UL, 0x11c81968UL, 0x4e734a41UL,
0xb3472dcaUL, 0x7b14a94aUL, 0x1b510052UL, 0x9a532915UL,
0xd60f573fUL, 0xbc9bc6e4UL, 0x2b60a476UL, 0x81e67400UL,
0x08ba6fb5UL, 0x571be91fUL, 0xf296ec6bUL, 0x2a0dd915UL,
0xb6636521UL, 0xe7b9f9b6UL, 0xff34052eUL, 0xc5855664UL,
0x53b02d5dUL, 0xa99f8fa1UL, 0x08ba4799UL, 0x6e85076aUL
};
static const word32 ks1[] = {
0x4b7a70e9UL, 0xb5b32944UL, 0xdb75092eUL, 0xc4192623UL,
0xad6ea6b0UL, 0x49a7df7dUL, 0x9cee60b8UL, 0x8fedb266UL,
0xecaa8c71UL, 0x699a17ffUL, 0x5664526cUL, 0xc2b19ee1UL,
0x193602a5UL, 0x75094c29UL, 0xa0591340UL, 0xe4183a3eUL,
0x3f54989aUL, 0x5b429d65UL, 0x6b8fe4d6UL, 0x99f73fd6UL,
0xa1d29c07UL, 0xefe830f5UL, 0x4d2d38e6UL, 0xf0255dc1UL,
0x4cdd2086UL, 0x8470eb26UL, 0x6382e9c6UL, 0x021ecc5eUL,
0x09686b3fUL, 0x3ebaefc9UL, 0x3c971814UL, 0x6b6a70a1UL,
0x687f3584UL, 0x52a0e286UL, 0xb79c5305UL, 0xaa500737UL,
0x3e07841cUL, 0x7fdeae5cUL, 0x8e7d44ecUL, 0x5716f2b8UL,
0xb03ada37UL, 0xf0500c0dUL, 0xf01c1f04UL, 0x0200b3ffUL,
0xae0cf51aUL, 0x3cb574b2UL, 0x25837a58UL, 0xdc0921bdUL,
0xd19113f9UL, 0x7ca92ff6UL, 0x94324773UL, 0x22f54701UL,
0x3ae5e581UL, 0x37c2dadcUL, 0xc8b57634UL, 0x9af3dda7UL,
0xa9446146UL, 0x0fd0030eUL, 0xecc8c73eUL, 0xa4751e41UL,
0xe238cd99UL, 0x3bea0e2fUL, 0x3280bba1UL, 0x183eb331UL,
0x4e548b38UL, 0x4f6db908UL, 0x6f420d03UL, 0xf60a04bfUL,
0x2cb81290UL, 0x24977c79UL, 0x5679b072UL, 0xbcaf89afUL,
0xde9a771fUL, 0xd9930810UL, 0xb38bae12UL, 0xdccf3f2eUL,
0x5512721fUL, 0x2e6b7124UL, 0x501adde6UL, 0x9f84cd87UL,
0x7a584718UL, 0x7408da17UL, 0xbc9f9abcUL, 0xe94b7d8cUL,
0xec7aec3aUL, 0xdb851dfaUL, 0x63094366UL, 0xc464c3d2UL,
0xef1c1847UL, 0x3215d908UL, 0xdd433b37UL, 0x24c2ba16UL,
0x12a14d43UL, 0x2a65c451UL, 0x50940002UL, 0x133ae4ddUL,
0x71dff89eUL, 0x10314e55UL, 0x81ac77d6UL, 0x5f11199bUL,
0x043556f1UL, 0xd7a3c76bUL, 0x3c11183bUL, 0x5924a509UL,
0xf28fe6edUL, 0x97f1fbfaUL, 0x9ebabf2cUL, 0x1e153c6eUL,
0x86e34570UL, 0xeae96fb1UL, 0x860e5e0aUL, 0x5a3e2ab3UL,
0x771fe71cUL, 0x4e3d06faUL, 0x2965dcb9UL, 0x99e71d0fUL,
0x803e89d6UL, 0x5266c825UL, 0x2e4cc978UL, 0x9c10b36aUL,
0xc6150ebaUL, 0x94e2ea78UL, 0xa5fc3c53UL, 0x1e0a2df4UL,
0xf2f74ea7UL, 0x361d2b3dUL, 0x1939260fUL, 0x19c27960UL,
0x5223a708UL, 0xf71312b6UL, 0xebadfe6eUL, 0xeac31f66UL,
0xe3bc4595UL, 0xa67bc883UL, 0xb17f37d1UL, 0x018cff28UL,
0xc332ddefUL, 0xbe6c5aa5UL, 0x65582185UL, 0x68ab9802UL,
0xeecea50fUL, 0xdb2f953bUL, 0x2aef7dadUL, 0x5b6e2f84UL,
0x1521b628UL, 0x29076170UL, 0xecdd4775UL, 0x619f1510UL,
0x13cca830UL, 0xeb61bd96UL, 0x0334fe1eUL, 0xaa0363cfUL,
0xb5735c90UL, 0x4c70a239UL, 0xd59e9e0bUL, 0xcbaade14UL,
0xeecc86bcUL, 0x60622ca7UL, 0x9cab5cabUL, 0xb2f3846eUL,
0x648b1eafUL, 0x19bdf0caUL, 0xa02369b9UL, 0x655abb50UL,
0x40685a32UL, 0x3c2ab4b3UL, 0x319ee9d5UL, 0xc021b8f7UL,
0x9b540b19UL, 0x875fa099UL, 0x95f7997eUL, 0x623d7da8UL,
0xf837889aUL, 0x97e32d77UL, 0x11ed935fUL, 0x16681281UL,
0x0e358829UL, 0xc7e61fd6UL, 0x96dedfa1UL, 0x7858ba99UL,
0x57f584a5UL, 0x1b227263UL, 0x9b83c3ffUL, 0x1ac24696UL,
0xcdb30aebUL, 0x532e3054UL, 0x8fd948e4UL, 0x6dbc3128UL,
0x58ebf2efUL, 0x34c6ffeaUL, 0xfe28ed61UL, 0xee7c3c73UL,
0x5d4a14d9UL, 0xe864b7e3UL, 0x42105d14UL, 0x203e13e0UL,
0x45eee2b6UL, 0xa3aaabeaUL, 0xdb6c4f15UL, 0xfacb4fd0UL,
0xc742f442UL, 0xef6abbb5UL, 0x654f3b1dUL, 0x41cd2105UL,
0xd81e799eUL, 0x86854dc7UL, 0xe44b476aUL, 0x3d816250UL,
0xcf62a1f2UL, 0x5b8d2646UL, 0xfc8883a0UL, 0xc1c7b6a3UL,
0x7f1524c3UL, 0x69cb7492UL, 0x47848a0bUL, 0x5692b285UL,
0x095bbf00UL, 0xad19489dUL, 0x1462b174UL, 0x23820e00UL,
0x58428d2aUL, 0x0c55f5eaUL, 0x1dadf43eUL, 0x233f7061UL,
0x3372f092UL, 0x8d937e41UL, 0xd65fecf1UL, 0x6c223bdbUL,
0x7cde3759UL, 0xcbee7460UL, 0x4085f2a7UL, 0xce77326eUL,
0xa6078084UL, 0x19f8509eUL, 0xe8efd855UL, 0x61d99735UL,
0xa969a7aaUL, 0xc50c06c2UL, 0x5a04abfcUL, 0x800bcadcUL,
0x9e447a2eUL, 0xc3453484UL, 0xfdd56705UL, 0x0e1e9ec9UL,
0xdb73dbd3UL, 0x105588cdUL, 0x675fda79UL, 0xe3674340UL,
0xc5c43465UL, 0x713e38d8UL, 0x3d28f89eUL, 0xf16dff20UL,
0x153e21e7UL, 0x8fb03d4aUL, 0xe6e39f2bUL, 0xdb83adf7UL
};
static const word32 ks2[] = {
0xe93d5a68UL, 0x948140f7UL, 0xf64c261cUL, 0x94692934UL,
0x411520f7UL, 0x7602d4f7UL, 0xbcf46b2eUL, 0xd4a20068UL,
0xd4082471UL, 0x3320f46aUL, 0x43b7d4b7UL, 0x500061afUL,
0x1e39f62eUL, 0x97244546UL, 0x14214f74UL, 0xbf8b8840UL,
0x4d95fc1dUL, 0x96b591afUL, 0x70f4ddd3UL, 0x66a02f45UL,
0xbfbc09ecUL, 0x03bd9785UL, 0x7fac6dd0UL, 0x31cb8504UL,
0x96eb27b3UL, 0x55fd3941UL, 0xda2547e6UL, 0xabca0a9aUL,
0x28507825UL, 0x530429f4UL, 0x0a2c86daUL, 0xe9b66dfbUL,
0x68dc1462UL, 0xd7486900UL, 0x680ec0a4UL, 0x27a18deeUL,
0x4f3ffea2UL, 0xe887ad8cUL, 0xb58ce006UL, 0x7af4d6b6UL,
0xaace1e7cUL, 0xd3375fecUL, 0xce78a399UL, 0x406b2a42UL,
0x20fe9e35UL, 0xd9f385b9UL, 0xee39d7abUL, 0x3b124e8bUL,
0x1dc9faf7UL, 0x4b6d1856UL, 0x26a36631UL, 0xeae397b2UL,
0x3a6efa74UL, 0xdd5b4332UL, 0x6841e7f7UL, 0xca7820fbUL,
0xfb0af54eUL, 0xd8feb397UL, 0x454056acUL, 0xba489527UL,
0x55533a3aUL, 0x20838d87UL, 0xfe6ba9b7UL, 0xd096954bUL,
0x55a867bcUL, 0xa1159a58UL, 0xcca92963UL, 0x99e1db33UL,
0xa62a4a56UL, 0x3f3125f9UL, 0x5ef47e1cUL, 0x9029317cUL,
0xfdf8e802UL, 0x04272f70UL, 0x80bb155cUL, 0x05282ce3UL,
0x95c11548UL, 0xe4c66d22UL, 0x48c1133fUL, 0xc70f86dcUL,
0x07f9c9eeUL, 0x41041f0fUL, 0x404779a4UL, 0x5d886e17UL,
0x325f51ebUL, 0xd59bc0d1UL, 0xf2bcc18fUL, 0x41113564UL,
0x257b7834UL, 0x602a9c60UL, 0xdff8e8a3UL, 0x1f636c1bUL,
0x0e12b4c2UL, 0x02e1329eUL, 0xaf664fd1UL, 0xcad18115UL,
0x6b2395e0UL, 0x333e92e1UL, 0x3b240b62UL, 0xeebeb922UL,
0x85b2a20eUL, 0xe6ba0d99UL, 0xde720c8cUL, 0x2da2f728UL,
0xd0127845UL, 0x95b794fdUL, 0x647d0862UL, 0xe7ccf5f0UL,
0x5449a36fUL, 0x877d48faUL, 0xc39dfd27UL, 0xf33e8d1eUL,
0x0a476341UL, 0x992eff74UL, 0x3a6f6eabUL, 0xf4f8fd37UL,
0xa812dc60UL, 0xa1ebddf8UL, 0x991be14cUL, 0xdb6e6b0dUL,
0xc67b5510UL, 0x6d672c37UL, 0x2765d43bUL, 0xdcd0e804UL,
0xf1290dc7UL, 0xcc00ffa3UL, 0xb5390f92UL, 0x690fed0bUL,
0x667b9ffbUL, 0xcedb7d9cUL, 0xa091cf0bUL, 0xd9155ea3UL,
0xbb132f88UL, 0x515bad24UL, 0x7b9479bfUL, 0x763bd6ebUL,
0x37392eb3UL, 0xcc115979UL, 0x8026e297UL, 0xf42e312dUL,
0x6842ada7UL, 0xc66a2b3bUL, 0x12754cccUL, 0x782ef11cUL,
0x6a124237UL, 0xb79251e7UL, 0x06a1bbe6UL, 0x4bfb6350UL,
0x1a6b1018UL, 0x11caedfaUL, 0x3d25bdd8UL, 0xe2e1c3c9UL,
0x44421659UL, 0x0a121386UL, 0xd90cec6eUL, 0xd5abea2aUL,
0x64af674eUL, 0xda86a85fUL, 0xbebfe988UL, 0x64e4c3feUL,
0x9dbc8057UL, 0xf0f7c086UL, 0x60787bf8UL, 0x6003604dUL,
0xd1fd8346UL, 0xf6381fb0UL, 0x7745ae04UL, 0xd736fcccUL,
0x83426b33UL, 0xf01eab71UL, 0xb0804187UL, 0x3c005e5fUL,
0x77a057beUL, 0xbde8ae24UL, 0x55464299UL, 0xbf582e61UL,
0x4e58f48fUL, 0xf2ddfda2UL, 0xf474ef38UL, 0x8789bdc2UL,
0x5366f9c3UL, 0xc8b38e74UL, 0xb475f255UL, 0x46fcd9b9UL,
0x7aeb2661UL, 0x8b1ddf84UL, 0x846a0e79UL, 0x915f95e2UL,
0x466e598eUL, 0x20b45770UL, 0x8cd55591UL, 0xc902de4cUL,
0xb90bace1UL, 0xbb8205d0UL, 0x11a86248UL, 0x7574a99eUL,
0xb77f19b6UL, 0xe0a9dc09UL, 0x662d09a1UL, 0xc4324633UL,
0xe85a1f02UL, 0x09f0be8cUL, 0x4a99a025UL, 0x1d6efe10UL,
0x1ab93d1dUL, 0x0ba5a4dfUL, 0xa186f20fUL, 0x2868f169UL,
0xdcb7da83UL, 0x573906feUL, 0xa1e2ce9bUL, 0x4fcd7f52UL,
0x50115e01UL, 0xa70683faUL, 0xa002b5c4UL, 0x0de6d027UL,
0x9af88c27UL, 0x773f8641UL, 0xc3604c06UL, 0x61a806b5UL,
0xf0177a28UL, 0xc0f586e0UL, 0x006058aaUL, 0x30dc7d62UL,
0x11e69ed7UL, 0x2338ea63UL, 0x53c2dd94UL, 0xc2c21634UL,
0xbbcbee56UL, 0x90bcb6deUL, 0xebfc7da1UL, 0xce591d76UL,
0x6f05e409UL, 0x4b7c0188UL, 0x39720a3dUL, 0x7c927c24UL,
0x86e3725fUL, 0x724d9db9UL, 0x1ac15bb4UL, 0xd39eb8fcUL,
0xed545578UL, 0x08fca5b5UL, 0xd83d7cd3UL, 0x4dad0fc4UL,
0x1e50ef5eUL, 0xb161e6f8UL, 0xa28514d9UL, 0x6c51133cUL,
0x6fd5c7e7UL, 0x56e14ec4UL, 0x362abfceUL, 0xddc6c837UL,
0xd79a3234UL, 0x92638212UL, 0x670efa8eUL, 0x406000e0UL
};
static const word32 ks3[] = {
0x3a39ce37UL, 0xd3faf5cfUL, 0xabc27737UL, 0x5ac52d1bUL,
0x5cb0679eUL, 0x4fa33742UL, 0xd3822740UL, 0x99bc9bbeUL,
0xd5118e9dUL, 0xbf0f7315UL, 0xd62d1c7eUL, 0xc700c47bUL,
0xb78c1b6bUL, 0x21a19045UL, 0xb26eb1beUL, 0x6a366eb4UL,
0x5748ab2fUL, 0xbc946e79UL, 0xc6a376d2UL, 0x6549c2c8UL,
0x530ff8eeUL, 0x468dde7dUL, 0xd5730a1dUL, 0x4cd04dc6UL,
0x2939bbdbUL, 0xa9ba4650UL, 0xac9526e8UL, 0xbe5ee304UL,
0xa1fad5f0UL, 0x6a2d519aUL, 0x63ef8ce2UL, 0x9a86ee22UL,
0xc089c2b8UL, 0x43242ef6UL, 0xa51e03aaUL, 0x9cf2d0a4UL,
0x83c061baUL, 0x9be96a4dUL, 0x8fe51550UL, 0xba645bd6UL,
0x2826a2f9UL, 0xa73a3ae1UL, 0x4ba99586UL, 0xef5562e9UL,
0xc72fefd3UL, 0xf752f7daUL, 0x3f046f69UL, 0x77fa0a59UL,
0x80e4a915UL, 0x87b08601UL, 0x9b09e6adUL, 0x3b3ee593UL,
0xe990fd5aUL, 0x9e34d797UL, 0x2cf0b7d9UL, 0x022b8b51UL,
0x96d5ac3aUL, 0x017da67dUL, 0xd1cf3ed6UL, 0x7c7d2d28UL,
0x1f9f25cfUL, 0xadf2b89bUL, 0x5ad6b472UL, 0x5a88f54cUL,
0xe029ac71UL, 0xe019a5e6UL, 0x47b0acfdUL, 0xed93fa9bUL,
0xe8d3c48dUL, 0x283b57ccUL, 0xf8d56629UL, 0x79132e28UL,
0x785f0191UL, 0xed756055UL, 0xf7960e44UL, 0xe3d35e8cUL,
0x15056dd4UL, 0x88f46dbaUL, 0x03a16125UL, 0x0564f0bdUL,
0xc3eb9e15UL, 0x3c9057a2UL, 0x97271aecUL, 0xa93a072aUL,
0x1b3f6d9bUL, 0x1e6321f5UL, 0xf59c66fbUL, 0x26dcf319UL,
0x7533d928UL, 0xb155fdf5UL, 0x03563482UL, 0x8aba3cbbUL,
0x28517711UL, 0xc20ad9f8UL, 0xabcc5167UL, 0xccad925fUL,
0x4de81751UL, 0x3830dc8eUL, 0x379d5862UL, 0x9320f991UL,
0xea7a90c2UL, 0xfb3e7bceUL, 0x5121ce64UL, 0x774fbe32UL,
0xa8b6e37eUL, 0xc3293d46UL, 0x48de5369UL, 0x6413e680UL,
0xa2ae0810UL, 0xdd6db224UL, 0x69852dfdUL, 0x09072166UL,
0xb39a460aUL, 0x6445c0ddUL, 0x586cdecfUL, 0x1c20c8aeUL,
0x5bbef7ddUL, 0x1b588d40UL, 0xccd2017fUL, 0x6bb4e3bbUL,
0xdda26a7eUL, 0x3a59ff45UL, 0x3e350a44UL, 0xbcb4cdd5UL,
0x72eacea8UL, 0xfa6484bbUL, 0x8d6612aeUL, 0xbf3c6f47UL,
0xd29be463UL, 0x542f5d9eUL, 0xaec2771bUL, 0xf64e6370UL,
0x740e0d8dUL, 0xe75b1357UL, 0xf8721671UL, 0xaf537d5dUL,
0x4040cb08UL, 0x4eb4e2ccUL, 0x34d2466aUL, 0x0115af84UL,
0xe1b00428UL, 0x95983a1dUL, 0x06b89fb4UL, 0xce6ea048UL,
0x6f3f3b82UL, 0x3520ab82UL, 0x011a1d4bUL, 0x277227f8UL,
0x611560b1UL, 0xe7933fdcUL, 0xbb3a792bUL, 0x344525bdUL,
0xa08839e1UL, 0x51ce794bUL, 0x2f32c9b7UL, 0xa01fbac9UL,
0xe01cc87eUL, 0xbcc7d1f6UL, 0xcf0111c3UL, 0xa1e8aac7UL,
0x1a908749UL, 0xd44fbd9aUL, 0xd0dadecbUL, 0xd50ada38UL,
0x0339c32aUL, 0xc6913667UL, 0x8df9317cUL, 0xe0b12b4fUL,
0xf79e59b7UL, 0x43f5bb3aUL, 0xf2d519ffUL, 0x27d9459cUL,
0xbf97222cUL, 0x15e6fc2aUL, 0x0f91fc71UL, 0x9b941525UL,
0xfae59361UL, 0xceb69cebUL, 0xc2a86459UL, 0x12baa8d1UL,
0xb6c1075eUL, 0xe3056a0cUL, 0x10d25065UL, 0xcb03a442UL,
0xe0ec6e0eUL, 0x1698db3bUL, 0x4c98a0beUL, 0x3278e964UL,
0x9f1f9532UL, 0xe0d392dfUL, 0xd3a0342bUL, 0x8971f21eUL,
0x1b0a7441UL, 0x4ba3348cUL, 0xc5be7120UL, 0xc37632d8UL,
0xdf359f8dUL, 0x9b992f2eUL, 0xe60b6f47UL, 0x0fe3f11dUL,
0xe54cda54UL, 0x1edad891UL, 0xce6279cfUL, 0xcd3e7e6fUL,
0x1618b166UL, 0xfd2c1d05UL, 0x848fd2c5UL, 0xf6fb2299UL,
0xf523f357UL, 0xa6327623UL, 0x93a83531UL, 0x56cccd02UL,
0xacf08162UL, 0x5a75ebb5UL, 0x6e163697UL, 0x88d273ccUL,
0xde966292UL, 0x81b949d0UL, 0x4c50901bUL, 0x71c65614UL,
0xe6c6c7bdUL, 0x327a140aUL, 0x45e1d006UL, 0xc3f27b9aUL,
0xc9aa53fdUL, 0x62a80f00UL, 0xbb25bfe2UL, 0x35bdd2f6UL,
0x71126905UL, 0xb2040222UL, 0xb6cbcf7cUL, 0xcd769c2bUL,
0x53113ec0UL, 0x1640e3d3UL, 0x38abbd60UL, 0x2547adf0UL,
0xba38209cUL, 0xf746ce76UL, 0x77afa1c5UL, 0x20756060UL,
0x85cbfe4eUL, 0x8ae88dd8UL, 0x7aaaf9b0UL, 0x4cf9aa7eUL,
0x1948c25cUL, 0x02fb8a8cUL, 0x01c36ae4UL, 0xd6ebe1f9UL,
0x90d4f869UL, 0xa65cdea0UL, 0x3f09252dUL, 0xc208e69fUL,
0xb74e6132UL, 0xce77e25bUL, 0x578fdfe3UL, 0x3ac372e6UL
};
static const word32 pi[] = {
0x243f6a88UL, 0x85a308d3UL, 0x13198a2eUL, 0x03707344UL,
0xa4093822UL, 0x299f31d0UL, 0x082efa98UL, 0xec4e6c89UL,
0x452821e6UL, 0x38d01377UL, 0xbe5466cfUL, 0x34e90c6cUL,
0xc0ac29b7UL, 0xc97c50ddUL, 0x3f84d5b5UL, 0xb5470917UL,
0x9216d5d9UL, 0x8979fb1bUL
};
static short initialize_blowfish(blf_ctx * c, unsigned char key[],
short keybytes)
{
short i, j;
word32 data, datarl[2];
/* Initialize s-boxes without file read. */
for (i = 0; i < 256; i++) {
c->S[0][i] = ks0[i];
c->S[1][i] = ks1[i];
c->S[2][i] = ks2[i];
c->S[3][i] = ks3[i];
}
/* P-boxes */
for (i = 0; i < 18; i++) {
c->P[i] = pi[i];
}
j = 0;
for (i = 0; i < BF_N + 2; ++i) {
data = 0x00000000;
data = (data << 8) | key[(j) % keybytes];
data = (data << 8) | key[(j + 1) % keybytes];
data = (data << 8) | key[(j + 2) % keybytes];
data = (data << 8) | key[(j + 3) % keybytes];
c->P[i] ^= data;
j = (j + 4) % keybytes;
}
datarl[0] = 0x000000000;
datarl[1] = 0x000000000;
for (i = 0; i < BF_N + 2; i += 2) {
enblf_noswap(c, datarl);
c->P[i] = datarl[0];
c->P[i + 1] = datarl[1];
}
for (i = 0; i < 4; ++i) {
for (j = 0; j < 256; j += 2) {
enblf_noswap(c, datarl);
c->S[i][j] = datarl[0];
c->S[i][j + 1] = datarl[1];
}
}
return 0;
}
WIN32DLL_DEFINE int _mcrypt_set_key(blf_ctx * c, char *k, int len)
{
initialize_blowfish(c, k, len);
return 0;
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(blf_ctx);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 56;
}
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = 0;
return NULL;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "Blowfish";
}
#define CIPHER "c8c033bc57874d74"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,5 @@
/* for blowfish */
typedef struct {
word32 S[4][256],P[18];
} blf_ctx;
@@ -0,0 +1,400 @@
/*
* $Id: cast-128.c,v 1.12 2003/01/19 17:48:27 nmav Exp $
*
* CAST-128 in C
* Written by Steve Reid <sreid@sea-to-sky.net>
* 100% Public Domain - no warranty
* Released 1997.10.11
*/
/* Adapted to the pike cryptographic toolkit by Niels Möller */
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: cast-128.c,v 1.12 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "cast-128.h"
#define _mcrypt_set_key cast_128_LTX__mcrypt_set_key
#define _mcrypt_encrypt cast_128_LTX__mcrypt_encrypt
#define _mcrypt_decrypt cast_128_LTX__mcrypt_decrypt
#define _mcrypt_get_size cast_128_LTX__mcrypt_get_size
#define _mcrypt_get_block_size cast_128_LTX__mcrypt_get_block_size
#define _is_block_algorithm cast_128_LTX__is_block_algorithm
#define _mcrypt_get_key_size cast_128_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes cast_128_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name cast_128_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test cast_128_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version cast_128_LTX__mcrypt_algorithm_version
#define u8 byte
#define u32 word32
#include "cast-128_sboxes.h"
/* Macros to access 8-bit bytes out of a 32-bit word */
#define U8a(x) ( (u8) (x>>24) )
#define U8b(x) ( (u8) ((x>>16)&255) )
#define U8c(x) ( (u8) ((x>>8)&255) )
#define U8d(x) ( (u8) ((x)&255) )
/* Circular left shift */
#define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
/* CAST-128 uses three different round functions */
#define F1(l, r, i) \
t = ROL(key->xkey[i] + r, key->xkey[i+16]); \
l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) \
- cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)];
#define F2(l, r, i) \
t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \
l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) \
+ cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)];
#define F3(l, r, i) \
t = ROL(key->xkey[i] - r, key->xkey[i+16]); \
l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) \
^ cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)];
/***** Encryption Function *****/
WIN32DLL_DEFINE void _mcrypt_encrypt(CAST_KEY * key, u8 * block)
{
u32 t, l, r;
/* Get inblock into l,r */
l = ((u32) block[0] << 24) | ((u32) block[1] << 16)
| ((u32) block[2] << 8) | (u32) block[3];
r = ((u32) block[4] << 24) | ((u32) block[5] << 16)
| ((u32) block[6] << 8) | (u32) block[7];
/* Do the work */
F1(l, r, 0);
F2(r, l, 1);
F3(l, r, 2);
F1(r, l, 3);
F2(l, r, 4);
F3(r, l, 5);
F1(l, r, 6);
F2(r, l, 7);
F3(l, r, 8);
F1(r, l, 9);
F2(l, r, 10);
F3(r, l, 11);
/* Only do full 16 rounds if key length > 80 bits */
if (key->rounds > 12) {
F1(l, r, 12);
F2(r, l, 13);
F3(l, r, 14);
F1(r, l, 15);
}
/* Put l,r into outblock */
block[0] = U8a(r);
block[1] = U8b(r);
block[2] = U8c(r);
block[3] = U8d(r);
block[4] = U8a(l);
block[5] = U8b(l);
block[6] = U8c(l);
block[7] = U8d(l);
/* Wipe clean */
t = l = r = 0;
}
/***** Decryption Function *****/
WIN32DLL_DEFINE void _mcrypt_decrypt(CAST_KEY * key, u8 * block)
{
u32 t, l, r;
/* Get inblock into l,r */
r = ((u32) block[0] << 24) | ((u32) block[1] << 16)
| ((u32) block[2] << 8) | (u32) block[3];
l = ((u32) block[4] << 24) | ((u32) block[5] << 16)
| ((u32) block[6] << 8) | (u32) block[7];
/* Do the work */
/* Only do full 16 rounds if key length > 80 bits */
if (key->rounds > 12) {
F1(r, l, 15);
F3(l, r, 14);
F2(r, l, 13);
F1(l, r, 12);
}
F3(r, l, 11);
F2(l, r, 10);
F1(r, l, 9);
F3(l, r, 8);
F2(r, l, 7);
F1(l, r, 6);
F3(r, l, 5);
F2(l, r, 4);
F1(r, l, 3);
F3(l, r, 2);
F2(r, l, 1);
F1(l, r, 0);
/* Put l,r into outblock */
block[0] = U8a(l);
block[1] = U8b(l);
block[2] = U8c(l);
block[3] = U8d(l);
block[4] = U8a(r);
block[5] = U8b(r);
block[6] = U8c(r);
block[7] = U8d(r);
/* Wipe clean */
t = l = r = 0;
}
/***** Key Schedual *****/
WIN32DLL_DEFINE
int _mcrypt_set_key(CAST_KEY * key, u8 * rawkey, unsigned keybytes)
{
u32 t[4], z[4], x[4];
unsigned i;
/* Set number of rounds to 12 or 16, depending on key length */
key->rounds = (keybytes <= CAST_SMALL_KEY)
? CAST_SMALL_ROUNDS : CAST_FULL_ROUNDS;
/* Copy key to workspace x */
for (i = 0; i < 4; i++) {
x[i] = 0;
if ((i * 4 + 0) < keybytes)
x[i] = (u32) rawkey[i * 4 + 0] << 24;
if ((i * 4 + 1) < keybytes)
x[i] |= (u32) rawkey[i * 4 + 1] << 16;
if ((i * 4 + 2) < keybytes)
x[i] |= (u32) rawkey[i * 4 + 2] << 8;
if ((i * 4 + 3) < keybytes)
x[i] |= (u32) rawkey[i * 4 + 3];
}
/* Generate 32 subkeys, four at a time */
for (i = 0; i < 32; i += 4) {
switch (i & 4) {
case 0:
t[0] = z[0] = x[0] ^ cast_sbox5[U8b(x[3])]
^ cast_sbox6[U8d(x[3])] ^ cast_sbox7[U8a(x[3])]
^ cast_sbox8[U8c(x[3])] ^
cast_sbox7[U8a(x[2])];
t[1] = z[1] = x[2] ^ cast_sbox5[U8a(z[0])]
^ cast_sbox6[U8c(z[0])] ^ cast_sbox7[U8b(z[0])]
^ cast_sbox8[U8d(z[0])] ^
cast_sbox8[U8c(x[2])];
t[2] = z[2] = x[3] ^ cast_sbox5[U8d(z[1])]
^ cast_sbox6[U8c(z[1])] ^ cast_sbox7[U8b(z[1])]
^ cast_sbox8[U8a(z[1])] ^
cast_sbox5[U8b(x[2])];
t[3] = z[3] =
x[1] ^ cast_sbox5[U8c(z[2])] ^
cast_sbox6[U8b(z[2])] ^ cast_sbox7[U8d(z[2])]
^ cast_sbox8[U8a(z[2])] ^
cast_sbox6[U8d(x[2])];
break;
case 4:
t[0] = x[0] = z[2] ^ cast_sbox5[U8b(z[1])]
^ cast_sbox6[U8d(z[1])] ^ cast_sbox7[U8a(z[1])]
^ cast_sbox8[U8c(z[1])] ^
cast_sbox7[U8a(z[0])];
t[1] = x[1] = z[0] ^ cast_sbox5[U8a(x[0])]
^ cast_sbox6[U8c(x[0])] ^ cast_sbox7[U8b(x[0])]
^ cast_sbox8[U8d(x[0])] ^
cast_sbox8[U8c(z[0])];
t[2] = x[2] = z[1] ^ cast_sbox5[U8d(x[1])]
^ cast_sbox6[U8c(x[1])] ^ cast_sbox7[U8b(x[1])]
^ cast_sbox8[U8a(x[1])] ^
cast_sbox5[U8b(z[0])];
t[3] = x[3] = z[3] ^ cast_sbox5[U8c(x[2])]
^ cast_sbox6[U8b(x[2])] ^ cast_sbox7[U8d(x[2])]
^ cast_sbox8[U8a(x[2])] ^
cast_sbox6[U8d(z[0])];
break;
}
switch (i & 12) {
case 0:
case 12:
key->xkey[i + 0] =
cast_sbox5[U8a(t[2])] ^ cast_sbox6[U8b(t[2])]
^ cast_sbox7[U8d(t[1])] ^
cast_sbox8[U8c(t[1])];
key->xkey[i + 1] =
cast_sbox5[U8c(t[2])] ^ cast_sbox6[U8d(t[2])]
^ cast_sbox7[U8b(t[1])] ^
cast_sbox8[U8a(t[1])];
key->xkey[i + 2] =
cast_sbox5[U8a(t[3])] ^ cast_sbox6[U8b(t[3])]
^ cast_sbox7[U8d(t[0])] ^
cast_sbox8[U8c(t[0])];
key->xkey[i + 3] =
cast_sbox5[U8c(t[3])] ^ cast_sbox6[U8d(t[3])]
^ cast_sbox7[U8b(t[0])] ^
cast_sbox8[U8a(t[0])];
break;
case 4:
case 8:
key->xkey[i + 0] =
cast_sbox5[U8d(t[0])] ^ cast_sbox6[U8c(t[0])]
^ cast_sbox7[U8a(t[3])] ^
cast_sbox8[U8b(t[3])];
key->xkey[i + 1] =
cast_sbox5[U8b(t[0])] ^ cast_sbox6[U8a(t[0])]
^ cast_sbox7[U8c(t[3])] ^
cast_sbox8[U8d(t[3])];
key->xkey[i + 2] =
cast_sbox5[U8d(t[1])] ^ cast_sbox6[U8c(t[1])]
^ cast_sbox7[U8a(t[2])] ^
cast_sbox8[U8b(t[2])];
key->xkey[i + 3] =
cast_sbox5[U8b(t[1])] ^ cast_sbox6[U8a(t[1])]
^ cast_sbox7[U8c(t[2])] ^
cast_sbox8[U8d(t[2])];
break;
}
switch (i & 12) {
case 0:
key->xkey[i + 0] ^= cast_sbox5[U8c(z[0])];
key->xkey[i + 1] ^= cast_sbox6[U8c(z[1])];
key->xkey[i + 2] ^= cast_sbox7[U8b(z[2])];
key->xkey[i + 3] ^= cast_sbox8[U8a(z[3])];
break;
case 4:
key->xkey[i + 0] ^= cast_sbox5[U8a(x[2])];
key->xkey[i + 1] ^= cast_sbox6[U8b(x[3])];
key->xkey[i + 2] ^= cast_sbox7[U8d(x[0])];
key->xkey[i + 3] ^= cast_sbox8[U8d(x[1])];
break;
case 8:
key->xkey[i + 0] ^= cast_sbox5[U8b(z[2])];
key->xkey[i + 1] ^= cast_sbox6[U8a(z[3])];
key->xkey[i + 2] ^= cast_sbox7[U8c(z[0])];
key->xkey[i + 3] ^= cast_sbox8[U8c(z[1])];
break;
case 12:
key->xkey[i + 0] ^= cast_sbox5[U8d(x[0])];
key->xkey[i + 1] ^= cast_sbox6[U8d(x[1])];
key->xkey[i + 2] ^= cast_sbox7[U8a(x[2])];
key->xkey[i + 3] ^= cast_sbox8[U8b(x[3])];
break;
}
if (i >= 16) {
key->xkey[i + 0] &= 31;
key->xkey[i + 1] &= 31;
key->xkey[i + 2] &= 31;
key->xkey[i + 3] &= 31;
}
}
/* Wipe clean */
for (i = 0; i < 4; i++) {
t[i] = x[i] = z[i] = 0;
}
return 0;
}
/* Made in Canada */
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(CAST_KEY);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 16;
}
static const int key_sizes[] = { 16 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "CAST-128";
}
#define CIPHER "434e25460c8c9525"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,27 @@
/*
* $Id: cast-128.h,v 1.1.1.1 2000/05/22 13:08:18 nmav Exp $
*
* CAST-128 in C
* Written by Steve Reid <sreid@sea-to-sky.net>
* 100% Public Domain - no warranty
* Released 1997.10.11
*/
#ifndef _CAST_H_INCLUDED
#define _CAST_H_INCLUDED
#define CAST_MIN_KEYSIZE 5
#define CAST_MAX_KEYSIZE 16
#define CAST_BLOCKSIZE 8
#define CAST_SMALL_KEY 10
#define CAST_SMALL_ROUNDS 12
#define CAST_FULL_ROUNDS 16
typedef struct cast_key {
word32 xkey[32]; /* Key, after expansion */
unsigned rounds; /* Number of rounds to use, 12 or 16 */
} CAST_KEY;
#endif /* ifndef _CAST_H_INCLUDED */
@@ -0,0 +1,545 @@
/*
* $Id: cast-128_sboxes.h,v 1.1.1.1 2000/05/22 13:08:20 nmav Exp $
*
* CAST-128 in C
* Written by Steve Reid <sreid@sea-to-sky.net>
* 100% Public Domain - no warranty
* Released 1997.10.11
*/
static const u32 cast_sbox1[256] = {
0x30FB40D4, 0x9FA0FF0B, 0x6BECCD2F, 0x3F258C7A,
0x1E213F2F, 0x9C004DD3, 0x6003E540, 0xCF9FC949,
0xBFD4AF27, 0x88BBBDB5, 0xE2034090, 0x98D09675,
0x6E63A0E0, 0x15C361D2, 0xC2E7661D, 0x22D4FF8E,
0x28683B6F, 0xC07FD059, 0xFF2379C8, 0x775F50E2,
0x43C340D3, 0xDF2F8656, 0x887CA41A, 0xA2D2BD2D,
0xA1C9E0D6, 0x346C4819, 0x61B76D87, 0x22540F2F,
0x2ABE32E1, 0xAA54166B, 0x22568E3A, 0xA2D341D0,
0x66DB40C8, 0xA784392F, 0x004DFF2F, 0x2DB9D2DE,
0x97943FAC, 0x4A97C1D8, 0x527644B7, 0xB5F437A7,
0xB82CBAEF, 0xD751D159, 0x6FF7F0ED, 0x5A097A1F,
0x827B68D0, 0x90ECF52E, 0x22B0C054, 0xBC8E5935,
0x4B6D2F7F, 0x50BB64A2, 0xD2664910, 0xBEE5812D,
0xB7332290, 0xE93B159F, 0xB48EE411, 0x4BFF345D,
0xFD45C240, 0xAD31973F, 0xC4F6D02E, 0x55FC8165,
0xD5B1CAAD, 0xA1AC2DAE, 0xA2D4B76D, 0xC19B0C50,
0x882240F2, 0x0C6E4F38, 0xA4E4BFD7, 0x4F5BA272,
0x564C1D2F, 0xC59C5319, 0xB949E354, 0xB04669FE,
0xB1B6AB8A, 0xC71358DD, 0x6385C545, 0x110F935D,
0x57538AD5, 0x6A390493, 0xE63D37E0, 0x2A54F6B3,
0x3A787D5F, 0x6276A0B5, 0x19A6FCDF, 0x7A42206A,
0x29F9D4D5, 0xF61B1891, 0xBB72275E, 0xAA508167,
0x38901091, 0xC6B505EB, 0x84C7CB8C, 0x2AD75A0F,
0x874A1427, 0xA2D1936B, 0x2AD286AF, 0xAA56D291,
0xD7894360, 0x425C750D, 0x93B39E26, 0x187184C9,
0x6C00B32D, 0x73E2BB14, 0xA0BEBC3C, 0x54623779,
0x64459EAB, 0x3F328B82, 0x7718CF82, 0x59A2CEA6,
0x04EE002E, 0x89FE78E6, 0x3FAB0950, 0x325FF6C2,
0x81383F05, 0x6963C5C8, 0x76CB5AD6, 0xD49974C9,
0xCA180DCF, 0x380782D5, 0xC7FA5CF6, 0x8AC31511,
0x35E79E13, 0x47DA91D0, 0xF40F9086, 0xA7E2419E,
0x31366241, 0x051EF495, 0xAA573B04, 0x4A805D8D,
0x548300D0, 0x00322A3C, 0xBF64CDDF, 0xBA57A68E,
0x75C6372B, 0x50AFD341, 0xA7C13275, 0x915A0BF5,
0x6B54BFAB, 0x2B0B1426, 0xAB4CC9D7, 0x449CCD82,
0xF7FBF265, 0xAB85C5F3, 0x1B55DB94, 0xAAD4E324,
0xCFA4BD3F, 0x2DEAA3E2, 0x9E204D02, 0xC8BD25AC,
0xEADF55B3, 0xD5BD9E98, 0xE31231B2, 0x2AD5AD6C,
0x954329DE, 0xADBE4528, 0xD8710F69, 0xAA51C90F,
0xAA786BF6, 0x22513F1E, 0xAA51A79B, 0x2AD344CC,
0x7B5A41F0, 0xD37CFBAD, 0x1B069505, 0x41ECE491,
0xB4C332E6, 0x032268D4, 0xC9600ACC, 0xCE387E6D,
0xBF6BB16C, 0x6A70FB78, 0x0D03D9C9, 0xD4DF39DE,
0xE01063DA, 0x4736F464, 0x5AD328D8, 0xB347CC96,
0x75BB0FC3, 0x98511BFB, 0x4FFBCC35, 0xB58BCF6A,
0xE11F0ABC, 0xBFC5FE4A, 0xA70AEC10, 0xAC39570A,
0x3F04442F, 0x6188B153, 0xE0397A2E, 0x5727CB79,
0x9CEB418F, 0x1CACD68D, 0x2AD37C96, 0x0175CB9D,
0xC69DFF09, 0xC75B65F0, 0xD9DB40D8, 0xEC0E7779,
0x4744EAD4, 0xB11C3274, 0xDD24CB9E, 0x7E1C54BD,
0xF01144F9, 0xD2240EB1, 0x9675B3FD, 0xA3AC3755,
0xD47C27AF, 0x51C85F4D, 0x56907596, 0xA5BB15E6,
0x580304F0, 0xCA042CF1, 0x011A37EA, 0x8DBFAADB,
0x35BA3E4A, 0x3526FFA0, 0xC37B4D09, 0xBC306ED9,
0x98A52666, 0x5648F725, 0xFF5E569D, 0x0CED63D0,
0x7C63B2CF, 0x700B45E1, 0xD5EA50F1, 0x85A92872,
0xAF1FBDA7, 0xD4234870, 0xA7870BF3, 0x2D3B4D79,
0x42E04198, 0x0CD0EDE7, 0x26470DB8, 0xF881814C,
0x474D6AD7, 0x7C0C5E5C, 0xD1231959, 0x381B7298,
0xF5D2F4DB, 0xAB838653, 0x6E2F1E23, 0x83719C9E,
0xBD91E046, 0x9A56456E, 0xDC39200C, 0x20C8C571,
0x962BDA1C, 0xE1E696FF, 0xB141AB08, 0x7CCA89B9,
0x1A69E783, 0x02CC4843, 0xA2F7C579, 0x429EF47D,
0x427B169C, 0x5AC9F049, 0xDD8F0F00, 0x5C8165BF
};
static const u32 cast_sbox2[256] = {
0x1F201094, 0xEF0BA75B, 0x69E3CF7E, 0x393F4380,
0xFE61CF7A, 0xEEC5207A, 0x55889C94, 0x72FC0651,
0xADA7EF79, 0x4E1D7235, 0xD55A63CE, 0xDE0436BA,
0x99C430EF, 0x5F0C0794, 0x18DCDB7D, 0xA1D6EFF3,
0xA0B52F7B, 0x59E83605, 0xEE15B094, 0xE9FFD909,
0xDC440086, 0xEF944459, 0xBA83CCB3, 0xE0C3CDFB,
0xD1DA4181, 0x3B092AB1, 0xF997F1C1, 0xA5E6CF7B,
0x01420DDB, 0xE4E7EF5B, 0x25A1FF41, 0xE180F806,
0x1FC41080, 0x179BEE7A, 0xD37AC6A9, 0xFE5830A4,
0x98DE8B7F, 0x77E83F4E, 0x79929269, 0x24FA9F7B,
0xE113C85B, 0xACC40083, 0xD7503525, 0xF7EA615F,
0x62143154, 0x0D554B63, 0x5D681121, 0xC866C359,
0x3D63CF73, 0xCEE234C0, 0xD4D87E87, 0x5C672B21,
0x071F6181, 0x39F7627F, 0x361E3084, 0xE4EB573B,
0x602F64A4, 0xD63ACD9C, 0x1BBC4635, 0x9E81032D,
0x2701F50C, 0x99847AB4, 0xA0E3DF79, 0xBA6CF38C,
0x10843094, 0x2537A95E, 0xF46F6FFE, 0xA1FF3B1F,
0x208CFB6A, 0x8F458C74, 0xD9E0A227, 0x4EC73A34,
0xFC884F69, 0x3E4DE8DF, 0xEF0E0088, 0x3559648D,
0x8A45388C, 0x1D804366, 0x721D9BFD, 0xA58684BB,
0xE8256333, 0x844E8212, 0x128D8098, 0xFED33FB4,
0xCE280AE1, 0x27E19BA5, 0xD5A6C252, 0xE49754BD,
0xC5D655DD, 0xEB667064, 0x77840B4D, 0xA1B6A801,
0x84DB26A9, 0xE0B56714, 0x21F043B7, 0xE5D05860,
0x54F03084, 0x066FF472, 0xA31AA153, 0xDADC4755,
0xB5625DBF, 0x68561BE6, 0x83CA6B94, 0x2D6ED23B,
0xECCF01DB, 0xA6D3D0BA, 0xB6803D5C, 0xAF77A709,
0x33B4A34C, 0x397BC8D6, 0x5EE22B95, 0x5F0E5304,
0x81ED6F61, 0x20E74364, 0xB45E1378, 0xDE18639B,
0x881CA122, 0xB96726D1, 0x8049A7E8, 0x22B7DA7B,
0x5E552D25, 0x5272D237, 0x79D2951C, 0xC60D894C,
0x488CB402, 0x1BA4FE5B, 0xA4B09F6B, 0x1CA815CF,
0xA20C3005, 0x8871DF63, 0xB9DE2FCB, 0x0CC6C9E9,
0x0BEEFF53, 0xE3214517, 0xB4542835, 0x9F63293C,
0xEE41E729, 0x6E1D2D7C, 0x50045286, 0x1E6685F3,
0xF33401C6, 0x30A22C95, 0x31A70850, 0x60930F13,
0x73F98417, 0xA1269859, 0xEC645C44, 0x52C877A9,
0xCDFF33A6, 0xA02B1741, 0x7CBAD9A2, 0x2180036F,
0x50D99C08, 0xCB3F4861, 0xC26BD765, 0x64A3F6AB,
0x80342676, 0x25A75E7B, 0xE4E6D1FC, 0x20C710E6,
0xCDF0B680, 0x17844D3B, 0x31EEF84D, 0x7E0824E4,
0x2CCB49EB, 0x846A3BAE, 0x8FF77888, 0xEE5D60F6,
0x7AF75673, 0x2FDD5CDB, 0xA11631C1, 0x30F66F43,
0xB3FAEC54, 0x157FD7FA, 0xEF8579CC, 0xD152DE58,
0xDB2FFD5E, 0x8F32CE19, 0x306AF97A, 0x02F03EF8,
0x99319AD5, 0xC242FA0F, 0xA7E3EBB0, 0xC68E4906,
0xB8DA230C, 0x80823028, 0xDCDEF3C8, 0xD35FB171,
0x088A1BC8, 0xBEC0C560, 0x61A3C9E8, 0xBCA8F54D,
0xC72FEFFA, 0x22822E99, 0x82C570B4, 0xD8D94E89,
0x8B1C34BC, 0x301E16E6, 0x273BE979, 0xB0FFEAA6,
0x61D9B8C6, 0x00B24869, 0xB7FFCE3F, 0x08DC283B,
0x43DAF65A, 0xF7E19798, 0x7619B72F, 0x8F1C9BA4,
0xDC8637A0, 0x16A7D3B1, 0x9FC393B7, 0xA7136EEB,
0xC6BCC63E, 0x1A513742, 0xEF6828BC, 0x520365D6,
0x2D6A77AB, 0x3527ED4B, 0x821FD216, 0x095C6E2E,
0xDB92F2FB, 0x5EEA29CB, 0x145892F5, 0x91584F7F,
0x5483697B, 0x2667A8CC, 0x85196048, 0x8C4BACEA,
0x833860D4, 0x0D23E0F9, 0x6C387E8A, 0x0AE6D249,
0xB284600C, 0xD835731D, 0xDCB1C647, 0xAC4C56EA,
0x3EBD81B3, 0x230EABB0, 0x6438BC87, 0xF0B5B1FA,
0x8F5EA2B3, 0xFC184642, 0x0A036B7A, 0x4FB089BD,
0x649DA589, 0xA345415E, 0x5C038323, 0x3E5D3BB9,
0x43D79572, 0x7E6DD07C, 0x06DFDF1E, 0x6C6CC4EF,
0x7160A539, 0x73BFBE70, 0x83877605, 0x4523ECF1
};
static const u32 cast_sbox3[256] = {
0x8DEFC240, 0x25FA5D9F, 0xEB903DBF, 0xE810C907,
0x47607FFF, 0x369FE44B, 0x8C1FC644, 0xAECECA90,
0xBEB1F9BF, 0xEEFBCAEA, 0xE8CF1950, 0x51DF07AE,
0x920E8806, 0xF0AD0548, 0xE13C8D83, 0x927010D5,
0x11107D9F, 0x07647DB9, 0xB2E3E4D4, 0x3D4F285E,
0xB9AFA820, 0xFADE82E0, 0xA067268B, 0x8272792E,
0x553FB2C0, 0x489AE22B, 0xD4EF9794, 0x125E3FBC,
0x21FFFCEE, 0x825B1BFD, 0x9255C5ED, 0x1257A240,
0x4E1A8302, 0xBAE07FFF, 0x528246E7, 0x8E57140E,
0x3373F7BF, 0x8C9F8188, 0xA6FC4EE8, 0xC982B5A5,
0xA8C01DB7, 0x579FC264, 0x67094F31, 0xF2BD3F5F,
0x40FFF7C1, 0x1FB78DFC, 0x8E6BD2C1, 0x437BE59B,
0x99B03DBF, 0xB5DBC64B, 0x638DC0E6, 0x55819D99,
0xA197C81C, 0x4A012D6E, 0xC5884A28, 0xCCC36F71,
0xB843C213, 0x6C0743F1, 0x8309893C, 0x0FEDDD5F,
0x2F7FE850, 0xD7C07F7E, 0x02507FBF, 0x5AFB9A04,
0xA747D2D0, 0x1651192E, 0xAF70BF3E, 0x58C31380,
0x5F98302E, 0x727CC3C4, 0x0A0FB402, 0x0F7FEF82,
0x8C96FDAD, 0x5D2C2AAE, 0x8EE99A49, 0x50DA88B8,
0x8427F4A0, 0x1EAC5790, 0x796FB449, 0x8252DC15,
0xEFBD7D9B, 0xA672597D, 0xADA840D8, 0x45F54504,
0xFA5D7403, 0xE83EC305, 0x4F91751A, 0x925669C2,
0x23EFE941, 0xA903F12E, 0x60270DF2, 0x0276E4B6,
0x94FD6574, 0x927985B2, 0x8276DBCB, 0x02778176,
0xF8AF918D, 0x4E48F79E, 0x8F616DDF, 0xE29D840E,
0x842F7D83, 0x340CE5C8, 0x96BBB682, 0x93B4B148,
0xEF303CAB, 0x984FAF28, 0x779FAF9B, 0x92DC560D,
0x224D1E20, 0x8437AA88, 0x7D29DC96, 0x2756D3DC,
0x8B907CEE, 0xB51FD240, 0xE7C07CE3, 0xE566B4A1,
0xC3E9615E, 0x3CF8209D, 0x6094D1E3, 0xCD9CA341,
0x5C76460E, 0x00EA983B, 0xD4D67881, 0xFD47572C,
0xF76CEDD9, 0xBDA8229C, 0x127DADAA, 0x438A074E,
0x1F97C090, 0x081BDB8A, 0x93A07EBE, 0xB938CA15,
0x97B03CFF, 0x3DC2C0F8, 0x8D1AB2EC, 0x64380E51,
0x68CC7BFB, 0xD90F2788, 0x12490181, 0x5DE5FFD4,
0xDD7EF86A, 0x76A2E214, 0xB9A40368, 0x925D958F,
0x4B39FFFA, 0xBA39AEE9, 0xA4FFD30B, 0xFAF7933B,
0x6D498623, 0x193CBCFA, 0x27627545, 0x825CF47A,
0x61BD8BA0, 0xD11E42D1, 0xCEAD04F4, 0x127EA392,
0x10428DB7, 0x8272A972, 0x9270C4A8, 0x127DE50B,
0x285BA1C8, 0x3C62F44F, 0x35C0EAA5, 0xE805D231,
0x428929FB, 0xB4FCDF82, 0x4FB66A53, 0x0E7DC15B,
0x1F081FAB, 0x108618AE, 0xFCFD086D, 0xF9FF2889,
0x694BCC11, 0x236A5CAE, 0x12DECA4D, 0x2C3F8CC5,
0xD2D02DFE, 0xF8EF5896, 0xE4CF52DA, 0x95155B67,
0x494A488C, 0xB9B6A80C, 0x5C8F82BC, 0x89D36B45,
0x3A609437, 0xEC00C9A9, 0x44715253, 0x0A874B49,
0xD773BC40, 0x7C34671C, 0x02717EF6, 0x4FEB5536,
0xA2D02FFF, 0xD2BF60C4, 0xD43F03C0, 0x50B4EF6D,
0x07478CD1, 0x006E1888, 0xA2E53F55, 0xB9E6D4BC,
0xA2048016, 0x97573833, 0xD7207D67, 0xDE0F8F3D,
0x72F87B33, 0xABCC4F33, 0x7688C55D, 0x7B00A6B0,
0x947B0001, 0x570075D2, 0xF9BB88F8, 0x8942019E,
0x4264A5FF, 0x856302E0, 0x72DBD92B, 0xEE971B69,
0x6EA22FDE, 0x5F08AE2B, 0xAF7A616D, 0xE5C98767,
0xCF1FEBD2, 0x61EFC8C2, 0xF1AC2571, 0xCC8239C2,
0x67214CB8, 0xB1E583D1, 0xB7DC3E62, 0x7F10BDCE,
0xF90A5C38, 0x0FF0443D, 0x606E6DC6, 0x60543A49,
0x5727C148, 0x2BE98A1D, 0x8AB41738, 0x20E1BE24,
0xAF96DA0F, 0x68458425, 0x99833BE5, 0x600D457D,
0x282F9350, 0x8334B362, 0xD91D1120, 0x2B6D8DA0,
0x642B1E31, 0x9C305A00, 0x52BCE688, 0x1B03588A,
0xF7BAEFD5, 0x4142ED9C, 0xA4315C11, 0x83323EC5,
0xDFEF4636, 0xA133C501, 0xE9D3531C, 0xEE353783
};
static const u32 cast_sbox4[256] = {
0x9DB30420, 0x1FB6E9DE, 0xA7BE7BEF, 0xD273A298,
0x4A4F7BDB, 0x64AD8C57, 0x85510443, 0xFA020ED1,
0x7E287AFF, 0xE60FB663, 0x095F35A1, 0x79EBF120,
0xFD059D43, 0x6497B7B1, 0xF3641F63, 0x241E4ADF,
0x28147F5F, 0x4FA2B8CD, 0xC9430040, 0x0CC32220,
0xFDD30B30, 0xC0A5374F, 0x1D2D00D9, 0x24147B15,
0xEE4D111A, 0x0FCA5167, 0x71FF904C, 0x2D195FFE,
0x1A05645F, 0x0C13FEFE, 0x081B08CA, 0x05170121,
0x80530100, 0xE83E5EFE, 0xAC9AF4F8, 0x7FE72701,
0xD2B8EE5F, 0x06DF4261, 0xBB9E9B8A, 0x7293EA25,
0xCE84FFDF, 0xF5718801, 0x3DD64B04, 0xA26F263B,
0x7ED48400, 0x547EEBE6, 0x446D4CA0, 0x6CF3D6F5,
0x2649ABDF, 0xAEA0C7F5, 0x36338CC1, 0x503F7E93,
0xD3772061, 0x11B638E1, 0x72500E03, 0xF80EB2BB,
0xABE0502E, 0xEC8D77DE, 0x57971E81, 0xE14F6746,
0xC9335400, 0x6920318F, 0x081DBB99, 0xFFC304A5,
0x4D351805, 0x7F3D5CE3, 0xA6C866C6, 0x5D5BCCA9,
0xDAEC6FEA, 0x9F926F91, 0x9F46222F, 0x3991467D,
0xA5BF6D8E, 0x1143C44F, 0x43958302, 0xD0214EEB,
0x022083B8, 0x3FB6180C, 0x18F8931E, 0x281658E6,
0x26486E3E, 0x8BD78A70, 0x7477E4C1, 0xB506E07C,
0xF32D0A25, 0x79098B02, 0xE4EABB81, 0x28123B23,
0x69DEAD38, 0x1574CA16, 0xDF871B62, 0x211C40B7,
0xA51A9EF9, 0x0014377B, 0x041E8AC8, 0x09114003,
0xBD59E4D2, 0xE3D156D5, 0x4FE876D5, 0x2F91A340,
0x557BE8DE, 0x00EAE4A7, 0x0CE5C2EC, 0x4DB4BBA6,
0xE756BDFF, 0xDD3369AC, 0xEC17B035, 0x06572327,
0x99AFC8B0, 0x56C8C391, 0x6B65811C, 0x5E146119,
0x6E85CB75, 0xBE07C002, 0xC2325577, 0x893FF4EC,
0x5BBFC92D, 0xD0EC3B25, 0xB7801AB7, 0x8D6D3B24,
0x20C763EF, 0xC366A5FC, 0x9C382880, 0x0ACE3205,
0xAAC9548A, 0xECA1D7C7, 0x041AFA32, 0x1D16625A,
0x6701902C, 0x9B757A54, 0x31D477F7, 0x9126B031,
0x36CC6FDB, 0xC70B8B46, 0xD9E66A48, 0x56E55A79,
0x026A4CEB, 0x52437EFF, 0x2F8F76B4, 0x0DF980A5,
0x8674CDE3, 0xEDDA04EB, 0x17A9BE04, 0x2C18F4DF,
0xB7747F9D, 0xAB2AF7B4, 0xEFC34D20, 0x2E096B7C,
0x1741A254, 0xE5B6A035, 0x213D42F6, 0x2C1C7C26,
0x61C2F50F, 0x6552DAF9, 0xD2C231F8, 0x25130F69,
0xD8167FA2, 0x0418F2C8, 0x001A96A6, 0x0D1526AB,
0x63315C21, 0x5E0A72EC, 0x49BAFEFD, 0x187908D9,
0x8D0DBD86, 0x311170A7, 0x3E9B640C, 0xCC3E10D7,
0xD5CAD3B6, 0x0CAEC388, 0xF73001E1, 0x6C728AFF,
0x71EAE2A1, 0x1F9AF36E, 0xCFCBD12F, 0xC1DE8417,
0xAC07BE6B, 0xCB44A1D8, 0x8B9B0F56, 0x013988C3,
0xB1C52FCA, 0xB4BE31CD, 0xD8782806, 0x12A3A4E2,
0x6F7DE532, 0x58FD7EB6, 0xD01EE900, 0x24ADFFC2,
0xF4990FC5, 0x9711AAC5, 0x001D7B95, 0x82E5E7D2,
0x109873F6, 0x00613096, 0xC32D9521, 0xADA121FF,
0x29908415, 0x7FBB977F, 0xAF9EB3DB, 0x29C9ED2A,
0x5CE2A465, 0xA730F32C, 0xD0AA3FE8, 0x8A5CC091,
0xD49E2CE7, 0x0CE454A9, 0xD60ACD86, 0x015F1919,
0x77079103, 0xDEA03AF6, 0x78A8565E, 0xDEE356DF,
0x21F05CBE, 0x8B75E387, 0xB3C50651, 0xB8A5C3EF,
0xD8EEB6D2, 0xE523BE77, 0xC2154529, 0x2F69EFDF,
0xAFE67AFB, 0xF470C4B2, 0xF3E0EB5B, 0xD6CC9876,
0x39E4460C, 0x1FDA8538, 0x1987832F, 0xCA007367,
0xA99144F8, 0x296B299E, 0x492FC295, 0x9266BEAB,
0xB5676E69, 0x9BD3DDDA, 0xDF7E052F, 0xDB25701C,
0x1B5E51EE, 0xF65324E6, 0x6AFCE36C, 0x0316CC04,
0x8644213E, 0xB7DC59D0, 0x7965291F, 0xCCD6FD43,
0x41823979, 0x932BCDF6, 0xB657C34D, 0x4EDFD282,
0x7AE5290C, 0x3CB9536B, 0x851E20FE, 0x9833557E,
0x13ECF0B0, 0xD3FFB372, 0x3F85C5C1, 0x0AEF7ED2
};
static const u32 cast_sbox5[256] = {
0x7EC90C04, 0x2C6E74B9, 0x9B0E66DF, 0xA6337911,
0xB86A7FFF, 0x1DD358F5, 0x44DD9D44, 0x1731167F,
0x08FBF1FA, 0xE7F511CC, 0xD2051B00, 0x735ABA00,
0x2AB722D8, 0x386381CB, 0xACF6243A, 0x69BEFD7A,
0xE6A2E77F, 0xF0C720CD, 0xC4494816, 0xCCF5C180,
0x38851640, 0x15B0A848, 0xE68B18CB, 0x4CAADEFF,
0x5F480A01, 0x0412B2AA, 0x259814FC, 0x41D0EFE2,
0x4E40B48D, 0x248EB6FB, 0x8DBA1CFE, 0x41A99B02,
0x1A550A04, 0xBA8F65CB, 0x7251F4E7, 0x95A51725,
0xC106ECD7, 0x97A5980A, 0xC539B9AA, 0x4D79FE6A,
0xF2F3F763, 0x68AF8040, 0xED0C9E56, 0x11B4958B,
0xE1EB5A88, 0x8709E6B0, 0xD7E07156, 0x4E29FEA7,
0x6366E52D, 0x02D1C000, 0xC4AC8E05, 0x9377F571,
0x0C05372A, 0x578535F2, 0x2261BE02, 0xD642A0C9,
0xDF13A280, 0x74B55BD2, 0x682199C0, 0xD421E5EC,
0x53FB3CE8, 0xC8ADEDB3, 0x28A87FC9, 0x3D959981,
0x5C1FF900, 0xFE38D399, 0x0C4EFF0B, 0x062407EA,
0xAA2F4FB1, 0x4FB96976, 0x90C79505, 0xB0A8A774,
0xEF55A1FF, 0xE59CA2C2, 0xA6B62D27, 0xE66A4263,
0xDF65001F, 0x0EC50966, 0xDFDD55BC, 0x29DE0655,
0x911E739A, 0x17AF8975, 0x32C7911C, 0x89F89468,
0x0D01E980, 0x524755F4, 0x03B63CC9, 0x0CC844B2,
0xBCF3F0AA, 0x87AC36E9, 0xE53A7426, 0x01B3D82B,
0x1A9E7449, 0x64EE2D7E, 0xCDDBB1DA, 0x01C94910,
0xB868BF80, 0x0D26F3FD, 0x9342EDE7, 0x04A5C284,
0x636737B6, 0x50F5B616, 0xF24766E3, 0x8ECA36C1,
0x136E05DB, 0xFEF18391, 0xFB887A37, 0xD6E7F7D4,
0xC7FB7DC9, 0x3063FCDF, 0xB6F589DE, 0xEC2941DA,
0x26E46695, 0xB7566419, 0xF654EFC5, 0xD08D58B7,
0x48925401, 0xC1BACB7F, 0xE5FF550F, 0xB6083049,
0x5BB5D0E8, 0x87D72E5A, 0xAB6A6EE1, 0x223A66CE,
0xC62BF3CD, 0x9E0885F9, 0x68CB3E47, 0x086C010F,
0xA21DE820, 0xD18B69DE, 0xF3F65777, 0xFA02C3F6,
0x407EDAC3, 0xCBB3D550, 0x1793084D, 0xB0D70EBA,
0x0AB378D5, 0xD951FB0C, 0xDED7DA56, 0x4124BBE4,
0x94CA0B56, 0x0F5755D1, 0xE0E1E56E, 0x6184B5BE,
0x580A249F, 0x94F74BC0, 0xE327888E, 0x9F7B5561,
0xC3DC0280, 0x05687715, 0x646C6BD7, 0x44904DB3,
0x66B4F0A3, 0xC0F1648A, 0x697ED5AF, 0x49E92FF6,
0x309E374F, 0x2CB6356A, 0x85808573, 0x4991F840,
0x76F0AE02, 0x083BE84D, 0x28421C9A, 0x44489406,
0x736E4CB8, 0xC1092910, 0x8BC95FC6, 0x7D869CF4,
0x134F616F, 0x2E77118D, 0xB31B2BE1, 0xAA90B472,
0x3CA5D717, 0x7D161BBA, 0x9CAD9010, 0xAF462BA2,
0x9FE459D2, 0x45D34559, 0xD9F2DA13, 0xDBC65487,
0xF3E4F94E, 0x176D486F, 0x097C13EA, 0x631DA5C7,
0x445F7382, 0x175683F4, 0xCDC66A97, 0x70BE0288,
0xB3CDCF72, 0x6E5DD2F3, 0x20936079, 0x459B80A5,
0xBE60E2DB, 0xA9C23101, 0xEBA5315C, 0x224E42F2,
0x1C5C1572, 0xF6721B2C, 0x1AD2FFF3, 0x8C25404E,
0x324ED72F, 0x4067B7FD, 0x0523138E, 0x5CA3BC78,
0xDC0FD66E, 0x75922283, 0x784D6B17, 0x58EBB16E,
0x44094F85, 0x3F481D87, 0xFCFEAE7B, 0x77B5FF76,
0x8C2302BF, 0xAAF47556, 0x5F46B02A, 0x2B092801,
0x3D38F5F7, 0x0CA81F36, 0x52AF4A8A, 0x66D5E7C0,
0xDF3B0874, 0x95055110, 0x1B5AD7A8, 0xF61ED5AD,
0x6CF6E479, 0x20758184, 0xD0CEFA65, 0x88F7BE58,
0x4A046826, 0x0FF6F8F3, 0xA09C7F70, 0x5346ABA0,
0x5CE96C28, 0xE176EDA3, 0x6BAC307F, 0x376829D2,
0x85360FA9, 0x17E3FE2A, 0x24B79767, 0xF5A96B20,
0xD6CD2595, 0x68FF1EBF, 0x7555442C, 0xF19F06BE,
0xF9E0659A, 0xEEB9491D, 0x34010718, 0xBB30CAB8,
0xE822FE15, 0x88570983, 0x750E6249, 0xDA627E55,
0x5E76FFA8, 0xB1534546, 0x6D47DE08, 0xEFE9E7D4
};
static const u32 cast_sbox6[256] = {
0xF6FA8F9D, 0x2CAC6CE1, 0x4CA34867, 0xE2337F7C,
0x95DB08E7, 0x016843B4, 0xECED5CBC, 0x325553AC,
0xBF9F0960, 0xDFA1E2ED, 0x83F0579D, 0x63ED86B9,
0x1AB6A6B8, 0xDE5EBE39, 0xF38FF732, 0x8989B138,
0x33F14961, 0xC01937BD, 0xF506C6DA, 0xE4625E7E,
0xA308EA99, 0x4E23E33C, 0x79CBD7CC, 0x48A14367,
0xA3149619, 0xFEC94BD5, 0xA114174A, 0xEAA01866,
0xA084DB2D, 0x09A8486F, 0xA888614A, 0x2900AF98,
0x01665991, 0xE1992863, 0xC8F30C60, 0x2E78EF3C,
0xD0D51932, 0xCF0FEC14, 0xF7CA07D2, 0xD0A82072,
0xFD41197E, 0x9305A6B0, 0xE86BE3DA, 0x74BED3CD,
0x372DA53C, 0x4C7F4448, 0xDAB5D440, 0x6DBA0EC3,
0x083919A7, 0x9FBAEED9, 0x49DBCFB0, 0x4E670C53,
0x5C3D9C01, 0x64BDB941, 0x2C0E636A, 0xBA7DD9CD,
0xEA6F7388, 0xE70BC762, 0x35F29ADB, 0x5C4CDD8D,
0xF0D48D8C, 0xB88153E2, 0x08A19866, 0x1AE2EAC8,
0x284CAF89, 0xAA928223, 0x9334BE53, 0x3B3A21BF,
0x16434BE3, 0x9AEA3906, 0xEFE8C36E, 0xF890CDD9,
0x80226DAE, 0xC340A4A3, 0xDF7E9C09, 0xA694A807,
0x5B7C5ECC, 0x221DB3A6, 0x9A69A02F, 0x68818A54,
0xCEB2296F, 0x53C0843A, 0xFE893655, 0x25BFE68A,
0xB4628ABC, 0xCF222EBF, 0x25AC6F48, 0xA9A99387,
0x53BDDB65, 0xE76FFBE7, 0xE967FD78, 0x0BA93563,
0x8E342BC1, 0xE8A11BE9, 0x4980740D, 0xC8087DFC,
0x8DE4BF99, 0xA11101A0, 0x7FD37975, 0xDA5A26C0,
0xE81F994F, 0x9528CD89, 0xFD339FED, 0xB87834BF,
0x5F04456D, 0x22258698, 0xC9C4C83B, 0x2DC156BE,
0x4F628DAA, 0x57F55EC5, 0xE2220ABE, 0xD2916EBF,
0x4EC75B95, 0x24F2C3C0, 0x42D15D99, 0xCD0D7FA0,
0x7B6E27FF, 0xA8DC8AF0, 0x7345C106, 0xF41E232F,
0x35162386, 0xE6EA8926, 0x3333B094, 0x157EC6F2,
0x372B74AF, 0x692573E4, 0xE9A9D848, 0xF3160289,
0x3A62EF1D, 0xA787E238, 0xF3A5F676, 0x74364853,
0x20951063, 0x4576698D, 0xB6FAD407, 0x592AF950,
0x36F73523, 0x4CFB6E87, 0x7DA4CEC0, 0x6C152DAA,
0xCB0396A8, 0xC50DFE5D, 0xFCD707AB, 0x0921C42F,
0x89DFF0BB, 0x5FE2BE78, 0x448F4F33, 0x754613C9,
0x2B05D08D, 0x48B9D585, 0xDC049441, 0xC8098F9B,
0x7DEDE786, 0xC39A3373, 0x42410005, 0x6A091751,
0x0EF3C8A6, 0x890072D6, 0x28207682, 0xA9A9F7BE,
0xBF32679D, 0xD45B5B75, 0xB353FD00, 0xCBB0E358,
0x830F220A, 0x1F8FB214, 0xD372CF08, 0xCC3C4A13,
0x8CF63166, 0x061C87BE, 0x88C98F88, 0x6062E397,
0x47CF8E7A, 0xB6C85283, 0x3CC2ACFB, 0x3FC06976,
0x4E8F0252, 0x64D8314D, 0xDA3870E3, 0x1E665459,
0xC10908F0, 0x513021A5, 0x6C5B68B7, 0x822F8AA0,
0x3007CD3E, 0x74719EEF, 0xDC872681, 0x073340D4,
0x7E432FD9, 0x0C5EC241, 0x8809286C, 0xF592D891,
0x08A930F6, 0x957EF305, 0xB7FBFFBD, 0xC266E96F,
0x6FE4AC98, 0xB173ECC0, 0xBC60B42A, 0x953498DA,
0xFBA1AE12, 0x2D4BD736, 0x0F25FAAB, 0xA4F3FCEB,
0xE2969123, 0x257F0C3D, 0x9348AF49, 0x361400BC,
0xE8816F4A, 0x3814F200, 0xA3F94043, 0x9C7A54C2,
0xBC704F57, 0xDA41E7F9, 0xC25AD33A, 0x54F4A084,
0xB17F5505, 0x59357CBE, 0xEDBD15C8, 0x7F97C5AB,
0xBA5AC7B5, 0xB6F6DEAF, 0x3A479C3A, 0x5302DA25,
0x653D7E6A, 0x54268D49, 0x51A477EA, 0x5017D55B,
0xD7D25D88, 0x44136C76, 0x0404A8C8, 0xB8E5A121,
0xB81A928A, 0x60ED5869, 0x97C55B96, 0xEAEC991B,
0x29935913, 0x01FDB7F1, 0x088E8DFA, 0x9AB6F6F5,
0x3B4CBF9F, 0x4A5DE3AB, 0xE6051D35, 0xA0E1D855,
0xD36B4CF1, 0xF544EDEB, 0xB0E93524, 0xBEBB8FBD,
0xA2D762CF, 0x49C92F54, 0x38B5F331, 0x7128A454,
0x48392905, 0xA65B1DB8, 0x851C97BD, 0xD675CF2F
};
static const u32 cast_sbox7[256] = {
0x85E04019, 0x332BF567, 0x662DBFFF, 0xCFC65693,
0x2A8D7F6F, 0xAB9BC912, 0xDE6008A1, 0x2028DA1F,
0x0227BCE7, 0x4D642916, 0x18FAC300, 0x50F18B82,
0x2CB2CB11, 0xB232E75C, 0x4B3695F2, 0xB28707DE,
0xA05FBCF6, 0xCD4181E9, 0xE150210C, 0xE24EF1BD,
0xB168C381, 0xFDE4E789, 0x5C79B0D8, 0x1E8BFD43,
0x4D495001, 0x38BE4341, 0x913CEE1D, 0x92A79C3F,
0x089766BE, 0xBAEEADF4, 0x1286BECF, 0xB6EACB19,
0x2660C200, 0x7565BDE4, 0x64241F7A, 0x8248DCA9,
0xC3B3AD66, 0x28136086, 0x0BD8DFA8, 0x356D1CF2,
0x107789BE, 0xB3B2E9CE, 0x0502AA8F, 0x0BC0351E,
0x166BF52A, 0xEB12FF82, 0xE3486911, 0xD34D7516,
0x4E7B3AFF, 0x5F43671B, 0x9CF6E037, 0x4981AC83,
0x334266CE, 0x8C9341B7, 0xD0D854C0, 0xCB3A6C88,
0x47BC2829, 0x4725BA37, 0xA66AD22B, 0x7AD61F1E,
0x0C5CBAFA, 0x4437F107, 0xB6E79962, 0x42D2D816,
0x0A961288, 0xE1A5C06E, 0x13749E67, 0x72FC081A,
0xB1D139F7, 0xF9583745, 0xCF19DF58, 0xBEC3F756,
0xC06EBA30, 0x07211B24, 0x45C28829, 0xC95E317F,
0xBC8EC511, 0x38BC46E9, 0xC6E6FA14, 0xBAE8584A,
0xAD4EBC46, 0x468F508B, 0x7829435F, 0xF124183B,
0x821DBA9F, 0xAFF60FF4, 0xEA2C4E6D, 0x16E39264,
0x92544A8B, 0x009B4FC3, 0xABA68CED, 0x9AC96F78,
0x06A5B79A, 0xB2856E6E, 0x1AEC3CA9, 0xBE838688,
0x0E0804E9, 0x55F1BE56, 0xE7E5363B, 0xB3A1F25D,
0xF7DEBB85, 0x61FE033C, 0x16746233, 0x3C034C28,
0xDA6D0C74, 0x79AAC56C, 0x3CE4E1AD, 0x51F0C802,
0x98F8F35A, 0x1626A49F, 0xEED82B29, 0x1D382FE3,
0x0C4FB99A, 0xBB325778, 0x3EC6D97B, 0x6E77A6A9,
0xCB658B5C, 0xD45230C7, 0x2BD1408B, 0x60C03EB7,
0xB9068D78, 0xA33754F4, 0xF430C87D, 0xC8A71302,
0xB96D8C32, 0xEBD4E7BE, 0xBE8B9D2D, 0x7979FB06,
0xE7225308, 0x8B75CF77, 0x11EF8DA4, 0xE083C858,
0x8D6B786F, 0x5A6317A6, 0xFA5CF7A0, 0x5DDA0033,
0xF28EBFB0, 0xF5B9C310, 0xA0EAC280, 0x08B9767A,
0xA3D9D2B0, 0x79D34217, 0x021A718D, 0x9AC6336A,
0x2711FD60, 0x438050E3, 0x069908A8, 0x3D7FEDC4,
0x826D2BEF, 0x4EEB8476, 0x488DCF25, 0x36C9D566,
0x28E74E41, 0xC2610ACA, 0x3D49A9CF, 0xBAE3B9DF,
0xB65F8DE6, 0x92AEAF64, 0x3AC7D5E6, 0x9EA80509,
0xF22B017D, 0xA4173F70, 0xDD1E16C3, 0x15E0D7F9,
0x50B1B887, 0x2B9F4FD5, 0x625ABA82, 0x6A017962,
0x2EC01B9C, 0x15488AA9, 0xD716E740, 0x40055A2C,
0x93D29A22, 0xE32DBF9A, 0x058745B9, 0x3453DC1E,
0xD699296E, 0x496CFF6F, 0x1C9F4986, 0xDFE2ED07,
0xB87242D1, 0x19DE7EAE, 0x053E561A, 0x15AD6F8C,
0x66626C1C, 0x7154C24C, 0xEA082B2A, 0x93EB2939,
0x17DCB0F0, 0x58D4F2AE, 0x9EA294FB, 0x52CF564C,
0x9883FE66, 0x2EC40581, 0x763953C3, 0x01D6692E,
0xD3A0C108, 0xA1E7160E, 0xE4F2DFA6, 0x693ED285,
0x74904698, 0x4C2B0EDD, 0x4F757656, 0x5D393378,
0xA132234F, 0x3D321C5D, 0xC3F5E194, 0x4B269301,
0xC79F022F, 0x3C997E7E, 0x5E4F9504, 0x3FFAFBBD,
0x76F7AD0E, 0x296693F4, 0x3D1FCE6F, 0xC61E45BE,
0xD3B5AB34, 0xF72BF9B7, 0x1B0434C0, 0x4E72B567,
0x5592A33D, 0xB5229301, 0xCFD2A87F, 0x60AEB767,
0x1814386B, 0x30BCC33D, 0x38A0C07D, 0xFD1606F2,
0xC363519B, 0x589DD390, 0x5479F8E6, 0x1CB8D647,
0x97FD61A9, 0xEA7759F4, 0x2D57539D, 0x569A58CF,
0xE84E63AD, 0x462E1B78, 0x6580F87E, 0xF3817914,
0x91DA55F4, 0x40A230F3, 0xD1988F35, 0xB6E318D2,
0x3FFA50BC, 0x3D40F021, 0xC3C0BDAE, 0x4958C24C,
0x518F36B2, 0x84B1D370, 0x0FEDCE83, 0x878DDADA,
0xF2A279C7, 0x94E01BE8, 0x90716F4B, 0x954B8AA3
};
static const u32 cast_sbox8[256] = {
0xE216300D, 0xBBDDFFFC, 0xA7EBDABD, 0x35648095,
0x7789F8B7, 0xE6C1121B, 0x0E241600, 0x052CE8B5,
0x11A9CFB0, 0xE5952F11, 0xECE7990A, 0x9386D174,
0x2A42931C, 0x76E38111, 0xB12DEF3A, 0x37DDDDFC,
0xDE9ADEB1, 0x0A0CC32C, 0xBE197029, 0x84A00940,
0xBB243A0F, 0xB4D137CF, 0xB44E79F0, 0x049EEDFD,
0x0B15A15D, 0x480D3168, 0x8BBBDE5A, 0x669DED42,
0xC7ECE831, 0x3F8F95E7, 0x72DF191B, 0x7580330D,
0x94074251, 0x5C7DCDFA, 0xABBE6D63, 0xAA402164,
0xB301D40A, 0x02E7D1CA, 0x53571DAE, 0x7A3182A2,
0x12A8DDEC, 0xFDAA335D, 0x176F43E8, 0x71FB46D4,
0x38129022, 0xCE949AD4, 0xB84769AD, 0x965BD862,
0x82F3D055, 0x66FB9767, 0x15B80B4E, 0x1D5B47A0,
0x4CFDE06F, 0xC28EC4B8, 0x57E8726E, 0x647A78FC,
0x99865D44, 0x608BD593, 0x6C200E03, 0x39DC5FF6,
0x5D0B00A3, 0xAE63AFF2, 0x7E8BD632, 0x70108C0C,
0xBBD35049, 0x2998DF04, 0x980CF42A, 0x9B6DF491,
0x9E7EDD53, 0x06918548, 0x58CB7E07, 0x3B74EF2E,
0x522FFFB1, 0xD24708CC, 0x1C7E27CD, 0xA4EB215B,
0x3CF1D2E2, 0x19B47A38, 0x424F7618, 0x35856039,
0x9D17DEE7, 0x27EB35E6, 0xC9AFF67B, 0x36BAF5B8,
0x09C467CD, 0xC18910B1, 0xE11DBF7B, 0x06CD1AF8,
0x7170C608, 0x2D5E3354, 0xD4DE495A, 0x64C6D006,
0xBCC0C62C, 0x3DD00DB3, 0x708F8F34, 0x77D51B42,
0x264F620F, 0x24B8D2BF, 0x15C1B79E, 0x46A52564,
0xF8D7E54E, 0x3E378160, 0x7895CDA5, 0x859C15A5,
0xE6459788, 0xC37BC75F, 0xDB07BA0C, 0x0676A3AB,
0x7F229B1E, 0x31842E7B, 0x24259FD7, 0xF8BEF472,
0x835FFCB8, 0x6DF4C1F2, 0x96F5B195, 0xFD0AF0FC,
0xB0FE134C, 0xE2506D3D, 0x4F9B12EA, 0xF215F225,
0xA223736F, 0x9FB4C428, 0x25D04979, 0x34C713F8,
0xC4618187, 0xEA7A6E98, 0x7CD16EFC, 0x1436876C,
0xF1544107, 0xBEDEEE14, 0x56E9AF27, 0xA04AA441,
0x3CF7C899, 0x92ECBAE6, 0xDD67016D, 0x151682EB,
0xA842EEDF, 0xFDBA60B4, 0xF1907B75, 0x20E3030F,
0x24D8C29E, 0xE139673B, 0xEFA63FB8, 0x71873054,
0xB6F2CF3B, 0x9F326442, 0xCB15A4CC, 0xB01A4504,
0xF1E47D8D, 0x844A1BE5, 0xBAE7DFDC, 0x42CBDA70,
0xCD7DAE0A, 0x57E85B7A, 0xD53F5AF6, 0x20CF4D8C,
0xCEA4D428, 0x79D130A4, 0x3486EBFB, 0x33D3CDDC,
0x77853B53, 0x37EFFCB5, 0xC5068778, 0xE580B3E6,
0x4E68B8F4, 0xC5C8B37E, 0x0D809EA2, 0x398FEB7C,
0x132A4F94, 0x43B7950E, 0x2FEE7D1C, 0x223613BD,
0xDD06CAA2, 0x37DF932B, 0xC4248289, 0xACF3EBC3,
0x5715F6B7, 0xEF3478DD, 0xF267616F, 0xC148CBE4,
0x9052815E, 0x5E410FAB, 0xB48A2465, 0x2EDA7FA4,
0xE87B40E4, 0xE98EA084, 0x5889E9E1, 0xEFD390FC,
0xDD07D35B, 0xDB485694, 0x38D7E5B2, 0x57720101,
0x730EDEBC, 0x5B643113, 0x94917E4F, 0x503C2FBA,
0x646F1282, 0x7523D24A, 0xE0779695, 0xF9C17A8F,
0x7A5B2121, 0xD187B896, 0x29263A4D, 0xBA510CDF,
0x81F47C9F, 0xAD1163ED, 0xEA7B5965, 0x1A00726E,
0x11403092, 0x00DA6D77, 0x4A0CDD61, 0xAD1F4603,
0x605BDFB0, 0x9EEDC364, 0x22EBE6A8, 0xCEE7D28A,
0xA0E736A0, 0x5564A6B9, 0x10853209, 0xC7EB8F37,
0x2DE705CA, 0x8951570F, 0xDF09822B, 0xBD691A6C,
0xAA12E4F2, 0x87451C0F, 0xE0F6A27A, 0x3ADA4819,
0x4CF1764F, 0x0D771C2B, 0x67CDB156, 0x350D8384,
0x5938FA0F, 0x42399EF3, 0x36997B07, 0x0E84093D,
0x4AA93E61, 0x8360D87B, 0x1FA98B0C, 0x1149382C,
0xE97625A5, 0x0614D1B7, 0x0E25244B, 0x0C768347,
0x589E8D82, 0x0D2059D1, 0xA466BB1E, 0xF8DA0A82,
0x04F19130, 0xBA6E4EC0, 0x99265164, 0x1EE7230D,
0x50B2AD80, 0xEAEE6801, 0x8DB2A283, 0xEA8BF59E
};
@@ -0,0 +1,581 @@
/* This is an independent implementation of the encryption algorithm: */
/* */
/* CAST-256 by Carlisle Adams of Entrust Tecnhologies */
/* */
/* which is a candidate algorithm in the Advanced Encryption Standard */
/* programme of the US National Institute of Standards and Technology. */
/* */
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
/* */
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: cast-256.c,v 1.13 2003/01/19 17:48:27 nmav Exp $ */
/* modified for mcrypt */
/* Timing data for CAST-256 (cast.c)
Core timing without I/O endian conversion:
128 bit key:
Key Setup: 4333 cycles
Encrypt: 633 cycles = 40.4 mbits/sec
Decrypt: 634 cycles = 40.4 mbits/sec
Mean: 634 cycles = 40.4 mbits/sec
192 bit key:
Key Setup: 4342 cycles
Encrypt: 633 cycles = 40.4 mbits/sec
Decrypt: 633 cycles = 40.4 mbits/sec
Mean: 633 cycles = 40.4 mbits/sec
256 bit key:
Key Setup: 4325 cycles
Encrypt: 639 cycles = 40.1 mbits/sec
Decrypt: 638 cycles = 40.1 mbits/sec
Mean: 639 cycles = 40.1 mbits/sec
Full timing with I/O endian conversion:
128 bit key:
Key Setup: 4294 cycles
Encrypt: 678 cycles = 37.8 mbits/sec
Decrypt: 669 cycles = 38.3 mbits/sec
Mean: 674 cycles = 38.0 mbits/sec
192 bit key:
Key Setup: 4314 cycles
Encrypt: 678 cycles = 37.8 mbits/sec
Decrypt: 670 cycles = 38.2 mbits/sec
Mean: 674 cycles = 38.0 mbits/sec
256 bit key:
Key Setup: 4313 cycles
Encrypt: 678 cycles = 37.8 mbits/sec
Decrypt: 669 cycles = 38.3 mbits/sec
Mean: 674 cycles = 38.0 mbits/sec
*/
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "cast-256.h"
#define _mcrypt_set_key cast_256_LTX__mcrypt_set_key
#define _mcrypt_encrypt cast_256_LTX__mcrypt_encrypt
#define _mcrypt_decrypt cast_256_LTX__mcrypt_decrypt
#define _mcrypt_get_size cast_256_LTX__mcrypt_get_size
#define _mcrypt_get_block_size cast_256_LTX__mcrypt_get_block_size
#define _is_block_algorithm cast_256_LTX__is_block_algorithm
#define _mcrypt_get_key_size cast_256_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes cast_256_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name cast_256_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test cast_256_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version cast_256_LTX__mcrypt_algorithm_version
#define byte(x,n) ((byte)((x) >> (8 * n)))
word32 cast256_sbox[4][256] = { {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f,
0x3f258c7a, 0x1e213f2f, 0x9C004dd3,
0x6003e540, 0xcf9fc949, 0xbfd4af27,
0x88bbbdb5, 0xe2034090, 0x98d09675,
0x6e63a0e0, 0x15c361d2, 0xc2e7661d,
0x22d4ff8e, 0x28683b6f, 0xc07fd059,
0xff2379c8, 0x775f50e2, 0x43c340d3,
0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
0xa1c9e0d6, 0x346c4819, 0x61b76d87,
0x22540f2f, 0x2abe32e1, 0xaa54166b,
0x22568e3a, 0xa2d341d0, 0x66db40c8,
0xa784392f, 0x004dff2f, 0x2db9d2de,
0x97943fac, 0x4a97c1d8, 0x527644b7,
0xb5f437a7, 0xb82cbaef, 0xd751d159,
0x6ff7f0ed, 0x5a097a1f, 0x827b68d0,
0x90ecf52e, 0x22b0c054, 0xbc8e5935,
0x4b6d2f7f, 0x50bb64a2, 0xd2664910,
0xbee5812d, 0xb7332290, 0xe93b159f,
0xb48ee411, 0x4bff345d, 0xfd45c240,
0xad31973f, 0xc4f6d02e, 0x55fc8165,
0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d,
0xc19b0C50, 0x882240f2, 0x0c6e4f38,
0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f,
0xc59c5319, 0xb949e354, 0xb04669fe,
0xb1b6ab8a, 0xc71358dd, 0x6385c545,
0x110f935d, 0x57538ad5, 0x6a390493,
0xe63d37e0, 0x2a54f6b3, 0x3a787d5f,
0x6276a0b5, 0x19a6fcdf, 0x7a42206a,
0x29f9d4d5, 0xf61b1891, 0xbb72275e,
0xaa508167, 0x38901091, 0xc6b505eb,
0x84c7cb8c, 0x2ad75a0f, 0x874a1427,
0xa2d1936b, 0x2ad286af, 0xaa56d291,
0xd7894360, 0x425c750d, 0x93b39e26,
0x187184c9, 0x6c00b32d, 0x73e2bb14,
0xa0bebc3c, 0x54623779, 0x64459eab,
0x3f328b82, 0x7718cf82, 0x59a2cea6,
0x04ee002e, 0x89fe78e6, 0x3fab0950,
0x325ff6C2, 0x81383f05, 0x6963c5c8,
0x76cb5ad6, 0xd49974c9, 0xca180dcf,
0x380782d5, 0xc7fa5cf6, 0x8ac31511,
0x35e79e13, 0x47da91d0, 0xf40f9086,
0xa7e2419e, 0x31366241, 0x051ef495,
0xaa573b04, 0x4a805d8d, 0x548300d0,
0x00322a3c, 0xbf64cddf, 0xba57a68e,
0x75c6372b, 0x50afd341, 0xa7c13275,
0x915a0bf5, 0x6b54bfab, 0x2b0b1426,
0xab4cc9d7, 0x449ccd82, 0xf7fbf265,
0xab85c5f3, 0x1b55db94, 0xaad4e324,
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02,
0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98,
0xe31231b2, 0x2ad5ad6c, 0x954329de,
0xadbe4528, 0xd8710f69, 0xaa51c90f,
0xaa786bf6, 0x22513f1e, 0xaa51a79b,
0x2ad344cc, 0x7b5a41f0, 0xd37cfbad,
0x1b069505, 0x41ece491, 0xb4c332e6,
0x032268d4, 0xc9600acc, 0xce387e6d,
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9,
0xd4df39de, 0xe01063da, 0x4736f464,
0x5ad328d8, 0xb347cc96, 0x75bb0fc3,
0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
0xe11f0abc, 0xbfc5fe4a, 0xa70aec10,
0xac39570a, 0x3f04442f, 0x6188b153,
0xe0397a2e, 0x5727cb79, 0x9ceb418f,
0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
0xc69dff09, 0xc75b65f0, 0xd9db40d8,
0xec0e7779, 0x4744ead4, 0xb11c3274,
0xdd24cb9e, 0x7e1c54bd, 0xf01144f9,
0xd2240eb1, 0x9675b3fd, 0xa3ac3755,
0xd47c27af, 0x51c85f4d, 0x56907596,
0xa5bb15e6, 0x580304f0, 0xca042cf1,
0x011a37ea, 0x8dbfaadb, 0x35ba3e4a,
0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
0x98a52666, 0x5648f725, 0xff5e569d,
0x0ced63d0, 0x7c63b2cf, 0x700b45e1,
0xd5ea50f1, 0x85a92872, 0xaf1fbda7,
0xd4234870, 0xa7870bf3, 0x2d3b4d79,
0x42e04198, 0x0cd0ede7, 0x26470db8,
0xf881814C, 0x474d6ad7, 0x7c0c5e5c,
0xd1231959, 0x381b7298, 0xf5d2f4db,
0xab838653, 0x6e2f1e23, 0x83719c9e,
0xbd91e046, 0x9a56456e, 0xdc39200c,
0x20c8c571, 0x962bda1c, 0xe1e696ff,
0xb141ab08, 0x7cca89b9, 0x1a69e783,
0x02cc4843, 0xa2f7c579, 0x429ef47d,
0x427b169c, 0x5ac9f049, 0xdd8f0f00,
0x5c8165bf}
,
{
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a,
0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba,
0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605,
0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b,
0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4,
0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083,
0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f,
0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e,
0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366,
0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4,
0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064,
0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6,
0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709,
0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364,
0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b,
0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9,
0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c,
0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741,
0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab,
0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b,
0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa,
0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028,
0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6,
0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b,
0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1,
0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb,
0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea,
0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d,
0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e,
0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef,
0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1}
,
{
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b,
0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae,
0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9,
0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd,
0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,
0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264,
0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e,
0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e,
0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790,
0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504,
0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e,
0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8,
0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d,
0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240,
0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c,
0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,
0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788,
0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa,
0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392,
0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f,
0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae,
0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9,
0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888,
0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d,
0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2,
0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2,
0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce,
0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d,
0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00,
0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5,
0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783}
,
{
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57,
0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120,
0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd,
0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe,
0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701,
0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801,
0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1,
0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3,
0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c,
0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,
0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16,
0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7,
0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327,
0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002,
0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7,
0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031,
0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff,
0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035,
0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69,
0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec,
0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e,
0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6,
0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f,
0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091,
0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6,
0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2,
0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367,
0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda,
0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6,
0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,
0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2}
};
#define f1(y,x,kr,km) \
t = rotl32(km + x, kr); \
u = cast256_sbox[0][byte(t,3)]; \
u ^= cast256_sbox[1][byte(t,2)]; \
u -= cast256_sbox[2][byte(t,1)]; \
u += cast256_sbox[3][byte(t,0)]; \
y ^= u
#define f2(y,x,kr,km) \
t = rotl32(km ^ x, kr); \
u = cast256_sbox[0][byte(t,3)]; \
u -= cast256_sbox[1][byte(t,2)]; \
u += cast256_sbox[2][byte(t,1)]; \
u ^= cast256_sbox[3][byte(t,0)]; \
y ^= u
#define f3(y,x,kr,km) \
t = rotl32(km - x, kr); \
u = cast256_sbox[0][byte(t,3)]; \
u += cast256_sbox[1][byte(t,2)]; \
u ^= cast256_sbox[2][byte(t,1)]; \
u -= cast256_sbox[3][byte(t,0)]; \
y ^= u
#define f_rnd(x,n) \
f1(x[2],x[3],key->l_key[n], key->l_key[n + 4]); \
f2(x[1],x[2],key->l_key[n + 1],key->l_key[n + 5]); \
f3(x[0],x[1],key->l_key[n + 2],key->l_key[n + 6]); \
f1(x[3],x[0],key->l_key[n + 3],key->l_key[n + 7])
#define i_rnd(x, n) \
f1(x[3],x[0],key->l_key[n + 3],key->l_key[n + 7]); \
f3(x[0],x[1],key->l_key[n + 2],key->l_key[n + 6]); \
f2(x[1],x[2],key->l_key[n + 1],key->l_key[n + 5]); \
f1(x[2],x[3],key->l_key[n], key->l_key[n + 4])
#define k_rnd(k,tr,tm) \
f1(k[6],k[7],tr[0],tm[0]); \
f2(k[5],k[6],tr[1],tm[1]); \
f3(k[4],k[5],tr[2],tm[2]); \
f1(k[3],k[4],tr[3],tm[3]); \
f2(k[2],k[3],tr[4],tm[4]); \
f3(k[1],k[2],tr[5],tm[5]); \
f1(k[0],k[1],tr[6],tm[6]); \
f2(k[7],k[0],tr[7],tm[7])
WIN32DLL_DEFINE
int _mcrypt_set_key(cast256_key * key, const word32 * in_key,
const int key_len)
{
word32 i, j, t, u, cm, cr, lk[8], tm[8], tr[8];
for (i = 0; i < key_len / sizeof(word32); ++i)
#ifdef WORDS_BIGENDIAN
lk[i] = byteswap32(in_key[i]);
#else
lk[i] = in_key[i];
#endif
for (; i < 8; ++i)
lk[i] = 0;
cm = 0x5a827999;
cr = 19;
for (i = 0; i < 96; i += 8) {
for (j = 0; j < 8; ++j) {
tm[j] = cm;
cm += 0x6ed9eba1;
tr[j] = cr;
cr += 17;
}
k_rnd(lk, tr, tm);
for (j = 0; j < 8; ++j) {
tm[j] = cm;
cm += 0x6ed9eba1;
tr[j] = cr;
cr += 17;
}
k_rnd(lk, tr, tm);
key->l_key[i + 0] = lk[0];
key->l_key[i + 1] = lk[2];
key->l_key[i + 2] = lk[4];
key->l_key[i + 3] = lk[6];
key->l_key[i + 4] = lk[7];
key->l_key[i + 5] = lk[5];
key->l_key[i + 6] = lk[3];
key->l_key[i + 7] = lk[1];
}
return 0;
}
/* encrypt a block of text */
/* 16 bytes */
WIN32DLL_DEFINE void _mcrypt_encrypt(cast256_key * key, word32 * blk)
{
word32 t, u;
#ifdef WORDS_BIGENDIAN
blk[0] = byteswap32(blk[0]);
blk[1] = byteswap32(blk[1]);
blk[2] = byteswap32(blk[2]);
blk[3] = byteswap32(blk[3]);
#endif
f_rnd(blk, 0);
f_rnd(blk, 8);
f_rnd(blk, 16);
f_rnd(blk, 24);
f_rnd(blk, 32);
f_rnd(blk, 40);
i_rnd(blk, 48);
i_rnd(blk, 56);
i_rnd(blk, 64);
i_rnd(blk, 72);
i_rnd(blk, 80);
i_rnd(blk, 88);
#ifdef WORDS_BIGENDIAN
blk[0] = byteswap32(blk[0]);
blk[1] = byteswap32(blk[1]);
blk[2] = byteswap32(blk[2]);
blk[3] = byteswap32(blk[3]);
#endif
}
/* decrypt a block of text */
WIN32DLL_DEFINE void _mcrypt_decrypt(cast256_key * key, word32 * blk)
{
word32 t, u;
#ifdef WORDS_BIGENDIAN
blk[0] = byteswap32(blk[0]);
blk[1] = byteswap32(blk[1]);
blk[2] = byteswap32(blk[2]);
blk[3] = byteswap32(blk[3]);
#endif
f_rnd(blk, 88);
f_rnd(blk, 80);
f_rnd(blk, 72);
f_rnd(blk, 64);
f_rnd(blk, 56);
f_rnd(blk, 48);
i_rnd(blk, 40);
i_rnd(blk, 32);
i_rnd(blk, 24);
i_rnd(blk, 16);
i_rnd(blk, 8);
i_rnd(blk, 0);
#ifdef WORDS_BIGENDIAN
blk[0] = byteswap32(blk[0]);
blk[1] = byteswap32(blk[1]);
blk[2] = byteswap32(blk[2]);
blk[3] = byteswap32(blk[3]);
#endif
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(cast256_key);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 16;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 16, 24, 32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "CAST-256";
}
#define CIPHER "5db4dd765f1d3835615a14afcb5dc2f5"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
_mcrypt_encrypt(key, (void *) ciphertext);
free(keyword);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,4 @@
typedef struct cast256_instance {
word32 l_key[96];
} cast256_key;
@@ -0,0 +1,673 @@
/* Sofware DES functions
* written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from
* the 1977 public-domain program by Jim Gillogly
* Modified for additional speed - 6 December 1988 Phil Karn
* Modified for parameterized key schedules - Jan 1991 Phil Karn
* Callers now allocate a key schedule as follows:
* kn = (char (*)[8])malloc(sizeof(char) * 8 * 16);
* or
* char kn[16][8];
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: des.c,v 1.13 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "des.h"
#define _mcrypt_set_key des_LTX__mcrypt_set_key
#define _mcrypt_encrypt des_LTX__mcrypt_encrypt
#define _mcrypt_decrypt des_LTX__mcrypt_decrypt
#define _mcrypt_get_size des_LTX__mcrypt_get_size
#define _mcrypt_get_block_size des_LTX__mcrypt_get_block_size
#define _is_block_algorithm des_LTX__is_block_algorithm
#define _mcrypt_get_key_size des_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes des_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name des_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test des_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version des_LTX__mcrypt_algorithm_version
/* #define NULL 0 */
static void permute_ip(), permute_fp(), perminit_ip(), spinit(),
perminit_fp();
static word32 f();
/* Tables defined in the Data Encryption Standard documents */
/* initial permutation IP */
static char ip[] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
/* final permutation IP^-1 */
static char fp[] = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
/* expansion operation matrix
* This is for reference only; it is unused in the code
* as the f() function performs it implicitly for speed
*/
#ifdef notdef
static char ei[] = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
#endif
/* permuted choice table (key) */
static char pc1[] = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
/* number left rotations of pc1 */
static char totrot[] = {
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
};
/* permuted choice key (table) */
static char pc2[] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
/* The (in)famous S-boxes */
static char si[8][64] = {
/* S1 */
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
/* S2 */
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
/* S3 */
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
/* S4 */
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
/* S5 */
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
/* S6 */
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
/* S7 */
{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
/* S8 */
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
};
/* 32-bit permutation function P used on the output of the S-boxes */
static char p32i[] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/* End of DES-defined tables */
/* Lookup tables initialized once only at startup by desinit() */
/* bit 0 is left-most in byte */
static int bytebit[] = {
0200, 0100, 040, 020, 010, 04, 02, 01
};
static int nibblebit[] = {
010, 04, 02, 01
};
/* Allocate space and initialize DES lookup arrays
* mode == 0: standard Data Encryption Algorithm
*/
static int _mcrypt_desinit(DES_KEY * key)
{
spinit(key);
perminit_ip(key);
perminit_fp(key);
return 0;
}
/* Set key (initialize key schedule array) */
WIN32DLL_DEFINE
int _mcrypt_set_key(DES_KEY * dkey, char *user_key, int len)
{
char pc1m[56]; /* place to modify pc1 into */
char pcr[56]; /* place to rotate pc1 into */
register int i, j, l;
int m;
Bzero(dkey, sizeof(DES_KEY));
_mcrypt_desinit(dkey);
/* Clear key schedule */
for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
l = pc1[j] - 1; /* integer bit location */
m = l & 07; /* find bit */
pc1m[j] = (user_key[l >> 3] & /* find which key byte l is in */
bytebit[m]) /* and which bit of that byte */
? 1 : 0; /* and store 1-bit result */
}
for (i = 0; i < 16; i++) { /* key chunk for each iteration */
for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
pcr[j] =
pc1m[(l = j + totrot[i]) <
(j < 28 ? 28 : 56) ? l : l - 28];
/* rotate left and right halves independently */
for (j = 0; j < 48; j++) { /* select bits individually */
/* check bit that goes to kn[j] */
if (pcr[pc2[j] - 1]) {
/* mask it in if it's there */
l = j % 6;
dkey->kn[i][j / 6] |= bytebit[l] >> 2;
}
}
}
return 0;
}
/* In-place encryption of 64-bit block */
WIN32DLL_DEFINE void _mcrypt_encrypt(DES_KEY * key, char *block)
{
register word32 left, right;
register char *knp;
word32 work[2]; /* Working data storage */
permute_ip(block, key, (char *) work); /* Initial Permutation */
#ifndef WORDS_BIGENDIAN
left = byteswap32(work[0]);
right = byteswap32(work[1]);
#else
left = work[0];
right = work[1];
#endif
/* Do the 16 rounds.
* The rounds are numbered from 0 to 15. On even rounds
* the right half is fed to f() and the result exclusive-ORs
* the left half; on odd rounds the reverse is done.
*/
knp = &key->kn[0][0];
left ^= f(key, right, knp);
knp += 8;
right ^= f(key, left, knp);
knp += 8;
left ^= f(key, right, knp);
knp += 8;
right ^= f(key, left, knp);
knp += 8;
left ^= f(key, right, knp);
knp += 8;
right ^= f(key, left, knp);
knp += 8;
left ^= f(key, right, knp);
knp += 8;
right ^= f(key, left, knp);
knp += 8;
left ^= f(key, right, knp);
knp += 8;
right ^= f(key, left, knp);
knp += 8;
left ^= f(key, right, knp);
knp += 8;
right ^= f(key, left, knp);
knp += 8;
left ^= f(key, right, knp);
knp += 8;
right ^= f(key, left, knp);
knp += 8;
left ^= f(key, right, knp);
knp += 8;
right ^= f(key, left, knp);
/* Left/right half swap, plus byte swap if little-endian */
#ifndef WORDS_BIGENDIAN
work[1] = byteswap32(left);
work[0] = byteswap32(right);
#else
work[0] = right;
work[1] = left;
#endif
permute_fp((char *) work, key, block); /* Inverse initial permutation */
}
/* In-place decryption of 64-bit block. This function is the mirror
* image of encryption; exactly the same steps are taken, but in
* reverse order
*/
WIN32DLL_DEFINE void _mcrypt_decrypt(DES_KEY * key, char *block)
{
register word32 left, right;
register char *knp;
word32 work[2]; /* Working data storage */
permute_ip(block, key, (char *) work); /* Initial permutation */
/* Left/right half swap, plus byte swap if little-endian */
#ifndef WORDS_BIGENDIAN
right = byteswap32(work[0]);
left = byteswap32(work[1]);
#else
right = work[0];
left = work[1];
#endif
/* Do the 16 rounds in reverse order.
* The rounds are numbered from 15 to 0. On even rounds
* the right half is fed to f() and the result exclusive-ORs
* the left half; on odd rounds the reverse is done.
*/
knp = &key->kn[15][0];
right ^= f(key, left, knp);
knp -= 8;
left ^= f(key, right, knp);
knp -= 8;
right ^= f(key, left, knp);
knp -= 8;
left ^= f(key, right, knp);
knp -= 8;
right ^= f(key, left, knp);
knp -= 8;
left ^= f(key, right, knp);
knp -= 8;
right ^= f(key, left, knp);
knp -= 8;
left ^= f(key, right, knp);
knp -= 8;
right ^= f(key, left, knp);
knp -= 8;
left ^= f(key, right, knp);
knp -= 8;
right ^= f(key, left, knp);
knp -= 8;
left ^= f(key, right, knp);
knp -= 8;
right ^= f(key, left, knp);
knp -= 8;
left ^= f(key, right, knp);
knp -= 8;
right ^= f(key, left, knp);
knp -= 8;
left ^= f(key, right, knp);
#ifndef WORDS_BIGENDIAN
work[0] = byteswap32(left);
work[1] = byteswap32(right);
#else
work[0] = left;
work[1] = right;
#endif
permute_fp((char *) work, key, block); /* Inverse initial permutation */
}
/* Permute inblock with perm */
static void permute_ip(char *inblock, DES_KEY * key, char *outblock)
{
register char *ib, *ob; /* ptr to input or output block */
register char *p, *q;
register int j;
/* Clear output block */
Bzero(outblock, 8);
ib = inblock;
for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
ob = outblock;
p = key->iperm[j][(*ib >> 4) & 0xf];
q = key->iperm[j + 1][*ib & 0xf];
/* and each output byte, OR the masks together */
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
}
}
/* Permute inblock with perm */
static void permute_fp(char *inblock, DES_KEY * key, char *outblock)
{
register char *ib, *ob; /* ptr to input or output block */
register char *p, *q;
register int j;
/* Clear output block */
Bzero(outblock, 8);
ib = inblock;
for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
ob = outblock;
p = key->fperm[j][(*ib >> 4) & 0xf];
q = key->fperm[j + 1][*ib & 0xf];
/* and each output byte, OR the masks together */
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
}
}
/* The nonlinear function f(r,k), the heart of DES */
static word32 f(DES_KEY * key, register word32 r, register char *subkey)
{
register word32 *spp;
register word32 rval, rt;
register int er;
#ifdef TRACE
printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
r,
subkey[0], subkey[1], subkey[2],
subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]);
#endif
/* Run E(R) ^ K through the combined S & P boxes.
* This code takes advantage of a convenient regularity in
* E, namely that each group of 6 bits in E(R) feeding
* a single S-box is a contiguous segment of R.
*/
subkey += 7;
/* Compute E(R) for each block of 6 bits, and run thru boxes */
er = ((int) r << 1) | ((r & 0x80000000) ? 1 : 0);
spp = &key->sp[7][0];
rval = spp[(er ^ *subkey--) & 0x3f];
spp -= 64;
rt = (word32) r >> 3;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rt |= (r & 1) << 5;
rval |= spp[((int) rt ^ *subkey) & 0x3f];
#ifdef TRACE
printf(" %08lx\n", rval);
#endif
return rval;
}
/* initialize a perm array */
static void perminit_ip(DES_KEY * key)
{
register int l, j, k;
int i, m;
/* Clear the permutation array */
Bzero(key->iperm, 16 * 16 * 8);
for (i = 0; i < 16; i++) /* each input nibble position */
for (j = 0; j < 16; j++) /* each possible input nibble */
for (k = 0; k < 64; k++) { /* each output bit position */
l = ip[k] - 1; /* where does this bit come from */
if ((l >> 2) != i) /* does it come from input posn? */
continue; /* if not, bit k is 0 */
if (!(j & nibblebit[l & 3]))
continue; /* any such bit in input? */
m = k & 07; /* which bit is this in the byte */
key->iperm[i][j][k >> 3] |= bytebit[m];
}
}
static void perminit_fp(DES_KEY * key)
{
register int l, j, k;
int i, m;
/* Clear the permutation array */
Bzero(key->fperm, 16 * 16 * 8);
for (i = 0; i < 16; i++) /* each input nibble position */
for (j = 0; j < 16; j++) /* each possible input nibble */
for (k = 0; k < 64; k++) { /* each output bit position */
l = fp[k] - 1; /* where does this bit come from */
if ((l >> 2) != i) /* does it come from input posn? */
continue; /* if not, bit k is 0 */
if (!(j & nibblebit[l & 3]))
continue; /* any such bit in input? */
m = k & 07; /* which bit is this in the byte */
key->fperm[i][j][k >> 3] |= bytebit[m];
}
}
/* Initialize the lookup table for the combined S and P boxes */
static void spinit(DES_KEY * key)
{
char pbox[32];
int p, i, s, j, rowcol;
word32 val;
/* Compute pbox, the inverse of p32i.
* This is easier to work with
*/
for (p = 0; p < 32; p++) {
for (i = 0; i < 32; i++) {
if (p32i[i] - 1 == p) {
pbox[p] = i;
break;
}
}
}
for (s = 0; s < 8; s++) { /* For each S-box */
for (i = 0; i < 64; i++) { /* For each possible input */
val = 0;
/* The row number is formed from the first and last
* bits; the column number is from the middle 4
*/
rowcol =
(i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) &
0xf);
for (j = 0; j < 4; j++) { /* For each output bit */
if (si[s][rowcol] & (8 >> j)) {
val |=
1L << (31 - pbox[4 * s + j]);
}
}
key->sp[s][i] = val;
#ifdef DEBUG
printf("sp[%d][%2d] = %08lx\n", s, i,
key->sp[s][i]);
#endif
}
}
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(DES_KEY);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 8;
}
static const int key_sizes[] = { 8 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "DES";
}
#define CIPHER "a1502d70ba1320c8"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,7 @@
typedef struct des_key {
char kn[16][8];
word32 sp[8][64];
char iperm[16][16][8];
char fperm[16][16][8];
} DES_KEY;
@@ -0,0 +1,293 @@
/*
* "enigma.c" is in file cbw.tar from
* anonymous FTP host watmsg.waterloo.edu: pub/crypt/cbw.tar.Z
*
* A one-rotor machine designed along the lines of Enigma
* but considerably trivialized.
*
* A public-domain replacement for the UNIX "crypt" command.
* Changed to fit in mcrypt by nmav@hellug.gr
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: enigma.c,v 1.13 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "enigma.h"
#define _mcrypt_set_key enigma_LTX__mcrypt_set_key
#define _mcrypt_encrypt enigma_LTX__mcrypt_encrypt
#define _mcrypt_decrypt enigma_LTX__mcrypt_decrypt
#define _mcrypt_get_size enigma_LTX__mcrypt_get_size
#define _mcrypt_get_block_size enigma_LTX__mcrypt_get_block_size
#define _is_block_algorithm enigma_LTX__is_block_algorithm
#define _mcrypt_get_key_size enigma_LTX__mcrypt_get_key_size
#define _mcrypt_get_algo_iv_size enigma_LTX__mcrypt_get_algo_iv_size
#define _mcrypt_get_supported_key_sizes enigma_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name enigma_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test enigma_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version enigma_LTX__mcrypt_algorithm_version
/* it needs to be linked against libufc or libcrypt */
/* it no longer needs that. It just needs the password to be
* transformed by unix crypt() or the mhash SCRYPT
*/
WIN32DLL_DEFINE
int _mcrypt_set_key(CRYPT_KEY * ckey, char *password, int plen,
void *u1, int u2)
{
int ic, i, k, temp;
unsigned random;
sword32 seed;
Bzero(ckey, sizeof(CRYPT_KEY));
ckey->n1 = ckey->n2 = ckey->nr1 = ckey->nr2 = 0;
if (plen > 13)
plen = 13;
memmove(ckey->cbuf, password, plen);
seed = 123;
for (i = 0; i < 13; i++)
seed = seed * ckey->cbuf[i] + i;
for (i = 0; i < ROTORSZ; i++) {
ckey->t1[i] = i;
ckey->deck[i] = i;
}
for (i = 0; i < ROTORSZ; i++) {
seed = 5 * seed + ckey->cbuf[i % 13];
random = seed % 65521;
k = ROTORSZ - 1 - i;
ic = (random & MASK) % (k + 1);
random >>= 8;
temp = ckey->t1[k];
ckey->t1[k] = ckey->t1[ic];
ckey->t1[ic] = temp;
if (ckey->t3[k] != 0)
continue;
ic = (random & MASK) % k;
while (ckey->t3[ic] != 0)
ic = (ic + 1) % k;
ckey->t3[k] = ic;
ckey->t3[ic] = k;
}
for (i = 0; i < ROTORSZ; i++)
ckey->t2[ckey->t1[i] & MASK] = i;
return 0;
}
int shuffle(CRYPT_KEY * ckey)
{
int i, ic, k, temp;
unsigned random;
static sword32 seed = 123;
for (i = 0; i < ROTORSZ; i++) {
seed = 5 * seed + ckey->cbuf[i % 13];
random = seed % 65521;
k = ROTORSZ - 1 - i;
ic = (random & MASK) % (k + 1);
temp = ckey->deck[k];
ckey->deck[k] = ckey->deck[ic];
ckey->deck[ic] = temp;
}
return 0;
}
WIN32DLL_DEFINE
void _mcrypt_encrypt(CRYPT_KEY * ckey, void *gtext, int textlen)
{ /* 0 or 1 */
int i, j;
int secureflg = 0;
char *text = gtext;
for (j = 0; j < textlen; j++) {
i = text[j];
if (secureflg) {
ckey->nr1 = ckey->deck[ckey->n1] & MASK;
ckey->nr2 = ckey->deck[ckey->nr1] & MASK;
} else {
ckey->nr1 = ckey->n1;
}
i = ckey->
t2[(ckey->
t3[(ckey->t1[(i + ckey->nr1) & MASK] +
ckey->nr2) & MASK] - ckey->nr2) & MASK] -
ckey->nr1;
text[j] = i;
ckey->n1++;
if (ckey->n1 == ROTORSZ) {
ckey->n1 = 0;
ckey->n2++;
if (ckey->n2 == ROTORSZ)
ckey->n2 = 0;
if (secureflg) {
shuffle(ckey);
} else {
ckey->nr2 = ckey->n2;
}
}
}
return;
}
WIN32DLL_DEFINE
void _mcrypt_decrypt(CRYPT_KEY * ckey, void *gtext, int textlen)
{ /* 0 or 1 */
int i, j;
int secureflg = 0;
char *text = gtext;
for (j = 0; j < textlen; j++) {
i = text[j];
if (secureflg) {
ckey->nr1 = ckey->deck[ckey->n1] & MASK;
ckey->nr2 = ckey->deck[ckey->nr1] & MASK;
} else {
ckey->nr1 = ckey->n1;
}
i = ckey->
t2[(ckey->
t3[(ckey->t1[(i + ckey->nr1) & MASK] +
ckey->nr2) & MASK] - ckey->nr2) & MASK] -
ckey->nr1;
text[j] = i;
ckey->n1++;
if (ckey->n1 == ROTORSZ) {
ckey->n1 = 0;
ckey->n2++;
if (ckey->n2 == ROTORSZ)
ckey->n2 = 0;
if (secureflg) {
shuffle(ckey);
} else {
ckey->nr2 = ckey->n2;
}
}
}
return;
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(CRYPT_KEY);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_algo_iv_size()
{
return 0;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 0;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 13;
}
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = 0;
return NULL;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "enigma";
}
#define CIPHER "f3edda7da20f8975884600f014d32c7a08e59d7b"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[20];
unsigned char ciphertext[20];
int blocksize = 20, j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
strcpy(keyword, "enadyotr");
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memmove(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size(),
NULL, 0);
_mcrypt_encrypt(key, (void *) ciphertext, blocksize);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(keyword);
free(key);
return -1;
}
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size(),
NULL, 0);
free(keyword);
_mcrypt_decrypt(key, (void *) ciphertext, blocksize);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,13 @@
#define E_ECHO 010
#define ROTORSZ 256
#define MASK 0377
typedef struct crypt_key {
char t1[ROTORSZ];
char t2[ROTORSZ];
char t3[ROTORSZ];
char deck[ROTORSZ];
char cbuf[13];
int n1, n2, nr1, nr2;
} CRYPT_KEY;
@@ -0,0 +1,423 @@
/*
* The GOST 28147-89 cipher
*
* This is based on the 25 Movember 1993 draft translation
* by Aleksandr Malchik, with Whitfield Diffie, of the Government
* Standard of the U.S.S.R. GOST 28149-89, "Cryptographic Transformation
* Algorithm", effective 1 July 1990. (Whitfield.Diffie@eng.sun.com)
*
* That is a draft, and may contain errors, which will be faithfully
* reflected here, along with possible exciting new bugs.
*
* Some details have been cleared up by the paper "Soviet Encryption
* Algorithm" by Josef Pieprzyk and Leonid Tombak of the University
* of Wollongong, New South Wales. (josef/leo@cs.adfa.oz.au)
*
* The standard is written by A. Zabotin (project leader), G.P. Glazkov,
* and V.B. Isaeva. It was accepted and introduced into use by the
* action of the State Standards Committee of the USSR on 2 June 89 as
* No. 1409. It was to be reviewed in 1993, but whether anyone wishes
* to take on this obligation from the USSR is questionable.
*
* This code is placed in the public domain.
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: gost.c,v 1.13 2003/01/19 17:48:27 nmav Exp $ */
/*
* If you read the standard, it belabors the point of copying corresponding
* bits from point A to point B quite a bit. It helps to understand that
* the standard is uniformly little-endian, although it numbers bits from
* 1 rather than 0, so bit n has value 2^(n-1). The least significant bit
* of the 32-bit words that are manipulated in the algorithm is the first,
* lowest-numbered, in the bit string.
*/
#include <libdefs.h>
#include <mcrypt_modules.h>
#define _mcrypt_set_key gost_LTX__mcrypt_set_key
#define _mcrypt_encrypt gost_LTX__mcrypt_encrypt
#define _mcrypt_decrypt gost_LTX__mcrypt_decrypt
#define _mcrypt_get_size gost_LTX__mcrypt_get_size
#define _mcrypt_get_block_size gost_LTX__mcrypt_get_block_size
#define _is_block_algorithm gost_LTX__is_block_algorithm
#define _mcrypt_get_key_size gost_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes gost_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name gost_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test gost_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version gost_LTX__mcrypt_algorithm_version
void _mcrypt_kboxinit(void);
/*
* The standard does not specify the contents of the 8 4 bit->4 bit
* substitution boxes, saying they're a parameter of the network
* being set up. For illustration purposes here, I have used
* the first rows of the 8 S-boxes from the DES. (Note that the
* DES S-boxes are numbered starting from 1 at the msb. In keeping
* with the rest of the GOST, I have used little-endian numbering.
* Thus, k8 is S-box 1.
*
* Obviously, a careful look at the cryptographic properties of the cipher
* must be undertaken before "production" substitution boxes are defined.
*
* The standard also does not specify a standard bit-string representation
* for the contents of these blocks.
*/
/* These are NOT the original s-boxes. I replaced them with the ones
* found in Applied Cryptography book by Bruce Schneier. These were
* used in an application for the Central Bank of the Russian Federation
* --Nikos
*/
static int init = 0;
static unsigned char const gost_k1[16] = {
1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 2
};
static unsigned char const gost_k2[16] = {
13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12
};
static unsigned char const gost_k3[16] = {
4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14
};
static unsigned char const gost_k4[16] = {
6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2
};
static unsigned char const gost_k5[16] = {
7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3
};
static unsigned char const gost_k6[16] = {
5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11
};
static unsigned char const gost_k7[16] = {
14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9
};
static unsigned char const gost_k8[16] = {
4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3
};
/* Byte-at-a-time substitution boxes */
static unsigned char gost_k87[256];
static unsigned char gost_k65[256];
static unsigned char gost_k43[256];
static unsigned char gost_k21[256];
/*
* Build byte-at-a-time subtitution tables.
* This must be called once for global setup.
*/
WIN32DLL_DEFINE int _mcrypt_set_key(word32 * inst, word32 * key, int len)
{
_mcrypt_kboxinit();
inst[0] = 0;
inst[1] = 0;
inst[2] = 0;
inst[3] = 0;
inst[4] = 0;
inst[5] = 0;
inst[6] = 0;
inst[7] = 0;
memmove(inst, key, len);
#ifdef WORDS_BIGENDIAN
inst[0] = byteswap32(inst[0]);
inst[1] = byteswap32(inst[1]);
inst[2] = byteswap32(inst[2]);
inst[3] = byteswap32(inst[3]);
inst[4] = byteswap32(inst[4]);
inst[5] = byteswap32(inst[5]);
inst[6] = byteswap32(inst[6]);
inst[7] = byteswap32(inst[7]);
#endif
return 0;
}
void _mcrypt_kboxinit(void)
{
int i;
if (init == 0) {
init = 1;
for (i = 0; i < 256; i++) {
gost_k87[i] = gost_k8[i >> 4] << 4 | gost_k7[i & 15];
gost_k65[i] = gost_k6[i >> 4] << 4 | gost_k5[i & 15];
gost_k43[i] = gost_k4[i >> 4] << 4 | gost_k3[i & 15];
gost_k21[i] = gost_k2[i >> 4] << 4 | gost_k1[i & 15];
}
}
}
/*
* Do the substitution and rotation that are the core of the operation,
* like the expansion, substitution and permutation of the DES.
* It would be possible to perform DES-like optimisations and store
* the table entries as 32-bit words, already rotated, but the
* efficiency gain is questionable.
*
* This should be inlined for maximum speed
*/
static word32 f(word32 x)
{
/* Do substitutions */
# if 0
/* This is annoyingly slow */
x = k8[x >> 28 & 15] << 28 | k7[x >> 24 & 15] << 24 |
k6[x >> 20 & 15] << 20 | k5[x >> 16 & 15] << 16 |
k4[x >> 12 & 15] << 12 | k3[x >> 8 & 15] << 8 |
k2[x >> 4 & 15] << 4 | k1[x & 15];
# else
/* This is faster */
x = gost_k87[x >> 24 & 255] << 24 | gost_k65[x >> 16 & 255] << 16 |
gost_k43[x >> 8 & 255] << 8 | gost_k21[x & 255];
# endif
/* Rotate left 11 bits */
return x << 11 | x >> (32 - 11);
}
/*
* The GOST standard defines the input in terms of bits 1..64, with
* bit 1 being the lsb of in[0] and bit 64 being the msb of in[1].
*
* The keys are defined similarly, with bit 256 being the msb of key[7].
*/
WIN32DLL_DEFINE void _mcrypt_encrypt(word32 const key[8], word32 * in)
{
register word32 n1, n2; /* As named in the GOST */
/* Added to make it compatible with bigendian machines
* --nikos
*/
#ifndef WORDS_BIGENDIAN
n1 = byteswap32(in[0]);
n2 = byteswap32(in[1]);
#else
n1 = in[0];
n2 = in[1];
#endif
/* Instead of swapping halves, swap names each round */
n2 ^= f(n1 + key[0]);
n1 ^= f(n2 + key[1]);
n2 ^= f(n1 + key[2]);
n1 ^= f(n2 + key[3]);
n2 ^= f(n1 + key[4]);
n1 ^= f(n2 + key[5]);
n2 ^= f(n1 + key[6]);
n1 ^= f(n2 + key[7]);
n2 ^= f(n1 + key[0]);
n1 ^= f(n2 + key[1]);
n2 ^= f(n1 + key[2]);
n1 ^= f(n2 + key[3]);
n2 ^= f(n1 + key[4]);
n1 ^= f(n2 + key[5]);
n2 ^= f(n1 + key[6]);
n1 ^= f(n2 + key[7]);
n2 ^= f(n1 + key[0]);
n1 ^= f(n2 + key[1]);
n2 ^= f(n1 + key[2]);
n1 ^= f(n2 + key[3]);
n2 ^= f(n1 + key[4]);
n1 ^= f(n2 + key[5]);
n2 ^= f(n1 + key[6]);
n1 ^= f(n2 + key[7]);
n2 ^= f(n1 + key[7]);
n1 ^= f(n2 + key[6]);
n2 ^= f(n1 + key[5]);
n1 ^= f(n2 + key[4]);
n2 ^= f(n1 + key[3]);
n1 ^= f(n2 + key[2]);
n2 ^= f(n1 + key[1]);
n1 ^= f(n2 + key[0]);
/* There is no swap after the last round */
#ifndef WORDS_BIGENDIAN
in[0] = byteswap32(n2);
in[1] = byteswap32(n1);
#else
in[0] = n2;
in[1] = n1;
#endif
}
/*
* The key schedule is somewhat different for decryption.
* (The key table is used once forward and three times backward.)
* You could define an expanded key, or just write the code twice,
* as done here.
*/
WIN32DLL_DEFINE void _mcrypt_decrypt(word32 const key[8], word32 * in)
{
register word32 n1, n2; /* As named in the GOST */
#ifndef WORDS_BIGENDIAN
n1 = byteswap32(in[0]);
n2 = byteswap32(in[1]);
#else
n1 = in[0];
n2 = in[1];
#endif
n2 ^= f(n1 + key[0]);
n1 ^= f(n2 + key[1]);
n2 ^= f(n1 + key[2]);
n1 ^= f(n2 + key[3]);
n2 ^= f(n1 + key[4]);
n1 ^= f(n2 + key[5]);
n2 ^= f(n1 + key[6]);
n1 ^= f(n2 + key[7]);
n2 ^= f(n1 + key[7]);
n1 ^= f(n2 + key[6]);
n2 ^= f(n1 + key[5]);
n1 ^= f(n2 + key[4]);
n2 ^= f(n1 + key[3]);
n1 ^= f(n2 + key[2]);
n2 ^= f(n1 + key[1]);
n1 ^= f(n2 + key[0]);
n2 ^= f(n1 + key[7]);
n1 ^= f(n2 + key[6]);
n2 ^= f(n1 + key[5]);
n1 ^= f(n2 + key[4]);
n2 ^= f(n1 + key[3]);
n1 ^= f(n2 + key[2]);
n2 ^= f(n1 + key[1]);
n1 ^= f(n2 + key[0]);
n2 ^= f(n1 + key[7]);
n1 ^= f(n2 + key[6]);
n2 ^= f(n1 + key[5]);
n1 ^= f(n2 + key[4]);
n2 ^= f(n1 + key[3]);
n1 ^= f(n2 + key[2]);
n2 ^= f(n1 + key[1]);
n1 ^= f(n2 + key[0]);
#ifndef WORDS_BIGENDIAN
in[0] = byteswap32(n2);
in[1] = byteswap32(n1);
#else
in[0] = n2;
in[1] = n1;
#endif
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return 8 * sizeof(word32);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "GOST";
}
#define CIPHER "e498cf78cdf1d4a5"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,484 @@
/* This is an independent implementation of the encryption algorithm: */
/* */
/* LOKI97 by Brown and Pieprzyk */
/* */
/* which is a candidate algorithm in the Advanced Encryption Standard */
/* programme of the US National Institute of Standards and Technology. */
/* */
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
/* */
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
/* $Id: loki97.c,v 1.14 2003/01/19 17:48:27 nmav Exp $ */
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* Timing data for LOKI97 (loki.c)
Core timing without I/O endian conversion:
128 bit key:
Key Setup: 7430 cycles
Encrypt: 2134 cycles = 12.0 mbits/sec
Decrypt: 2192 cycles = 11.7 mbits/sec
Mean: 2163 cycles = 11.8 mbits/sec
192 bit key:
Key Setup: 7303 cycles
Encrypt: 2138 cycles = 12.0 mbits/sec
Decrypt: 2189 cycles = 11.7 mbits/sec
Mean: 2164 cycles = 11.8 mbits/sec
256 bit key:
Key Setup: 7166 cycles
Encrypt: 2131 cycles = 12.0 mbits/sec
Decrypt: 2184 cycles = 11.7 mbits/sec
Mean: 2158 cycles = 11.9 mbits/sec
Full timing with I/O endian conversion:
128 bit key:
Key Setup: 7582 cycles
Encrypt: 2174 cycles = 11.8 mbits/sec
Decrypt: 2235 cycles = 11.5 mbits/sec
Mean: 2205 cycles = 11.6 mbits/sec
192 bit key:
Key Setup: 7477 cycles
Encrypt: 2167 cycles = 11.8 mbits/sec
Decrypt: 2223 cycles = 11.5 mbits/sec
Mean: 2195 cycles = 11.7 mbits/sec
256 bit key:
Key Setup: 7365 cycles
Encrypt: 2177 cycles = 11.8 mbits/sec
Decrypt: 2194 cycles = 11.7 mbits/sec
Mean: 2186 cycles = 11.7 mbits/sec
*/
#include <libdefs.h>
#include <mcrypt_modules.h>
#define _mcrypt_set_key loki97_LTX__mcrypt_set_key
#define _mcrypt_encrypt loki97_LTX__mcrypt_encrypt
#define _mcrypt_decrypt loki97_LTX__mcrypt_decrypt
#define _mcrypt_get_size loki97_LTX__mcrypt_get_size
#define _mcrypt_get_block_size loki97_LTX__mcrypt_get_block_size
#define _is_block_algorithm loki97_LTX__is_block_algorithm
#define _mcrypt_get_key_size loki97_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes loki97_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name loki97_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test loki97_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version loki97_LTX__mcrypt_algorithm_version
#define byte(x,n) ((byte)((x) >> (8 * n)))
#define S1_SIZE 13
#define S1_LEN (1 << S1_SIZE)
#define S1_MASK (S1_LEN - 1)
#define S1_HMASK (S1_MASK & ~0xff)
#define S1_POLY 0x2911
#define S2_SIZE 11
#define S2_LEN (1 << S2_SIZE)
#define S2_MASK (S2_LEN - 1)
#define S2_HMASK (S2_MASK & ~0xff)
#define S2_POLY 0x0aa7
word32 delta[2] = { 0x7f4a7c15, 0x9e3779b9 };
byte sb1[S1_LEN]; /* GF(2^11) S box */
byte sb2[S2_LEN]; /* GF(2^11) S box */
word32 prm[256][2];
word32 init_done = 0;
/* word32 l_key[96]; */
#define add_eq(x,y) (x)[1] += (y)[1] + (((x)[0] += (y)[0]) < (y)[0] ? 1 : 0)
#define sub_eq(x,y) xs = (x)[0]; (x)[1] -= (y)[1] + (((x)[0] -= (y)[0]) > xs ? 1 : 0)
word32 ff_mult(word32 a, word32 b, word32 tpow, word32 mpol)
{
word32 r, s, m;
r = s = 0;
m = (1 << tpow);
while (b) {
if (b & 1)
s ^= a;
b >>= 1;
a <<= 1;
if (a & m)
a ^= mpol;
}
return s;
}
void init_tables(void)
{
word32 i, j, v;
/* initialise S box 1 */
for (i = 0; i < S1_LEN; ++i) {
j = v = i ^ S1_MASK;
v = ff_mult(v, j, S1_SIZE, S1_POLY);
sb1[i] = (byte) ff_mult(v, j, S1_SIZE, S1_POLY);
}
/* initialise S box 2 */
for (i = 0; i < S2_LEN; ++i) {
j = v = i ^ S2_MASK;
v = ff_mult(v, j, S2_SIZE, S2_POLY);
sb2[i] = (byte) ff_mult(v, j, S2_SIZE, S2_POLY);
}
/* initialise permutation table */
for (i = 0; i < 256; ++i) {
prm[i][0] =
((i & 1) << 7) | ((i & 2) << 14) | ((i & 4) << 21) |
((i & 8) << 28);
prm[i][1] =
((i & 16) << 3) | ((i & 32) << 10) | ((i & 64) << 17) |
((i & 128) << 24);
}
}
void f_fun(word32 res[2], const word32 in[2], const word32 key[2])
{
word32 i, tt[2], pp[2];
/* tt[0] = in[0] & ~key[0] | in[1] & key[0];
* tt[1] = in[1] & ~key[0] | in[0] & key[0];
*/
tt[0] = (in[0] & ~key[0]) | (in[1] & key[0]);
tt[1] = (in[1] & ~key[0]) | (in[0] & key[0]);
i = sb1[((tt[1] >> 24) | (tt[0] << 8)) & S1_MASK];
pp[0] = prm[i][0] >> 7;
pp[1] = prm[i][1] >> 7;
i = sb2[(tt[1] >> 16) & S2_MASK];
pp[0] |= prm[i][0] >> 6;
pp[1] |= prm[i][1] >> 6;
i = sb1[(tt[1] >> 8) & S1_MASK];
pp[0] |= prm[i][0] >> 5;
pp[1] |= prm[i][1] >> 5;
i = sb2[tt[1] & S2_MASK];
pp[0] |= prm[i][0] >> 4;
pp[1] |= prm[i][1] >> 4;
i = sb2[((tt[0] >> 24) | (tt[1] << 8)) & S2_MASK];
pp[0] |= prm[i][0] >> 3;
pp[1] |= prm[i][1] >> 3;
i = sb1[(tt[0] >> 16) & S1_MASK];
pp[0] |= prm[i][0] >> 2;
pp[1] |= prm[i][1] >> 2;
i = sb2[(tt[0] >> 8) & S2_MASK];
pp[0] |= prm[i][0] >> 1;
pp[1] |= prm[i][1] >> 1;
i = sb1[tt[0] & S1_MASK];
pp[0] |= prm[i][0];
pp[1] |= prm[i][1];
/*
res[0] ^= sb1[byte(pp[0], 0) | (key[1] << 8) & S1_HMASK]
| (sb1[byte(pp[0], 1) | (key[1] << 3) & S1_HMASK] << 8)
| (sb2[byte(pp[0], 2) | (key[1] >> 2) & S2_HMASK] << 16)
| (sb2[byte(pp[0], 3) | (key[1] >> 5) & S2_HMASK] << 24);
res[1] ^= sb1[byte(pp[1], 0) | (key[1] >> 8) & S1_HMASK]
| (sb1[byte(pp[1], 1) | (key[1] >> 13) & S1_HMASK] << 8)
| (sb2[byte(pp[1], 2) | (key[1] >> 18) & S2_HMASK] << 16)
| (sb2[byte(pp[1], 3) | (key[1] >> 21) & S2_HMASK] << 24);
*/
res[0] ^= sb1[byte(pp[0], 0) | ((key[1] << 8) & S1_HMASK)]
| ((sb1[byte(pp[0], 1) | ((key[1] << 3) & S1_HMASK)] << 8))
| ((sb2[byte(pp[0], 2) | ((key[1] >> 2) & S2_HMASK)] << 16))
| ((sb2[byte(pp[0], 3) | ((key[1] >> 5) & S2_HMASK)] << 24));
res[1] ^= sb1[byte(pp[1], 0) | ((key[1] >> 8) & S1_HMASK)]
| ((sb1[byte(pp[1], 1) | ((key[1] >> 13) & S1_HMASK)] << 8))
| ((sb2[byte(pp[1], 2) | ((key[1] >> 18) & S2_HMASK)] << 16))
| ((sb2[byte(pp[1], 3) | ((key[1] >> 21) & S2_HMASK)] << 24));
}
/* 256 bit version only */
WIN32DLL_DEFINE
int _mcrypt_set_key(word32 * l_key, const word32 in_key[],
const word32 key_len)
{
word32 i, k1[2], k2[2], k3[2], k4[2], del[2], tt[2], sk[2];
if (!init_done) {
init_tables();
init_done = 1;
}
#ifdef WORDS_BIGENDIAN
k4[0] = byteswap32(in_key[1]);
k4[1] = byteswap32(in_key[0]);
k3[0] = byteswap32(in_key[3]);
k3[1] = byteswap32(in_key[2]);
#else
k4[0] = (in_key[1]);
k4[1] = (in_key[0]);
k3[0] = (in_key[3]);
k3[1] = (in_key[2]);
#endif
#ifdef WORDS_BIGENDIAN
k2[0] = byteswap32(in_key[5]);
k2[1] = byteswap32(in_key[4]);
k1[0] = byteswap32(in_key[7]);
k1[1] = byteswap32(in_key[6]);
#else
k2[0] = (in_key[5]);
k2[1] = (in_key[4]);
k1[0] = (in_key[7]);
k1[1] = (in_key[6]);
#endif
del[0] = delta[0];
del[1] = delta[1];
for (i = 0; i < 48; ++i) {
tt[0] = k1[0];
tt[1] = k1[1];
add_eq(tt, k3);
add_eq(tt, del);
add_eq(del, delta);
sk[0] = k4[0];
sk[1] = k4[1];
k4[0] = k3[0];
k4[1] = k3[1];
k3[0] = k2[0];
k3[1] = k2[1];
k2[0] = k1[0];
k2[1] = k1[1];
k1[0] = sk[0];
k1[1] = sk[1];
f_fun(k1, tt, k3);
l_key[i + i] = k1[0];
l_key[i + i + 1] = k1[1];
}
return 0;
}
#define r_fun(l,r,k) \
add_eq((l),(k)); \
f_fun((r),(l),(k) + 2); \
add_eq((l), (k) + 4)
WIN32DLL_DEFINE void _mcrypt_encrypt(word32 * l_key, word32 * _blk)
{
word32 blk[4];
#ifdef WORDS_BIGENDIAN
blk[3] = byteswap32(_blk[0]);
blk[2] = byteswap32(_blk[1]);
blk[1] = byteswap32(_blk[2]);
blk[0] = byteswap32(_blk[3]);
#else
blk[3] = (_blk[0]);
blk[2] = (_blk[1]);
blk[1] = (_blk[2]);
blk[0] = (_blk[3]);
#endif
r_fun(blk, blk + 2, l_key + 0);
r_fun(blk + 2, blk, l_key + 6);
r_fun(blk, blk + 2, l_key + 12);
r_fun(blk + 2, blk, l_key + 18);
r_fun(blk, blk + 2, l_key + 24);
r_fun(blk + 2, blk, l_key + 30);
r_fun(blk, blk + 2, l_key + 36);
r_fun(blk + 2, blk, l_key + 42);
r_fun(blk, blk + 2, l_key + 48);
r_fun(blk + 2, blk, l_key + 54);
r_fun(blk, blk + 2, l_key + 60);
r_fun(blk + 2, blk, l_key + 66);
r_fun(blk, blk + 2, l_key + 72);
r_fun(blk + 2, blk, l_key + 78);
r_fun(blk, blk + 2, l_key + 84);
r_fun(blk + 2, blk, l_key + 90);
#ifdef WORDS_BIGENDIAN
_blk[3] = byteswap32(blk[2]);
_blk[2] = byteswap32(blk[3]);
_blk[1] = byteswap32(blk[0]);
_blk[0] = byteswap32(blk[1]);
#else
_blk[3] = (blk[2]);
_blk[2] = (blk[3]);
_blk[1] = (blk[0]);
_blk[0] = (blk[1]);
#endif
}
#define ir_fun(l,r,k) \
sub_eq((l),(k) + 4); \
f_fun((r),(l),(k) + 2); \
sub_eq((l),(k))
WIN32DLL_DEFINE void _mcrypt_decrypt(word32 * l_key, word32 * _blk)
{
word32 xs, blk[4];
#ifdef WORDS_BIGENDIAN
blk[3] = byteswap32(_blk[0]);
blk[2] = byteswap32(_blk[1]);
blk[1] = byteswap32(_blk[2]);
blk[0] = byteswap32(_blk[3]);
#else
blk[3] = (_blk[0]);
blk[2] = (_blk[1]);
blk[1] = (_blk[2]);
blk[0] = (_blk[3]);
#endif
ir_fun(blk, blk + 2, l_key + 90);
ir_fun(blk + 2, blk, l_key + 84);
ir_fun(blk, blk + 2, l_key + 78);
ir_fun(blk + 2, blk, l_key + 72);
ir_fun(blk, blk + 2, l_key + 66);
ir_fun(blk + 2, blk, l_key + 60);
ir_fun(blk, blk + 2, l_key + 54);
ir_fun(blk + 2, blk, l_key + 48);
ir_fun(blk, blk + 2, l_key + 42);
ir_fun(blk + 2, blk, l_key + 36);
ir_fun(blk, blk + 2, l_key + 30);
ir_fun(blk + 2, blk, l_key + 24);
ir_fun(blk, blk + 2, l_key + 18);
ir_fun(blk + 2, blk, l_key + 12);
ir_fun(blk, blk + 2, l_key + 6);
ir_fun(blk + 2, blk, l_key);
#ifdef WORDS_BIGENDIAN
_blk[3] = byteswap32(blk[2]);
_blk[2] = byteswap32(blk[3]);
_blk[1] = byteswap32(blk[0]);
_blk[0] = byteswap32(blk[1]);
#else
_blk[3] = (blk[2]);
_blk[2] = (blk[3]);
_blk[1] = (blk[0]);
_blk[0] = (blk[1]);
#endif
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return 96 * sizeof(word32);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 16;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 16, 24, 32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "LOKI97";
}
#define CIPHER "8cb28c958024bae27a94c698f96f12a9"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,700 @@
/* panama_x.c */
/* $Id: panama.c,v 1.21 2003/01/19 17:48:27 nmav Exp $ */
/* daemen.j@protonworld.com */
/**************************************************************************+
*
* PANAMA high-performance reference C-code, based on the description in
* the paper 'Fast Hashing and Stream Encryption with PANAMA', presented
* at the Fast Software Encryption Workshop, Paris, 1998, see "Fast
* Software Encryption - 5th International Workshop, FSE'98", edited by
* Serge Vaudenay, LNCS-1372, Springer-Verlag, 1998, pp 60-74, also
* available on-line at http://standard.pictel.com/ftp/research/security
*
* Algorithm design by Joan Daemen and Craig Clapp
*
* panama_x.c - Core routines for the Panama stream/hash module, this
* exportable version excludes an encryption routine.
*
*
* History:
*
* 29-Oct-98 Craig Clapp Implemention for Dr. Dobbs, Dec. 1998 issue,
* based on earlier performance-benchmark code.
*
*
* Notes: This code is supplied for the purposes of evaluating the
* performance of the Panama stream/hash module and as a
* reference implementation for generating test vectors for
* compatibility / interoperability verification.
*
*
+**************************************************************************/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "panama.h"
#define _mcrypt_set_key panama_LTX__mcrypt_set_key
#define _mcrypt_encrypt panama_LTX__mcrypt_encrypt
#define _mcrypt_decrypt panama_LTX__mcrypt_decrypt
#define _mcrypt_get_size panama_LTX__mcrypt_get_size
#define _mcrypt_get_block_size panama_LTX__mcrypt_get_block_size
#define _is_block_algorithm panama_LTX__is_block_algorithm
#define _mcrypt_get_key_size panama_LTX__mcrypt_get_key_size
#define _mcrypt_get_algo_iv_size panama_LTX__mcrypt_get_algo_iv_size
#define _mcrypt_get_supported_key_sizes panama_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name panama_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test panama_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version panama_LTX__mcrypt_algorithm_version
/**************************************************************************+
* Panama internal routines *
+**************************************************************************/
/* tau, rotate word 'a' to the left by rol_bits bit positions */
#define tau(a, rol_bits) ROTL32(a, rol_bits)
/**************************************************************************/
/* move state between memory and local registers */
#define READ_STATE_i(i) state_##i = state->word[i]
#define WRITE_STATE_i(i) state->word[i] = state_##i
#define READ_STATE \
\
READ_STATE_i(0); \
READ_STATE_i(1); \
READ_STATE_i(2); \
READ_STATE_i(3); \
READ_STATE_i(4); \
READ_STATE_i(5); \
READ_STATE_i(6); \
READ_STATE_i(7); \
READ_STATE_i(8); \
READ_STATE_i(9); \
READ_STATE_i(10); \
READ_STATE_i(11); \
READ_STATE_i(12); \
READ_STATE_i(13); \
READ_STATE_i(14); \
READ_STATE_i(15); \
READ_STATE_i(16)
#define WRITE_STATE \
\
WRITE_STATE_i(0); \
WRITE_STATE_i(1); \
WRITE_STATE_i(2); \
WRITE_STATE_i(3); \
WRITE_STATE_i(4); \
WRITE_STATE_i(5); \
WRITE_STATE_i(6); \
WRITE_STATE_i(7); \
WRITE_STATE_i(8); \
WRITE_STATE_i(9); \
WRITE_STATE_i(10); \
WRITE_STATE_i(11); \
WRITE_STATE_i(12); \
WRITE_STATE_i(13); \
WRITE_STATE_i(14); \
WRITE_STATE_i(15); \
WRITE_STATE_i(16)
/**************************************************************************/
/* gamma, shift-invariant transformation a[i] XOR (a[i+1] OR NOT a[i+2]) */
#define gamma_in_(i) state_##i
#define gamma_out_(i) gamma_##i
#define GAMMA_i(i, i_plus_1, i_plus_2) \
\
gamma_out_(i) = gamma_in_(i) ^ (gamma_in_(i_plus_1) | ~gamma_in_(i_plus_2))
#define GAMMA \
\
GAMMA_i( 0, 1, 2); \
GAMMA_i( 1, 2, 3); \
GAMMA_i( 2, 3, 4); \
GAMMA_i( 3, 4, 5); \
GAMMA_i( 4, 5, 6); \
GAMMA_i( 5, 6, 7); \
GAMMA_i( 6, 7, 8); \
GAMMA_i( 7, 8, 9); \
GAMMA_i( 8, 9, 10); \
GAMMA_i( 9, 10, 11); \
GAMMA_i(10, 11, 12); \
GAMMA_i(11, 12, 13); \
GAMMA_i(12, 13, 14); \
GAMMA_i(13, 14, 15); \
GAMMA_i(14, 15, 16); \
GAMMA_i(15, 16, 0); \
GAMMA_i(16, 0, 1)
/**************************************************************************/
/* pi, permute and cyclicly rotate the state words */
#define pi_in_(i) gamma_##i
#define pi_out_(i) pi_##i
#define PI_i(i, j, k) pi_out_(i) = tau(pi_in_(j), k)
#define PI \
\
pi_out_(0) = pi_in_(0); \
PI_i( 1, 7, 1); \
PI_i( 2, 14, 3); \
PI_i( 3, 4, 6); \
PI_i( 4, 11, 10); \
PI_i( 5, 1, 15); \
PI_i( 6, 8, 21); \
PI_i( 7, 15, 28); \
PI_i( 8, 5, 4); \
PI_i( 9, 12, 13); \
PI_i(10, 2, 23); \
PI_i(11, 9, 2); \
PI_i(12, 16, 14); \
PI_i(13, 6, 27); \
PI_i(14, 13, 9); \
PI_i(15, 3, 24); \
PI_i(16, 10, 8)
/**************************************************************************/
/* theta, shift-invariant transformation a[i] XOR a[i+1] XOR a[i+4] */
#define theta_in_(i) pi_##i
#define theta_out_(i) theta_##i
#define THETA_i(i, i_plus_1, i_plus_4) \
\
theta_out_(i) = theta_in_(i) ^ theta_in_(i_plus_1) ^ theta_in_(i_plus_4)
#define THETA \
\
THETA_i( 0, 1, 4); \
THETA_i( 1, 2, 5); \
THETA_i( 2, 3, 6); \
THETA_i( 3, 4, 7); \
THETA_i( 4, 5, 8); \
THETA_i( 5, 6, 9); \
THETA_i( 6, 7, 10); \
THETA_i( 7, 8, 11); \
THETA_i( 8, 9, 12); \
THETA_i( 9, 10, 13); \
THETA_i(10, 11, 14); \
THETA_i(11, 12, 15); \
THETA_i(12, 13, 16); \
THETA_i(13, 14, 0); \
THETA_i(14, 15, 1); \
THETA_i(15, 16, 2); \
THETA_i(16, 0, 3)
/**************************************************************************/
/* sigma, merge two buffer stages with current state */
#define sigma_in_(i) theta_##i
#define sigma_out_(i) state_##i
#define SIGMA_L_i(i) sigma_out_(i) = sigma_in_(i) ^ L->word[i-1]
#define SIGMA_B_i(i) sigma_out_(i) = sigma_in_(i) ^ b->word[i-9]
#define SIGMA \
\
sigma_out_(0) = sigma_in_(0) ^ 0x00000001L; \
\
SIGMA_L_i(1); \
SIGMA_L_i(2); \
SIGMA_L_i(3); \
SIGMA_L_i(4); \
SIGMA_L_i(5); \
SIGMA_L_i(6); \
SIGMA_L_i(7); \
SIGMA_L_i(8); \
\
SIGMA_B_i(9); \
SIGMA_B_i(10); \
SIGMA_B_i(11); \
SIGMA_B_i(12); \
SIGMA_B_i(13); \
SIGMA_B_i(14); \
SIGMA_B_i(15); \
SIGMA_B_i(16)
/**************************************************************************/
/* lambda, update the 256-bit wide by 32-stage LFSR buffer */
#define LAMBDA_25_i(i) \
ptap_25->word[i] = ptap_25->word[i] ^ ptap_0->word[(i+2) & (PAN_STAGE_SIZE-1)]
#define LAMBDA_0_i(i, source) ptap_0->word[i] = source ^ ptap_0->word[i]
#define LAMBDA_25_UPDATE \
\
LAMBDA_25_i(0); \
LAMBDA_25_i(1); \
LAMBDA_25_i(2); \
LAMBDA_25_i(3); \
LAMBDA_25_i(4); \
LAMBDA_25_i(5); \
LAMBDA_25_i(6); \
LAMBDA_25_i(7)
#define LAMBDA_0_PULL \
\
LAMBDA_0_i(0, state_1); \
LAMBDA_0_i(1, state_2); \
LAMBDA_0_i(2, state_3); \
LAMBDA_0_i(3, state_4); \
LAMBDA_0_i(4, state_5); \
LAMBDA_0_i(5, state_6); \
LAMBDA_0_i(6, state_7); \
LAMBDA_0_i(7, state_8)
#define LAMBDA_0_PUSH \
\
LAMBDA_0_i(0, L->word[0]); \
LAMBDA_0_i(1, L->word[1]); \
LAMBDA_0_i(2, L->word[2]); \
LAMBDA_0_i(3, L->word[3]); \
LAMBDA_0_i(4, L->word[4]); \
LAMBDA_0_i(5, L->word[5]); \
LAMBDA_0_i(6, L->word[6]); \
LAMBDA_0_i(7, L->word[7])
/* avoid temporary register for tap 31 by finishing updating tap 25 before updating tap 0 */
#define LAMBDA_PULL \
LAMBDA_25_UPDATE; \
LAMBDA_0_PULL
#define LAMBDA_PUSH \
LAMBDA_25_UPDATE; \
LAMBDA_0_PUSH
/**************************************************************************/
#define regs(i) state_##i, gamma_##i, pi_##i, theta_##i
/**************************************************************************/
/**************************************************************************+
* Panama external routines *
+**************************************************************************/
/**************************************************************************+
*
* pan_pull() - Performs multiple iterations of the Panama 'Pull' operation.
* The input and output arrays are treated as integer multiples
* of Panama's natural 256-bit block size.
*
* Input and output arrays may be disjoint or coincident but
* may not be overlapped if offset from one another.
*
* If 'In' is a NULL pointer then output is taken direct from
* the state machine (used for hash output). If 'Out' is a NULL
* pointer then a dummy 'Pull' is performed. Otherwise 'In' is
* XOR combined with the state machine to produce 'Out'
* (used for stream encryption / decryption).
*
+**************************************************************************/
static void pan_pull(word32 * restrict In, /* input array */
word32 * restrict Out, /* output array */
word32 pan_blocks, /* number of blocks to be Pulled */
PAN_BUFFER * restrict buffer, /* LFSR buffer */
PAN_STATE * restrict state)
{ /* 17-word finite-state machine */
int i;
word32 regs(0), regs(1), regs(2), regs(3), regs(4);
word32 regs(5), regs(6), regs(7), regs(8), regs(9);
word32 regs(10), regs(11), regs(12), regs(13), regs(14);
word32 regs(15), regs(16);
word32 tap_0;
PAN_STAGE *restrict ptap_0, *restrict ptap_25;
PAN_STAGE *restrict L, *restrict b;
/* configure routine according to which PULL mode is intended */
static word32 null_in[PAN_STAGE_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 };
word32 dummy_out[PAN_STAGE_SIZE];
word32 in_step, out_step;
in_step = out_step = PAN_STAGE_SIZE;
if (In == NULL || Out == NULL) {
In = null_in;
in_step = 0;
}
if (Out == NULL) {
Out = dummy_out;
out_step = 0;
}
/* copy buffer pointers and state to registers */
tap_0 = buffer->tap_0;
READ_STATE;
/* rho, cascade of state update operations */
for (i = 0; i < pan_blocks; i++) {
/* apply state output to crypto buffer */
Out[0] = In[0] ^ gamma_in_(9);
Out[1] = In[1] ^ gamma_in_(10);
Out[2] = In[2] ^ gamma_in_(11);
Out[3] = In[3] ^ gamma_in_(12);
Out[4] = In[4] ^ gamma_in_(13);
Out[5] = In[5] ^ gamma_in_(14);
Out[6] = In[6] ^ gamma_in_(15);
Out[7] = In[7] ^ gamma_in_(16);
Out += out_step;
In += in_step;
GAMMA; /* perform non-linearity stage */
PI; /* perform bit-dispersion stage */
THETA; /* perform diffusion stage */
/* calculate pointers to taps 4 and 16 for sigma based on current position of tap 0 */
L = &buffer->stage[(tap_0 + 4) & (PAN_STAGES - 1)];
b = &buffer->stage[(tap_0 + 16) & (PAN_STAGES - 1)];
/* move tap_0 left by one stage, equivalent to shifting LFSR one stage right */
tap_0 = (tap_0 - 1) & (PAN_STAGES - 1);
/* set tap pointers for use by lambda */
ptap_0 = &buffer->stage[tap_0];
ptap_25 = &buffer->stage[(tap_0 + 25) & (PAN_STAGES - 1)];
LAMBDA_PULL; /* update the LFSR buffer */
/* postpone sigma until after lambda in order to avoid extra temporaries for feedback path */
/* note that sigma gets to use the old positions of taps 4 and 16 */
SIGMA; /* perform buffer injection stage */
}
/* write buffer pointer and state back to memory */
buffer->tap_0 = tap_0;
WRITE_STATE;
}
/**************************************************************************+
*
* pan_push() - Performs multiple iterations of the Panama 'Push' operation.
* The input array is treated as an integer multiple of the
* 256-bit blocks which are Panama's natural input size.
*
+**************************************************************************/
static void pan_push(word32 * restrict In, /* input array */
word32 pan_blocks, /* number of blocks to be Pushed */
PAN_BUFFER * restrict buffer, /* LFSR buffer */
PAN_STATE * restrict state)
{ /* 17-word finite-state machine */
int i;
word32 regs(0), regs(1), regs(2), regs(3), regs(4);
word32 regs(5), regs(6), regs(7), regs(8), regs(9);
word32 regs(10), regs(11), regs(12), regs(13), regs(14);
word32 regs(15), regs(16);
word32 tap_0;
PAN_STAGE *restrict ptap_0, *restrict ptap_25;
PAN_STAGE *restrict L, *restrict b;
/* copy buffer pointers and state to registers */
tap_0 = buffer->tap_0;
READ_STATE;
/* assert((word32 *) ((PAN_STAGE *) In) == In); */
L = (PAN_STAGE *) In; /* we assume pointer to input buffer is compatible with pointer to PAN_STAGE */
#ifdef WORDS_BIGENDIAN
if (L != NULL)
for (i = 0; i < PAN_STAGE_SIZE; i++) {
L->word[i] = byteswap32(L->word[i]);
}
#endif
/* rho, cascade of state update operations */
for (i = 0; i < pan_blocks; i++) {
GAMMA; /* perform non-linearity stage */
PI; /* perform bit-dispersion stage */
THETA; /* perform diffusion stage */
/* calculate pointer to tap 16 for sigma based on current position of tap 0 */
b = &buffer->stage[(tap_0 + 16) & (PAN_STAGES - 1)];
/* move tap_0 left by one stage, equivalent to shifting LFSR one stage right */
tap_0 = (tap_0 - 1) & (PAN_STAGES - 1);
/* set tap pointers for use by lambda */
ptap_0 = &buffer->stage[tap_0];
ptap_25 = &buffer->stage[(tap_0 + 25) & (PAN_STAGES - 1)];
LAMBDA_PUSH; /* update the LFSR buffer */
/* postpone sigma until after lambda in order to avoid extra temporaries for feedback path */
/* note that sigma gets to use the old positions of taps 4 and 16 */
SIGMA; /* perform buffer injection stage */
L++; /* In += PAN_STAGE_SIZE; */
}
/* write buffer pointer and state back to memory */
buffer->tap_0 = tap_0;
WRITE_STATE;
}
/**************************************************************************+
*
* pan_reset() - Initializes an LFSR buffer and Panama state machine to
* all zeros, ready for a new hash to be accumulated or to
* re-synchronize or start up an encryption key-stream.
*
+**************************************************************************/
static void pan_reset(PAN_BUFFER * buffer, PAN_STATE * state)
{
int i, j;
buffer->tap_0 = 0;
for (j = 0; j < PAN_STAGES; j++) {
for (i = 0; i < PAN_STAGE_SIZE; i++) {
buffer->stage[j].word[i] = 0L;
}
}
for (i = 0; i < PAN_STATE_SIZE; i++) {
state->word[i] = 0L;
}
}
/**************************************************************************+
*
* pan_crypt() - Performs stream encryption or decryption.
*
+**************************************************************************/
WIN32DLL_DEFINE
int _mcrypt_set_key(PANAMA_KEY * pan_key, char *in_key, int keysize,
char *init_vec, int vecsize)
{
byte key[32];
int keyblocks = (8 * keysize) / (PAN_STAGE_SIZE * WORDLENGTH);
int vecblocks = (8 * vecsize) / (PAN_STAGE_SIZE * WORDLENGTH);
int i;
pan_key->keymat = (void*) pan_key->wkeymat;
/* initialize the Panama state machine for a fresh crypting operation */
pan_reset(&pan_key->buffer, &pan_key->state);
pan_push((void *) in_key, keyblocks, &pan_key->buffer,
&pan_key->state);
if (init_vec != NULL)
pan_push((void *) init_vec, vecblocks, &pan_key->buffer,
&pan_key->state);
pan_pull(NULL, NULL, 32, &pan_key->buffer, &pan_key->state);
pan_pull(NULL, pan_key->wkeymat, 1, &pan_key->buffer,
&pan_key->state);
pan_key->keymat_pointer = 0;
#ifdef WORDS_BIGENDIAN
for (i = 0; i < 8; i++) {
pan_key->wkeymat[i] =
byteswap32( pan_key->wkeymat[i]);
}
#endif
return 0;
}
WIN32DLL_DEFINE void _mcrypt_encrypt(PANAMA_KEY * pan_key, /* the key from pan_init */
byte * buf, /* input array */
int length)
{ /* length to be encrypted, in bits */
int i;
#ifdef WORDS_BIGENDIAN
int j;
#endif
/* initialize the Panama state machine for a fresh crypting operation */
for (i = 0; i < length; i++) {
if (pan_key->keymat_pointer == 32) {
pan_pull(NULL, (void *) pan_key->wkeymat, 1,
&pan_key->buffer, &pan_key->state);
pan_key->keymat_pointer = 0;
#ifdef WORDS_BIGENDIAN
for (j = 0; j < 8; j++) {
pan_key->wkeymat[j] =
byteswap32( pan_key->wkeymat[j]);
}
#endif
}
buf[i] ^= pan_key->keymat[pan_key->keymat_pointer];
pan_key->keymat_pointer++;
}
}
WIN32DLL_DEFINE void _mcrypt_decrypt(PANAMA_KEY * pan_key, /* the key from pan_init */
byte * buf, /* input array */
int length)
{ /* length to be encrypted, in bits */
_mcrypt_encrypt(pan_key, buf, length);
}
/**************************************************************************/
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(PANAMA_KEY);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_algo_iv_size()
{
return 32;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 0;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "PANAMA";
}
#define CIPHER "d76e3c2243feadd2c99edfcb95c64c852ba6c59f"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[20];
unsigned char ciphertext[20];
int blocksize = 20, j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size(),
NULL, 0);
_mcrypt_encrypt(key, (void *) ciphertext, blocksize);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(keyword);
free(key);
return -1;
}
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size(),
NULL, 0);
free(keyword);
_mcrypt_decrypt(key, (void *) ciphertext, blocksize);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version(void)
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,102 @@
/* panama.h */
/**************************************************************************+
*
* PANAMA high-performance reference C-code, based on the description in
* the paper 'Fast Hashing and Stream Encryption with PANAMA', presented
* at the Fast Software Encryption Workshop, Paris, 1998, see "Fast
* Software Encryption - 5th International Workshop, FSE'98", edited by
* Serge Vaudenay, LNCS-1372, Springer-Verlag, 1998, pp 60-74, also
* available on-line at http://standard.pictel.com/ftp/research/security
*
* Algorithm design by Joan Daemen and Craig Clapp
*
* panama.h - Header file for Panama C-code implementation.
*
*
* History:
*
* 29-Oct-98 Craig Clapp Implemention for Dr. Dobbs, Dec. 1998 issue,
* based on earlier performance-benchmark code.
*
*
* Notes: This code is supplied for the purposes of evaluating the
* performance of the Panama stream/hash module and as a
* reference implementation for generating test vectors for
* compatibility / interoperability verification.
*
*
+**************************************************************************/
#ifndef NULL
#define NULL 0
#endif
#define WORDLENGTH 32
#define ONES 0xffffffffL
/* standard C idioms for Microsoft and TriMedia compiler features */
#define restrict /* 'restrict' keyword is not part of ANSI C, null it out */
#define ROTL32(a,shift) (((a) << (shift)) | ((a) >> (WORDLENGTH - (shift))))
/****** structure definitions ******/
#define PAN_STAGE_SIZE 8
#define PAN_STAGES 32
#define PAN_STATE_SIZE 17
typedef struct {
word32 word[PAN_STAGE_SIZE];
} PAN_STAGE;
typedef struct {
PAN_STAGE stage[PAN_STAGES];
int tap_0;
} PAN_BUFFER;
typedef struct {
word32 word[PAN_STATE_SIZE];
} PAN_STATE;
typedef struct {
PAN_BUFFER buffer;
PAN_STATE state;
word32 wkeymat[8];
byte *keymat;
int keymat_pointer;
} PANAMA_KEY;
/****** function prototypes ******/
static void pan_pull(word32 * restrict In, /* input array */
word32 * restrict Out, /* output array */
word32 pan_blocks, /* number of blocks to be Pulled */
PAN_BUFFER * restrict buffer, /* LFSR buffer */
PAN_STATE * restrict state); /* 17-word finite-state machine */
static void pan_push(word32 * restrict In, /* input array */
word32 pan_blocks, /* number of blocks to be Pushed */
PAN_BUFFER * restrict buffer, /* LFSR buffer */
PAN_STATE * restrict state); /* 17-word finite-state machine */
static void pan_reset(PAN_BUFFER * buffer, PAN_STATE * state);
#ifndef USE_MODULES
void _mcrypt_panama_set_key(PANAMA_KEY * pan_key, char *in_key, int keysize,
char *init_vec, int vecsize);
void _mcrypt_panama_encrypt(PANAMA_KEY * pan_key, byte * buf, int length);
void _mcrypt_panama_decrypt(PANAMA_KEY * pan_key, byte * buf, int length);
int _mcrypt_panama_get_size ();
int _mcrypt_panama_get_block_size();
int _panama_is_block_algorithm();
int _mcrypt_panama_get_key_size();
int _mcrypt_panama_get_supported_key_sizes(int *size);
char * _mcrypt_panama_get_algorithms_name();
int _mcrypt_panama_self_test();
word32 _mcrypt_panama_algorithm_version();
#endif
@@ -0,0 +1,323 @@
/**********************************************************************\
* To commemorate the 1996 RSA Data Security Conference, the following *
* code is released into the public domain by its author. Prost! *
* *
* This cipher uses 16-bit words and little-endian byte ordering. *
* I wonder which processor it was optimized for? *
* *
* Thanks to CodeView, SoftIce, and D86 for helping bring this code to *
* the public. *
\**********************************************************************/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: rc2.c,v 1.14 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
/* #include <assert.h> */
#include "rc2.h"
#define _mcrypt_set_key rc2_LTX__mcrypt_set_key
#define _mcrypt_encrypt rc2_LTX__mcrypt_encrypt
#define _mcrypt_decrypt rc2_LTX__mcrypt_decrypt
#define _mcrypt_get_size rc2_LTX__mcrypt_get_size
#define _mcrypt_get_block_size rc2_LTX__mcrypt_get_block_size
#define _is_block_algorithm rc2_LTX__is_block_algorithm
#define _mcrypt_get_key_size rc2_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes rc2_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name rc2_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test rc2_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version rc2_LTX__mcrypt_algorithm_version
/**********************************************************************\
* Expand a variable-length user key (between 1 and 128 bytes) to a *
* 64-short working rc2 key, of at most "bits" effective key bits. *
* The effective key bits parameter looks like an export control hack. *
* For normal use, it should always be set to 1024. For convenience, *
* zero is accepted as an alias for 1024. *
\**********************************************************************/
WIN32DLL_DEFINE
int _mcrypt_set_key(word16 * xkey, const byte * key, unsigned int len)
{
unsigned int j;
byte *xkey_p = (void *) xkey;
int i;
/* 256-entry permutation table, probably derived somehow from pi */
static const byte permute[256] = {
217, 120, 249, 196, 25, 221, 181, 237, 40, 233, 253, 121,
74, 160, 216, 157,
198, 126, 55, 131, 43, 118, 83, 142, 98, 76, 100, 136,
68, 139, 251, 162,
23, 154, 89, 245, 135, 179, 79, 19, 97, 69, 109, 141, 9,
129, 125, 50,
189, 143, 64, 235, 134, 183, 123, 11, 240, 149, 33, 34,
92, 107, 78, 130,
84, 214, 101, 147, 206, 96, 178, 28, 115, 86, 192, 20,
167, 140, 241, 220,
18, 117, 202, 31, 59, 190, 228, 209, 66, 61, 212, 48,
163, 60, 182, 38,
111, 191, 14, 218, 70, 105, 7, 87, 39, 242, 29, 155, 188,
148, 67, 3,
248, 17, 199, 246, 144, 239, 62, 231, 6, 195, 213, 47,
200, 102, 30, 215,
8, 232, 234, 222, 128, 82, 238, 247, 132, 170, 114, 172,
53, 77, 106, 42,
150, 26, 210, 113, 90, 21, 73, 116, 75, 159, 208, 94, 4,
24, 164, 236,
194, 224, 65, 110, 15, 81, 203, 204, 36, 145, 175, 80,
161, 244, 112, 57,
153, 124, 58, 133, 35, 184, 180, 122, 252, 2, 54, 91, 37,
85, 151, 49,
45, 93, 250, 152, 227, 138, 146, 174, 5, 223, 41, 16,
103, 108, 186, 201,
211, 0, 230, 207, 225, 158, 168, 44, 99, 22, 1, 63, 88,
226, 137, 169,
13, 56, 52, 27, 171, 51, 255, 176, 187, 72, 12, 95, 185,
177, 205, 46,
197, 243, 219, 71, 229, 165, 156, 119, 10, 166, 32, 104,
254, 127, 193, 173
};
/* assert(len > 0 && len <= 128); */
memmove(xkey, key, len);
/* Phase 1: Expand input key to 128 bytes */
for (j = len; j < 128; j++) {
xkey_p[j] =
permute[(xkey_p[j - len] + xkey_p[j - 1]) % 256];
}
xkey_p[0] = permute[xkey_p[0]];
/* Phase 2 - reduce effective key size to "bits" */
/* stripped */
/* Phase 3 - copy to xkey in little-endian order */
i = 63;
do {
xkey[i] = xkey_p[2 * i] + (xkey_p[2 * i + 1] << 8);
} while (i--);
return 0;
}
/**********************************************************************\
* Encrypt an 8-byte block of plaintext using the given key. *
\**********************************************************************/
WIN32DLL_DEFINE void _mcrypt_encrypt(const word16 * xkey, word16 * plain)
{
word16 x3, x2, x1, x0, i;
#ifdef WORDS_BIGENDIAN
x3 = byteswap16(plain[3]);
x2 = byteswap16(plain[2]);
x1 = byteswap16(plain[1]);
x0 = byteswap16(plain[0]);
#else
x3 = plain[3];
x2 = plain[2];
x1 = plain[1];
x0 = plain[0];
#endif
for (i = 0; i < 16; i++) {
x0 += (x1 & ~x3) + (x2 & x3) + xkey[4 * i + 0];
x0 = rotl16(x0, 1);
x1 += (x2 & ~x0) + (x3 & x0) + xkey[4 * i + 1];
x1 = rotl16(x1, 2);
x2 += (x3 & ~x1) + (x0 & x1) + xkey[4 * i + 2];
x2 = rotl16(x2, 3);
x3 += (x0 & ~x2) + (x1 & x2) + xkey[4 * i + 3];
x3 = rotl16(x3, 5);
if (i == 4 || i == 10) {
x0 += xkey[x3 & 63];
x1 += xkey[x0 & 63];
x2 += xkey[x1 & 63];
x3 += xkey[x2 & 63];
}
}
#ifdef WORDS_BIGENDIAN
plain[0] = byteswap16(x0);
plain[1] = byteswap16(x1);
plain[2] = byteswap16(x2);
plain[3] = byteswap16(x3);
#else
plain[0] = (x0);
plain[1] = (x1);
plain[2] = (x2);
plain[3] = (x3);
#endif
}
/**********************************************************************\
* Decrypt an 8-byte block of ciphertext using the given key. *
\**********************************************************************/
WIN32DLL_DEFINE void _mcrypt_decrypt(const word16 * xkey, word16 * plain)
{
word16 x3, x2, x1, x0, i;
#ifndef WORDS_BIGENDIAN
x3 = plain[3];
x2 = plain[2];
x1 = plain[1];
x0 = plain[0];
#else
x3 = byteswap16(plain[3]);
x2 = byteswap16(plain[2]);
x1 = byteswap16(plain[1]);
x0 = byteswap16(plain[0]);
#endif
i = 15;
do {
x3 = rotr16(x3, 5);
x3 -= (x0 & ~x2) + (x1 & x2) + xkey[4 * i + 3];
x2 = rotr16(x2, 3);
x2 -= (x3 & ~x1) + (x0 & x1) + xkey[4 * i + 2];
x1 = rotr16(x1, 2);
x1 -= (x2 & ~x0) + (x3 & x0) + xkey[4 * i + 1];
x0 = rotr16(x0, 1);
x0 -= (x1 & ~x3) + (x2 & x3) + xkey[4 * i + 0];
if (i == 5 || i == 11) {
x3 -= xkey[x2 & 63];
x2 -= xkey[x1 & 63];
x1 -= xkey[x0 & 63];
x0 -= xkey[x3 & 63];
}
} while (i--);
#ifdef WORDS_BIGENDIAN
plain[0] = byteswap16(x0);
plain[1] = byteswap16(x1);
plain[2] = byteswap16(x2);
plain[3] = byteswap16(x3);
#else
plain[0] = x0;
plain[1] = x1;
plain[2] = x2;
plain[3] = x3;
#endif
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return 64 * sizeof(word16);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 128;
}
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = 0;
return NULL;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "RC2";
}
#define CIPHER "becbe4c8e6237a14"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,507 @@
/* Rijndael Cipher
Written by Mike Scott 21st April 1999
Copyright (c) 1999 Mike Scott
See rijndael documentation
Permission for free direct or derivative use is granted subject
to compliance with any conditions that the originators of the
algorithm place on its exploitation.
Inspiration from Brian Gladman's implementation is acknowledged.
Written for clarity, rather than speed.
Full implementation.
Endian indifferent.
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: rijndael-128.c,v 1.14 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "rijndael.h"
#define _mcrypt_set_key rijndael_128_LTX__mcrypt_set_key
#define _mcrypt_encrypt rijndael_128_LTX__mcrypt_encrypt
#define _mcrypt_decrypt rijndael_128_LTX__mcrypt_decrypt
#define _mcrypt_get_size rijndael_128_LTX__mcrypt_get_size
#define _mcrypt_get_block_size rijndael_128_LTX__mcrypt_get_block_size
#define _is_block_algorithm rijndael_128_LTX__is_block_algorithm
#define _mcrypt_get_key_size rijndael_128_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes rijndael_128_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name rijndael_128_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test rijndael_128_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version rijndael_128_LTX__mcrypt_algorithm_version
/* rotates x one bit to the left */
#define ROTL(x) (((x)>>7)|((x)<<1))
/* Rotates 32-bit word left by 1, 2 or 3 byte */
#define ROTL8(x) (((x)<<8)|((x)>>24))
#define ROTL16(x) (((x)<<16)|((x)>>16))
#define ROTL24(x) (((x)<<24)|((x)>>8))
/* Fixed Data */
static byte InCo[4] = { 0xB, 0xD, 0x9, 0xE }; /* Inverse Coefficients */
static byte fbsub[256];
static byte rbsub[256];
static byte ptab[256], ltab[256];
static word32 ftable[256];
static word32 rtable[256];
static word32 rco[30];
static int tables_ok = 0;
/* Parameter-dependent data */
/* in "rijndael.h" */
static word32 pack(byte * b)
{ /* pack bytes into a 32-bit Word */
return ((word32) b[3] << 24) | ((word32) b[2] << 16) | ((word32)
b[1] << 8)
| (word32) b[0];
}
static void unpack(word32 a, byte * b)
{ /* unpack bytes from a word */
b[0] = (byte) a;
b[1] = (byte) (a >> 8);
b[2] = (byte) (a >> 16);
b[3] = (byte) (a >> 24);
}
static byte xtime(byte a)
{
byte b;
if (a & 0x80)
b = 0x1B;
else
b = 0;
a <<= 1;
a ^= b;
return a;
}
static byte bmul(byte x, byte y)
{ /* x.y= AntiLog(Log(x) + Log(y)) */
if (x && y)
return ptab[(ltab[x] + ltab[y]) % 255];
else
return 0;
}
static word32 SubByte(word32 a)
{
byte b[4];
unpack(a, b);
b[0] = fbsub[b[0]];
b[1] = fbsub[b[1]];
b[2] = fbsub[b[2]];
b[3] = fbsub[b[3]];
return pack(b);
}
static byte product(word32 x, word32 y)
{ /* dot product of two 4-byte arrays */
byte xb[4], yb[4];
unpack(x, xb);
unpack(y, yb);
return bmul(xb[0], yb[0]) ^ bmul(xb[1], yb[1]) ^ bmul(xb[2],
yb[2]) ^
bmul(xb[3], yb[3]);
}
static word32 InvMixCol(word32 x)
{ /* matrix Multiplication */
word32 y, m;
byte b[4];
m = pack(InCo);
b[3] = product(m, x);
m = ROTL24(m);
b[2] = product(m, x);
m = ROTL24(m);
b[1] = product(m, x);
m = ROTL24(m);
b[0] = product(m, x);
y = pack(b);
return y;
}
static byte ByteSub(byte x)
{
byte y = ptab[255 - ltab[x]]; /* multiplicative inverse */
x = y;
x = ROTL(x);
y ^= x;
x = ROTL(x);
y ^= x;
x = ROTL(x);
y ^= x;
x = ROTL(x);
y ^= x;
y ^= 0x63;
return y;
}
static void _mcrypt_rijndael_gentables(void)
{ /* generate tables */
int i;
byte y, b[4];
/* use 3 as primitive root to generate power and log tables */
ltab[0] = 0;
ptab[0] = 1;
ltab[1] = 0;
ptab[1] = 3;
ltab[3] = 1;
for (i = 2; i < 256; i++) {
ptab[i] = ptab[i - 1] ^ xtime(ptab[i - 1]);
ltab[ptab[i]] = i;
}
/* affine transformation:- each bit is xored with itself shifted one bit */
fbsub[0] = 0x63;
rbsub[0x63] = 0;
for (i = 1; i < 256; i++) {
y = ByteSub((byte) i);
fbsub[i] = y;
rbsub[y] = i;
}
for (i = 0, y = 1; i < 30; i++) {
rco[i] = y;
y = xtime(y);
}
/* calculate forward and reverse tables */
for (i = 0; i < 256; i++) {
y = fbsub[i];
b[3] = y ^ xtime(y);
b[2] = y;
b[1] = y;
b[0] = xtime(y);
ftable[i] = pack(b);
y = rbsub[i];
b[3] = bmul(InCo[0], y);
b[2] = bmul(InCo[1], y);
b[1] = bmul(InCo[2], y);
b[0] = bmul(InCo[3], y);
rtable[i] = pack(b);
}
}
WIN32DLL_DEFINE int _mcrypt_set_key(RI * rinst, byte * key, int nk)
{ /* blocksize=32*nb bits. Key=32*nk bits */
/* currently nb,bk = 4, 6 or 8 */
/* key comes as 4*rinst->Nk bytes */
/* Key Scheduler. Create expanded encryption key */
int nb = 4; /* 128 block size */
int i, j, k, m, N;
int C1, C2, C3;
word32 CipherKey[8];
nk /= 4;
if (nk < 4)
nk = 4;
if (tables_ok == 0) {
_mcrypt_rijndael_gentables();
tables_ok = 1;
}
rinst->Nb = nb;
rinst->Nk = nk;
/* rinst->Nr is number of rounds */
if (rinst->Nb >= rinst->Nk)
rinst->Nr = 6 + rinst->Nb;
else
rinst->Nr = 6 + rinst->Nk;
C1 = 1;
if (rinst->Nb < 8) {
C2 = 2;
C3 = 3;
} else {
C2 = 3;
C3 = 4;
}
/* pre-calculate forward and reverse increments */
for (m = j = 0; j < nb; j++, m += 3) {
rinst->fi[m] = (j + C1) % nb;
rinst->fi[m + 1] = (j + C2) % nb;
rinst->fi[m + 2] = (j + C3) % nb;
rinst->ri[m] = (nb + j - C1) % nb;
rinst->ri[m + 1] = (nb + j - C2) % nb;
rinst->ri[m + 2] = (nb + j - C3) % nb;
}
N = rinst->Nb * (rinst->Nr + 1);
for (i = j = 0; i < rinst->Nk; i++, j += 4) {
CipherKey[i] = pack(&key[j]);
}
for (i = 0; i < rinst->Nk; i++)
rinst->fkey[i] = CipherKey[i];
for (j = rinst->Nk, k = 0; j < N; j += rinst->Nk, k++) {
rinst->fkey[j] =
rinst->fkey[j -
rinst->Nk] ^ SubByte(ROTL24(rinst->
fkey[j -
1])) ^
rco[k];
if (rinst->Nk <= 6) {
for (i = 1; i < rinst->Nk && (i + j) < N; i++)
rinst->fkey[i + j] =
rinst->fkey[i + j -
rinst->Nk] ^ rinst->
fkey[i + j - 1];
} else {
for (i = 1; i < 4 && (i + j) < N; i++)
rinst->fkey[i + j] =
rinst->fkey[i + j -
rinst->Nk] ^ rinst->
fkey[i + j - 1];
if ((j + 4) < N)
rinst->fkey[j + 4] =
rinst->fkey[j + 4 -
rinst->
Nk] ^ SubByte(rinst->
fkey[j + 3]);
for (i = 5; i < rinst->Nk && (i + j) < N; i++)
rinst->fkey[i + j] =
rinst->fkey[i + j -
rinst->Nk] ^ rinst->
fkey[i + j - 1];
}
}
/* now for the expanded decrypt key in reverse order */
for (j = 0; j < rinst->Nb; j++)
rinst->rkey[j + N - rinst->Nb] = rinst->fkey[j];
for (i = rinst->Nb; i < N - rinst->Nb; i += rinst->Nb) {
k = N - rinst->Nb - i;
for (j = 0; j < rinst->Nb; j++)
rinst->rkey[k + j] = InvMixCol(rinst->fkey[i + j]);
}
for (j = N - rinst->Nb; j < N; j++)
rinst->rkey[j - N + rinst->Nb] = rinst->fkey[j];
return 0;
}
/* There is an obvious time/space trade-off possible here. *
* Instead of just one ftable[], I could have 4, the other *
* 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */
WIN32DLL_DEFINE void _mcrypt_encrypt(RI * rinst, byte * buff)
{
int i, j, k, m;
word32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
a[i] = pack(&buff[j]);
a[i] ^= rinst->fkey[i];
}
k = rinst->Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < rinst->Nr; i++) { /* rinst->Nr is number of rounds. May be odd. */
/* if rinst->Nb is fixed - unroll this next
loop and hard-code in the values of fi[] */
for (m = j = 0; j < rinst->Nb; j++, m += 3) { /* deal with each 32-bit element of the State */
/* This is the time-critical bit */
y[j] = rinst->fkey[k++] ^ ftable[(byte) x[j]] ^
ROTL8(ftable[(byte) (x[rinst->fi[m]] >> 8)]) ^
ROTL16(ftable
[(byte) (x[rinst->fi[m + 1]] >> 16)]) ^
ROTL24(ftable[x[rinst->fi[m + 2]] >> 24]);
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < rinst->Nb; j++, m += 3) {
y[j] = rinst->fkey[k++] ^ (word32) fbsub[(byte) x[j]] ^
ROTL8((word32) fbsub[(byte) (x[rinst->fi[m]] >> 8)]) ^
ROTL16((word32)
fbsub[(byte) (x[rinst->fi[m + 1]] >> 16)]) ^
ROTL24((word32) fbsub[x[rinst->fi[m + 2]] >> 24]);
}
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
unpack(y[i], &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
WIN32DLL_DEFINE void _mcrypt_decrypt(RI * rinst, byte * buff)
{
int i, j, k, m;
word32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
a[i] = pack(&buff[j]);
a[i] ^= rinst->rkey[i];
}
k = rinst->Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < rinst->Nr; i++) { /* rinst->Nr is number of rounds. May be odd. */
/* if rinst->Nb is fixed - unroll this next
loop and hard-code in the values of ri[] */
for (m = j = 0; j < rinst->Nb; j++, m += 3) { /* This is the time-critical bit */
y[j] = rinst->rkey[k++] ^ rtable[(byte) x[j]] ^
ROTL8(rtable[(byte) (x[rinst->ri[m]] >> 8)]) ^
ROTL16(rtable
[(byte) (x[rinst->ri[m + 1]] >> 16)]) ^
ROTL24(rtable[x[rinst->ri[m + 2]] >> 24]);
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < rinst->Nb; j++, m += 3) {
y[j] = rinst->rkey[k++] ^ (word32) rbsub[(byte) x[j]] ^
ROTL8((word32) rbsub[(byte) (x[rinst->ri[m]] >> 8)]) ^
ROTL16((word32)
rbsub[(byte) (x[rinst->ri[m + 1]] >> 16)]) ^
ROTL24((word32) rbsub[x[rinst->ri[m + 2]] >> 24]);
}
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
unpack(y[i], &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(RI);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 16;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 16, 24 ,32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "Rijndael-128";
}
#define CIPHER "5352e43763eec1a8502433d6d520b1f0"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[32];
unsigned char ciphertext[32];
int blocksize = _mcrypt_get_block_size(), j;
int keysize = 16;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, keysize);
if (keyword == NULL)
return -1;
for (j = 0; j < keysize; j++) {
keyword[j] = 0;
}
keyword[0] = 1;
for (j = 0; j < blocksize; j++) {
plaintext[j] = j;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, keysize);
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,505 @@
/* Rijndael Cipher
Written by Mike Scott 21st April 1999
Copyright (c) 1999 Mike Scott
See rijndael documentation
Permission for free direct or derivative use is granted subject
to compliance with any conditions that the originators of the
algorithm place on its exploitation.
Inspiration from Brian Gladman's implementation is acknowledged.
Written for clarity, rather than speed.
Full implementation.
Endian indifferent.
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: rijndael-192.c,v 1.15 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "rijndael.h"
#define _mcrypt_set_key rijndael_192_LTX__mcrypt_set_key
#define _mcrypt_encrypt rijndael_192_LTX__mcrypt_encrypt
#define _mcrypt_decrypt rijndael_192_LTX__mcrypt_decrypt
#define _mcrypt_get_size rijndael_192_LTX__mcrypt_get_size
#define _mcrypt_get_block_size rijndael_192_LTX__mcrypt_get_block_size
#define _is_block_algorithm rijndael_192_LTX__is_block_algorithm
#define _mcrypt_get_key_size rijndael_192_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes rijndael_192_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name rijndael_192_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test rijndael_192_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version rijndael_192_LTX__mcrypt_algorithm_version
/* rotates x one bit to the left */
#define ROTL(x) (((x)>>7)|((x)<<1))
/* Rotates 32-bit word left by 1, 2 or 3 byte */
#define ROTL8(x) (((x)<<8)|((x)>>24))
#define ROTL16(x) (((x)<<16)|((x)>>16))
#define ROTL24(x) (((x)<<24)|((x)>>8))
/* Fixed Data */
static byte InCo[4] = { 0xB, 0xD, 0x9, 0xE }; /* Inverse Coefficients */
static byte fbsub[256];
static byte rbsub[256];
static byte ptab[256], ltab[256];
static word32 ftable[256];
static word32 rtable[256];
static word32 rco[30];
static int tables_ok = 0;
/* Parameter-dependent data */
/* in "rijndael.h" */
static word32 pack(byte * b)
{ /* pack bytes into a 32-bit Word */
return ((word32) b[3] << 24) | ((word32) b[2] << 16) | ((word32)
b[1] << 8)
| (word32) b[0];
}
static void unpack(word32 a, byte * b)
{ /* unpack bytes from a word */
b[0] = (byte) a;
b[1] = (byte) (a >> 8);
b[2] = (byte) (a >> 16);
b[3] = (byte) (a >> 24);
}
static byte xtime(byte a)
{
byte b;
if (a & 0x80)
b = 0x1B;
else
b = 0;
a <<= 1;
a ^= b;
return a;
}
static byte bmul(byte x, byte y)
{ /* x.y= AntiLog(Log(x) + Log(y)) */
if (x && y)
return ptab[(ltab[x] + ltab[y]) % 255];
else
return 0;
}
static word32 SubByte(word32 a)
{
byte b[4];
unpack(a, b);
b[0] = fbsub[b[0]];
b[1] = fbsub[b[1]];
b[2] = fbsub[b[2]];
b[3] = fbsub[b[3]];
return pack(b);
}
static byte product(word32 x, word32 y)
{ /* dot product of two 4-byte arrays */
byte xb[4], yb[4];
unpack(x, xb);
unpack(y, yb);
return bmul(xb[0], yb[0]) ^ bmul(xb[1], yb[1]) ^ bmul(xb[2],
yb[2]) ^
bmul(xb[3], yb[3]);
}
static word32 InvMixCol(word32 x)
{ /* matrix Multiplication */
word32 y, m;
byte b[4];
m = pack(InCo);
b[3] = product(m, x);
m = ROTL24(m);
b[2] = product(m, x);
m = ROTL24(m);
b[1] = product(m, x);
m = ROTL24(m);
b[0] = product(m, x);
y = pack(b);
return y;
}
static byte ByteSub(byte x)
{
byte y = ptab[255 - ltab[x]]; /* multiplicative inverse */
x = y;
x = ROTL(x);
y ^= x;
x = ROTL(x);
y ^= x;
x = ROTL(x);
y ^= x;
x = ROTL(x);
y ^= x;
y ^= 0x63;
return y;
}
static void _mcrypt_rijndael_gentables(void)
{ /* generate tables */
int i;
byte y, b[4];
/* use 3 as primitive root to generate power and log tables */
ltab[0] = 0;
ptab[0] = 1;
ltab[1] = 0;
ptab[1] = 3;
ltab[3] = 1;
for (i = 2; i < 256; i++) {
ptab[i] = ptab[i - 1] ^ xtime(ptab[i - 1]);
ltab[ptab[i]] = i;
}
/* affine transformation:- each bit is xored with itself shifted one bit */
fbsub[0] = 0x63;
rbsub[0x63] = 0;
for (i = 1; i < 256; i++) {
y = ByteSub((byte) i);
fbsub[i] = y;
rbsub[y] = i;
}
for (i = 0, y = 1; i < 30; i++) {
rco[i] = y;
y = xtime(y);
}
/* calculate forward and reverse tables */
for (i = 0; i < 256; i++) {
y = fbsub[i];
b[3] = y ^ xtime(y);
b[2] = y;
b[1] = y;
b[0] = xtime(y);
ftable[i] = pack(b);
y = rbsub[i];
b[3] = bmul(InCo[0], y);
b[2] = bmul(InCo[1], y);
b[1] = bmul(InCo[2], y);
b[0] = bmul(InCo[3], y);
rtable[i] = pack(b);
}
}
WIN32DLL_DEFINE int _mcrypt_set_key(RI * rinst, byte * key, int nk)
{ /* blocksize=32*nb bits. Key=32*nk bits */
/* currently nb,bk = 4, 6 or 8 */
/* key comes as 4*rinst->Nk bytes */
/* Key Scheduler. Create expanded encryption key */
int nb = 6; /* 192 block size */
int i, j, k, m, N;
int C1, C2, C3;
word32 CipherKey[8];
nk /= 4;
if (tables_ok == 0) {
_mcrypt_rijndael_gentables();
tables_ok = 1;
}
rinst->Nb = nb;
rinst->Nk = nk;
/* rinst->Nr is number of rounds */
if (rinst->Nb >= rinst->Nk)
rinst->Nr = 6 + rinst->Nb;
else
rinst->Nr = 6 + rinst->Nk;
C1 = 1;
if (rinst->Nb < 8) {
C2 = 2;
C3 = 3;
} else {
C2 = 3;
C3 = 4;
}
/* pre-calculate forward and reverse increments */
for (m = j = 0; j < nb; j++, m += 3) {
rinst->fi[m] = (j + C1) % nb;
rinst->fi[m + 1] = (j + C2) % nb;
rinst->fi[m + 2] = (j + C3) % nb;
rinst->ri[m] = (nb + j - C1) % nb;
rinst->ri[m + 1] = (nb + j - C2) % nb;
rinst->ri[m + 2] = (nb + j - C3) % nb;
}
N = rinst->Nb * (rinst->Nr + 1);
for (i = j = 0; i < rinst->Nk; i++, j += 4) {
CipherKey[i] = pack(&key[j]);
}
for (i = 0; i < rinst->Nk; i++)
rinst->fkey[i] = CipherKey[i];
for (j = rinst->Nk, k = 0; j < N; j += rinst->Nk, k++) {
rinst->fkey[j] =
rinst->fkey[j -
rinst->Nk] ^ SubByte(ROTL24(rinst->
fkey[j -
1])) ^
rco[k];
if (rinst->Nk <= 6) {
for (i = 1; i < rinst->Nk && (i + j) < N; i++)
rinst->fkey[i + j] =
rinst->fkey[i + j -
rinst->Nk] ^ rinst->
fkey[i + j - 1];
} else {
for (i = 1; i < 4 && (i + j) < N; i++)
rinst->fkey[i + j] =
rinst->fkey[i + j -
rinst->Nk] ^ rinst->
fkey[i + j - 1];
if ((j + 4) < N)
rinst->fkey[j + 4] =
rinst->fkey[j + 4 -
rinst->
Nk] ^ SubByte(rinst->
fkey[j + 3]);
for (i = 5; i < rinst->Nk && (i + j) < N; i++)
rinst->fkey[i + j] =
rinst->fkey[i + j -
rinst->Nk] ^ rinst->
fkey[i + j - 1];
}
}
/* now for the expanded decrypt key in reverse order */
for (j = 0; j < rinst->Nb; j++)
rinst->rkey[j + N - rinst->Nb] = rinst->fkey[j];
for (i = rinst->Nb; i < N - rinst->Nb; i += rinst->Nb) {
k = N - rinst->Nb - i;
for (j = 0; j < rinst->Nb; j++)
rinst->rkey[k + j] = InvMixCol(rinst->fkey[i + j]);
}
for (j = N - rinst->Nb; j < N; j++)
rinst->rkey[j - N + rinst->Nb] = rinst->fkey[j];
return 0;
}
/* There is an obvious time/space trade-off possible here. *
* Instead of just one ftable[], I could have 4, the other *
* 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */
WIN32DLL_DEFINE void _mcrypt_encrypt(RI * rinst, byte * buff)
{
int i, j, k, m;
word32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
a[i] = pack(&buff[j]);
a[i] ^= rinst->fkey[i];
}
k = rinst->Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < rinst->Nr; i++) { /* rinst->Nr is number of rounds. May be odd. */
/* if rinst->Nb is fixed - unroll this next
loop and hard-code in the values of fi[] */
for (m = j = 0; j < rinst->Nb; j++, m += 3) { /* deal with each 32-bit element of the State */
/* This is the time-critical bit */
y[j] = rinst->fkey[k++] ^ ftable[(byte) x[j]] ^
ROTL8(ftable[(byte) (x[rinst->fi[m]] >> 8)]) ^
ROTL16(ftable
[(byte) (x[rinst->fi[m + 1]] >> 16)]) ^
ROTL24(ftable[x[rinst->fi[m + 2]] >> 24]);
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < rinst->Nb; j++, m += 3) {
y[j] = rinst->fkey[k++] ^ (word32) fbsub[(byte) x[j]] ^
ROTL8((word32) fbsub[(byte) (x[rinst->fi[m]] >> 8)]) ^
ROTL16((word32)
fbsub[(byte) (x[rinst->fi[m + 1]] >> 16)]) ^
ROTL24((word32) fbsub[x[rinst->fi[m + 2]] >> 24]);
}
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
unpack(y[i], &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
WIN32DLL_DEFINE void _mcrypt_decrypt(RI * rinst, byte * buff)
{
int i, j, k, m;
word32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
a[i] = pack(&buff[j]);
a[i] ^= rinst->rkey[i];
}
k = rinst->Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < rinst->Nr; i++) { /* rinst->Nr is number of rounds. May be odd. */
/* if rinst->Nb is fixed - unroll this next
loop and hard-code in the values of ri[] */
for (m = j = 0; j < rinst->Nb; j++, m += 3) { /* This is the time-critical bit */
y[j] = rinst->rkey[k++] ^ rtable[(byte) x[j]] ^
ROTL8(rtable[(byte) (x[rinst->ri[m]] >> 8)]) ^
ROTL16(rtable
[(byte) (x[rinst->ri[m + 1]] >> 16)]) ^
ROTL24(rtable[x[rinst->ri[m + 2]] >> 24]);
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < rinst->Nb; j++, m += 3) {
y[j] = rinst->rkey[k++] ^ (word32) rbsub[(byte) x[j]] ^
ROTL8((word32) rbsub[(byte) (x[rinst->ri[m]] >> 8)]) ^
ROTL16((word32)
rbsub[(byte) (x[rinst->ri[m + 1]] >> 16)]) ^
ROTL24((word32) rbsub[x[rinst->ri[m + 2]] >> 24]);
}
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
unpack(y[i], &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(RI);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 24;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 16, 24, 32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "Rijndael-192";
}
#define CIPHER "380ee49a5de1dbd4b9cc11af60b8c8ff669e367af8948a8a"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[32];
unsigned char ciphertext[32];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,506 @@
/* Rijndael Cipher
Written by Mike Scott 21st April 1999
Copyright (c) 1999 Mike Scott
See rijndael documentation
Permission for free direct or derivative use is granted subject
to compliance with any conditions that the originators of the
algorithm place on its exploitation.
Inspiration from Brian Gladman's implementation is acknowledged.
Written for clarity, rather than speed.
Full implementation.
Endian indifferent.
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: rijndael-256.c,v 1.15 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "rijndael.h"
#define _mcrypt_set_key rijndael_256_LTX__mcrypt_set_key
#define _mcrypt_encrypt rijndael_256_LTX__mcrypt_encrypt
#define _mcrypt_decrypt rijndael_256_LTX__mcrypt_decrypt
#define _mcrypt_get_size rijndael_256_LTX__mcrypt_get_size
#define _mcrypt_get_block_size rijndael_256_LTX__mcrypt_get_block_size
#define _is_block_algorithm rijndael_256_LTX__is_block_algorithm
#define _mcrypt_get_key_size rijndael_256_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes rijndael_256_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name rijndael_256_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test rijndael_256_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version rijndael_256_LTX__mcrypt_algorithm_version
/* rotates x one bit to the left */
#define ROTL(x) (((x)>>7)|((x)<<1))
/* Rotates 32-bit word left by 1, 2 or 3 byte */
#define ROTL8(x) (((x)<<8)|((x)>>24))
#define ROTL16(x) (((x)<<16)|((x)>>16))
#define ROTL24(x) (((x)<<24)|((x)>>8))
/* Fixed Data */
static byte InCo[4] = { 0xB, 0xD, 0x9, 0xE }; /* Inverse Coefficients */
static byte fbsub[256];
static byte rbsub[256];
static byte ptab[256], ltab[256];
static word32 ftable[256];
static word32 rtable[256];
static word32 rco[30];
static int tables_ok = 0;
/* Parameter-dependent data */
/* in "rijndael.h" */
static word32 pack(byte * b)
{ /* pack bytes into a 32-bit Word */
return ((word32) b[3] << 24) | ((word32) b[2] << 16) | ((word32)
b[1] << 8)
| (word32) b[0];
}
static void unpack(word32 a, byte * b)
{ /* unpack bytes from a word */
b[0] = (byte) a;
b[1] = (byte) (a >> 8);
b[2] = (byte) (a >> 16);
b[3] = (byte) (a >> 24);
}
static byte xtime(byte a)
{
byte b;
if (a & 0x80)
b = 0x1B;
else
b = 0;
a <<= 1;
a ^= b;
return a;
}
static byte bmul(byte x, byte y)
{ /* x.y= AntiLog(Log(x) + Log(y)) */
if (x && y)
return ptab[(ltab[x] + ltab[y]) % 255];
else
return 0;
}
static word32 SubByte(word32 a)
{
byte b[4];
unpack(a, b);
b[0] = fbsub[b[0]];
b[1] = fbsub[b[1]];
b[2] = fbsub[b[2]];
b[3] = fbsub[b[3]];
return pack(b);
}
static byte product(word32 x, word32 y)
{ /* dot product of two 4-byte arrays */
byte xb[4], yb[4];
unpack(x, xb);
unpack(y, yb);
return bmul(xb[0], yb[0]) ^ bmul(xb[1], yb[1]) ^ bmul(xb[2],
yb[2]) ^
bmul(xb[3], yb[3]);
}
static word32 InvMixCol(word32 x)
{ /* matrix Multiplication */
word32 y, m;
byte b[4];
m = pack(InCo);
b[3] = product(m, x);
m = ROTL24(m);
b[2] = product(m, x);
m = ROTL24(m);
b[1] = product(m, x);
m = ROTL24(m);
b[0] = product(m, x);
y = pack(b);
return y;
}
static byte ByteSub(byte x)
{
byte y = ptab[255 - ltab[x]]; /* multiplicative inverse */
x = y;
x = ROTL(x);
y ^= x;
x = ROTL(x);
y ^= x;
x = ROTL(x);
y ^= x;
x = ROTL(x);
y ^= x;
y ^= 0x63;
return y;
}
static void _mcrypt_rijndael_gentables(void)
{ /* generate tables */
int i;
byte y, b[4];
/* use 3 as primitive root to generate power and log tables */
ltab[0] = 0;
ptab[0] = 1;
ltab[1] = 0;
ptab[1] = 3;
ltab[3] = 1;
for (i = 2; i < 256; i++) {
ptab[i] = ptab[i - 1] ^ xtime(ptab[i - 1]);
ltab[ptab[i]] = i;
}
/* affine transformation:- each bit is xored with itself shifted one bit */
fbsub[0] = 0x63;
rbsub[0x63] = 0;
for (i = 1; i < 256; i++) {
y = ByteSub((byte) i);
fbsub[i] = y;
rbsub[y] = i;
}
for (i = 0, y = 1; i < 30; i++) {
rco[i] = y;
y = xtime(y);
}
/* calculate forward and reverse tables */
for (i = 0; i < 256; i++) {
y = fbsub[i];
b[3] = y ^ xtime(y);
b[2] = y;
b[1] = y;
b[0] = xtime(y);
ftable[i] = pack(b);
y = rbsub[i];
b[3] = bmul(InCo[0], y);
b[2] = bmul(InCo[1], y);
b[1] = bmul(InCo[2], y);
b[0] = bmul(InCo[3], y);
rtable[i] = pack(b);
}
}
WIN32DLL_DEFINE int _mcrypt_set_key(RI * rinst, byte * key, int nk)
{ /* blocksize=32*nb bits. Key=32*nk bits */
/* currently nb,bk = 4, 6 or 8 */
/* key comes as 4*rinst->Nk bytes */
/* Key Scheduler. Create expanded encryption key */
int nb = 8; /* 256 block size */
int i, j, k, m, N;
int C1, C2, C3;
word32 CipherKey[8];
nk /= 4;
if (tables_ok == 0) {
_mcrypt_rijndael_gentables();
tables_ok = 1;
}
rinst->Nb = nb;
rinst->Nk = nk;
/* rinst->Nr is number of rounds */
if (rinst->Nb >= rinst->Nk)
rinst->Nr = 6 + rinst->Nb;
else
rinst->Nr = 6 + rinst->Nk;
C1 = 1;
if (rinst->Nb < 8) {
C2 = 2;
C3 = 3;
} else {
C2 = 3;
C3 = 4;
}
/* pre-calculate forward and reverse increments */
for (m = j = 0; j < nb; j++, m += 3) {
rinst->fi[m] = (j + C1) % nb;
rinst->fi[m + 1] = (j + C2) % nb;
rinst->fi[m + 2] = (j + C3) % nb;
rinst->ri[m] = (nb + j - C1) % nb;
rinst->ri[m + 1] = (nb + j - C2) % nb;
rinst->ri[m + 2] = (nb + j - C3) % nb;
}
N = rinst->Nb * (rinst->Nr + 1);
for (i = j = 0; i < rinst->Nk; i++, j += 4) {
CipherKey[i] = pack(&key[j]);
}
for (i = 0; i < rinst->Nk; i++)
rinst->fkey[i] = CipherKey[i];
for (j = rinst->Nk, k = 0; j < N; j += rinst->Nk, k++) {
rinst->fkey[j] =
rinst->fkey[j -
rinst->Nk] ^ SubByte(ROTL24(rinst->
fkey[j -
1])) ^
rco[k];
if (rinst->Nk <= 6) {
for (i = 1; i < rinst->Nk && (i + j) < N; i++)
rinst->fkey[i + j] =
rinst->fkey[i + j -
rinst->Nk] ^ rinst->
fkey[i + j - 1];
} else {
for (i = 1; i < 4 && (i + j) < N; i++)
rinst->fkey[i + j] =
rinst->fkey[i + j -
rinst->Nk] ^ rinst->
fkey[i + j - 1];
if ((j + 4) < N)
rinst->fkey[j + 4] =
rinst->fkey[j + 4 -
rinst->
Nk] ^ SubByte(rinst->
fkey[j + 3]);
for (i = 5; i < rinst->Nk && (i + j) < N; i++)
rinst->fkey[i + j] =
rinst->fkey[i + j -
rinst->Nk] ^ rinst->
fkey[i + j - 1];
}
}
/* now for the expanded decrypt key in reverse order */
for (j = 0; j < rinst->Nb; j++)
rinst->rkey[j + N - rinst->Nb] = rinst->fkey[j];
for (i = rinst->Nb; i < N - rinst->Nb; i += rinst->Nb) {
k = N - rinst->Nb - i;
for (j = 0; j < rinst->Nb; j++)
rinst->rkey[k + j] = InvMixCol(rinst->fkey[i + j]);
}
for (j = N - rinst->Nb; j < N; j++)
rinst->rkey[j - N + rinst->Nb] = rinst->fkey[j];
return 0;
}
/* There is an obvious time/space trade-off possible here. *
* Instead of just one ftable[], I could have 4, the other *
* 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */
WIN32DLL_DEFINE void _mcrypt_encrypt(RI * rinst, byte * buff)
{
int i, j, k, m;
word32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
a[i] = pack(&buff[j]);
a[i] ^= rinst->fkey[i];
}
k = rinst->Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < rinst->Nr; i++) { /* rinst->Nr is number of rounds. May be odd. */
/* if rinst->Nb is fixed - unroll this next
loop and hard-code in the values of fi[] */
for (m = j = 0; j < rinst->Nb; j++, m += 3) { /* deal with each 32-bit element of the State */
/* This is the time-critical bit */
y[j] = rinst->fkey[k++] ^ ftable[(byte) x[j]] ^
ROTL8(ftable[(byte) (x[rinst->fi[m]] >> 8)]) ^
ROTL16(ftable
[(byte) (x[rinst->fi[m + 1]] >> 16)]) ^
ROTL24(ftable[x[rinst->fi[m + 2]] >> 24]);
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < rinst->Nb; j++, m += 3) {
y[j] = rinst->fkey[k++] ^ (word32) fbsub[(byte) x[j]] ^
ROTL8((word32) fbsub[(byte) (x[rinst->fi[m]] >> 8)]) ^
ROTL16((word32)
fbsub[(byte) (x[rinst->fi[m + 1]] >> 16)]) ^
ROTL24((word32) fbsub[x[rinst->fi[m + 2]] >> 24]);
}
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
unpack(y[i], &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
WIN32DLL_DEFINE void _mcrypt_decrypt(RI * rinst, byte * buff)
{
int i, j, k, m;
word32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
a[i] = pack(&buff[j]);
a[i] ^= rinst->rkey[i];
}
k = rinst->Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < rinst->Nr; i++) { /* rinst->Nr is number of rounds. May be odd. */
/* if rinst->Nb is fixed - unroll this next
loop and hard-code in the values of ri[] */
for (m = j = 0; j < rinst->Nb; j++, m += 3) { /* This is the time-critical bit */
y[j] = rinst->rkey[k++] ^ rtable[(byte) x[j]] ^
ROTL8(rtable[(byte) (x[rinst->ri[m]] >> 8)]) ^
ROTL16(rtable
[(byte) (x[rinst->ri[m + 1]] >> 16)]) ^
ROTL24(rtable[x[rinst->ri[m + 2]] >> 24]);
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < rinst->Nb; j++, m += 3) {
y[j] = rinst->rkey[k++] ^ (word32) rbsub[(byte) x[j]] ^
ROTL8((word32) rbsub[(byte) (x[rinst->ri[m]] >> 8)]) ^
ROTL16((word32)
rbsub[(byte) (x[rinst->ri[m + 1]] >> 16)]) ^
ROTL24((word32) rbsub[x[rinst->ri[m + 2]] >> 24]);
}
for (i = j = 0; i < rinst->Nb; i++, j += 4) {
unpack(y[i], &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(RI);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 32;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 16, 24, 32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "Rijndael-256";
}
#define CIPHER "45af6c269326fd935edd24733cff74fc1aa358841a6cd80b79f242d983f8ff2e"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[32];
unsigned char ciphertext[32];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,13 @@
typedef struct rijndael_instance {
int Nk,Nb,Nr;
byte fi[24],ri[24];
word32 fkey[120];
word32 rkey[120];
} RI;
/* void _mcrypt_rijndael_128_set_key(RI* rinst, int nb,int nk,byte *key); */
/* blocksize=32*nb bits. Key=32*nk bits */
/* currently nb,bk = 4, 6 or 8 */
/* key comes as 4*Nk bytes */
/* Key Scheduler. Create expanded encryption key */
@@ -0,0 +1,100 @@
/*******************************************************************************
*
* FILE: safer.h
*
* DESCRIPTION: block-cipher algorithm SAFER (Secure And Fast Encryption
* Routine) in its four versions: SAFER K-64, SAFER K-128,
* SAFER SK-64 and SAFER SK-128.
*
* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
* Signal and Information Processing Laboratory
* Swiss Federal Institute of Technology
* CH-8092 Zuerich, Switzerland
*
* DATE: September 9, 1995
*
* CHANGE HISTORY:
*
*******************************************************************************/
#ifndef SAFER_H
#define SAFER_H
/******************* External Headers *****************************************/
/******************* Local Headers ********************************************/
/******************* Constants ************************************************/
#define SAFER_K64_DEFAULT_NOF_ROUNDS 6
#define SAFER_K128_DEFAULT_NOF_ROUNDS 10
#define SAFER_SK64_DEFAULT_NOF_ROUNDS 8
#define SAFER_SK128_DEFAULT_NOF_ROUNDS 10
#define SAFER_MAX_NOF_ROUNDS 13
#define SAFER_BLOCK_LEN 8
#define SAFER_KEY_LEN (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS))
/******************* Assertions ***********************************************/
/******************* Macros ***************************************************/
/******************* Types ****************************************************/
#define safer_block_t unsigned char
/* [SAFER_BLOCK_LEN]; */
#define safer_key_t unsigned char
/* [SAFER_KEY_LEN]; */
/******************* Module Data **********************************************/
/******************* Prototypes ***********************************************/
/*******************************************************************************
* void Safer_Init_Module(void)
*
* initializes this module.
*
********************************************************************************
* void Safer_Expand_Userkey(safer_block_t userkey_1,
* safer_block_t userkey_2,
* unsigned int nof_rounds,
* int strengthened,
* safer_key_t key)
*
* expands a user-selected key of length 64 bits or 128 bits to a encryption /
* decryption key. If your user-selected key is of length 64 bits, then give
* this key to both arguments 'userkey_1' and 'userkey_2', e.g.
* 'Safer_Expand_Userkey(z, z, key)'. Note: SAFER K-64 and SAFER SK-64 with a
* user-selected key 'z' of length 64 bits are identical to SAFER K-128 and
* SAFER SK-128 with a user-selected key 'z z' of length 128 bits,
* respectively.
* pre: 'userkey_1' contains the first 64 bits of user key.
* 'userkey_2' contains the second 64 bits of user key.
* 'nof_rounds' contains the number of encryption rounds
* 'nof_rounds' <= 'SAFER_MAX_NOF_ROUNDS'
* 'strengthened' is non-zero if the strengthened key schedule should be
* used and zero if the original key schedule should be
* used.
* post: 'key' contains the expanded key.
*
********************************************************************************
* void Safer_Encrypt_Block(safer_block_t block_in, safer_key_t key,
* safer_block_t block_out)
*
* encryption algorithm.
* pre: 'block_in' contains the plain-text block.
* 'key' contains the expanded key.
* post: 'block_out' contains the cipher-text block.
*
********************************************************************************
* void Safer_Decrypt_Block(safer_block_t block_in, safer_key_t key,
* safer_block_t block_out)
*
* decryption algorithm.
* pre: 'block_in' contains the cipher-text block.
* 'key' contains the expanded key.
* post: 'block_out' contains the plain-text block.
*
*******************************************************************************/
static void _mcrypt_Safer_Init_Module();
/******************************************************************************/
#endif /* SAFER_H */
@@ -0,0 +1,397 @@
/*******************************************************************************
*
* FILE: safer.c
*
* DESCRIPTION: block-cipher algorithm SAFER (Secure And Fast Encryption
* Routine) in its four versions: SAFER K-64, SAFER K-128,
* SAFER SK-64 and SAFER SK-128.
*
* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
* Signal and Information Processing Laboratory
* Swiss Federal Institute of Technology
* CH-8092 Zuerich, Switzerland
*
* DATE: September 9, 1995
*
* CHANGE HISTORY:
*
*******************************************************************************/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: safer128.c,v 1.12 2003/01/19 17:48:27 nmav Exp $ */
/******************* External Headers *****************************************/
/******************* Local Headers ********************************************/
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "safer.h"
#define _mcrypt_set_key safer_sk128_LTX__mcrypt_set_key
#define _mcrypt_encrypt safer_sk128_LTX__mcrypt_encrypt
#define _mcrypt_decrypt safer_sk128_LTX__mcrypt_decrypt
#define _mcrypt_get_size safer_sk128_LTX__mcrypt_get_size
#define _mcrypt_get_block_size safer_sk128_LTX__mcrypt_get_block_size
#define _is_block_algorithm safer_sk128_LTX__is_block_algorithm
#define _mcrypt_get_key_size safer_sk128_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes safer_sk128_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name safer_sk128_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test safer_sk128_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version safer_sk128_LTX__mcrypt_algorithm_version
/******************* Constants ************************************************/
#define TAB_LEN 256
static int _safer128_init = 0;
/******************* Assertions ***********************************************/
/******************* Macros ***************************************************/
#define ROL(x, n) ((unsigned char)((unsigned int)(x) << (n)\
|(unsigned int)((x) & 0xFF) >> (8 - (n))))
#define EXP(x) exp_tab128[(x) & 0xFF]
#define LOG(x) log_tab128[(x) & 0xFF]
#define PHT(x, y) { y += x; x += y; }
#define IPHT(x, y) { x -= y; y -= x; }
/******************* Types ****************************************************/
static unsigned char exp_tab128[TAB_LEN];
static unsigned char log_tab128[TAB_LEN];
/******************* Module Data **********************************************/
/******************* Functions ************************************************/
/******************************************************************************/
static void _mcrypt_Safer_Init_Module(void)
{
unsigned int i, exp;
exp = 1;
for (i = 0; i < TAB_LEN; i++) {
exp_tab128[i] = (unsigned char) (exp & 0xFF);
log_tab128[exp_tab128[i]] = (unsigned char) i;
exp = exp * 45 % 257;
}
} /* Safer_Init_Module */
/******************************************************************************/
WIN32DLL_DEFINE
int _mcrypt_set_key(safer_key_t * key, safer_block_t * userkey,
int len)
{
unsigned int i, j;
unsigned char ka[SAFER_BLOCK_LEN + 1];
unsigned char kb[SAFER_BLOCK_LEN + 1];
int nof_rounds = SAFER_SK64_DEFAULT_NOF_ROUNDS;
int strengthened = 1;
unsigned char *userkey_1 = &userkey[0];
unsigned char *userkey_2 = &userkey[8];
if (_safer128_init == 0) {
_mcrypt_Safer_Init_Module();
_safer128_init = 1;
}
if (SAFER_MAX_NOF_ROUNDS < nof_rounds)
nof_rounds = SAFER_MAX_NOF_ROUNDS;
*key++ = (unsigned char) nof_rounds;
ka[SAFER_BLOCK_LEN] = 0;
kb[SAFER_BLOCK_LEN] = 0;
for (j = 0; j < SAFER_BLOCK_LEN; j++) {
ka[SAFER_BLOCK_LEN] ^= ka[j] = ROL(userkey_1[j], 5);
kb[SAFER_BLOCK_LEN] ^= kb[j] = *key++ = userkey_2[j];
}
for (i = 1; i <= nof_rounds; i++) {
for (j = 0; j < SAFER_BLOCK_LEN + 1; j++) {
ka[j] = ROL(ka[j], 6);
kb[j] = ROL(kb[j], 6);
}
for (j = 0; j < SAFER_BLOCK_LEN; j++)
if (strengthened)
*key++ =
(ka
[(j + 2 * i - 1) %
(SAFER_BLOCK_LEN + 1)] +
exp_tab128[exp_tab128[18 * i + j + 1]]) &
0xFF;
else
*key++ =
(ka[j] +
exp_tab128[exp_tab128[18 * i + j + 1]]) &
0xFF;
for (j = 0; j < SAFER_BLOCK_LEN; j++)
if (strengthened)
*key++ =
(kb
[(j + 2 * i) %
(SAFER_BLOCK_LEN + 1)] +
exp_tab128[exp_tab128[18 * i + j + 10]]) &
0xFF;
else
*key++ =
(kb[j] +
exp_tab128[exp_tab128[18 * i + j + 10]]) &
0xFF;
}
for (j = 0; j < SAFER_BLOCK_LEN + 1; j++)
ka[j] = kb[j] = 0;
return 0;
} /* Safer_Expand_Userkey */
/******************************************************************************/
WIN32DLL_DEFINE
void _mcrypt_encrypt(const safer_key_t * key, safer_block_t * block_in)
{
unsigned char a, b, c, d, e, f, g, h, t;
unsigned int round;
a = block_in[0];
b = block_in[1];
c = block_in[2];
d = block_in[3];
e = block_in[4];
f = block_in[5];
g = block_in[6];
h = block_in[7];
if (SAFER_MAX_NOF_ROUNDS < (round = *key))
round = SAFER_MAX_NOF_ROUNDS;
while (round--) {
a ^= *++key;
b += *++key;
c += *++key;
d ^= *++key;
e ^= *++key;
f += *++key;
g += *++key;
h ^= *++key;
a = EXP(a) + *++key;
b = LOG(b) ^ *++key;
c = LOG(c) ^ *++key;
d = EXP(d) + *++key;
e = EXP(e) + *++key;
f = LOG(f) ^ *++key;
g = LOG(g) ^ *++key;
h = EXP(h) + *++key;
PHT(a, b);
PHT(c, d);
PHT(e, f);
PHT(g, h);
PHT(a, c);
PHT(e, g);
PHT(b, d);
PHT(f, h);
PHT(a, e);
PHT(b, f);
PHT(c, g);
PHT(d, h);
t = b;
b = e;
e = c;
c = t;
t = d;
d = f;
f = g;
g = t;
}
a ^= *++key;
b += *++key;
c += *++key;
d ^= *++key;
e ^= *++key;
f += *++key;
g += *++key;
h ^= *++key;
block_in[0] = a & 0xFF;
block_in[1] = b & 0xFF;
block_in[2] = c & 0xFF;
block_in[3] = d & 0xFF;
block_in[4] = e & 0xFF;
block_in[5] = f & 0xFF;
block_in[6] = g & 0xFF;
block_in[7] = h & 0xFF;
} /* Safer_Encrypt_Block */
/******************************************************************************/
WIN32DLL_DEFINE
void _mcrypt_decrypt(const safer_key_t * key, safer_block_t * block_in)
{
safer_block_t a, b, c, d, e, f, g, h, t;
unsigned int round;
a = block_in[0];
b = block_in[1];
c = block_in[2];
d = block_in[3];
e = block_in[4];
f = block_in[5];
g = block_in[6];
h = block_in[7];
if (SAFER_MAX_NOF_ROUNDS < (round = *key))
round = SAFER_MAX_NOF_ROUNDS;
key += SAFER_BLOCK_LEN * (1 + 2 * round);
h ^= *key;
g -= *--key;
f -= *--key;
e ^= *--key;
d ^= *--key;
c -= *--key;
b -= *--key;
a ^= *--key;
while (round--) {
t = e;
e = b;
b = c;
c = t;
t = f;
f = d;
d = g;
g = t;
IPHT(a, e);
IPHT(b, f);
IPHT(c, g);
IPHT(d, h);
IPHT(a, c);
IPHT(e, g);
IPHT(b, d);
IPHT(f, h);
IPHT(a, b);
IPHT(c, d);
IPHT(e, f);
IPHT(g, h);
h -= *--key;
g ^= *--key;
f ^= *--key;
e -= *--key;
d -= *--key;
c ^= *--key;
b ^= *--key;
a -= *--key;
h = LOG(h) ^ *--key;
g = EXP(g) - *--key;
f = EXP(f) - *--key;
e = LOG(e) ^ *--key;
d = LOG(d) ^ *--key;
c = EXP(c) - *--key;
b = EXP(b) - *--key;
a = LOG(a) ^ *--key;
}
block_in[0] = a & 0xFF;
block_in[1] = b & 0xFF;
block_in[2] = c & 0xFF;
block_in[3] = d & 0xFF;
block_in[4] = e & 0xFF;
block_in[5] = f & 0xFF;
block_in[6] = g & 0xFF;
block_in[7] = h & 0xFF;
} /* Safer_Decrypt_Block */
/******************************************************************************/
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS));
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 16;
}
static const int key_sizes[] = { 16 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "SAFER-SK128";
}
#define CIPHER "35ed856e2cf90947"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,394 @@
/*******************************************************************************
*
* FILE: safer.c
*
* DESCRIPTION: block-cipher algorithm SAFER (Secure And Fast Encryption
* Routine) in its four versions: SAFER K-64, SAFER K-128,
* SAFER SK-64 and SAFER SK-128.
*
* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
* Signal and Information Processing Laboratory
* Swiss Federal Institute of Technology
* CH-8092 Zuerich, Switzerland
*
* DATE: September 9, 1995
*
* CHANGE HISTORY:
*
*******************************************************************************/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: safer64.c,v 1.12 2003/01/19 17:48:27 nmav Exp $ */
/******************* External Headers *****************************************/
/******************* Local Headers ********************************************/
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "safer.h"
#define _mcrypt_set_key safer_sk64_LTX__mcrypt_set_key
#define _mcrypt_encrypt safer_sk64_LTX__mcrypt_encrypt
#define _mcrypt_decrypt safer_sk64_LTX__mcrypt_decrypt
#define _mcrypt_get_size safer_sk64_LTX__mcrypt_get_size
#define _mcrypt_get_block_size safer_sk64_LTX__mcrypt_get_block_size
#define _is_block_algorithm safer_sk64_LTX__is_block_algorithm
#define _mcrypt_get_key_size safer_sk64_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes safer_sk64_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name safer_sk64_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test safer_sk64_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version safer_sk64_LTX__mcrypt_algorithm_version
/******************* Constants ************************************************/
#define TAB_LEN 256
static int _safer64_init = 0;
/******************* Assertions ***********************************************/
/******************* Macros ***************************************************/
#define ROL(x, n) ((unsigned char)((unsigned int)(x) << (n)\
|(unsigned int)((x) & 0xFF) >> (8 - (n))))
#define EXP(x) exp_tab64[(x) & 0xFF]
#define LOG(x) log_tab64[(x) & 0xFF]
#define PHT(x, y) { y += x; x += y; }
#define IPHT(x, y) { x -= y; y -= x; }
/******************* Types ****************************************************/
static unsigned char exp_tab64[TAB_LEN];
static unsigned char log_tab64[TAB_LEN];
/******************* Module Data **********************************************/
/******************* Functions ************************************************/
/******************************************************************************/
static void _mcrypt_Safer_Init_Module(void)
{
unsigned int i, exp;
exp = 1;
for (i = 0; i < TAB_LEN; i++) {
exp_tab64[i] = (unsigned char) (exp & 0xFF);
log_tab64[exp_tab64[i]] = (unsigned char) i;
exp = exp * 45 % 257;
}
} /* Safer_Init_Module */
/******************************************************************************/
WIN32DLL_DEFINE
int _mcrypt_set_key(safer_key_t * key, safer_block_t * userkey,
int len)
{
unsigned int i, j;
unsigned char ka[SAFER_BLOCK_LEN + 1];
unsigned char kb[SAFER_BLOCK_LEN + 1];
int nof_rounds = SAFER_SK64_DEFAULT_NOF_ROUNDS;
int strengthened = 1;
if (_safer64_init == 0) {
_mcrypt_Safer_Init_Module();
_safer64_init = 1;
}
if (SAFER_MAX_NOF_ROUNDS < nof_rounds)
nof_rounds = SAFER_MAX_NOF_ROUNDS;
*key++ = (unsigned char) nof_rounds;
ka[SAFER_BLOCK_LEN] = 0;
kb[SAFER_BLOCK_LEN] = 0;
for (j = 0; j < SAFER_BLOCK_LEN; j++) {
ka[SAFER_BLOCK_LEN] ^= ka[j] = ROL(userkey[j], 5);
kb[SAFER_BLOCK_LEN] ^= kb[j] = *key++ = userkey[j];
}
for (i = 1; i <= nof_rounds; i++) {
for (j = 0; j < SAFER_BLOCK_LEN + 1; j++) {
ka[j] = ROL(ka[j], 6);
kb[j] = ROL(kb[j], 6);
}
for (j = 0; j < SAFER_BLOCK_LEN; j++)
if (strengthened)
*key++ =
(ka
[(j + 2 * i - 1) %
(SAFER_BLOCK_LEN + 1)] +
exp_tab64[exp_tab64[18 * i + j + 1]]) &
0xFF;
else
*key++ =
(ka[j] +
exp_tab64[exp_tab64[18 * i + j + 1]]) &
0xFF;
for (j = 0; j < SAFER_BLOCK_LEN; j++)
if (strengthened)
*key++ =
(kb
[(j + 2 * i) %
(SAFER_BLOCK_LEN + 1)] +
exp_tab64[exp_tab64[18 * i + j + 10]]) &
0xFF;
else
*key++ =
(kb[j] +
exp_tab64[exp_tab64[18 * i + j + 10]]) &
0xFF;
}
for (j = 0; j < SAFER_BLOCK_LEN + 1; j++)
ka[j] = kb[j] = 0;
return 0;
} /* Safer_Expand_Userkey */
/******************************************************************************/
WIN32DLL_DEFINE
void _mcrypt_encrypt(const safer_key_t * key, safer_block_t * block_in)
{
unsigned char a, b, c, d, e, f, g, h, t;
unsigned int round;
a = block_in[0];
b = block_in[1];
c = block_in[2];
d = block_in[3];
e = block_in[4];
f = block_in[5];
g = block_in[6];
h = block_in[7];
if (SAFER_MAX_NOF_ROUNDS < (round = *key))
round = SAFER_MAX_NOF_ROUNDS;
while (round--) {
a ^= *++key;
b += *++key;
c += *++key;
d ^= *++key;
e ^= *++key;
f += *++key;
g += *++key;
h ^= *++key;
a = EXP(a) + *++key;
b = LOG(b) ^ *++key;
c = LOG(c) ^ *++key;
d = EXP(d) + *++key;
e = EXP(e) + *++key;
f = LOG(f) ^ *++key;
g = LOG(g) ^ *++key;
h = EXP(h) + *++key;
PHT(a, b);
PHT(c, d);
PHT(e, f);
PHT(g, h);
PHT(a, c);
PHT(e, g);
PHT(b, d);
PHT(f, h);
PHT(a, e);
PHT(b, f);
PHT(c, g);
PHT(d, h);
t = b;
b = e;
e = c;
c = t;
t = d;
d = f;
f = g;
g = t;
}
a ^= *++key;
b += *++key;
c += *++key;
d ^= *++key;
e ^= *++key;
f += *++key;
g += *++key;
h ^= *++key;
block_in[0] = a & 0xFF;
block_in[1] = b & 0xFF;
block_in[2] = c & 0xFF;
block_in[3] = d & 0xFF;
block_in[4] = e & 0xFF;
block_in[5] = f & 0xFF;
block_in[6] = g & 0xFF;
block_in[7] = h & 0xFF;
} /* Safer_Encrypt_Block */
/******************************************************************************/
WIN32DLL_DEFINE
void _mcrypt_decrypt(const safer_key_t * key, safer_block_t * block_in)
{
safer_block_t a, b, c, d, e, f, g, h, t;
unsigned int round;
a = block_in[0];
b = block_in[1];
c = block_in[2];
d = block_in[3];
e = block_in[4];
f = block_in[5];
g = block_in[6];
h = block_in[7];
if (SAFER_MAX_NOF_ROUNDS < (round = *key))
round = SAFER_MAX_NOF_ROUNDS;
key += SAFER_BLOCK_LEN * (1 + 2 * round);
h ^= *key;
g -= *--key;
f -= *--key;
e ^= *--key;
d ^= *--key;
c -= *--key;
b -= *--key;
a ^= *--key;
while (round--) {
t = e;
e = b;
b = c;
c = t;
t = f;
f = d;
d = g;
g = t;
IPHT(a, e);
IPHT(b, f);
IPHT(c, g);
IPHT(d, h);
IPHT(a, c);
IPHT(e, g);
IPHT(b, d);
IPHT(f, h);
IPHT(a, b);
IPHT(c, d);
IPHT(e, f);
IPHT(g, h);
h -= *--key;
g ^= *--key;
f ^= *--key;
e -= *--key;
d -= *--key;
c ^= *--key;
b ^= *--key;
a -= *--key;
h = LOG(h) ^ *--key;
g = EXP(g) - *--key;
f = EXP(f) - *--key;
e = LOG(e) ^ *--key;
d = LOG(d) ^ *--key;
c = EXP(c) - *--key;
b = EXP(b) - *--key;
a = LOG(a) ^ *--key;
}
block_in[0] = a & 0xFF;
block_in[1] = b & 0xFF;
block_in[2] = c & 0xFF;
block_in[3] = d & 0xFF;
block_in[4] = e & 0xFF;
block_in[5] = f & 0xFF;
block_in[6] = g & 0xFF;
block_in[7] = h & 0xFF;
} /* Safer_Decrypt_Block */
/******************************************************************************/
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS));
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 8;
}
static const int key_sizes[] = { 8 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "SAFER-SK64";
}
#define CIPHER "e490eebffd908f34"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL) {
free(keyword);
return -1;
}
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,687 @@
/* This is an independent implementation of the encryption algorithm: */
/* */
/* SAFER+ by Cylink */
/* */
/* which is a candidate algorithm in the Advanced Encryption Standard */
/* programme of the US National Institute of Standards and Technology. */
/* */
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
/* */
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
/* $Id: saferplus.c,v 1.13 2003/01/19 17:48:27 nmav Exp $ */
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* Timing data for SAFER+ (safer.c)
Core timing without I/O endian conversion:
128 bit key:
Key Setup: 4278 cycles
Encrypt: 1722 cycles = 14.9 mbits/sec
Decrypt: 1709 cycles = 15.0 mbits/sec
Mean: 1716 cycles = 14.9 mbits/sec
192 bit key:
Key Setup: 7426 cycles
Encrypt: 2555 cycles = 10.0 mbits/sec
Decrypt: 2530 cycles = 10.1 mbits/sec
Mean: 2543 cycles = 10.1 mbits/sec
256 bit key:
Key Setup: 11313 cycles
Encrypt: 3391 cycles = 7.5 mbits/sec
Decrypt: 3338 cycles = 7.7 mbits/sec
Mean: 3365 cycles = 7.6 mbits/sec
Full timing with I/O endian conversion:
128 bit key:
Key Setup: 3977 cycles
Encrypt: 1751 cycles = 14.6 mbits/sec
Decrypt: 1734 cycles = 14.8 mbits/sec
Mean: 1743 cycles = 14.7 mbits/sec
192 bit key:
Key Setup: 6490 cycles
Encrypt: 2574 cycles = 9.9 mbits/sec
Decrypt: 2549 cycles = 10.0 mbits/sec
Mean: 2562 cycles = 10.0 mbits/sec
256 bit key:
Key Setup: 9487 cycles
Encrypt: 3412 cycles = 7.5 mbits/sec
Decrypt: 3372 cycles = 7.6 mbits/sec
Mean: 3392 cycles = 7.5 mbits/sec
*/
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "saferplus.h"
#include <stdlib.h>
#define _mcrypt_set_key saferplus_LTX__mcrypt_set_key
#define _mcrypt_encrypt saferplus_LTX__mcrypt_encrypt
#define _mcrypt_decrypt saferplus_LTX__mcrypt_decrypt
#define _mcrypt_get_size saferplus_LTX__mcrypt_get_size
#define _mcrypt_get_block_size saferplus_LTX__mcrypt_get_block_size
#define _is_block_algorithm saferplus_LTX__is_block_algorithm
#define _mcrypt_get_key_size saferplus_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes saferplus_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name saferplus_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test saferplus_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version saferplus_LTX__mcrypt_algorithm_version
byte safer_expf[256] =
{ 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207,
63,
8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114,
247,
64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141,
177,
255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145,
100, 131,
241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132,
29, 20,
129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28,
232, 160,
4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57,
252,
32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250,
199, 217,
0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50,
194,
249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66,
143, 10,
193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14,
116, 80,
2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157,
126,
16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228,
237,
128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229,
25, 97,
253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33,
200, 5,
225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58,
40
};
byte safer_logf[512] = {
128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173,
248,
192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168,
130,
112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1,
172, 37,
201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50,
15,
32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225,
115, 198,
175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139,
213, 84,
121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147,
131, 188,
189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205,
191, 217,
208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107,
158,
210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118,
42,
95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7,
219,
164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4,
29,
41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154,
193, 14,
122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242,
108, 104,
109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207,
229, 66,
184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224,
137, 48,
128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173,
248,
192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168,
130,
112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1,
172, 37,
201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50,
15,
32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225,
115, 198,
175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139,
213, 84,
121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147,
131, 188,
189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205,
191, 217,
208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107,
158,
210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118,
42,
95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7,
219,
164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4,
29,
41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154,
193, 14,
122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242,
108, 104,
109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207,
229, 66,
184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224,
137, 48
};
/* byte l_key[33 * 16]; */
/* word32 k_bytes; */
WIN32DLL_DEFINE
int _mcrypt_set_key(SPI * sp_key, const word32 * in_key,
const word32 key_len)
{
word32 wlk[9]; /* 36 bytes */
byte *lk = (void*)wlk, by; /* lk should have 33 bytes */
word32 i, j, k, l, m, *lkp = wlk;
memset( wlk, 0, sizeof(wlk));
for (i = 0; i < key_len / sizeof(word32); ++i) {
lkp[i] = in_key[(key_len / sizeof(word32)) - i - 1];
}
sp_key->k_bytes = key_len;
lk[sp_key->k_bytes] = 0;
for (i = 0; i < sp_key->k_bytes; ++i) {
lk[sp_key->k_bytes] ^= lk[i];
sp_key->l_key[i] = lk[i];
}
for (i = 0; i < sp_key->k_bytes; ++i) {
for (j = 0; j <= sp_key->k_bytes; ++j) {
by = lk[j];
lk[j] = by << 3 | by >> 5;
}
k = 17 * i + 35;
l = 16 * i + 16;
m = i + 1;
if (i < 16) {
for (j = 0; j < 16; ++j) {
sp_key->l_key[l + j] =
lk[m] +
safer_expf[safer_expf[(k + j) & 255]];
m = (m == sp_key->k_bytes ? 0 : m + 1);
}
} else {
for (j = 0; j < 16; ++j) {
sp_key->l_key[l + j] =
lk[m] + safer_expf[(k + j) & 255];
m = (m == sp_key->k_bytes ? 0 : m + 1);
}
}
}
return 0;
}
void do_fr(byte x[16], byte * kp)
{
byte t;
x[0] = safer_expf[x[0] ^ kp[0]] + kp[16];
x[1] = safer_logf[x[1] + kp[1]] ^ kp[17];
x[2] = safer_logf[x[2] + kp[2]] ^ kp[18];
x[3] = safer_expf[x[3] ^ kp[3]] + kp[19];
x[4] = safer_expf[x[4] ^ kp[4]] + kp[20];
x[5] = safer_logf[x[5] + kp[5]] ^ kp[21];
x[6] = safer_logf[x[6] + kp[6]] ^ kp[22];
x[7] = safer_expf[x[7] ^ kp[7]] + kp[23];
x[8] = safer_expf[x[8] ^ kp[8]] + kp[24];
x[9] = safer_logf[x[9] + kp[9]] ^ kp[25];
x[10] = safer_logf[x[10] + kp[10]] ^ kp[26];
x[11] = safer_expf[x[11] ^ kp[11]] + kp[27];
x[12] = safer_expf[x[12] ^ kp[12]] + kp[28];
x[13] = safer_logf[x[13] + kp[13]] ^ kp[29];
x[14] = safer_logf[x[14] + kp[14]] ^ kp[30];
x[15] = safer_expf[x[15] ^ kp[15]] + kp[31];
x[1] += x[0];
x[0] += x[1];
x[3] += x[2];
x[2] += x[3];
x[5] += x[4];
x[4] += x[5];
x[7] += x[6];
x[6] += x[7];
x[9] += x[8];
x[8] += x[9];
x[11] += x[10];
x[10] += x[11];
x[13] += x[12];
x[12] += x[13];
x[15] += x[14];
x[14] += x[15];
x[7] += x[0];
x[0] += x[7];
x[1] += x[2];
x[2] += x[1];
x[3] += x[4];
x[4] += x[3];
x[5] += x[6];
x[6] += x[5];
x[11] += x[8];
x[8] += x[11];
x[9] += x[10];
x[10] += x[9];
x[15] += x[12];
x[12] += x[15];
x[13] += x[14];
x[14] += x[13];
x[3] += x[0];
x[0] += x[3];
x[15] += x[2];
x[2] += x[15];
x[7] += x[4];
x[4] += x[7];
x[1] += x[6];
x[6] += x[1];
x[5] += x[8];
x[8] += x[5];
x[13] += x[10];
x[10] += x[13];
x[11] += x[12];
x[12] += x[11];
x[9] += x[14];
x[14] += x[9];
x[13] += x[0];
x[0] += x[13];
x[5] += x[2];
x[2] += x[5];
x[9] += x[4];
x[4] += x[9];
x[11] += x[6];
x[6] += x[11];
x[15] += x[8];
x[8] += x[15];
x[1] += x[10];
x[10] += x[1];
x[3] += x[12];
x[12] += x[3];
x[7] += x[14];
x[14] += x[7];
t = x[0];
x[0] = x[14];
x[14] = x[12];
x[12] = x[10];
x[10] = x[2];
x[2] = x[8];
x[8] = x[4];
x[4] = t;
t = x[1];
x[1] = x[7];
x[7] = x[11];
x[11] = x[5];
x[5] = x[13];
x[13] = t;
t = x[15];
x[15] = x[3];
x[3] = t;
}
void do_ir(byte x[16], byte * kp)
{
byte t;
t = x[3];
x[3] = x[15];
x[15] = t;
t = x[13];
x[13] = x[5];
x[5] = x[11];
x[11] = x[7];
x[7] = x[1];
x[1] = t;
t = x[4];
x[4] = x[8];
x[8] = x[2];
x[2] = x[10];
x[10] = x[12];
x[12] = x[14];
x[14] = x[0];
x[0] = t;
x[14] -= x[7];
x[7] -= x[14];
x[12] -= x[3];
x[3] -= x[12];
x[10] -= x[1];
x[1] -= x[10];
x[8] -= x[15];
x[15] -= x[8];
x[6] -= x[11];
x[11] -= x[6];
x[4] -= x[9];
x[9] -= x[4];
x[2] -= x[5];
x[5] -= x[2];
x[0] -= x[13];
x[13] -= x[0];
x[14] -= x[9];
x[9] -= x[14];
x[12] -= x[11];
x[11] -= x[12];
x[10] -= x[13];
x[13] -= x[10];
x[8] -= x[5];
x[5] -= x[8];
x[6] -= x[1];
x[1] -= x[6];
x[4] -= x[7];
x[7] -= x[4];
x[2] -= x[15];
x[15] -= x[2];
x[0] -= x[3];
x[3] -= x[0];
x[14] -= x[13];
x[13] -= x[14];
x[12] -= x[15];
x[15] -= x[12];
x[10] -= x[9];
x[9] -= x[10];
x[8] -= x[11];
x[11] -= x[8];
x[6] -= x[5];
x[5] -= x[6];
x[4] -= x[3];
x[3] -= x[4];
x[2] -= x[1];
x[1] -= x[2];
x[0] -= x[7];
x[7] -= x[0];
x[14] -= x[15];
x[15] -= x[14];
x[12] -= x[13];
x[13] -= x[12];
x[10] -= x[11];
x[11] -= x[10];
x[8] -= x[9];
x[9] -= x[8];
x[6] -= x[7];
x[7] -= x[6];
x[4] -= x[5];
x[5] -= x[4];
x[2] -= x[3];
x[3] -= x[2];
x[0] -= x[1];
x[1] -= x[0];
x[0] = safer_logf[x[0] - kp[16] + 256] ^ kp[0];
x[1] = safer_expf[x[1] ^ kp[17]] - kp[1];
x[2] = safer_expf[x[2] ^ kp[18]] - kp[2];
x[3] = safer_logf[x[3] - kp[19] + 256] ^ kp[3];
x[4] = safer_logf[x[4] - kp[20] + 256] ^ kp[4];
x[5] = safer_expf[x[5] ^ kp[21]] - kp[5];
x[6] = safer_expf[x[6] ^ kp[22]] - kp[6];
x[7] = safer_logf[x[7] - kp[23] + 256] ^ kp[7];
x[8] = safer_logf[x[8] - kp[24] + 256] ^ kp[8];
x[9] = safer_expf[x[9] ^ kp[25]] - kp[9];
x[10] = safer_expf[x[10] ^ kp[26]] - kp[10];
x[11] = safer_logf[x[11] - kp[27] + 256] ^ kp[11];
x[12] = safer_logf[x[12] - kp[28] + 256] ^ kp[12];
x[13] = safer_expf[x[13] ^ kp[29]] - kp[13];
x[14] = safer_expf[x[14] ^ kp[30]] - kp[14];
x[15] = safer_logf[x[15] - kp[31] + 256] ^ kp[15];
}
WIN32DLL_DEFINE void _mcrypt_encrypt(SPI * spi, word32 * _blk)
{
byte *kp;
word32 __blk[16];
byte *blk = (void *) __blk;
__blk[3] = _blk[0];
__blk[2] = _blk[1];
__blk[1] = _blk[2];
__blk[0] = _blk[3];
do_fr(blk, spi->l_key);
do_fr(blk, spi->l_key + 32);
do_fr(blk, spi->l_key + 64);
do_fr(blk, spi->l_key + 96);
do_fr(blk, spi->l_key + 128);
do_fr(blk, spi->l_key + 160);
do_fr(blk, spi->l_key + 192);
do_fr(blk, spi->l_key + 224);
if (spi->k_bytes > 16) {
do_fr(blk, spi->l_key + 256);
do_fr(blk, spi->l_key + 288);
do_fr(blk, spi->l_key + 320);
do_fr(blk, spi->l_key + 352);
}
if (spi->k_bytes > 24) {
do_fr(blk, spi->l_key + 384);
do_fr(blk, spi->l_key + 416);
do_fr(blk, spi->l_key + 448);
do_fr(blk, spi->l_key + 480);
}
kp = spi->l_key + 16 * spi->k_bytes;
blk[0] ^= kp[0];
blk[1] += kp[1];
blk[2] += kp[2];
blk[3] ^= kp[3];
blk[4] ^= kp[4];
blk[5] += kp[5];
blk[6] += kp[6];
blk[7] ^= kp[7];
blk[8] ^= kp[8];
blk[9] += kp[9];
blk[10] += kp[10];
blk[11] ^= kp[11];
blk[12] ^= kp[12];
blk[13] += kp[13];
blk[14] += kp[14];
blk[15] ^= kp[15];
_blk[3] = (__blk[0]);
_blk[2] = (__blk[1]);
_blk[1] = (__blk[2]);
_blk[0] = (__blk[3]);
}
WIN32DLL_DEFINE void _mcrypt_decrypt(SPI * spi, word32 * _blk)
{
byte *kp;
word32 __blk[16];
byte *blk = (void *) __blk;
__blk[3] = _blk[0];
__blk[2] = _blk[1];
__blk[1] = _blk[2];
__blk[0] = _blk[3];
kp = spi->l_key + 16 * spi->k_bytes;
blk[0] ^= kp[0];
blk[1] -= kp[1];
blk[2] -= kp[2];
blk[3] ^= kp[3];
blk[4] ^= kp[4];
blk[5] -= kp[5];
blk[6] -= kp[6];
blk[7] ^= kp[7];
blk[8] ^= kp[8];
blk[9] -= kp[9];
blk[10] -= kp[10];
blk[11] ^= kp[11];
blk[12] ^= kp[12];
blk[13] -= kp[13];
blk[14] -= kp[14];
blk[15] ^= kp[15];
if (spi->k_bytes > 24) {
do_ir(blk, spi->l_key + 480);
do_ir(blk, spi->l_key + 448);
do_ir(blk, spi->l_key + 416);
do_ir(blk, spi->l_key + 384);
}
if (spi->k_bytes > 16) {
do_ir(blk, spi->l_key + 352);
do_ir(blk, spi->l_key + 320);
do_ir(blk, spi->l_key + 288);
do_ir(blk, spi->l_key + 256);
}
do_ir(blk, spi->l_key + 224);
do_ir(blk, spi->l_key + 192);
do_ir(blk, spi->l_key + 160);
do_ir(blk, spi->l_key + 128);
do_ir(blk, spi->l_key + 96);
do_ir(blk, spi->l_key + 64);
do_ir(blk, spi->l_key + 32);
do_ir(blk, spi->l_key);
_blk[3] = (__blk[0]);
_blk[2] = (__blk[1]);
_blk[1] = (__blk[2]);
_blk[0] = (__blk[3]);
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(SPI);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 16;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 16,24,32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
{
return "Safer+";
}
#define CIPHER "97fa76704bf6b578549f65c6f75b228b"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,5 @@
typedef struct saferplus_instance {
byte l_key[33*16];
word32 k_bytes;
} SPI;
@@ -0,0 +1,967 @@
/* This is an independent implementation of the encryption algorithm:
*
* Serpent by Ross Anderson, Eli Biham and Lars Knudsen
*
* which is a candidate algorithm in the Advanced Encryption Standard
* programme of the US National Institute of Standards and Technology
*
* Copyright in this implementation is held by Dr B R Gladman but I
* hereby give permission for its free direct or derivative use subject
* to acknowledgment of its origin and compliance with any conditions
* that the originators of the algorithm place on its exploitation.
*
* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/*
Algorithm serpent (serpent.c)
128 bit key:
Key Setup: 2366 cycles
Encrypt: 954 cycles = 26.8 mbits/sec
Decrypt: 907 cycles = 28.2 mbits/sec
Mean: 931 cycles = 27.5 mbits/sec
192 bit key:
Key Setup: 2382 cycles
Encrypt: 967 cycles = 26.5 mbits/sec
Decrypt: 915 cycles = 28.0 mbits/sec
Mean: 941 cycles = 27.2 mbits/sec
256 bit key:
Key Setup: 2360 cycles
Encrypt: 967 cycles = 26.5 mbits/sec
Decrypt: 915 cycles = 28.0 mbits/sec
Mean: 941 cycles = 27.2 mbits/sec
*/
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "serpent.h"
#define _mcrypt_set_key serpent_LTX__mcrypt_set_key
#define _mcrypt_encrypt serpent_LTX__mcrypt_encrypt
#define _mcrypt_decrypt serpent_LTX__mcrypt_decrypt
#define _mcrypt_get_size serpent_LTX__mcrypt_get_size
#define _mcrypt_get_block_size serpent_LTX__mcrypt_get_block_size
#define _is_block_algorithm serpent_LTX__is_block_algorithm
#define _mcrypt_get_key_size serpent_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes serpent_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name serpent_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test serpent_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version serpent_LTX__mcrypt_algorithm_version
/* Partially optimised Serpent S Box boolean functions derived */
/* using a recursive descent analyser but without a full search */
/* of all subtrees. This set of S boxes is the result of work */
/* by Sam Simpson and Brian Gladman using the spare time on a */
/* cluster of high capacity servers to search for S boxes with */
/* this customised search engine. */
/* */
/* Copyright: Dr B. R Gladman (gladman@seven77.demon.co.uk) */
/* and Sam Simpson (s.simpson@mia.co.uk) */
/* 17th December 1998 */
/* */
/* We hereby give permission for information in this file to be */
/* used freely subject only to acknowledgement of its origin */
/* 15 terms */
#define sb0(a,b,c,d,e,f,g,h) \
t1 = a ^ d; \
t2 = a & d; \
t3 = c ^ t1; \
t6 = b & t1; \
t4 = b ^ t3; \
t10 = ~t3; \
h = t2 ^ t4; \
t7 = a ^ t6; \
t14 = ~t7; \
t8 = c | t7; \
t11 = t3 ^ t7; \
g = t4 ^ t8; \
t12 = h & t11; \
f = t10 ^ t12; \
e = t12 ^ t14
/* 15 terms */
#define ib0(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ b; \
t3 = t1 | t2; \
t4 = d ^ t3; \
t7 = d & t2; \
t5 = c ^ t4; \
t8 = t1 ^ t7; \
g = t2 ^ t5; \
t11 = a & t4; \
t9 = g & t8; \
t14 = t5 ^ t8; \
f = t4 ^ t9; \
t12 = t5 | f; \
h = t11 ^ t12; \
e = h ^ t14
/* 14 terms! */
#define sb1(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = b ^ t1; \
t3 = a | t2; \
t4 = d | t2; \
t5 = c ^ t3; \
g = d ^ t5; \
t7 = b ^ t4; \
t8 = t2 ^ g; \
t9 = t5 & t7; \
h = t8 ^ t9; \
t11 = t5 ^ t7; \
f = h ^ t11; \
t13 = t8 & t11; \
e = t5 ^ t13
/* 17 terms */
#define ib1(a,b,c,d,e,f,g,h) \
t1 = a ^ d; \
t2 = a & b; \
t3 = b ^ c; \
t4 = a ^ t3; \
t5 = b | d; \
t7 = c | t1; \
h = t4 ^ t5; \
t8 = b ^ t7; \
t11 = ~t2; \
t9 = t4 & t8; \
f = t1 ^ t9; \
t13 = t9 ^ t11; \
t12 = h & f; \
g = t12 ^ t13; \
t15 = a & d; \
t16 = c ^ t13; \
e = t15 ^ t16
/* 16 terms */
#define sb2(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = b ^ d; \
t3 = c & t1; \
t13 = d | t1; \
e = t2 ^ t3; \
t5 = c ^ t1; \
t6 = c ^ e; \
t7 = b & t6; \
t10 = e | t5; \
h = t5 ^ t7; \
t9 = d | t7; \
t11 = t9 & t10; \
t14 = t2 ^ h; \
g = a ^ t11; \
t15 = g ^ t13; \
f = t14 ^ t15
/* 16 terms */
#define ib2(a,b,c,d,e,f,g,h) \
t1 = b ^ d; \
t2 = ~t1; \
t3 = a ^ c; \
t4 = c ^ t1; \
t7 = a | t2; \
t5 = b & t4; \
t8 = d ^ t7; \
t11 = ~t4; \
e = t3 ^ t5; \
t9 = t3 | t8; \
t14 = d & t11; \
h = t1 ^ t9; \
t12 = e | h; \
f = t11 ^ t12; \
t15 = t3 ^ t12; \
g = t14 ^ t15
/* 17 terms */
#define sb3(a,b,c,d,e,f,g,h) \
t1 = a ^ c; \
t2 = d ^ t1; \
t3 = a & t2; \
t4 = d ^ t3; \
t5 = b & t4; \
g = t2 ^ t5; \
t7 = a | g; \
t8 = b | d; \
t11 = a | d; \
t9 = t4 & t7; \
f = t8 ^ t9; \
t12 = b ^ t11; \
t13 = g ^ t9; \
t15 = t3 ^ t8; \
h = t12 ^ t13; \
t16 = c & t15; \
e = t12 ^ t16
/* 16 term solution that performs less well than 17 term one
in my environment (PPro/PII)
#define sb3(a,b,c,d,e,f,g,h) \
t1 = a ^ b; \
t2 = a & c; \
t3 = a | d; \
t4 = c ^ d; \
t5 = t1 & t3; \
t6 = t2 | t5; \
g = t4 ^ t6; \
t8 = b ^ t3; \
t9 = t6 ^ t8; \
t10 = t4 & t9; \
e = t1 ^ t10; \
t12 = g & e; \
f = t9 ^ t12; \
t14 = b | d; \
t15 = t4 ^ t12; \
h = t14 ^ t15
*/
/* 17 terms */
#define ib3(a,b,c,d,e,f,g,h) \
t1 = b ^ c; \
t2 = b | c; \
t3 = a ^ c; \
t7 = a ^ d; \
t4 = t2 ^ t3; \
t5 = d | t4; \
t9 = t2 ^ t7; \
e = t1 ^ t5; \
t8 = t1 | t5; \
t11 = a & t4; \
g = t8 ^ t9; \
t12 = e | t9; \
f = t11 ^ t12; \
t14 = a & g; \
t15 = t2 ^ t14; \
t16 = e & t15; \
h = t4 ^ t16
/* 15 terms */
#define sb4(a,b,c,d,e,f,g,h) \
t1 = a ^ d; \
t2 = d & t1; \
t3 = c ^ t2; \
t4 = b | t3; \
h = t1 ^ t4; \
t6 = ~b; \
t7 = t1 | t6; \
e = t3 ^ t7; \
t9 = a & e; \
t10 = t1 ^ t6; \
t11 = t4 & t10; \
g = t9 ^ t11; \
t13 = a ^ t3; \
t14 = t10 & g; \
f = t13 ^ t14
/* 17 terms */
#define ib4(a,b,c,d,e,f,g,h) \
t1 = c ^ d; \
t2 = c | d; \
t3 = b ^ t2; \
t4 = a & t3; \
f = t1 ^ t4; \
t6 = a ^ d; \
t7 = b | d; \
t8 = t6 & t7; \
h = t3 ^ t8; \
t10 = ~a; \
t11 = c ^ h; \
t12 = t10 | t11;\
e = t3 ^ t12; \
t14 = c | t4; \
t15 = t7 ^ t14; \
t16 = h | t10; \
g = t15 ^ t16
/* 16 terms */
#define sb5(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ b; \
t3 = a ^ d; \
t4 = c ^ t1; \
t5 = t2 | t3; \
e = t4 ^ t5; \
t7 = d & e; \
t8 = t2 ^ e; \
t10 = t1 | e; \
f = t7 ^ t8; \
t11 = t2 | t7; \
t12 = t3 ^ t10; \
t14 = b ^ t7; \
g = t11 ^ t12; \
t15 = f & t12; \
h = t14 ^ t15
/* 16 terms */
#define ib5(a,b,c,d,e,f,g,h) \
t1 = ~c; \
t2 = b & t1; \
t3 = d ^ t2; \
t4 = a & t3; \
t5 = b ^ t1; \
h = t4 ^ t5; \
t7 = b | h; \
t8 = a & t7; \
f = t3 ^ t8; \
t10 = a | d; \
t11 = t1 ^ t7; \
e = t10 ^ t11; \
t13 = a ^ c; \
t14 = b & t10; \
t15 = t4 | t13; \
g = t14 ^ t15
/* 15 terms */
#define sb6(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ d; \
t3 = b ^ t2; \
t4 = t1 | t2; \
t5 = c ^ t4; \
f = b ^ t5; \
t13 = ~t5; \
t7 = t2 | f; \
t8 = d ^ t7; \
t9 = t5 & t8; \
g = t3 ^ t9; \
t11 = t5 ^ t8; \
e = g ^ t11; \
t14 = t3 & t11; \
h = t13 ^ t14
/* 15 terms */
#define ib6(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ b; \
t3 = c ^ t2; \
t4 = c | t1; \
t5 = d ^ t4; \
t13 = d & t1; \
f = t3 ^ t5; \
t7 = t3 & t5; \
t8 = t2 ^ t7; \
t9 = b | t8; \
h = t5 ^ t9; \
t11 = b | h; \
e = t8 ^ t11; \
t14 = t3 ^ t11; \
g = t13 ^ t14
/* 17 terms */
#define sb7(a,b,c,d,e,f,g,h) \
t1 = ~c; \
t2 = b ^ c; \
t3 = b | t1; \
t4 = d ^ t3; \
t5 = a & t4; \
t7 = a ^ d; \
h = t2 ^ t5; \
t8 = b ^ t5; \
t9 = t2 | t8; \
t11 = d & t3; \
f = t7 ^ t9; \
t12 = t5 ^ f; \
t15 = t1 | t4; \
t13 = h & t12; \
g = t11 ^ t13; \
t16 = t12 ^ g; \
e = t15 ^ t16
/* 17 terms */
#define ib7(a,b,c,d,e,f,g,h) \
t1 = a & b; \
t2 = a | b; \
t3 = c | t1; \
t4 = d & t2; \
h = t3 ^ t4; \
t6 = ~d; \
t7 = b ^ t4; \
t8 = h ^ t6; \
t11 = c ^ t7; \
t9 = t7 | t8; \
f = a ^ t9; \
t12 = d | f; \
e = t11 ^ t12; \
t14 = a & h; \
t15 = t3 ^ f; \
t16 = e ^ t14; \
g = t15 ^ t16
#define k_xor(r,a,b,c,d) \
a ^= spkey->l_key[4 * r + 8]; \
b ^= spkey->l_key[4 * r + 9]; \
c ^= spkey->l_key[4 * r + 10]; \
d ^= spkey->l_key[4 * r + 11]
#define k_set(r,a,b,c,d) \
a = spkey->l_key[4 * r + 8]; \
b = spkey->l_key[4 * r + 9]; \
c = spkey->l_key[4 * r + 10]; \
d = spkey->l_key[4 * r + 11]
#define k_get(r,a,b,c,d) \
spkey->l_key[4 * r + 8] = a; \
spkey->l_key[4 * r + 9] = b; \
spkey->l_key[4 * r + 10] = c; \
spkey->l_key[4 * r + 11] = d
/* the linear transformation and its inverse */
#define rot(a,b,c,d) \
a = rotl32(a, 13); \
c = rotl32(c, 3); \
d ^= c ^ (a << 3); \
b ^= a ^ c; \
d = rotl32(d, 7); \
b = rotl32(b, 1); \
a ^= b ^ d; \
c ^= d ^ (b << 7); \
a = rotl32(a, 5); \
c = rotl32(c, 22)
#define irot(a,b,c,d) \
c = rotr32(c, 22); \
a = rotr32(a, 5); \
c ^= d ^ (b << 7); \
a ^= b ^ d; \
d = rotr32(d, 7); \
b = rotr32(b, 1); \
d ^= c ^ (a << 3); \
b ^= a ^ c; \
c = rotr32(c, 3); \
a = rotr32(a, 13)
/* initialise the key schedule from the user supplied key */
WIN32DLL_DEFINE
int _mcrypt_set_key(SERPENT_KEY * spkey, const word32 * in_key,
word32 key_len)
{
word32 i, lk, a, b, c, d, e, f, g, h;
word32 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
t15, t16;
key_len *= 8;
if (key_len > 256)
return -1;
i = 0;
lk = (key_len + 31) / 32;
while (i < lk) {
#ifdef WORDS_BIGENDIAN
spkey->l_key[i] = byteswap32(in_key[i]);
#else
spkey->l_key[i] = (in_key[i]);
#endif
i++;
}
if (key_len < 256) {
while (i < 8)
spkey->l_key[i++] = 0;
i = key_len / 32;
lk = 1 << key_len % 32;
spkey->l_key[i] = (spkey->l_key[i] & (lk - 1)) | lk;
}
for (i = 0; i < 132; ++i) {
lk = spkey->l_key[i] ^ spkey->l_key[i +
3] ^ spkey->l_key[i +
5] ^
spkey->l_key[i + 7] ^ 0x9e3779b9 ^ i;
spkey->l_key[i + 8] = (lk << 11) | (lk >> 21);
}
k_set(0, a, b, c, d);
sb3(a, b, c, d, e, f, g, h);
k_get(0, e, f, g, h);
k_set(1, a, b, c, d);
sb2(a, b, c, d, e, f, g, h);
k_get(1, e, f, g, h);
k_set(2, a, b, c, d);
sb1(a, b, c, d, e, f, g, h);
k_get(2, e, f, g, h);
k_set(3, a, b, c, d);
sb0(a, b, c, d, e, f, g, h);
k_get(3, e, f, g, h);
k_set(4, a, b, c, d);
sb7(a, b, c, d, e, f, g, h);
k_get(4, e, f, g, h);
k_set(5, a, b, c, d);
sb6(a, b, c, d, e, f, g, h);
k_get(5, e, f, g, h);
k_set(6, a, b, c, d);
sb5(a, b, c, d, e, f, g, h);
k_get(6, e, f, g, h);
k_set(7, a, b, c, d);
sb4(a, b, c, d, e, f, g, h);
k_get(7, e, f, g, h);
k_set(8, a, b, c, d);
sb3(a, b, c, d, e, f, g, h);
k_get(8, e, f, g, h);
k_set(9, a, b, c, d);
sb2(a, b, c, d, e, f, g, h);
k_get(9, e, f, g, h);
k_set(10, a, b, c, d);
sb1(a, b, c, d, e, f, g, h);
k_get(10, e, f, g, h);
k_set(11, a, b, c, d);
sb0(a, b, c, d, e, f, g, h);
k_get(11, e, f, g, h);
k_set(12, a, b, c, d);
sb7(a, b, c, d, e, f, g, h);
k_get(12, e, f, g, h);
k_set(13, a, b, c, d);
sb6(a, b, c, d, e, f, g, h);
k_get(13, e, f, g, h);
k_set(14, a, b, c, d);
sb5(a, b, c, d, e, f, g, h);
k_get(14, e, f, g, h);
k_set(15, a, b, c, d);
sb4(a, b, c, d, e, f, g, h);
k_get(15, e, f, g, h);
k_set(16, a, b, c, d);
sb3(a, b, c, d, e, f, g, h);
k_get(16, e, f, g, h);
k_set(17, a, b, c, d);
sb2(a, b, c, d, e, f, g, h);
k_get(17, e, f, g, h);
k_set(18, a, b, c, d);
sb1(a, b, c, d, e, f, g, h);
k_get(18, e, f, g, h);
k_set(19, a, b, c, d);
sb0(a, b, c, d, e, f, g, h);
k_get(19, e, f, g, h);
k_set(20, a, b, c, d);
sb7(a, b, c, d, e, f, g, h);
k_get(20, e, f, g, h);
k_set(21, a, b, c, d);
sb6(a, b, c, d, e, f, g, h);
k_get(21, e, f, g, h);
k_set(22, a, b, c, d);
sb5(a, b, c, d, e, f, g, h);
k_get(22, e, f, g, h);
k_set(23, a, b, c, d);
sb4(a, b, c, d, e, f, g, h);
k_get(23, e, f, g, h);
k_set(24, a, b, c, d);
sb3(a, b, c, d, e, f, g, h);
k_get(24, e, f, g, h);
k_set(25, a, b, c, d);
sb2(a, b, c, d, e, f, g, h);
k_get(25, e, f, g, h);
k_set(26, a, b, c, d);
sb1(a, b, c, d, e, f, g, h);
k_get(26, e, f, g, h);
k_set(27, a, b, c, d);
sb0(a, b, c, d, e, f, g, h);
k_get(27, e, f, g, h);
k_set(28, a, b, c, d);
sb7(a, b, c, d, e, f, g, h);
k_get(28, e, f, g, h);
k_set(29, a, b, c, d);
sb6(a, b, c, d, e, f, g, h);
k_get(29, e, f, g, h);
k_set(30, a, b, c, d);
sb5(a, b, c, d, e, f, g, h);
k_get(30, e, f, g, h);
k_set(31, a, b, c, d);
sb4(a, b, c, d, e, f, g, h);
k_get(31, e, f, g, h);
k_set(32, a, b, c, d);
sb3(a, b, c, d, e, f, g, h);
k_get(32, e, f, g, h);
return 0;
}
/* encrypt a block of text */
WIN32DLL_DEFINE void _mcrypt_encrypt(SERPENT_KEY * spkey, word32 * in_blk)
{
word32 a, b, c, d, e, f, g, h;
word32 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
t15, t16;
#ifdef WORDS_BIGENDIAN
a = byteswap32(in_blk[0]);
b = byteswap32(in_blk[1]);
c = byteswap32(in_blk[2]);
d = byteswap32(in_blk[3]);
#else
a = in_blk[0];
b = in_blk[1];
c = in_blk[2];
d = in_blk[3];
#endif
k_xor(0, a, b, c, d);
sb0(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(1, e, f, g, h);
sb1(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(2, a, b, c, d);
sb2(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(3, e, f, g, h);
sb3(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(4, a, b, c, d);
sb4(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(5, e, f, g, h);
sb5(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(6, a, b, c, d);
sb6(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(7, e, f, g, h);
sb7(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(8, a, b, c, d);
sb0(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(9, e, f, g, h);
sb1(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(10, a, b, c, d);
sb2(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(11, e, f, g, h);
sb3(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(12, a, b, c, d);
sb4(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(13, e, f, g, h);
sb5(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(14, a, b, c, d);
sb6(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(15, e, f, g, h);
sb7(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(16, a, b, c, d);
sb0(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(17, e, f, g, h);
sb1(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(18, a, b, c, d);
sb2(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(19, e, f, g, h);
sb3(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(20, a, b, c, d);
sb4(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(21, e, f, g, h);
sb5(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(22, a, b, c, d);
sb6(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(23, e, f, g, h);
sb7(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(24, a, b, c, d);
sb0(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(25, e, f, g, h);
sb1(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(26, a, b, c, d);
sb2(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(27, e, f, g, h);
sb3(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(28, a, b, c, d);
sb4(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(29, e, f, g, h);
sb5(e, f, g, h, a, b, c, d);
rot(a, b, c, d);
k_xor(30, a, b, c, d);
sb6(a, b, c, d, e, f, g, h);
rot(e, f, g, h);
k_xor(31, e, f, g, h);
sb7(e, f, g, h, a, b, c, d);
k_xor(32, a, b, c, d);
#ifdef WORDS_BIGENDIAN
in_blk[0] = byteswap32(a);
in_blk[1] = byteswap32(b);
in_blk[2] = byteswap32(c);
in_blk[3] = byteswap32(d);
#else
in_blk[0] = a;
in_blk[1] = b;
in_blk[2] = c;
in_blk[3] = d;
#endif
}
/* decrypt a block of text */
WIN32DLL_DEFINE void _mcrypt_decrypt(SERPENT_KEY * spkey, word32 * in_blk)
{
word32 a, b, c, d, e, f, g, h;
word32 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
t15, t16;
#ifdef WORDS_BIGENDIAN
a = byteswap32(in_blk[0]);
b = byteswap32(in_blk[1]);
c = byteswap32(in_blk[2]);
d = byteswap32(in_blk[3]);
#else
a = in_blk[0];
b = in_blk[1];
c = in_blk[2];
d = in_blk[3];
#endif
k_xor(32, a, b, c, d);
ib7(a, b, c, d, e, f, g, h);
k_xor(31, e, f, g, h);
irot(e, f, g, h);
ib6(e, f, g, h, a, b, c, d);
k_xor(30, a, b, c, d);
irot(a, b, c, d);
ib5(a, b, c, d, e, f, g, h);
k_xor(29, e, f, g, h);
irot(e, f, g, h);
ib4(e, f, g, h, a, b, c, d);
k_xor(28, a, b, c, d);
irot(a, b, c, d);
ib3(a, b, c, d, e, f, g, h);
k_xor(27, e, f, g, h);
irot(e, f, g, h);
ib2(e, f, g, h, a, b, c, d);
k_xor(26, a, b, c, d);
irot(a, b, c, d);
ib1(a, b, c, d, e, f, g, h);
k_xor(25, e, f, g, h);
irot(e, f, g, h);
ib0(e, f, g, h, a, b, c, d);
k_xor(24, a, b, c, d);
irot(a, b, c, d);
ib7(a, b, c, d, e, f, g, h);
k_xor(23, e, f, g, h);
irot(e, f, g, h);
ib6(e, f, g, h, a, b, c, d);
k_xor(22, a, b, c, d);
irot(a, b, c, d);
ib5(a, b, c, d, e, f, g, h);
k_xor(21, e, f, g, h);
irot(e, f, g, h);
ib4(e, f, g, h, a, b, c, d);
k_xor(20, a, b, c, d);
irot(a, b, c, d);
ib3(a, b, c, d, e, f, g, h);
k_xor(19, e, f, g, h);
irot(e, f, g, h);
ib2(e, f, g, h, a, b, c, d);
k_xor(18, a, b, c, d);
irot(a, b, c, d);
ib1(a, b, c, d, e, f, g, h);
k_xor(17, e, f, g, h);
irot(e, f, g, h);
ib0(e, f, g, h, a, b, c, d);
k_xor(16, a, b, c, d);
irot(a, b, c, d);
ib7(a, b, c, d, e, f, g, h);
k_xor(15, e, f, g, h);
irot(e, f, g, h);
ib6(e, f, g, h, a, b, c, d);
k_xor(14, a, b, c, d);
irot(a, b, c, d);
ib5(a, b, c, d, e, f, g, h);
k_xor(13, e, f, g, h);
irot(e, f, g, h);
ib4(e, f, g, h, a, b, c, d);
k_xor(12, a, b, c, d);
irot(a, b, c, d);
ib3(a, b, c, d, e, f, g, h);
k_xor(11, e, f, g, h);
irot(e, f, g, h);
ib2(e, f, g, h, a, b, c, d);
k_xor(10, a, b, c, d);
irot(a, b, c, d);
ib1(a, b, c, d, e, f, g, h);
k_xor(9, e, f, g, h);
irot(e, f, g, h);
ib0(e, f, g, h, a, b, c, d);
k_xor(8, a, b, c, d);
irot(a, b, c, d);
ib7(a, b, c, d, e, f, g, h);
k_xor(7, e, f, g, h);
irot(e, f, g, h);
ib6(e, f, g, h, a, b, c, d);
k_xor(6, a, b, c, d);
irot(a, b, c, d);
ib5(a, b, c, d, e, f, g, h);
k_xor(5, e, f, g, h);
irot(e, f, g, h);
ib4(e, f, g, h, a, b, c, d);
k_xor(4, a, b, c, d);
irot(a, b, c, d);
ib3(a, b, c, d, e, f, g, h);
k_xor(3, e, f, g, h);
irot(e, f, g, h);
ib2(e, f, g, h, a, b, c, d);
k_xor(2, a, b, c, d);
irot(a, b, c, d);
ib1(a, b, c, d, e, f, g, h);
k_xor(1, e, f, g, h);
irot(e, f, g, h);
ib0(e, f, g, h, a, b, c, d);
k_xor(0, a, b, c, d);
#ifdef WORDS_BIGENDIAN
in_blk[0] = byteswap32(a);
in_blk[1] = byteswap32(b);
in_blk[2] = byteswap32(c);
in_blk[3] = byteswap32(d);
#else
in_blk[0] = a;
in_blk[1] = b;
in_blk[2] = c;
in_blk[3] = d;
#endif
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(SERPENT_KEY);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 16;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 16, 24, 32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "Serpent";
}
#define CIPHER "9a99455df5080bfccadf049b5aaf7d61"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,4 @@
typedef struct {
word32 l_key[140];
} SERPENT_KEY;
@@ -0,0 +1,859 @@
/* Sofware DES functions
* written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from
* the 1977 public-domain program by Jim Gillogly
* Modified for additional speed - 6 December 1988 Phil Karn
* Modified for parameterized key schedules - Jan 1991 Phil Karn
* Modified modified such that will operate in EDE 3DES - 1999 Nikos Mavroyanopoulos
*
* Callers now allocate a key schedule as follows:
* kn = (char (*)[8])malloc(sizeof(char) * 8 * 16);
* or
* char kn[16][8];
*/
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: tripledes.c,v 1.13 2003/01/19 17:48:27 nmav Exp $ */
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "tripledes.h"
#define _mcrypt_set_key tripledes_LTX__mcrypt_set_key
#define _mcrypt_encrypt tripledes_LTX__mcrypt_encrypt
#define _mcrypt_decrypt tripledes_LTX__mcrypt_decrypt
#define _mcrypt_get_size tripledes_LTX__mcrypt_get_size
#define _mcrypt_get_block_size tripledes_LTX__mcrypt_get_block_size
#define _is_block_algorithm tripledes_LTX__is_block_algorithm
#define _mcrypt_get_key_size tripledes_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes tripledes_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name tripledes_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test tripledes_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version tripledes_LTX__mcrypt_algorithm_version
/* #define NULL 0 */
static void permute(), perminit(), spinit();
static word32 f();
/* Tables defined in the Data Encryption Standard documents */
/* initial permutation IP */
static char ip[] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
/* final permutation IP^-1 */
static char fp[] = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
/* expansion operation matrix
* This is for reference only; it is unused in the code
* as the f() function performs it implicitly for speed
*/
#ifdef notdef
static char ei[] = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
#endif
/* permuted choice table (key) */
static char pc1[] = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
/* number left rotations of pc1 */
static char totrot[] = {
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
};
/* permuted choice key (table) */
static char pc2[] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
/* The (in)famous S-boxes */
static char si[8][64] = {
/* S1 */
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
/* S2 */
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
/* S3 */
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
/* S4 */
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
/* S5 */
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
/* S6 */
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
/* S7 */
{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
/* S8 */
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
};
/* 32-bit permutation function P used on the output of the S-boxes */
static char p32i[] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/* End of DES-defined tables */
/* Lookup tables initialized once only at startup by desinit() */
/* bit 0 is left-most in byte */
static int bytebit[] = {
0200, 0100, 040, 020, 010, 04, 02, 01
};
static int nibblebit[] = {
010, 04, 02, 01
};
/* Allocate space and initialize DES lookup arrays
* mode == 0: standard Data Encryption Algorithm
*/
static int _mcrypt_desinit(TRIPLEDES_KEY * key)
{
spinit(key, 0);
spinit(key, 1);
spinit(key, 2);
perminit(&key->iperm, ip);
perminit(&key->fperm, fp);
return 0;
}
/* Set key (initialize key schedule array) */
WIN32DLL_DEFINE
int _mcrypt_set_key(TRIPLEDES_KEY * dkey, char *user_key, int len)
{
char pc1m[56]; /* place to modify pc1 into */
char pcr[56]; /* place to rotate pc1 into */
register int i, j, l;
int m;
char *user_key1 = &user_key[0];
char *user_key2 = &user_key[8];
char *user_key3 = &user_key[16];
_mcrypt_desinit(dkey);
/* Clear key schedule */
Bzero(dkey->kn[0], 16 * 8);
Bzero(dkey->kn[1], 16 * 8);
Bzero(dkey->kn[2], 16 * 8);
/* DES 1 */
for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
l = pc1[j] - 1; /* integer bit location */
m = l & 07; /* find bit */
pc1m[j] = (user_key1[l >> 3] & /* find which key byte l is in */
bytebit[m]) /* and which bit of that byte */
? 1 : 0; /* and store 1-bit result */
}
for (i = 0; i < 16; i++) { /* key chunk for each iteration */
for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
pcr[j] =
pc1m[(l = j + totrot[i]) <
(j < 28 ? 28 : 56) ? l : l - 28];
/* rotate left and right halves independently */
for (j = 0; j < 48; j++) { /* select bits individually */
/* check bit that goes to kn[j] */
if (pcr[pc2[j] - 1]) {
/* mask it in if it's there */
l = j % 6;
dkey->kn[0][i][j / 6] |= bytebit[l] >> 2;
}
}
}
/* DES 2 */
for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
l = pc1[j] - 1; /* integer bit location */
m = l & 07; /* find bit */
pc1m[j] = (user_key2[l >> 3] & /* find which key byte l is in */
bytebit[m]) /* and which bit of that byte */
? 1 : 0; /* and store 1-bit result */
}
for (i = 0; i < 16; i++) { /* key chunk for each iteration */
for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
pcr[j] =
pc1m[(l = j + totrot[i]) <
(j < 28 ? 28 : 56) ? l : l - 28];
/* rotate left and right halves independently */
for (j = 0; j < 48; j++) { /* select bits individually */
/* check bit that goes to kn[j] */
if (pcr[pc2[j] - 1]) {
/* mask it in if it's there */
l = j % 6;
dkey->kn[1][i][j / 6] |= bytebit[l] >> 2;
}
}
}
/* DES 3 */
for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
l = pc1[j] - 1; /* integer bit location */
m = l & 07; /* find bit */
pc1m[j] = (user_key3[l >> 3] & /* find which key byte l is in */
bytebit[m]) /* and which bit of that byte */
? 1 : 0; /* and store 1-bit result */
}
for (i = 0; i < 16; i++) { /* key chunk for each iteration */
for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
pcr[j] =
pc1m[(l = j + totrot[i]) <
(j < 28 ? 28 : 56) ? l : l - 28];
/* rotate left and right halves independently */
for (j = 0; j < 48; j++) { /* select bits individually */
/* check bit that goes to kn[j] */
if (pcr[pc2[j] - 1]) {
/* mask it in if it's there */
l = j % 6;
dkey->kn[2][i][j / 6] |= bytebit[l] >> 2;
}
}
}
return 0;
}
/* In-place encryption of 64-bit block */
WIN32DLL_DEFINE void _mcrypt_encrypt(TRIPLEDES_KEY * key, char *block)
{
register word32 left, right;
register char *knp;
word32 work[2]; /* Working data storage */
/* DES 1 */
permute(block, key->iperm, (char *) work); /* Initial Permutation */
#ifndef WORDS_BIGENDIAN
left = byteswap32(work[0]);
right = byteswap32(work[1]);
#else
left = work[0];
right = work[1];
#endif
/* Do the 16 rounds.
* The rounds are numbered from 0 to 15. On even rounds
* the right half is fed to f() and the result exclusive-ORs
* the left half; on odd rounds the reverse is done.
*/
knp = &key->kn[0][0][0];
left ^= f(key, 0, right, knp);
knp += 8;
right ^= f(key, 0, left, knp);
knp += 8;
left ^= f(key, 0, right, knp);
knp += 8;
right ^= f(key, 0, left, knp);
knp += 8;
left ^= f(key, 0, right, knp);
knp += 8;
right ^= f(key, 0, left, knp);
knp += 8;
left ^= f(key, 0, right, knp);
knp += 8;
right ^= f(key, 0, left, knp);
knp += 8;
left ^= f(key, 0, right, knp);
knp += 8;
right ^= f(key, 0, left, knp);
knp += 8;
left ^= f(key, 0, right, knp);
knp += 8;
right ^= f(key, 0, left, knp);
knp += 8;
left ^= f(key, 0, right, knp);
knp += 8;
right ^= f(key, 0, left, knp);
knp += 8;
left ^= f(key, 0, right, knp);
knp += 8;
right ^= f(key, 0, left, knp);
/* DES 2 */
/* Do the 16 rounds in reverse order.
* The rounds are numbered from 15 to 0. On even rounds
* the right half is fed to f() and the result exclusive-ORs
* the left half; on odd rounds the reverse is done.
*/
knp = &key->kn[1][15][0];
right ^= f(key, 1, left, knp);
knp -= 8;
left ^= f(key, 1, right, knp);
knp -= 8;
right ^= f(key, 1, left, knp);
knp -= 8;
left ^= f(key, 1, right, knp);
knp -= 8;
right ^= f(key, 1, left, knp);
knp -= 8;
left ^= f(key, 1, right, knp);
knp -= 8;
right ^= f(key, 1, left, knp);
knp -= 8;
left ^= f(key, 1, right, knp);
knp -= 8;
right ^= f(key, 1, left, knp);
knp -= 8;
left ^= f(key, 1, right, knp);
knp -= 8;
right ^= f(key, 1, left, knp);
knp -= 8;
left ^= f(key, 1, right, knp);
knp -= 8;
right ^= f(key, 1, left, knp);
knp -= 8;
left ^= f(key, 1, right, knp);
knp -= 8;
right ^= f(key, 1, left, knp);
knp -= 8;
left ^= f(key, 1, right, knp);
/* Do the 16 rounds.
* The rounds are numbered from 0 to 15. On even rounds
* the right half is fed to f() and the result exclusive-ORs
* the left half; on odd rounds the reverse is done.
*/
knp = &key->kn[2][0][0];
left ^= f(key, 2, right, knp);
knp += 8;
right ^= f(key, 2, left, knp);
knp += 8;
left ^= f(key, 2, right, knp);
knp += 8;
right ^= f(key, 2, left, knp);
knp += 8;
left ^= f(key, 2, right, knp);
knp += 8;
right ^= f(key, 2, left, knp);
knp += 8;
left ^= f(key, 2, right, knp);
knp += 8;
right ^= f(key, 2, left, knp);
knp += 8;
left ^= f(key, 2, right, knp);
knp += 8;
right ^= f(key, 2, left, knp);
knp += 8;
left ^= f(key, 2, right, knp);
knp += 8;
right ^= f(key, 2, left, knp);
knp += 8;
left ^= f(key, 2, right, knp);
knp += 8;
right ^= f(key, 2, left, knp);
knp += 8;
left ^= f(key, 2, right, knp);
knp += 8;
right ^= f(key, 2, left, knp);
/* Left/right half swap, plus byte swap if little-endian */
#ifndef WORDS_BIGENDIAN
work[1] = byteswap32(left);
work[0] = byteswap32(right);
#else
work[0] = right;
work[1] = left;
#endif
permute((char *) work, key->fperm, block); /* Inverse initial permutation */
}
/* In-place decryption of 64-bit block. This function is the mirror
* image of encryption; exactly the same steps are taken, but in
* reverse order
*/
WIN32DLL_DEFINE void _mcrypt_decrypt(TRIPLEDES_KEY * key, char *block)
{
register word32 left, right;
register char *knp;
word32 work[2]; /* Working data storage */
permute(block, key->iperm, (char *) work); /* Initial permutation */
/* Left/right half swap, plus byte swap if little-endian */
#ifndef WORDS_BIGENDIAN
right = byteswap32(work[0]);
left = byteswap32(work[1]);
#else
right = work[0];
left = work[1];
#endif
/* DES 3 */
/* Do the 16 rounds in reverse order.
* The rounds are numbered from 15 to 0. On even rounds
* the right half is fed to f() and the result exclusive-ORs
* the left half; on odd rounds the reverse is done.
*/
knp = &key->kn[2][15][0];
right ^= f(key, 2, left, knp);
knp -= 8;
left ^= f(key, 2, right, knp);
knp -= 8;
right ^= f(key, 2, left, knp);
knp -= 8;
left ^= f(key, 2, right, knp);
knp -= 8;
right ^= f(key, 2, left, knp);
knp -= 8;
left ^= f(key, 2, right, knp);
knp -= 8;
right ^= f(key, 2, left, knp);
knp -= 8;
left ^= f(key, 2, right, knp);
knp -= 8;
right ^= f(key, 2, left, knp);
knp -= 8;
left ^= f(key, 2, right, knp);
knp -= 8;
right ^= f(key, 2, left, knp);
knp -= 8;
left ^= f(key, 2, right, knp);
knp -= 8;
right ^= f(key, 2, left, knp);
knp -= 8;
left ^= f(key, 2, right, knp);
knp -= 8;
right ^= f(key, 2, left, knp);
knp -= 8;
left ^= f(key, 2, right, knp);
/* DES 2*/
/* Do the 16 rounds.
* The rounds are numbered from 0 to 15. On even rounds
* the right half is fed to f() and the result exclusive-ORs
* the left half; on odd rounds the reverse is done.
*/
knp = &key->kn[1][0][0];
left ^= f(key, 1, right, knp);
knp += 8;
right ^= f(key, 1, left, knp);
knp += 8;
left ^= f(key, 1, right, knp);
knp += 8;
right ^= f(key, 1, left, knp);
knp += 8;
left ^= f(key, 1, right, knp);
knp += 8;
right ^= f(key, 1, left, knp);
knp += 8;
left ^= f(key, 1, right, knp);
knp += 8;
right ^= f(key, 1, left, knp);
knp += 8;
left ^= f(key, 1, right, knp);
knp += 8;
right ^= f(key, 1, left, knp);
knp += 8;
left ^= f(key, 1, right, knp);
knp += 8;
right ^= f(key, 1, left, knp);
knp += 8;
left ^= f(key, 1, right, knp);
knp += 8;
right ^= f(key, 1, left, knp);
knp += 8;
left ^= f(key, 1, right, knp);
knp += 8;
right ^= f(key, 1, left, knp);
/* DES 1 */
/* Do the 16 rounds in reverse order.
* The rounds are numbered from 15 to 0. On even rounds
* the right half is fed to f() and the result exclusive-ORs
* the left half; on odd rounds the reverse is done.
*/
knp = &key->kn[0][15][0];
right ^= f(key, 0, left, knp);
knp -= 8;
left ^= f(key, 0, right, knp);
knp -= 8;
right ^= f(key, 0, left, knp);
knp -= 8;
left ^= f(key, 0, right, knp);
knp -= 8;
right ^= f(key, 0, left, knp);
knp -= 8;
left ^= f(key, 0, right, knp);
knp -= 8;
right ^= f(key, 0, left, knp);
knp -= 8;
left ^= f(key, 0, right, knp);
knp -= 8;
right ^= f(key, 0, left, knp);
knp -= 8;
left ^= f(key, 0, right, knp);
knp -= 8;
right ^= f(key, 0, left, knp);
knp -= 8;
left ^= f(key, 0, right, knp);
knp -= 8;
right ^= f(key, 0, left, knp);
knp -= 8;
left ^= f(key, 0, right, knp);
knp -= 8;
right ^= f(key, 0, left, knp);
knp -= 8;
left ^= f(key, 0, right, knp);
#ifndef WORDS_BIGENDIAN
work[0] = byteswap32(left);
work[1] = byteswap32(right);
#else
work[0] = left;
work[1] = right;
#endif
permute((char *) work, key->fperm, block); /* Inverse initial permutation */
}
/* Permute inblock with perm */
static void permute(char *inblock, char perm[16][16][8], char *outblock)
{
register char *ib, *ob; /* ptr to input or output block */
register char *p, *q;
register int j;
if (perm == NULL) {
/* No permutation, just copy */
memmove(outblock, inblock, 8);
return;
}
/* Clear output block */
Bzero(outblock, 8);
ib = inblock;
for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
ob = outblock;
p = perm[j][(*ib >> 4) & 0xf];
q = perm[j + 1][*ib & 0xf];
/* and each output byte, OR the masks together */
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
*ob++ |= *p++ | *q++;
}
}
/* The nonlinear function f(r,k), the heart of DES */
static word32 f(TRIPLEDES_KEY * key, int pos, register word32 r,
register char *subkey)
{
register word32 *spp;
register word32 rval, rt;
register int er;
#ifdef TRACE
printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
r,
subkey[0], subkey[1], subkey[2],
subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]);
#endif
/* Run E(R) ^ K through the combined S & P boxes.
* This code takes advantage of a convenient regularity in
* E, namely that each group of 6 bits in E(R) feeding
* a single S-box is a contiguous segment of R.
*/
subkey += 7;
/* Compute E(R) for each block of 6 bits, and run thru boxes */
er = ((int) r << 1) | ((r & 0x80000000) ? 1 : 0);
spp = &key->sp[pos][7][0];
rval = spp[(er ^ *subkey--) & 0x3f];
spp -= 64;
rt = (word32) r >> 3;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rval |= spp[((int) rt ^ *subkey--) & 0x3f];
spp -= 64;
rt >>= 4;
rt |= (r & 1) << 5;
rval |= spp[((int) rt ^ *subkey) & 0x3f];
#ifdef TRACE
printf(" %08lx\n", rval);
#endif
return rval;
}
/* initialize a perm array */
static void perminit(char perm[16][16][8], char p[64])
{
register int l, j, k;
int i, m;
/* Clear the permutation array */
Bzero((char *) perm, 16 * 16 * 8);
for (i = 0; i < 16; i++) /* each input nibble position */
for (j = 0; j < 16; j++) /* each possible input nibble */
for (k = 0; k < 64; k++) { /* each output bit position */
l = p[k] - 1; /* where does this bit come from */
if ((l >> 2) != i) /* does it come from input posn? */
continue; /* if not, bit k is 0 */
if (!(j & nibblebit[l & 3]))
continue; /* any such bit in input? */
m = k & 07; /* which bit is this in the byte */
perm[i][j][k >> 3] |= bytebit[m];
}
}
/* Initialize the lookup table for the combined S and P boxes */
static void spinit(TRIPLEDES_KEY * key, int pos)
{
char pbox[32];
int p, i, s, j, rowcol;
word32 val;
/* Compute pbox, the inverse of p32i.
* This is easier to work with
*/
for (p = 0; p < 32; p++) {
for (i = 0; i < 32; i++) {
if (p32i[i] - 1 == p) {
pbox[p] = i;
break;
}
}
}
for (s = 0; s < 8; s++) { /* For each S-box */
for (i = 0; i < 64; i++) { /* For each possible input */
val = 0;
/* The row number is formed from the first and last
* bits; the column number is from the middle 4
*/
rowcol =
(i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) &
0xf);
for (j = 0; j < 4; j++) { /* For each output bit */
if (si[s][rowcol] & (8 >> j)) {
val |=
1L << (31 - pbox[4 * s + j]);
}
}
key->sp[pos][s][i] = val;
#ifdef DEBUG
printf("sp[%d][%2d] = %08lx\n", s, i,
sp[pos][s][i]);
#endif
}
}
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(TRIPLEDES_KEY);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 24;
}
static const int key_sizes[] = { 24 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "3DES";
}
#define CIPHER "58ed248f77f6b19e"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n%s\n", cipher_tmp);
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 19991129;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,9 @@
typedef struct triple_des_key {
char kn[3][16][8];
word32 sp[3][8][64];
char iperm[16][16][8];
char fperm[16][16][8];
} TRIPLEDES_KEY;
@@ -0,0 +1,675 @@
/* This is an independent implementation of the encryption algorithm: */
/* */
/* Twofish by Bruce Schneier and colleagues */
/* */
/* which is a candidate algorithm in the Advanced Encryption Standard */
/* programme of the US National Institute of Standards and Technology. */
/* */
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of t he algorithm place on its exploitation. */
/* */
/* My thanks to Doug Whiting and Niels Ferguson for comments that led */
/* to improvements in this implementation. */
/* */
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
/* $Id: twofish.c,v 1.16 2003/01/19 17:48:27 nmav Exp $ */
/* Timing data for Twofish (twofish.c)
128 bit key:
Key Setup: 8414 cycles
Encrypt: 376 cycles = 68.1 mbits/sec
Decrypt: 374 cycles = 68.4 mbits/sec
Mean: 375 cycles = 68.3 mbits/sec
192 bit key:
Key Setup: 11628 cycles
Encrypt: 376 cycles = 68.1 mbits/sec
Decrypt: 374 cycles = 68.4 mbits/sec
Mean: 375 cycles = 68.3 mbits/sec
256 bit key:
Key Setup: 15457 cycles
Encrypt: 381 cycles = 67.2 mbits/sec
Decrypt: 374 cycles = 68.4 mbits/sec
Mean: 378 cycles = 67.8 mbits/sec
*/
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "twofish.h"
#define _mcrypt_set_key twofish_LTX__mcrypt_set_key
#define _mcrypt_encrypt twofish_LTX__mcrypt_encrypt
#define _mcrypt_decrypt twofish_LTX__mcrypt_decrypt
#define _mcrypt_get_size twofish_LTX__mcrypt_get_size
#define _mcrypt_get_block_size twofish_LTX__mcrypt_get_block_size
#define _is_block_algorithm twofish_LTX__is_block_algorithm
#define _mcrypt_get_key_size twofish_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes twofish_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name twofish_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test twofish_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version twofish_LTX__mcrypt_algorithm_version
/* word32 k_len;
* word32 l_key[40];
* word32 s_key[4];
*/
/* Extract byte from a 32 bit quantity (little endian notation) */
#define byte(x,n) ((byte)((x) >> (8 * n)))
/* finite field arithmetic for GF(2**8) with the modular */
/* polynomial x^8 + x^6 + x^5 + x^3 + 1 (0x169) */
#define G_M 0x0169
byte tab_5b[4] = { 0, G_M >> 2, G_M >> 1, (G_M >> 1) ^ (G_M >> 2) };
byte tab_ef[4] = { 0, (G_M >> 1) ^ (G_M >> 2), G_M >> 1, G_M >> 2 };
#define ffm_01(x) (x)
#define ffm_5b(x) ((x) ^ ((x) >> 2) ^ tab_5b[(x) & 3])
#define ffm_ef(x) ((x) ^ ((x) >> 1) ^ ((x) >> 2) ^ tab_ef[(x) & 3])
byte ror4[16] = { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 };
byte ashx[16] = { 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7 };
byte qt0[2][16] = {
{8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4}
,
{2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5}
};
byte qt1[2][16] = {
{14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13}
,
{1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8}
};
byte qt2[2][16] = {
{11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1}
,
{4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15}
};
byte qt3[2][16] = {
{13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10}
,
{11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10}
};
byte qp(const word32 n, const byte x)
{
byte a0, a1, a2, a3, a4, b0, b1, b2, b3, b4;
a0 = x >> 4;
b0 = x & 15;
a1 = a0 ^ b0;
b1 = ror4[b0] ^ ashx[a0];
a2 = qt0[n][a1];
b2 = qt1[n][b1];
a3 = a2 ^ b2;
b3 = ror4[b2] ^ ashx[a2];
a4 = qt2[n][a3];
b4 = qt3[n][b3];
return (b4 << 4) | a4;
}
#ifdef Q_TABLES
#define q(n,x) pkey->q_tab[n][x]
void gen_qtab(TWI * pkey)
{
word32 i;
for (i = 0; i < 256; ++i) {
q(0, i) = qp(0, (byte) i);
q(1, i) = qp(1, (byte) i);
}
}
#else
#define q(n,x) qp(n, x)
#endif
#ifdef M_TABLE
void gen_mtab(TWI * pkey)
{
word32 i, f01, f5b, fef;
for (i = 0; i < 256; ++i) {
f01 = q(1, i);
f5b = ffm_5b(f01);
fef = ffm_ef(f01);
pkey->m_tab[0][i] =
f01 + (f5b << 8) + (fef << 16) + (fef << 24);
pkey->m_tab[2][i] =
f5b + (fef << 8) + (f01 << 16) + (fef << 24);
f01 = q(0, i);
f5b = ffm_5b(f01);
fef = ffm_ef(f01);
pkey->m_tab[1][i] =
fef + (fef << 8) + (f5b << 16) + (f01 << 24);
pkey->m_tab[3][i] =
f5b + (f01 << 8) + (fef << 16) + (f5b << 24);
}
}
#define mds(n,x) pkey->m_tab[n][x]
#else
#define fm_00 ffm_01
#define fm_10 ffm_5b
#define fm_20 ffm_ef
#define fm_30 ffm_ef
#define q_0(x) q(1,x)
#define fm_01 ffm_ef
#define fm_11 ffm_ef
#define fm_21 ffm_5b
#define fm_31 ffm_01
#define q_1(x) q(0,x)
#define fm_02 ffm_5b
#define fm_12 ffm_ef
#define fm_22 ffm_01
#define fm_32 ffm_ef
#define q_2(x) q(1,x)
#define fm_03 ffm_5b
#define fm_13 ffm_01
#define fm_23 ffm_ef
#define fm_33 ffm_5b
#define q_3(x) q(0,x)
#define f_0(n,x) ((word32)fm_0##n(x))
#define f_1(n,x) ((word32)fm_1##n(x) << 8)
#define f_2(n,x) ((word32)fm_2##n(x) << 16)
#define f_3(n,x) ((word32)fm_3##n(x) << 24)
#define mds(n,x) f_0(n,q_##n(x)) ^ f_1(n,q_##n(x)) ^ f_2(n,q_##n(x)) ^ f_3(n,q_##n(x))
#endif
word32 h_fun(TWI * pkey, const word32 x, const word32 key[])
{
word32 b0, b1, b2, b3;
#ifndef M_TABLE
word32 m5b_b0, m5b_b1, m5b_b2, m5b_b3;
word32 mef_b0, mef_b1, mef_b2, mef_b3;
#endif
b0 = byte(x, 0);
b1 = byte(x, 1);
b2 = byte(x, 2);
b3 = byte(x, 3);
switch (pkey->k_len) {
case 4:
b0 = q(1, b0) ^ byte(key[3], 0);
b1 = q(0, b1) ^ byte(key[3], 1);
b2 = q(0, b2) ^ byte(key[3], 2);
b3 = q(1, b3) ^ byte(key[3], 3);
case 3:
b0 = q(1, b0) ^ byte(key[2], 0);
b1 = q(1, b1) ^ byte(key[2], 1);
b2 = q(0, b2) ^ byte(key[2], 2);
b3 = q(0, b3) ^ byte(key[2], 3);
case 2:
b0 = q(0, q(0, b0) ^ byte(key[1], 0)) ^ byte(key[0], 0);
b1 = q(0, q(1, b1) ^ byte(key[1], 1)) ^ byte(key[0], 1);
b2 = q(1, q(0, b2) ^ byte(key[1], 2)) ^ byte(key[0], 2);
b3 = q(1, q(1, b3) ^ byte(key[1], 3)) ^ byte(key[0], 3);
}
#ifdef M_TABLE
return mds(0, b0) ^ mds(1, b1) ^ mds(2, b2) ^ mds(3, b3);
#else
b0 = q(1, b0);
b1 = q(0, b1);
b2 = q(1, b2);
b3 = q(0, b3);
m5b_b0 = ffm_5b(b0);
m5b_b1 = ffm_5b(b1);
m5b_b2 = ffm_5b(b2);
m5b_b3 = ffm_5b(b3);
mef_b0 = ffm_ef(b0);
mef_b1 = ffm_ef(b1);
mef_b2 = ffm_ef(b2);
mef_b3 = ffm_ef(b3);
b0 ^= mef_b1 ^ m5b_b2 ^ m5b_b3;
b3 ^= m5b_b0 ^ mef_b1 ^ mef_b2;
b2 ^= mef_b0 ^ m5b_b1 ^ mef_b3;
b1 ^= mef_b0 ^ mef_b2 ^ m5b_b3;
return b0 | (b3 << 8) | (b2 << 16) | (b1 << 24);
#endif
}
#ifdef MK_TABLE
#define q20(x) q(0,q(0,x) ^ byte(key[1],0)) ^ byte(key[0],0)
#define q21(x) q(0,q(1,x) ^ byte(key[1],1)) ^ byte(key[0],1)
#define q22(x) q(1,q(0,x) ^ byte(key[1],2)) ^ byte(key[0],2)
#define q23(x) q(1,q(1,x) ^ byte(key[1],3)) ^ byte(key[0],3)
#define q30(x) q(0,q(0,q(1, x) ^ byte(key[2],0)) ^ byte(key[1],0)) ^ byte(key[0],0)
#define q31(x) q(0,q(1,q(1, x) ^ byte(key[2],1)) ^ byte(key[1],1)) ^ byte(key[0],1)
#define q32(x) q(1,q(0,q(0, x) ^ byte(key[2],2)) ^ byte(key[1],2)) ^ byte(key[0],2)
#define q33(x) q(1,q(1,q(0, x) ^ byte(key[2],3)) ^ byte(key[1],3)) ^ byte(key[0],3)
#define q40(x) q(0,q(0,q(1, q(1, x) ^ byte(key[3],0)) ^ byte(key[2],0)) ^ byte(key[1],0)) ^ byte(key[0],0)
#define q41(x) q(0,q(1,q(1, q(0, x) ^ byte(key[3],1)) ^ byte(key[2],1)) ^ byte(key[1],1)) ^ byte(key[0],1)
#define q42(x) q(1,q(0,q(0, q(0, x) ^ byte(key[3],2)) ^ byte(key[2],2)) ^ byte(key[1],2)) ^ byte(key[0],2)
#define q43(x) q(1,q(1,q(0, q(1, x) ^ byte(key[3],3)) ^ byte(key[2],3)) ^ byte(key[1],3)) ^ byte(key[0],3)
void gen_mk_tab(TWI * pkey, word32 key[])
{
word32 i;
byte by;
switch (pkey->k_len) {
case 2:
for (i = 0; i < 256; ++i) {
by = (byte) i;
#ifdef ONE_STEP
pkey->mk_tab[0][i] = mds(0, q20(by));
pkey->mk_tab[1][i] = mds(1, q21(by));
pkey->mk_tab[2][i] = mds(2, q22(by));
pkey->mk_tab[3][i] = mds(3, q23(by));
#else
pkey->sb[0][i] = q20(by);
pkey->sb[1][i] = q21(by);
pkey->sb[2][i] = q22(by);
pkey->sb[3][i] = q23(by);
#endif
}
break;
case 3:
for (i = 0; i < 256; ++i) {
by = (byte) i;
#ifdef ONE_STEP
pkey->mk_tab[0][i] = mds(0, q30(by));
pkey->mk_tab[1][i] = mds(1, q31(by));
pkey->mk_tab[2][i] = mds(2, q32(by));
pkey->mk_tab[3][i] = mds(3, q33(by));
#else
pkey->sb[0][i] = q30(by);
pkey->sb[1][i] = q31(by);
pkey->sb[2][i] = q32(by);
pkey->sb[3][i] = q33(by);
#endif
}
break;
case 4:
for (i = 0; i < 256; ++i) {
by = (byte) i;
#ifdef ONE_STEP
pkey->mk_tab[0][i] = mds(0, q40(by));
pkey->mk_tab[1][i] = mds(1, q41(by));
pkey->mk_tab[2][i] = mds(2, q42(by));
pkey->mk_tab[3][i] = mds(3, q43(by));
#else
pkey->sb[0][i] = q40(by);
pkey->sb[1][i] = q41(by);
pkey->sb[2][i] = q42(by);
pkey->sb[3][i] = q43(by);
#endif
}
}
}
#ifdef ONE_STEP
#define g0_fun(x) ( pkey->mk_tab[0][byte(x,0)] ^ pkey->mk_tab[1][byte(x,1)] \
^ pkey->mk_tab[2][byte(x,2)] ^ pkey->mk_tab[3][byte(x,3)] )
#define g1_fun(x) ( pkey->mk_tab[0][byte(x,3)] ^ pkey->mk_tab[1][byte(x,0)] \
^ pkey->mk_tab[2][byte(x,1)] ^ pkey->mk_tab[3][byte(x,2)] )
#else
#define g0_fun(x) ( mds(0, pkey->sb[0][byte(x,0)]) ^ mds(1, pkey->sb[1][byte(x,1)]) \
^ mds(2, pkey->sb[2][byte(x,2)]) ^ mds(3, pkey->sb[3][byte(x,3)]) )
#define g1_fun(x) ( mds(0, pkey->sb[0][byte(x,3)]) ^ mds(1, pkey->sb[1][byte(x,0)]) \
^ mds(2, pkey->sb[2][byte(x,1)]) ^ mds(3, pkey->sb[3][byte(x,2)]) )
#endif
#else
#define g0_fun(x) h_fun(pkey, x,pkey->s_key)
#define g1_fun(x) h_fun(pkey, rotl32(x,8),pkey->s_key)
#endif
/* The (12,8) Reed Soloman code has the generator polynomial
g(x) = x^4 + (a + 1/a) * x^3 + a * x^2 + (a + 1/a) * x + 1
where the coefficients are in the finite field GF(2^8) with a
modular polynomial a^8 + a^6 + a^3 + a^2 + 1. To generate the
remainder we have to start with a 12th order polynomial with our
eight input bytes as the coefficients of the 4th to 11th terms.
That is:
m[7] * x^11 + m[6] * x^10 ... + m[0] * x^4 + 0 * x^3 +... + 0
We then multiply the generator polynomial by m[7] * x^7 and subtract
it - xor in GF(2^8) - from the above to eliminate the x^7 term (the
artihmetic on the coefficients is done in GF(2^8). We then multiply
the generator polynomial by x^6 * coeff(x^10) and use this to remove
the x^10 term. We carry on in this way until the x^4 term is removed
so that we are left with:
r[3] * x^3 + r[2] * x^2 + r[1] 8 x^1 + r[0]
which give the resulting 4 bytes of the remainder. This is equivalent
to the matrix multiplication in the Twofish description but much faster
to implement.
*/
#define G_MOD 0x0000014d
word32 mds_rem(word32 p0, word32 p1)
{
word32 i, t, u;
for (i = 0; i < 8; ++i) {
t = p1 >> 24; /* get most significant coefficient */
p1 = (p1 << 8) | (p0 >> 24);
p0 <<= 8; /* shift others up */
/* multiply t by a (the primitive element - i.e. left shift) */
u = (t << 1);
if (t & 0x80)
/* subtract modular polynomial on overflow */
u ^= G_MOD;
p1 ^= t ^ (u << 16); /* remove t * (a * x^2 + 1) */
u ^= (t >> 1); /* form u = a * t + t / a = t * (a + 1 / a); */
if (t & 0x01)
/* add the modular polynomial on underflow */
u ^= G_MOD >> 1;
p1 ^= (u << 24) | (u << 8); /* remove t * (a + 1/a) * (x^3 + x) */
}
return p1;
}
/* initialise the key schedule from the user supplied key */
WIN32DLL_DEFINE
int _mcrypt_set_key(TWI * pkey, const word32 in_key[],
const word32 key_len)
{
word32 i, a, b, me_key[4], mo_key[4];
#ifdef Q_TABLES
pkey->qt_gen = 0;
if (!pkey->qt_gen) {
gen_qtab(pkey);
pkey->qt_gen = 1;
}
#endif
#ifdef M_TABLE
pkey->mt_gen = 0;
if (!pkey->mt_gen) {
gen_mtab(pkey);
pkey->mt_gen = 1;
}
#endif
pkey->k_len = (key_len * 8) / 64; /* 2, 3 or 4 */
for (i = 0; i < pkey->k_len; ++i) {
#ifdef WORDS_BIGENDIAN
a = byteswap32(in_key[i + i]);
me_key[i] = a;
b = byteswap32(in_key[i + i + 1]);
#else
a = in_key[i + i];
me_key[i] = a;
b = in_key[i + i + 1];
#endif
mo_key[i] = b;
pkey->s_key[pkey->k_len - i - 1] = mds_rem(a, b);
}
for (i = 0; i < 40; i += 2) {
a = 0x01010101 * i;
b = a + 0x01010101;
a = h_fun(pkey, a, me_key);
b = rotl32(h_fun(pkey, b, mo_key), 8);
pkey->l_key[i] = a + b;
pkey->l_key[i + 1] = rotl32(a + 2 * b, 9);
}
#ifdef MK_TABLE
gen_mk_tab(pkey, pkey->s_key);
#endif
return 0;
}
/* This macro was moved to an inline function, because it
* was breaking some compilers.
*/
inline
static void f_rnd(int i, word32* blk, TWI* pkey, word32 t0, word32 t1)
{
t1 = g1_fun(blk[1]);
t0 = g0_fun(blk[0]);
blk[2] = rotr32(blk[2] ^ (t0 + t1 + pkey->l_key[4 * (i) + 8]), 1);
blk[3] = rotl32(blk[3], 1) ^ (t0 + 2 * t1 + pkey->l_key[4 * (i) + 9]);
t1 = g1_fun(blk[3]);
t0 = g0_fun(blk[2]);
blk[0] = rotr32(blk[0] ^ (t0 + t1 + pkey->l_key[4 * (i) + 10]), 1);
blk[1] = rotl32(blk[1], 1) ^ (t0 + 2 * t1 + pkey->l_key[4 * (i) + 11]);
}
/* encrypt a block of text */
WIN32DLL_DEFINE void _mcrypt_encrypt(TWI * pkey, word32 * in_blk)
{
word32 t0, t1, blk[4];
#ifdef WORDS_BIGENDIAN
blk[0] = byteswap32(in_blk[0]) ^ pkey->l_key[0];
blk[1] = byteswap32(in_blk[1]) ^ pkey->l_key[1];
blk[2] = byteswap32(in_blk[2]) ^ pkey->l_key[2];
blk[3] = byteswap32(in_blk[3]) ^ pkey->l_key[3];
#else
blk[0] = in_blk[0] ^ pkey->l_key[0];
blk[1] = in_blk[1] ^ pkey->l_key[1];
blk[2] = in_blk[2] ^ pkey->l_key[2];
blk[3] = in_blk[3] ^ pkey->l_key[3];
#endif
f_rnd(0, blk, pkey, t0, t1);
f_rnd(1, blk, pkey, t0, t1);
f_rnd(2, blk, pkey, t0, t1);
f_rnd(3, blk, pkey, t0, t1);
f_rnd(4, blk, pkey, t0, t1);
f_rnd(5, blk, pkey, t0, t1);
f_rnd(6, blk, pkey, t0, t1);
f_rnd(7, blk, pkey, t0, t1);
#ifdef WORDS_BIGENDIAN
in_blk[0] = byteswap32(blk[2] ^ pkey->l_key[4]);
in_blk[1] = byteswap32(blk[3] ^ pkey->l_key[5]);
in_blk[2] = byteswap32(blk[0] ^ pkey->l_key[6]);
in_blk[3] = byteswap32(blk[1] ^ pkey->l_key[7]);
#else
in_blk[0] = blk[2] ^ pkey->l_key[4];
in_blk[1] = blk[3] ^ pkey->l_key[5];
in_blk[2] = blk[0] ^ pkey->l_key[6];
in_blk[3] = blk[1] ^ pkey->l_key[7];
#endif
}
/* decrypt a block of text */
#define i_rnd(i) \
t1 = g1_fun(blk[1]); t0 = g0_fun(blk[0]); \
blk[2] = rotl32(blk[2], 1) ^ (t0 + t1 + pkey->l_key[4 * (i) + 10]); \
blk[3] = rotr32(blk[3] ^ (t0 + 2 * t1 + pkey->l_key[4 * (i) + 11]), 1); \
t1 = g1_fun(blk[3]); t0 = g0_fun(blk[2]); \
blk[0] = rotl32(blk[0], 1) ^ (t0 + t1 + pkey->l_key[4 * (i) + 8]); \
blk[1] = rotr32(blk[1] ^ (t0 + 2 * t1 + pkey->l_key[4 * (i) + 9]), 1)
WIN32DLL_DEFINE void _mcrypt_decrypt(TWI * pkey, word32 * in_blk)
{
word32 t0, t1, blk[4];
#ifdef WORDS_BIGENDIAN
blk[0] = byteswap32(in_blk[0]) ^ pkey->l_key[4];
blk[1] = byteswap32(in_blk[1]) ^ pkey->l_key[5];
blk[2] = byteswap32(in_blk[2]) ^ pkey->l_key[6];
blk[3] = byteswap32(in_blk[3]) ^ pkey->l_key[7];
#else
blk[0] = in_blk[0] ^ pkey->l_key[4];
blk[1] = in_blk[1] ^ pkey->l_key[5];
blk[2] = in_blk[2] ^ pkey->l_key[6];
blk[3] = in_blk[3] ^ pkey->l_key[7];
#endif
i_rnd(7);
i_rnd(6);
i_rnd(5);
i_rnd(4);
i_rnd(3);
i_rnd(2);
i_rnd(1);
i_rnd(0);
#ifdef WORDS_BIGENDIAN
in_blk[0] = byteswap32(blk[2] ^ pkey->l_key[0]);
in_blk[1] = byteswap32(blk[3] ^ pkey->l_key[1]);
in_blk[2] = byteswap32(blk[0] ^ pkey->l_key[2]);
in_blk[3] = byteswap32(blk[1] ^ pkey->l_key[3]);
#else
in_blk[0] = blk[2] ^ pkey->l_key[0];
in_blk[1] = blk[3] ^ pkey->l_key[1];
in_blk[2] = blk[0] ^ pkey->l_key[2];
in_blk[3] = blk[1] ^ pkey->l_key[3];
#endif
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(TWI);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 16;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 16, 24, 32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "Twofish";
}
#define CIPHER "019f9809de1711858faac3a3ba20fbc3"
#define PT "\xD4\x91\xDB\x16\xE7\xB1\xC3\x9E\x86\xCB\x08\x6B\x78\x9F\x54\x19"
#define KEY "\x9F\x58\x9F\x5C\xF6\x12\x2C\x32\xB6\xBF\xEC\x2F\x2A\xE8\xC3\x5A"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
unsigned char keyword[16];
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void* key;
unsigned char cipher_tmp[200];
memcpy( keyword, KEY, 16);
memcpy( plaintext, PT, 16);
memcpy(ciphertext, plaintext, 16);
key = malloc(_mcrypt_get_size());
if (key==NULL) return -1;
_mcrypt_set_key(key, (void *) keyword, 16);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (memcmp(ciphertext, plaintext, 16) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 19991129;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,24 @@
#define Q_TABLES
#define M_TABLE
#define MK_TABLE
#define ONE_STEP
typedef struct twofish_instance {
word32 k_len;
word32 l_key[40];
word32 s_key[4];
#ifdef Q_TABLES
word32 qt_gen;
byte q_tab[2][256];
#endif
#ifdef M_TABLE
word32 mt_gen;
word32 m_tab[4][256];
#endif
#ifdef ONE_STEP
word32 mk_tab[4][256];
#else
byte sb[4][256];
#endif
} TWI;
@@ -0,0 +1,377 @@
/*
* Copyright (C) 1998,1999,2000,2001 Nikos Mavroyanopoulos
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <libdefs.h>
#include <mcrypt_modules.h>
#include "wake.h"
#define _mcrypt_set_key wake_LTX__mcrypt_set_key
#define _mcrypt_encrypt wake_LTX__mcrypt_encrypt
#define _mcrypt_decrypt wake_LTX__mcrypt_decrypt
#define _mcrypt_get_size wake_LTX__mcrypt_get_size
#define _mcrypt_get_block_size wake_LTX__mcrypt_get_block_size
#define _is_block_algorithm wake_LTX__is_block_algorithm
#define _mcrypt_get_key_size wake_LTX__mcrypt_get_key_size
#define _mcrypt_get_algo_iv_size wake_LTX__mcrypt_get_algo_iv_size
#define _mcrypt_get_supported_key_sizes wake_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name wake_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test wake_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version wake_LTX__mcrypt_algorithm_version
/* WAKE reference C-code, based on the description in David J. Wheeler's
* paper "A bulk Data Encryption Algorithm"
*/
/* #define USE_IV */
/* IV is an mcrypt extension */
static const word32 tt[10] = {
0x726a8f3bUL,
0xe69a3b5cUL,
0xd3c71fe5UL,
0xab3c73d2UL,
0x4d3a8eb3UL,
0x0396d6e8UL,
0x3d4c2f7aUL,
0x9ee27cf3UL
};
WIN32DLL_DEFINE
int _mcrypt_set_key(WAKE_KEY * wake_key, word32 * key, int len,
word32 * IV, int ivlen)
{
word32 x, z, p;
word32 k[4];
/* the key must be exactly 256 bits */
if (len != 32)
return -1;
#ifdef WORDS_BIGENDIAN
k[0] = byteswap32(key[0]);
k[1] = byteswap32(key[1]);
k[2] = byteswap32(key[2]);
k[3] = byteswap32(key[3]);
#else
k[0] = key[0];
k[1] = key[1];
k[2] = key[2];
k[3] = key[3];
#endif
for (p = 0; p < 4; p++) {
wake_key->t[p] = k[p];
}
for (p = 4; p < 256; p++) {
x = wake_key->t[p - 4] + wake_key->t[p - 1];
wake_key->t[p] = x >> 3 ^ tt[x & 7];
}
for (p = 0; p < 23; p++)
wake_key->t[p] += wake_key->t[p + 89];
x = wake_key->t[33];
z = wake_key->t[59] | 0x01000001;
z &= 0xff7fffff;
for (p = 0; p < 256; p++) {
x = (x & 0xff7fffff) + z;
wake_key->t[p] = (wake_key->t[p] & 0x00ffffff) ^ x;
}
wake_key->t[256] = wake_key->t[0];
x &= 0xff;
for (p = 0; p < 256; p++) {
wake_key->t[p] = wake_key->t[x =
(wake_key->t[p ^ x] ^ x) &
0xff];
wake_key->t[x] = wake_key->t[p + 1];
}
wake_key->counter = 0;
wake_key->r[0] = k[0];
wake_key->r[1] = k[1];
wake_key->r[2] = k[2];
#ifdef WORDS_BIGENDIAN
wake_key->r[3] = byteswap32(k[3]);
#else
wake_key->r[3] = k[3];
#endif
#ifdef USE_IV
wake_key->started = 0;
if (ivlen > 32)
wake_key->ivsize = 32;
else
wake_key->ivsize = ivlen / 4 * 4;
if (IV == NULL)
wake_key->ivsize = 0;
if (wake_key->ivsize > 0 && IV != NULL)
memcpy(&wake_key->iv, IV, wake_key->ivsize);
#endif
return 0;
}
/* in order to read the code easier */
#define r2 wake_key->tmp
#define r1 wake_key->tmp
#define counter wake_key->counter
/* M(X,Y) = (X+Y)>>8 XOR t[(X+Y) & 0xff] */
#define M(X,Y) _int_M(X,Y, wake_key)
inline static word32 _int_M(word32 X, word32 Y, WAKE_KEY * wake_key)
{
register word32 TMP;
TMP = X + Y;
return ((((TMP) >> 8) & 0x00ffffff) ^ wake_key->t[(TMP) & 0xff]);
}
WIN32DLL_DEFINE
void _mcrypt_encrypt(WAKE_KEY * wake_key, byte * input, int len)
{
register word32 r3, r4, r5;
word32 r6;
int i;
if (len == 0)
return;
r3 = wake_key->r[0];
r4 = wake_key->r[1];
r5 = wake_key->r[2];
r6 = wake_key->r[3];
#ifdef USE_IV
if (wake_key->started == 0) {
wake_key->started = 1;
_mcrypt_encrypt(wake_key, (byte *) & wake_key->iv,
wake_key->ivsize);
}
#endif
for (i = 0; i < len; i++) {
/* R1 = V[n] = V[n] XOR R6 - here we do it per byte --sloooow */
/* R1 is ignored */
input[i] ^= ((byte *) & r6)[counter];
/* R2 = V[n] = R1 - per byte also */
((byte *) & r2)[counter] = input[i];
counter++;
if (counter == 4) { /* r6 was used - update it! */
counter = 0;
#ifdef WORDS_BIGENDIAN
/* these swaps are because we do operations per byte */
r2 = byteswap32(r2);
r6 = byteswap32(r6);
#endif
r3 = M(r3, r2);
r4 = M(r4, r3);
r5 = M(r5, r4);
r6 = M(r6, r5);
#ifdef WORDS_BIGENDIAN
r6 = byteswap32(r6);
#endif
}
}
wake_key->r[0] = r3;
wake_key->r[1] = r4;
wake_key->r[2] = r5;
wake_key->r[3] = r6;
}
WIN32DLL_DEFINE
void _mcrypt_decrypt(WAKE_KEY * wake_key, byte * input, int len)
{
register word32 r3, r4, r5;
word32 r6;
int i;
if (len == 0)
return;
r3 = wake_key->r[0];
r4 = wake_key->r[1];
r5 = wake_key->r[2];
r6 = wake_key->r[3];
#ifdef USE_IV
if (wake_key->started == 0) {
wake_key->started = 1;
_mcrypt_encrypt(wake_key, (byte *) & wake_key->iv,
wake_key->ivsize);
wake_key->r[0] = r3;
wake_key->r[1] = r4;
wake_key->r[2] = r5;
wake_key->r[3] = r6;
_mcrypt_decrypt(wake_key, (byte *) & wake_key->iv,
wake_key->ivsize);
}
#endif
for (i = 0; i < len; i++) {
/* R1 = V[n] */
((byte *) & r1)[counter] = input[i];
/* R2 = V[n] = V[n] ^ R6 */
/* R2 is ignored */
input[i] ^= ((byte *) & r6)[counter];
counter++;
if (counter == 4) {
counter = 0;
#ifdef WORDS_BIGENDIAN
r1 = byteswap32(r1);
r6 = byteswap32(r6);
#endif
r3 = M(r3, r1);
r4 = M(r4, r3);
r5 = M(r5, r4);
r6 = M(r6, r5);
#ifdef WORDS_BIGENDIAN
r6 = byteswap32(r6);
#endif
}
}
wake_key->r[0] = r3;
wake_key->r[1] = r4;
wake_key->r[2] = r5;
wake_key->r[3] = r6;
}
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return sizeof(WAKE_KEY);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_algo_iv_size()
{
#ifdef USE_IV
return 32;
#else
return 0;
#endif
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 0;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 32;
}
static const int key_sizes[] = { 32 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "WAKE";
}
#define CIPHER "434d575db053acfe6e4076f05298bedbd5f4f000be555d029b1367cffc7cd51bba61c76aa17da3530fb7d9"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
unsigned char *keyword;
unsigned char plaintext[43];
unsigned char ciphertext[43];
int blocksize = 43, j;
void *key, *key2;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = (j * 5 + 10) & 0xff;
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = (j + 5) % 0xff;
}
key = malloc(_mcrypt_get_size());
key2 = malloc(_mcrypt_get_size());
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size(),
NULL, 0);
_mcrypt_encrypt(key, (void *) ciphertext, blocksize);
free(key);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
free(key2);
return -1;
}
_mcrypt_set_key(key2, (void *) keyword, _mcrypt_get_key_size(),
NULL, 0);
free(keyword);
_mcrypt_decrypt(key2, (void *) ciphertext, blocksize);
free(key2);
if (memcmp(ciphertext, plaintext, blocksize) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif
@@ -0,0 +1,10 @@
typedef struct wake_key {
word32 t[257];
word32 r[4];
int counter;
word32 tmp; /* used as r1 or r2 */
int started;
word32 iv[8];
int ivsize;
} WAKE_KEY;
@@ -0,0 +1,240 @@
/**********************************************************
TEA - Tiny Encryption Algorithm
Feistel cipher by David Wheeler & Roger M. Needham
(extended version)
**********************************************************/
/* $Id: xtea.c,v 1.13 2003/01/19 17:48:27 nmav Exp $ */
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*/
#include <libdefs.h>
#include <mcrypt_modules.h>
#define _mcrypt_set_key xtea_LTX__mcrypt_set_key
#define _mcrypt_encrypt xtea_LTX__mcrypt_encrypt
#define _mcrypt_decrypt xtea_LTX__mcrypt_decrypt
#define _mcrypt_get_size xtea_LTX__mcrypt_get_size
#define _mcrypt_get_block_size xtea_LTX__mcrypt_get_block_size
#define _is_block_algorithm xtea_LTX__is_block_algorithm
#define _mcrypt_get_key_size xtea_LTX__mcrypt_get_key_size
#define _mcrypt_get_supported_key_sizes xtea_LTX__mcrypt_get_supported_key_sizes
#define _mcrypt_get_algorithms_name xtea_LTX__mcrypt_get_algorithms_name
#define _mcrypt_self_test xtea_LTX__mcrypt_self_test
#define _mcrypt_algorithm_version xtea_LTX__mcrypt_algorithm_version
#define ROUNDS 32
#define DELTA 0x9e3779b9 /* sqr(5)-1 * 2^31 */
/**********************************************************
Input values: k[4] 128-bit key
v[2] 64-bit plaintext block
Output values: v[2] 64-bit ciphertext block
**********************************************************/
WIN32DLL_DEFINE
int _mcrypt_set_key(word32 * k, word32 * input_key, int len)
{
k[0] = 0;
k[2] = 0;
k[1] = 0;
k[3] = 0;
memmove(k, input_key, len);
return 0;
}
WIN32DLL_DEFINE void _mcrypt_encrypt(word32 * k, word32 * v)
{
#ifdef WORDS_BIGENDIAN
word32 y = v[0], z = v[1];
#else
word32 y = byteswap32(v[0]), z = byteswap32(v[1]);
#endif
word32 limit, sum = 0;
int N = ROUNDS;
limit = DELTA * N;
#ifdef WORDS_BIGENDIAN
while (sum != limit) {
y += (((z << 4) ^ (z >> 5)) + z) ^ (sum + k[sum & 3]);
sum += DELTA;
z += (((y << 4) ^ (y >> 5)) + y) ^ (sum +
k[(sum >> 11) & 3]);
}
#else
while (sum != limit) {
y += (((z << 4) ^ (z >> 5)) + z) ^ (sum +
byteswap32(k
[sum & 3]));
sum += DELTA;
z += (((y << 4) ^ (y >> 5)) + y) ^ (sum +
byteswap32(k
[(sum >>
11) &
3]));
}
#endif
#ifdef WORDS_BIGENDIAN
v[0] = y;
v[1] = z;
#else
v[0] = byteswap32(y);
v[1] = byteswap32(z);
#endif
}
WIN32DLL_DEFINE void _mcrypt_decrypt(word32 * k, word32 * v)
{
#ifdef WORDS_BIGENDIAN
word32 y = v[0], z = v[1];
#else
word32 y = byteswap32(v[0]), z = byteswap32(v[1]);
#endif
word32 limit, sum = 0;
int N = (-ROUNDS);
limit = DELTA * N;
#ifdef WORDS_BIGENDIAN
sum = DELTA * (-N);
while (sum) {
z -= (((y << 4) ^ (y >> 5)) + y) ^ (sum +
k[(sum >> 11) & 3]);
sum -= DELTA;
y -= (((z << 4) ^ (z >> 5)) + z) ^ (sum + k[sum & 3]);
#else
sum = DELTA * (-N);
while (sum) {
z -= (((y << 4) ^ (y >> 5)) + y) ^ (sum +
byteswap32(k
[(sum >>
11) &
3]));
sum -= DELTA;
y -= (((z << 4) ^ (z >> 5)) + z) ^ (sum +
byteswap32(k
[sum & 3]));
#endif
}
#ifdef WORDS_BIGENDIAN
v[0] = y;
v[1] = z;
#else
v[0] = byteswap32(y);
v[1] = byteswap32(z);
#endif
}
/*
void _mcrypt_encrypt(word32 * k, word32 * v)
{
_mcrypt_tean(k, v, ROUNDS);
}
void _mcrypt_decrypt(word32 * k, word32 * v)
{
_mcrypt_tean(k, v, -ROUNDS);
}
*/
WIN32DLL_DEFINE int _mcrypt_get_size()
{
return 4 * sizeof(word32);
}
WIN32DLL_DEFINE int _mcrypt_get_block_size()
{
return 8;
}
WIN32DLL_DEFINE int _is_block_algorithm()
{
return 1;
}
WIN32DLL_DEFINE int _mcrypt_get_key_size()
{
return 16;
}
static const int key_sizes[] = { 16 };
WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
{
*len = sizeof(key_sizes)/sizeof(int);
return key_sizes;
}
WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
{
return "xTEA";
}
#define CIPHER "f61e7ff6da7cdb27"
WIN32DLL_DEFINE int _mcrypt_self_test()
{
char *keyword;
unsigned char plaintext[16];
unsigned char ciphertext[16];
int blocksize = _mcrypt_get_block_size(), j;
void *key;
unsigned char cipher_tmp[200];
keyword = calloc(1, _mcrypt_get_key_size());
if (keyword == NULL)
return -1;
for (j = 0; j < _mcrypt_get_key_size(); j++) {
keyword[j] = ((j * 2 + 10) % 256);
}
for (j = 0; j < blocksize; j++) {
plaintext[j] = j % 256;
}
key = malloc(_mcrypt_get_size());
if (key == NULL)
return -1;
memcpy(ciphertext, plaintext, blocksize);
_mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
free(keyword);
_mcrypt_encrypt(key, (void *) ciphertext);
for (j = 0; j < blocksize; j++) {
sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
ciphertext[j]);
}
if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
printf("failed compatibility\n");
printf("Expected: %s\nGot: %s\n", CIPHER,
(char *) cipher_tmp);
free(key);
return -1;
}
_mcrypt_decrypt(key, (void *) ciphertext);
free(key);
if (strcmp(ciphertext, plaintext) != 0) {
printf("failed internally\n");
return -1;
}
return 0;
}
WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
{
return 20010801;
}
#ifdef WIN32
# ifdef USE_LTDL
WIN32DLL_DEFINE int main (void)
{
/* empty main function to avoid linker error (see cygwin FAQ) */
}
# endif
#endif