… | |
… | |
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 */ |
… | |
… | |
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 | * |
… | |
… | |
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 | { |
… | |
… | |
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.*/ |
… | |
… | |
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++) |
… | |
… | |
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 | |
… | |
… | |
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 | |
… | |
… | |
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; } |
… | |
… | |
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]; |
… | |
… | |
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) |
… | |
… | |
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 */ |
… | |
… | |
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 */ |
… | |
… | |
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 */ |
… | |
… | |
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(); |