|
|
1.1 ! root 1: /* crypto/des/set_key.c */ ! 2: /* Copyright (C) 1995-1997 Eric Young ([email protected]) ! 3: * All rights reserved. ! 4: * ! 5: * This package is an SSL implementation written ! 6: * by Eric Young ([email protected]). ! 7: * The implementation was written so as to conform with Netscapes SSL. ! 8: * ! 9: * This library is free for commercial and non-commercial use as long as ! 10: * the following conditions are aheared to. The following conditions ! 11: * apply to all code found in this distribution, be it the RC4, RSA, ! 12: * lhash, DES, etc., code; not just the SSL code. The SSL documentation ! 13: * included with this distribution is covered by the same copyright terms ! 14: * except that the holder is Tim Hudson ([email protected]). ! 15: * ! 16: * Copyright remains Eric Young's, and as such any Copyright notices in ! 17: * the code are not to be removed. ! 18: * If this package is used in a product, Eric Young should be given attribution ! 19: * as the author of the parts of the library used. ! 20: * This can be in the form of a textual message at program startup or ! 21: * in documentation (online or textual) provided with the package. ! 22: * ! 23: * Redistribution and use in source and binary forms, with or without ! 24: * modification, are permitted provided that the following conditions ! 25: * are met: ! 26: * 1. Redistributions of source code must retain the copyright ! 27: * notice, this list of conditions and the following disclaimer. ! 28: * 2. Redistributions in binary form must reproduce the above copyright ! 29: * notice, this list of conditions and the following disclaimer in the ! 30: * documentation and/or other materials provided with the distribution. ! 31: * 3. All advertising materials mentioning features or use of this software ! 32: * must display the following acknowledgement: ! 33: * "This product includes cryptographic software written by ! 34: * Eric Young ([email protected])" ! 35: * The word 'cryptographic' can be left out if the rouines from the library ! 36: * being used are not cryptographic related :-). ! 37: * 4. If you include any Windows specific code (or a derivative thereof) from ! 38: * the apps directory (application code) you must include an acknowledgement: ! 39: * "This product includes software written by Tim Hudson ([email protected])" ! 40: * ! 41: * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ! 42: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 43: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 44: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ! 45: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 46: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 47: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 48: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 49: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 50: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 51: * SUCH DAMAGE. ! 52: * ! 53: * The licence and distribution terms for any publically available version or ! 54: * derivative of this code cannot be changed. i.e. this code cannot simply be ! 55: * copied and put under another distribution licence ! 56: * [including the GNU Public Licence.] ! 57: */ ! 58: ! 59: /* set_key.c v 1.4 eay 24/9/91 ! 60: * 1.4 Speed up by 400% :-) ! 61: * 1.3 added register declarations. ! 62: * 1.2 unrolled make_key_sched a bit more ! 63: * 1.1 added norm_expand_bits ! 64: * 1.0 First working version ! 65: */ ! 66: ! 67: #include "des_locl.h" ! 68: #include "podd.h" ! 69: #include "sk.h" ! 70: ! 71: #pragma intrinsic(memcmp,_lrotr) ! 72: ! 73: ! 74: #ifndef NOPROTO ! 75: static int check_parity(des_cblock (*key)); ! 76: #else ! 77: static int check_parity(); ! 78: #endif ! 79: ! 80: #pragma warning( disable : 4131 ) ! 81: ! 82: int des_check_key=0; ! 83: ! 84: void des_set_odd_parity(key) ! 85: des_cblock (*key); ! 86: { ! 87: int i; ! 88: ! 89: for (i=0; i<DES_KEY_SZ; i++) ! 90: (*key)[i]=odd_parity[(*key)[i]]; ! 91: } ! 92: ! 93: static int check_parity(key) ! 94: des_cblock (*key); ! 95: { ! 96: int i; ! 97: ! 98: for (i=0; i<DES_KEY_SZ; i++) ! 99: { ! 100: if ((*key)[i] != odd_parity[(*key)[i]]) ! 101: return(0); ! 102: } ! 103: return(1); ! 104: } ! 105: ! 106: /* Weak and semi week keys as take from ! 107: * %A D.W. Davies ! 108: * %A W.L. Price ! 109: * %T Security for Computer Networks ! 110: * %I John Wiley & Sons ! 111: * %D 1984 ! 112: * Many thanks to [email protected] (Steven Bellovin) for the reference ! 113: * (and actual cblock values). ! 114: */ ! 115: #define NUM_WEAK_KEY 16 ! 116: static des_cblock weak_keys[NUM_WEAK_KEY]={ ! 117: /* weak keys */ ! 118: {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, ! 119: {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE}, ! 120: {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, ! 121: {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0}, ! 122: /* semi-weak keys */ ! 123: {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, ! 124: {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01}, ! 125: {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1}, ! 126: {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E}, ! 127: {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1}, ! 128: {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01}, ! 129: {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE}, ! 130: {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E}, ! 131: {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E}, ! 132: {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01}, ! 133: {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, ! 134: {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}}; ! 135: ! 136: int des_is_weak_key(key) ! 137: des_cblock (*key); ! 138: { ! 139: int i; ! 140: ! 141: for (i=0; i<NUM_WEAK_KEY; i++) ! 142: /* Added == 0 to comparision, I obviously don't run ! 143: * this section very often :-(, thanks to ! 144: * [email protected] for the fix ! 145: * eay 93/06/29 ! 146: * Another problem, I was comparing only the first 4 ! 147: * bytes, 97/03/18 */ ! 148: if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1); ! 149: return(0); ! 150: } ! 151: ! 152: /* NOW DEFINED IN des_local.h ! 153: * See ecb_encrypt.c for a pseudo description of these macros. ! 154: * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ ! 155: * (b)^=(t),\ ! 156: * (a)=((a)^((t)<<(n)))) ! 157: */ ! 158: ! 159: #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ ! 160: (a)=(a)^(t)^(t>>(16-(n)))) ! 161: ! 162: /* return 0 if key parity is odd (correct), ! 163: * return -1 if key parity error, ! 164: * return -2 if illegal weak key. ! 165: */ ! 166: int des_set_key(key, schedule) ! 167: des_cblock (*key); ! 168: des_key_schedule schedule; ! 169: { ! 170: static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; ! 171: register DES_LONG c,d,t,s,t2; ! 172: register unsigned char *in; ! 173: register DES_LONG *k; ! 174: register int i; ! 175: ! 176: if (des_check_key) ! 177: { ! 178: if (!check_parity(key)) ! 179: return(-1); ! 180: ! 181: if (des_is_weak_key(key)) ! 182: return(-2); ! 183: } ! 184: ! 185: k=(DES_LONG *)schedule; ! 186: in=(unsigned char *)key; ! 187: ! 188: c2l(in,c); ! 189: c2l(in,d); ! 190: ! 191: /* do PC1 in 60 simple operations */ ! 192: /* PERM_OP(d,c,t,4,0x0f0f0f0fL); ! 193: HPERM_OP(c,t,-2, 0xcccc0000L); ! 194: HPERM_OP(c,t,-1, 0xaaaa0000L); ! 195: HPERM_OP(c,t, 8, 0x00ff0000L); ! 196: HPERM_OP(c,t,-1, 0xaaaa0000L); ! 197: HPERM_OP(d,t,-8, 0xff000000L); ! 198: HPERM_OP(d,t, 8, 0x00ff0000L); ! 199: HPERM_OP(d,t, 2, 0x33330000L); ! 200: d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L); ! 201: d=(d>>8)|((c&0xf0000000L)>>4); ! 202: c&=0x0fffffffL; */ ! 203: ! 204: /* I now do it in 47 simple operations :-) ! 205: * Thanks to John Fletcher ([email protected]) ! 206: * for the inspiration. :-) */ ! 207: PERM_OP (d,c,t,4,0x0f0f0f0fL); ! 208: HPERM_OP(c,t,-2,0xcccc0000L); ! 209: HPERM_OP(d,t,-2,0xcccc0000L); ! 210: PERM_OP (d,c,t,1,0x55555555L); ! 211: PERM_OP (c,d,t,8,0x00ff00ffL); ! 212: PERM_OP (d,c,t,1,0x55555555L); ! 213: d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) | ! 214: ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L)); ! 215: c&=0x0fffffffL; ! 216: ! 217: for (i=0; i<ITERATIONS; i++) ! 218: { ! 219: if (shifts2[i]) ! 220: { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); } ! 221: else ! 222: { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); } ! 223: c&=0x0fffffffL; ! 224: d&=0x0fffffffL; ! 225: /* could be a few less shifts but I am to lazy at this ! 226: * point in time to investigate */ ! 227: s= des_skb[0][ (c )&0x3f ]| ! 228: des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]| ! 229: des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]| ! 230: des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) | ! 231: ((c>>22L)&0x38)]; ! 232: t= des_skb[4][ (d )&0x3f ]| ! 233: des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]| ! 234: des_skb[6][ (d>>15L)&0x3f ]| ! 235: des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)]; ! 236: ! 237: /* table contained 0213 4657 */ ! 238: t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL; ! 239: *(k++)=ROTATE(t2,30)&0xffffffffL; ! 240: ! 241: t2=((s>>16L)|(t&0xffff0000L)); ! 242: *(k++)=ROTATE(t2,26)&0xffffffffL; ! 243: } ! 244: return(0); ! 245: } ! 246: ! 247: int _cdecl des_key_sched(key, schedule) ! 248: des_cblock (*key); ! 249: des_key_schedule schedule; ! 250: { ! 251: return(des_set_key(key,schedule)); ! 252: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.