1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <sys/types.h>
30*0Sstevel@tonic-gate #include <sys/systm.h>
31*0Sstevel@tonic-gate #include <sys/ddi.h>
32*0Sstevel@tonic-gate #include <sys/sysmacros.h>
33*0Sstevel@tonic-gate #include <sys/strsun.h>
34*0Sstevel@tonic-gate #include <sys/note.h>
35*0Sstevel@tonic-gate #include <sys/crypto/common.h>
36*0Sstevel@tonic-gate #include "des_impl.h"
37*0Sstevel@tonic-gate #ifndef	_KERNEL
38*0Sstevel@tonic-gate #include <strings.h>
39*0Sstevel@tonic-gate #include <stdlib.h>
40*0Sstevel@tonic-gate #endif	/* !_KERNEL */
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate /* EXPORT DELETE START */
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate typedef struct keysched_s {
45*0Sstevel@tonic-gate 	uint64_t ksch_encrypt[16];
46*0Sstevel@tonic-gate 	uint64_t ksch_decrypt[16];
47*0Sstevel@tonic-gate } keysched_t;
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate typedef struct keysched3_s {
50*0Sstevel@tonic-gate 	uint64_t ksch_encrypt[48];
51*0Sstevel@tonic-gate 	uint64_t ksch_decrypt[48];
52*0Sstevel@tonic-gate } keysched3_t;
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate static void fix_des_parity(uint64_t *);
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate #ifndef sun4u
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate static const uint64_t sbox_table[8][64]=
59*0Sstevel@tonic-gate {
60*0Sstevel@tonic-gate {
61*0Sstevel@tonic-gate 0x0000140140020000, 0x0000000000000000, 0x0000000140000000, 0x0000140140020020,
62*0Sstevel@tonic-gate 0x0000140140000020, 0x0000000140020020, 0x0000000000000020, 0x0000000140000000,
63*0Sstevel@tonic-gate 0x0000000000020000, 0x0000140140020000, 0x0000140140020020, 0x0000000000020000,
64*0Sstevel@tonic-gate 0x0000140000020020, 0x0000140140000020, 0x0000140000000000, 0x0000000000000020,
65*0Sstevel@tonic-gate 0x0000000000020020, 0x0000140000020000, 0x0000140000020000, 0x0000000140020000,
66*0Sstevel@tonic-gate 0x0000000140020000, 0x0000140140000000, 0x0000140140000000, 0x0000140000020020,
67*0Sstevel@tonic-gate 0x0000000140000020, 0x0000140000000020, 0x0000140000000020, 0x0000000140000020,
68*0Sstevel@tonic-gate 0x0000000000000000, 0x0000000000020020, 0x0000000140020020, 0x0000140000000000,
69*0Sstevel@tonic-gate 0x0000000140000000, 0x0000140140020020, 0x0000000000000020, 0x0000140140000000,
70*0Sstevel@tonic-gate 0x0000140140020000, 0x0000140000000000, 0x0000140000000000, 0x0000000000020000,
71*0Sstevel@tonic-gate 0x0000140140000020, 0x0000000140000000, 0x0000000140020000, 0x0000140000000020,
72*0Sstevel@tonic-gate 0x0000000000020000, 0x0000000000000020, 0x0000140000020020, 0x0000000140020020,
73*0Sstevel@tonic-gate 0x0000140140020020, 0x0000000140000020, 0x0000140140000000, 0x0000140000020020,
74*0Sstevel@tonic-gate 0x0000140000000020, 0x0000000000020020, 0x0000000140020020, 0x0000140140020000,
75*0Sstevel@tonic-gate 0x0000000000020020, 0x0000140000020000, 0x0000140000020000, 0x0000000000000000,
76*0Sstevel@tonic-gate 0x0000000140000020, 0x0000000140020000, 0x0000000000000000, 0x0000140140000020
77*0Sstevel@tonic-gate },
78*0Sstevel@tonic-gate {
79*0Sstevel@tonic-gate 0x2000005020000500, 0x2000000020000000, 0x0000000020000000, 0x0000005020000500,
80*0Sstevel@tonic-gate 0x0000005000000000, 0x0000000000000500, 0x2000005000000500, 0x2000000020000500,
81*0Sstevel@tonic-gate 0x2000000000000500, 0x2000005020000500, 0x2000005020000000, 0x2000000000000000,
82*0Sstevel@tonic-gate 0x2000000020000000, 0x0000005000000000, 0x0000000000000500, 0x2000005000000500,
83*0Sstevel@tonic-gate 0x0000005020000000, 0x0000005000000500, 0x2000000020000500, 0x0000000000000000,
84*0Sstevel@tonic-gate 0x2000000000000000, 0x0000000020000000, 0x0000005020000500, 0x2000005000000000,
85*0Sstevel@tonic-gate 0x0000005000000500, 0x2000000000000500, 0x0000000000000000, 0x0000005020000000,
86*0Sstevel@tonic-gate 0x0000000020000500, 0x2000005020000000, 0x2000005000000000, 0x0000000020000500,
87*0Sstevel@tonic-gate 0x0000000000000000, 0x0000005020000500, 0x2000005000000500, 0x0000005000000000,
88*0Sstevel@tonic-gate 0x2000000020000500, 0x2000005000000000, 0x2000005020000000, 0x0000000020000000,
89*0Sstevel@tonic-gate 0x2000005000000000, 0x2000000020000000, 0x0000000000000500, 0x2000005020000500,
90*0Sstevel@tonic-gate 0x0000005020000500, 0x0000000000000500, 0x0000000020000000, 0x2000000000000000,
91*0Sstevel@tonic-gate 0x0000000020000500, 0x2000005020000000, 0x0000005000000000, 0x2000000000000500,
92*0Sstevel@tonic-gate 0x0000005000000500, 0x2000000020000500, 0x2000000000000500, 0x0000005000000500,
93*0Sstevel@tonic-gate 0x0000005020000000, 0x0000000000000000, 0x2000000020000000, 0x0000000020000500,
94*0Sstevel@tonic-gate 0x2000000000000000, 0x2000005000000500, 0x2000005020000500, 0x0000005020000000
95*0Sstevel@tonic-gate },
96*0Sstevel@tonic-gate {
97*0Sstevel@tonic-gate 0x0000000000014040, 0x0000800280014000, 0x0000000000000000, 0x0000800280000040,
98*0Sstevel@tonic-gate 0x0000800000014000, 0x0000000000000000, 0x0000000280014040, 0x0000800000014000,
99*0Sstevel@tonic-gate 0x0000000280000040, 0x0000800000000040, 0x0000800000000040, 0x0000000280000000,
100*0Sstevel@tonic-gate 0x0000800280014040, 0x0000000280000040, 0x0000800280000000, 0x0000000000014040,
101*0Sstevel@tonic-gate 0x0000800000000000, 0x0000000000000040, 0x0000800280014000, 0x0000000000014000,
102*0Sstevel@tonic-gate 0x0000000280014000, 0x0000800280000000, 0x0000800280000040, 0x0000000280014040,
103*0Sstevel@tonic-gate 0x0000800000014040, 0x0000000280014000, 0x0000000280000000, 0x0000800000014040,
104*0Sstevel@tonic-gate 0x0000000000000040, 0x0000800280014040, 0x0000000000014000, 0x0000800000000000,
105*0Sstevel@tonic-gate 0x0000800280014000, 0x0000800000000000, 0x0000000280000040, 0x0000000000014040,
106*0Sstevel@tonic-gate 0x0000000280000000, 0x0000800280014000, 0x0000800000014000, 0x0000000000000000,
107*0Sstevel@tonic-gate 0x0000000000014000, 0x0000000280000040, 0x0000800280014040, 0x0000800000014000,
108*0Sstevel@tonic-gate 0x0000800000000040, 0x0000000000014000, 0x0000000000000000, 0x0000800280000040,
109*0Sstevel@tonic-gate 0x0000800000014040, 0x0000000280000000, 0x0000800000000000, 0x0000800280014040,
110*0Sstevel@tonic-gate 0x0000000000000040, 0x0000000280014040, 0x0000000280014000, 0x0000800000000040,
111*0Sstevel@tonic-gate 0x0000800280000000, 0x0000800000014040, 0x0000000000014040, 0x0000800280000000,
112*0Sstevel@tonic-gate 0x0000000280014040, 0x0000000000000040, 0x0000800280000040, 0x0000000280014000
113*0Sstevel@tonic-gate },
114*0Sstevel@tonic-gate {
115*0Sstevel@tonic-gate 0x4000020008100008, 0x4000000008101008, 0x4000000008101008, 0x0000000000001000,
116*0Sstevel@tonic-gate 0x0000020008101000, 0x4000020000001008, 0x4000020000000008, 0x4000000008100008,
117*0Sstevel@tonic-gate 0x0000000000000000, 0x0000020008100000, 0x0000020008100000, 0x4000020008101008,
118*0Sstevel@tonic-gate 0x4000000000001008, 0x0000000000000000, 0x0000020000001000, 0x4000020000000008,
119*0Sstevel@tonic-gate 0x4000000000000008, 0x0000000008100000, 0x0000020000000000, 0x4000020008100008,
120*0Sstevel@tonic-gate 0x0000000000001000, 0x0000020000000000, 0x4000000008100008, 0x0000000008101000,
121*0Sstevel@tonic-gate 0x4000020000001008, 0x4000000000000008, 0x0000000008101000, 0x0000020000001000,
122*0Sstevel@tonic-gate 0x0000000008100000, 0x0000020008101000, 0x4000020008101008, 0x4000000000001008,
123*0Sstevel@tonic-gate 0x0000020000001000, 0x4000020000000008, 0x0000020008100000, 0x4000020008101008,
124*0Sstevel@tonic-gate 0x4000000000001008, 0x0000000000000000, 0x0000000000000000, 0x0000020008100000,
125*0Sstevel@tonic-gate 0x0000000008101000, 0x0000020000001000, 0x4000020000001008, 0x4000000000000008,
126*0Sstevel@tonic-gate 0x4000020008100008, 0x4000000008101008, 0x4000000008101008, 0x0000000000001000,
127*0Sstevel@tonic-gate 0x4000020008101008, 0x4000000000001008, 0x4000000000000008, 0x0000000008100000,
128*0Sstevel@tonic-gate 0x4000020000000008, 0x4000000008100008, 0x0000020008101000, 0x4000020000001008,
129*0Sstevel@tonic-gate 0x4000000008100008, 0x0000000008101000, 0x0000020000000000, 0x4000020008100008,
130*0Sstevel@tonic-gate 0x0000000000001000, 0x0000020000000000, 0x0000000008100000, 0x0000020008101000
131*0Sstevel@tonic-gate },
132*0Sstevel@tonic-gate {
133*0Sstevel@tonic-gate 0x000000000000a000, 0x000028080000a000, 0x0000280800000000, 0x100028000000a000,
134*0Sstevel@tonic-gate 0x0000000800000000, 0x000000000000a000, 0x1000000000000000, 0x0000280800000000,
135*0Sstevel@tonic-gate 0x100000080000a000, 0x0000000800000000, 0x000028000000a000, 0x100000080000a000,
136*0Sstevel@tonic-gate 0x100028000000a000, 0x1000280800000000, 0x000000080000a000, 0x1000000000000000,
137*0Sstevel@tonic-gate 0x0000280000000000, 0x1000000800000000, 0x1000000800000000, 0x0000000000000000,
138*0Sstevel@tonic-gate 0x100000000000a000, 0x100028080000a000, 0x100028080000a000, 0x000028000000a000,
139*0Sstevel@tonic-gate 0x1000280800000000, 0x100000000000a000, 0x0000000000000000, 0x1000280000000000,
140*0Sstevel@tonic-gate 0x000028080000a000, 0x0000280000000000, 0x1000280000000000, 0x000000080000a000,
141*0Sstevel@tonic-gate 0x0000000800000000, 0x100028000000a000, 0x000000000000a000, 0x0000280000000000,
142*0Sstevel@tonic-gate 0x1000000000000000, 0x0000280800000000, 0x100028000000a000, 0x100000080000a000,
143*0Sstevel@tonic-gate 0x000028000000a000, 0x1000000000000000, 0x1000280800000000, 0x000028080000a000,
144*0Sstevel@tonic-gate 0x100000080000a000, 0x000000000000a000, 0x0000280000000000, 0x1000280800000000,
145*0Sstevel@tonic-gate 0x100028080000a000, 0x000000080000a000, 0x1000280000000000, 0x100028080000a000,
146*0Sstevel@tonic-gate 0x0000280800000000, 0x0000000000000000, 0x1000000800000000, 0x1000280000000000,
147*0Sstevel@tonic-gate 0x000000080000a000, 0x000028000000a000, 0x100000000000a000, 0x0000000800000000,
148*0Sstevel@tonic-gate 0x0000000000000000, 0x1000000800000000, 0x000028080000a000, 0x100000000000a000
149*0Sstevel@tonic-gate },
150*0Sstevel@tonic-gate {
151*0Sstevel@tonic-gate 0x0802000000000280, 0x0802010000000000, 0x0000000010000000, 0x0802010010000280,
152*0Sstevel@tonic-gate 0x0802010000000000, 0x0000000000000280, 0x0802010010000280, 0x0000010000000000,
153*0Sstevel@tonic-gate 0x0802000010000000, 0x0000010010000280, 0x0000010000000000, 0x0802000000000280,
154*0Sstevel@tonic-gate 0x0000010000000280, 0x0802000010000000, 0x0802000000000000, 0x0000000010000280,
155*0Sstevel@tonic-gate 0x0000000000000000, 0x0000010000000280, 0x0802000010000280, 0x0000000010000000,
156*0Sstevel@tonic-gate 0x0000010010000000, 0x0802000010000280, 0x0000000000000280, 0x0802010000000280,
157*0Sstevel@tonic-gate 0x0802010000000280, 0x0000000000000000, 0x0000010010000280, 0x0802010010000000,
158*0Sstevel@tonic-gate 0x0000000010000280, 0x0000010010000000, 0x0802010010000000, 0x0802000000000000,
159*0Sstevel@tonic-gate 0x0802000010000000, 0x0000000000000280, 0x0802010000000280, 0x0000010010000000,
160*0Sstevel@tonic-gate 0x0802010010000280, 0x0000010000000000, 0x0000000010000280, 0x0802000000000280,
161*0Sstevel@tonic-gate 0x0000010000000000, 0x0802000010000000, 0x0802000000000000, 0x0000000010000280,
162*0Sstevel@tonic-gate 0x0802000000000280, 0x0802010010000280, 0x0000010010000000, 0x0802010000000000,
163*0Sstevel@tonic-gate 0x0000010010000280, 0x0802010010000000, 0x0000000000000000, 0x0802010000000280,
164*0Sstevel@tonic-gate 0x0000000000000280, 0x0000000010000000, 0x0802010000000000, 0x0000010010000280,
165*0Sstevel@tonic-gate 0x0000000010000000, 0x0000010000000280, 0x0802000010000280, 0x0000000000000000,
166*0Sstevel@tonic-gate 0x0802010010000000, 0x0802000000000000, 0x0000010000000280, 0x0802000010000280
167*0Sstevel@tonic-gate },
168*0Sstevel@tonic-gate {
169*0Sstevel@tonic-gate 0x000000a000000000, 0x800040a000000010, 0x8000400000040010, 0x0000000000000000,
170*0Sstevel@tonic-gate 0x0000000000040000, 0x8000400000040010, 0x800000a000040010, 0x000040a000040000,
171*0Sstevel@tonic-gate 0x800040a000040010, 0x000000a000000000, 0x0000000000000000, 0x8000400000000010,
172*0Sstevel@tonic-gate 0x8000000000000010, 0x0000400000000000, 0x800040a000000010, 0x8000000000040010,
173*0Sstevel@tonic-gate 0x0000400000040000, 0x800000a000040010, 0x800000a000000010, 0x0000400000040000,
174*0Sstevel@tonic-gate 0x8000400000000010, 0x000040a000000000, 0x000040a000040000, 0x800000a000000010,
175*0Sstevel@tonic-gate 0x000040a000000000, 0x0000000000040000, 0x8000000000040010, 0x800040a000040010,
176*0Sstevel@tonic-gate 0x000000a000040000, 0x8000000000000010, 0x0000400000000000, 0x000000a000040000,
177*0Sstevel@tonic-gate 0x0000400000000000, 0x000000a000040000, 0x000000a000000000, 0x8000400000040010,
178*0Sstevel@tonic-gate 0x8000400000040010, 0x800040a000000010, 0x800040a000000010, 0x8000000000000010,
179*0Sstevel@tonic-gate 0x800000a000000010, 0x0000400000000000, 0x0000400000040000, 0x000000a000000000,
180*0Sstevel@tonic-gate 0x000040a000040000, 0x8000000000040010, 0x800000a000040010, 0x000040a000040000,
181*0Sstevel@tonic-gate 0x8000000000040010, 0x8000400000000010, 0x800040a000040010, 0x000040a000000000,
182*0Sstevel@tonic-gate 0x000000a000040000, 0x0000000000000000, 0x8000000000000010, 0x800040a000040010,
183*0Sstevel@tonic-gate 0x0000000000000000, 0x800000a000040010, 0x000040a000000000, 0x0000000000040000,
184*0Sstevel@tonic-gate 0x8000400000000010, 0x0000400000040000, 0x0000000000040000, 0x800000a000000010
185*0Sstevel@tonic-gate },
186*0Sstevel@tonic-gate {
187*0Sstevel@tonic-gate 0x0401000004080800, 0x0000000004080000, 0x0000000400000000, 0x0401000404080800,
188*0Sstevel@tonic-gate 0x0401000000000000, 0x0401000004080800, 0x0000000000000800, 0x0401000000000000,
189*0Sstevel@tonic-gate 0x0000000400000800, 0x0401000400000000, 0x0401000404080800, 0x0000000404080000,
190*0Sstevel@tonic-gate 0x0401000404080000, 0x0000000404080800, 0x0000000004080000, 0x0000000000000800,
191*0Sstevel@tonic-gate 0x0401000400000000, 0x0401000000000800, 0x0401000004080000, 0x0000000004080800,
192*0Sstevel@tonic-gate 0x0000000404080000, 0x0000000400000800, 0x0401000400000800, 0x0401000404080000,
193*0Sstevel@tonic-gate 0x0000000004080800, 0x0000000000000000, 0x0000000000000000, 0x0401000400000800,
194*0Sstevel@tonic-gate 0x0401000000000800, 0x0401000004080000, 0x0000000404080800, 0x0000000400000000,
195*0Sstevel@tonic-gate 0x0000000404080800, 0x0000000400000000, 0x0401000404080000, 0x0000000004080000,
196*0Sstevel@tonic-gate 0x0000000000000800, 0x0401000400000800, 0x0000000004080000, 0x0000000404080800,
197*0Sstevel@tonic-gate 0x0401000004080000, 0x0000000000000800, 0x0401000000000800, 0x0401000400000000,
198*0Sstevel@tonic-gate 0x0401000400000800, 0x0401000000000000, 0x0000000400000000, 0x0401000004080800,
199*0Sstevel@tonic-gate 0x0000000000000000, 0x0401000404080800, 0x0000000400000800, 0x0401000000000800,
200*0Sstevel@tonic-gate 0x0401000400000000, 0x0401000004080000, 0x0401000004080800, 0x0000000000000000,
201*0Sstevel@tonic-gate 0x0401000404080800, 0x0000000404080000, 0x0000000404080000, 0x0000000004080800,
202*0Sstevel@tonic-gate 0x0000000004080800, 0x0000000400000800, 0x0401000000000000, 0x0401000404080000
203*0Sstevel@tonic-gate }
204*0Sstevel@tonic-gate };
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 
207*0Sstevel@tonic-gate static const uint64_t ip_table[2][256]=
208*0Sstevel@tonic-gate {
209*0Sstevel@tonic-gate {
210*0Sstevel@tonic-gate 0x0000000000000000, 0x0000000000000400, 0x0080000000000280, 0x0080000000000680,
211*0Sstevel@tonic-gate 0x0000000000400000, 0x0000000000400400, 0x0080000000400280, 0x0080000000400680,
212*0Sstevel@tonic-gate 0x0000000000280000, 0x0000000000280400, 0x0080000000280280, 0x0080000000280680,
213*0Sstevel@tonic-gate 0x0000000000680000, 0x0000000000680400, 0x0080000000680280, 0x0080000000680680,
214*0Sstevel@tonic-gate 0x0000000400000000, 0x0000000400000400, 0x0080000400000280, 0x0080000400000680,
215*0Sstevel@tonic-gate 0x0000000400400000, 0x0000000400400400, 0x0080000400400280, 0x0080000400400680,
216*0Sstevel@tonic-gate 0x0000000400280000, 0x0000000400280400, 0x0080000400280280, 0x0080000400280680,
217*0Sstevel@tonic-gate 0x0000000400680000, 0x0000000400680400, 0x0080000400680280, 0x0080000400680680,
218*0Sstevel@tonic-gate 0x0000000280000000, 0x0000000280000400, 0x0080000280000280, 0x0080000280000680,
219*0Sstevel@tonic-gate 0x0000000280400000, 0x0000000280400400, 0x0080000280400280, 0x0080000280400680,
220*0Sstevel@tonic-gate 0x0000000280280000, 0x0000000280280400, 0x0080000280280280, 0x0080000280280680,
221*0Sstevel@tonic-gate 0x0000000280680000, 0x0000000280680400, 0x0080000280680280, 0x0080000280680680,
222*0Sstevel@tonic-gate 0x0000000680000000, 0x0000000680000400, 0x0080000680000280, 0x0080000680000680,
223*0Sstevel@tonic-gate 0x0000000680400000, 0x0000000680400400, 0x0080000680400280, 0x0080000680400680,
224*0Sstevel@tonic-gate 0x0000000680280000, 0x0000000680280400, 0x0080000680280280, 0x0080000680280680,
225*0Sstevel@tonic-gate 0x0000000680680000, 0x0000000680680400, 0x0080000680680280, 0x0080000680680680,
226*0Sstevel@tonic-gate 0x0000400000000000, 0x0000400000000400, 0x0080400000000280, 0x0080400000000680,
227*0Sstevel@tonic-gate 0x0000400000400000, 0x0000400000400400, 0x0080400000400280, 0x0080400000400680,
228*0Sstevel@tonic-gate 0x0000400000280000, 0x0000400000280400, 0x0080400000280280, 0x0080400000280680,
229*0Sstevel@tonic-gate 0x0000400000680000, 0x0000400000680400, 0x0080400000680280, 0x0080400000680680,
230*0Sstevel@tonic-gate 0x0000400400000000, 0x0000400400000400, 0x0080400400000280, 0x0080400400000680,
231*0Sstevel@tonic-gate 0x0000400400400000, 0x0000400400400400, 0x0080400400400280, 0x0080400400400680,
232*0Sstevel@tonic-gate 0x0000400400280000, 0x0000400400280400, 0x0080400400280280, 0x0080400400280680,
233*0Sstevel@tonic-gate 0x0000400400680000, 0x0000400400680400, 0x0080400400680280, 0x0080400400680680,
234*0Sstevel@tonic-gate 0x0000400280000000, 0x0000400280000400, 0x0080400280000280, 0x0080400280000680,
235*0Sstevel@tonic-gate 0x0000400280400000, 0x0000400280400400, 0x0080400280400280, 0x0080400280400680,
236*0Sstevel@tonic-gate 0x0000400280280000, 0x0000400280280400, 0x0080400280280280, 0x0080400280280680,
237*0Sstevel@tonic-gate 0x0000400280680000, 0x0000400280680400, 0x0080400280680280, 0x0080400280680680,
238*0Sstevel@tonic-gate 0x0000400680000000, 0x0000400680000400, 0x0080400680000280, 0x0080400680000680,
239*0Sstevel@tonic-gate 0x0000400680400000, 0x0000400680400400, 0x0080400680400280, 0x0080400680400680,
240*0Sstevel@tonic-gate 0x0000400680280000, 0x0000400680280400, 0x0080400680280280, 0x0080400680280680,
241*0Sstevel@tonic-gate 0x0000400680680000, 0x0000400680680400, 0x0080400680680280, 0x0080400680680680,
242*0Sstevel@tonic-gate 0x0000280000000000, 0x0000280000000400, 0x0080280000000280, 0x0080280000000680,
243*0Sstevel@tonic-gate 0x0000280000400000, 0x0000280000400400, 0x0080280000400280, 0x0080280000400680,
244*0Sstevel@tonic-gate 0x0000280000280000, 0x0000280000280400, 0x0080280000280280, 0x0080280000280680,
245*0Sstevel@tonic-gate 0x0000280000680000, 0x0000280000680400, 0x0080280000680280, 0x0080280000680680,
246*0Sstevel@tonic-gate 0x0000280400000000, 0x0000280400000400, 0x0080280400000280, 0x0080280400000680,
247*0Sstevel@tonic-gate 0x0000280400400000, 0x0000280400400400, 0x0080280400400280, 0x0080280400400680,
248*0Sstevel@tonic-gate 0x0000280400280000, 0x0000280400280400, 0x0080280400280280, 0x0080280400280680,
249*0Sstevel@tonic-gate 0x0000280400680000, 0x0000280400680400, 0x0080280400680280, 0x0080280400680680,
250*0Sstevel@tonic-gate 0x0000280280000000, 0x0000280280000400, 0x0080280280000280, 0x0080280280000680,
251*0Sstevel@tonic-gate 0x0000280280400000, 0x0000280280400400, 0x0080280280400280, 0x0080280280400680,
252*0Sstevel@tonic-gate 0x0000280280280000, 0x0000280280280400, 0x0080280280280280, 0x0080280280280680,
253*0Sstevel@tonic-gate 0x0000280280680000, 0x0000280280680400, 0x0080280280680280, 0x0080280280680680,
254*0Sstevel@tonic-gate 0x0000280680000000, 0x0000280680000400, 0x0080280680000280, 0x0080280680000680,
255*0Sstevel@tonic-gate 0x0000280680400000, 0x0000280680400400, 0x0080280680400280, 0x0080280680400680,
256*0Sstevel@tonic-gate 0x0000280680280000, 0x0000280680280400, 0x0080280680280280, 0x0080280680280680,
257*0Sstevel@tonic-gate 0x0000280680680000, 0x0000280680680400, 0x0080280680680280, 0x0080280680680680,
258*0Sstevel@tonic-gate 0x0000680000000000, 0x0000680000000400, 0x0080680000000280, 0x0080680000000680,
259*0Sstevel@tonic-gate 0x0000680000400000, 0x0000680000400400, 0x0080680000400280, 0x0080680000400680,
260*0Sstevel@tonic-gate 0x0000680000280000, 0x0000680000280400, 0x0080680000280280, 0x0080680000280680,
261*0Sstevel@tonic-gate 0x0000680000680000, 0x0000680000680400, 0x0080680000680280, 0x0080680000680680,
262*0Sstevel@tonic-gate 0x0000680400000000, 0x0000680400000400, 0x0080680400000280, 0x0080680400000680,
263*0Sstevel@tonic-gate 0x0000680400400000, 0x0000680400400400, 0x0080680400400280, 0x0080680400400680,
264*0Sstevel@tonic-gate 0x0000680400280000, 0x0000680400280400, 0x0080680400280280, 0x0080680400280680,
265*0Sstevel@tonic-gate 0x0000680400680000, 0x0000680400680400, 0x0080680400680280, 0x0080680400680680,
266*0Sstevel@tonic-gate 0x0000680280000000, 0x0000680280000400, 0x0080680280000280, 0x0080680280000680,
267*0Sstevel@tonic-gate 0x0000680280400000, 0x0000680280400400, 0x0080680280400280, 0x0080680280400680,
268*0Sstevel@tonic-gate 0x0000680280280000, 0x0000680280280400, 0x0080680280280280, 0x0080680280280680,
269*0Sstevel@tonic-gate 0x0000680280680000, 0x0000680280680400, 0x0080680280680280, 0x0080680280680680,
270*0Sstevel@tonic-gate 0x0000680680000000, 0x0000680680000400, 0x0080680680000280, 0x0080680680000680,
271*0Sstevel@tonic-gate 0x0000680680400000, 0x0000680680400400, 0x0080680680400280, 0x0080680680400680,
272*0Sstevel@tonic-gate 0x0000680680280000, 0x0000680680280400, 0x0080680680280280, 0x0080680680280680,
273*0Sstevel@tonic-gate 0x0000680680680000, 0x0000680680680400, 0x0080680680680280, 0x0080680680680680
274*0Sstevel@tonic-gate },
275*0Sstevel@tonic-gate {
276*0Sstevel@tonic-gate 0x0000000000000000, 0x0000000000005000, 0x0000000000000800, 0x0000000000005800,
277*0Sstevel@tonic-gate 0x0000000005000000, 0x0000000005005000, 0x0000000005000800, 0x0000000005005800,
278*0Sstevel@tonic-gate 0x0000000000800000, 0x0000000000805000, 0x0000000000800800, 0x0000000000805800,
279*0Sstevel@tonic-gate 0x0000000005800000, 0x0000000005805000, 0x0000000005800800, 0x0000000005805800,
280*0Sstevel@tonic-gate 0x0000005000000000, 0x0000005000005000, 0x0000005000000800, 0x0000005000005800,
281*0Sstevel@tonic-gate 0x0000005005000000, 0x0000005005005000, 0x0000005005000800, 0x0000005005005800,
282*0Sstevel@tonic-gate 0x0000005000800000, 0x0000005000805000, 0x0000005000800800, 0x0000005000805800,
283*0Sstevel@tonic-gate 0x0000005005800000, 0x0000005005805000, 0x0000005005800800, 0x0000005005805800,
284*0Sstevel@tonic-gate 0x0000000800000000, 0x0000000800005000, 0x0000000800000800, 0x0000000800005800,
285*0Sstevel@tonic-gate 0x0000000805000000, 0x0000000805005000, 0x0000000805000800, 0x0000000805005800,
286*0Sstevel@tonic-gate 0x0000000800800000, 0x0000000800805000, 0x0000000800800800, 0x0000000800805800,
287*0Sstevel@tonic-gate 0x0000000805800000, 0x0000000805805000, 0x0000000805800800, 0x0000000805805800,
288*0Sstevel@tonic-gate 0x0000005800000000, 0x0000005800005000, 0x0000005800000800, 0x0000005800005800,
289*0Sstevel@tonic-gate 0x0000005805000000, 0x0000005805005000, 0x0000005805000800, 0x0000005805005800,
290*0Sstevel@tonic-gate 0x0000005800800000, 0x0000005800805000, 0x0000005800800800, 0x0000005800805800,
291*0Sstevel@tonic-gate 0x0000005805800000, 0x0000005805805000, 0x0000005805800800, 0x0000005805805800,
292*0Sstevel@tonic-gate 0x0005000000000004, 0x0005000000005004, 0x0005000000000804, 0x0005000000005804,
293*0Sstevel@tonic-gate 0x0005000005000004, 0x0005000005005004, 0x0005000005000804, 0x0005000005005804,
294*0Sstevel@tonic-gate 0x0005000000800004, 0x0005000000805004, 0x0005000000800804, 0x0005000000805804,
295*0Sstevel@tonic-gate 0x0005000005800004, 0x0005000005805004, 0x0005000005800804, 0x0005000005805804,
296*0Sstevel@tonic-gate 0x0005005000000004, 0x0005005000005004, 0x0005005000000804, 0x0005005000005804,
297*0Sstevel@tonic-gate 0x0005005005000004, 0x0005005005005004, 0x0005005005000804, 0x0005005005005804,
298*0Sstevel@tonic-gate 0x0005005000800004, 0x0005005000805004, 0x0005005000800804, 0x0005005000805804,
299*0Sstevel@tonic-gate 0x0005005005800004, 0x0005005005805004, 0x0005005005800804, 0x0005005005805804,
300*0Sstevel@tonic-gate 0x0005000800000004, 0x0005000800005004, 0x0005000800000804, 0x0005000800005804,
301*0Sstevel@tonic-gate 0x0005000805000004, 0x0005000805005004, 0x0005000805000804, 0x0005000805005804,
302*0Sstevel@tonic-gate 0x0005000800800004, 0x0005000800805004, 0x0005000800800804, 0x0005000800805804,
303*0Sstevel@tonic-gate 0x0005000805800004, 0x0005000805805004, 0x0005000805800804, 0x0005000805805804,
304*0Sstevel@tonic-gate 0x0005005800000004, 0x0005005800005004, 0x0005005800000804, 0x0005005800005804,
305*0Sstevel@tonic-gate 0x0005005805000004, 0x0005005805005004, 0x0005005805000804, 0x0005005805005804,
306*0Sstevel@tonic-gate 0x0005005800800004, 0x0005005800805004, 0x0005005800800804, 0x0005005800805804,
307*0Sstevel@tonic-gate 0x0005005805800004, 0x0005005805805004, 0x0005005805800804, 0x0005005805805804,
308*0Sstevel@tonic-gate 0x0000800000000000, 0x0000800000005000, 0x0000800000000800, 0x0000800000005800,
309*0Sstevel@tonic-gate 0x0000800005000000, 0x0000800005005000, 0x0000800005000800, 0x0000800005005800,
310*0Sstevel@tonic-gate 0x0000800000800000, 0x0000800000805000, 0x0000800000800800, 0x0000800000805800,
311*0Sstevel@tonic-gate 0x0000800005800000, 0x0000800005805000, 0x0000800005800800, 0x0000800005805800,
312*0Sstevel@tonic-gate 0x0000805000000000, 0x0000805000005000, 0x0000805000000800, 0x0000805000005800,
313*0Sstevel@tonic-gate 0x0000805005000000, 0x0000805005005000, 0x0000805005000800, 0x0000805005005800,
314*0Sstevel@tonic-gate 0x0000805000800000, 0x0000805000805000, 0x0000805000800800, 0x0000805000805800,
315*0Sstevel@tonic-gate 0x0000805005800000, 0x0000805005805000, 0x0000805005800800, 0x0000805005805800,
316*0Sstevel@tonic-gate 0x0000800800000000, 0x0000800800005000, 0x0000800800000800, 0x0000800800005800,
317*0Sstevel@tonic-gate 0x0000800805000000, 0x0000800805005000, 0x0000800805000800, 0x0000800805005800,
318*0Sstevel@tonic-gate 0x0000800800800000, 0x0000800800805000, 0x0000800800800800, 0x0000800800805800,
319*0Sstevel@tonic-gate 0x0000800805800000, 0x0000800805805000, 0x0000800805800800, 0x0000800805805800,
320*0Sstevel@tonic-gate 0x0000805800000000, 0x0000805800005000, 0x0000805800000800, 0x0000805800005800,
321*0Sstevel@tonic-gate 0x0000805805000000, 0x0000805805005000, 0x0000805805000800, 0x0000805805005800,
322*0Sstevel@tonic-gate 0x0000805800800000, 0x0000805800805000, 0x0000805800800800, 0x0000805800805800,
323*0Sstevel@tonic-gate 0x0000805805800000, 0x0000805805805000, 0x0000805805800800, 0x0000805805805800,
324*0Sstevel@tonic-gate 0x0005800000000004, 0x0005800000005004, 0x0005800000000804, 0x0005800000005804,
325*0Sstevel@tonic-gate 0x0005800005000004, 0x0005800005005004, 0x0005800005000804, 0x0005800005005804,
326*0Sstevel@tonic-gate 0x0005800000800004, 0x0005800000805004, 0x0005800000800804, 0x0005800000805804,
327*0Sstevel@tonic-gate 0x0005800005800004, 0x0005800005805004, 0x0005800005800804, 0x0005800005805804,
328*0Sstevel@tonic-gate 0x0005805000000004, 0x0005805000005004, 0x0005805000000804, 0x0005805000005804,
329*0Sstevel@tonic-gate 0x0005805005000004, 0x0005805005005004, 0x0005805005000804, 0x0005805005005804,
330*0Sstevel@tonic-gate 0x0005805000800004, 0x0005805000805004, 0x0005805000800804, 0x0005805000805804,
331*0Sstevel@tonic-gate 0x0005805005800004, 0x0005805005805004, 0x0005805005800804, 0x0005805005805804,
332*0Sstevel@tonic-gate 0x0005800800000004, 0x0005800800005004, 0x0005800800000804, 0x0005800800005804,
333*0Sstevel@tonic-gate 0x0005800805000004, 0x0005800805005004, 0x0005800805000804, 0x0005800805005804,
334*0Sstevel@tonic-gate 0x0005800800800004, 0x0005800800805004, 0x0005800800800804, 0x0005800800805804,
335*0Sstevel@tonic-gate 0x0005800805800004, 0x0005800805805004, 0x0005800805800804, 0x0005800805805804,
336*0Sstevel@tonic-gate 0x0005805800000004, 0x0005805800005004, 0x0005805800000804, 0x0005805800005804,
337*0Sstevel@tonic-gate 0x0005805805000004, 0x0005805805005004, 0x0005805805000804, 0x0005805805005804,
338*0Sstevel@tonic-gate 0x0005805800800004, 0x0005805800805004, 0x0005805800800804, 0x0005805800805804,
339*0Sstevel@tonic-gate 0x0005805805800004, 0x0005805805805004, 0x0005805805800804, 0x0005805805805804
340*0Sstevel@tonic-gate }
341*0Sstevel@tonic-gate };
342*0Sstevel@tonic-gate 
343*0Sstevel@tonic-gate static const uint32_t fp_table[256]=
344*0Sstevel@tonic-gate {
345*0Sstevel@tonic-gate 0x00000000, 0x80000000, 0x00800000, 0x80800000,
346*0Sstevel@tonic-gate 0x00008000, 0x80008000, 0x00808000, 0x80808000,
347*0Sstevel@tonic-gate 0x00000080, 0x80000080, 0x00800080, 0x80800080,
348*0Sstevel@tonic-gate 0x00008080, 0x80008080, 0x00808080, 0x80808080,
349*0Sstevel@tonic-gate 0x40000000, 0xc0000000, 0x40800000, 0xc0800000,
350*0Sstevel@tonic-gate 0x40008000, 0xc0008000, 0x40808000, 0xc0808000,
351*0Sstevel@tonic-gate 0x40000080, 0xc0000080, 0x40800080, 0xc0800080,
352*0Sstevel@tonic-gate 0x40008080, 0xc0008080, 0x40808080, 0xc0808080,
353*0Sstevel@tonic-gate 0x00400000, 0x80400000, 0x00c00000, 0x80c00000,
354*0Sstevel@tonic-gate 0x00408000, 0x80408000, 0x00c08000, 0x80c08000,
355*0Sstevel@tonic-gate 0x00400080, 0x80400080, 0x00c00080, 0x80c00080,
356*0Sstevel@tonic-gate 0x00408080, 0x80408080, 0x00c08080, 0x80c08080,
357*0Sstevel@tonic-gate 0x40400000, 0xc0400000, 0x40c00000, 0xc0c00000,
358*0Sstevel@tonic-gate 0x40408000, 0xc0408000, 0x40c08000, 0xc0c08000,
359*0Sstevel@tonic-gate 0x40400080, 0xc0400080, 0x40c00080, 0xc0c00080,
360*0Sstevel@tonic-gate 0x40408080, 0xc0408080, 0x40c08080, 0xc0c08080,
361*0Sstevel@tonic-gate 0x00004000, 0x80004000, 0x00804000, 0x80804000,
362*0Sstevel@tonic-gate 0x0000c000, 0x8000c000, 0x0080c000, 0x8080c000,
363*0Sstevel@tonic-gate 0x00004080, 0x80004080, 0x00804080, 0x80804080,
364*0Sstevel@tonic-gate 0x0000c080, 0x8000c080, 0x0080c080, 0x8080c080,
365*0Sstevel@tonic-gate 0x40004000, 0xc0004000, 0x40804000, 0xc0804000,
366*0Sstevel@tonic-gate 0x4000c000, 0xc000c000, 0x4080c000, 0xc080c000,
367*0Sstevel@tonic-gate 0x40004080, 0xc0004080, 0x40804080, 0xc0804080,
368*0Sstevel@tonic-gate 0x4000c080, 0xc000c080, 0x4080c080, 0xc080c080,
369*0Sstevel@tonic-gate 0x00404000, 0x80404000, 0x00c04000, 0x80c04000,
370*0Sstevel@tonic-gate 0x0040c000, 0x8040c000, 0x00c0c000, 0x80c0c000,
371*0Sstevel@tonic-gate 0x00404080, 0x80404080, 0x00c04080, 0x80c04080,
372*0Sstevel@tonic-gate 0x0040c080, 0x8040c080, 0x00c0c080, 0x80c0c080,
373*0Sstevel@tonic-gate 0x40404000, 0xc0404000, 0x40c04000, 0xc0c04000,
374*0Sstevel@tonic-gate 0x4040c000, 0xc040c000, 0x40c0c000, 0xc0c0c000,
375*0Sstevel@tonic-gate 0x40404080, 0xc0404080, 0x40c04080, 0xc0c04080,
376*0Sstevel@tonic-gate 0x4040c080, 0xc040c080, 0x40c0c080, 0xc0c0c080,
377*0Sstevel@tonic-gate 0x00000040, 0x80000040, 0x00800040, 0x80800040,
378*0Sstevel@tonic-gate 0x00008040, 0x80008040, 0x00808040, 0x80808040,
379*0Sstevel@tonic-gate 0x000000c0, 0x800000c0, 0x008000c0, 0x808000c0,
380*0Sstevel@tonic-gate 0x000080c0, 0x800080c0, 0x008080c0, 0x808080c0,
381*0Sstevel@tonic-gate 0x40000040, 0xc0000040, 0x40800040, 0xc0800040,
382*0Sstevel@tonic-gate 0x40008040, 0xc0008040, 0x40808040, 0xc0808040,
383*0Sstevel@tonic-gate 0x400000c0, 0xc00000c0, 0x408000c0, 0xc08000c0,
384*0Sstevel@tonic-gate 0x400080c0, 0xc00080c0, 0x408080c0, 0xc08080c0,
385*0Sstevel@tonic-gate 0x00400040, 0x80400040, 0x00c00040, 0x80c00040,
386*0Sstevel@tonic-gate 0x00408040, 0x80408040, 0x00c08040, 0x80c08040,
387*0Sstevel@tonic-gate 0x004000c0, 0x804000c0, 0x00c000c0, 0x80c000c0,
388*0Sstevel@tonic-gate 0x004080c0, 0x804080c0, 0x00c080c0, 0x80c080c0,
389*0Sstevel@tonic-gate 0x40400040, 0xc0400040, 0x40c00040, 0xc0c00040,
390*0Sstevel@tonic-gate 0x40408040, 0xc0408040, 0x40c08040, 0xc0c08040,
391*0Sstevel@tonic-gate 0x404000c0, 0xc04000c0, 0x40c000c0, 0xc0c000c0,
392*0Sstevel@tonic-gate 0x404080c0, 0xc04080c0, 0x40c080c0, 0xc0c080c0,
393*0Sstevel@tonic-gate 0x00004040, 0x80004040, 0x00804040, 0x80804040,
394*0Sstevel@tonic-gate 0x0000c040, 0x8000c040, 0x0080c040, 0x8080c040,
395*0Sstevel@tonic-gate 0x000040c0, 0x800040c0, 0x008040c0, 0x808040c0,
396*0Sstevel@tonic-gate 0x0000c0c0, 0x8000c0c0, 0x0080c0c0, 0x8080c0c0,
397*0Sstevel@tonic-gate 0x40004040, 0xc0004040, 0x40804040, 0xc0804040,
398*0Sstevel@tonic-gate 0x4000c040, 0xc000c040, 0x4080c040, 0xc080c040,
399*0Sstevel@tonic-gate 0x400040c0, 0xc00040c0, 0x408040c0, 0xc08040c0,
400*0Sstevel@tonic-gate 0x4000c0c0, 0xc000c0c0, 0x4080c0c0, 0xc080c0c0,
401*0Sstevel@tonic-gate 0x00404040, 0x80404040, 0x00c04040, 0x80c04040,
402*0Sstevel@tonic-gate 0x0040c040, 0x8040c040, 0x00c0c040, 0x80c0c040,
403*0Sstevel@tonic-gate 0x004040c0, 0x804040c0, 0x00c040c0, 0x80c040c0,
404*0Sstevel@tonic-gate 0x0040c0c0, 0x8040c0c0, 0x00c0c0c0, 0x80c0c0c0,
405*0Sstevel@tonic-gate 0x40404040, 0xc0404040, 0x40c04040, 0xc0c04040,
406*0Sstevel@tonic-gate 0x4040c040, 0xc040c040, 0x40c0c040, 0xc0c0c040,
407*0Sstevel@tonic-gate 0x404040c0, 0xc04040c0, 0x40c040c0, 0xc0c040c0,
408*0Sstevel@tonic-gate 0x4040c0c0, 0xc040c0c0, 0x40c0c0c0, 0xc0c0c0c0
409*0Sstevel@tonic-gate };
410*0Sstevel@tonic-gate 
411*0Sstevel@tonic-gate static const uint64_t all_a = 0xaaaaaaaaaaaaaaaaull;
412*0Sstevel@tonic-gate static const uint64_t all_5 = 0x5555555555555555ull;
413*0Sstevel@tonic-gate static const uint64_t top_1 = 0xfc000000000000ull;
414*0Sstevel@tonic-gate static const uint64_t mid_4 = 0x3fffffc000000ull;
415*0Sstevel@tonic-gate static const uint64_t low_3 = 0x3ffff00ull;
416*0Sstevel@tonic-gate 
417*0Sstevel@tonic-gate 
418*0Sstevel@tonic-gate static void
419*0Sstevel@tonic-gate des_ip(uint64_t *l, uint64_t *r, uint64_t pt)
420*0Sstevel@tonic-gate {
421*0Sstevel@tonic-gate 	uint64_t a, b;
422*0Sstevel@tonic-gate 
423*0Sstevel@tonic-gate 	a = pt & all_a;
424*0Sstevel@tonic-gate 	b = pt & all_5;
425*0Sstevel@tonic-gate 	a = a | (a << 7);
426*0Sstevel@tonic-gate 	b = b | (b >> 7);
427*0Sstevel@tonic-gate 
428*0Sstevel@tonic-gate 	b = (ip_table[0][(b >> 48) & 255ull]) |
429*0Sstevel@tonic-gate 		(ip_table[1][(b >> 32) & 255ull]) |
430*0Sstevel@tonic-gate 		(ip_table[0][(b >> 16) & 255ull] << 6) |
431*0Sstevel@tonic-gate 		(ip_table[1][b & 255ull] << 6);
432*0Sstevel@tonic-gate 
433*0Sstevel@tonic-gate 	a = (ip_table[0][(a >> 56) & 255]) |
434*0Sstevel@tonic-gate 		(ip_table[1][(a >> 40) & 255]) |
435*0Sstevel@tonic-gate 		(ip_table[0][(a >> 24) & 255] << 6) |
436*0Sstevel@tonic-gate 		(ip_table[1][(a >> 8) & 255] << 6);
437*0Sstevel@tonic-gate 
438*0Sstevel@tonic-gate 	*l = ((b & top_1) << 8) |
439*0Sstevel@tonic-gate 		(b & mid_4) |
440*0Sstevel@tonic-gate 		((b & low_3) >> 5);
441*0Sstevel@tonic-gate 
442*0Sstevel@tonic-gate 	*r = ((a & top_1) << 8) |
443*0Sstevel@tonic-gate 		(a & mid_4) |
444*0Sstevel@tonic-gate 		((a & low_3) >> 5);
445*0Sstevel@tonic-gate }
446*0Sstevel@tonic-gate 
447*0Sstevel@tonic-gate 
448*0Sstevel@tonic-gate static uint64_t
449*0Sstevel@tonic-gate des_fp(uint64_t l, uint64_t r)
450*0Sstevel@tonic-gate {
451*0Sstevel@tonic-gate 	uint32_t upper, lower;
452*0Sstevel@tonic-gate 
453*0Sstevel@tonic-gate 	lower = fp_table[((l >> 55) & 240) | ((r >> 59) & 15)] |
454*0Sstevel@tonic-gate 		(fp_table[((l >> 35) & 240) | ((r>>39) & 15)] >> 2) |
455*0Sstevel@tonic-gate 		(fp_table[((l >> 23) & 240) | ((r >> 27) & 15)] >> 4) |
456*0Sstevel@tonic-gate 		(fp_table[((l >> 6) & 240) | ((r >> 10) & 15)] >> 6);
457*0Sstevel@tonic-gate 
458*0Sstevel@tonic-gate 	upper = fp_table[((l >> 41) & 240) | ((r >> 45) & 15)] |
459*0Sstevel@tonic-gate 		(fp_table[((l >> 29) & 240) | ((r >> 33) & 15)] >> 2) |
460*0Sstevel@tonic-gate 		(fp_table[((l >> 12) & 240) | ((r >> 16) & 15)] >> 4) |
461*0Sstevel@tonic-gate 		(fp_table[(l & 240) | (r >> 4) & 15] >> 6);
462*0Sstevel@tonic-gate 
463*0Sstevel@tonic-gate 	return ((((uint64_t)upper) << 32) | (uint64_t)lower);
464*0Sstevel@tonic-gate 
465*0Sstevel@tonic-gate }
466*0Sstevel@tonic-gate 
467*0Sstevel@tonic-gate uint64_t
468*0Sstevel@tonic-gate des_crypt_impl(uint64_t *ks, uint64_t block, int one_or_three)
469*0Sstevel@tonic-gate {
470*0Sstevel@tonic-gate 	int i, j;
471*0Sstevel@tonic-gate 	uint64_t l, r, t;
472*0Sstevel@tonic-gate 
473*0Sstevel@tonic-gate 	des_ip(&l, &r, block);
474*0Sstevel@tonic-gate 	for (j = 0; j < one_or_three; j++) {
475*0Sstevel@tonic-gate 		for (i = j * 16; i < (j + 1) * 16; i++) {
476*0Sstevel@tonic-gate 			t = r ^ ks[i];
477*0Sstevel@tonic-gate 			t = sbox_table[0][t >> 58] |
478*0Sstevel@tonic-gate 				sbox_table[1][(t >> 44) & 63] |
479*0Sstevel@tonic-gate 				sbox_table[2][(t >> 38) & 63] |
480*0Sstevel@tonic-gate 				sbox_table[3][(t >> 32) & 63] |
481*0Sstevel@tonic-gate 				sbox_table[4][(t >> 26) & 63] |
482*0Sstevel@tonic-gate 				sbox_table[5][(t >> 15) & 63] |
483*0Sstevel@tonic-gate 				sbox_table[6][(t >> 9) & 63] |
484*0Sstevel@tonic-gate 				sbox_table[7][(t >> 3) & 63];
485*0Sstevel@tonic-gate 			t = t^l;
486*0Sstevel@tonic-gate 			l = r;
487*0Sstevel@tonic-gate 			r = t;
488*0Sstevel@tonic-gate 		}
489*0Sstevel@tonic-gate 		r = l;
490*0Sstevel@tonic-gate 		l = t;
491*0Sstevel@tonic-gate 	}
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate 	return (des_fp(l, r));
494*0Sstevel@tonic-gate }
495*0Sstevel@tonic-gate #endif /* !sun4u */
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate /* EXPORT DELETE END */
498*0Sstevel@tonic-gate 
499*0Sstevel@tonic-gate void
500*0Sstevel@tonic-gate des3_crunch_block(void *cookie, uint8_t block[DES_BLOCK_LEN],
501*0Sstevel@tonic-gate     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
502*0Sstevel@tonic-gate {
503*0Sstevel@tonic-gate /* EXPORT DELETE START */
504*0Sstevel@tonic-gate 	keysched3_t *ksch = (keysched3_t *)cookie;
505*0Sstevel@tonic-gate 
506*0Sstevel@tonic-gate 	/*
507*0Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
508*0Sstevel@tonic-gate 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
509*0Sstevel@tonic-gate 	 * copies the block without reversing bytes.
510*0Sstevel@tonic-gate 	 */
511*0Sstevel@tonic-gate #ifdef _BIG_ENDIAN
512*0Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
513*0Sstevel@tonic-gate 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
514*0Sstevel@tonic-gate 		if (decrypt == B_TRUE)
515*0Sstevel@tonic-gate 			/* LINTED */
516*0Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
517*0Sstevel@tonic-gate 			    ksch->ksch_decrypt,
518*0Sstevel@tonic-gate 			    /* LINTED */
519*0Sstevel@tonic-gate 			    *(uint64_t *)block, 3);
520*0Sstevel@tonic-gate 		else
521*0Sstevel@tonic-gate 			/* LINTED */
522*0Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
523*0Sstevel@tonic-gate 			    ksch->ksch_encrypt,
524*0Sstevel@tonic-gate 			    /* LINTED */
525*0Sstevel@tonic-gate 			    *(uint64_t *)block, 3);
526*0Sstevel@tonic-gate 	} else {
527*0Sstevel@tonic-gate #endif
528*0Sstevel@tonic-gate 		uint64_t tmp;
529*0Sstevel@tonic-gate 
530*0Sstevel@tonic-gate 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
531*0Sstevel@tonic-gate 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
532*0Sstevel@tonic-gate 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
533*0Sstevel@tonic-gate 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
534*0Sstevel@tonic-gate 
535*0Sstevel@tonic-gate 		if (decrypt == B_TRUE)
536*0Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 3);
537*0Sstevel@tonic-gate 		else
538*0Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 3);
539*0Sstevel@tonic-gate 
540*0Sstevel@tonic-gate 		out_block[0] = tmp >> 56;
541*0Sstevel@tonic-gate 		out_block[1] = tmp >> 48;
542*0Sstevel@tonic-gate 		out_block[2] = tmp >> 40;
543*0Sstevel@tonic-gate 		out_block[3] = tmp >> 32;
544*0Sstevel@tonic-gate 		out_block[4] = tmp >> 24;
545*0Sstevel@tonic-gate 		out_block[5] = tmp >> 16;
546*0Sstevel@tonic-gate 		out_block[6] = tmp >> 8;
547*0Sstevel@tonic-gate 		out_block[7] = (uint8_t)tmp;
548*0Sstevel@tonic-gate #ifdef _BIG_ENDIAN
549*0Sstevel@tonic-gate 	}
550*0Sstevel@tonic-gate #endif
551*0Sstevel@tonic-gate /* EXPORT DELETE END */
552*0Sstevel@tonic-gate }
553*0Sstevel@tonic-gate 
554*0Sstevel@tonic-gate void
555*0Sstevel@tonic-gate des_crunch_block(void *cookie, uint8_t block[DES_BLOCK_LEN],
556*0Sstevel@tonic-gate     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
557*0Sstevel@tonic-gate {
558*0Sstevel@tonic-gate /* EXPORT DELETE START */
559*0Sstevel@tonic-gate 	keysched_t *ksch = (keysched_t *)cookie;
560*0Sstevel@tonic-gate 
561*0Sstevel@tonic-gate 	/*
562*0Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
563*0Sstevel@tonic-gate 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
564*0Sstevel@tonic-gate 	 * copies the block without reversing bytes.
565*0Sstevel@tonic-gate 	 */
566*0Sstevel@tonic-gate #ifdef _BIG_ENDIAN
567*0Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
568*0Sstevel@tonic-gate 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
569*0Sstevel@tonic-gate 		if (decrypt == B_TRUE)
570*0Sstevel@tonic-gate 			/* LINTED */
571*0Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
572*0Sstevel@tonic-gate 			    ksch->ksch_decrypt,
573*0Sstevel@tonic-gate 			    /* LINTED */
574*0Sstevel@tonic-gate 			    *(uint64_t *)block, 1);
575*0Sstevel@tonic-gate 		else
576*0Sstevel@tonic-gate 			/* LINTED */
577*0Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
578*0Sstevel@tonic-gate 			    ksch->ksch_encrypt,
579*0Sstevel@tonic-gate 			    /* LINTED */
580*0Sstevel@tonic-gate 			    *(uint64_t *)block, 1);
581*0Sstevel@tonic-gate 
582*0Sstevel@tonic-gate 	} else {
583*0Sstevel@tonic-gate #endif
584*0Sstevel@tonic-gate 		uint64_t tmp;
585*0Sstevel@tonic-gate 
586*0Sstevel@tonic-gate 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
587*0Sstevel@tonic-gate 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
588*0Sstevel@tonic-gate 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
589*0Sstevel@tonic-gate 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
590*0Sstevel@tonic-gate 
591*0Sstevel@tonic-gate 		if (decrypt == B_TRUE)
592*0Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 1);
593*0Sstevel@tonic-gate 		else
594*0Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 1);
595*0Sstevel@tonic-gate 
596*0Sstevel@tonic-gate 		out_block[0] = tmp >> 56;
597*0Sstevel@tonic-gate 		out_block[1] = tmp >> 48;
598*0Sstevel@tonic-gate 		out_block[2] = tmp >> 40;
599*0Sstevel@tonic-gate 		out_block[3] = tmp >> 32;
600*0Sstevel@tonic-gate 		out_block[4] = tmp >> 24;
601*0Sstevel@tonic-gate 		out_block[5] = tmp >> 16;
602*0Sstevel@tonic-gate 		out_block[6] = tmp >> 8;
603*0Sstevel@tonic-gate 		out_block[7] = (uint8_t)tmp;
604*0Sstevel@tonic-gate #ifdef _BIG_ENDIAN
605*0Sstevel@tonic-gate 	}
606*0Sstevel@tonic-gate #endif
607*0Sstevel@tonic-gate /* EXPORT DELETE END */
608*0Sstevel@tonic-gate }
609*0Sstevel@tonic-gate 
610*0Sstevel@tonic-gate static boolean_t
611*0Sstevel@tonic-gate keycheck(uint8_t *key, uint8_t *corrected_key)
612*0Sstevel@tonic-gate {
613*0Sstevel@tonic-gate /* EXPORT DELETE START */
614*0Sstevel@tonic-gate 	uint64_t key_so_far;
615*0Sstevel@tonic-gate 	uint_t i;
616*0Sstevel@tonic-gate 	/*
617*0Sstevel@tonic-gate 	 * Table of weak and semi-weak keys.  Fortunately, weak keys are
618*0Sstevel@tonic-gate 	 * endian-independent, and some semi-weak keys can be paired up in
619*0Sstevel@tonic-gate 	 * endian-opposite order.  Since keys are stored as uint64_t's,
620*0Sstevel@tonic-gate 	 * use the ifdef _LITTLE_ENDIAN where appropriate.
621*0Sstevel@tonic-gate 	 */
622*0Sstevel@tonic-gate 	static uint64_t des_weak_keys[] = {
623*0Sstevel@tonic-gate 		/* Really weak keys.  Byte-order independent values. */
624*0Sstevel@tonic-gate 		0x0101010101010101,
625*0Sstevel@tonic-gate 		0x1f1f1f1f0e0e0e0e,
626*0Sstevel@tonic-gate 		0xe0e0e0e0f1f1f1f1,
627*0Sstevel@tonic-gate 		0xfefefefefefefefe,
628*0Sstevel@tonic-gate 
629*0Sstevel@tonic-gate 		/* Semi-weak (and a few possibly-weak) keys. */
630*0Sstevel@tonic-gate 
631*0Sstevel@tonic-gate 		/* Byte-order independent semi-weak keys. */
632*0Sstevel@tonic-gate 		0x01fe01fe01fe01fe,	0xfe01fe01fe01fe01,
633*0Sstevel@tonic-gate 
634*0Sstevel@tonic-gate 		/* Byte-order dependent semi-weak keys. */
635*0Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
636*0Sstevel@tonic-gate 		0xf10ef10ee01fe01f,	0x0ef10ef11fe01fe0,
637*0Sstevel@tonic-gate 		0x01f101f101e001e0,	0xf101f101e001e001,
638*0Sstevel@tonic-gate 		0x0efe0efe1ffe1ffe,	0xfe0efe0efe1ffe1f,
639*0Sstevel@tonic-gate 		0x010e010e011f011f,	0x0e010e011f011f01,
640*0Sstevel@tonic-gate 		0xf1fef1fee0fee0fe,	0xfef1fef1fee0fee0,
641*0Sstevel@tonic-gate #else	/* Big endian */
642*0Sstevel@tonic-gate 		0x1fe01fe00ef10ef1,	0xe01fe01ff10ef10e,
643*0Sstevel@tonic-gate 		0x01e001e001f101f1,	0xe001e001f101f101,
644*0Sstevel@tonic-gate 		0x1ffe1ffe0efe0efe,	0xfe1ffe1ffe0efe0e,
645*0Sstevel@tonic-gate 		0x011f011f010e010e,	0x1f011f010e010e01,
646*0Sstevel@tonic-gate 		0xe0fee0fef1fef1fe,	0xfee0fee0fef1fef1,
647*0Sstevel@tonic-gate #endif
648*0Sstevel@tonic-gate 
649*0Sstevel@tonic-gate 		/* We'll save the other possibly-weak keys for the future. */
650*0Sstevel@tonic-gate 	};
651*0Sstevel@tonic-gate 
652*0Sstevel@tonic-gate 	if (key == NULL)
653*0Sstevel@tonic-gate 		return (B_FALSE);
654*0Sstevel@tonic-gate 
655*0Sstevel@tonic-gate 	/*
656*0Sstevel@tonic-gate 	 * The code below reverses the bytes on LITTLE_ENDIAN machines.
657*0Sstevel@tonic-gate 	 * On BIG_ENDIAN, the same code copies without reversing
658*0Sstevel@tonic-gate 	 * the bytes.
659*0Sstevel@tonic-gate 	 */
660*0Sstevel@tonic-gate 	key_so_far = (((uint64_t)key[0] << 56) | ((uint64_t)key[1] << 48) |
661*0Sstevel@tonic-gate 	    ((uint64_t)key[2] << 40) | ((uint64_t)key[3] << 32) |
662*0Sstevel@tonic-gate 	    ((uint64_t)key[4] << 24) | ((uint64_t)key[5] << 16) |
663*0Sstevel@tonic-gate 	    ((uint64_t)key[6] << 8) | (uint64_t)key[7]);
664*0Sstevel@tonic-gate 
665*0Sstevel@tonic-gate 	/*
666*0Sstevel@tonic-gate 	 * Fix parity.
667*0Sstevel@tonic-gate 	 */
668*0Sstevel@tonic-gate 	fix_des_parity(&key_so_far);
669*0Sstevel@tonic-gate 	key_so_far ^= 0x0101010101010101;
670*0Sstevel@tonic-gate 
671*0Sstevel@tonic-gate 	/* Do weak key check itself. */
672*0Sstevel@tonic-gate 	for (i = 0; i < (sizeof (des_weak_keys) / sizeof (uint64_t)); i++)
673*0Sstevel@tonic-gate 		if (key_so_far == des_weak_keys[i]) {
674*0Sstevel@tonic-gate 			return (B_FALSE);
675*0Sstevel@tonic-gate 		}
676*0Sstevel@tonic-gate 
677*0Sstevel@tonic-gate 	if (corrected_key != NULL) {
678*0Sstevel@tonic-gate 		/*
679*0Sstevel@tonic-gate 		 * The code below reverses the bytes on LITTLE_ENDIAN machines.
680*0Sstevel@tonic-gate 		 * On BIG_ENDIAN, the same code copies without reversing
681*0Sstevel@tonic-gate 		 * the bytes.
682*0Sstevel@tonic-gate 		 */
683*0Sstevel@tonic-gate 		corrected_key[0] = key_so_far >> 56;
684*0Sstevel@tonic-gate 		corrected_key[1] = key_so_far >> 48;
685*0Sstevel@tonic-gate 		corrected_key[2] = key_so_far >> 40;
686*0Sstevel@tonic-gate 		corrected_key[3] = key_so_far >> 32;
687*0Sstevel@tonic-gate 		corrected_key[4] = key_so_far >> 24;
688*0Sstevel@tonic-gate 		corrected_key[5] = key_so_far >> 16;
689*0Sstevel@tonic-gate 		corrected_key[6] = key_so_far >> 8;
690*0Sstevel@tonic-gate 		corrected_key[7] = (uint8_t)key_so_far;
691*0Sstevel@tonic-gate 	}
692*0Sstevel@tonic-gate /* EXPORT DELETE END */
693*0Sstevel@tonic-gate 	return (B_TRUE);
694*0Sstevel@tonic-gate }
695*0Sstevel@tonic-gate 
696*0Sstevel@tonic-gate static boolean_t
697*0Sstevel@tonic-gate des3_keycheck(uint8_t *key, uint8_t *corrected_key)
698*0Sstevel@tonic-gate {
699*0Sstevel@tonic-gate /* EXPORT DELETE START */
700*0Sstevel@tonic-gate 	uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
701*0Sstevel@tonic-gate 	uint64_t key_so_far, scratch, *currentkey;
702*0Sstevel@tonic-gate 	uint_t j, num_weakkeys = 0;
703*0Sstevel@tonic-gate 
704*0Sstevel@tonic-gate 	if (key == NULL) {
705*0Sstevel@tonic-gate 		return (B_FALSE);
706*0Sstevel@tonic-gate 	}
707*0Sstevel@tonic-gate 
708*0Sstevel@tonic-gate 	if (!IS_P2ALIGNED(key, sizeof (uint64_t))) {
709*0Sstevel@tonic-gate 		bcopy(key, aligned_key, DES3_KEYSIZE);
710*0Sstevel@tonic-gate 		currentkey = (uint64_t *)aligned_key;
711*0Sstevel@tonic-gate 	} else {
712*0Sstevel@tonic-gate 		/* LINTED */
713*0Sstevel@tonic-gate 		currentkey = (uint64_t *)key;
714*0Sstevel@tonic-gate 	}
715*0Sstevel@tonic-gate 
716*0Sstevel@tonic-gate 	for (j = 0; j < 3; j++) {
717*0Sstevel@tonic-gate 		key_so_far = currentkey[j];
718*0Sstevel@tonic-gate 
719*0Sstevel@tonic-gate 		if (!keycheck((uint8_t *)&key_so_far, (uint8_t *)&scratch)) {
720*0Sstevel@tonic-gate 			if (++num_weakkeys > 1) {
721*0Sstevel@tonic-gate 				return (B_FALSE);
722*0Sstevel@tonic-gate 			}
723*0Sstevel@tonic-gate 			/*
724*0Sstevel@tonic-gate 			 * We found a weak key, but since
725*0Sstevel@tonic-gate 			 * we've only found one weak key,
726*0Sstevel@tonic-gate 			 * we can not reject the whole 3DES
727*0Sstevel@tonic-gate 			 * set of keys as weak.
728*0Sstevel@tonic-gate 			 *
729*0Sstevel@tonic-gate 			 * Break from the weak key loop
730*0Sstevel@tonic-gate 			 * (since this DES key is weak) and
731*0Sstevel@tonic-gate 			 * continue on.
732*0Sstevel@tonic-gate 			 */
733*0Sstevel@tonic-gate 		}
734*0Sstevel@tonic-gate 
735*0Sstevel@tonic-gate 		currentkey[j] = scratch;
736*0Sstevel@tonic-gate 	}
737*0Sstevel@tonic-gate 
738*0Sstevel@tonic-gate 	/*
739*0Sstevel@tonic-gate 	 * Perform key equivalence checks, now that parity is properly set.
740*0Sstevel@tonic-gate 	 * All three keys must be unique.
741*0Sstevel@tonic-gate 	 */
742*0Sstevel@tonic-gate 	if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2] ||
743*0Sstevel@tonic-gate 	    currentkey[2] == currentkey[0])
744*0Sstevel@tonic-gate 		return (B_FALSE);
745*0Sstevel@tonic-gate 
746*0Sstevel@tonic-gate 	if (corrected_key != NULL) {
747*0Sstevel@tonic-gate 		bcopy(currentkey, corrected_key, DES3_KEYSIZE);
748*0Sstevel@tonic-gate 	}
749*0Sstevel@tonic-gate /* EXPORT DELETE END */
750*0Sstevel@tonic-gate 	return (B_TRUE);
751*0Sstevel@tonic-gate }
752*0Sstevel@tonic-gate 
753*0Sstevel@tonic-gate boolean_t
754*0Sstevel@tonic-gate des_keycheck(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
755*0Sstevel@tonic-gate {
756*0Sstevel@tonic-gate 	if (strength == DES) {
757*0Sstevel@tonic-gate 		return (keycheck(key, corrected_key));
758*0Sstevel@tonic-gate 	} else if (strength == DES3) {
759*0Sstevel@tonic-gate 		return (des3_keycheck(key, corrected_key));
760*0Sstevel@tonic-gate 	} else {
761*0Sstevel@tonic-gate 		return (B_FALSE);
762*0Sstevel@tonic-gate 	}
763*0Sstevel@tonic-gate }
764*0Sstevel@tonic-gate 
765*0Sstevel@tonic-gate /*
766*0Sstevel@tonic-gate  * Initialize key schedule for DES, DES2, and DES3
767*0Sstevel@tonic-gate  */
768*0Sstevel@tonic-gate void
769*0Sstevel@tonic-gate des_init_keysched(uint8_t *cipherKey, des_strength_t strength, void *ks)
770*0Sstevel@tonic-gate {
771*0Sstevel@tonic-gate /* EXPORT DELETE START */
772*0Sstevel@tonic-gate 	uint64_t *encryption_ks;
773*0Sstevel@tonic-gate 	uint64_t *decryption_ks;
774*0Sstevel@tonic-gate 	uint64_t keysched[48];
775*0Sstevel@tonic-gate 	uint64_t key_uint64[3];
776*0Sstevel@tonic-gate 	uint64_t tmp;
777*0Sstevel@tonic-gate 	uint_t keysize, i, j;
778*0Sstevel@tonic-gate 
779*0Sstevel@tonic-gate 	switch (strength) {
780*0Sstevel@tonic-gate 	case DES:
781*0Sstevel@tonic-gate 		keysize = DES_KEYSIZE;
782*0Sstevel@tonic-gate 		encryption_ks = ((keysched_t *)ks)->ksch_encrypt;
783*0Sstevel@tonic-gate 		decryption_ks = ((keysched_t *)ks)->ksch_decrypt;
784*0Sstevel@tonic-gate 		break;
785*0Sstevel@tonic-gate 	case DES2:
786*0Sstevel@tonic-gate 		keysize = DES2_KEYSIZE;
787*0Sstevel@tonic-gate 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
788*0Sstevel@tonic-gate 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
789*0Sstevel@tonic-gate 		break;
790*0Sstevel@tonic-gate 	case DES3:
791*0Sstevel@tonic-gate 		keysize = DES3_KEYSIZE;
792*0Sstevel@tonic-gate 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
793*0Sstevel@tonic-gate 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
794*0Sstevel@tonic-gate 	}
795*0Sstevel@tonic-gate 
796*0Sstevel@tonic-gate 	/*
797*0Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
798*0Sstevel@tonic-gate 	 * reverses every 8 bytes in the key.  On BIG_ENDIAN, the same code
799*0Sstevel@tonic-gate 	 * copies the key without reversing bytes.
800*0Sstevel@tonic-gate 	 */
801*0Sstevel@tonic-gate #ifdef _BIG_ENDIAN
802*0Sstevel@tonic-gate 	if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) {
803*0Sstevel@tonic-gate 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
804*0Sstevel@tonic-gate 			/* LINTED: pointer alignment */
805*0Sstevel@tonic-gate 			key_uint64[i] = *((uint64_t *)&cipherKey[j]);
806*0Sstevel@tonic-gate 		}
807*0Sstevel@tonic-gate 	} else {
808*0Sstevel@tonic-gate #endif
809*0Sstevel@tonic-gate 	{
810*0Sstevel@tonic-gate 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
811*0Sstevel@tonic-gate 			key_uint64[i] = (((uint64_t)cipherKey[j] << 56) |
812*0Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 1] << 48) |
813*0Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 2] << 40) |
814*0Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 3] << 32) |
815*0Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 4] << 24) |
816*0Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 5] << 16) |
817*0Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 6] << 8) |
818*0Sstevel@tonic-gate 			    (uint64_t)cipherKey[j + 7]);
819*0Sstevel@tonic-gate 		}
820*0Sstevel@tonic-gate 	}
821*0Sstevel@tonic-gate #ifdef _BIG_ENDIAN
822*0Sstevel@tonic-gate 	}
823*0Sstevel@tonic-gate #endif
824*0Sstevel@tonic-gate 
825*0Sstevel@tonic-gate 	switch (strength) {
826*0Sstevel@tonic-gate 	case DES:
827*0Sstevel@tonic-gate 		des_ks(keysched, key_uint64[0]);
828*0Sstevel@tonic-gate 		break;
829*0Sstevel@tonic-gate 
830*0Sstevel@tonic-gate 	case DES2:
831*0Sstevel@tonic-gate 		/* DES2 is just DES3 with the first and third keys the same */
832*0Sstevel@tonic-gate 		bcopy(key_uint64, key_uint64 + 2, DES_KEYSIZE);
833*0Sstevel@tonic-gate 		/* FALLTHRU */
834*0Sstevel@tonic-gate 	case DES3:
835*0Sstevel@tonic-gate 		des_ks(keysched, key_uint64[0]);
836*0Sstevel@tonic-gate 		des_ks(keysched + 16, key_uint64[1]);
837*0Sstevel@tonic-gate 		for (i = 0; i < 8; i++) {
838*0Sstevel@tonic-gate 			tmp = keysched[16+i];
839*0Sstevel@tonic-gate 			keysched[16+i] = keysched[31-i];
840*0Sstevel@tonic-gate 			keysched[31-i] = tmp;
841*0Sstevel@tonic-gate 		}
842*0Sstevel@tonic-gate 		des_ks(keysched+32, key_uint64[2]);
843*0Sstevel@tonic-gate 		keysize = DES3_KEYSIZE;
844*0Sstevel@tonic-gate 	}
845*0Sstevel@tonic-gate 
846*0Sstevel@tonic-gate 	/* save the encryption keyschedule */
847*0Sstevel@tonic-gate 	bcopy(keysched, encryption_ks, keysize * 16);
848*0Sstevel@tonic-gate 
849*0Sstevel@tonic-gate 	/* reverse the key schedule */
850*0Sstevel@tonic-gate 	for (i = 0; i < keysize; i++) {
851*0Sstevel@tonic-gate 		tmp = keysched[i];
852*0Sstevel@tonic-gate 		keysched[i] = keysched[2 * keysize - 1 - i];
853*0Sstevel@tonic-gate 		keysched[2 * keysize -1 -i] = tmp;
854*0Sstevel@tonic-gate 	}
855*0Sstevel@tonic-gate 
856*0Sstevel@tonic-gate 	/* save the decryption keyschedule */
857*0Sstevel@tonic-gate 	bcopy(keysched, decryption_ks, keysize * 16);
858*0Sstevel@tonic-gate /* EXPORT DELETE END */
859*0Sstevel@tonic-gate }
860*0Sstevel@tonic-gate 
861*0Sstevel@tonic-gate /*
862*0Sstevel@tonic-gate  * Allocate key schedule.
863*0Sstevel@tonic-gate  */
864*0Sstevel@tonic-gate /*ARGSUSED*/
865*0Sstevel@tonic-gate void *
866*0Sstevel@tonic-gate des_alloc_keysched(size_t *keysched_size, des_strength_t strength, int kmflag)
867*0Sstevel@tonic-gate {
868*0Sstevel@tonic-gate 	void *keysched;
869*0Sstevel@tonic-gate 
870*0Sstevel@tonic-gate /* EXPORT DELETE START */
871*0Sstevel@tonic-gate 
872*0Sstevel@tonic-gate 	size_t size;
873*0Sstevel@tonic-gate 
874*0Sstevel@tonic-gate 	switch (strength) {
875*0Sstevel@tonic-gate 	case DES:
876*0Sstevel@tonic-gate 		size = sizeof (keysched_t);
877*0Sstevel@tonic-gate 		break;
878*0Sstevel@tonic-gate 	case DES2:
879*0Sstevel@tonic-gate 	case DES3:
880*0Sstevel@tonic-gate 		size = sizeof (keysched3_t);
881*0Sstevel@tonic-gate 	}
882*0Sstevel@tonic-gate 
883*0Sstevel@tonic-gate #ifdef	_KERNEL
884*0Sstevel@tonic-gate 	keysched = (keysched_t *)kmem_alloc(size, kmflag);
885*0Sstevel@tonic-gate #else	/* !_KERNEL */
886*0Sstevel@tonic-gate 	keysched = (keysched_t *)malloc(size);
887*0Sstevel@tonic-gate #endif	/* _KERNEL */
888*0Sstevel@tonic-gate 
889*0Sstevel@tonic-gate 	if (keysched == NULL)
890*0Sstevel@tonic-gate 		return (NULL);
891*0Sstevel@tonic-gate 
892*0Sstevel@tonic-gate 	if (keysched_size != NULL)
893*0Sstevel@tonic-gate 		*keysched_size = size;
894*0Sstevel@tonic-gate 
895*0Sstevel@tonic-gate /* EXPORT DELETE END */
896*0Sstevel@tonic-gate 
897*0Sstevel@tonic-gate 	return (keysched);
898*0Sstevel@tonic-gate }
899*0Sstevel@tonic-gate 
900*0Sstevel@tonic-gate /*
901*0Sstevel@tonic-gate  * Replace the LSB of each byte by the xor of the other
902*0Sstevel@tonic-gate  * 7 bits.  The tricky thing is that the original contents of the LSBs
903*0Sstevel@tonic-gate  * are nullifed by including them twice in the xor computation.
904*0Sstevel@tonic-gate  */
905*0Sstevel@tonic-gate static void
906*0Sstevel@tonic-gate fix_des_parity(uint64_t *keyp)
907*0Sstevel@tonic-gate {
908*0Sstevel@tonic-gate /* EXPORT DELETE START */
909*0Sstevel@tonic-gate 	uint64_t k = *keyp;
910*0Sstevel@tonic-gate 	k ^= k >> 1;
911*0Sstevel@tonic-gate 	k ^= k >> 2;
912*0Sstevel@tonic-gate 	k ^= k >> 4;
913*0Sstevel@tonic-gate 	*keyp ^= (k & 0x0101010101010101LL);
914*0Sstevel@tonic-gate /* EXPORT DELETE END */
915*0Sstevel@tonic-gate }
916