From d1e726bc6d20bf64ef09e3a8c05b75ef96942109 Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 10 Mar 2000 17:27:20 +0000 Subject: [PATCH] New DES implementation, replacing Eric Young's. All of PuTTY is now under my own copyright and there are no tricky licensing issues! git-svn-id: svn://svn.tartarus.org/sgt/putty@398 cda61777-01e9-0310-a592-d414129be87e --- LICENCE | 3 +- sshdes.c | 1213 +++++++++++++++++++++++++----------------------------------- win_res.rc | 45 ++- 3 files changed, 533 insertions(+), 728 deletions(-) diff --git a/LICENCE b/LICENCE index c3bfcced..4632573d 100644 --- a/LICENCE +++ b/LICENCE @@ -1,5 +1,4 @@ -PuTTY is copyright 1997-1999 Simon Tatham. Portions copyright Eric -Young. +PuTTY is copyright 1997-2000 Simon Tatham. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files diff --git a/sshdes.c b/sshdes.c index 83d4d26a..eace6583 100644 --- a/sshdes.c +++ b/sshdes.c @@ -1,671 +1,544 @@ #include #include "ssh.h" +/* des.c - implementation of DES + */ + /* + * Description of DES + * + * Unlike the description in FIPS 46, I'm going to use _sensible_ indices: + * bits in an n-bit word are numbered from 0 at the LSB to n-1 at the MSB. + * And S-boxes are indexed by six consecutive bits, not by the outer two + * followed by the middle four. + * + * The DES encryption routine requires a 64-bit input, and a key schedule K + * containing 16 48-bit elements. + * + * First the input is permuted by the initial permutation IP. + * Then the input is split into 32-bit words L and R. (L is the MSW.) + * Next, 16 rounds. In each round: + * (L, R) <- (R, L xor f(R, K[i])) + * Then the pre-output words L and R are swapped. + * Then L and R are glued back together into a 64-bit word. (L is the MSW, + * again, but since we just swapped them, the MSW is the R that came out + * of the last round.) + * The 64-bit output block is permuted by the inverse of IP and returned. + * + * Decryption is identical except that the elements of K are used in the + * opposite order. (This wouldn't work if that word swap didn't happen.) + * + * The function f, used in each round, accepts a 32-bit word R and a + * 48-bit key block K. It produces a 32-bit output. + * + * First R is expanded to 48 bits using the bit-selection function E. + * The resulting 48-bit block is XORed with the key block K to produce + * a 48-bit block X. + * This block X is split into eight groups of 6 bits. Each group of 6 + * bits is then looked up in one of the eight S-boxes to convert + * it to 4 bits. These eight groups of 4 bits are glued back + * together to produce a 32-bit preoutput block. + * The preoutput block is permuted using the permutation P and returned. + * + * Key setup maps a 64-bit key word into a 16x48-bit key schedule. Although + * the approved input format for the key is a 64-bit word, eight of the + * bits are discarded, so the actual quantity of key used is 56 bits. + * + * First the input key is converted to two 28-bit words C and D using + * the bit-selection function PC1. + * Then 16 rounds of key setup occur. In each round, C and D are each + * rotated left by either 1 or 2 bits (depending on which round), and + * then converted into a key schedule element using the bit-selection + * function PC2. + * + * That's the actual algorithm. Now for the tedious details: all those + * painful permutations and lookup tables. + * + * IP is a 64-to-64 bit permutation. Its output contains the following + * bits of its input (listed in order MSB to LSB of output). + * + * 6 14 22 30 38 46 54 62 4 12 20 28 36 44 52 60 + * 2 10 18 26 34 42 50 58 0 8 16 24 32 40 48 56 + * 7 15 23 31 39 47 55 63 5 13 21 29 37 45 53 61 + * 3 11 19 27 35 43 51 59 1 9 17 25 33 41 49 57 + * + * E is a 32-to-48 bit selection function. Its output contains the following + * bits of its input (listed in order MSB to LSB of output). + * + * 0 31 30 29 28 27 28 27 26 25 24 23 24 23 22 21 20 19 20 19 18 17 16 15 + * 16 15 14 13 12 11 12 11 10 9 8 7 8 7 6 5 4 3 4 3 2 1 0 31 + * + * The S-boxes are arbitrary table-lookups each mapping a 6-bit input to a + * 4-bit output. In other words, each S-box is an array[64] of 4-bit numbers. + * The S-boxes are listed below. The first S-box listed is applied to the + * most significant six bits of the block X; the last one is applied to the + * least significant. + * + * 14 0 4 15 13 7 1 4 2 14 15 2 11 13 8 1 + * 3 10 10 6 6 12 12 11 5 9 9 5 0 3 7 8 + * 4 15 1 12 14 8 8 2 13 4 6 9 2 1 11 7 + * 15 5 12 11 9 3 7 14 3 10 10 0 5 6 0 13 + * + * 15 3 1 13 8 4 14 7 6 15 11 2 3 8 4 14 + * 9 12 7 0 2 1 13 10 12 6 0 9 5 11 10 5 + * 0 13 14 8 7 10 11 1 10 3 4 15 13 4 1 2 + * 5 11 8 6 12 7 6 12 9 0 3 5 2 14 15 9 + * + * 10 13 0 7 9 0 14 9 6 3 3 4 15 6 5 10 + * 1 2 13 8 12 5 7 14 11 12 4 11 2 15 8 1 + * 13 1 6 10 4 13 9 0 8 6 15 9 3 8 0 7 + * 11 4 1 15 2 14 12 3 5 11 10 5 14 2 7 12 + * + * 7 13 13 8 14 11 3 5 0 6 6 15 9 0 10 3 + * 1 4 2 7 8 2 5 12 11 1 12 10 4 14 15 9 + * 10 3 6 15 9 0 0 6 12 10 11 1 7 13 13 8 + * 15 9 1 4 3 5 14 11 5 12 2 7 8 2 4 14 + * + * 2 14 12 11 4 2 1 12 7 4 10 7 11 13 6 1 + * 8 5 5 0 3 15 15 10 13 3 0 9 14 8 9 6 + * 4 11 2 8 1 12 11 7 10 1 13 14 7 2 8 13 + * 15 6 9 15 12 0 5 9 6 10 3 4 0 5 14 3 + * + * 12 10 1 15 10 4 15 2 9 7 2 12 6 9 8 5 + * 0 6 13 1 3 13 4 14 14 0 7 11 5 3 11 8 + * 9 4 14 3 15 2 5 12 2 9 8 5 12 15 3 10 + * 7 11 0 14 4 1 10 7 1 6 13 0 11 8 6 13 + * + * 4 13 11 0 2 11 14 7 15 4 0 9 8 1 13 10 + * 3 14 12 3 9 5 7 12 5 2 10 15 6 8 1 6 + * 1 6 4 11 11 13 13 8 12 1 3 4 7 10 14 7 + * 10 9 15 5 6 0 8 15 0 14 5 2 9 3 2 12 + * + * 13 1 2 15 8 13 4 8 6 10 15 3 11 7 1 4 + * 10 12 9 5 3 6 14 11 5 0 0 14 12 9 7 2 + * 7 2 11 1 4 14 1 7 9 4 12 10 14 8 2 13 + * 0 15 6 12 10 9 13 0 15 3 3 5 5 6 8 11 + * + * P is a 32-to-32 bit permutation. Its output contains the following + * bits of its input (listed in order MSB to LSB of output). + * + * 16 25 12 11 3 20 4 15 31 17 9 6 27 14 1 22 + * 30 24 8 18 0 5 29 23 13 19 2 26 10 21 28 7 + * + * PC1 is a 64-to-56 bit selection function. Its output is in two words, + * C and D. The word C contains the following bits of its input (listed + * in order MSB to LSB of output). + * + * 7 15 23 31 39 47 55 63 6 14 22 30 38 46 + * 54 62 5 13 21 29 37 45 53 61 4 12 20 28 + * + * And the word D contains these bits. + * + * 1 9 17 25 33 41 49 57 2 10 18 26 34 42 + * 50 58 3 11 19 27 35 43 51 59 36 44 52 60 + * + * PC2 is a 56-to-48 bit selection function. Its input is in two words, + * C and D. These are treated as one 56-bit word (with C more significant, + * so that bits 55 to 28 of the word are bits 27 to 0 of C, and bits 27 to + * 0 of the word are bits 27 to 0 of D). The output contains the following + * bits of this 56-bit input word (listed in order MSB to LSB of output). + * + * 42 39 45 32 55 51 53 28 41 50 35 46 33 37 44 52 30 48 40 49 29 36 43 54 + * 15 4 25 19 9 1 26 16 5 11 23 8 12 7 17 0 22 3 10 14 6 20 27 24 + */ + +typedef struct { + word32 k0246[16], k1357[16]; + word32 eiv0, eiv1; + word32 div0, div1; +} DESContext; -DES implementation; 1995 Tatu Ylonen +#define rotl(x, c) ( (x << c) | (x >> (32-c)) ) +#define rotl28(x, c) ( ( (x << c) | (x >> (28-c)) ) & 0x0FFFFFFF) -This implementation is derived from libdes-3.06, which is copyright -(c) 1993 Eric Young, and distributed under the GNU GPL or the ARTISTIC licence -(at the user's option). The original distribution can be found e.g. from -ftp://ftp.dsi.unimi.it/pub/security/crypt/libdes/libdes-3.06.tar.gz. +static word32 bitsel(word32 *input, const int *bitnums, int size) { + word32 ret = 0; + while (size--) { + int bitpos = *bitnums++; + ret <<= 1; + if (bitpos >= 0) + ret |= 1 & (input[bitpos / 32] >> (bitpos % 32)); + } + return ret; +} -This implementation is distributed under the same terms. See -libdes-README, libdes-ARTISTIC, and libdes-COPYING for more -information. +void des_key_setup(word32 key_msw, word32 key_lsw, DESContext *sched) { + + static const int PC1_Cbits[] = { + 7, 15, 23, 31, 39, 47, 55, 63, 6, 14, 22, 30, 38, 46, + 54, 62, 5, 13, 21, 29, 37, 45, 53, 61, 4, 12, 20, 28 + }; + static const int PC1_Dbits[] = { + 1, 9, 17, 25, 33, 41, 49, 57, 2, 10, 18, 26, 34, 42, + 50, 58, 3, 11, 19, 27, 35, 43, 51, 59, 36, 44, 52, 60 + }; + static const int PC2_0246[] = { + 49, 36, 59, 55, -1, -1, 37, 41, 48, 56, 34, 52, -1, -1, 15, 4, + 25, 19, 9, 1, -1, -1, 12, 7, 17, 0, 22, 3, -1, -1, 46, 43 + }; + static const int PC2_1357[] = { + -1, -1, 57, 32, 45, 54, 39, 50, -1, -1, 44, 53, 33, 40, 47, 58, + -1, -1, 26, 16, 5, 11, 23, 8, -1, -1, 10, 14, 6, 20, 27, 24 + }; + static const int leftshifts[] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; + + word32 C, D; + word32 buf[2]; + int i; + + buf[0] = key_lsw; + buf[1] = key_msw; + + C = bitsel(buf, PC1_Cbits, 28); + D = bitsel(buf, PC1_Dbits, 28); + + for (i = 0; i < 16; i++) { + C = rotl28(C, leftshifts[i]); + D = rotl28(D, leftshifts[i]); + buf[0] = D; + buf[1] = C; + sched->k0246[i] = bitsel(buf, PC2_0246, 32); + sched->k1357[i] = bitsel(buf, PC2_1357, 32); + } -*/ + sched->eiv0 = sched->eiv1 = 0; + sched->div0 = sched->div1 = 0; /* for good measure */ +} -typedef struct -{ - word32 key_schedule[32]; -} DESContext; +static const word32 SPboxes[8][64] = { + {0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004L}, + + {0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000L}, + + {0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200L}, + + {0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080L}, + + {0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100L}, + + {0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010L}, + + {0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002L}, + + {0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000L} +}; -/* Sets the des key for the context. Initializes the context. The least - significant bit of each byte of the key is ignored as parity. */ -static void des_set_key(unsigned char *key, DESContext *ks); - -/* Encrypts 32 bits in l,r, and stores the result in output[0] and output[1]. - Performs encryption if encrypt is non-zero, and decryption if it is zero. - The key context must have been initialized previously with des_set_key. */ -static void des_encrypt(word32 l, word32 r, word32 *output, DESContext *ks, - int encrypt); - -/* Encrypts len bytes from src to dest in CBC modes. Len must be a multiple - of 8. iv will be modified at end to a value suitable for continuing - encryption. */ -static void des_cbc_encrypt(DESContext *ks, unsigned char *iv, unsigned char *dest, - const unsigned char *src, unsigned int len); - -/* Decrypts len bytes from src to dest in CBC modes. Len must be a multiple - of 8. iv will be modified at end to a value suitable for continuing - decryption. */ -static void des_cbc_decrypt(DESContext *ks, unsigned char *iv, unsigned char *dest, - const unsigned char *src, unsigned int len); - -/* Encrypts in CBC mode using triple-DES. */ -static void des_3cbc_encrypt(DESContext *ks1, unsigned char *iv1, - DESContext *ks2, unsigned char *iv2, - DESContext *ks3, unsigned char *iv3, - unsigned char *dest, const unsigned char *src, - unsigned int len); - -/* Decrypts in CBC mode using triple-DES. */ -static void des_3cbc_decrypt(DESContext *ks1, unsigned char *iv1, - DESContext *ks2, unsigned char *iv2, - DESContext *ks3, unsigned char *iv3, - unsigned char *dest, const unsigned char *src, - unsigned int len); - -#define GET_32BIT_LSB_FIRST(cp) \ - (((unsigned long)(unsigned char)(cp)[0]) | \ - ((unsigned long)(unsigned char)(cp)[1] << 8) | \ - ((unsigned long)(unsigned char)(cp)[2] << 16) | \ - ((unsigned long)(unsigned char)(cp)[3] << 24)) - -#define PUT_32BIT_LSB_FIRST(cp, value) do { \ - (cp)[0] = (value); \ - (cp)[1] = (value) >> 8; \ - (cp)[2] = (value) >> 16; \ - (cp)[3] = (value) >> 24; } while (0) +#define f(R, K0246, K1357) (\ + s0246 = R ^ K0246, \ + s1357 = R ^ K1357, \ + s0246 = rotl(s0246, 28), \ + SPboxes[0] [(s0246 >> 24) & 0x3F] | \ + SPboxes[1] [(s1357 >> 24) & 0x3F] | \ + SPboxes[2] [(s0246 >> 16) & 0x3F] | \ + SPboxes[3] [(s1357 >> 16) & 0x3F] | \ + SPboxes[4] [(s0246 >> 8) & 0x3F] | \ + SPboxes[5] [(s1357 >> 8) & 0x3F] | \ + SPboxes[6] [(s0246 ) & 0x3F] | \ + SPboxes[7] [(s1357 ) & 0x3F]) + +#define bitswap(L, R, n, mask) (\ + swap = mask & ( (R >> n) ^ L ), \ + R ^= swap << n, \ + L ^= swap) + +/* Initial permutation */ +#define IP(L, R) (\ + bitswap(R, L, 4, 0x0F0F0F0F), \ + bitswap(R, L, 16, 0x0000FFFF), \ + bitswap(L, R, 2, 0x33333333), \ + bitswap(L, R, 8, 0x00FF00FF), \ + bitswap(R, L, 1, 0x55555555)) + +/* Final permutation */ +#define FP(L, R) (\ + bitswap(R, L, 1, 0x55555555), \ + bitswap(L, R, 8, 0x00FF00FF), \ + bitswap(L, R, 2, 0x33333333), \ + bitswap(R, L, 16, 0x0000FFFF), \ + bitswap(R, L, 4, 0x0F0F0F0F)) + +void des_encipher(word32 *output, word32 L, word32 R, DESContext *sched) { + word32 swap, s0246, s1357; + + IP(L, R); + + L = rotl(L, 1); + R = rotl(R, 1); + + L ^= f(R, sched->k0246[ 0], sched->k1357[ 0]); + R ^= f(L, sched->k0246[ 1], sched->k1357[ 1]); + L ^= f(R, sched->k0246[ 2], sched->k1357[ 2]); + R ^= f(L, sched->k0246[ 3], sched->k1357[ 3]); + L ^= f(R, sched->k0246[ 4], sched->k1357[ 4]); + R ^= f(L, sched->k0246[ 5], sched->k1357[ 5]); + L ^= f(R, sched->k0246[ 6], sched->k1357[ 6]); + R ^= f(L, sched->k0246[ 7], sched->k1357[ 7]); + L ^= f(R, sched->k0246[ 8], sched->k1357[ 8]); + R ^= f(L, sched->k0246[ 9], sched->k1357[ 9]); + L ^= f(R, sched->k0246[10], sched->k1357[10]); + R ^= f(L, sched->k0246[11], sched->k1357[11]); + L ^= f(R, sched->k0246[12], sched->k1357[12]); + R ^= f(L, sched->k0246[13], sched->k1357[13]); + L ^= f(R, sched->k0246[14], sched->k1357[14]); + R ^= f(L, sched->k0246[15], sched->k1357[15]); + + L = rotl(L, 31); + R = rotl(R, 31); + + swap = L; L = R; R = swap; + + FP(L, R); + + output[0] = L; + output[1] = R; +} -/* +void des_decipher(word32 *output, word32 L, word32 R, DESContext *sched) { + word32 swap, s0246, s1357; -DES implementation; 1995 Tatu Ylonen - -This implementation is derived from libdes-3.06, which is copyright -(c) 1993 Eric Young, and distributed under the GNU GPL or the ARTISTIC licence -(at the user's option). The original distribution can be found e.g. from -ftp://ftp.dsi.unimi.it/pub/security/crypt/libdes/libdes-3.06.tar.gz. - -This implementation is distributed under the same terms. See -libdes-README, libdes-ARTISTIC, and libdes-COPYING for more -information. - -A description of the DES algorithm can be found in every modern book on -cryptography and data security, including the following: - - Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. - - Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to - Computer Security. Prentice-Hall, 1989. - - Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill, - 1994. - -*/ - -/* Table for key generation. This used to be in sk.h. */ -/* Copyright (C) 1993 Eric Young - see README for more details */ -static const word32 des_skb[8][64]={ -/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ -{ 0x00000000,0x00000010,0x20000000,0x20000010, -0x00010000,0x00010010,0x20010000,0x20010010, -0x00000800,0x00000810,0x20000800,0x20000810, -0x00010800,0x00010810,0x20010800,0x20010810, -0x00000020,0x00000030,0x20000020,0x20000030, -0x00010020,0x00010030,0x20010020,0x20010030, -0x00000820,0x00000830,0x20000820,0x20000830, -0x00010820,0x00010830,0x20010820,0x20010830, -0x00080000,0x00080010,0x20080000,0x20080010, -0x00090000,0x00090010,0x20090000,0x20090010, -0x00080800,0x00080810,0x20080800,0x20080810, -0x00090800,0x00090810,0x20090800,0x20090810, -0x00080020,0x00080030,0x20080020,0x20080030, -0x00090020,0x00090030,0x20090020,0x20090030, -0x00080820,0x00080830,0x20080820,0x20080830, -0x00090820,0x00090830,0x20090820,0x20090830 }, -/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ -{ 0x00000000,0x02000000,0x00002000,0x02002000, -0x00200000,0x02200000,0x00202000,0x02202000, -0x00000004,0x02000004,0x00002004,0x02002004, -0x00200004,0x02200004,0x00202004,0x02202004, -0x00000400,0x02000400,0x00002400,0x02002400, -0x00200400,0x02200400,0x00202400,0x02202400, -0x00000404,0x02000404,0x00002404,0x02002404, -0x00200404,0x02200404,0x00202404,0x02202404, -0x10000000,0x12000000,0x10002000,0x12002000, -0x10200000,0x12200000,0x10202000,0x12202000, -0x10000004,0x12000004,0x10002004,0x12002004, -0x10200004,0x12200004,0x10202004,0x12202004, -0x10000400,0x12000400,0x10002400,0x12002400, -0x10200400,0x12200400,0x10202400,0x12202400, -0x10000404,0x12000404,0x10002404,0x12002404, -0x10200404,0x12200404,0x10202404,0x12202404 }, -/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ -{ 0x00000000,0x00000001,0x00040000,0x00040001, -0x01000000,0x01000001,0x01040000,0x01040001, -0x00000002,0x00000003,0x00040002,0x00040003, -0x01000002,0x01000003,0x01040002,0x01040003, -0x00000200,0x00000201,0x00040200,0x00040201, -0x01000200,0x01000201,0x01040200,0x01040201, -0x00000202,0x00000203,0x00040202,0x00040203, -0x01000202,0x01000203,0x01040202,0x01040203, -0x08000000,0x08000001,0x08040000,0x08040001, -0x09000000,0x09000001,0x09040000,0x09040001, -0x08000002,0x08000003,0x08040002,0x08040003, -0x09000002,0x09000003,0x09040002,0x09040003, -0x08000200,0x08000201,0x08040200,0x08040201, -0x09000200,0x09000201,0x09040200,0x09040201, -0x08000202,0x08000203,0x08040202,0x08040203, -0x09000202,0x09000203,0x09040202,0x09040203 }, -/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ -{ 0x00000000,0x00100000,0x00000100,0x00100100, -0x00000008,0x00100008,0x00000108,0x00100108, -0x00001000,0x00101000,0x00001100,0x00101100, -0x00001008,0x00101008,0x00001108,0x00101108, -0x04000000,0x04100000,0x04000100,0x04100100, -0x04000008,0x04100008,0x04000108,0x04100108, -0x04001000,0x04101000,0x04001100,0x04101100, -0x04001008,0x04101008,0x04001108,0x04101108, -0x00020000,0x00120000,0x00020100,0x00120100, -0x00020008,0x00120008,0x00020108,0x00120108, -0x00021000,0x00121000,0x00021100,0x00121100, -0x00021008,0x00121008,0x00021108,0x00121108, -0x04020000,0x04120000,0x04020100,0x04120100, -0x04020008,0x04120008,0x04020108,0x04120108, -0x04021000,0x04121000,0x04021100,0x04121100, -0x04021008,0x04121008,0x04021108,0x04121108 }, -/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ -{ 0x00000000,0x10000000,0x00010000,0x10010000, -0x00000004,0x10000004,0x00010004,0x10010004, -0x20000000,0x30000000,0x20010000,0x30010000, -0x20000004,0x30000004,0x20010004,0x30010004, -0x00100000,0x10100000,0x00110000,0x10110000, -0x00100004,0x10100004,0x00110004,0x10110004, -0x20100000,0x30100000,0x20110000,0x30110000, -0x20100004,0x30100004,0x20110004,0x30110004, -0x00001000,0x10001000,0x00011000,0x10011000, -0x00001004,0x10001004,0x00011004,0x10011004, -0x20001000,0x30001000,0x20011000,0x30011000, -0x20001004,0x30001004,0x20011004,0x30011004, -0x00101000,0x10101000,0x00111000,0x10111000, -0x00101004,0x10101004,0x00111004,0x10111004, -0x20101000,0x30101000,0x20111000,0x30111000, -0x20101004,0x30101004,0x20111004,0x30111004 }, -/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ -{ 0x00000000,0x08000000,0x00000008,0x08000008, -0x00000400,0x08000400,0x00000408,0x08000408, -0x00020000,0x08020000,0x00020008,0x08020008, -0x00020400,0x08020400,0x00020408,0x08020408, -0x00000001,0x08000001,0x00000009,0x08000009, -0x00000401,0x08000401,0x00000409,0x08000409, -0x00020001,0x08020001,0x00020009,0x08020009, -0x00020401,0x08020401,0x00020409,0x08020409, -0x02000000,0x0A000000,0x02000008,0x0A000008, -0x02000400,0x0A000400,0x02000408,0x0A000408, -0x02020000,0x0A020000,0x02020008,0x0A020008, -0x02020400,0x0A020400,0x02020408,0x0A020408, -0x02000001,0x0A000001,0x02000009,0x0A000009, -0x02000401,0x0A000401,0x02000409,0x0A000409, -0x02020001,0x0A020001,0x02020009,0x0A020009, -0x02020401,0x0A020401,0x02020409,0x0A020409 }, -/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ -{ 0x00000000,0x00000100,0x00080000,0x00080100, -0x01000000,0x01000100,0x01080000,0x01080100, -0x00000010,0x00000110,0x00080010,0x00080110, -0x01000010,0x01000110,0x01080010,0x01080110, -0x00200000,0x00200100,0x00280000,0x00280100, -0x01200000,0x01200100,0x01280000,0x01280100, -0x00200010,0x00200110,0x00280010,0x00280110, -0x01200010,0x01200110,0x01280010,0x01280110, -0x00000200,0x00000300,0x00080200,0x00080300, -0x01000200,0x01000300,0x01080200,0x01080300, -0x00000210,0x00000310,0x00080210,0x00080310, -0x01000210,0x01000310,0x01080210,0x01080310, -0x00200200,0x00200300,0x00280200,0x00280300, -0x01200200,0x01200300,0x01280200,0x01280300, -0x00200210,0x00200310,0x00280210,0x00280310, -0x01200210,0x01200310,0x01280210,0x01280310 }, -/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ -{ 0x00000000,0x04000000,0x00040000,0x04040000, -0x00000002,0x04000002,0x00040002,0x04040002, -0x00002000,0x04002000,0x00042000,0x04042000, -0x00002002,0x04002002,0x00042002,0x04042002, -0x00000020,0x04000020,0x00040020,0x04040020, -0x00000022,0x04000022,0x00040022,0x04040022, -0x00002020,0x04002020,0x00042020,0x04042020, -0x00002022,0x04002022,0x00042022,0x04042022, -0x00000800,0x04000800,0x00040800,0x04040800, -0x00000802,0x04000802,0x00040802,0x04040802, -0x00002800,0x04002800,0x00042800,0x04042800, -0x00002802,0x04002802,0x00042802,0x04042802, -0x00000820,0x04000820,0x00040820,0x04040820, -0x00000822,0x04000822,0x00040822,0x04040822, -0x00002820,0x04002820,0x00042820,0x04042820, -0x00002822,0x04002822,0x00042822,0x04042822 } -}; + IP(L, R); -/* Tables used for executing des. This used to be in spr.h. */ -/* Copyright (C) 1993 Eric Young - see README for more details */ -static const word32 des_SPtrans[8][64]={ -/* nibble 0 */ -{ 0x00820200, 0x00020000, 0x80800000, 0x80820200, -0x00800000, 0x80020200, 0x80020000, 0x80800000, -0x80020200, 0x00820200, 0x00820000, 0x80000200, -0x80800200, 0x00800000, 0x00000000, 0x80020000, -0x00020000, 0x80000000, 0x00800200, 0x00020200, -0x80820200, 0x00820000, 0x80000200, 0x00800200, -0x80000000, 0x00000200, 0x00020200, 0x80820000, -0x00000200, 0x80800200, 0x80820000, 0x00000000, -0x00000000, 0x80820200, 0x00800200, 0x80020000, -0x00820200, 0x00020000, 0x80000200, 0x00800200, -0x80820000, 0x00000200, 0x00020200, 0x80800000, -0x80020200, 0x80000000, 0x80800000, 0x00820000, -0x80820200, 0x00020200, 0x00820000, 0x80800200, -0x00800000, 0x80000200, 0x80020000, 0x00000000, -0x00020000, 0x00800000, 0x80800200, 0x00820200, -0x80000000, 0x80820000, 0x00000200, 0x80020200 }, - -/* nibble 1 */ -{ 0x10042004, 0x00000000, 0x00042000, 0x10040000, -0x10000004, 0x00002004, 0x10002000, 0x00042000, -0x00002000, 0x10040004, 0x00000004, 0x10002000, -0x00040004, 0x10042000, 0x10040000, 0x00000004, -0x00040000, 0x10002004, 0x10040004, 0x00002000, -0x00042004, 0x10000000, 0x00000000, 0x00040004, -0x10002004, 0x00042004, 0x10042000, 0x10000004, -0x10000000, 0x00040000, 0x00002004, 0x10042004, -0x00040004, 0x10042000, 0x10002000, 0x00042004, -0x10042004, 0x00040004, 0x10000004, 0x00000000, -0x10000000, 0x00002004, 0x00040000, 0x10040004, -0x00002000, 0x10000000, 0x00042004, 0x10002004, -0x10042000, 0x00002000, 0x00000000, 0x10000004, -0x00000004, 0x10042004, 0x00042000, 0x10040000, -0x10040004, 0x00040000, 0x00002004, 0x10002000, -0x10002004, 0x00000004, 0x10040000, 0x00042000 }, - -/* nibble 2 */ -{ 0x41000000, 0x01010040, 0x00000040, 0x41000040, -0x40010000, 0x01000000, 0x41000040, 0x00010040, -0x01000040, 0x00010000, 0x01010000, 0x40000000, -0x41010040, 0x40000040, 0x40000000, 0x41010000, -0x00000000, 0x40010000, 0x01010040, 0x00000040, -0x40000040, 0x41010040, 0x00010000, 0x41000000, -0x41010000, 0x01000040, 0x40010040, 0x01010000, -0x00010040, 0x00000000, 0x01000000, 0x40010040, -0x01010040, 0x00000040, 0x40000000, 0x00010000, -0x40000040, 0x40010000, 0x01010000, 0x41000040, -0x00000000, 0x01010040, 0x00010040, 0x41010000, -0x40010000, 0x01000000, 0x41010040, 0x40000000, -0x40010040, 0x41000000, 0x01000000, 0x41010040, -0x00010000, 0x01000040, 0x41000040, 0x00010040, -0x01000040, 0x00000000, 0x41010000, 0x40000040, -0x41000000, 0x40010040, 0x00000040, 0x01010000 }, - -/* nibble 3 */ -{ 0x00100402, 0x04000400, 0x00000002, 0x04100402, -0x00000000, 0x04100000, 0x04000402, 0x00100002, -0x04100400, 0x04000002, 0x04000000, 0x00000402, -0x04000002, 0x00100402, 0x00100000, 0x04000000, -0x04100002, 0x00100400, 0x00000400, 0x00000002, -0x00100400, 0x04000402, 0x04100000, 0x00000400, -0x00000402, 0x00000000, 0x00100002, 0x04100400, -0x04000400, 0x04100002, 0x04100402, 0x00100000, -0x04100002, 0x00000402, 0x00100000, 0x04000002, -0x00100400, 0x04000400, 0x00000002, 0x04100000, -0x04000402, 0x00000000, 0x00000400, 0x00100002, -0x00000000, 0x04100002, 0x04100400, 0x00000400, -0x04000000, 0x04100402, 0x00100402, 0x00100000, -0x04100402, 0x00000002, 0x04000400, 0x00100402, -0x00100002, 0x00100400, 0x04100000, 0x04000402, -0x00000402, 0x04000000, 0x04000002, 0x04100400 }, - -/* nibble 4 */ -{ 0x02000000, 0x00004000, 0x00000100, 0x02004108, -0x02004008, 0x02000100, 0x00004108, 0x02004000, -0x00004000, 0x00000008, 0x02000008, 0x00004100, -0x02000108, 0x02004008, 0x02004100, 0x00000000, -0x00004100, 0x02000000, 0x00004008, 0x00000108, -0x02000100, 0x00004108, 0x00000000, 0x02000008, -0x00000008, 0x02000108, 0x02004108, 0x00004008, -0x02004000, 0x00000100, 0x00000108, 0x02004100, -0x02004100, 0x02000108, 0x00004008, 0x02004000, -0x00004000, 0x00000008, 0x02000008, 0x02000100, -0x02000000, 0x00004100, 0x02004108, 0x00000000, -0x00004108, 0x02000000, 0x00000100, 0x00004008, -0x02000108, 0x00000100, 0x00000000, 0x02004108, -0x02004008, 0x02004100, 0x00000108, 0x00004000, -0x00004100, 0x02004008, 0x02000100, 0x00000108, -0x00000008, 0x00004108, 0x02004000, 0x02000008 }, - -/* nibble 5 */ -{ 0x20000010, 0x00080010, 0x00000000, 0x20080800, -0x00080010, 0x00000800, 0x20000810, 0x00080000, -0x00000810, 0x20080810, 0x00080800, 0x20000000, -0x20000800, 0x20000010, 0x20080000, 0x00080810, -0x00080000, 0x20000810, 0x20080010, 0x00000000, -0x00000800, 0x00000010, 0x20080800, 0x20080010, -0x20080810, 0x20080000, 0x20000000, 0x00000810, -0x00000010, 0x00080800, 0x00080810, 0x20000800, -0x00000810, 0x20000000, 0x20000800, 0x00080810, -0x20080800, 0x00080010, 0x00000000, 0x20000800, -0x20000000, 0x00000800, 0x20080010, 0x00080000, -0x00080010, 0x20080810, 0x00080800, 0x00000010, -0x20080810, 0x00080800, 0x00080000, 0x20000810, -0x20000010, 0x20080000, 0x00080810, 0x00000000, -0x00000800, 0x20000010, 0x20000810, 0x20080800, -0x20080000, 0x00000810, 0x00000010, 0x20080010 }, - -/* nibble 6 */ -{ 0x00001000, 0x00000080, 0x00400080, 0x00400001, -0x00401081, 0x00001001, 0x00001080, 0x00000000, -0x00400000, 0x00400081, 0x00000081, 0x00401000, -0x00000001, 0x00401080, 0x00401000, 0x00000081, -0x00400081, 0x00001000, 0x00001001, 0x00401081, -0x00000000, 0x00400080, 0x00400001, 0x00001080, -0x00401001, 0x00001081, 0x00401080, 0x00000001, -0x00001081, 0x00401001, 0x00000080, 0x00400000, -0x00001081, 0x00401000, 0x00401001, 0x00000081, -0x00001000, 0x00000080, 0x00400000, 0x00401001, -0x00400081, 0x00001081, 0x00001080, 0x00000000, -0x00000080, 0x00400001, 0x00000001, 0x00400080, -0x00000000, 0x00400081, 0x00400080, 0x00001080, -0x00000081, 0x00001000, 0x00401081, 0x00400000, -0x00401080, 0x00000001, 0x00001001, 0x00401081, -0x00400001, 0x00401080, 0x00401000, 0x00001001 }, - -/* nibble 7 */ -{ 0x08200020, 0x08208000, 0x00008020, 0x00000000, -0x08008000, 0x00200020, 0x08200000, 0x08208020, -0x00000020, 0x08000000, 0x00208000, 0x00008020, -0x00208020, 0x08008020, 0x08000020, 0x08200000, -0x00008000, 0x00208020, 0x00200020, 0x08008000, -0x08208020, 0x08000020, 0x00000000, 0x00208000, -0x08000000, 0x00200000, 0x08008020, 0x08200020, -0x00200000, 0x00008000, 0x08208000, 0x00000020, -0x00200000, 0x00008000, 0x08000020, 0x08208020, -0x00008020, 0x08000000, 0x00000000, 0x00208000, -0x08200020, 0x08008020, 0x08008000, 0x00200020, -0x08208000, 0x00000020, 0x00200020, 0x08008000, -0x08208020, 0x00200000, 0x08200000, 0x08000020, -0x00208000, 0x00008020, 0x08008020, 0x08200000, -0x00000020, 0x08208000, 0x00208020, 0x00000000, -0x08000000, 0x08200020, 0x00008000, 0x00208020 }}; - -/* Some stuff that used to be in des_locl.h. Heavily modified. */ - /* IP and FP - * The problem is more of a geometric problem that random bit fiddling. - 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 - 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 - 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 - 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 - - 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 - 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 - 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 - 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 - - The output has been subject to swaps of the form - 0 1 -> 3 1 but the odd and even bits have been put into - 2 3 2 0 - different words. The main trick is to remember that - t=((l>>size)^r)&(mask); - r^=t; - l^=(t<>(n))^(b))&(m)),\ - (b)^=(t),\ - (a)^=((t)<<(n))) - -#define IP(l,r,t) \ - PERM_OP(r,l,t, 4,0x0f0f0f0f); \ - PERM_OP(l,r,t,16,0x0000ffff); \ - PERM_OP(r,l,t, 2,0x33333333); \ - PERM_OP(l,r,t, 8,0x00ff00ff); \ - PERM_OP(r,l,t, 1,0x55555555); - -#define FP(l,r,t) \ - PERM_OP(l,r,t, 1,0x55555555); \ - PERM_OP(r,l,t, 8,0x00ff00ff); \ - PERM_OP(l,r,t, 2,0x33333333); \ - PERM_OP(r,l,t,16,0x0000ffff); \ - PERM_OP(l,r,t, 4,0x0f0f0f0f); - -#define D_ENCRYPT(L,R,S) \ - u=(R^s[S ]); \ - t=R^s[S+1]; \ - t=((t>>4)+(t<<28)); \ - L^= des_SPtrans[1][(t )&0x3f]| \ - des_SPtrans[3][(t>> 8)&0x3f]| \ - des_SPtrans[5][(t>>16)&0x3f]| \ - des_SPtrans[7][(t>>24)&0x3f]| \ - des_SPtrans[0][(u )&0x3f]| \ - des_SPtrans[2][(u>> 8)&0x3f]| \ - des_SPtrans[4][(u>>16)&0x3f]| \ - des_SPtrans[6][(u>>24)&0x3f]; - -/* This part is based on code that used to be in ecb_enc.c. */ -/* Copyright (C) 1993 Eric Young - see README for more details */ - -static void des_encrypt(word32 l, word32 r, word32 *output, DESContext *ks, - int encrypt) -{ - register word32 t,u; - register int i; - register word32 *s; - - s = ks->key_schedule; - - IP(l,r,t); - /* Things have been modified so that the initial rotate is - * done outside the loop. This required the - * des_SPtrans values in sp.h to be rotated 1 bit to the right. - * One perl script later and things have a 5% speed up on a sparc2. - * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> - * for pointing this out. */ - t=(r<<1)|(r>>31); - r=(l<<1)|(l>>31); - l=t; - - /* I don't know if it is worth the effort of loop unrolling the - * inner loop */ - if (encrypt) - { - for (i=0; i<32; i+=4) - { - D_ENCRYPT(l,r,i+0); /* 1 */ - D_ENCRYPT(r,l,i+2); /* 2 */ - } - } - else - { - for (i=30; i>0; i-=4) - { - D_ENCRYPT(l,r,i-0); /* 16 */ - D_ENCRYPT(r,l,i-2); /* 15 */ - } - } - l=(l>>1)|(l<<31); - r=(r>>1)|(r<<31); - - FP(r,l,t); - output[0]=l; - output[1]=r; -} + L = rotl(L, 1); + R = rotl(R, 1); -/* Code based on set_key.c. */ -/* Copyright (C) 1993 Eric Young - see README for more details */ - -#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ - (a)=(a)^(t)^(t>>(16-(n)))) - -static void des_set_key(unsigned char *key, DESContext *ks) -{ - register word32 c, d, t, s, shifts; - register int i; - register word32 *schedule; - - schedule = ks->key_schedule; - - c = GET_32BIT_LSB_FIRST(key); - d = GET_32BIT_LSB_FIRST(key + 4); - - /* I now do it in 47 simple operations :-) - * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) - * for the inspiration. :-) */ - PERM_OP(d,c,t,4,0x0f0f0f0f); - HPERM_OP(c,t,-2,0xcccc0000); - HPERM_OP(d,t,-2,0xcccc0000); - PERM_OP(d,c,t,1,0x55555555); - PERM_OP(c,d,t,8,0x00ff00ff); - PERM_OP(d,c,t,1,0x55555555); - d = ((d & 0xff) << 16) | (d & 0xff00) | - ((d >> 16) & 0xff) | ((c >> 4) & 0xf000000); - c&=0x0fffffff; - - shifts = 0x7efc; - for (i=0; i < 16; i++) - { - if (shifts & 1) - { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); } - else - { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); } - shifts >>= 1; - c&=0x0fffffff; - d&=0x0fffffff; - - /* could be a few less shifts but I am to lazy at this - * point in time to investigate */ - - s = des_skb[0][ (c )&0x3f ] | - des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)] | - des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)] | - des_skb[3][((c>>20)&0x01)|((c>>21)&0x06)|((c>>22)&0x38)]; - - t = des_skb[4][ (d )&0x3f ] | - des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)] | - des_skb[6][ (d>>15)&0x3f ] | - des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)]; - - /* table contained 0213 4657 */ - *schedule++ = ((t << 16) | (s & 0xffff)); - s = ((s >> 16) | (t & 0xffff0000)); - *schedule++ = (s << 4) | (s >> 28); - } + L ^= f(R, sched->k0246[15], sched->k1357[15]); + R ^= f(L, sched->k0246[14], sched->k1357[14]); + L ^= f(R, sched->k0246[13], sched->k1357[13]); + R ^= f(L, sched->k0246[12], sched->k1357[12]); + L ^= f(R, sched->k0246[11], sched->k1357[11]); + R ^= f(L, sched->k0246[10], sched->k1357[10]); + L ^= f(R, sched->k0246[ 9], sched->k1357[ 9]); + R ^= f(L, sched->k0246[ 8], sched->k1357[ 8]); + L ^= f(R, sched->k0246[ 7], sched->k1357[ 7]); + R ^= f(L, sched->k0246[ 6], sched->k1357[ 6]); + L ^= f(R, sched->k0246[ 5], sched->k1357[ 5]); + R ^= f(L, sched->k0246[ 4], sched->k1357[ 4]); + L ^= f(R, sched->k0246[ 3], sched->k1357[ 3]); + R ^= f(L, sched->k0246[ 2], sched->k1357[ 2]); + L ^= f(R, sched->k0246[ 1], sched->k1357[ 1]); + R ^= f(L, sched->k0246[ 0], sched->k1357[ 0]); + + L = rotl(L, 31); + R = rotl(R, 31); + + swap = L; L = R; R = swap; + + FP(L, R); + + output[0] = L; + output[1] = R; } -static void des_cbc_encrypt(DESContext *ks, unsigned char *iv, - unsigned char *dest, const unsigned char *src, - unsigned int len) -{ - word32 iv0, iv1, out[2]; - unsigned int i; - - assert((len & 7) == 0); - - iv0 = GET_32BIT_LSB_FIRST(iv); - iv1 = GET_32BIT_LSB_FIRST(iv + 4); - - for (i = 0; i < len; i += 8) - { - iv0 ^= GET_32BIT_LSB_FIRST(src + i); - iv1 ^= GET_32BIT_LSB_FIRST(src + i + 4); - des_encrypt(iv0, iv1, out, ks, 1); - iv0 = out[0]; - iv1 = out[1]; - PUT_32BIT_LSB_FIRST(dest + i, iv0); - PUT_32BIT_LSB_FIRST(dest + i + 4, iv1); +#define GET_32BIT_MSB_FIRST(cp) \ + (((unsigned long)(unsigned char)(cp)[3]) | \ + ((unsigned long)(unsigned char)(cp)[2] << 8) | \ + ((unsigned long)(unsigned char)(cp)[1] << 16) | \ + ((unsigned long)(unsigned char)(cp)[0] << 24)) + +#define PUT_32BIT_MSB_FIRST(cp, value) do { \ + (cp)[3] = (value); \ + (cp)[2] = (value) >> 8; \ + (cp)[1] = (value) >> 16; \ + (cp)[0] = (value) >> 24; } while (0) + +static void des_cbc_encrypt(unsigned char *dest, const unsigned char *src, + unsigned int len, DESContext *sched) { + word32 out[2], iv0, iv1; + unsigned int i; + + assert((len & 7) == 0); + + iv0 = sched->eiv0; + iv1 = sched->eiv1; + for (i = 0; i < len; i += 8) { + iv0 ^= GET_32BIT_MSB_FIRST(src); src += 4; + iv1 ^= GET_32BIT_MSB_FIRST(src); src += 4; + des_encipher(out, iv0, iv1, sched); + iv0 = out[0]; + iv1 = out[1]; + PUT_32BIT_MSB_FIRST(dest, iv0); dest += 4; + PUT_32BIT_MSB_FIRST(dest, iv1); dest += 4; } - PUT_32BIT_LSB_FIRST(iv, iv0); - PUT_32BIT_LSB_FIRST(iv + 4, iv1); + sched->eiv0 = iv0; + sched->eiv1 = iv1; } -static void des_cbc_decrypt(DESContext *ks, unsigned char *iv, - unsigned char *dest, const unsigned char *src, - unsigned int len) -{ - word32 iv0, iv1, d0, d1, out[2]; - unsigned int i; - - assert((len & 7) == 0); - - iv0 = GET_32BIT_LSB_FIRST(iv); - iv1 = GET_32BIT_LSB_FIRST(iv + 4); - - for (i = 0; i < len; i += 8) - { - d0 = GET_32BIT_LSB_FIRST(src + i); - d1 = GET_32BIT_LSB_FIRST(src + i + 4); - des_encrypt(d0, d1, out, ks, 0); - iv0 ^= out[0]; - iv1 ^= out[1]; - PUT_32BIT_LSB_FIRST(dest + i, iv0); - PUT_32BIT_LSB_FIRST(dest + i + 4, iv1); - iv0 = d0; - iv1 = d1; +static void des_cbc_decrypt(unsigned char *dest, const unsigned char *src, + unsigned int len, DESContext *sched) { + word32 out[2], iv0, iv1, xL, xR; + unsigned int i; + + assert((len & 7) == 0); + + iv0 = sched->div0; + iv1 = sched->div1; + for (i = 0; i < len; i += 8) { + xL = GET_32BIT_MSB_FIRST(src); src += 4; + xR = GET_32BIT_MSB_FIRST(src); src += 4; + des_decipher(out, xL, xR, sched); + iv0 ^= out[0]; + iv1 ^= out[1]; + PUT_32BIT_MSB_FIRST(dest, iv0); dest += 4; + PUT_32BIT_MSB_FIRST(dest, iv1); dest += 4; + iv0 = xL; + iv1 = xR; } - PUT_32BIT_LSB_FIRST(iv, iv0); - PUT_32BIT_LSB_FIRST(iv + 4, iv1); + sched->div0 = iv0; + sched->div1 = iv1; } -static void des_3cbc_encrypt(DESContext *ks1, unsigned char *iv1, - DESContext *ks2, unsigned char *iv2, - DESContext *ks3, unsigned char *iv3, - unsigned char *dest, const unsigned char *src, - unsigned int len) -{ - des_cbc_encrypt(ks1, iv1, dest, src, len); - des_cbc_decrypt(ks2, iv2, dest, dest, len); - des_cbc_encrypt(ks3, iv3, dest, dest, len); +static void des_3cbc_encrypt(unsigned char *dest, const unsigned char *src, + unsigned int len, DESContext *scheds) { + des_cbc_encrypt(dest, src, len, &scheds[0]); + des_cbc_decrypt(dest, src, len, &scheds[1]); + des_cbc_encrypt(dest, src, len, &scheds[2]); } -static void des_3cbc_decrypt(DESContext *ks1, unsigned char *iv1, - DESContext *ks2, unsigned char *iv2, - DESContext *ks3, unsigned char *iv3, - unsigned char *dest, const unsigned char *src, - unsigned int len) -{ - des_cbc_decrypt(ks3, iv3, dest, src, len); - des_cbc_encrypt(ks2, iv2, dest, dest, len); - des_cbc_decrypt(ks1, iv1, dest, dest, len); +static void des_3cbc_decrypt(unsigned char *dest, const unsigned char *src, + unsigned int len, DESContext *scheds) { + des_cbc_decrypt(dest, src, len, &scheds[2]); + des_cbc_encrypt(dest, src, len, &scheds[1]); + des_cbc_decrypt(dest, src, len, &scheds[0]); } -DESContext ekey1, ekey2, ekey3; -unsigned char eiv1[8], eiv2[8], eiv3[8]; - -DESContext dkey1, dkey2, dkey3; -unsigned char div1[8], div2[8], div3[8]; +DESContext keys[3]; static void des3_sesskey(unsigned char *key) { - des_set_key(key, &ekey1); - des_set_key(key+8, &ekey2); - des_set_key(key+16, &ekey3); - memset(eiv1, 0, sizeof(eiv1)); - memset(eiv2, 0, sizeof(eiv2)); - memset(eiv3, 0, sizeof(eiv3)); - des_set_key(key, &dkey1); - des_set_key(key+8, &dkey2); - des_set_key(key+16, &dkey3); - memset(div1, 0, sizeof(div1)); - memset(div2, 0, sizeof(div2)); - memset(div3, 0, sizeof(div3)); + des_key_setup(GET_32BIT_MSB_FIRST(key), + GET_32BIT_MSB_FIRST(key+4), &keys[0]); + des_key_setup(GET_32BIT_MSB_FIRST(key+8), + GET_32BIT_MSB_FIRST(key+12), &keys[1]); + des_key_setup(GET_32BIT_MSB_FIRST(key+16), + GET_32BIT_MSB_FIRST(key+20), &keys[2]); logevent("Initialised triple-DES encryption"); } static void des3_encrypt_blk(unsigned char *blk, int len) { - des_3cbc_encrypt(&ekey1, eiv1, &ekey2, eiv2, &ekey3, eiv3, blk, blk, len); + des_3cbc_encrypt(blk, blk, len, keys); } static void des3_decrypt_blk(unsigned char *blk, int len) { - des_3cbc_decrypt(&dkey1, div1, &dkey2, div2, &dkey3, div3, blk, blk, len); + des_3cbc_decrypt(blk, blk, len, keys); } struct ssh_cipher ssh_3des = { @@ -675,19 +548,17 @@ struct ssh_cipher ssh_3des = { }; static void des_sesskey(unsigned char *key) { - des_set_key(key, &ekey1); - memset(eiv1, 0, sizeof(eiv1)); - des_set_key(key, &dkey1); - memset(div1, 0, sizeof(div1)); + des_key_setup(GET_32BIT_MSB_FIRST(key), + GET_32BIT_MSB_FIRST(key+4), &keys[0]); logevent("Initialised single-DES encryption"); } static void des_encrypt_blk(unsigned char *blk, int len) { - des_cbc_encrypt(&ekey1, eiv1, blk, blk, len); + des_cbc_encrypt(blk, blk, len, keys); } static void des_decrypt_blk(unsigned char *blk, int len) { - des_cbc_decrypt(&dkey1, div1, blk, blk, len); + des_cbc_decrypt(blk, blk, len, keys); } struct ssh_cipher ssh_des = { @@ -695,67 +566,3 @@ struct ssh_cipher ssh_des = { des_encrypt_blk, des_decrypt_blk }; - -#ifdef DES_TEST - -void des_encrypt_buf(DESContext *ks, unsigned char *out, - const unsigned char *in, int encrypt) -{ - word32 in0, in1, output[0]; - - in0 = GET_32BIT_LSB_FIRST(in); - in1 = GET_32BIT_LSB_FIRST(in + 4); - des_encrypt(in0, in1, output, ks, encrypt); - PUT_32BIT_LSB_FIRST(out, output[0]); - PUT_32BIT_LSB_FIRST(out + 4, output[1]); -} - -int main(int ac, char **av) -{ - FILE *f; - char line[1024], *cp; - int i, value; - unsigned char key[8], data[8], result[8], output[8]; - DESContext ks; - - while (fgets(line, sizeof(line), stdin)) - { - for (i = 0; i < 8; i++) - { - if (sscanf(line + 2 * i, "%02x", &value) != 1) - { - fprintf(stderr, "1st col, i = %d, line: %s", i, line); - exit(1); - } - key[i] = value; - } - for (i = 0; i < 8; i++) - { - if (sscanf(line + 2 * i + 17, "%02x", &value) != 1) - { - fprintf(stderr, "2nd col, i = %d, line: %s", i, line); - exit(1); - } - data[i] = value; - } - for (i = 0; i < 8; i++) - { - if (sscanf(line + 2 * i + 2*17, "%02x", &value) != 1) - { - fprintf(stderr, "3rd col, i = %d, line: %s", i, line); - exit(1); - } - result[i] = value; - } - des_set_key(key, &ks); - des_encrypt_buf(&ks, output, data, 1); - if (memcmp(output, result, 8) != 0) - fprintf(stderr, "Encrypt failed: %s", line); - des_encrypt_buf(&ks, output, result, 0); - if (memcmp(output, data, 8) != 0) - fprintf(stderr, "Decrypt failed: %s", line); - } - exit(0); -} -#endif /* DES_TEST */ - diff --git a/win_res.rc b/win_res.rc index dd33d4f0..fc400c2c 100644 --- a/win_res.rc +++ b/win_res.rc @@ -253,36 +253,35 @@ BEGIN LISTBOX IDN_LIST, 3, 3, 154, 95, LBS_HASSTRINGS | LBS_USETABSTOPS | WS_VSCROLL END -IDD_LICENCEBOX DIALOG DISCARDABLE 50, 50, 226, 231 +IDD_LICENCEBOX DIALOG DISCARDABLE 50, 50, 226, 223 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "PuTTY Licence" FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK", IDOK, 98, 211, 44, 14 + DEFPUSHBUTTON "OK", IDOK, 98, 203, 44, 14 - LTEXT "Copyright \251 1997-9 Simon Tatham", 1000, 10, 10, 206, 8 - LTEXT "Portions copyright Eric Young", 1100, 10, 18, 206, 8 + LTEXT "Copyright \251 1997-2000 Simon Tatham", 1000, 10, 10, 206, 8 - LTEXT "Permission is hereby granted, free of charge, to any person", 1002, 10, 34, 206, 8 - LTEXT "obtaining a copy of this software and associated documentation", 1003, 10, 42, 206, 8 - LTEXT "files (the ""Software""), to deal in the Software without restriction,", 1004, 10, 50, 206, 8 - LTEXT "including without limitation the rights to use, copy, modify, merge,", 1005, 10, 58, 206, 8 - LTEXT "publish, distribute, sublicense, and/or sell copies of the Software,", 1006, 10, 66, 206, 8 - LTEXT "and to permit persons to whom the Software is furnished to do so,", 1007, 10, 74, 206, 8 - LTEXT "subject to the following conditions:", 1008, 10, 82, 206, 8 + LTEXT "Permission is hereby granted, free of charge, to any person", 1002, 10, 26, 206, 8 + LTEXT "obtaining a copy of this software and associated documentation", 1003, 10, 34, 206, 8 + LTEXT "files (the ""Software""), to deal in the Software without restriction,", 1004, 10, 42, 206, 8 + LTEXT "including without limitation the rights to use, copy, modify, merge,", 1005, 10, 50, 206, 8 + LTEXT "publish, distribute, sublicense, and/or sell copies of the Software,", 1006, 10, 58, 206, 8 + LTEXT "and to permit persons to whom the Software is furnished to do so,", 1007, 10, 66, 206, 8 + LTEXT "subject to the following conditions:", 1008, 10, 74, 206, 8 - LTEXT "The above copyright notice and this permission notice shall be", 1010, 10, 98, 206, 8 - LTEXT "included in all copies or substantial portions of the Software.", 1011, 10, 106, 206, 8 + LTEXT "The above copyright notice and this permission notice shall be", 1010, 10, 90, 206, 8 + LTEXT "included in all copies or substantial portions of the Software.", 1011, 10, 98, 206, 8 - LTEXT "THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT", 1013, 10, 122, 206, 8 - LTEXT "WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,", 1014, 10, 130, 206, 8 - LTEXT "INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF", 1015, 10, 138, 206, 8 - LTEXT "MERCHANTABILITY, FITNESS FOR A PARTICULAR", 1016, 10, 146, 206, 8 - LTEXT "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", 1017, 10, 154, 206, 8 - LTEXT "SIMON TATHAM BE LIABLE FOR ANY CLAIM, DAMAGES OR", 1018, 10, 162, 206, 8 - LTEXT "OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,", 1019, 10, 170, 206, 8 - LTEXT "TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", 1020, 10, 178, 206, 8 - LTEXT "CONNECTION WITH THE SOFTWARE OR THE USE OR", 1021, 10, 186, 206, 8 - LTEXT "OTHER DEALINGS IN THE SOFTWARE.", 1022, 10, 194, 206, 8 + LTEXT "THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT", 1013, 10, 114, 206, 8 + LTEXT "WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,", 1014, 10, 122, 206, 8 + LTEXT "INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF", 1015, 10, 130, 206, 8 + LTEXT "MERCHANTABILITY, FITNESS FOR A PARTICULAR", 1016, 10, 138, 206, 8 + LTEXT "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", 1017, 10, 146, 206, 8 + LTEXT "SIMON TATHAM BE LIABLE FOR ANY CLAIM, DAMAGES OR", 1018, 10, 154, 206, 8 + LTEXT "OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,", 1019, 10, 162, 206, 8 + LTEXT "TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", 1020, 10, 170, 206, 8 + LTEXT "CONNECTION WITH THE SOFTWARE OR THE USE OR", 1021, 10, 178, 206, 8 + LTEXT "OTHER DEALINGS IN THE SOFTWARE.", 1022, 10, 186, 206, 8 END -- 2.11.0