Line 0
Link Here
|
|
|
1 |
/* $Id: snortpatchb,v 1.5 2005/10/06 08:50:39 fknobbe Exp $ |
2 |
* |
3 |
* |
4 |
* Copyright (C) 1997-2000 The Cryptix Foundation Limited. |
5 |
* Copyright (C) 2000 Farm9. |
6 |
* Copyright (C) 2001 Frank Knobbe. |
7 |
* All rights reserved. |
8 |
* |
9 |
* For Cryptix code: |
10 |
* Use, modification, copying and distribution of this software is subject |
11 |
* the terms and conditions of the Cryptix General Licence. You should have |
12 |
* received a copy of the Cryptix General Licence along with this library; |
13 |
* if not, you can download a copy from http://www.cryptix.org/ . |
14 |
* |
15 |
* For Farm9: |
16 |
* --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and |
17 |
* ciphertext stealing technique, added AsciiTwofish class for easy encryption |
18 |
* decryption of text strings |
19 |
* |
20 |
* Frank Knobbe <frank@knobbe.us>: |
21 |
* --- April 2001, converted from C++ to C, prefixed global variables |
22 |
* with TwoFish, substituted some defines, changed functions to make use of |
23 |
* variables supplied in a struct, modified and added routines for modular calls. |
24 |
* Cleaned up the code so that defines are used instead of fixed 16's and 32's. |
25 |
* Created two general purpose crypt routines for one block and multiple block |
26 |
* encryption using Joh's CBC code. |
27 |
* Added crypt routines that use a header (with a magic and data length). |
28 |
* (Basically a major rewrite). |
29 |
* |
30 |
* Note: Routines labeled _TwoFish are private and should not be used |
31 |
* (or with extreme caution). |
32 |
* |
33 |
*/ |
34 |
|
35 |
#ifndef __TWOFISH_LIBRARY_SOURCE__ |
36 |
#define __TWOFISH_LIBRARY_SOURCE__ |
37 |
|
38 |
#include <string.h> |
39 |
#include <stdlib.h> |
40 |
#include <time.h> |
41 |
#include <ctype.h> |
42 |
#include "twofish.h" |
43 |
|
44 |
|
45 |
bool TwoFish_srand=TRUE; /* if TRUE, first call of TwoFishInit will seed rand(); */ |
46 |
/* of TwoFishInit */ |
47 |
|
48 |
/* Fixed 8x8 permutation S-boxes */ |
49 |
static const unsigned char TwoFish_P[2][256] = |
50 |
{ |
51 |
{ /* p0 */ |
52 |
0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, |
53 |
0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, |
54 |
0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, |
55 |
0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, |
56 |
0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, |
57 |
0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, |
58 |
0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, |
59 |
0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, |
60 |
0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, |
61 |
0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, |
62 |
0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, |
63 |
0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, |
64 |
0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, |
65 |
0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, |
66 |
0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, |
67 |
0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, |
68 |
0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, |
69 |
0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, |
70 |
0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, |
71 |
0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, |
72 |
0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, |
73 |
0x4A, 0x5E, 0xC1, 0xE0 |
74 |
}, |
75 |
{ /* p1 */ |
76 |
0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, |
77 |
0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, |
78 |
0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, |
79 |
0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, |
80 |
0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, |
81 |
0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, |
82 |
0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, |
83 |
0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, |
84 |
0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, |
85 |
0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, |
86 |
0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, |
87 |
0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, |
88 |
0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, |
89 |
0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, |
90 |
0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, |
91 |
0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, |
92 |
0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, |
93 |
0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, |
94 |
0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, |
95 |
0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, |
96 |
0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, |
97 |
0x55, 0x09, 0xBE, 0x91 |
98 |
} |
99 |
}; |
100 |
|
101 |
static bool TwoFish_MDSready=FALSE; |
102 |
static unsigned long TwoFish_MDS[4][256]; /* TwoFish_MDS matrix */ |
103 |
|
104 |
|
105 |
#define TwoFish_LFSR1(x) (((x)>>1)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/2:0)) |
106 |
#define TwoFish_LFSR2(x) (((x)>>2)^(((x)&0x02)?TwoFish_MDS_GF_FDBK/2:0)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/4:0)) |
107 |
|
108 |
#define TwoFish_Mx_1(x) ((unsigned long)(x)) /* force result to dword so << will work */ |
109 |
#define TwoFish_Mx_X(x) ((unsigned long)((x)^TwoFish_LFSR2(x))) /* 5B */ |
110 |
#define TwoFish_Mx_Y(x) ((unsigned long)((x)^TwoFish_LFSR1(x)^TwoFish_LFSR2(x))) /* EF */ |
111 |
#define TwoFish_RS_rem(x) { unsigned char b=(unsigned char)(x>>24); unsigned long g2=((b<<1)^((b&0x80)?TwoFish_RS_GF_FDBK:0))&0xFF; unsigned long g3=((b>>1)&0x7F)^((b&1)?TwoFish_RS_GF_FDBK>>1:0)^g2; x=(x<<8)^(g3<<24)^(g2<<16)^(g3<<8)^b; } |
112 |
|
113 |
/*#define TwoFish__b(x,N) (((unsigned char *)&x)[((N)&3)^TwoFish_ADDR_XOR])*/ /* pick bytes out of a dword */ |
114 |
|
115 |
#define TwoFish_b0(x) TwoFish__b(x,0) /* extract LSB of unsigned long */ |
116 |
#define TwoFish_b1(x) TwoFish__b(x,1) |
117 |
#define TwoFish_b2(x) TwoFish__b(x,2) |
118 |
#define TwoFish_b3(x) TwoFish__b(x,3) /* extract MSB of unsigned long */ |
119 |
|
120 |
unsigned char TwoFish__b(unsigned long x,int n) |
121 |
{ n&=3; |
122 |
while(n-->0) |
123 |
x>>=8; |
124 |
return (unsigned char)x; |
125 |
} |
126 |
|
127 |
|
128 |
/* TwoFish Initialization |
129 |
* |
130 |
* This routine generates a global data structure for use with TwoFish, |
131 |
* initializes important values (such as subkeys, sBoxes), generates subkeys |
132 |
* and precomputes the MDS matrix if not already done. |
133 |
* |
134 |
* Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') |
135 |
* |
136 |
* Output: Pointer to TWOFISH structure. This data structure contains key dependent data. |
137 |
* This pointer is used with all other crypt functions. |
138 |
*/ |
139 |
|
140 |
TWOFISH *TwoFishInit(char *userkey) |
141 |
{ TWOFISH *tfdata; |
142 |
int i,x,m; |
143 |
char tkey[TwoFish_KEY_LENGTH+40]; |
144 |
|
145 |
tfdata=malloc(sizeof(TWOFISH)); /* allocate the TwoFish structure */ |
146 |
if(tfdata!=NULL) |
147 |
{ if(*userkey) |
148 |
{ strncpy(tkey,userkey,TwoFish_KEY_LENGTH); /* use first 32 chars of user supplied password */ |
149 |
tkey[TwoFish_KEY_LENGTH]=0; /* make sure it wasn't more */ |
150 |
} |
151 |
else |
152 |
strcpy(tkey,TwoFish_DEFAULT_PW); /* if no key defined, use default password */ |
153 |
for(i=0,x=0,m=strlen(tkey);i<TwoFish_KEY_LENGTH;i++) /* copy into data structure */ |
154 |
{ tfdata->key[i]=tkey[x++]; /* fill the whole keyspace with repeating key. */ |
155 |
if(x==m) |
156 |
x=0; |
157 |
} |
158 |
|
159 |
if(!TwoFish_MDSready) |
160 |
_TwoFish_PrecomputeMDSmatrix(); /* "Wake Up, Neo" */ |
161 |
_TwoFish_MakeSubKeys(tfdata); /* generate subkeys */ |
162 |
_TwoFish_ResetCBC(tfdata); /* reset the CBC */ |
163 |
tfdata->output=NULL; /* nothing to output yet */ |
164 |
tfdata->dontflush=FALSE; /* reset decrypt skip block flag */ |
165 |
if(TwoFish_srand) |
166 |
{ TwoFish_srand=FALSE; |
167 |
srand(time(NULL)); |
168 |
} |
169 |
} |
170 |
return tfdata; /* return the data pointer */ |
171 |
} |
172 |
|
173 |
|
174 |
void TwoFishDestroy(TWOFISH *tfdata) |
175 |
{ if(tfdata!=NULL) |
176 |
free(tfdata); |
177 |
} |
178 |
|
179 |
|
180 |
/* en/decryption with CBC mode */ |
181 |
unsigned long _TwoFish_CryptRawCBC(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata) |
182 |
{ unsigned long rl; |
183 |
|
184 |
rl=len; /* remember how much data to crypt. */ |
185 |
while(len>TwoFish_BLOCK_SIZE) /* and now we process block by block. */ |
186 |
{ _TwoFish_BlockCrypt(in,out,TwoFish_BLOCK_SIZE,decrypt,tfdata); /* de/encrypt it. */ |
187 |
in+=TwoFish_BLOCK_SIZE; /* adjust pointers. */ |
188 |
out+=TwoFish_BLOCK_SIZE; |
189 |
len-=TwoFish_BLOCK_SIZE; |
190 |
} |
191 |
if(len>0) /* if we have less than a block left... */ |
192 |
_TwoFish_BlockCrypt(in,out,len,decrypt,tfdata); /* ...then we de/encrypt that too. */ |
193 |
if(tfdata->qBlockDefined && !tfdata->dontflush) /* in case len was exactly one block... */ |
194 |
_TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); /* ...we need to write the... */ |
195 |
/* ...remaining bytes of the buffer */ |
196 |
return rl; |
197 |
} |
198 |
|
199 |
/* en/decryption on one block only */ |
200 |
unsigned long _TwoFish_CryptRaw16(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata) |
201 |
{ /* qBlockPlain already zero'ed through ResetCBC */ |
202 |
memcpy(tfdata->qBlockPlain,in,len); /* toss the data into it. */ |
203 |
_TwoFish_BlockCrypt16(tfdata->qBlockPlain,tfdata->qBlockCrypt,decrypt,tfdata); /* encrypt just that block without CBC. */ |
204 |
memcpy(out,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE); /* and return what we got */ |
205 |
return TwoFish_BLOCK_SIZE; |
206 |
} |
207 |
|
208 |
/* en/decryption without reset of CBC and output assignment */ |
209 |
unsigned long _TwoFish_CryptRaw(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata) |
210 |
{ |
211 |
if(in!=NULL && out!=NULL && len>0 && tfdata!=NULL) /* if we have valid data, then... */ |
212 |
{ if(len>TwoFish_BLOCK_SIZE) /* ...check if we have more than one block. */ |
213 |
return _TwoFish_CryptRawCBC(in,out,len,decrypt,tfdata); /* if so, use the CBC routines... */ |
214 |
else |
215 |
return _TwoFish_CryptRaw16(in,out,len,decrypt,tfdata); /* ...otherwise just do one block. */ |
216 |
} |
217 |
return 0; |
218 |
} |
219 |
|
220 |
|
221 |
/* TwoFish Raw Encryption |
222 |
* |
223 |
* Does not use header, but does use CBC (if more than one block has to be encrypted). |
224 |
* |
225 |
* Input: Pointer to the buffer of the plaintext to be encrypted. |
226 |
* Pointer to the buffer receiving the ciphertext. |
227 |
* The length of the plaintext buffer. |
228 |
* The TwoFish structure. |
229 |
* |
230 |
* Output: The amount of bytes encrypted if successful, otherwise 0. |
231 |
*/ |
232 |
|
233 |
unsigned long TwoFishEncryptRaw(char *in, |
234 |
char *out, |
235 |
unsigned long len, |
236 |
TWOFISH *tfdata) |
237 |
{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ |
238 |
tfdata->output=out; /* output straight into output buffer. */ |
239 |
return _TwoFish_CryptRaw(in,out,len,FALSE,tfdata); /* and go for it. */ |
240 |
} |
241 |
|
242 |
/* TwoFish Raw Decryption |
243 |
* |
244 |
* Does not use header, but does use CBC (if more than one block has to be decrypted). |
245 |
* |
246 |
* Input: Pointer to the buffer of the ciphertext to be decrypted. |
247 |
* Pointer to the buffer receiving the plaintext. |
248 |
* The length of the ciphertext buffer (at least one cipher block). |
249 |
* The TwoFish structure. |
250 |
* |
251 |
* Output: The amount of bytes decrypted if successful, otherwise 0. |
252 |
*/ |
253 |
|
254 |
unsigned long TwoFishDecryptRaw(char *in, |
255 |
char *out, |
256 |
unsigned long len, |
257 |
TWOFISH *tfdata) |
258 |
{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ |
259 |
tfdata->output=out; /* output straight into output buffer. */ |
260 |
return _TwoFish_CryptRaw(in,out,len,TRUE,tfdata); /* and go for it. */ |
261 |
} |
262 |
|
263 |
/* TwoFish Free |
264 |
* |
265 |
* Free's the allocated buffer. |
266 |
* |
267 |
* Input: Pointer to the TwoFish structure |
268 |
* |
269 |
* Output: (none) |
270 |
*/ |
271 |
|
272 |
void TwoFishFree(TWOFISH *tfdata) |
273 |
{ if(tfdata->output!=NULL) /* if a valid buffer is present... */ |
274 |
{ free(tfdata->output); /* ...then we free it for you... */ |
275 |
tfdata->output=NULL; /* ...and mark as such. */ |
276 |
} |
277 |
} |
278 |
|
279 |
/* TwoFish Set Output |
280 |
* |
281 |
* If you want to allocate the output buffer yourself, |
282 |
* then you can set it with this function. |
283 |
* |
284 |
* Input: Pointer to your output buffer |
285 |
* Pointer to the TwoFish structure |
286 |
* |
287 |
* Output: (none) |
288 |
*/ |
289 |
|
290 |
void TwoFishSetOutput(char *outp,TWOFISH *tfdata) |
291 |
{ tfdata->output=outp; /* (do we really need a function for this?) */ |
292 |
} |
293 |
|
294 |
/* TwoFish Alloc |
295 |
* |
296 |
* Allocates enough memory for the output buffer that would be required |
297 |
* |
298 |
* Input: Length of the plaintext. |
299 |
* Boolean flag for BinHex Output. |
300 |
* Pointer to the TwoFish structure. |
301 |
* |
302 |
* Output: Returns a pointer to the memory allocated. |
303 |
*/ |
304 |
|
305 |
void *TwoFishAlloc(unsigned long len,bool binhex,bool decrypt,TWOFISH *tfdata) |
306 |
{ |
307 |
/* TwoFishFree(tfdata); */ /* (don't for now) discard whatever was allocated earlier. */ |
308 |
if(decrypt) /* if decrypting... */ |
309 |
{ if(binhex) /* ...and input is binhex encoded... */ |
310 |
len/=2; /* ...use half as much for output. */ |
311 |
len-=TwoFish_BLOCK_SIZE; /* Also, subtract the size of the header. */ |
312 |
} |
313 |
else |
314 |
{ len+=TwoFish_BLOCK_SIZE; /* the size is just increased by the header... */ |
315 |
if(binhex) |
316 |
len*=2; /* ...and doubled if output is to be binhexed. */ |
317 |
} |
318 |
tfdata->output=malloc(len+TwoFish_BLOCK_SIZE);/* grab some memory...plus some extra (it's running over somewhere, crashes without extra padding) */ |
319 |
|
320 |
return tfdata->output; /* ...and return to caller. */ |
321 |
} |
322 |
|
323 |
/* bin2hex and hex2bin conversion */ |
324 |
void _TwoFish_BinHex(unsigned char *buf,unsigned long len,bool bintohex) |
325 |
{ unsigned char *pi,*po,c; |
326 |
|
327 |
if(bintohex) |
328 |
{ for(pi=buf+len-1,po=buf+(2*len)-1;len>0;pi--,po--,len--) /* let's start from the end of the bin block. */ |
329 |
{ c=*pi; /* grab value. */ |
330 |
c&=15; /* use lower 4 bits. */ |
331 |
if(c>9) /* convert to ascii. */ |
332 |
c+=('a'-10); |
333 |
else |
334 |
c+='0'; |
335 |
*po--=c; /* set the lower nibble. */ |
336 |
c=*pi; /* grab value again. */ |
337 |
c>>=4; /* right shift 4 bits. */ |
338 |
c&=15; /* make sure we only have 4 bits. */ |
339 |
if(c>9) /* convert to ascii. */ |
340 |
c+=('a'-10); |
341 |
else |
342 |
c+='0'; |
343 |
*po=c; /* set the higher nibble. */ |
344 |
} /* and keep going. */ |
345 |
} |
346 |
else |
347 |
{ for(pi=buf,po=buf;len>0;pi++,po++,len-=2) /* let's start from the beginning of the hex block. */ |
348 |
{ c=tolower(*pi++)-'0'; /* grab higher nibble. */ |
349 |
if(c>9) /* convert to value. */ |
350 |
c-=('0'-9); |
351 |
*po=c<<4; /* left shit 4 bits. */ |
352 |
c=tolower(*pi)-'0'; /* grab lower nibble. */ |
353 |
if(c>9) /* convert to value. */ |
354 |
c-=('0'-9); |
355 |
*po|=c; /* and add to value. */ |
356 |
} |
357 |
} |
358 |
} |
359 |
|
360 |
|
361 |
/* TwoFish Encryption |
362 |
* |
363 |
* Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, |
364 |
* this routine will alloc the memory. In addition, it will include a small 'header' |
365 |
* containing the magic and some salt. That way the decrypt routine can check if the |
366 |
* packet got decrypted successfully, and return 0 instead of garbage. |
367 |
* |
368 |
* Input: Pointer to the buffer of the plaintext to be encrypted. |
369 |
* Pointer to the pointer to the buffer receiving the ciphertext. |
370 |
* The pointer either points to user allocated output buffer space, or to NULL, in which case |
371 |
* this routine will set the pointer to the buffer allocated through the struct. |
372 |
* The length of the plaintext buffer. |
373 |
* Can be -1 if the input is a null terminated string, in which case we'll count for you. |
374 |
* Boolean flag for BinHex Output (if used, output will be twice as large as input). |
375 |
* Note: BinHex conversion overwrites (converts) input buffer! |
376 |
* The TwoFish structure. |
377 |
* |
378 |
* Output: The amount of bytes encrypted if successful, otherwise 0. |
379 |
*/ |
380 |
|
381 |
unsigned long TwoFishEncrypt(char *in, |
382 |
char **out, |
383 |
signed long len, |
384 |
bool binhex, |
385 |
TWOFISH *tfdata) |
386 |
{ unsigned long ilen,olen; |
387 |
|
388 |
|
389 |
if(len== -1) /* if we got -1 for len, we'll assume IN is a... */ |
390 |
ilen=strlen(in); /* ...\0 terminated string and figure len out ourselves... */ |
391 |
else |
392 |
ilen=len; /* ...otherwise we trust you supply a correct length. */ |
393 |
|
394 |
if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ |
395 |
{ if(*out==NULL) /* if OUT points to a NULL pointer... */ |
396 |
*out=TwoFishAlloc(ilen,binhex,FALSE,tfdata); /* ...we'll (re-)allocate buffer space. */ |
397 |
if(*out!=NULL) |
398 |
{ tfdata->output=*out; /* set output buffer. */ |
399 |
tfdata->header.salt=rand()*65536+rand(); /* toss in some salt. */ |
400 |
tfdata->header.length[0]= (unsigned char)(ilen); |
401 |
tfdata->header.length[1]= (unsigned char)(ilen>>8); |
402 |
tfdata->header.length[2]= (unsigned char)(ilen>>16); |
403 |
tfdata->header.length[3]= (unsigned char)(ilen>>24); |
404 |
memcpy(tfdata->header.magic,TwoFish_MAGIC,TwoFish_MAGIC_LEN); /* set the magic. */ |
405 |
olen=TwoFish_BLOCK_SIZE; /* set output counter. */ |
406 |
_TwoFish_ResetCBC(tfdata); /* reset the CBC flag */ |
407 |
_TwoFish_BlockCrypt((unsigned char *)&(tfdata->header),*out,olen,FALSE,tfdata); /* encrypt first block (without flush on 16 byte boundary). */ |
408 |
olen+=_TwoFish_CryptRawCBC(in,*out+TwoFish_BLOCK_SIZE,ilen,FALSE,tfdata); /* and encrypt the rest (we do not reset the CBC flag). */ |
409 |
if(binhex) /* if binhex... */ |
410 |
{ _TwoFish_BinHex(*out,olen,TRUE); /* ...convert output to binhex... */ |
411 |
olen*=2; /* ...and size twice as large. */ |
412 |
} |
413 |
tfdata->output=*out; |
414 |
return olen; |
415 |
} |
416 |
} |
417 |
return 0; |
418 |
} |
419 |
|
420 |
/* TwoFish Decryption |
421 |
* |
422 |
* Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, |
423 |
* this routine will alloc the memory. In addition, it will check the small 'header' |
424 |
* containing the magic. If magic does not match we return 0. Otherwise we return the |
425 |
* amount of bytes decrypted (should be the same as the length in the header). |
426 |
* |
427 |
* Input: Pointer to the buffer of the ciphertext to be decrypted. |
428 |
* Pointer to the pointer to the buffer receiving the plaintext. |
429 |
* The pointer either points to user allocated output buffer space, or to NULL, in which case |
430 |
* this routine will set the pointer to the buffer allocated through the struct. |
431 |
* The length of the ciphertext buffer. |
432 |
* Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. |
433 |
* Boolean flag for BinHex Input (if used, plaintext will be half as large as input). |
434 |
* Note: BinHex conversion overwrites (converts) input buffer! |
435 |
* The TwoFish structure. |
436 |
* |
437 |
* Output: The amount of bytes decrypted if successful, otherwise 0. |
438 |
*/ |
439 |
|
440 |
unsigned long TwoFishDecrypt(char *in, |
441 |
char **out, |
442 |
signed long len, |
443 |
bool binhex, |
444 |
TWOFISH *tfdata) |
445 |
{ unsigned long ilen,elen,olen; |
446 |
const unsigned char cmagic[TwoFish_MAGIC_LEN]=TwoFish_MAGIC; |
447 |
unsigned char *tbuf; |
448 |
|
449 |
|
450 |
|
451 |
if(len== -1) /* if we got -1 for len, we'll assume IN is... */ |
452 |
ilen=strlen(in); /* ...\0 terminated binhex and figure len out ourselves... */ |
453 |
else |
454 |
ilen=len; /* ...otherwise we trust you supply a correct length. */ |
455 |
|
456 |
if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ |
457 |
{ if(*out==NULL) /* if OUT points to a NULL pointer... */ |
458 |
*out=TwoFishAlloc(ilen,binhex,TRUE,tfdata); /* ...we'll (re-)allocate buffer space. */ |
459 |
if(*out!=NULL) |
460 |
{ if(binhex) /* if binhex... */ |
461 |
{ _TwoFish_BinHex(in,ilen,FALSE); /* ...convert input to values... */ |
462 |
ilen/=2; /* ...and size half as much. */ |
463 |
} |
464 |
_TwoFish_ResetCBC(tfdata); /* reset the CBC flag. */ |
465 |
|
466 |
tbuf=(unsigned char *)malloc(ilen+TwoFish_BLOCK_SIZE); /* get memory for data and header. */ |
467 |
if(tbuf==NULL) |
468 |
return 0; |
469 |
tfdata->output=tbuf; /* set output to temp buffer. */ |
470 |
|
471 |
olen=_TwoFish_CryptRawCBC(in,tbuf,ilen,TRUE,tfdata)-TwoFish_BLOCK_SIZE; /* decrypt the whole thing. */ |
472 |
memcpy(&(tfdata->header),tbuf,TwoFish_BLOCK_SIZE); /* copy first block into header. */ |
473 |
tfdata->output=*out; |
474 |
for(elen=0;elen<TwoFish_MAGIC_LEN;elen++) /* compare magic. */ |
475 |
if(tfdata->header.magic[elen]!=cmagic[elen]) |
476 |
break; |
477 |
if(elen==TwoFish_MAGIC_LEN) /* if magic matches then... */ |
478 |
{ elen=(tfdata->header.length[0]) | |
479 |
(tfdata->header.length[1])<<8 | |
480 |
(tfdata->header.length[2])<<16 | |
481 |
(tfdata->header.length[3])<<24; /* .. we know how much to expect. */ |
482 |
if(elen>olen) /* adjust if necessary. */ |
483 |
elen=olen; |
484 |
memcpy(*out,tbuf+TwoFish_BLOCK_SIZE,elen); /* copy data into intended output. */ |
485 |
free(tbuf); |
486 |
return elen; |
487 |
} |
488 |
free(tbuf); |
489 |
} |
490 |
} |
491 |
return 0; |
492 |
} |
493 |
|
494 |
void _TwoFish_PrecomputeMDSmatrix(void) /* precompute the TwoFish_MDS matrix */ |
495 |
{ unsigned long m1[2]; |
496 |
unsigned long mX[2]; |
497 |
unsigned long mY[2]; |
498 |
unsigned long i, j; |
499 |
|
500 |
for (i = 0; i < 256; i++) |
501 |
{ j = TwoFish_P[0][i] & 0xFF; /* compute all the matrix elements */ |
502 |
m1[0] = j; |
503 |
mX[0] = TwoFish_Mx_X( j ) & 0xFF; |
504 |
mY[0] = TwoFish_Mx_Y( j ) & 0xFF; |
505 |
|
506 |
j = TwoFish_P[1][i] & 0xFF; |
507 |
m1[1] = j; |
508 |
mX[1] = TwoFish_Mx_X( j ) & 0xFF; |
509 |
mY[1] = TwoFish_Mx_Y( j ) & 0xFF; |
510 |
|
511 |
TwoFish_MDS[0][i] = m1[TwoFish_P_00] | /* fill matrix w/ above elements */ |
512 |
mX[TwoFish_P_00] << 8 | |
513 |
mY[TwoFish_P_00] << 16 | |
514 |
mY[TwoFish_P_00] << 24; |
515 |
TwoFish_MDS[1][i] = mY[TwoFish_P_10] | |
516 |
mY[TwoFish_P_10] << 8 | |
517 |
mX[TwoFish_P_10] << 16 | |
518 |
m1[TwoFish_P_10] << 24; |
519 |
TwoFish_MDS[2][i] = mX[TwoFish_P_20] | |
520 |
mY[TwoFish_P_20] << 8 | |
521 |
m1[TwoFish_P_20] << 16 | |
522 |
mY[TwoFish_P_20] << 24; |
523 |
TwoFish_MDS[3][i] = mX[TwoFish_P_30] | |
524 |
m1[TwoFish_P_30] << 8 | |
525 |
mY[TwoFish_P_30] << 16 | |
526 |
mX[TwoFish_P_30] << 24; |
527 |
} |
528 |
TwoFish_MDSready=TRUE; |
529 |
} |
530 |
|
531 |
|
532 |
void _TwoFish_MakeSubKeys(TWOFISH *tfdata) /* Expand a user-supplied key material into a session key. */ |
533 |
{ unsigned long k64Cnt = TwoFish_KEY_LENGTH / 8; |
534 |
unsigned long k32e[4]; /* even 32-bit entities */ |
535 |
unsigned long k32o[4]; /* odd 32-bit entities */ |
536 |
unsigned long sBoxKey[4]; |
537 |
unsigned long offset,i,j; |
538 |
unsigned long A, B, q=0; |
539 |
unsigned long k0,k1,k2,k3; |
540 |
unsigned long b0,b1,b2,b3; |
541 |
|
542 |
/* split user key material into even and odd 32-bit entities and */ |
543 |
/* compute S-box keys using (12, 8) Reed-Solomon code over GF(256) */ |
544 |
|
545 |
|
546 |
for (offset=0,i=0,j=k64Cnt-1;i<4 && offset<TwoFish_KEY_LENGTH;i++,j--) |
547 |
{ k32e[i] = tfdata->key[offset++]; |
548 |
k32e[i]|= tfdata->key[offset++]<<8; |
549 |
k32e[i]|= tfdata->key[offset++]<<16; |
550 |
k32e[i]|= tfdata->key[offset++]<<24; |
551 |
k32o[i] = tfdata->key[offset++]; |
552 |
k32o[i]|= tfdata->key[offset++]<<8; |
553 |
k32o[i]|= tfdata->key[offset++]<<16; |
554 |
k32o[i]|= tfdata->key[offset++]<<24; |
555 |
sBoxKey[j] = _TwoFish_RS_MDS_Encode( k32e[i], k32o[i] ); /* reverse order */ |
556 |
} |
557 |
|
558 |
/* compute the round decryption subkeys for PHT. these same subkeys */ |
559 |
/* will be used in encryption but will be applied in reverse order. */ |
560 |
i=0; |
561 |
while(i < TwoFish_TOTAL_SUBKEYS) |
562 |
{ A = _TwoFish_F32( k64Cnt, q, k32e ); /* A uses even key entities */ |
563 |
q += TwoFish_SK_BUMP; |
564 |
|
565 |
B = _TwoFish_F32( k64Cnt, q, k32o ); /* B uses odd key entities */ |
566 |
q += TwoFish_SK_BUMP; |
567 |
|
568 |
B = B << 8 | B >> 24; |
569 |
|
570 |
A += B; |
571 |
tfdata->subKeys[i++] = A; /* combine with a PHT */ |
572 |
|
573 |
A += B; |
574 |
tfdata->subKeys[i++] = A << TwoFish_SK_ROTL | A >> (32-TwoFish_SK_ROTL); |
575 |
} |
576 |
|
577 |
/* fully expand the table for speed */ |
578 |
k0 = sBoxKey[0]; |
579 |
k1 = sBoxKey[1]; |
580 |
k2 = sBoxKey[2]; |
581 |
k3 = sBoxKey[3]; |
582 |
|
583 |
for (i = 0; i < 256; i++) |
584 |
{ b0 = b1 = b2 = b3 = i; |
585 |
switch (k64Cnt & 3) |
586 |
{ case 1: /* 64-bit keys */ |
587 |
tfdata->sBox[ 2*i ] = TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0]) ^ TwoFish_b0(k0)]; |
588 |
tfdata->sBox[ 2*i+1] = TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1]) ^ TwoFish_b1(k0)]; |
589 |
tfdata->sBox[0x200+2*i ] = TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2]) ^ TwoFish_b2(k0)]; |
590 |
tfdata->sBox[0x200+2*i+1] = TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3]) ^ TwoFish_b3(k0)]; |
591 |
break; |
592 |
case 0: /* 256-bit keys (same as 4) */ |
593 |
b0 = (TwoFish_P[TwoFish_P_04][b0]) ^ TwoFish_b0(k3); |
594 |
b1 = (TwoFish_P[TwoFish_P_14][b1]) ^ TwoFish_b1(k3); |
595 |
b2 = (TwoFish_P[TwoFish_P_24][b2]) ^ TwoFish_b2(k3); |
596 |
b3 = (TwoFish_P[TwoFish_P_34][b3]) ^ TwoFish_b3(k3); |
597 |
case 3: /* 192-bit keys */ |
598 |
b0 = (TwoFish_P[TwoFish_P_03][b0]) ^ TwoFish_b0(k2); |
599 |
b1 = (TwoFish_P[TwoFish_P_13][b1]) ^ TwoFish_b1(k2); |
600 |
b2 = (TwoFish_P[TwoFish_P_23][b2]) ^ TwoFish_b2(k2); |
601 |
b3 = (TwoFish_P[TwoFish_P_33][b3]) ^ TwoFish_b3(k2); |
602 |
case 2: /* 128-bit keys */ |
603 |
tfdata->sBox[ 2*i ]= |
604 |
TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0]) ^ |
605 |
TwoFish_b0(k1)]) ^ TwoFish_b0(k0)]; |
606 |
|
607 |
tfdata->sBox[ 2*i+1]= |
608 |
TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1]) ^ |
609 |
TwoFish_b1(k1)]) ^ TwoFish_b1(k0)]; |
610 |
|
611 |
tfdata->sBox[0x200+2*i ]= |
612 |
TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2]) ^ |
613 |
TwoFish_b2(k1)]) ^ TwoFish_b2(k0)]; |
614 |
|
615 |
tfdata->sBox[0x200+2*i+1]= |
616 |
TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3]) ^ |
617 |
TwoFish_b3(k1)]) ^ TwoFish_b3(k0)]; |
618 |
} |
619 |
} |
620 |
} |
621 |
|
622 |
|
623 |
/** |
624 |
* Encrypt or decrypt exactly one block of plaintext in CBC mode. |
625 |
* Use "ciphertext stealing" technique described on pg. 196 |
626 |
* of "Applied Cryptography" to encrypt the final partial |
627 |
* (i.e. <16 byte) block if necessary. |
628 |
* |
629 |
* jojo: the "ciphertext stealing" requires we read ahead and have |
630 |
* special handling for the last two blocks. Because of this, the |
631 |
* output from the TwoFish algorithm is handled internally here. |
632 |
* It would be better to have a higher level handle this as well as |
633 |
* CBC mode. Unfortunately, I've mixed the two together, which is |
634 |
* pretty crappy... The Java version separates these out correctly. |
635 |
* |
636 |
* fknobbe: I have reduced the CBC mode to work on memory buffer only. |
637 |
* Higher routines should use an intermediate buffer and handle |
638 |
* their output seperately (mainly so the data can be flushed |
639 |
* in one chunk, not seperate 16 byte blocks...) |
640 |
* |
641 |
* @param in The plaintext. |
642 |
* @param out The ciphertext |
643 |
* @param size how much to encrypt |
644 |
* @param tfdata: Pointer to the global data structure containing session keys. |
645 |
* @return none |
646 |
*/ |
647 |
void _TwoFish_BlockCrypt(unsigned char *in,unsigned char *out,unsigned long size,int decrypt,TWOFISH *tfdata) |
648 |
{ unsigned char PnMinusOne[TwoFish_BLOCK_SIZE]; |
649 |
unsigned char CnMinusOne[TwoFish_BLOCK_SIZE]; |
650 |
unsigned char CBCplusCprime[TwoFish_BLOCK_SIZE]; |
651 |
unsigned char Pn[TwoFish_BLOCK_SIZE]; |
652 |
unsigned char *p,*pout; |
653 |
unsigned long i; |
654 |
|
655 |
/* here is where we implement CBC mode and cipher block stealing */ |
656 |
if(size==TwoFish_BLOCK_SIZE) |
657 |
{ /* if we are encrypting, CBC means we XOR the plain text block with the */ |
658 |
/* previous cipher text block before encrypting */ |
659 |
if(!decrypt && tfdata->qBlockDefined) |
660 |
{ for(p=in,i=0;i<TwoFish_BLOCK_SIZE;i++,p++) |
661 |
Pn[i]=*p ^ tfdata->qBlockCrypt[i]; /* FK: I'm copying the xor'ed input into Pn... */ |
662 |
} |
663 |
else |
664 |
memcpy(Pn,in,TwoFish_BLOCK_SIZE); /* FK: same here. we work of Pn all the time. */ |
665 |
|
666 |
/* TwoFish block level encryption or decryption */ |
667 |
_TwoFish_BlockCrypt16(Pn,out,decrypt,tfdata); |
668 |
|
669 |
/* if we are decrypting, CBC means we XOR the result of the decryption */ |
670 |
/* with the previous cipher text block to get the resulting plain text */ |
671 |
if(decrypt && tfdata->qBlockDefined) |
672 |
{ for (p=out,i=0;i<TwoFish_BLOCK_SIZE;i++,p++) |
673 |
*p^=tfdata->qBlockPlain[i]; |
674 |
} |
675 |
|
676 |
/* save the input and output blocks, since CBC needs these for XOR */ |
677 |
/* operations */ |
678 |
_TwoFish_qBlockPush(Pn,out,tfdata); |
679 |
} |
680 |
else |
681 |
{ /* cipher block stealing, we are at Pn, */ |
682 |
/* but since Cn-1 must now be replaced with CnC' */ |
683 |
/* we pop it off, and recalculate Cn-1 */ |
684 |
|
685 |
if(decrypt) |
686 |
{ /* We are on an odd block, and had to do cipher block stealing, */ |
687 |
/* so the PnMinusOne has to be derived differently. */ |
688 |
|
689 |
/* First we decrypt it into CBC and C' */ |
690 |
_TwoFish_qBlockPop(CnMinusOne,PnMinusOne,tfdata); |
691 |
_TwoFish_BlockCrypt16(CnMinusOne,CBCplusCprime,decrypt,tfdata); |
692 |
|
693 |
/* we then xor the first few bytes with the "in" bytes (Cn) */ |
694 |
/* to recover Pn, which we put in out */ |
695 |
for(p=in,pout=out,i=0;i<size;i++,p++,pout++) |
696 |
*pout=*p ^ CBCplusCprime[i]; |
697 |
|
698 |
/* We now recover the original CnMinusOne, which consists of */ |
699 |
/* the first "size" bytes of "in" data, followed by the */ |
700 |
/* "Cprime" portion of CBCplusCprime */ |
701 |
for(p=in,i=0;i<size;i++,p++) |
702 |
CnMinusOne[i]=*p; |
703 |
for(;i<TwoFish_BLOCK_SIZE;i++) |
704 |
CnMinusOne[i]=CBCplusCprime[i]; |
705 |
|
706 |
/* we now decrypt CnMinusOne to get PnMinusOne xored with Cn-2 */ |
707 |
_TwoFish_BlockCrypt16(CnMinusOne,PnMinusOne,decrypt,tfdata); |
708 |
|
709 |
for(i=0;i<TwoFish_BLOCK_SIZE;i++) |
710 |
PnMinusOne[i]=PnMinusOne[i] ^ tfdata->prevCipher[i]; |
711 |
|
712 |
/* So at this point, out has PnMinusOne */ |
713 |
_TwoFish_qBlockPush(CnMinusOne,PnMinusOne,tfdata); |
714 |
_TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); |
715 |
_TwoFish_FlushOutput(out,size,tfdata); |
716 |
} |
717 |
else |
718 |
{ _TwoFish_qBlockPop(PnMinusOne,CnMinusOne,tfdata); |
719 |
memset(Pn,0,TwoFish_BLOCK_SIZE); |
720 |
memcpy(Pn,in,size); |
721 |
for(i=0;i<TwoFish_BLOCK_SIZE;i++) |
722 |
Pn[i]^=CnMinusOne[i]; |
723 |
_TwoFish_BlockCrypt16(Pn,out,decrypt,tfdata); |
724 |
_TwoFish_qBlockPush(Pn,out,tfdata); /* now we officially have Cn-1 */ |
725 |
_TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); |
726 |
_TwoFish_FlushOutput(CnMinusOne,size,tfdata); /* old Cn-1 becomes new partial Cn */ |
727 |
} |
728 |
tfdata->qBlockDefined=FALSE; |
729 |
} |
730 |
} |
731 |
|
732 |
void _TwoFish_qBlockPush(unsigned char *p,unsigned char *c,TWOFISH *tfdata) |
733 |
{ if(tfdata->qBlockDefined) |
734 |
_TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); |
735 |
memcpy(tfdata->prevCipher,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE); |
736 |
memcpy(tfdata->qBlockPlain,p,TwoFish_BLOCK_SIZE); |
737 |
memcpy(tfdata->qBlockCrypt,c,TwoFish_BLOCK_SIZE); |
738 |
tfdata->qBlockDefined=TRUE; |
739 |
} |
740 |
|
741 |
void _TwoFish_qBlockPop(unsigned char *p,unsigned char *c,TWOFISH *tfdata) |
742 |
{ memcpy(p,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE ); |
743 |
memcpy(c,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE ); |
744 |
tfdata->qBlockDefined=FALSE; |
745 |
} |
746 |
|
747 |
/* Reset's the CBC flag and zero's PrevCipher (through qBlockPlain) (important) */ |
748 |
void _TwoFish_ResetCBC(TWOFISH *tfdata) |
749 |
{ tfdata->qBlockDefined=FALSE; |
750 |
memset(tfdata->qBlockPlain,0,TwoFish_BLOCK_SIZE); |
751 |
} |
752 |
|
753 |
void _TwoFish_FlushOutput(unsigned char *b,unsigned long len,TWOFISH *tfdata) |
754 |
{ unsigned long i; |
755 |
|
756 |
for(i=0;i<len && !tfdata->dontflush;i++) |
757 |
*tfdata->output++ = *b++; |
758 |
tfdata->dontflush=FALSE; |
759 |
} |
760 |
|
761 |
void _TwoFish_BlockCrypt16(unsigned char *in,unsigned char *out,bool decrypt,TWOFISH *tfdata) |
762 |
{ unsigned long x0,x1,x2,x3; |
763 |
unsigned long k,t0,t1,R; |
764 |
|
765 |
|
766 |
x0=*in++; |
767 |
x0|=(*in++ << 8 ); |
768 |
x0|=(*in++ << 16); |
769 |
x0|=(*in++ << 24); |
770 |
x1=*in++; |
771 |
x1|=(*in++ << 8 ); |
772 |
x1|=(*in++ << 16); |
773 |
x1|=(*in++ << 24); |
774 |
x2=*in++; |
775 |
x2|=(*in++ << 8 ); |
776 |
x2|=(*in++ << 16); |
777 |
x2|=(*in++ << 24); |
778 |
x3=*in++; |
779 |
x3|=(*in++ << 8 ); |
780 |
x3|=(*in++ << 16); |
781 |
x3|=(*in++ << 24); |
782 |
|
783 |
if(decrypt) |
784 |
{ x0 ^= tfdata->subKeys[4]; /* swap input and output whitening keys when decrypting */ |
785 |
x1 ^= tfdata->subKeys[5]; |
786 |
x2 ^= tfdata->subKeys[6]; |
787 |
x3 ^= tfdata->subKeys[7]; |
788 |
|
789 |
k = 7+(TwoFish_ROUNDS*2); |
790 |
for (R = 0; R < TwoFish_ROUNDS; R += 2) |
791 |
{ t0 = _TwoFish_Fe320( tfdata->sBox, x0); |
792 |
t1 = _TwoFish_Fe323( tfdata->sBox, x1); |
793 |
x3 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; |
794 |
x3 = x3 >> 1 | x3 << 31; |
795 |
x2 = x2 << 1 | x2 >> 31; |
796 |
x2 ^= t0 + t1 + tfdata->subKeys[k--]; |
797 |
|
798 |
t0 = _TwoFish_Fe320( tfdata->sBox, x2); |
799 |
t1 = _TwoFish_Fe323( tfdata->sBox, x3); |
800 |
x1 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; |
801 |
x1 = x1 >> 1 | x1 << 31; |
802 |
x0 = x0 << 1 | x0 >> 31; |
803 |
x0 ^= t0 + t1 + tfdata->subKeys[k--]; |
804 |
} |
805 |
|
806 |
x2 ^= tfdata->subKeys[0]; |
807 |
x3 ^= tfdata->subKeys[1]; |
808 |
x0 ^= tfdata->subKeys[2]; |
809 |
x1 ^= tfdata->subKeys[3]; |
810 |
} |
811 |
else |
812 |
{ x0 ^= tfdata->subKeys[0]; |
813 |
x1 ^= tfdata->subKeys[1]; |
814 |
x2 ^= tfdata->subKeys[2]; |
815 |
x3 ^= tfdata->subKeys[3]; |
816 |
|
817 |
k = 8; |
818 |
for (R = 0; R < TwoFish_ROUNDS; R += 2) |
819 |
{ t0 = _TwoFish_Fe320( tfdata->sBox, x0); |
820 |
t1 = _TwoFish_Fe323( tfdata->sBox, x1); |
821 |
x2 ^= t0 + t1 + tfdata->subKeys[k++]; |
822 |
x2 = x2 >> 1 | x2 << 31; |
823 |
x3 = x3 << 1 | x3 >> 31; |
824 |
x3 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; |
825 |
|
826 |
t0 = _TwoFish_Fe320( tfdata->sBox, x2); |
827 |
t1 = _TwoFish_Fe323( tfdata->sBox, x3); |
828 |
x0 ^= t0 + t1 + tfdata->subKeys[k++]; |
829 |
x0 = x0 >> 1 | x0 << 31; |
830 |
x1 = x1 << 1 | x1 >> 31; |
831 |
x1 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; |
832 |
} |
833 |
|
834 |
x2 ^= tfdata->subKeys[4]; |
835 |
x3 ^= tfdata->subKeys[5]; |
836 |
x0 ^= tfdata->subKeys[6]; |
837 |
x1 ^= tfdata->subKeys[7]; |
838 |
} |
839 |
|
840 |
*out++ = (unsigned char)(x2 ); |
841 |
*out++ = (unsigned char)(x2 >> 8); |
842 |
*out++ = (unsigned char)(x2 >> 16); |
843 |
*out++ = (unsigned char)(x2 >> 24); |
844 |
|
845 |
*out++ = (unsigned char)(x3 ); |
846 |
*out++ = (unsigned char)(x3 >> 8); |
847 |
*out++ = (unsigned char)(x3 >> 16); |
848 |
*out++ = (unsigned char)(x3 >> 24); |
849 |
|
850 |
*out++ = (unsigned char)(x0 ); |
851 |
*out++ = (unsigned char)(x0 >> 8); |
852 |
*out++ = (unsigned char)(x0 >> 16); |
853 |
*out++ = (unsigned char)(x0 >> 24); |
854 |
|
855 |
*out++ = (unsigned char)(x1 ); |
856 |
*out++ = (unsigned char)(x1 >> 8); |
857 |
*out++ = (unsigned char)(x1 >> 16); |
858 |
*out++ = (unsigned char)(x1 >> 24); |
859 |
} |
860 |
|
861 |
/** |
862 |
* Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box |
863 |
* 32-bit entity from two key material 32-bit entities. |
864 |
* |
865 |
* @param k0 1st 32-bit entity. |
866 |
* @param k1 2nd 32-bit entity. |
867 |
* @return Remainder polynomial generated using RS code |
868 |
*/ |
869 |
unsigned long _TwoFish_RS_MDS_Encode(unsigned long k0,unsigned long k1) |
870 |
{ unsigned long i,r; |
871 |
|
872 |
for(r=k1,i=0;i<4;i++) /* shift 1 byte at a time */ |
873 |
TwoFish_RS_rem(r); |
874 |
r ^= k0; |
875 |
for(i=0;i<4;i++) |
876 |
TwoFish_RS_rem(r); |
877 |
|
878 |
return r; |
879 |
} |
880 |
|
881 |
unsigned long _TwoFish_F32(unsigned long k64Cnt,unsigned long x,unsigned long *k32) |
882 |
{ unsigned char b0,b1,b2,b3; |
883 |
unsigned long k0,k1,k2,k3,result = 0; |
884 |
|
885 |
b0=TwoFish_b0(x); |
886 |
b1=TwoFish_b1(x); |
887 |
b2=TwoFish_b2(x); |
888 |
b3=TwoFish_b3(x); |
889 |
k0=k32[0]; |
890 |
k1=k32[1]; |
891 |
k2=k32[2]; |
892 |
k3=k32[3]; |
893 |
|
894 |
switch (k64Cnt & 3) |
895 |
{ case 1: /* 64-bit keys */ |
896 |
result = |
897 |
TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0] & 0xFF) ^ TwoFish_b0(k0)] ^ |
898 |
TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1] & 0xFF) ^ TwoFish_b1(k0)] ^ |
899 |
TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2] & 0xFF) ^ TwoFish_b2(k0)] ^ |
900 |
TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3] & 0xFF) ^ TwoFish_b3(k0)]; |
901 |
break; |
902 |
case 0: /* 256-bit keys (same as 4) */ |
903 |
b0 = (TwoFish_P[TwoFish_P_04][b0] & 0xFF) ^ TwoFish_b0(k3); |
904 |
b1 = (TwoFish_P[TwoFish_P_14][b1] & 0xFF) ^ TwoFish_b1(k3); |
905 |
b2 = (TwoFish_P[TwoFish_P_24][b2] & 0xFF) ^ TwoFish_b2(k3); |
906 |
b3 = (TwoFish_P[TwoFish_P_34][b3] & 0xFF) ^ TwoFish_b3(k3); |
907 |
|
908 |
case 3: /* 192-bit keys */ |
909 |
b0 = (TwoFish_P[TwoFish_P_03][b0] & 0xFF) ^ TwoFish_b0(k2); |
910 |
b1 = (TwoFish_P[TwoFish_P_13][b1] & 0xFF) ^ TwoFish_b1(k2); |
911 |
b2 = (TwoFish_P[TwoFish_P_23][b2] & 0xFF) ^ TwoFish_b2(k2); |
912 |
b3 = (TwoFish_P[TwoFish_P_33][b3] & 0xFF) ^ TwoFish_b3(k2); |
913 |
case 2: /* 128-bit keys (optimize for this case) */ |
914 |
result = |
915 |
TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0] & 0xFF) ^ TwoFish_b0(k1)] & 0xFF) ^ TwoFish_b0(k0)] ^ |
916 |
TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1] & 0xFF) ^ TwoFish_b1(k1)] & 0xFF) ^ TwoFish_b1(k0)] ^ |
917 |
TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2] & 0xFF) ^ TwoFish_b2(k1)] & 0xFF) ^ TwoFish_b2(k0)] ^ |
918 |
TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3] & 0xFF) ^ TwoFish_b3(k1)] & 0xFF) ^ TwoFish_b3(k0)]; |
919 |
break; |
920 |
} |
921 |
return result; |
922 |
} |
923 |
|
924 |
unsigned long _TwoFish_Fe320(unsigned long *lsBox,unsigned long x) |
925 |
{ return lsBox[ TwoFish_b0(x)<<1 ]^ |
926 |
lsBox[ ((TwoFish_b1(x)<<1)|1)]^ |
927 |
lsBox[0x200+ (TwoFish_b2(x)<<1) ]^ |
928 |
lsBox[0x200+((TwoFish_b3(x)<<1)|1)]; |
929 |
} |
930 |
|
931 |
unsigned long _TwoFish_Fe323(unsigned long *lsBox,unsigned long x) |
932 |
{ return lsBox[ (TwoFish_b3(x)<<1) ]^ |
933 |
lsBox[ ((TwoFish_b0(x)<<1)|1)]^ |
934 |
lsBox[0x200+ (TwoFish_b1(x)<<1) ]^ |
935 |
lsBox[0x200+((TwoFish_b2(x)<<1)|1)]; |
936 |
} |
937 |
|
938 |
unsigned long _TwoFish_Fe32(unsigned long *lsBox,unsigned long x,unsigned long R) |
939 |
{ return lsBox[ 2*TwoFish__b(x,R ) ]^ |
940 |
lsBox[ 2*TwoFish__b(x,R+1)+1]^ |
941 |
lsBox[0x200+2*TwoFish__b(x,R+2) ]^ |
942 |
lsBox[0x200+2*TwoFish__b(x,R+3)+1]; |
943 |
} |
944 |
|
945 |
|
946 |
#endif |