Basic libgcrypt usage... no idea if it works, but it has to be better than nothing right?

This commit is contained in:
Catatonic Prime 2016-12-25 03:24:06 +00:00
parent 0c2e02135d
commit 43e3040062
7 changed files with 43 additions and 1380 deletions

View file

@ -3,7 +3,7 @@
# #
OPTS=-I. -O3 OPTS=-I. -O3
# -Wall -g -pedantic # -Wall -g -pedantic
LIBS=-lm LIBS=-lm -lgcrypt
BINDIR = /bin BINDIR = /bin
MANDIR ?= /man/man1/ MANDIR ?= /man/man1/
DATADIR ?= /etc DATADIR ?= /etc
@ -20,7 +20,7 @@ SRC = hydra-vnc.c hydra-pcnfs.c hydra-rexec.c hydra-nntp.c hydra-socks5.c \
hydra-oracle-sid.c hydra-http-proxy.c hydra-http-form.c hydra-irc.c \ hydra-oracle-sid.c hydra-http-proxy.c hydra-http-form.c hydra-irc.c \
hydra-rdp.c hydra-s7-300.c hydra-redis.c hydra-adam6500.c \ hydra-rdp.c hydra-s7-300.c hydra-redis.c hydra-adam6500.c \
crc32.c d3des.c bfg.c ntlm.c sasl.c hmacmd5.c hydra-mod.c hydra-rtsp.c hydra-time.c hydra-rpcap.c \ crc32.c d3des.c bfg.c ntlm.c sasl.c hmacmd5.c hydra-mod.c hydra-rtsp.c hydra-time.c hydra-rpcap.c \
hydra-radmin2.c twofish.c hydra-radmin2.c
OBJ = hydra-vnc.o hydra-pcnfs.o hydra-rexec.o hydra-nntp.o hydra-socks5.o \ OBJ = hydra-vnc.o hydra-pcnfs.o hydra-rexec.o hydra-nntp.o hydra-socks5.o \
hydra-telnet.o hydra-cisco.o hydra-http.o hydra-ftp.o hydra-imap.o \ hydra-telnet.o hydra-cisco.o hydra-http.o hydra-ftp.o hydra-imap.o \
hydra-pop3.o hydra-smb.o hydra-icq.o hydra-cisco-enable.o hydra-ldap.o \ hydra-pop3.o hydra-smb.o hydra-icq.o hydra-cisco-enable.o hydra-ldap.o \
@ -32,7 +32,7 @@ OBJ = hydra-vnc.o hydra-pcnfs.o hydra-rexec.o hydra-nntp.o hydra-socks5.o \
hydra-http-proxy.o hydra-http-form.o hydra-irc.o hydra-redis.o \ hydra-http-proxy.o hydra-http-form.o hydra-irc.o hydra-redis.o \
hydra-rdp.o hydra-s7-300.c hydra-adam6500.o \ hydra-rdp.o hydra-s7-300.c hydra-adam6500.o \
crc32.o d3des.o bfg.o ntlm.o sasl.o hmacmd5.o hydra-mod.o hydra-rtsp.o hydra-time.o hydra-rpcap.o \ crc32.o d3des.o bfg.o ntlm.o sasl.o hmacmd5.o hydra-mod.o hydra-rtsp.o hydra-time.o hydra-rpcap.o \
hydra-radmin2.o twofish.o hydra-radmin2.o
BINS = hydra pw-inspector BINS = hydra pw-inspector
EXTRA_DIST = README README.arm README.palm CHANGES TODO INSTALL LICENSE \ EXTRA_DIST = README README.arm README.palm CHANGES TODO INSTALL LICENSE \

View file

@ -2,17 +2,10 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include <openssl/md5.h> #include <openssl/md5.h>
#include <gcrypt.h>
extern char *HYDRA_EXIT; extern char *HYDRA_EXIT;
//Twofish references
#include "twofish/aes.h"
extern int makeKey(keyInstance *key, BYTE direction, int keyLen,CONST char *keyMaterial);
extern int cipherInit(cipherInstance *cipher, BYTE mode,CONST char *IV);
extern int blockEncrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input, int inputLen, BYTE *outBuffer);
extern int blockDecrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input, int inputLen, BYTE *outBuffer);
//RAdmin 2.x //RAdmin 2.x
struct rmessage { struct rmessage {
@ -185,18 +178,20 @@ void service_radmin2(char *ip, int sp, unsigned char options, char *miscptr, FIL
char password[101]; char password[101];
unsigned char rawkey[16]; unsigned char rawkey[16];
char pkey[33]; char pkey[33];
char *IV = "FEDCBA9876543210A39D4A18F85B4A52"; char *IV = "\xFE\xDC\xBA\x98\x76\x54\x32\x10\xA3\x9D\x4A\x18\xF8\x5B\x4A\x52";
unsigned char encrypted[32]; unsigned char encrypted[32];
gcry_error_t err;
gcry_cipher_hd_t cipher;
//Initialization nonsense. //Initialization nonsense.
MD5_CTX md5c; MD5_CTX md5c;
keyInstance key;
cipherInstance cipher;
if(port != 0) { if(port != 0) {
myport = port; myport = port;
} }
gcry_check_version(NULL);
memset(buffer, 0x00, sizeof(buffer)); memset(buffer, 0x00, sizeof(buffer));
memset(pkey, 0x00, 33); memset(pkey, 0x00, 33);
memset(encrypted, 0x00, 32); memset(encrypted, 0x00, 32);
@ -263,28 +258,48 @@ void service_radmin2(char *ip, int sp, unsigned char options, char *miscptr, FIL
} }
//3) Send challenge solution. //3) Send challenge solution.
//3.a) generate a new message from the buffer //3.a) generate a new message from the buffer
msg = buffer2message(buffer); msg = buffer2message(buffer);
//3.b) encrypt data received using pkey & known IV //3.b) encrypt data received using pkey & known IV
index = makeKey(&key, DIR_ENCRYPT, 128, pkey); err= gcry_cipher_open(&cipher, GCRY_CIPHER_TWOFISH128, GCRY_CIPHER_MODE_CBC, 0);
if(index != TRUE) { if(err) {
hydra_report(stderr, "Error: Child with pid %d terminating, make key error (%08x)\n", (int)getpid(), index); hydra_report(stderr, "Error: Child with pid %d terminating, gcry_cipher_open error (%08x)\n", (int)getpid(), index);
hydra_child_exit(1); hydra_child_exit(1);
} }
err = gcry_cipher_setkey(cipher, pkey, 128);
if(err) {
hydra_report(stderr, "Error: Child with pid %d terminating, gcry_cipher_setkey error (%08x)\n", (int)getpid(), index);
hydra_child_exit(1);
}
err = gcry_cipher_setiv(cipher, IV, 128);
if(err) {
hydra_report(stderr, "Error: Child with pid %d terminating, gcry_cipher_setiv error (%08x)\n", (int)getpid(), index);
hydra_child_exit(1);
}
err = gcry_cipher_encrypt(cipher, encrypted, 32, msg->data, 32);
if(err) {
hydra_report(stderr, "Error: Child with pid %d terminating, gcry_cipher_encrypt error (%08x)\n", (int)getpid(), index);
hydra_child_exit(1);
}
gcry_cipher_close(cipher);
// index = makeKey(&key, DIR_ENCRYPT, 128, pkey);
// if(index != TRUE) {
// hydra_report(stderr, "Error: Child with pid %d terminating, make key error (%08x)\n", (int)getpid(), index);
// hydra_child_exit(1);
// }
index = cipherInit(&cipher, MODE_CBC, IV); // index = cipherInit(&cipher, MODE_CBC, IV);
if(index != TRUE) { // if(index != TRUE) {
hydra_report(stderr, "Error: Child with pid %d terminating, cipher init error(%08x)\n", (int)getpid(), index); // hydra_report(stderr, "Error: Child with pid %d terminating, cipher init error(%08x)\n", (int)getpid(), index);
hydra_child_exit(1); // hydra_child_exit(1);
} // }
index = blockEncrypt(&cipher, &key, msg->data, 32 * 8, encrypted); // index = blockEncrypt(&cipher, &key, msg->data, 32 * 8, encrypted);
if(index <= 0) { // if(index <= 0) {
hydra_report(stderr, "Error: Child with pid %d terminating, encrypt error(%08x)\n", (int)getpid(), index); // hydra_report(stderr, "Error: Child with pid %d terminating, encrypt error(%08x)\n", (int)getpid(), index);
hydra_child_exit(1); // hydra_child_exit(1);
} // }
//3.c) half sum - this is the solution to the challenge. //3.c) half sum - this is the solution to the challenge.
for(index=0; index < 16; index++) { for(index=0; index < 16; index++) {

704
twofish.c
View file

@ -1,704 +0,0 @@
/***************************************************************************
TWOFISH.C -- C API calls for TWOFISH AES submission
Submitters:
Bruce Schneier, Counterpane Systems
Doug Whiting, Hi/fn
John Kelsey, Counterpane Systems
Chris Hall, Counterpane Systems
David Wagner, UC Berkeley
Code Author: Doug Whiting, Hi/fn
Version 1.00 April 1998
Copyright 1998, Hi/fn and Counterpane Systems. All rights reserved.
Notes:
* Pedagogical version (non-optimized)
* Tab size is set to 4 characters in this file
***************************************************************************/
#include "twofish/aes.h"
#include "twofish/table.h"
/*
+*****************************************************************************
* Constants/Macros/Tables
-****************************************************************************/
#define VALIDATE_PARMS 1 /* nonzero --> check all parameters */
#define FEISTEL 0 /* nonzero --> use Feistel version (slow) */
int tabEnable=0; /* are we gathering stats? */
BYTE tabUsed[256]; /* one bit per table */
#if FEISTEL
CONST char *moduleDescription="Pedagogical C code (Feistel)";
#else
CONST char *moduleDescription="Pedagogical C code";
#endif
CONST char *modeString = "";
#define P0_USED 0x01
#define P1_USED 0x02
#define B0_USED 0x04
#define B1_USED 0x08
#define B2_USED 0x10
#define B3_USED 0x20
#define ALL_USED 0x3F
/* number of rounds for various key sizes: 128, 192, 256 */
int numRounds[4]= {0,ROUNDS_128,ROUNDS_192,ROUNDS_256};
#ifndef DEBUG
#ifdef GetCodeSize
#define DEBUG 1 /* force debug */
#endif
#endif
#include "twofish/debug.h" /* debug display macros */
#ifdef GetCodeSize
extern DWORD Here(DWORD x); /* return caller's address! */
DWORD TwofishCodeStart(void) { return Here(0); };
#endif
/*
+*****************************************************************************
*
* Function Name: TableOp
*
* Function: Handle table use checking
*
* Arguments: op = what to do (see TAB_* defns in AES.H)
*
* Return: TRUE --> done (for TAB_QUERY)
*
* Notes: This routine is for use in generating the tables KAT file.
*
-****************************************************************************/
int TableOp(int op)
{
static int queryCnt=0;
int i;
switch (op)
{
case TAB_DISABLE:
tabEnable=0;
break;
case TAB_ENABLE:
tabEnable=1;
break;
case TAB_RESET:
queryCnt=0;
for (i=0;i<256;i++)
tabUsed[i]=0;
break;
case TAB_QUERY:
queryCnt++;
for (i=0;i<256;i++)
if (tabUsed[i] != ALL_USED)
return FALSE;
if (queryCnt < TAB_MIN_QUERY) /* do a certain minimum number */
return FALSE;
break;
}
return TRUE;
}
/*
+*****************************************************************************
*
* Function Name: ParseHexDword
*
* Function: Parse ASCII hex nibbles and fill in key/iv dwords
*
* Arguments: bit = # bits to read
* srcTxt = ASCII source
* d = ptr to dwords to fill in
* dstTxt = where to make a copy of ASCII source
* (NULL ok)
*
* Return: Zero if no error. Nonzero --> invalid hex or length
*
* Notes: Note that the parameter d is a DWORD array, not a byte array.
* This routine is coded to work both for little-endian and big-endian
* architectures. The character stream is interpreted as a LITTLE-ENDIAN
* byte stream, since that is how the Pentium works, but the conversion
* happens automatically below.
*
-****************************************************************************/
int ParseHexDword(int bits,CONST char *srcTxt,DWORD *d,char *dstTxt)
{
int i;
DWORD b;
char c;
#if ALIGN32
char alignDummy[3]; /* keep dword alignment */
#endif
union /* make sure LittleEndian is defined correctly */
{
BYTE b[4];
DWORD d[1];
} v;
v.d[0]=1;
if (v.b[0 ^ ADDR_XOR] != 1) /* sanity check on compile-time switch */
return BAD_ENDIAN;
#if VALIDATE_PARMS
#if ALIGN32
if (((int)d) & 3)
return BAD_ALIGN32;
#endif
#endif
for (i=0;i*32<bits;i++)
d[i]=0; /* first, zero the field */
for (i=0;i*4<bits;i++) /* parse one nibble at a time */
{ /* case out the hexadecimal characters */
c=srcTxt[i];
if (dstTxt) dstTxt[i]=c;
if ((c >= '0') && (c <= '9'))
b=c-'0';
else if ((c >= 'a') && (c <= 'f'))
b=c-'a'+10;
else if ((c >= 'A') && (c <= 'F'))
b=c-'A'+10;
else
return BAD_KEY_MAT; /* invalid hex character */
/* works for big and little endian! */
d[i/8] |= b << (4*((i^1)&7));
}
return 0; /* no error */
}
/*
+*****************************************************************************
*
* Function Name: f32
*
* Function: Run four bytes through keyed S-boxes and apply MDS matrix
*
* Arguments: x = input to f function
* k32 = pointer to key dwords
* keyLen = total key length (k32 --> keyLey/2 bits)
*
* Return: The output of the keyed permutation applied to x.
*
* Notes:
* This function is a keyed 32-bit permutation. It is the major building
* block for the Twofish round function, including the four keyed 8x8
* permutations and the 4x4 MDS matrix multiply. This function is used
* both for generating round subkeys and within the round function on the
* block being encrypted.
*
* This version is fairly slow and pedagogical, although a smartcard would
* probably perform the operation exactly this way in firmware. For
* ultimate performance, the entire operation can be completed with four
* lookups into four 256x32-bit tables, with three dword xors.
*
* The MDS matrix is defined in TABLE.H. To multiply by Mij, just use the
* macro Mij(x).
*
-****************************************************************************/
DWORD f32(DWORD x,CONST DWORD *k32,int keyLen)
{
BYTE b[4];
/* Run each byte thru 8x8 S-boxes, xoring with key byte at each stage. */
/* Note that each byte goes through a different combination of S-boxes.*/
*((DWORD *)b) = Bswap(x); /* make b[0] = LSB, b[3] = MSB */
switch (((keyLen + 63)/64) & 3)
{
case 0: /* 256 bits of key */
b[0] = p8(04)[b[0]] ^ b0(k32[3]);
b[1] = p8(14)[b[1]] ^ b1(k32[3]);
b[2] = p8(24)[b[2]] ^ b2(k32[3]);
b[3] = p8(34)[b[3]] ^ b3(k32[3]);
/* fall thru, having pre-processed b[0]..b[3] with k32[3] */
case 3: /* 192 bits of key */
b[0] = p8(03)[b[0]] ^ b0(k32[2]);
b[1] = p8(13)[b[1]] ^ b1(k32[2]);
b[2] = p8(23)[b[2]] ^ b2(k32[2]);
b[3] = p8(33)[b[3]] ^ b3(k32[2]);
/* fall thru, having pre-processed b[0]..b[3] with k32[2] */
case 2: /* 128 bits of key */
b[0] = p8(00)[p8(01)[p8(02)[b[0]] ^ b0(k32[1])] ^ b0(k32[0])];
b[1] = p8(10)[p8(11)[p8(12)[b[1]] ^ b1(k32[1])] ^ b1(k32[0])];
b[2] = p8(20)[p8(21)[p8(22)[b[2]] ^ b2(k32[1])] ^ b2(k32[0])];
b[3] = p8(30)[p8(31)[p8(32)[b[3]] ^ b3(k32[1])] ^ b3(k32[0])];
}
if (tabEnable)
{ /* we could give a "tighter" bound, but this works acceptably well */
tabUsed[b0(x)] |= (P_00 == 0) ? P0_USED : P1_USED;
tabUsed[b1(x)] |= (P_10 == 0) ? P0_USED : P1_USED;
tabUsed[b2(x)] |= (P_20 == 0) ? P0_USED : P1_USED;
tabUsed[b3(x)] |= (P_30 == 0) ? P0_USED : P1_USED;
tabUsed[b[0] ] |= B0_USED;
tabUsed[b[1] ] |= B1_USED;
tabUsed[b[2] ] |= B2_USED;
tabUsed[b[3] ] |= B3_USED;
}
/* Now perform the MDS matrix multiply inline. */
return ((M00(b[0]) ^ M01(b[1]) ^ M02(b[2]) ^ M03(b[3])) ) ^
((M10(b[0]) ^ M11(b[1]) ^ M12(b[2]) ^ M13(b[3])) << 8) ^
((M20(b[0]) ^ M21(b[1]) ^ M22(b[2]) ^ M23(b[3])) << 16) ^
((M30(b[0]) ^ M31(b[1]) ^ M32(b[2]) ^ M33(b[3])) << 24) ;
}
/*
+*****************************************************************************
*
* Function Name: RS_MDS_Encode
*
* Function: Use (12,8) Reed-Solomon code over GF(256) to produce
* a key S-box dword from two key material dwords.
*
* Arguments: k0 = 1st dword
* k1 = 2nd dword
*
* Return: Remainder polynomial generated using RS code
*
* Notes:
* Since this computation is done only once per reKey per 64 bits of key,
* the performance impact of this routine is imperceptible. The RS code
* chosen has "simple" coefficients to allow smartcard/hardware implementation
* without lookup tables.
*
-****************************************************************************/
DWORD RS_MDS_Encode(DWORD k0,DWORD k1)
{
int i,j;
DWORD r;
for (i=r=0;i<2;i++)
{
r ^= (i) ? k0 : k1; /* merge in 32 more key bits */
for (j=0;j<4;j++) /* shift one byte at a time */
RS_rem(r);
}
return r;
}
/*
+*****************************************************************************
*
* Function Name: reKey
*
* Function: Initialize the Twofish key schedule from key32
*
* Arguments: key = ptr to keyInstance to be initialized
*
* Return: TRUE on success
*
* Notes:
* Here we precompute all the round subkeys, although that is not actually
* required. For example, on a smartcard, the round subkeys can
* be generated on-the-fly using f32()
*
-****************************************************************************/
int reKey(keyInstance *key)
{
int i,k64Cnt;
int keyLen = key->keyLen;
int subkeyCnt = ROUND_SUBKEYS + 2*key->numRounds;
DWORD A,B;
DWORD k32e[MAX_KEY_BITS/64],k32o[MAX_KEY_BITS/64]; /* even/odd key dwords */
#if VALIDATE_PARMS
#if ALIGN32
if ((((int)key) & 3) || (((int)key->key32) & 3))
return BAD_ALIGN32;
#endif
if ((key->keyLen % 64) || (key->keyLen < MIN_KEY_BITS))
return BAD_KEY_INSTANCE;
if (subkeyCnt > TOTAL_SUBKEYS)
return BAD_KEY_INSTANCE;
#endif
k64Cnt=(keyLen+63)/64; /* round up to next multiple of 64 bits */
for (i=0;i<k64Cnt;i++)
{ /* split into even/odd key dwords */
k32e[i]=key->key32[2*i ];
k32o[i]=key->key32[2*i+1];
/* compute S-box keys using (12,8) Reed-Solomon code over GF(256) */
key->sboxKeys[k64Cnt-1-i]=RS_MDS_Encode(k32e[i],k32o[i]); /* reverse order */
}
for (i=0;i<subkeyCnt/2;i++) /* compute round subkeys for PHT */
{
A = f32(i*SK_STEP ,k32e,keyLen); /* A uses even key dwords */
B = f32(i*SK_STEP+SK_BUMP,k32o,keyLen); /* B uses odd key dwords */
B = ROL(B,8);
key->subKeys[2*i ] = A+ B; /* combine with a PHT */
key->subKeys[2*i+1] = ROL(A+2*B,SK_ROTL);
}
DebugDumpKey(key);
return TRUE;
}
/*
+*****************************************************************************
*
* Function Name: makeKey
*
* Function: Initialize the Twofish key schedule
*
* Arguments: key = ptr to keyInstance to be initialized
* direction = DIR_ENCRYPT or DIR_DECRYPT
* keyLen = # bits of key text at *keyMaterial
* keyMaterial = ptr to hex ASCII chars representing key bits
*
* Return: TRUE on success
* else error code (e.g., BAD_KEY_DIR)
*
* Notes:
* This parses the key bits from keyMaterial. No crypto stuff happens here.
* The function reKey() is called to actually build the key schedule after
* the keyMaterial has been parsed.
*
-****************************************************************************/
int makeKey(keyInstance *key, BYTE direction, int keyLen,CONST char *keyMaterial)
{
int i;
#if VALIDATE_PARMS /* first, sanity check on parameters */
if (key == NULL)
return BAD_KEY_INSTANCE;/* must have a keyInstance to initialize */
if ((direction != DIR_ENCRYPT) && (direction != DIR_DECRYPT))
return BAD_KEY_DIR; /* must have valid direction */
if ((keyLen > MAX_KEY_BITS) || (keyLen < 8))
return BAD_KEY_MAT; /* length must be valid */
key->keySig = VALID_SIG; /* show that we are initialized */
#if ALIGN32
if ((((int)key) & 3) || (((int)key->key32) & 3))
return BAD_ALIGN32;
#endif
#endif
key->direction = direction; /* set our cipher direction */
key->keyLen = (keyLen+63) & ~63; /* round up to multiple of 64 */
key->numRounds = numRounds[(keyLen-1)/64];
for (i=0;i<MAX_KEY_BITS/32;i++) /* zero unused bits */
key->key32[i]=0;
key->keyMaterial[MAX_KEY_SIZE]=0; /* terminate ASCII string */
if ((keyMaterial == NULL) || (keyMaterial[0]==0))
return TRUE; /* allow a "dummy" call */
if (ParseHexDword(keyLen,keyMaterial,key->key32,key->keyMaterial))
return BAD_KEY_MAT;
return reKey(key); /* generate round subkeys */
}
/*
+*****************************************************************************
*
* Function Name: cipherInit
*
* Function: Initialize the Twofish cipher in a given mode
*
* Arguments: cipher = ptr to cipherInstance to be initialized
* mode = MODE_ECB, MODE_CBC, or MODE_CFB1
* IV = ptr to hex ASCII test representing IV bytes
*
* Return: TRUE on success
* else error code (e.g., BAD_CIPHER_MODE)
*
-****************************************************************************/
int cipherInit(cipherInstance *cipher, BYTE mode,CONST char *IV)
{
int i;
#if VALIDATE_PARMS /* first, sanity check on parameters */
if (cipher == NULL)
return BAD_PARAMS; /* must have a cipherInstance to initialize */
if ((mode != MODE_ECB) && (mode != MODE_CBC) && (mode != MODE_CFB1))
return BAD_CIPHER_MODE; /* must have valid cipher mode */
cipher->cipherSig = VALID_SIG;
#if ALIGN32
if ((((int)cipher) & 3) || (((int)cipher->IV) & 3) || (((int)cipher->iv32) & 3))
return BAD_ALIGN32;
#endif
#endif
if ((mode != MODE_ECB) && (IV)) /* parse the IV */
{
if (ParseHexDword(BLOCK_SIZE,IV,cipher->iv32,NULL))
return BAD_IV_MAT;
for (i=0;i<BLOCK_SIZE/32;i++) /* make byte-oriented copy for CFB1 */
((DWORD *)cipher->IV)[i] = Bswap(cipher->iv32[i]);
}
cipher->mode = mode;
return TRUE;
}
/*
+*****************************************************************************
*
* Function Name: blockEncrypt
*
* Function: Encrypt block(s) of data using Twofish
*
* Arguments: cipher = ptr to already initialized cipherInstance
* key = ptr to already initialized keyInstance
* input = ptr to data blocks to be encrypted
* inputLen = # bits to encrypt (multiple of blockSize)
* outBuffer = ptr to where to put encrypted blocks
*
* Return: # bits ciphered (>= 0)
* else error code (e.g., BAD_CIPHER_STATE, BAD_KEY_MATERIAL)
*
* Notes: The only supported block size for ECB/CBC modes is BLOCK_SIZE bits.
* If inputLen is not a multiple of BLOCK_SIZE bits in those modes,
* an error BAD_INPUT_LEN is returned. In CFB1 mode, all block
* sizes can be supported.
*
-****************************************************************************/
int blockEncrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input,
int inputLen, BYTE *outBuffer)
{
int i,n,r; /* loop variables */
DWORD x[BLOCK_SIZE/32]; /* block being encrypted */
DWORD t0,t1,tmp; /* temp variables */
int rounds=key->numRounds; /* number of rounds */
BYTE bit,ctBit,carry; /* temps for CFB */
#if ALIGN32
BYTE alignDummy; /* keep 32-bit variable alignment on stack */
#endif
#if VALIDATE_PARMS
if ((cipher == NULL) || (cipher->cipherSig != VALID_SIG))
return BAD_CIPHER_STATE;
if ((key == NULL) || (key->keySig != VALID_SIG))
return BAD_KEY_INSTANCE;
if ((rounds < 2) || (rounds > MAX_ROUNDS) || (rounds&1))
return BAD_KEY_INSTANCE;
if ((cipher->mode != MODE_CFB1) && (inputLen % BLOCK_SIZE))
return BAD_INPUT_LEN;
#if ALIGN32
if ( (((int)cipher) & 3) || (((int)key ) & 3) ||
(((int)input ) & 3) || (((int)outBuffer) & 3))
return BAD_ALIGN32;
#endif
#endif
if (cipher->mode == MODE_CFB1)
{ /* use recursion here to handle CFB, one block at a time */
cipher->mode = MODE_ECB; /* do encryption in ECB */
for (n=0;n<inputLen;n++)
{
blockEncrypt(cipher,key,cipher->IV,BLOCK_SIZE,(BYTE *)x);
bit = 0x80 >> (n & 7);/* which bit position in byte */
ctBit = (input[n/8] & bit) ^ ((((BYTE *) x)[0] & 0x80) >> (n&7));
outBuffer[n/8] = (outBuffer[n/8] & ~ bit) | ctBit;
carry = ctBit >> (7 - (n&7));
for (i=BLOCK_SIZE/8-1;i>=0;i--)
{
bit = cipher->IV[i] >> 7; /* save next "carry" from shift */
cipher->IV[i] = (cipher->IV[i] << 1) ^ carry;
carry = bit;
}
}
cipher->mode = MODE_CFB1; /* restore mode for next time */
return inputLen;
}
/* here for ECB, CBC modes */
for (n=0;n<inputLen;n+=BLOCK_SIZE,input+=BLOCK_SIZE/8,outBuffer+=BLOCK_SIZE/8)
{
#ifdef DEBUG
DebugDump(input,"\n",-1,0,0,0,1);
if (cipher->mode == MODE_CBC)
DebugDump(cipher->iv32,"",IV_ROUND,0,0,0,0);
#endif
for (i=0;i<BLOCK_SIZE/32;i++) /* copy in the block, add whitening */
{
x[i]=Bswap(((DWORD *)input)[i]) ^ key->subKeys[INPUT_WHITEN+i];
if (cipher->mode == MODE_CBC)
x[i] ^= Bswap(cipher->iv32[i]);
}
DebugDump(x,"",0,0,0,0,0);
for (r=0;r<rounds;r++) /* main Twofish encryption loop */
{
#if FEISTEL
t0 = f32(ROR(x[0], (r+1)/2),key->sboxKeys,key->keyLen);
t1 = f32(ROL(x[1],8+(r+1)/2),key->sboxKeys,key->keyLen);
/* PHT, round keys */
x[2]^= ROL(t0 + t1 + key->subKeys[ROUND_SUBKEYS+2*r ], r /2);
x[3]^= ROR(t0 + 2*t1 + key->subKeys[ROUND_SUBKEYS+2*r+1],(r+2) /2);
DebugDump(x,"",r+1,2*(r&1),1,1,0);
#else
t0 = f32( x[0] ,key->sboxKeys,key->keyLen);
t1 = f32(ROL(x[1],8),key->sboxKeys,key->keyLen);
x[3] = ROL(x[3],1);
x[2]^= t0 + t1 + key->subKeys[ROUND_SUBKEYS+2*r ]; /* PHT, round keys */
x[3]^= t0 + 2*t1 + key->subKeys[ROUND_SUBKEYS+2*r+1];
x[2] = ROR(x[2],1);
DebugDump(x,"",r+1,2*(r&1),0,1,0);/* make format compatible with optimized code */
#endif
if (r < rounds-1) /* swap for next round */
{
tmp = x[0]; x[0]= x[2]; x[2] = tmp;
tmp = x[1]; x[1]= x[3]; x[3] = tmp;
}
}
#if FEISTEL
x[0] = ROR(x[0],8); /* "final permutation" */
x[1] = ROL(x[1],8);
x[2] = ROR(x[2],8);
x[3] = ROL(x[3],8);
#endif
for (i=0;i<BLOCK_SIZE/32;i++) /* copy out, with whitening */
{
((DWORD *)outBuffer)[i] = Bswap(x[i] ^ key->subKeys[OUTPUT_WHITEN+i]);
if (cipher->mode == MODE_CBC)
cipher->iv32[i] = ((DWORD *)outBuffer)[i];
}
#ifdef DEBUG
DebugDump(outBuffer,"",rounds+1,0,0,0,1);
if (cipher->mode == MODE_CBC)
DebugDump(cipher->iv32,"",IV_ROUND,0,0,0,0);
#endif
}
return inputLen;
}
/*
+*****************************************************************************
*
* Function Name: blockDecrypt
*
* Function: Decrypt block(s) of data using Twofish
*
* Arguments: cipher = ptr to already initialized cipherInstance
* key = ptr to already initialized keyInstance
* input = ptr to data blocks to be decrypted
* inputLen = # bits to encrypt (multiple of blockSize)
* outBuffer = ptr to where to put decrypted blocks
*
* Return: # bits ciphered (>= 0)
* else error code (e.g., BAD_CIPHER_STATE, BAD_KEY_MATERIAL)
*
* Notes: The only supported block size for ECB/CBC modes is BLOCK_SIZE bits.
* If inputLen is not a multiple of BLOCK_SIZE bits in those modes,
* an error BAD_INPUT_LEN is returned. In CFB1 mode, all block
* sizes can be supported.
*
-****************************************************************************/
int blockDecrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input,
int inputLen, BYTE *outBuffer)
{
int i,n,r; /* loop counters */
DWORD x[BLOCK_SIZE/32]; /* block being encrypted */
DWORD t0,t1; /* temp variables */
int rounds=key->numRounds; /* number of rounds */
BYTE bit,ctBit,carry; /* temps for CFB */
#if ALIGN32
BYTE alignDummy; /* keep 32-bit variable alignment on stack */
#endif
#if VALIDATE_PARMS
if ((cipher == NULL) || (cipher->cipherSig != VALID_SIG))
return BAD_CIPHER_STATE;
if ((key == NULL) || (key->keySig != VALID_SIG))
return BAD_KEY_INSTANCE;
if ((rounds < 2) || (rounds > MAX_ROUNDS) || (rounds&1))
return BAD_KEY_INSTANCE;
if ((cipher->mode != MODE_CFB1) && (inputLen % BLOCK_SIZE))
return BAD_INPUT_LEN;
#if ALIGN32
if ( (((int)cipher) & 3) || (((int)key ) & 3) ||
(((int)input) & 3) || (((int)outBuffer) & 3))
return BAD_ALIGN32;
#endif
#endif
if (cipher->mode == MODE_CFB1)
{ /* use blockEncrypt here to handle CFB, one block at a time */
cipher->mode = MODE_ECB; /* do encryption in ECB */
for (n=0;n<inputLen;n++)
{
blockEncrypt(cipher,key,cipher->IV,BLOCK_SIZE,(BYTE *)x);
bit = 0x80 >> (n & 7);
ctBit = input[n/8] & bit;
outBuffer[n/8] = (outBuffer[n/8] & ~ bit) |
(ctBit ^ ((((BYTE *) x)[0] & 0x80) >> (n&7)));
carry = ctBit >> (7 - (n&7));
for (i=BLOCK_SIZE/8-1;i>=0;i--)
{
bit = cipher->IV[i] >> 7; /* save next "carry" from shift */
cipher->IV[i] = (cipher->IV[i] << 1) ^ carry;
carry = bit;
}
}
cipher->mode = MODE_CFB1; /* restore mode for next time */
return inputLen;
}
/* here for ECB, CBC modes */
for (n=0;n<inputLen;n+=BLOCK_SIZE,input+=BLOCK_SIZE/8,outBuffer+=BLOCK_SIZE/8)
{
DebugDump(input,"\n",rounds+1,0,0,0,1);
for (i=0;i<BLOCK_SIZE/32;i++) /* copy in the block, add whitening */
x[i]=Bswap(((DWORD *)input)[i]) ^ key->subKeys[OUTPUT_WHITEN+i];
for (r=rounds-1;r>=0;r--) /* main Twofish decryption loop */
{
t0 = f32( x[0] ,key->sboxKeys,key->keyLen);
t1 = f32(ROL(x[1],8),key->sboxKeys,key->keyLen);
DebugDump(x,"",r+1,2*(r&1),0,1,0);/* make format compatible with optimized code */
x[2] = ROL(x[2],1);
x[2]^= t0 + t1 + key->subKeys[ROUND_SUBKEYS+2*r ]; /* PHT, round keys */
x[3]^= t0 + 2*t1 + key->subKeys[ROUND_SUBKEYS+2*r+1];
x[3] = ROR(x[3],1);
if (r) /* unswap, except for last round */
{
t0 = x[0]; x[0]= x[2]; x[2] = t0;
t1 = x[1]; x[1]= x[3]; x[3] = t1;
}
}
DebugDump(x,"",0,0,0,0,0);/* make final output match encrypt initial output */
for (i=0;i<BLOCK_SIZE/32;i++) /* copy out, with whitening */
{
x[i] ^= key->subKeys[INPUT_WHITEN+i];
if (cipher->mode == MODE_CBC)
{
x[i] ^= Bswap(cipher->iv32[i]);
cipher->iv32[i] = ((DWORD *)input)[i];
}
((DWORD *)outBuffer)[i] = Bswap(x[i]);
}
DebugDump(outBuffer,"",-1,0,0,0,1);
}
return inputLen;
}
#ifdef GetCodeSize
DWORD TwofishCodeSize(void) { return Here(0)-TwofishCodeStart(); };
#endif

View file

@ -1,268 +0,0 @@
/* aes.h */
/* ---------- See examples at end of this file for typical usage -------- */
/* AES Cipher header file for ANSI C Submissions
Lawrence E. Bassham III
Computer Security Division
National Institute of Standards and Technology
This sample is to assist implementers developing to the
Cryptographic API Profile for AES Candidate Algorithm Submissions.
Please consult this document as a cross-reference.
ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE
MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH
THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS
CANNOT BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO
INCLUDE IMPLEMENTATION SPECIFIC INFORMATION.
*/
/* Includes:
Standard include files
*/
#include <stdio.h>
#include "platform.h" /* platform-specific defines */
/* Defines:
Add any additional defines you need
*/
#define DIR_ENCRYPT 0 /* Are we encrpyting? */
#define DIR_DECRYPT 1 /* Are we decrpyting? */
#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
#define TRUE 1
#define FALSE 0
#define BAD_KEY_DIR -1 /* Key direction is invalid (unknown value) */
#define BAD_KEY_MAT -2 /* Key material not of correct length */
#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */
#define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */
#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */
/* CHANGE POSSIBLE: inclusion of algorithm specific defines */
/* TWOFISH specific definitions */
#define MAX_KEY_SIZE 64 /* # of ASCII chars needed to represent a key */
#define MAX_IV_SIZE 16 /* # of bytes needed to represent an IV */
#define BAD_INPUT_LEN -6 /* inputLen not a multiple of block size */
#define BAD_PARAMS -7 /* invalid parameters */
#define BAD_IV_MAT -8 /* invalid IV text */
#define BAD_ENDIAN -9 /* incorrect endianness define */
#define BAD_ALIGN32 -10 /* incorrect 32-bit alignment */
#define BLOCK_SIZE 128 /* number of bits per block */
#define MAX_ROUNDS 16 /* max # rounds (for allocating subkey array) */
#define ROUNDS_128 16 /* default number of rounds for 128-bit keys*/
#define ROUNDS_192 16 /* default number of rounds for 192-bit keys*/
#define ROUNDS_256 16 /* default number of rounds for 256-bit keys*/
#define MAX_KEY_BITS 256 /* max number of bits of key */
#define MIN_KEY_BITS 128 /* min number of bits of key (zero pad) */
#define VALID_SIG 0x48534946 /* initialization signature ('FISH') */
#define MCT_OUTER 400 /* MCT outer loop */
#define MCT_INNER 10000 /* MCT inner loop */
#define REENTRANT 1 /* nonzero forces reentrant code (slightly slower) */
#define INPUT_WHITEN 0 /* subkey array indices */
#define OUTPUT_WHITEN ( INPUT_WHITEN + BLOCK_SIZE/32)
#define ROUND_SUBKEYS (OUTPUT_WHITEN + BLOCK_SIZE/32) /* use 2 * (# rounds) */
#define TOTAL_SUBKEYS (ROUND_SUBKEYS + 2*MAX_ROUNDS)
/* Typedefs:
Typedef'ed data storage elements. Add any algorithm specific
parameters at the bottom of the structs as appropriate.
*/
typedef unsigned char BYTE;
typedef unsigned long DWORD; /* 32-bit unsigned quantity */
typedef DWORD fullSbox[4][256];
/* The structure for key information */
typedef struct
{
BYTE direction; /* Key used for encrypting or decrypting? */
#if ALIGN32
BYTE dummyAlign[3]; /* keep 32-bit alignment */
#endif
int keyLen; /* Length of the key */
char keyMaterial[MAX_KEY_SIZE+4];/* Raw key data in ASCII */
/* Twofish-specific parameters: */
DWORD keySig; /* set to VALID_SIG by makeKey() */
int numRounds; /* number of rounds in cipher */
DWORD key32[MAX_KEY_BITS/32]; /* actual key bits, in dwords */
DWORD sboxKeys[MAX_KEY_BITS/64];/* key bits used for S-boxes */
DWORD subKeys[TOTAL_SUBKEYS]; /* round subkeys, input/output whitening bits */
#if REENTRANT
fullSbox sBox8x32; /* fully expanded S-box */
#if defined(COMPILE_KEY) && defined(USE_ASM)
#undef VALID_SIG
#define VALID_SIG 0x504D4F43 /* 'COMP': C is compiled with -DCOMPILE_KEY */
DWORD cSig1; /* set after first "compile" (zero at "init") */
void *encryptFuncPtr; /* ptr to asm encrypt function */
void *decryptFuncPtr; /* ptr to asm decrypt function */
DWORD codeSize; /* size of compiledCode */
DWORD cSig2; /* set after first "compile" */
BYTE compiledCode[5000]; /* make room for the code itself */
#endif
#endif
} keyInstance;
/* The structure for cipher information */
typedef struct
{
BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */
#if ALIGN32
BYTE dummyAlign[3]; /* keep 32-bit alignment */
#endif
BYTE IV[MAX_IV_SIZE]; /* CFB1 iv bytes (CBC uses iv32) */
/* Twofish-specific parameters: */
DWORD cipherSig; /* set to VALID_SIG by cipherInit() */
DWORD iv32[BLOCK_SIZE/32]; /* CBC IV bytes arranged as dwords */
} cipherInstance;
/* Function protoypes */
int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial);
int cipherInit(cipherInstance *cipher, BYTE mode, char *IV);
int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
int inputLen, BYTE *outBuffer);
int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
int inputLen, BYTE *outBuffer);
int reKey(keyInstance *key); /* do key schedule using modified key.keyDwords */
/* API to check table usage, for use in ECB_TBL KAT */
#define TAB_DISABLE 0
#define TAB_ENABLE 1
#define TAB_RESET 2
#define TAB_QUERY 3
#define TAB_MIN_QUERY 50
int TableOp(int op);
#define CONST /* helpful C++ syntax sugar, NOP for ANSI C */
#if BLOCK_SIZE == 128 /* optimize block copies */
#define Copy1(d,s,N) ((DWORD *)(d))[N] = ((DWORD *)(s))[N]
#define BlockCopy(d,s) { Copy1(d,s,0);Copy1(d,s,1);Copy1(d,s,2);Copy1(d,s,3); }
#else
#define BlockCopy(d,s) { memcpy(d,s,BLOCK_SIZE/8); }
#endif
#ifdef TEST_2FISH
/* ----- EXAMPLES -----
Unfortunately, the AES API is somewhat clumsy, and it is not entirely
obvious how to use the above functions. In particular, note that
makeKey() takes an ASCII hex nibble key string (e.g., 32 characters
for a 128-bit key), which is rarely the way that keys are internally
represented. The reKey() function uses instead the keyInstance.key32
array of key bits and is the preferred method. In fact, makeKey()
initializes some internal keyInstance state, then parse the ASCII
string into the binary key32, and calls reKey(). To initialize the
keyInstance state, use a 'dummy' call to makeKey(); i.e., set the
keyMaterial parameter to NULL. Then use reKey() for all key changes.
Similarly, cipherInit takes an IV string in ASCII hex, so a dummy setup
call with a null IV string will skip the ASCII parse.
Note that CFB mode is not well tested nor defined by AES, so using the
Twofish MODE_CFB it not recommended. If you wish to implement a CFB mode,
build it external to the Twofish code, using the Twofish functions only
in ECB mode.
Below is a sample piece of code showing how the code is typically used
to set up a key, encrypt, and decrypt. Error checking is somewhat limited
in this example. Pseudorandom bytes are used for all key and text.
If you compile TWOFISH2.C or TWOFISH.C as a DOS (or Windows Console) app
with this code enabled, the test will be run. For example, using
Borland C, you would compile using:
BCC32 -DTEST_2FISH twofish2.c
to run the test on the optimized code, or
BCC32 -DTEST_2FISH twofish.c
to run the test on the pedagogical code.
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define MAX_BLK_CNT 4 /* max # blocks per call in TestTwofish */
int TestTwofish(int mode,int keySize) /* keySize must be 128, 192, or 256 */
{ /* return 0 iff test passes */
keyInstance ki; /* key information, including tables */
cipherInstance ci; /* keeps mode (ECB, CBC) and IV */
BYTE plainText[MAX_BLK_CNT*(BLOCK_SIZE/8)];
BYTE cipherText[MAX_BLK_CNT*(BLOCK_SIZE/8)];
BYTE decryptOut[MAX_BLK_CNT*(BLOCK_SIZE/8)];
BYTE iv[BLOCK_SIZE/8];
int i,byteCnt;
if (makeKey(&ki,DIR_ENCRYPT,keySize,NULL) != TRUE)
return 1; /* 'dummy' setup for a 128-bit key */
if (cipherInit(&ci,mode,NULL) != TRUE)
return 1; /* 'dummy' setup for cipher */
for (i=0;i<keySize/32;i++) /* select key bits */
ki.key32[i]=0x10003 * rand();
reKey(&ki); /* run the key schedule */
if (mode != MODE_ECB) /* set up random iv (if needed)*/
{
for (i=0;i<sizeof(iv);i++)
iv[i]=(BYTE) rand();
memcpy(ci.iv32,iv,sizeof(ci.iv32)); /* copy the IV to ci */
}
/* select number of bytes to encrypt (multiple of block) */
/* e.g., byteCnt = 16, 32, 48, 64 */
byteCnt = (BLOCK_SIZE/8) * (1 + (rand() % MAX_BLK_CNT));
for (i=0;i<byteCnt;i++) /* generate test data */
plainText[i]=(BYTE) rand();
/* encrypt the bytes */
if (blockEncrypt(&ci,&ki, plainText,byteCnt*8,cipherText) != byteCnt*8)
return 1;
/* decrypt the bytes */
if (mode != MODE_ECB) /* first re-init the IV (if needed) */
memcpy(ci.iv32,iv,sizeof(ci.iv32));
if (blockDecrypt(&ci,&ki,cipherText,byteCnt*8,decryptOut) != byteCnt*8)
return 1;
/* make sure the decrypt output matches original plaintext */
if (memcmp(plainText,decryptOut,byteCnt))
return 1;
return 0; /* tests passed! */
}
void main(void)
{
int testCnt,keySize;
srand((unsigned) time(NULL)); /* randomize */
for (keySize=128;keySize<=256;keySize+=64)
for (testCnt=0;testCnt<10;testCnt++)
{
if (TestTwofish(MODE_ECB,keySize))
{ printf("ECB Failure at keySize=%d",keySize); return; }
if (TestTwofish(MODE_CBC,keySize))
{ printf("CBC Failure at keySize=%d",keySize); return; }
}
printf("Tests passed");
}
#endif /* TEST_2FISH */

View file

@ -1,77 +0,0 @@
#ifdef DEBUG /* keep these macros common so they are same for both versions */
CONST int debugCompile = 1;
extern int debug;
extern void DebugIO(CONST char *s); /* display the debug output */
#define DebugDump(x,s,R,XOR,doRot,showT,needBswap) \
{ if (debug) _Dump(x,s,R,XOR,doRot,showT,needBswap,t0,t1); }
#define DebugDumpKey(key) { if (debug) _DumpKey(key); }
#define IV_ROUND -100
void _Dump(CONST void *p,CONST char *s,int R,int XOR,int doRot,int showT,int needBswap,
DWORD t0,DWORD t1)
{
char line[512]; /* build output here */
int i,n;
DWORD q[4];
if (R == IV_ROUND)
sprintf(line,"%sIV: ",s);
else
sprintf(line,"%sR[%2d]: ",s,R);
for (n=0;line[n];n++) ;
for (i=0;i<4;i++)
{
q[i]=((CONST DWORD *)p)[i^(XOR)];
if (needBswap) q[i]=Bswap(q[i]);
}
sprintf(line+n,"x= %08lX %08lX %08lX %08lX.",
ROR(q[0],doRot*(R )/2),
ROL(q[1],doRot*(R )/2),
ROR(q[2],doRot*(R+1)/2),
ROL(q[3],doRot*(R+1)/2));
for (;line[n];n++) ;
if (showT)
sprintf(line+n," t0=%08lX. t1=%08lX.",t0,t1);
for (;line[n];n++) ;
sprintf(line+n,"\n");
DebugIO(line);
}
void _DumpKey(CONST keyInstance *key)
{
char line[512];
int i;
int k64Cnt=(key->keyLen+63)/64; /* round up to next multiple of 64 bits */
int subkeyCnt = ROUND_SUBKEYS + 2*key->numRounds;
sprintf(line,";\n;makeKey: Input key --> S-box key [%s]\n",
(key->direction == DIR_ENCRYPT) ? "Encrypt" : "Decrypt");
DebugIO(line);
for (i=0;i<k64Cnt;i++) /* display in RS format */
{
sprintf(line,";%12s %08lX %08lX --> %08lX\n","",
key->key32[2*i+1],key->key32[2*i],key->sboxKeys[k64Cnt-1-i]);
DebugIO(line);
}
sprintf(line,";%11sSubkeys\n","");
DebugIO(line);
for (i=0;i<subkeyCnt/2;i++)
{
sprintf(line,";%12s %08lX %08lX%s\n","",key->subKeys[2*i],key->subKeys[2*i+1],
(2*i == INPUT_WHITEN) ? " Input whiten" :
(2*i == OUTPUT_WHITEN) ? " Output whiten" :
(2*i == ROUND_SUBKEYS) ? " Round subkeys" : "");
DebugIO(line);
}
DebugIO(";\n");
}
#else
CONST int debugCompile = 0;
#define DebugDump(x,s,R,XOR,doRot,showT,needBswap)
#define DebugDumpKey(key)
#endif

View file

@ -1,75 +0,0 @@
/***************************************************************************
PLATFORM.H -- Platform-specific defines for TWOFISH code
Submitters:
Bruce Schneier, Counterpane Systems
Doug Whiting, Hi/fn
John Kelsey, Counterpane Systems
Chris Hall, Counterpane Systems
David Wagner, UC Berkeley
Code Author: Doug Whiting, Hi/fn
Version 1.00 April 1998
Copyright 1998, Hi/fn and Counterpane Systems. All rights reserved.
Notes:
* Tab size is set to 4 characters in this file
***************************************************************************/
/* use intrinsic rotate if possible */
#define ROL(x,n) (((x) << ((n) & 0x1F)) | ((x) >> (32-((n) & 0x1F))))
#define ROR(x,n) (((x) >> ((n) & 0x1F)) | ((x) << (32-((n) & 0x1F))))
#if (0) && defined(__BORLANDC__) && (__BORLANDC__ >= 0x462)
#error "!!!This does not work for some reason!!!"
#include <stdlib.h> /* get prototype for _lrotl() , _lrotr() */
#pragma inline __lrotl__
#pragma inline __lrotr__
#undef ROL /* get rid of inefficient definitions */
#undef ROR
#define ROL(x,n) __lrotl__(x,n) /* use compiler intrinsic rotations */
#define ROR(x,n) __lrotr__(x,n)
#endif
#ifdef _MSC_VER
#include <stdlib.h> /* get prototypes for rotation functions */
#undef ROL
#undef ROR
#pragma intrinsic(_lrotl,_lrotr) /* use intrinsic compiler rotations */
#define ROL(x,n) _lrotl(x,n)
#define ROR(x,n) _lrotr(x,n)
#endif
#if !defined(__i386__) && !defined(__x86_64__)
#ifdef __BORLANDC__
#define __i386__ 300 /* make sure this is defined for Intel CPUs */
#endif
#endif
#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
#define LittleEndian 1 /* e.g., 1 for Pentium, 0 for 68K */
#define ALIGN32 0 /* need dword alignment? (no for Pentium) */
#else /* non-Intel platforms */
#define LittleEndian 0 /* (assume big endian */
#define ALIGN32 0 /* (assume need alignment for non-Intel) */
#endif
#if LittleEndian
#define Bswap(x) (x) /* NOP for little-endian machines */
#define ADDR_XOR 0 /* NOP for little-endian machines */
#else
#define Bswap(x) ((ROR(x,8) & 0xFF00FF00) | (ROL(x,8) & 0x00FF00FF))
#define ADDR_XOR 3 /* convert byte address in dword */
#endif
/* Macros for extracting bytes from dwords (correct for endianness) */
#define _b(x,N) (((BYTE *)&x)[((N) & 3) ^ ADDR_XOR]) /* pick bytes out of a dword */
#define b0(x) _b(x,0) /* extract LSB of DWORD */
#define b1(x) _b(x,1)
#define b2(x) _b(x,2)
#define b3(x) _b(x,3) /* extract MSB of DWORD */

View file

@ -1,228 +0,0 @@
/***************************************************************************
TABLE.H -- Tables, macros, constants for Twofish S-boxes and MDS matrix
Submitters:
Bruce Schneier, Counterpane Systems
Doug Whiting, Hi/fn
John Kelsey, Counterpane Systems
Chris Hall, Counterpane Systems
David Wagner, UC Berkeley
Code Author: Doug Whiting, Hi/fn
Version 1.00 April 1998
Copyright 1998, Hi/fn and Counterpane Systems. All rights reserved.
Notes:
* Tab size is set to 4 characters in this file
* These definitions should be used in optimized and unoptimized
versions to insure consistency.
***************************************************************************/
/* for computing subkeys */
#define SK_STEP 0x02020202u
#define SK_BUMP 0x01010101u
#define SK_ROTL 9
/* Reed-Solomon code parameters: (12,8) reversible code
g(x) = x**4 + (a + 1/a) x**3 + a x**2 + (a + 1/a) x + 1
where a = primitive root of field generator 0x14D */
#define RS_GF_FDBK 0x14D /* field generator */
#define RS_rem(x) \
{ BYTE b = (BYTE) (x >> 24); \
DWORD g2 = ((b << 1) ^ ((b & 0x80) ? RS_GF_FDBK : 0 )) & 0xFF; \
DWORD g3 = ((b >> 1) & 0x7F) ^ ((b & 1) ? RS_GF_FDBK >> 1 : 0 ) ^ g2 ; \
x = (x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b; \
}
/* Macros for the MDS matrix
* The MDS matrix is (using primitive polynomial 169):
* 01 EF 5B 5B
* 5B EF EF 01
* EF 5B 01 EF
* EF 01 EF 5B
*----------------------------------------------------------------
* More statistical properties of this matrix (from MDS.EXE output):
*
* Min Hamming weight (one byte difference) = 8. Max=26. Total = 1020.
* Prob[8]: 7 23 42 20 52 95 88 94 121 128 91
* 102 76 41 24 8 4 1 3 0 0 0
* Runs[8]: 2 4 5 6 7 8 9 11
* MSBs[8]: 1 4 15 8 18 38 40 43
* HW= 8: 05040705 0A080E0A 14101C14 28203828 50407050 01499101 A080E0A0
* HW= 9: 04050707 080A0E0E 10141C1C 20283838 40507070 80A0E0E0 C6432020 07070504
* 0E0E0A08 1C1C1410 38382820 70705040 E0E0A080 202043C6 05070407 0A0E080E
* 141C101C 28382038 50704070 A0E080E0 4320C620 02924B02 089A4508
* Min Hamming weight (two byte difference) = 3. Max=28. Total = 390150.
* Prob[3]: 7 18 55 149 270 914 2185 5761 11363 20719 32079
* 43492 51612 53851 52098 42015 31117 20854 11538 6223 2492 1033
* MDS OK, ROR: 6+ 7+ 8+ 9+ 10+ 11+ 12+ 13+ 14+ 15+ 16+
* 17+ 18+ 19+ 20+ 21+ 22+ 23+ 24+ 25+ 26+
*/
#define MDS_GF_FDBK 0x169 /* primitive polynomial for GF(256)*/
#define LFSR1(x) ( ((x) >> 1) ^ (((x) & 0x01) ? MDS_GF_FDBK/2 : 0))
#define LFSR2(x) ( ((x) >> 2) ^ (((x) & 0x02) ? MDS_GF_FDBK/2 : 0) \
^ (((x) & 0x01) ? MDS_GF_FDBK/4 : 0))
#define Mx_1(x) ((DWORD) (x)) /* force result to dword so << will work */
#define Mx_X(x) ((DWORD) ((x) ^ LFSR2(x))) /* 5B */
#define Mx_Y(x) ((DWORD) ((x) ^ LFSR1(x) ^ LFSR2(x))) /* EF */
#define M00 Mul_1
#define M01 Mul_Y
#define M02 Mul_X
#define M03 Mul_X
#define M10 Mul_X
#define M11 Mul_Y
#define M12 Mul_Y
#define M13 Mul_1
#define M20 Mul_Y
#define M21 Mul_X
#define M22 Mul_1
#define M23 Mul_Y
#define M30 Mul_Y
#define M31 Mul_1
#define M32 Mul_Y
#define M33 Mul_X
#define Mul_1 Mx_1
#define Mul_X Mx_X
#define Mul_Y Mx_Y
/* Define the fixed p0/p1 permutations used in keyed S-box lookup.
By changing the following constant definitions for P_ij, the S-boxes will
automatically get changed in all the Twofish source code. Note that P_i0 is
the "outermost" 8x8 permutation applied. See the f32() function to see
how these constants are to be used.
*/
#define P_00 1 /* "outermost" permutation */
#define P_01 0
#define P_02 0
#define P_03 (P_01^1) /* "extend" to larger key sizes */
#define P_04 1
#define P_10 0
#define P_11 0
#define P_12 1
#define P_13 (P_11^1)
#define P_14 0
#define P_20 1
#define P_21 1
#define P_22 0
#define P_23 (P_21^1)
#define P_24 0
#define P_30 0
#define P_31 1
#define P_32 1
#define P_33 (P_31^1)
#define P_34 1
#define p8(N) P8x8[P_##N] /* some syntax shorthand */
/* fixed 8x8 permutation S-boxes */
/***********************************************************************
* 07:07:14 05/30/98 [4x4] TestCnt=256. keySize=128. CRC=4BD14D9E.
* maxKeyed: dpMax = 18. lpMax =100. fixPt = 8. skXor = 0. skDup = 6.
* log2(dpMax[ 6..18])= --- 15.42 1.33 0.89 4.05 7.98 12.05
* log2(lpMax[ 7..12])= 9.32 1.01 1.16 4.23 8.02 12.45
* log2(fixPt[ 0.. 8])= 1.44 1.44 2.44 4.06 6.01 8.21 11.07 14.09 17.00
* log2(skXor[ 0.. 0])
* log2(skDup[ 0.. 6])= --- 2.37 0.44 3.94 8.36 13.04 17.99
***********************************************************************/
CONST BYTE P8x8[2][256]=
{
/* p0: */
/* dpMax = 10. lpMax = 64. cycleCnt= 1 1 1 0. */
/* 817D6F320B59ECA4.ECB81235F4A6709D.BA5E6D90C8F32471.D7F4126E9B3085CA. */
/* Karnaugh maps:
* 0111 0001 0011 1010. 0001 1001 1100 1111. 1001 1110 0011 1110. 1101 0101 1111 1001.
* 0101 1111 1100 0100. 1011 0101 0010 0000. 0101 1000 1100 0101. 1000 0111 0011 0010.
* 0000 1001 1110 1101. 1011 1000 1010 0011. 0011 1001 0101 0000. 0100 0010 0101 1011.
* 0111 0100 0001 0110. 1000 1011 1110 1001. 0011 0011 1001 1101. 1101 0101 0000 1100.
*/
{
0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
},
/* p1: */
/* dpMax = 10. lpMax = 64. cycleCnt= 2 0 0 1. */
/* 28BDF76E31940AC5.1E2B4C376DA5F908.4C75169A0ED82B3F.B951C3DE647F208A. */
/* Karnaugh maps:
* 0011 1001 0010 0111. 1010 0111 0100 0110. 0011 0001 1111 0100. 1111 1000 0001 1100.
* 1100 1111 1111 1010. 0011 0011 1110 0100. 1001 0110 0100 0011. 0101 0110 1011 1011.
* 0010 0100 0011 0101. 1100 1000 1000 1110. 0111 1111 0010 0110. 0000 1010 0000 0011.
* 1101 1000 0010 0001. 0110 1001 1110 0101. 0001 0100 0101 0111. 0011 1011 1111 0010.
*/
{
0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
}
};