POK
set_key.c
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Tue Dec 8 15:53:28 2009
15  */
16 
17 /* crypto/des/set_key.c */
18 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
19  * All rights reserved.
20  *
21  * This package is an SSL implementation written
22  * by Eric Young (eay@cryptsoft.com).
23  * The implementation was written so as to conform with Netscapes SSL.
24  *
25  * This library is free for commercial and non-commercial use as long as
26  * the following conditions are aheared to. The following conditions
27  * apply to all code found in this distribution, be it the RC4, RSA,
28  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
29  * included with this distribution is covered by the same copyright terms
30  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
31  *
32  * Copyright remains Eric Young's, and as such any Copyright notices in
33  * the code are not to be removed.
34  * If this package is used in a product, Eric Young should be given attribution
35  * as the author of the parts of the library used.
36  * This can be in the form of a textual message at program startup or
37  * in documentation (online or textual) provided with the package.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the copyright
43  * notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  * notice, this list of conditions and the following disclaimer in the
46  * documentation and/or other materials provided with the distribution.
47  * 3. All advertising materials mentioning features or use of this software
48  * must display the following acknowledgement:
49  * "This product includes cryptographic software written by
50  * Eric Young (eay@cryptsoft.com)"
51  * The word 'cryptographic' can be left out if the rouines from the library
52  * being used are not cryptographic related :-).
53  * 4. If you include any Windows specific code (or a derivative thereof) from
54  * the apps directory (application code) you must include an acknowledgement:
55  * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
56  *
57  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
58  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
61  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
67  * SUCH DAMAGE.
68  *
69  * The licence and distribution terms for any publically available version or
70  * derivative of this code cannot be changed. i.e. this code cannot simply be
71  * copied and put under another distribution licence
72  * [including the GNU Public Licence.]
73  */
74 
75 /* set_key.c v 1.4 eay 24/9/91
76  * 1.4 Speed up by 400% :-)
77  * 1.3 added register declarations.
78  * 1.2 unrolled make_key_sched a bit more
79  * 1.1 added norm_expand_bits
80  * 1.0 First working version
81  */
82 
83 
84 #ifdef POK_NEEDS_PROTOCOLS_DES
85 
86 #include "des_locl.h"
87 #ifdef OPENSSL_FIPS
88 #include <openssl/fips.h>
89 #endif
90 
91 
92 OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key); /* defaults to false */
93 
94 static const unsigned char odd_parity[256]={
95  1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
96  16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
97  32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
98  49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
99  64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
100  81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
101  97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
102 112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
103 128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
104 145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
105 161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
106 176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
107 193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
108 208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
109 224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
110 241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
111 
112 void DES_set_odd_parity(DES_cblock *key)
113  {
114  unsigned int i;
115 
116  for (i=0; i<DES_KEY_SZ; i++)
117  (*key)[i]=odd_parity[(*key)[i]];
118  }
119 
120 int DES_check_key_parity(const_DES_cblock *key)
121  {
122  unsigned int i;
123 
124  for (i=0; i<DES_KEY_SZ; i++)
125  {
126  if ((*key)[i] != odd_parity[(*key)[i]])
127  return(0);
128  }
129  return(1);
130  }
131 
132 /* Weak and semi week keys as take from
133  * %A D.W. Davies
134  * %A W.L. Price
135  * %T Security for Computer Networks
136  * %I John Wiley & Sons
137  * %D 1984
138  * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
139  * (and actual cblock values).
140  */
141 #define NUM_WEAK_KEY 16
142 static const DES_cblock weak_keys[NUM_WEAK_KEY]={
143  /* weak keys */
144  {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
145  {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
146  {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
147  {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
148  /* semi-weak keys */
149  {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
150  {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
151  {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
152  {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
153  {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
154  {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
155  {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
156  {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
157  {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
158  {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
159  {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
160  {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
161 
162 int DES_is_weak_key(const_DES_cblock *key)
163  {
164  int i;
165 
166  for (i=0; i<NUM_WEAK_KEY; i++)
167  /* Added == 0 to comparison, I obviously don't run
168  * this section very often :-(, thanks to
169  * engineering@MorningStar.Com for the fix
170  * eay 93/06/29
171  * Another problem, I was comparing only the first 4
172  * bytes, 97/03/18 */
173  if (memcmp(weak_keys[i],key,sizeof(DES_cblock)) == 0) return(1);
174  return(0);
175  }
176 
177 /* NOW DEFINED IN des_local.h
178  * See ecb_encrypt.c for a pseudo description of these macros.
179  * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
180  * (b)^=(t),\
181  * (a)=((a)^((t)<<(n))))
182  */
183 
184 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
185  (a)=(a)^(t)^(t>>(16-(n))))
186 
187 static const DES_LONG des_skb[8][64]={
188  {
189  /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
190  0x00000000L,0x00000010L,0x20000000L,0x20000010L,
191  0x00010000L,0x00010010L,0x20010000L,0x20010010L,
192  0x00000800L,0x00000810L,0x20000800L,0x20000810L,
193  0x00010800L,0x00010810L,0x20010800L,0x20010810L,
194  0x00000020L,0x00000030L,0x20000020L,0x20000030L,
195  0x00010020L,0x00010030L,0x20010020L,0x20010030L,
196  0x00000820L,0x00000830L,0x20000820L,0x20000830L,
197  0x00010820L,0x00010830L,0x20010820L,0x20010830L,
198  0x00080000L,0x00080010L,0x20080000L,0x20080010L,
199  0x00090000L,0x00090010L,0x20090000L,0x20090010L,
200  0x00080800L,0x00080810L,0x20080800L,0x20080810L,
201  0x00090800L,0x00090810L,0x20090800L,0x20090810L,
202  0x00080020L,0x00080030L,0x20080020L,0x20080030L,
203  0x00090020L,0x00090030L,0x20090020L,0x20090030L,
204  0x00080820L,0x00080830L,0x20080820L,0x20080830L,
205  0x00090820L,0x00090830L,0x20090820L,0x20090830L,
206  },{
207  /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
208  0x00000000L,0x02000000L,0x00002000L,0x02002000L,
209  0x00200000L,0x02200000L,0x00202000L,0x02202000L,
210  0x00000004L,0x02000004L,0x00002004L,0x02002004L,
211  0x00200004L,0x02200004L,0x00202004L,0x02202004L,
212  0x00000400L,0x02000400L,0x00002400L,0x02002400L,
213  0x00200400L,0x02200400L,0x00202400L,0x02202400L,
214  0x00000404L,0x02000404L,0x00002404L,0x02002404L,
215  0x00200404L,0x02200404L,0x00202404L,0x02202404L,
216  0x10000000L,0x12000000L,0x10002000L,0x12002000L,
217  0x10200000L,0x12200000L,0x10202000L,0x12202000L,
218  0x10000004L,0x12000004L,0x10002004L,0x12002004L,
219  0x10200004L,0x12200004L,0x10202004L,0x12202004L,
220  0x10000400L,0x12000400L,0x10002400L,0x12002400L,
221  0x10200400L,0x12200400L,0x10202400L,0x12202400L,
222  0x10000404L,0x12000404L,0x10002404L,0x12002404L,
223  0x10200404L,0x12200404L,0x10202404L,0x12202404L,
224  },{
225  /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
226  0x00000000L,0x00000001L,0x00040000L,0x00040001L,
227  0x01000000L,0x01000001L,0x01040000L,0x01040001L,
228  0x00000002L,0x00000003L,0x00040002L,0x00040003L,
229  0x01000002L,0x01000003L,0x01040002L,0x01040003L,
230  0x00000200L,0x00000201L,0x00040200L,0x00040201L,
231  0x01000200L,0x01000201L,0x01040200L,0x01040201L,
232  0x00000202L,0x00000203L,0x00040202L,0x00040203L,
233  0x01000202L,0x01000203L,0x01040202L,0x01040203L,
234  0x08000000L,0x08000001L,0x08040000L,0x08040001L,
235  0x09000000L,0x09000001L,0x09040000L,0x09040001L,
236  0x08000002L,0x08000003L,0x08040002L,0x08040003L,
237  0x09000002L,0x09000003L,0x09040002L,0x09040003L,
238  0x08000200L,0x08000201L,0x08040200L,0x08040201L,
239  0x09000200L,0x09000201L,0x09040200L,0x09040201L,
240  0x08000202L,0x08000203L,0x08040202L,0x08040203L,
241  0x09000202L,0x09000203L,0x09040202L,0x09040203L,
242  },{
243  /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
244  0x00000000L,0x00100000L,0x00000100L,0x00100100L,
245  0x00000008L,0x00100008L,0x00000108L,0x00100108L,
246  0x00001000L,0x00101000L,0x00001100L,0x00101100L,
247  0x00001008L,0x00101008L,0x00001108L,0x00101108L,
248  0x04000000L,0x04100000L,0x04000100L,0x04100100L,
249  0x04000008L,0x04100008L,0x04000108L,0x04100108L,
250  0x04001000L,0x04101000L,0x04001100L,0x04101100L,
251  0x04001008L,0x04101008L,0x04001108L,0x04101108L,
252  0x00020000L,0x00120000L,0x00020100L,0x00120100L,
253  0x00020008L,0x00120008L,0x00020108L,0x00120108L,
254  0x00021000L,0x00121000L,0x00021100L,0x00121100L,
255  0x00021008L,0x00121008L,0x00021108L,0x00121108L,
256  0x04020000L,0x04120000L,0x04020100L,0x04120100L,
257  0x04020008L,0x04120008L,0x04020108L,0x04120108L,
258  0x04021000L,0x04121000L,0x04021100L,0x04121100L,
259  0x04021008L,0x04121008L,0x04021108L,0x04121108L,
260  },{
261  /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
262  0x00000000L,0x10000000L,0x00010000L,0x10010000L,
263  0x00000004L,0x10000004L,0x00010004L,0x10010004L,
264  0x20000000L,0x30000000L,0x20010000L,0x30010000L,
265  0x20000004L,0x30000004L,0x20010004L,0x30010004L,
266  0x00100000L,0x10100000L,0x00110000L,0x10110000L,
267  0x00100004L,0x10100004L,0x00110004L,0x10110004L,
268  0x20100000L,0x30100000L,0x20110000L,0x30110000L,
269  0x20100004L,0x30100004L,0x20110004L,0x30110004L,
270  0x00001000L,0x10001000L,0x00011000L,0x10011000L,
271  0x00001004L,0x10001004L,0x00011004L,0x10011004L,
272  0x20001000L,0x30001000L,0x20011000L,0x30011000L,
273  0x20001004L,0x30001004L,0x20011004L,0x30011004L,
274  0x00101000L,0x10101000L,0x00111000L,0x10111000L,
275  0x00101004L,0x10101004L,0x00111004L,0x10111004L,
276  0x20101000L,0x30101000L,0x20111000L,0x30111000L,
277  0x20101004L,0x30101004L,0x20111004L,0x30111004L,
278  },{
279  /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
280  0x00000000L,0x08000000L,0x00000008L,0x08000008L,
281  0x00000400L,0x08000400L,0x00000408L,0x08000408L,
282  0x00020000L,0x08020000L,0x00020008L,0x08020008L,
283  0x00020400L,0x08020400L,0x00020408L,0x08020408L,
284  0x00000001L,0x08000001L,0x00000009L,0x08000009L,
285  0x00000401L,0x08000401L,0x00000409L,0x08000409L,
286  0x00020001L,0x08020001L,0x00020009L,0x08020009L,
287  0x00020401L,0x08020401L,0x00020409L,0x08020409L,
288  0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
289  0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
290  0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
291  0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
292  0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
293  0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
294  0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
295  0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
296  },{
297  /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
298  0x00000000L,0x00000100L,0x00080000L,0x00080100L,
299  0x01000000L,0x01000100L,0x01080000L,0x01080100L,
300  0x00000010L,0x00000110L,0x00080010L,0x00080110L,
301  0x01000010L,0x01000110L,0x01080010L,0x01080110L,
302  0x00200000L,0x00200100L,0x00280000L,0x00280100L,
303  0x01200000L,0x01200100L,0x01280000L,0x01280100L,
304  0x00200010L,0x00200110L,0x00280010L,0x00280110L,
305  0x01200010L,0x01200110L,0x01280010L,0x01280110L,
306  0x00000200L,0x00000300L,0x00080200L,0x00080300L,
307  0x01000200L,0x01000300L,0x01080200L,0x01080300L,
308  0x00000210L,0x00000310L,0x00080210L,0x00080310L,
309  0x01000210L,0x01000310L,0x01080210L,0x01080310L,
310  0x00200200L,0x00200300L,0x00280200L,0x00280300L,
311  0x01200200L,0x01200300L,0x01280200L,0x01280300L,
312  0x00200210L,0x00200310L,0x00280210L,0x00280310L,
313  0x01200210L,0x01200310L,0x01280210L,0x01280310L,
314  },{
315  /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
316  0x00000000L,0x04000000L,0x00040000L,0x04040000L,
317  0x00000002L,0x04000002L,0x00040002L,0x04040002L,
318  0x00002000L,0x04002000L,0x00042000L,0x04042000L,
319  0x00002002L,0x04002002L,0x00042002L,0x04042002L,
320  0x00000020L,0x04000020L,0x00040020L,0x04040020L,
321  0x00000022L,0x04000022L,0x00040022L,0x04040022L,
322  0x00002020L,0x04002020L,0x00042020L,0x04042020L,
323  0x00002022L,0x04002022L,0x00042022L,0x04042022L,
324  0x00000800L,0x04000800L,0x00040800L,0x04040800L,
325  0x00000802L,0x04000802L,0x00040802L,0x04040802L,
326  0x00002800L,0x04002800L,0x00042800L,0x04042800L,
327  0x00002802L,0x04002802L,0x00042802L,0x04042802L,
328  0x00000820L,0x04000820L,0x00040820L,0x04040820L,
329  0x00000822L,0x04000822L,0x00040822L,0x04040822L,
330  0x00002820L,0x04002820L,0x00042820L,0x04042820L,
331  0x00002822L,0x04002822L,0x00042822L,0x04042822L,
332  }};
333 
334 int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
335  {
336  if (DES_check_key)
337  {
338  return DES_set_key_checked(key, schedule);
339  }
340  else
341  {
342  DES_set_key_unchecked(key, schedule);
343  return 0;
344  }
345  }
346 
347 /* return 0 if key parity is odd (correct),
348  * return -1 if key parity error,
349  * return -2 if illegal weak key.
350  */
351 int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
352  {
353  if (!DES_check_key_parity(key))
354  return(-1);
355  if (DES_is_weak_key(key))
356  return(-2);
357  DES_set_key_unchecked(key, schedule);
358  return 0;
359  }
360 
361 void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
362  {
363  static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
364  register DES_LONG c,d,t,s,t2;
365  register const unsigned char *in;
366  register DES_LONG *k;
367  register int i;
368 
369 #ifdef OPENBSD_DEV_CRYPTO
370  memcpy(schedule->key,key,sizeof schedule->key);
371  schedule->session=NULL;
372 #endif
373  k = &schedule->ks->deslong[0];
374  in = &(*key)[0];
375 
376 #ifdef OPENSSL_FIPS
377  FIPS_selftest_check();
378 #endif
379 
380  c2l(in,c);
381  c2l(in,d);
382 
383  /* do PC1 in 47 simple operations :-)
384  * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
385  * for the inspiration. :-) */
386  PERM_OP (d,c,t,4,0x0f0f0f0fL);
387  HPERM_OP(c,t,-2,0xcccc0000L);
388  HPERM_OP(d,t,-2,0xcccc0000L);
389  PERM_OP (d,c,t,1,0x55555555L);
390  PERM_OP (c,d,t,8,0x00ff00ffL);
391  PERM_OP (d,c,t,1,0x55555555L);
392  d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
393  ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
394  c&=0x0fffffffL;
395 
396  for (i=0; i<ITERATIONS; i++)
397  {
398  if (shifts2[i])
399  { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
400  else
401  { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
402  c&=0x0fffffffL;
403  d&=0x0fffffffL;
404  /* could be a few less shifts but I am to lazy at this
405  * point in time to investigate */
406  s= des_skb[0][ (c )&0x3f ]|
407  des_skb[1][((c>> 6L)&0x03)|((c>> 7L)&0x3c)]|
408  des_skb[2][((c>>13L)&0x0f)|((c>>14L)&0x30)]|
409  des_skb[3][((c>>20L)&0x01)|((c>>21L)&0x06) |
410  ((c>>22L)&0x38)];
411  t= des_skb[4][ (d )&0x3f ]|
412  des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
413  des_skb[6][ (d>>15L)&0x3f ]|
414  des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
415 
416  /* table contained 0213 4657 */
417  t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
418  *(k++)=ROTATE(t2,30)&0xffffffffL;
419 
420  t2=((s>>16L)|(t&0xffff0000L));
421  *(k++)=ROTATE(t2,26)&0xffffffffL;
422  }
423  }
424 
425 int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
426  {
427  return(DES_set_key(key,schedule));
428  }
429 /*
430 #undef des_fixup_key_parity
431 void des_fixup_key_parity(des_cblock *key)
432  {
433  des_set_odd_parity(key);
434  }
435 */
436 
437 #endif /* POK_NEEDS_ ...*/