1 /* $FreeBSD$ */ 2 /* $KAME: des_locl.h,v 1.6 2000/11/06 13:58:09 itojun Exp $ */ 3 4 /* lib/des/des_locl.h */ 5 /* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au) 6 * All rights reserved. 7 * 8 * This file is part of an SSL implementation written 9 * by Eric Young (eay@mincom.oz.au). 10 * The implementation was written so as to conform with Netscapes SSL 11 * specification. This library and applications are 12 * FREE FOR COMMERCIAL AND NON-COMMERCIAL USE 13 * as long as the following conditions are aheared to. 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. If this code is used in a product, 17 * Eric Young should be given attribution as the author of the parts used. 18 * This can be in the form of a textual message at program startup or 19 * in documentation (online or textual) provided with the package. 20 * 21 * Redistribution and use in source and binary forms, with or without 22 * modification, are permitted provided that the following conditions 23 * are met: 24 * 1. Redistributions of source code must retain the copyright 25 * notice, this list of conditions and the following disclaimer. 26 * 2. Redistributions in binary form must reproduce the above copyright 27 * notice, this list of conditions and the following disclaimer in the 28 * documentation and/or other materials provided with the distribution. 29 * 3. All advertising materials mentioning features or use of this software 30 * must display the following acknowledgement: 31 * This product includes software developed by Eric Young (eay@mincom.oz.au) 32 * 33 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 43 * SUCH DAMAGE. 44 * 45 * The licence and distribution terms for any publically available version or 46 * derivative of this code cannot be changed. i.e. this code cannot simply be 47 * copied and put under another distribution licence 48 * [including the GNU Public Licence.] 49 */ 50 /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 51 * 52 * Always modify des_locl.org since des_locl.h is automatically generated from 53 * it during SSLeay configuration. 54 * 55 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 56 */ 57 58 #ifndef HEADER_DES_LOCL_H 59 #define HEADER_DES_LOCL_H 60 61 #include <crypto/des/des.h> 62 63 #undef DES_PTR 64 65 #ifdef __STDC__ 66 #undef NOPROTO 67 #endif 68 69 #define ITERATIONS 16 70 #define HALF_ITERATIONS 8 71 72 /* used in des_read and des_write */ 73 #define MAXWRITE (1024*16) 74 #define BSIZE (MAXWRITE+4) 75 76 #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ 77 l|=((DES_LONG)(*((c)++)))<< 8L, \ 78 l|=((DES_LONG)(*((c)++)))<<16L, \ 79 l|=((DES_LONG)(*((c)++)))<<24L) 80 81 /* NOTE - c is not incremented as per c2l */ 82 #define c2ln(c,l1,l2,n) { \ 83 c+=n; \ 84 l1=l2=0; \ 85 switch (n) { \ 86 case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ 87 case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ 88 case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ 89 case 5: l2|=((DES_LONG)(*(--(c)))); \ 90 case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ 91 case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ 92 case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ 93 case 1: l1|=((DES_LONG)(*(--(c)))); \ 94 } \ 95 } 96 97 #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 98 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 99 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 100 *((c)++)=(unsigned char)(((l)>>24L)&0xff)) 101 102 /* replacements for htonl and ntohl since I have no idea what to do 103 * when faced with machines with 8 byte longs. */ 104 #define HDRSIZE 4 105 106 #define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ 107 l|=((DES_LONG)(*((c)++)))<<16L, \ 108 l|=((DES_LONG)(*((c)++)))<< 8L, \ 109 l|=((DES_LONG)(*((c)++)))) 110 111 #define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ 112 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 113 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 114 *((c)++)=(unsigned char)(((l) )&0xff)) 115 116 /* NOTE - c is not incremented as per l2c */ 117 #define l2cn(l1,l2,c,n) { \ 118 c+=n; \ 119 switch (n) { \ 120 case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ 121 case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ 122 case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ 123 case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ 124 case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ 125 case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ 126 case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ 127 case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ 128 } \ 129 } 130 131 #define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) 132 133 /* The changes to this macro may help or hinder, depending on the 134 * compiler and the achitecture. gcc2 always seems to do well :-). 135 * Inspired by Dana How <how@isl.stanford.edu> 136 * DO NOT use the alternative version on machines with 8 byte longs. 137 * It does not seem to work on the Alpha, even when DES_LONG is 4 138 * bytes, probably an issue of accessing non-word aligned objects :-( */ 139 #ifdef DES_PTR 140 141 #define D_ENCRYPT(L,R,S) { \ 142 u=((R^s[S ])<<2); \ 143 t= R^s[S+1]; \ 144 t=ROTATE(t,2); \ 145 L^= (\ 146 *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))+ \ 147 *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8)&0xfc))+ \ 148 *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16)&0xfc))+ \ 149 *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24)&0xfc))+ \ 150 *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))+ \ 151 *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8)&0xfc))+ \ 152 *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16)&0xfc))+ \ 153 *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24)&0xfc))); } 154 #else /* original version */ 155 #ifdef undef 156 #define D_ENCRYPT(L,R,S) \ 157 U.l=R^s[S+1]; \ 158 T.s[0]=((U.s[0]>>4)|(U.s[1]<<12))&0x3f3f; \ 159 T.s[1]=((U.s[1]>>4)|(U.s[0]<<12))&0x3f3f; \ 160 U.l=(R^s[S ])&0x3f3f3f3fL; \ 161 L^= des_SPtrans[1][(T.c[0])]| \ 162 des_SPtrans[3][(T.c[1])]| \ 163 des_SPtrans[5][(T.c[2])]| \ 164 des_SPtrans[7][(T.c[3])]| \ 165 des_SPtrans[0][(U.c[0])]| \ 166 des_SPtrans[2][(U.c[1])]| \ 167 des_SPtrans[4][(U.c[2])]| \ 168 des_SPtrans[6][(U.c[3])]; 169 #else 170 #define D_ENCRYPT(Q,R,S) {\ 171 u=(R^s[S ]); \ 172 t=R^s[S+1]; \ 173 t=ROTATE(t,4); \ 174 Q^= des_SPtrans[1][(t )&0x3f]| \ 175 des_SPtrans[3][(t>> 8L)&0x3f]| \ 176 des_SPtrans[5][(t>>16L)&0x3f]| \ 177 des_SPtrans[7][(t>>24L)&0x3f]| \ 178 des_SPtrans[0][(u )&0x3f]| \ 179 des_SPtrans[2][(u>> 8L)&0x3f]| \ 180 des_SPtrans[4][(u>>16L)&0x3f]| \ 181 des_SPtrans[6][(u>>24L)&0x3f]; } 182 #endif 183 #endif 184 185 /* IP and FP 186 * The problem is more of a geometric problem that random bit fiddling. 187 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 188 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 189 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 190 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 191 192 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 193 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 194 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 195 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 196 197 The output has been subject to swaps of the form 198 0 1 -> 3 1 but the odd and even bits have been put into 199 2 3 2 0 200 different words. The main trick is to remember that 201 t=((l>>size)^r)&(mask); 202 r^=t; 203 l^=(t<<size); 204 can be used to swap and move bits between words. 205 206 So l = 0 1 2 3 r = 16 17 18 19 207 4 5 6 7 20 21 22 23 208 8 9 10 11 24 25 26 27 209 12 13 14 15 28 29 30 31 210 becomes (for size == 2 and mask == 0x3333) 211 t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19 212 6^20 7^21 -- -- 4 5 20 21 6 7 22 23 213 10^24 11^25 -- -- 8 9 24 25 10 11 24 25 214 14^28 15^29 -- -- 12 13 28 29 14 15 28 29 215 216 Thanks for hints from Richard Outerbridge - he told me IP&FP 217 could be done in 15 xor, 10 shifts and 5 ands. 218 When I finally started to think of the problem in 2D 219 I first got ~42 operations without xors. When I remembered 220 how to use xors :-) I got it to its final state. 221 */ 222 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ 223 (b)^=(t),\ 224 (a)^=((t)<<(n))) 225 226 #define IP(l,r) \ 227 { \ 228 register DES_LONG tt; \ 229 PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ 230 PERM_OP(l,r,tt,16,0x0000ffffL); \ 231 PERM_OP(r,l,tt, 2,0x33333333L); \ 232 PERM_OP(l,r,tt, 8,0x00ff00ffL); \ 233 PERM_OP(r,l,tt, 1,0x55555555L); \ 234 } 235 236 #define FP(l,r) \ 237 { \ 238 register DES_LONG tt; \ 239 PERM_OP(l,r,tt, 1,0x55555555L); \ 240 PERM_OP(r,l,tt, 8,0x00ff00ffL); \ 241 PERM_OP(l,r,tt, 2,0x33333333L); \ 242 PERM_OP(r,l,tt,16,0x0000ffffL); \ 243 PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ 244 } 245 #endif 246