1 /* crypto/des/set_key.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
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 (tjh@cryptsoft.com).
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.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
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 (eay@cryptsoft.com)"
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 (tjh@cryptsoft.com)"
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
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.]
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
70 static const unsigned char odd_parity
[256]={
71 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
72 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
73 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
74 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
75 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
76 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
77 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
78 112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
79 128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
80 145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
81 161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
82 176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
83 193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
84 208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
85 224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
86 241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
88 void des_set_odd_parity(des_cblock
*key
)
92 for (i
=0; i
<DES_KEY_SZ
; i
++)
93 (*key
)[i
]=odd_parity
[(*key
)[i
]];
96 int des_check_key_parity(const_des_cblock
*key
)
100 for (i
=0; i
<DES_KEY_SZ
; i
++)
102 if ((*key
)[i
] != odd_parity
[(*key
)[i
]])
108 /* Weak and semi week keys as take from
111 * %T Security for Computer Networks
112 * %I John Wiley & Sons
114 * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
115 * (and actual cblock values).
117 #define NUM_WEAK_KEY 16
118 static des_cblock weak_keys
[NUM_WEAK_KEY
]={
120 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
121 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
122 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
123 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
125 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
126 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
127 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
128 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
129 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
130 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
131 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
132 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
133 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
134 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
135 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
136 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
138 int des_is_weak_key(const_des_cblock
*key
)
142 for (i
=0; i
<NUM_WEAK_KEY
; i
++)
143 /* Added == 0 to comparison, I obviously don't run
144 * this section very often :-(, thanks to
145 * engineering@MorningStar.Com for the fix
147 * Another problem, I was comparing only the first 4
149 if (memcmp(weak_keys
[i
],key
,sizeof(des_cblock
)) == 0) return(1);
153 /* NOW DEFINED IN des_local.h
154 * See ecb_encrypt.c for a pseudo description of these macros.
155 * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
157 * (a)=((a)^((t)<<(n))))
160 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
161 (a)=(a)^(t)^(t>>(16-(n))))
163 static const DES_LONG des_skb
[8][64]={
165 /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
166 0x00000000L
,0x00000010L
,0x20000000L
,0x20000010L
,
167 0x00010000L
,0x00010010L
,0x20010000L
,0x20010010L
,
168 0x00000800L
,0x00000810L
,0x20000800L
,0x20000810L
,
169 0x00010800L
,0x00010810L
,0x20010800L
,0x20010810L
,
170 0x00000020L
,0x00000030L
,0x20000020L
,0x20000030L
,
171 0x00010020L
,0x00010030L
,0x20010020L
,0x20010030L
,
172 0x00000820L
,0x00000830L
,0x20000820L
,0x20000830L
,
173 0x00010820L
,0x00010830L
,0x20010820L
,0x20010830L
,
174 0x00080000L
,0x00080010L
,0x20080000L
,0x20080010L
,
175 0x00090000L
,0x00090010L
,0x20090000L
,0x20090010L
,
176 0x00080800L
,0x00080810L
,0x20080800L
,0x20080810L
,
177 0x00090800L
,0x00090810L
,0x20090800L
,0x20090810L
,
178 0x00080020L
,0x00080030L
,0x20080020L
,0x20080030L
,
179 0x00090020L
,0x00090030L
,0x20090020L
,0x20090030L
,
180 0x00080820L
,0x00080830L
,0x20080820L
,0x20080830L
,
181 0x00090820L
,0x00090830L
,0x20090820L
,0x20090830L
,
183 /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
184 0x00000000L
,0x02000000L
,0x00002000L
,0x02002000L
,
185 0x00200000L
,0x02200000L
,0x00202000L
,0x02202000L
,
186 0x00000004L
,0x02000004L
,0x00002004L
,0x02002004L
,
187 0x00200004L
,0x02200004L
,0x00202004L
,0x02202004L
,
188 0x00000400L
,0x02000400L
,0x00002400L
,0x02002400L
,
189 0x00200400L
,0x02200400L
,0x00202400L
,0x02202400L
,
190 0x00000404L
,0x02000404L
,0x00002404L
,0x02002404L
,
191 0x00200404L
,0x02200404L
,0x00202404L
,0x02202404L
,
192 0x10000000L
,0x12000000L
,0x10002000L
,0x12002000L
,
193 0x10200000L
,0x12200000L
,0x10202000L
,0x12202000L
,
194 0x10000004L
,0x12000004L
,0x10002004L
,0x12002004L
,
195 0x10200004L
,0x12200004L
,0x10202004L
,0x12202004L
,
196 0x10000400L
,0x12000400L
,0x10002400L
,0x12002400L
,
197 0x10200400L
,0x12200400L
,0x10202400L
,0x12202400L
,
198 0x10000404L
,0x12000404L
,0x10002404L
,0x12002404L
,
199 0x10200404L
,0x12200404L
,0x10202404L
,0x12202404L
,
201 /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
202 0x00000000L
,0x00000001L
,0x00040000L
,0x00040001L
,
203 0x01000000L
,0x01000001L
,0x01040000L
,0x01040001L
,
204 0x00000002L
,0x00000003L
,0x00040002L
,0x00040003L
,
205 0x01000002L
,0x01000003L
,0x01040002L
,0x01040003L
,
206 0x00000200L
,0x00000201L
,0x00040200L
,0x00040201L
,
207 0x01000200L
,0x01000201L
,0x01040200L
,0x01040201L
,
208 0x00000202L
,0x00000203L
,0x00040202L
,0x00040203L
,
209 0x01000202L
,0x01000203L
,0x01040202L
,0x01040203L
,
210 0x08000000L
,0x08000001L
,0x08040000L
,0x08040001L
,
211 0x09000000L
,0x09000001L
,0x09040000L
,0x09040001L
,
212 0x08000002L
,0x08000003L
,0x08040002L
,0x08040003L
,
213 0x09000002L
,0x09000003L
,0x09040002L
,0x09040003L
,
214 0x08000200L
,0x08000201L
,0x08040200L
,0x08040201L
,
215 0x09000200L
,0x09000201L
,0x09040200L
,0x09040201L
,
216 0x08000202L
,0x08000203L
,0x08040202L
,0x08040203L
,
217 0x09000202L
,0x09000203L
,0x09040202L
,0x09040203L
,
219 /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
220 0x00000000L
,0x00100000L
,0x00000100L
,0x00100100L
,
221 0x00000008L
,0x00100008L
,0x00000108L
,0x00100108L
,
222 0x00001000L
,0x00101000L
,0x00001100L
,0x00101100L
,
223 0x00001008L
,0x00101008L
,0x00001108L
,0x00101108L
,
224 0x04000000L
,0x04100000L
,0x04000100L
,0x04100100L
,
225 0x04000008L
,0x04100008L
,0x04000108L
,0x04100108L
,
226 0x04001000L
,0x04101000L
,0x04001100L
,0x04101100L
,
227 0x04001008L
,0x04101008L
,0x04001108L
,0x04101108L
,
228 0x00020000L
,0x00120000L
,0x00020100L
,0x00120100L
,
229 0x00020008L
,0x00120008L
,0x00020108L
,0x00120108L
,
230 0x00021000L
,0x00121000L
,0x00021100L
,0x00121100L
,
231 0x00021008L
,0x00121008L
,0x00021108L
,0x00121108L
,
232 0x04020000L
,0x04120000L
,0x04020100L
,0x04120100L
,
233 0x04020008L
,0x04120008L
,0x04020108L
,0x04120108L
,
234 0x04021000L
,0x04121000L
,0x04021100L
,0x04121100L
,
235 0x04021008L
,0x04121008L
,0x04021108L
,0x04121108L
,
237 /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
238 0x00000000L
,0x10000000L
,0x00010000L
,0x10010000L
,
239 0x00000004L
,0x10000004L
,0x00010004L
,0x10010004L
,
240 0x20000000L
,0x30000000L
,0x20010000L
,0x30010000L
,
241 0x20000004L
,0x30000004L
,0x20010004L
,0x30010004L
,
242 0x00100000L
,0x10100000L
,0x00110000L
,0x10110000L
,
243 0x00100004L
,0x10100004L
,0x00110004L
,0x10110004L
,
244 0x20100000L
,0x30100000L
,0x20110000L
,0x30110000L
,
245 0x20100004L
,0x30100004L
,0x20110004L
,0x30110004L
,
246 0x00001000L
,0x10001000L
,0x00011000L
,0x10011000L
,
247 0x00001004L
,0x10001004L
,0x00011004L
,0x10011004L
,
248 0x20001000L
,0x30001000L
,0x20011000L
,0x30011000L
,
249 0x20001004L
,0x30001004L
,0x20011004L
,0x30011004L
,
250 0x00101000L
,0x10101000L
,0x00111000L
,0x10111000L
,
251 0x00101004L
,0x10101004L
,0x00111004L
,0x10111004L
,
252 0x20101000L
,0x30101000L
,0x20111000L
,0x30111000L
,
253 0x20101004L
,0x30101004L
,0x20111004L
,0x30111004L
,
255 /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
256 0x00000000L
,0x08000000L
,0x00000008L
,0x08000008L
,
257 0x00000400L
,0x08000400L
,0x00000408L
,0x08000408L
,
258 0x00020000L
,0x08020000L
,0x00020008L
,0x08020008L
,
259 0x00020400L
,0x08020400L
,0x00020408L
,0x08020408L
,
260 0x00000001L
,0x08000001L
,0x00000009L
,0x08000009L
,
261 0x00000401L
,0x08000401L
,0x00000409L
,0x08000409L
,
262 0x00020001L
,0x08020001L
,0x00020009L
,0x08020009L
,
263 0x00020401L
,0x08020401L
,0x00020409L
,0x08020409L
,
264 0x02000000L
,0x0A000000L
,0x02000008L
,0x0A000008L
,
265 0x02000400L
,0x0A000400L
,0x02000408L
,0x0A000408L
,
266 0x02020000L
,0x0A020000L
,0x02020008L
,0x0A020008L
,
267 0x02020400L
,0x0A020400L
,0x02020408L
,0x0A020408L
,
268 0x02000001L
,0x0A000001L
,0x02000009L
,0x0A000009L
,
269 0x02000401L
,0x0A000401L
,0x02000409L
,0x0A000409L
,
270 0x02020001L
,0x0A020001L
,0x02020009L
,0x0A020009L
,
271 0x02020401L
,0x0A020401L
,0x02020409L
,0x0A020409L
,
273 /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
274 0x00000000L
,0x00000100L
,0x00080000L
,0x00080100L
,
275 0x01000000L
,0x01000100L
,0x01080000L
,0x01080100L
,
276 0x00000010L
,0x00000110L
,0x00080010L
,0x00080110L
,
277 0x01000010L
,0x01000110L
,0x01080010L
,0x01080110L
,
278 0x00200000L
,0x00200100L
,0x00280000L
,0x00280100L
,
279 0x01200000L
,0x01200100L
,0x01280000L
,0x01280100L
,
280 0x00200010L
,0x00200110L
,0x00280010L
,0x00280110L
,
281 0x01200010L
,0x01200110L
,0x01280010L
,0x01280110L
,
282 0x00000200L
,0x00000300L
,0x00080200L
,0x00080300L
,
283 0x01000200L
,0x01000300L
,0x01080200L
,0x01080300L
,
284 0x00000210L
,0x00000310L
,0x00080210L
,0x00080310L
,
285 0x01000210L
,0x01000310L
,0x01080210L
,0x01080310L
,
286 0x00200200L
,0x00200300L
,0x00280200L
,0x00280300L
,
287 0x01200200L
,0x01200300L
,0x01280200L
,0x01280300L
,
288 0x00200210L
,0x00200310L
,0x00280210L
,0x00280310L
,
289 0x01200210L
,0x01200310L
,0x01280210L
,0x01280310L
,
291 /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
292 0x00000000L
,0x04000000L
,0x00040000L
,0x04040000L
,
293 0x00000002L
,0x04000002L
,0x00040002L
,0x04040002L
,
294 0x00002000L
,0x04002000L
,0x00042000L
,0x04042000L
,
295 0x00002002L
,0x04002002L
,0x00042002L
,0x04042002L
,
296 0x00000020L
,0x04000020L
,0x00040020L
,0x04040020L
,
297 0x00000022L
,0x04000022L
,0x00040022L
,0x04040022L
,
298 0x00002020L
,0x04002020L
,0x00042020L
,0x04042020L
,
299 0x00002022L
,0x04002022L
,0x00042022L
,0x04042022L
,
300 0x00000800L
,0x04000800L
,0x00040800L
,0x04040800L
,
301 0x00000802L
,0x04000802L
,0x00040802L
,0x04040802L
,
302 0x00002800L
,0x04002800L
,0x00042800L
,0x04042800L
,
303 0x00002802L
,0x04002802L
,0x00042802L
,0x04042802L
,
304 0x00000820L
,0x04000820L
,0x00040820L
,0x04040820L
,
305 0x00000822L
,0x04000822L
,0x00040822L
,0x04040822L
,
306 0x00002820L
,0x04002820L
,0x00042820L
,0x04042820L
,
307 0x00002822L
,0x04002822L
,0x00042822L
,0x04042822L
,
310 int des_set_key(const_des_cblock
*key
, des_key_schedule schedule
)
314 return des_set_key_checked(key
, schedule
);
318 des_set_key_unchecked(key
, schedule
);
323 /* return 0 if key parity is odd (correct),
324 * return -1 if key parity error,
325 * return -2 if illegal weak key.
327 int des_set_key_checked(const_des_cblock
*key
, des_key_schedule schedule
)
329 if (!des_check_key_parity(key
))
331 if (des_is_weak_key(key
))
333 des_set_key_unchecked(key
, schedule
);
337 void des_set_key_unchecked(const_des_cblock
*key
, des_key_schedule schedule
)
339 static int shifts2
[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
340 register DES_LONG c
,d
,t
,s
,t2
;
341 register const unsigned char *in
;
342 register DES_LONG
*k
;
351 /* do PC1 in 47 simple operations :-)
352 * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
353 * for the inspiration. :-) */
354 PERM_OP (d
,c
,t
,4,0x0f0f0f0fL
);
355 HPERM_OP(c
,t
,-2,0xcccc0000L
);
356 HPERM_OP(d
,t
,-2,0xcccc0000L
);
357 PERM_OP (d
,c
,t
,1,0x55555555L
);
358 PERM_OP (c
,d
,t
,8,0x00ff00ffL
);
359 PERM_OP (d
,c
,t
,1,0x55555555L
);
360 d
= (((d
&0x000000ffL
)<<16L)| (d
&0x0000ff00L
) |
361 ((d
&0x00ff0000L
)>>16L)|((c
&0xf0000000L
)>>4L));
364 for (i
=0; i
<ITERATIONS
; i
++)
367 { c
=((c
>>2L)|(c
<<26L)); d
=((d
>>2L)|(d
<<26L)); }
369 { c
=((c
>>1L)|(c
<<27L)); d
=((d
>>1L)|(d
<<27L)); }
372 /* could be a few less shifts but I am to lazy at this
373 * point in time to investigate */
374 s
= des_skb
[0][ (c
)&0x3f ]|
375 des_skb
[1][((c
>> 6L)&0x03)|((c
>> 7L)&0x3c)]|
376 des_skb
[2][((c
>>13L)&0x0f)|((c
>>14L)&0x30)]|
377 des_skb
[3][((c
>>20L)&0x01)|((c
>>21L)&0x06) |
379 t
= des_skb
[4][ (d
)&0x3f ]|
380 des_skb
[5][((d
>> 7L)&0x03)|((d
>> 8L)&0x3c)]|
381 des_skb
[6][ (d
>>15L)&0x3f ]|
382 des_skb
[7][((d
>>21L)&0x0f)|((d
>>22L)&0x30)];
384 /* table contained 0213 4657 */
385 t2
=((t
<<16L)|(s
&0x0000ffffL
))&0xffffffffL
;
386 *(k
++)=ROTATE(t2
,30)&0xffffffffL
;
388 t2
=((s
>>16L)|(t
&0xffff0000L
));
389 *(k
++)=ROTATE(t2
,26)&0xffffffffL
;
393 int des_key_sched(const_des_cblock
*key
, des_key_schedule schedule
)
395 return(des_set_key(key
,schedule
));
398 #undef des_fixup_key_parity
399 void des_fixup_key_parity(des_cblock
*key
)
401 des_set_odd_parity(key
);