… | |
… | |
5 | Bruce Schneier, Counterpane Systems |
5 | Bruce Schneier, Counterpane Systems |
6 | Doug Whiting, Hi/fn |
6 | Doug Whiting, Hi/fn |
7 | John Kelsey, Counterpane Systems |
7 | John Kelsey, Counterpane Systems |
8 | Chris Hall, Counterpane Systems |
8 | Chris Hall, Counterpane Systems |
9 | David Wagner, UC Berkeley |
9 | David Wagner, UC Berkeley |
10 | |
10 | |
11 | Code Author: Doug Whiting, Hi/fn |
11 | Code Author: Doug Whiting, Hi/fn |
12 | |
12 | |
13 | Version 1.00 April 1998 |
13 | Version 1.00 April 1998 |
14 | |
14 | |
15 | Copyright 1998, Hi/fn and Counterpane Systems. All rights reserved. |
15 | Copyright 1998, Hi/fn and Counterpane Systems. All rights reserved. |
16 | |
16 | |
17 | Notes: |
17 | Notes: |
18 | * Optimized version |
18 | * Optimized version |
19 | * Tab size is set to 4 characters in this file |
19 | * Tab size is set to 4 characters in this file |
20 | |
20 | |
21 | ***************************************************************************/ |
21 | ***************************************************************************/ |
… | |
… | |
52 | * Constants/Macros/Tables |
52 | * Constants/Macros/Tables |
53 | -****************************************************************************/ |
53 | -****************************************************************************/ |
54 | |
54 | |
55 | #define CONST /* help syntax from C++, NOP here */ |
55 | #define CONST /* help syntax from C++, NOP here */ |
56 | |
56 | |
57 | CONST fullSbox MDStab; /* not actually const. Initialized ONE time */ |
57 | static CONST fullSbox MDStab; /* not actually const. Initialized ONE time */ |
58 | int needToBuildMDS=1; /* is MDStab initialized yet? */ |
58 | static int needToBuildMDS=1; /* is MDStab initialized yet? */ |
59 | |
59 | |
60 | #define BIG_TAB 0 |
60 | #define BIG_TAB 0 |
61 | |
61 | |
62 | #if BIG_TAB |
62 | #if BIG_TAB |
63 | BYTE bigTab[4][256][256]; /* pre-computed S-box */ |
63 | static BYTE bigTab[4][256][256]; /* pre-computed S-box */ |
64 | #endif |
64 | #endif |
65 | |
65 | |
66 | /* number of rounds for various key sizes: 128, 192, 256 */ |
66 | /* number of rounds for various key sizes: 128, 192, 256 */ |
67 | /* (ignored for now in optimized code!) */ |
67 | /* (ignored for now in optimized code!) */ |
68 | CONST int numRounds[4]= {0,ROUNDS_128,ROUNDS_192,ROUNDS_256}; |
68 | static CONST int numRounds[4]= {0,ROUNDS_128,ROUNDS_192,ROUNDS_256}; |
69 | |
69 | |
70 | #if REENTRANT |
70 | #if REENTRANT |
71 | #define _sBox_ key->sBox8x32 |
71 | #define _sBox_ key->sBox8x32 |
72 | #else |
72 | #else |
73 | static fullSbox _sBox_; /* permuted MDStab based on keys */ |
73 | static fullSbox _sBox_; /* permuted MDStab based on keys */ |
… | |
… | |
103 | MDStab[2][p8(21)[_sBox8_(2)[_b(x,R+2)]] ^ b2(SKEY0)] ^ \ |
103 | MDStab[2][p8(21)[_sBox8_(2)[_b(x,R+2)]] ^ b2(SKEY0)] ^ \ |
104 | MDStab[3][p8(31)[_sBox8_(3)[_b(x,R+3)]] ^ b3(SKEY0)]) |
104 | MDStab[3][p8(31)[_sBox8_(3)[_b(x,R+3)]] ^ b3(SKEY0)]) |
105 | #define sbSet(N,i,J,v) { _sBox8_(N)[i+J] = v; } |
105 | #define sbSet(N,i,J,v) { _sBox8_(N)[i+J] = v; } |
106 | #define GetSboxKey DWORD SKEY0 = key->sboxKeys[0] /* local copy */ |
106 | #define GetSboxKey DWORD SKEY0 = key->sboxKeys[0] /* local copy */ |
107 | /*----------------------------------------------------------------*/ |
107 | /*----------------------------------------------------------------*/ |
108 | #elif defined(PART_KEY) |
108 | #elif defined(PART_KEY) |
109 | #define MOD_STRING "(Partial keying)" |
109 | #define MOD_STRING "(Partial keying)" |
110 | #define Fe32_(x,R)(MDStab[0][_sBox8_(0)[_b(x,R )]] ^ \ |
110 | #define Fe32_(x,R)(MDStab[0][_sBox8_(0)[_b(x,R )]] ^ \ |
111 | MDStab[1][_sBox8_(1)[_b(x,R+1)]] ^ \ |
111 | MDStab[1][_sBox8_(1)[_b(x,R+1)]] ^ \ |
112 | MDStab[2][_sBox8_(2)[_b(x,R+2)]] ^ \ |
112 | MDStab[2][_sBox8_(2)[_b(x,R+2)]] ^ \ |
113 | MDStab[3][_sBox8_(3)[_b(x,R+3)]]) |
113 | MDStab[3][_sBox8_(3)[_b(x,R+3)]]) |
114 | #define sbSet(N,i,J,v) { _sBox8_(N)[i+J] = v; } |
114 | #define sbSet(N,i,J,v) { _sBox8_(N)[i+J] = v; } |
115 | #define GetSboxKey |
115 | #define GetSboxKey |
116 | /*----------------------------------------------------------------*/ |
116 | /*----------------------------------------------------------------*/ |
117 | #else /* default is FULL_KEY */ |
117 | #else /* default is FULL_KEY */ |
118 | #ifndef FULL_KEY |
118 | #ifndef FULL_KEY |
119 | #define FULL_KEY 1 |
119 | #define FULL_KEY 1 |
120 | #endif |
120 | #endif |
… | |
… | |
134 | */ |
134 | */ |
135 | #define Fe32_(x,R) (_sBox_[0][2*_b(x,R )] ^ _sBox_[0][2*_b(x,R+1)+1] ^ \ |
135 | #define Fe32_(x,R) (_sBox_[0][2*_b(x,R )] ^ _sBox_[0][2*_b(x,R+1)+1] ^ \ |
136 | _sBox_[2][2*_b(x,R+2)] ^ _sBox_[2][2*_b(x,R+3)+1]) |
136 | _sBox_[2][2*_b(x,R+2)] ^ _sBox_[2][2*_b(x,R+3)+1]) |
137 | /* set a single S-box value, given the input byte */ |
137 | /* set a single S-box value, given the input byte */ |
138 | #define sbSet(N,i,J,v) { _sBox_[N&2][2*i+(N&1)+2*J]=MDStab[N][v]; } |
138 | #define sbSet(N,i,J,v) { _sBox_[N&2][2*i+(N&1)+2*J]=MDStab[N][v]; } |
139 | #define GetSboxKey |
139 | #define GetSboxKey |
140 | #endif |
140 | #endif |
141 | |
141 | |
142 | /* macro(s) for debugging help */ |
142 | /* macro(s) for debugging help */ |
143 | #define CHECK_TABLE 0 /* nonzero --> compare against "slow" table */ |
143 | #define CHECK_TABLE 0 /* nonzero --> compare against "slow" table */ |
144 | #define VALIDATE_PARMS 0 /* disable for full speed */ |
144 | #define VALIDATE_PARMS 0 /* disable for full speed */ |
145 | |
145 | |
146 | /* end of debug macros */ |
146 | /* end of debug macros */ |
147 | |
147 | |
148 | #ifdef GetCodeSize |
148 | #ifdef GetCodeSize |
149 | extern DWORD Here(DWORD x); /* return caller's address! */ |
149 | static extern DWORD Here(DWORD x); /* return caller's address! */ |
150 | DWORD TwofishCodeStart(void) { return Here(0); } |
150 | static DWORD TwofishCodeStart(void) { return Here(0); } |
151 | #endif |
151 | #endif |
152 | |
152 | |
153 | /* |
153 | /* |
154 | +***************************************************************************** |
154 | +***************************************************************************** |
155 | * |
155 | * |
… | |
… | |
157 | * |
157 | * |
158 | * Function: Handle table use checking |
158 | * Function: Handle table use checking |
159 | * |
159 | * |
160 | * Arguments: op = what to do (see TAB_* defns in AES.H) |
160 | * Arguments: op = what to do (see TAB_* defns in AES.H) |
161 | * |
161 | * |
162 | * Return: TRUE --> done (for TAB_QUERY) |
162 | * Return: TRUE --> done (for TAB_QUERY) |
163 | * |
163 | * |
164 | * Notes: This routine is for use in generating the tables KAT file. |
164 | * Notes: This routine is for use in generating the tables KAT file. |
165 | * For this optimized version, we don't actually track table usage, |
165 | * For this optimized version, we don't actually track table usage, |
166 | * since it would make the macros incredibly ugly. Instead we just |
166 | * since it would make the macros incredibly ugly. Instead we just |
167 | * run for a fixed number of queries and then say we're done. |
167 | * run for a fixed number of queries and then say we're done. |
168 | * |
168 | * |
169 | -****************************************************************************/ |
169 | -****************************************************************************/ |
170 | int TableOp(int op) |
170 | static int TableOp(int op) |
171 | { |
171 | { |
172 | static int queryCnt=0; |
172 | static int queryCnt=0; |
173 | |
173 | |
174 | switch (op) |
174 | switch (op) |
175 | { |
175 | { |
… | |
… | |
203 | * |
203 | * |
204 | * Return: The output of the keyed permutation applied to x. |
204 | * Return: The output of the keyed permutation applied to x. |
205 | * |
205 | * |
206 | * Notes: |
206 | * Notes: |
207 | * This function is a keyed 32-bit permutation. It is the major building |
207 | * This function is a keyed 32-bit permutation. It is the major building |
208 | * block for the Twofish round function, including the four keyed 8x8 |
208 | * block for the Twofish round function, including the four keyed 8x8 |
209 | * permutations and the 4x4 MDS matrix multiply. This function is used |
209 | * permutations and the 4x4 MDS matrix multiply. This function is used |
210 | * both for generating round subkeys and within the round function on the |
210 | * both for generating round subkeys and within the round function on the |
211 | * block being encrypted. |
211 | * block being encrypted. |
212 | * |
212 | * |
213 | * This version is fairly slow and pedagogical, although a smartcard would |
213 | * This version is fairly slow and pedagogical, although a smartcard would |
214 | * probably perform the operation exactly this way in firmware. For |
214 | * probably perform the operation exactly this way in firmware. For |
215 | * ultimate performance, the entire operation can be completed with four |
215 | * ultimate performance, the entire operation can be completed with four |
216 | * lookups into four 256x32-bit tables, with three dword xors. |
216 | * lookups into four 256x32-bit tables, with three dword xors. |
217 | * |
217 | * |
218 | * The MDS matrix is defined in TABLE.H. To multiply by Mij, just use the |
218 | * The MDS matrix is defined in TABLE.H. To multiply by Mij, just use the |
219 | * macro Mij(x). |
219 | * macro Mij(x). |
220 | * |
220 | * |
221 | -****************************************************************************/ |
221 | -****************************************************************************/ |
222 | DWORD f32(DWORD x,CONST DWORD *k32,int keyLen) |
222 | static DWORD f32(DWORD x,CONST DWORD *k32,int keyLen) |
223 | { |
223 | { |
224 | BYTE b[4]; |
224 | BYTE b[4]; |
225 | |
225 | |
226 | /* Run each byte thru 8x8 S-boxes, xoring with key byte at each stage. */ |
226 | /* Run each byte thru 8x8 S-boxes, xoring with key byte at each stage. */ |
227 | /* Note that each byte goes through a different combination of S-boxes.*/ |
227 | /* Note that each byte goes through a different combination of S-boxes.*/ |
228 | |
228 | |
229 | *((DWORD *)b) = Bswap(x); /* make b[0] = LSB, b[3] = MSB */ |
229 | *((DWORD *)b) = Bswap(x); /* make b[0] = LSB, b[3] = MSB */ |
230 | switch (((keyLen + 63)/64) & 3) |
230 | switch (((keyLen + 63)/64) & 3) |
… | |
… | |
275 | * the performance impact of this routine is imperceptible. The RS code |
275 | * the performance impact of this routine is imperceptible. The RS code |
276 | * chosen has "simple" coefficients to allow smartcard/hardware implementation |
276 | * chosen has "simple" coefficients to allow smartcard/hardware implementation |
277 | * without lookup tables. |
277 | * without lookup tables. |
278 | * |
278 | * |
279 | -****************************************************************************/ |
279 | -****************************************************************************/ |
280 | DWORD RS_MDS_Encode(DWORD k0,DWORD k1) |
280 | static DWORD RS_MDS_Encode(DWORD k0,DWORD k1) |
281 | { |
281 | { |
282 | int i,j; |
282 | int i,j; |
283 | DWORD r; |
283 | DWORD r; |
284 | |
284 | |
285 | for (i=r=0;i<2;i++) |
285 | for (i=r=0;i<2;i++) |
286 | { |
286 | { |
287 | r ^= (i) ? k0 : k1; /* merge in 32 more key bits */ |
287 | r ^= (i) ? k0 : k1; /* merge in 32 more key bits */ |
288 | for (j=0;j<4;j++) /* shift one byte at a time */ |
288 | for (j=0;j<4;j++) /* shift one byte at a time */ |
289 | RS_rem(r); |
289 | RS_rem(r); |
290 | } |
290 | } |
291 | return r; |
291 | return r; |
292 | } |
292 | } |
293 | |
293 | |
294 | |
294 | |
… | |
… | |
306 | * Notes: |
306 | * Notes: |
307 | * Here we precompute all the fixed MDS table. This only needs to be done |
307 | * Here we precompute all the fixed MDS table. This only needs to be done |
308 | * one time at initialization, after which the table is "CONST". |
308 | * one time at initialization, after which the table is "CONST". |
309 | * |
309 | * |
310 | -****************************************************************************/ |
310 | -****************************************************************************/ |
311 | void BuildMDS(void) |
311 | static void BuildMDS(void) |
312 | { |
312 | { |
313 | int i; |
313 | int i; |
314 | DWORD d; |
314 | DWORD d; |
315 | BYTE m1[2],mX[2],mY[4]; |
315 | BYTE m1[2],mX[2],mY[4]; |
316 | |
316 | |
… | |
… | |
326 | |
326 | |
327 | #undef Mul_1 /* change what the pre-processor does with Mij */ |
327 | #undef Mul_1 /* change what the pre-processor does with Mij */ |
328 | #undef Mul_X |
328 | #undef Mul_X |
329 | #undef Mul_Y |
329 | #undef Mul_Y |
330 | #define Mul_1 m1 /* It will now access m01[], m5B[], and mEF[] */ |
330 | #define Mul_1 m1 /* It will now access m01[], m5B[], and mEF[] */ |
331 | #define Mul_X mX |
331 | #define Mul_X mX |
332 | #define Mul_Y mY |
332 | #define Mul_Y mY |
333 | |
333 | |
334 | #define SetMDS(N) \ |
334 | #define SetMDS(N) \ |
335 | b0(d) = M0##N[P_##N##0]; \ |
335 | b0(d) = M0##N[P_##N##0]; \ |
336 | b1(d) = M1##N[P_##N##0]; \ |
336 | b1(d) = M1##N[P_##N##0]; \ |
… | |
… | |
347 | #undef Mul_X |
347 | #undef Mul_X |
348 | #undef Mul_Y |
348 | #undef Mul_Y |
349 | #define Mul_1 Mx_1 /* re-enable true multiply */ |
349 | #define Mul_1 Mx_1 /* re-enable true multiply */ |
350 | #define Mul_X Mx_X |
350 | #define Mul_X Mx_X |
351 | #define Mul_Y Mx_Y |
351 | #define Mul_Y Mx_Y |
352 | |
352 | |
353 | #if BIG_TAB |
353 | #if BIG_TAB |
354 | { |
354 | { |
355 | int j,k; |
355 | int j,k; |
356 | BYTE *q0,*q1; |
356 | BYTE *q0,*q1; |
357 | |
357 | |
… | |
… | |
390 | * This optimization allows both blockEncrypt and blockDecrypt to use the same |
390 | * This optimization allows both blockEncrypt and blockDecrypt to use the same |
391 | * "fallthru" switch statement based on the number of rounds. |
391 | * "fallthru" switch statement based on the number of rounds. |
392 | * Note that key->numRounds must be even and >= 2 here. |
392 | * Note that key->numRounds must be even and >= 2 here. |
393 | * |
393 | * |
394 | -****************************************************************************/ |
394 | -****************************************************************************/ |
395 | void ReverseRoundSubkeys(keyInstance *key,BYTE newDir) |
395 | static void ReverseRoundSubkeys(keyInstance *key,BYTE newDir) |
396 | { |
396 | { |
397 | DWORD t0,t1; |
397 | DWORD t0,t1; |
398 | register DWORD *r0=key->subKeys+ROUND_SUBKEYS; |
398 | register DWORD *r0=key->subKeys+ROUND_SUBKEYS; |
399 | register DWORD *r1=r0 + 2*key->numRounds - 2; |
399 | register DWORD *r1=r0 + 2*key->numRounds - 2; |
400 | |
400 | |
… | |
… | |
431 | * The penalty is nearly 50%! So we take the code size hit for inlining for |
431 | * The penalty is nearly 50%! So we take the code size hit for inlining for |
432 | * Borland, while Microsoft happily works with a call. |
432 | * Borland, while Microsoft happily works with a call. |
433 | * |
433 | * |
434 | -****************************************************************************/ |
434 | -****************************************************************************/ |
435 | #if defined(__BORLANDC__) /* do it inline */ |
435 | #if defined(__BORLANDC__) /* do it inline */ |
436 | #define Xor32(dst,src,i) { ((DWORD *)dst)[i] = ((DWORD *)src)[i] ^ tmpX; } |
436 | #define Xor32(dst,src,i) { ((DWORD *)dst)[i] = ((DWORD *)src)[i] ^ tmpX; } |
437 | #define Xor256(dst,src,b) \ |
437 | #define Xor256(dst,src,b) \ |
438 | { \ |
438 | { \ |
439 | register DWORD tmpX=0x01010101u * b;\ |
439 | register DWORD tmpX=0x01010101u * b;\ |
440 | for (i=0;i<64;i+=4) \ |
440 | for (i=0;i<64;i+=4) \ |
441 | { Xor32(dst,src,i ); Xor32(dst,src,i+1); Xor32(dst,src,i+2); Xor32(dst,src,i+3); } \ |
441 | { Xor32(dst,src,i ); Xor32(dst,src,i+1); Xor32(dst,src,i+2); Xor32(dst,src,i+3); } \ |
442 | } |
442 | } |
443 | #else /* do it as a function call */ |
443 | #else /* do it as a function call */ |
444 | void Xor256(void *dst,void *src,BYTE b) |
444 | static void Xor256(void *dst,void *src,BYTE b) |
445 | { |
445 | { |
446 | register DWORD x=b*0x01010101u; /* replicate byte to all four bytes */ |
446 | register DWORD x=b*0x01010101u; /* replicate byte to all four bytes */ |
447 | register DWORD *d=(DWORD *)dst; |
447 | register DWORD *d=(DWORD *)dst; |
448 | register DWORD *s=(DWORD *)src; |
448 | register DWORD *s=(DWORD *)src; |
449 | #define X_8(N) { d[N]=s[N] ^ x; d[N+1]=s[N+1] ^ x; } |
449 | #define X_8(N) { d[N]=s[N] ^ x; d[N+1]=s[N+1] ^ x; } |
… | |
… | |
466 | * |
466 | * |
467 | * Return: TRUE on success |
467 | * Return: TRUE on success |
468 | * |
468 | * |
469 | * Notes: |
469 | * Notes: |
470 | * Here we precompute all the round subkeys, although that is not actually |
470 | * Here we precompute all the round subkeys, although that is not actually |
471 | * required. For example, on a smartcard, the round subkeys can |
471 | * required. For example, on a smartcard, the round subkeys can |
472 | * be generated on-the-fly using f32() |
472 | * be generated on-the-fly using f32() |
473 | * |
473 | * |
474 | -****************************************************************************/ |
474 | -****************************************************************************/ |
475 | int reKey(keyInstance *key) |
475 | static int reKey(keyInstance *key) |
476 | { |
476 | { |
477 | int i,j,k64Cnt,keyLen; |
477 | int i,j,k64Cnt,keyLen; |
478 | int subkeyCnt; |
478 | int subkeyCnt; |
479 | DWORD A=0,B=0,q; |
479 | DWORD A=0,B=0,q; |
480 | DWORD sKey[MAX_KEY_BITS/64],k32e[MAX_KEY_BITS/64],k32o[MAX_KEY_BITS/64]; |
480 | DWORD sKey[MAX_KEY_BITS/64],k32e[MAX_KEY_BITS/64],k32o[MAX_KEY_BITS/64]; |
… | |
… | |
545 | reKey_86(key); |
545 | reKey_86(key); |
546 | } |
546 | } |
547 | else |
547 | else |
548 | #endif |
548 | #endif |
549 | { |
549 | { |
550 | for (i=q=0;i<subkeyCnt/2;i++,q+=SK_STEP) |
550 | for (i=q=0;i<subkeyCnt/2;i++,q+=SK_STEP) |
551 | { /* compute round subkeys for PHT */ |
551 | { /* compute round subkeys for PHT */ |
552 | F32(A,q ,k32e); /* A uses even key dwords */ |
552 | F32(A,q ,k32e); /* A uses even key dwords */ |
553 | F32(B,q+SK_BUMP,k32o); /* B uses odd key dwords */ |
553 | F32(B,q+SK_BUMP,k32o); /* B uses odd key dwords */ |
554 | B = ROL(B,8); |
554 | B = ROL(B,8); |
555 | key->subKeys[2*i ] = A+B; /* combine with a PHT */ |
555 | key->subKeys[2*i ] = A+B; /* combine with a PHT */ |
… | |
… | |
639 | assert(f32(q,key->sboxKeys,keyLen) == Fe32_(q,0)); |
639 | assert(f32(q,key->sboxKeys,keyLen) == Fe32_(q,0)); |
640 | #endif |
640 | #endif |
641 | } |
641 | } |
642 | #endif /* CHECK_TABLE */ |
642 | #endif /* CHECK_TABLE */ |
643 | |
643 | |
644 | if (key->direction == DIR_ENCRYPT) |
644 | if (key->direction == DIR_ENCRYPT) |
645 | ReverseRoundSubkeys(key,DIR_ENCRYPT); /* reverse the round subkey order */ |
645 | ReverseRoundSubkeys(key,DIR_ENCRYPT); /* reverse the round subkey order */ |
646 | |
646 | |
647 | return TRUE; |
647 | return TRUE; |
648 | } |
648 | } |
649 | /* |
649 | /* |
… | |
… | |
662 | * else error code (e.g., BAD_KEY_DIR) |
662 | * else error code (e.g., BAD_KEY_DIR) |
663 | * |
663 | * |
664 | * Notes: This parses the key bits from keyMaterial. Zeroes out unused key bits |
664 | * Notes: This parses the key bits from keyMaterial. Zeroes out unused key bits |
665 | * |
665 | * |
666 | -****************************************************************************/ |
666 | -****************************************************************************/ |
667 | int makeKey(keyInstance *key, BYTE direction, int keyLen,CONST char *keyMaterial) |
667 | static int makeKey(keyInstance *key, BYTE direction, int keyLen,CONST char *keyMaterial) |
668 | { |
668 | { |
669 | int i; |
669 | int i; |
670 | |
670 | |
671 | #if VALIDATE_PARMS /* first, sanity check on parameters */ |
671 | #if VALIDATE_PARMS /* first, sanity check on parameters */ |
672 | if (key == NULL) |
672 | if (key == NULL) |
673 | return BAD_KEY_INSTANCE;/* must have a keyInstance to initialize */ |
673 | return BAD_KEY_INSTANCE;/* must have a keyInstance to initialize */ |
674 | if ((direction != DIR_ENCRYPT) && (direction != DIR_DECRYPT)) |
674 | if ((direction != DIR_ENCRYPT) && (direction != DIR_DECRYPT)) |
675 | return BAD_KEY_DIR; /* must have valid direction */ |
675 | return BAD_KEY_DIR; /* must have valid direction */ |
676 | if ((keyLen > MAX_KEY_BITS) || (keyLen < 8) || (keyLen & 0x3F)) |
676 | if ((keyLen > MAX_KEY_BITS) || (keyLen < 8) || (keyLen & 0x3F)) |
677 | return BAD_KEY_MAT; /* length must be valid */ |
677 | return BAD_KEY_MAT; /* length must be valid */ |
… | |
… | |
687 | key->numRounds = numRounds[(keyLen-1)/64]; |
687 | key->numRounds = numRounds[(keyLen-1)/64]; |
688 | memset(key->key32,0,sizeof(key->key32)); /* zero unused bits */ |
688 | memset(key->key32,0,sizeof(key->key32)); /* zero unused bits */ |
689 | |
689 | |
690 | if (keyMaterial == NULL) |
690 | if (keyMaterial == NULL) |
691 | return TRUE; /* allow a "dummy" call */ |
691 | return TRUE; /* allow a "dummy" call */ |
692 | |
692 | |
693 | for (i=0;i<keyLen/32;i++) /* make byte-oriented copy for CFB1 */ |
693 | for (i=0;i<keyLen/32;i++) /* make byte-oriented copy for CFB1 */ |
694 | key->key32[i] = (((unsigned char *)keyMaterial)[i*4+0] << 0) |
694 | key->key32[i] = (((unsigned char *)keyMaterial)[i*4+0] << 0) |
695 | | (((unsigned char *)keyMaterial)[i*4+1] << 8) |
695 | | (((unsigned char *)keyMaterial)[i*4+1] << 8) |
696 | | (((unsigned char *)keyMaterial)[i*4+2] << 16) |
696 | | (((unsigned char *)keyMaterial)[i*4+2] << 16) |
697 | | (((unsigned char *)keyMaterial)[i*4+3] << 24); |
697 | | (((unsigned char *)keyMaterial)[i*4+3] << 24); |
… | |
… | |
713 | * |
713 | * |
714 | * Return: TRUE on success |
714 | * Return: TRUE on success |
715 | * else error code (e.g., BAD_CIPHER_MODE) |
715 | * else error code (e.g., BAD_CIPHER_MODE) |
716 | * |
716 | * |
717 | -****************************************************************************/ |
717 | -****************************************************************************/ |
718 | int cipherInit(cipherInstance *cipher, BYTE mode,CONST char *IV) |
718 | static int cipherInit(cipherInstance *cipher, BYTE mode,CONST char *IV) |
719 | { |
719 | { |
720 | int i; |
720 | int i; |
721 | #if VALIDATE_PARMS /* first, sanity check on parameters */ |
721 | #if VALIDATE_PARMS /* first, sanity check on parameters */ |
722 | if (cipher == NULL) |
722 | if (cipher == NULL) |
723 | return BAD_PARAMS; /* must have a cipherInstance to initialize */ |
723 | return BAD_PARAMS; /* must have a cipherInstance to initialize */ |
724 | if ((mode != MODE_ECB) && (mode != MODE_CBC) && (mode != MODE_CFB1)) |
724 | if ((mode != MODE_ECB) && (mode != MODE_CBC) && (mode != MODE_CFB1)) |
725 | return BAD_CIPHER_MODE; /* must have valid cipher mode */ |
725 | return BAD_CIPHER_MODE; /* must have valid cipher mode */ |
726 | cipher->cipherSig = VALID_SIG; |
726 | cipher->cipherSig = VALID_SIG; |
727 | #if ALIGN32 |
727 | #if ALIGN32 |
… | |
… | |
758 | * Return: # bits ciphered (>= 0) |
758 | * Return: # bits ciphered (>= 0) |
759 | * else error code (e.g., BAD_CIPHER_STATE, BAD_KEY_MATERIAL) |
759 | * else error code (e.g., BAD_CIPHER_STATE, BAD_KEY_MATERIAL) |
760 | * |
760 | * |
761 | * Notes: The only supported block size for ECB/CBC modes is BLOCK_SIZE bits. |
761 | * Notes: The only supported block size for ECB/CBC modes is BLOCK_SIZE bits. |
762 | * If inputLen is not a multiple of BLOCK_SIZE bits in those modes, |
762 | * If inputLen is not a multiple of BLOCK_SIZE bits in those modes, |
763 | * an error BAD_INPUT_LEN is returned. In CFB1 mode, all block |
763 | * an error BAD_INPUT_LEN is returned. In CFB1 mode, all block |
764 | * sizes can be supported. |
764 | * sizes can be supported. |
765 | * |
765 | * |
766 | -****************************************************************************/ |
766 | -****************************************************************************/ |
767 | int blockEncrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input, |
767 | static int blockEncrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input, |
768 | int inputLen, BYTE *outBuffer) |
768 | int inputLen, BYTE *outBuffer) |
769 | { |
769 | { |
770 | int i,n; /* loop counters */ |
770 | int i,n; /* loop counters */ |
771 | DWORD x[BLOCK_SIZE/32]; /* block being encrypted */ |
771 | DWORD x[BLOCK_SIZE/32]; /* block being encrypted */ |
772 | DWORD t0,t1; /* temp variables */ |
772 | DWORD t0,t1; /* temp variables */ |
… | |
… | |
824 | #ifdef USE_ASM |
824 | #ifdef USE_ASM |
825 | if ((useAsm & 1) && (inputLen)) |
825 | if ((useAsm & 1) && (inputLen)) |
826 | #ifdef COMPILE_KEY |
826 | #ifdef COMPILE_KEY |
827 | if (key->keySig == VALID_SIG) |
827 | if (key->keySig == VALID_SIG) |
828 | return ((CipherProc *)(key->encryptFuncPtr))(cipher,key,input,inputLen,outBuffer); |
828 | return ((CipherProc *)(key->encryptFuncPtr))(cipher,key,input,inputLen,outBuffer); |
829 | #else |
829 | #else |
830 | return (*blockEncrypt_86)(cipher,key,input,inputLen,outBuffer); |
830 | return (*blockEncrypt_86)(cipher,key,input,inputLen,outBuffer); |
831 | #endif |
831 | #endif |
832 | #endif |
832 | #endif |
833 | /* make local copy of subkeys for speed */ |
833 | /* make local copy of subkeys for speed */ |
834 | memcpy(sk,key->subKeys,sizeof(DWORD)*(ROUND_SUBKEYS+2*rounds)); |
834 | memcpy(sk,key->subKeys,sizeof(DWORD)*(ROUND_SUBKEYS+2*rounds)); |
… | |
… | |
915 | * Return: # bits ciphered (>= 0) |
915 | * Return: # bits ciphered (>= 0) |
916 | * else error code (e.g., BAD_CIPHER_STATE, BAD_KEY_MATERIAL) |
916 | * else error code (e.g., BAD_CIPHER_STATE, BAD_KEY_MATERIAL) |
917 | * |
917 | * |
918 | * Notes: The only supported block size for ECB/CBC modes is BLOCK_SIZE bits. |
918 | * Notes: The only supported block size for ECB/CBC modes is BLOCK_SIZE bits. |
919 | * If inputLen is not a multiple of BLOCK_SIZE bits in those modes, |
919 | * If inputLen is not a multiple of BLOCK_SIZE bits in those modes, |
920 | * an error BAD_INPUT_LEN is returned. In CFB1 mode, all block |
920 | * an error BAD_INPUT_LEN is returned. In CFB1 mode, all block |
921 | * sizes can be supported. |
921 | * sizes can be supported. |
922 | * |
922 | * |
923 | -****************************************************************************/ |
923 | -****************************************************************************/ |
924 | int blockDecrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input, |
924 | static int blockDecrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input, |
925 | int inputLen, BYTE *outBuffer) |
925 | int inputLen, BYTE *outBuffer) |
926 | { |
926 | { |
927 | int i,n; /* loop counters */ |
927 | int i,n; /* loop counters */ |
928 | DWORD x[BLOCK_SIZE/32]; /* block being encrypted */ |
928 | DWORD x[BLOCK_SIZE/32]; /* block being encrypted */ |
929 | DWORD t0,t1; /* temp variables */ |
929 | DWORD t0,t1; /* temp variables */ |
… | |
… | |
981 | #ifdef USE_ASM |
981 | #ifdef USE_ASM |
982 | if ((useAsm & 2) && (inputLen)) |
982 | if ((useAsm & 2) && (inputLen)) |
983 | #ifdef COMPILE_KEY |
983 | #ifdef COMPILE_KEY |
984 | if (key->keySig == VALID_SIG) |
984 | if (key->keySig == VALID_SIG) |
985 | return ((CipherProc *)(key->decryptFuncPtr))(cipher,key,input,inputLen,outBuffer); |
985 | return ((CipherProc *)(key->decryptFuncPtr))(cipher,key,input,inputLen,outBuffer); |
986 | #else |
986 | #else |
987 | return (*blockDecrypt_86)(cipher,key,input,inputLen,outBuffer); |
987 | return (*blockDecrypt_86)(cipher,key,input,inputLen,outBuffer); |
988 | #endif |
988 | #endif |
989 | #endif |
989 | #endif |
990 | /* make local copy of subkeys for speed */ |
990 | /* make local copy of subkeys for speed */ |
991 | memcpy(sk,key->subKeys,sizeof(DWORD)*(ROUND_SUBKEYS+2*rounds)); |
991 | memcpy(sk,key->subKeys,sizeof(DWORD)*(ROUND_SUBKEYS+2*rounds)); |
… | |
… | |
1062 | |
1062 | |
1063 | return inputLen; |
1063 | return inputLen; |
1064 | } |
1064 | } |
1065 | |
1065 | |
1066 | #ifdef GetCodeSize |
1066 | #ifdef GetCodeSize |
1067 | DWORD TwofishCodeSize(void) |
1067 | static DWORD TwofishCodeSize(void) |
1068 | { |
1068 | { |
1069 | DWORD x= Here(0); |
1069 | DWORD x= Here(0); |
1070 | #ifdef USE_ASM |
1070 | #ifdef USE_ASM |
1071 | if (useAsm & 3) |
1071 | if (useAsm & 3) |
1072 | return TwofishAsmCodeSize(); |
1072 | return TwofishAsmCodeSize(); |