155714Skris/* crypto/des/set_key.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296465Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296465Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296465Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296465Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296465Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
59296465Sdelphij/*-
60296465Sdelphij * set_key.c v 1.4 eay 24/9/91
6155714Skris * 1.4 Speed up by 400% :-)
6255714Skris * 1.3 added register declarations.
6355714Skris * 1.2 unrolled make_key_sched a bit more
6455714Skris * 1.1 added norm_expand_bits
6555714Skris * 1.0 First working version
6655714Skris */
6755714Skris#include "des_locl.h"
68194206Ssimon#ifdef OPENSSL_FIPS
69296465Sdelphij# include <openssl/fips.h>
70194206Ssimon#endif
7155714Skris
72296465SdelphijOPENSSL_IMPLEMENT_GLOBAL(int, DES_check_key); /* defaults to false */
73194206Ssimon
74296465Sdelphijstatic const unsigned char odd_parity[256] = {
75296465Sdelphij    1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
76296465Sdelphij    16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
77296465Sdelphij    32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
78296465Sdelphij    49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
79296465Sdelphij    64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
80296465Sdelphij    81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
81296465Sdelphij    97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110,
82296465Sdelphij    110,
83296465Sdelphij    112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127,
84296465Sdelphij    127,
85296465Sdelphij    128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143,
86296465Sdelphij    143,
87296465Sdelphij    145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158,
88296465Sdelphij    158,
89296465Sdelphij    161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174,
90296465Sdelphij    174,
91296465Sdelphij    176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191,
92296465Sdelphij    191,
93296465Sdelphij    193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206,
94296465Sdelphij    206,
95296465Sdelphij    208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223,
96296465Sdelphij    223,
97296465Sdelphij    224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239,
98296465Sdelphij    239,
99296465Sdelphij    241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254,
100296465Sdelphij    254
101296465Sdelphij};
10255714Skris
103109998Smarkmvoid DES_set_odd_parity(DES_cblock *key)
104296465Sdelphij{
105296465Sdelphij    unsigned int i;
10655714Skris
107296465Sdelphij    for (i = 0; i < DES_KEY_SZ; i++)
108296465Sdelphij        (*key)[i] = odd_parity[(*key)[i]];
109296465Sdelphij}
11055714Skris
111109998Smarkmint DES_check_key_parity(const_DES_cblock *key)
112296465Sdelphij{
113296465Sdelphij    unsigned int i;
11455714Skris
115296465Sdelphij    for (i = 0; i < DES_KEY_SZ; i++) {
116296465Sdelphij        if ((*key)[i] != odd_parity[(*key)[i]])
117296465Sdelphij            return (0);
118296465Sdelphij    }
119296465Sdelphij    return (1);
120296465Sdelphij}
12155714Skris
122296465Sdelphij/*-
123296465Sdelphij * Weak and semi week keys as take from
12455714Skris * %A D.W. Davies
12555714Skris * %A W.L. Price
12655714Skris * %T Security for Computer Networks
12755714Skris * %I John Wiley & Sons
12855714Skris * %D 1984
12955714Skris * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
13055714Skris * (and actual cblock values).
13155714Skris */
132296465Sdelphij#define NUM_WEAK_KEY    16
133296465Sdelphijstatic const DES_cblock weak_keys[NUM_WEAK_KEY] = {
134296465Sdelphij    /* weak keys */
135296465Sdelphij    {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
136296465Sdelphij    {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE},
137296465Sdelphij    {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
138296465Sdelphij    {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1},
139296465Sdelphij    /* semi-weak keys */
140296465Sdelphij    {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE},
141296465Sdelphij    {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01},
142296465Sdelphij    {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1},
143296465Sdelphij    {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E},
144296465Sdelphij    {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1},
145296465Sdelphij    {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01},
146296465Sdelphij    {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE},
147296465Sdelphij    {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E},
148296465Sdelphij    {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E},
149296465Sdelphij    {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01},
150296465Sdelphij    {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
151296465Sdelphij    {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1}
152296465Sdelphij};
15355714Skris
154109998Smarkmint DES_is_weak_key(const_DES_cblock *key)
155296465Sdelphij{
156296465Sdelphij    int i;
15755714Skris
158296465Sdelphij    for (i = 0; i < NUM_WEAK_KEY; i++)
159296465Sdelphij        /*
160296465Sdelphij         * Added == 0 to comparison, I obviously don't run this section very
161296465Sdelphij         * often :-(, thanks to engineering@MorningStar.Com for the fix eay
162296465Sdelphij         * 93/06/29 Another problem, I was comparing only the first 4 bytes,
163296465Sdelphij         * 97/03/18
164296465Sdelphij         */
165296465Sdelphij        if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0)
166296465Sdelphij            return (1);
167296465Sdelphij    return (0);
168296465Sdelphij}
16955714Skris
170296465Sdelphij/*-
171296465Sdelphij * NOW DEFINED IN des_local.h
172296465Sdelphij * See ecb_encrypt.c for a pseudo description of these macros.
17355714Skris * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
174296465Sdelphij *      (b)^=(t),\
175296465Sdelphij *      (a)=((a)^((t)<<(n))))
17655714Skris */
17755714Skris
17855714Skris#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
179296465Sdelphij        (a)=(a)^(t)^(t>>(16-(n))))
18055714Skris
181296465Sdelphijstatic const DES_LONG des_skb[8][64] = {
182296465Sdelphij    {
183296465Sdelphij     /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
184296465Sdelphij     0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L,
185296465Sdelphij     0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L,
186296465Sdelphij     0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L,
187296465Sdelphij     0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L,
188296465Sdelphij     0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L,
189296465Sdelphij     0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L,
190296465Sdelphij     0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L,
191296465Sdelphij     0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L,
192296465Sdelphij     0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L,
193296465Sdelphij     0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L,
194296465Sdelphij     0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L,
195296465Sdelphij     0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L,
196296465Sdelphij     0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L,
197296465Sdelphij     0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L,
198296465Sdelphij     0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L,
199296465Sdelphij     0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L,
200296465Sdelphij     },
201296465Sdelphij    {
202296465Sdelphij     /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
203296465Sdelphij     0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L,
204296465Sdelphij     0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L,
205296465Sdelphij     0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L,
206296465Sdelphij     0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L,
207296465Sdelphij     0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L,
208296465Sdelphij     0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L,
209296465Sdelphij     0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L,
210296465Sdelphij     0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L,
211296465Sdelphij     0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L,
212296465Sdelphij     0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L,
213296465Sdelphij     0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L,
214296465Sdelphij     0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L,
215296465Sdelphij     0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L,
216296465Sdelphij     0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L,
217296465Sdelphij     0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L,
218296465Sdelphij     0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L,
219296465Sdelphij     },
220296465Sdelphij    {
221296465Sdelphij     /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
222296465Sdelphij     0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L,
223296465Sdelphij     0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L,
224296465Sdelphij     0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L,
225296465Sdelphij     0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L,
226296465Sdelphij     0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L,
227296465Sdelphij     0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L,
228296465Sdelphij     0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L,
229296465Sdelphij     0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L,
230296465Sdelphij     0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L,
231296465Sdelphij     0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L,
232296465Sdelphij     0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L,
233296465Sdelphij     0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L,
234296465Sdelphij     0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L,
235296465Sdelphij     0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L,
236296465Sdelphij     0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L,
237296465Sdelphij     0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L,
238296465Sdelphij     },
239296465Sdelphij    {
240296465Sdelphij     /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
241296465Sdelphij     0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L,
242296465Sdelphij     0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L,
243296465Sdelphij     0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L,
244296465Sdelphij     0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L,
245296465Sdelphij     0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L,
246296465Sdelphij     0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L,
247296465Sdelphij     0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L,
248296465Sdelphij     0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L,
249296465Sdelphij     0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L,
250296465Sdelphij     0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L,
251296465Sdelphij     0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L,
252296465Sdelphij     0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L,
253296465Sdelphij     0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L,
254296465Sdelphij     0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L,
255296465Sdelphij     0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L,
256296465Sdelphij     0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L,
257296465Sdelphij     },
258296465Sdelphij    {
259296465Sdelphij     /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
260296465Sdelphij     0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L,
261296465Sdelphij     0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L,
262296465Sdelphij     0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L,
263296465Sdelphij     0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L,
264296465Sdelphij     0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L,
265296465Sdelphij     0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L,
266296465Sdelphij     0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L,
267296465Sdelphij     0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L,
268296465Sdelphij     0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L,
269296465Sdelphij     0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L,
270296465Sdelphij     0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L,
271296465Sdelphij     0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L,
272296465Sdelphij     0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L,
273296465Sdelphij     0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L,
274296465Sdelphij     0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L,
275296465Sdelphij     0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L,
276296465Sdelphij     },
277296465Sdelphij    {
278296465Sdelphij     /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
279296465Sdelphij     0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L,
280296465Sdelphij     0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L,
281296465Sdelphij     0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L,
282296465Sdelphij     0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L,
283296465Sdelphij     0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L,
284296465Sdelphij     0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L,
285296465Sdelphij     0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L,
286296465Sdelphij     0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L,
287296465Sdelphij     0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L,
288296465Sdelphij     0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L,
289296465Sdelphij     0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L,
290296465Sdelphij     0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L,
291296465Sdelphij     0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L,
292296465Sdelphij     0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L,
293296465Sdelphij     0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L,
294296465Sdelphij     0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L,
295296465Sdelphij     },
296296465Sdelphij    {
297296465Sdelphij     /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
298296465Sdelphij     0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L,
299296465Sdelphij     0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L,
300296465Sdelphij     0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L,
301296465Sdelphij     0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L,
302296465Sdelphij     0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L,
303296465Sdelphij     0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L,
304296465Sdelphij     0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L,
305296465Sdelphij     0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L,
306296465Sdelphij     0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L,
307296465Sdelphij     0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L,
308296465Sdelphij     0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L,
309296465Sdelphij     0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L,
310296465Sdelphij     0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L,
311296465Sdelphij     0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L,
312296465Sdelphij     0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L,
313296465Sdelphij     0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L,
314296465Sdelphij     },
315296465Sdelphij    {
316296465Sdelphij     /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
317296465Sdelphij     0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L,
318296465Sdelphij     0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L,
319296465Sdelphij     0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L,
320296465Sdelphij     0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L,
321296465Sdelphij     0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L,
322296465Sdelphij     0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L,
323296465Sdelphij     0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L,
324296465Sdelphij     0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L,
325296465Sdelphij     0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L,
326296465Sdelphij     0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L,
327296465Sdelphij     0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L,
328296465Sdelphij     0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L,
329296465Sdelphij     0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L,
330296465Sdelphij     0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L,
331296465Sdelphij     0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L,
332296465Sdelphij     0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L,
333296465Sdelphij     }
334296465Sdelphij};
33559191Skris
336109998Smarkmint DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
337296465Sdelphij{
338296465Sdelphij    if (DES_check_key) {
339296465Sdelphij        return DES_set_key_checked(key, schedule);
340296465Sdelphij    } else {
341296465Sdelphij        DES_set_key_unchecked(key, schedule);
342296465Sdelphij        return 0;
343296465Sdelphij    }
344296465Sdelphij}
34559191Skris
346296465Sdelphij/*-
347296465Sdelphij * return 0 if key parity is odd (correct),
34855714Skris * return -1 if key parity error,
34955714Skris * return -2 if illegal weak key.
35055714Skris */
351109998Smarkmint DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
352296465Sdelphij{
353296465Sdelphij    if (!DES_check_key_parity(key))
354296465Sdelphij        return (-1);
355296465Sdelphij    if (DES_is_weak_key(key))
356296465Sdelphij        return (-2);
357296465Sdelphij    DES_set_key_unchecked(key, schedule);
358296465Sdelphij    return 0;
359296465Sdelphij}
36059191Skris
361109998Smarkmvoid DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
362296465Sdelphij{
363296465Sdelphij    static int shifts2[16] =
364296465Sdelphij        { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 };
365296465Sdelphij    register DES_LONG c, d, t, s, t2;
366296465Sdelphij    register const unsigned char *in;
367296465Sdelphij    register DES_LONG *k;
368296465Sdelphij    register int i;
36955714Skris
370109998Smarkm#ifdef OPENBSD_DEV_CRYPTO
371296465Sdelphij    memcpy(schedule->key, key, sizeof schedule->key);
372296465Sdelphij    schedule->session = NULL;
373109998Smarkm#endif
374296465Sdelphij    k = &schedule->ks->deslong[0];
375296465Sdelphij    in = &(*key)[0];
37655714Skris
377194206Ssimon#ifdef OPENSSL_FIPS
378296465Sdelphij    FIPS_selftest_check();
379194206Ssimon#endif
380194206Ssimon
381296465Sdelphij    c2l(in, c);
382296465Sdelphij    c2l(in, d);
38355714Skris
384296465Sdelphij    /*
385296465Sdelphij     * do PC1 in 47 simple operations :-) Thanks to John Fletcher
386296465Sdelphij     * (john_fletcher@lccmail.ocf.llnl.gov) for the inspiration. :-)
387296465Sdelphij     */
388296465Sdelphij    PERM_OP(d, c, t, 4, 0x0f0f0f0fL);
389296465Sdelphij    HPERM_OP(c, t, -2, 0xcccc0000L);
390296465Sdelphij    HPERM_OP(d, t, -2, 0xcccc0000L);
391296465Sdelphij    PERM_OP(d, c, t, 1, 0x55555555L);
392296465Sdelphij    PERM_OP(c, d, t, 8, 0x00ff00ffL);
393296465Sdelphij    PERM_OP(d, c, t, 1, 0x55555555L);
394296465Sdelphij    d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) |
395296465Sdelphij         ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L));
396296465Sdelphij    c &= 0x0fffffffL;
39755714Skris
398296465Sdelphij    for (i = 0; i < ITERATIONS; i++) {
399296465Sdelphij        if (shifts2[i]) {
400296465Sdelphij            c = ((c >> 2L) | (c << 26L));
401296465Sdelphij            d = ((d >> 2L) | (d << 26L));
402296465Sdelphij        } else {
403296465Sdelphij            c = ((c >> 1L) | (c << 27L));
404296465Sdelphij            d = ((d >> 1L) | (d << 27L));
405296465Sdelphij        }
406296465Sdelphij        c &= 0x0fffffffL;
407296465Sdelphij        d &= 0x0fffffffL;
408296465Sdelphij        /*
409296465Sdelphij         * could be a few less shifts but I am to lazy at this point in time
410296465Sdelphij         * to investigate
411296465Sdelphij         */
412296465Sdelphij        s = des_skb[0][(c) & 0x3f] |
413296465Sdelphij            des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] |
414296465Sdelphij            des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] |
415296465Sdelphij            des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) |
416296465Sdelphij                       ((c >> 22L) & 0x38)];
417296465Sdelphij        t = des_skb[4][(d) & 0x3f] |
418296465Sdelphij            des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] |
419296465Sdelphij            des_skb[6][(d >> 15L) & 0x3f] |
420296465Sdelphij            des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)];
42155714Skris
422296465Sdelphij        /* table contained 0213 4657 */
423296465Sdelphij        t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
424296465Sdelphij        *(k++) = ROTATE(t2, 30) & 0xffffffffL;
42555714Skris
426296465Sdelphij        t2 = ((s >> 16L) | (t & 0xffff0000L));
427296465Sdelphij        *(k++) = ROTATE(t2, 26) & 0xffffffffL;
428296465Sdelphij    }
429296465Sdelphij}
43055714Skris
431109998Smarkmint DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
432296465Sdelphij{
433296465Sdelphij    return (DES_set_key(key, schedule));
434296465Sdelphij}
435296465Sdelphij
436296465Sdelphij/*-
43759191Skris#undef des_fixup_key_parity
43859191Skrisvoid des_fixup_key_parity(des_cblock *key)
439296465Sdelphij        {
440296465Sdelphij        des_set_odd_parity(key);
441296465Sdelphij        }
442109998Smarkm*/
443