xref: /illumos-gate/usr/src/common/crypto/des/des_impl.c (revision 0173c38a73f34277e0c97a19fedfd25d81ba8380)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/types.h>
29 #include <sys/systm.h>
30 #include <sys/ddi.h>
31 #include <sys/sysmacros.h>
32 #include <sys/strsun.h>
33 #include <sys/note.h>
34 #include <sys/crypto/common.h>
35 #include "des_impl.h"
36 #ifndef	_KERNEL
37 #include <strings.h>
38 #include <stdlib.h>
39 #endif	/* !_KERNEL */
40 
41 /* EXPORT DELETE START */
42 
43 typedef struct keysched_s {
44 	uint64_t ksch_encrypt[16];
45 	uint64_t ksch_decrypt[16];
46 } keysched_t;
47 
48 typedef struct keysched3_s {
49 	uint64_t ksch_encrypt[48];
50 	uint64_t ksch_decrypt[48];
51 } keysched3_t;
52 
53 static void fix_des_parity(uint64_t *);
54 
55 #ifndef sun4u
56 
57 static const uint64_t sbox_table[8][64]=
58 {
59 /* BEGIN CSTYLED */
60 {
61 0x0000140140020000ULL, 0x0000000000000000ULL, 0x0000000140000000ULL, 0x0000140140020020ULL,
62 0x0000140140000020ULL, 0x0000000140020020ULL, 0x0000000000000020ULL, 0x0000000140000000ULL,
63 0x0000000000020000ULL, 0x0000140140020000ULL, 0x0000140140020020ULL, 0x0000000000020000ULL,
64 0x0000140000020020ULL, 0x0000140140000020ULL, 0x0000140000000000ULL, 0x0000000000000020ULL,
65 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000140020000ULL,
66 0x0000000140020000ULL, 0x0000140140000000ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
67 0x0000000140000020ULL, 0x0000140000000020ULL, 0x0000140000000020ULL, 0x0000000140000020ULL,
68 0x0000000000000000ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140000000000ULL,
69 0x0000000140000000ULL, 0x0000140140020020ULL, 0x0000000000000020ULL, 0x0000140140000000ULL,
70 0x0000140140020000ULL, 0x0000140000000000ULL, 0x0000140000000000ULL, 0x0000000000020000ULL,
71 0x0000140140000020ULL, 0x0000000140000000ULL, 0x0000000140020000ULL, 0x0000140000000020ULL,
72 0x0000000000020000ULL, 0x0000000000000020ULL, 0x0000140000020020ULL, 0x0000000140020020ULL,
73 0x0000140140020020ULL, 0x0000000140000020ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
74 0x0000140000000020ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140140020000ULL,
75 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000000000000ULL,
76 0x0000000140000020ULL, 0x0000000140020000ULL, 0x0000000000000000ULL, 0x0000140140000020ULL
77 },
78 {
79 0x2000005020000500ULL, 0x2000000020000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL,
80 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL, 0x2000000020000500ULL,
81 0x2000000000000500ULL, 0x2000005020000500ULL, 0x2000005020000000ULL, 0x2000000000000000ULL,
82 0x2000000020000000ULL, 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL,
83 0x0000005020000000ULL, 0x0000005000000500ULL, 0x2000000020000500ULL, 0x0000000000000000ULL,
84 0x2000000000000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL, 0x2000005000000000ULL,
85 0x0000005000000500ULL, 0x2000000000000500ULL, 0x0000000000000000ULL, 0x0000005020000000ULL,
86 0x0000000020000500ULL, 0x2000005020000000ULL, 0x2000005000000000ULL, 0x0000000020000500ULL,
87 0x0000000000000000ULL, 0x0000005020000500ULL, 0x2000005000000500ULL, 0x0000005000000000ULL,
88 0x2000000020000500ULL, 0x2000005000000000ULL, 0x2000005020000000ULL, 0x0000000020000000ULL,
89 0x2000005000000000ULL, 0x2000000020000000ULL, 0x0000000000000500ULL, 0x2000005020000500ULL,
90 0x0000005020000500ULL, 0x0000000000000500ULL, 0x0000000020000000ULL, 0x2000000000000000ULL,
91 0x0000000020000500ULL, 0x2000005020000000ULL, 0x0000005000000000ULL, 0x2000000000000500ULL,
92 0x0000005000000500ULL, 0x2000000020000500ULL, 0x2000000000000500ULL, 0x0000005000000500ULL,
93 0x0000005020000000ULL, 0x0000000000000000ULL, 0x2000000020000000ULL, 0x0000000020000500ULL,
94 0x2000000000000000ULL, 0x2000005000000500ULL, 0x2000005020000500ULL, 0x0000005020000000ULL
95 },
96 {
97 0x0000000000014040ULL, 0x0000800280014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
98 0x0000800000014000ULL, 0x0000000000000000ULL, 0x0000000280014040ULL, 0x0000800000014000ULL,
99 0x0000000280000040ULL, 0x0000800000000040ULL, 0x0000800000000040ULL, 0x0000000280000000ULL,
100 0x0000800280014040ULL, 0x0000000280000040ULL, 0x0000800280000000ULL, 0x0000000000014040ULL,
101 0x0000800000000000ULL, 0x0000000000000040ULL, 0x0000800280014000ULL, 0x0000000000014000ULL,
102 0x0000000280014000ULL, 0x0000800280000000ULL, 0x0000800280000040ULL, 0x0000000280014040ULL,
103 0x0000800000014040ULL, 0x0000000280014000ULL, 0x0000000280000000ULL, 0x0000800000014040ULL,
104 0x0000000000000040ULL, 0x0000800280014040ULL, 0x0000000000014000ULL, 0x0000800000000000ULL,
105 0x0000800280014000ULL, 0x0000800000000000ULL, 0x0000000280000040ULL, 0x0000000000014040ULL,
106 0x0000000280000000ULL, 0x0000800280014000ULL, 0x0000800000014000ULL, 0x0000000000000000ULL,
107 0x0000000000014000ULL, 0x0000000280000040ULL, 0x0000800280014040ULL, 0x0000800000014000ULL,
108 0x0000800000000040ULL, 0x0000000000014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
109 0x0000800000014040ULL, 0x0000000280000000ULL, 0x0000800000000000ULL, 0x0000800280014040ULL,
110 0x0000000000000040ULL, 0x0000000280014040ULL, 0x0000000280014000ULL, 0x0000800000000040ULL,
111 0x0000800280000000ULL, 0x0000800000014040ULL, 0x0000000000014040ULL, 0x0000800280000000ULL,
112 0x0000000280014040ULL, 0x0000000000000040ULL, 0x0000800280000040ULL, 0x0000000280014000ULL
113 },
114 {
115 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
116 0x0000020008101000ULL, 0x4000020000001008ULL, 0x4000020000000008ULL, 0x4000000008100008ULL,
117 0x0000000000000000ULL, 0x0000020008100000ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
118 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000020000001000ULL, 0x4000020000000008ULL,
119 0x4000000000000008ULL, 0x0000000008100000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
120 0x0000000000001000ULL, 0x0000020000000000ULL, 0x4000000008100008ULL, 0x0000000008101000ULL,
121 0x4000020000001008ULL, 0x4000000000000008ULL, 0x0000000008101000ULL, 0x0000020000001000ULL,
122 0x0000000008100000ULL, 0x0000020008101000ULL, 0x4000020008101008ULL, 0x4000000000001008ULL,
123 0x0000020000001000ULL, 0x4000020000000008ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
124 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000020008100000ULL,
125 0x0000000008101000ULL, 0x0000020000001000ULL, 0x4000020000001008ULL, 0x4000000000000008ULL,
126 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
127 0x4000020008101008ULL, 0x4000000000001008ULL, 0x4000000000000008ULL, 0x0000000008100000ULL,
128 0x4000020000000008ULL, 0x4000000008100008ULL, 0x0000020008101000ULL, 0x4000020000001008ULL,
129 0x4000000008100008ULL, 0x0000000008101000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
130 0x0000000000001000ULL, 0x0000020000000000ULL, 0x0000000008100000ULL, 0x0000020008101000ULL
131 },
132 {
133 0x000000000000a000ULL, 0x000028080000a000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL,
134 0x0000000800000000ULL, 0x000000000000a000ULL, 0x1000000000000000ULL, 0x0000280800000000ULL,
135 0x100000080000a000ULL, 0x0000000800000000ULL, 0x000028000000a000ULL, 0x100000080000a000ULL,
136 0x100028000000a000ULL, 0x1000280800000000ULL, 0x000000080000a000ULL, 0x1000000000000000ULL,
137 0x0000280000000000ULL, 0x1000000800000000ULL, 0x1000000800000000ULL, 0x0000000000000000ULL,
138 0x100000000000a000ULL, 0x100028080000a000ULL, 0x100028080000a000ULL, 0x000028000000a000ULL,
139 0x1000280800000000ULL, 0x100000000000a000ULL, 0x0000000000000000ULL, 0x1000280000000000ULL,
140 0x000028080000a000ULL, 0x0000280000000000ULL, 0x1000280000000000ULL, 0x000000080000a000ULL,
141 0x0000000800000000ULL, 0x100028000000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL,
142 0x1000000000000000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL, 0x100000080000a000ULL,
143 0x000028000000a000ULL, 0x1000000000000000ULL, 0x1000280800000000ULL, 0x000028080000a000ULL,
144 0x100000080000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL, 0x1000280800000000ULL,
145 0x100028080000a000ULL, 0x000000080000a000ULL, 0x1000280000000000ULL, 0x100028080000a000ULL,
146 0x0000280800000000ULL, 0x0000000000000000ULL, 0x1000000800000000ULL, 0x1000280000000000ULL,
147 0x000000080000a000ULL, 0x000028000000a000ULL, 0x100000000000a000ULL, 0x0000000800000000ULL,
148 0x0000000000000000ULL, 0x1000000800000000ULL, 0x000028080000a000ULL, 0x100000000000a000ULL
149 },
150 {
151 0x0802000000000280ULL, 0x0802010000000000ULL, 0x0000000010000000ULL, 0x0802010010000280ULL,
152 0x0802010000000000ULL, 0x0000000000000280ULL, 0x0802010010000280ULL, 0x0000010000000000ULL,
153 0x0802000010000000ULL, 0x0000010010000280ULL, 0x0000010000000000ULL, 0x0802000000000280ULL,
154 0x0000010000000280ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
155 0x0000000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000010000000ULL,
156 0x0000010010000000ULL, 0x0802000010000280ULL, 0x0000000000000280ULL, 0x0802010000000280ULL,
157 0x0802010000000280ULL, 0x0000000000000000ULL, 0x0000010010000280ULL, 0x0802010010000000ULL,
158 0x0000000010000280ULL, 0x0000010010000000ULL, 0x0802010010000000ULL, 0x0802000000000000ULL,
159 0x0802000010000000ULL, 0x0000000000000280ULL, 0x0802010000000280ULL, 0x0000010010000000ULL,
160 0x0802010010000280ULL, 0x0000010000000000ULL, 0x0000000010000280ULL, 0x0802000000000280ULL,
161 0x0000010000000000ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
162 0x0802000000000280ULL, 0x0802010010000280ULL, 0x0000010010000000ULL, 0x0802010000000000ULL,
163 0x0000010010000280ULL, 0x0802010010000000ULL, 0x0000000000000000ULL, 0x0802010000000280ULL,
164 0x0000000000000280ULL, 0x0000000010000000ULL, 0x0802010000000000ULL, 0x0000010010000280ULL,
165 0x0000000010000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000000000000ULL,
166 0x0802010010000000ULL, 0x0802000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL
167 },
168 {
169 0x000000a000000000ULL, 0x800040a000000010ULL, 0x8000400000040010ULL, 0x0000000000000000ULL,
170 0x0000000000040000ULL, 0x8000400000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
171 0x800040a000040010ULL, 0x000000a000000000ULL, 0x0000000000000000ULL, 0x8000400000000010ULL,
172 0x8000000000000010ULL, 0x0000400000000000ULL, 0x800040a000000010ULL, 0x8000000000040010ULL,
173 0x0000400000040000ULL, 0x800000a000040010ULL, 0x800000a000000010ULL, 0x0000400000040000ULL,
174 0x8000400000000010ULL, 0x000040a000000000ULL, 0x000040a000040000ULL, 0x800000a000000010ULL,
175 0x000040a000000000ULL, 0x0000000000040000ULL, 0x8000000000040010ULL, 0x800040a000040010ULL,
176 0x000000a000040000ULL, 0x8000000000000010ULL, 0x0000400000000000ULL, 0x000000a000040000ULL,
177 0x0000400000000000ULL, 0x000000a000040000ULL, 0x000000a000000000ULL, 0x8000400000040010ULL,
178 0x8000400000040010ULL, 0x800040a000000010ULL, 0x800040a000000010ULL, 0x8000000000000010ULL,
179 0x800000a000000010ULL, 0x0000400000000000ULL, 0x0000400000040000ULL, 0x000000a000000000ULL,
180 0x000040a000040000ULL, 0x8000000000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
181 0x8000000000040010ULL, 0x8000400000000010ULL, 0x800040a000040010ULL, 0x000040a000000000ULL,
182 0x000000a000040000ULL, 0x0000000000000000ULL, 0x8000000000000010ULL, 0x800040a000040010ULL,
183 0x0000000000000000ULL, 0x800000a000040010ULL, 0x000040a000000000ULL, 0x0000000000040000ULL,
184 0x8000400000000010ULL, 0x0000400000040000ULL, 0x0000000000040000ULL, 0x800000a000000010ULL
185 },
186 {
187 0x0401000004080800ULL, 0x0000000004080000ULL, 0x0000000400000000ULL, 0x0401000404080800ULL,
188 0x0401000000000000ULL, 0x0401000004080800ULL, 0x0000000000000800ULL, 0x0401000000000000ULL,
189 0x0000000400000800ULL, 0x0401000400000000ULL, 0x0401000404080800ULL, 0x0000000404080000ULL,
190 0x0401000404080000ULL, 0x0000000404080800ULL, 0x0000000004080000ULL, 0x0000000000000800ULL,
191 0x0401000400000000ULL, 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000004080800ULL,
192 0x0000000404080000ULL, 0x0000000400000800ULL, 0x0401000400000800ULL, 0x0401000404080000ULL,
193 0x0000000004080800ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0401000400000800ULL,
194 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000404080800ULL, 0x0000000400000000ULL,
195 0x0000000404080800ULL, 0x0000000400000000ULL, 0x0401000404080000ULL, 0x0000000004080000ULL,
196 0x0000000000000800ULL, 0x0401000400000800ULL, 0x0000000004080000ULL, 0x0000000404080800ULL,
197 0x0401000004080000ULL, 0x0000000000000800ULL, 0x0401000000000800ULL, 0x0401000400000000ULL,
198 0x0401000400000800ULL, 0x0401000000000000ULL, 0x0000000400000000ULL, 0x0401000004080800ULL,
199 0x0000000000000000ULL, 0x0401000404080800ULL, 0x0000000400000800ULL, 0x0401000000000800ULL,
200 0x0401000400000000ULL, 0x0401000004080000ULL, 0x0401000004080800ULL, 0x0000000000000000ULL,
201 0x0401000404080800ULL, 0x0000000404080000ULL, 0x0000000404080000ULL, 0x0000000004080800ULL,
202 0x0000000004080800ULL, 0x0000000400000800ULL, 0x0401000000000000ULL, 0x0401000404080000ULL
203 }
204 /* END CSTYLED */
205 };
206 
207 
208 static const uint64_t ip_table[2][256]=
209 {
210 /* BEGIN CSTYLED */
211 {
212 0x0000000000000000ULL, 0x0000000000000400ULL, 0x0080000000000280ULL, 0x0080000000000680ULL,
213 0x0000000000400000ULL, 0x0000000000400400ULL, 0x0080000000400280ULL, 0x0080000000400680ULL,
214 0x0000000000280000ULL, 0x0000000000280400ULL, 0x0080000000280280ULL, 0x0080000000280680ULL,
215 0x0000000000680000ULL, 0x0000000000680400ULL, 0x0080000000680280ULL, 0x0080000000680680ULL,
216 0x0000000400000000ULL, 0x0000000400000400ULL, 0x0080000400000280ULL, 0x0080000400000680ULL,
217 0x0000000400400000ULL, 0x0000000400400400ULL, 0x0080000400400280ULL, 0x0080000400400680ULL,
218 0x0000000400280000ULL, 0x0000000400280400ULL, 0x0080000400280280ULL, 0x0080000400280680ULL,
219 0x0000000400680000ULL, 0x0000000400680400ULL, 0x0080000400680280ULL, 0x0080000400680680ULL,
220 0x0000000280000000ULL, 0x0000000280000400ULL, 0x0080000280000280ULL, 0x0080000280000680ULL,
221 0x0000000280400000ULL, 0x0000000280400400ULL, 0x0080000280400280ULL, 0x0080000280400680ULL,
222 0x0000000280280000ULL, 0x0000000280280400ULL, 0x0080000280280280ULL, 0x0080000280280680ULL,
223 0x0000000280680000ULL, 0x0000000280680400ULL, 0x0080000280680280ULL, 0x0080000280680680ULL,
224 0x0000000680000000ULL, 0x0000000680000400ULL, 0x0080000680000280ULL, 0x0080000680000680ULL,
225 0x0000000680400000ULL, 0x0000000680400400ULL, 0x0080000680400280ULL, 0x0080000680400680ULL,
226 0x0000000680280000ULL, 0x0000000680280400ULL, 0x0080000680280280ULL, 0x0080000680280680ULL,
227 0x0000000680680000ULL, 0x0000000680680400ULL, 0x0080000680680280ULL, 0x0080000680680680ULL,
228 0x0000400000000000ULL, 0x0000400000000400ULL, 0x0080400000000280ULL, 0x0080400000000680ULL,
229 0x0000400000400000ULL, 0x0000400000400400ULL, 0x0080400000400280ULL, 0x0080400000400680ULL,
230 0x0000400000280000ULL, 0x0000400000280400ULL, 0x0080400000280280ULL, 0x0080400000280680ULL,
231 0x0000400000680000ULL, 0x0000400000680400ULL, 0x0080400000680280ULL, 0x0080400000680680ULL,
232 0x0000400400000000ULL, 0x0000400400000400ULL, 0x0080400400000280ULL, 0x0080400400000680ULL,
233 0x0000400400400000ULL, 0x0000400400400400ULL, 0x0080400400400280ULL, 0x0080400400400680ULL,
234 0x0000400400280000ULL, 0x0000400400280400ULL, 0x0080400400280280ULL, 0x0080400400280680ULL,
235 0x0000400400680000ULL, 0x0000400400680400ULL, 0x0080400400680280ULL, 0x0080400400680680ULL,
236 0x0000400280000000ULL, 0x0000400280000400ULL, 0x0080400280000280ULL, 0x0080400280000680ULL,
237 0x0000400280400000ULL, 0x0000400280400400ULL, 0x0080400280400280ULL, 0x0080400280400680ULL,
238 0x0000400280280000ULL, 0x0000400280280400ULL, 0x0080400280280280ULL, 0x0080400280280680ULL,
239 0x0000400280680000ULL, 0x0000400280680400ULL, 0x0080400280680280ULL, 0x0080400280680680ULL,
240 0x0000400680000000ULL, 0x0000400680000400ULL, 0x0080400680000280ULL, 0x0080400680000680ULL,
241 0x0000400680400000ULL, 0x0000400680400400ULL, 0x0080400680400280ULL, 0x0080400680400680ULL,
242 0x0000400680280000ULL, 0x0000400680280400ULL, 0x0080400680280280ULL, 0x0080400680280680ULL,
243 0x0000400680680000ULL, 0x0000400680680400ULL, 0x0080400680680280ULL, 0x0080400680680680ULL,
244 0x0000280000000000ULL, 0x0000280000000400ULL, 0x0080280000000280ULL, 0x0080280000000680ULL,
245 0x0000280000400000ULL, 0x0000280000400400ULL, 0x0080280000400280ULL, 0x0080280000400680ULL,
246 0x0000280000280000ULL, 0x0000280000280400ULL, 0x0080280000280280ULL, 0x0080280000280680ULL,
247 0x0000280000680000ULL, 0x0000280000680400ULL, 0x0080280000680280ULL, 0x0080280000680680ULL,
248 0x0000280400000000ULL, 0x0000280400000400ULL, 0x0080280400000280ULL, 0x0080280400000680ULL,
249 0x0000280400400000ULL, 0x0000280400400400ULL, 0x0080280400400280ULL, 0x0080280400400680ULL,
250 0x0000280400280000ULL, 0x0000280400280400ULL, 0x0080280400280280ULL, 0x0080280400280680ULL,
251 0x0000280400680000ULL, 0x0000280400680400ULL, 0x0080280400680280ULL, 0x0080280400680680ULL,
252 0x0000280280000000ULL, 0x0000280280000400ULL, 0x0080280280000280ULL, 0x0080280280000680ULL,
253 0x0000280280400000ULL, 0x0000280280400400ULL, 0x0080280280400280ULL, 0x0080280280400680ULL,
254 0x0000280280280000ULL, 0x0000280280280400ULL, 0x0080280280280280ULL, 0x0080280280280680ULL,
255 0x0000280280680000ULL, 0x0000280280680400ULL, 0x0080280280680280ULL, 0x0080280280680680ULL,
256 0x0000280680000000ULL, 0x0000280680000400ULL, 0x0080280680000280ULL, 0x0080280680000680ULL,
257 0x0000280680400000ULL, 0x0000280680400400ULL, 0x0080280680400280ULL, 0x0080280680400680ULL,
258 0x0000280680280000ULL, 0x0000280680280400ULL, 0x0080280680280280ULL, 0x0080280680280680ULL,
259 0x0000280680680000ULL, 0x0000280680680400ULL, 0x0080280680680280ULL, 0x0080280680680680ULL,
260 0x0000680000000000ULL, 0x0000680000000400ULL, 0x0080680000000280ULL, 0x0080680000000680ULL,
261 0x0000680000400000ULL, 0x0000680000400400ULL, 0x0080680000400280ULL, 0x0080680000400680ULL,
262 0x0000680000280000ULL, 0x0000680000280400ULL, 0x0080680000280280ULL, 0x0080680000280680ULL,
263 0x0000680000680000ULL, 0x0000680000680400ULL, 0x0080680000680280ULL, 0x0080680000680680ULL,
264 0x0000680400000000ULL, 0x0000680400000400ULL, 0x0080680400000280ULL, 0x0080680400000680ULL,
265 0x0000680400400000ULL, 0x0000680400400400ULL, 0x0080680400400280ULL, 0x0080680400400680ULL,
266 0x0000680400280000ULL, 0x0000680400280400ULL, 0x0080680400280280ULL, 0x0080680400280680ULL,
267 0x0000680400680000ULL, 0x0000680400680400ULL, 0x0080680400680280ULL, 0x0080680400680680ULL,
268 0x0000680280000000ULL, 0x0000680280000400ULL, 0x0080680280000280ULL, 0x0080680280000680ULL,
269 0x0000680280400000ULL, 0x0000680280400400ULL, 0x0080680280400280ULL, 0x0080680280400680ULL,
270 0x0000680280280000ULL, 0x0000680280280400ULL, 0x0080680280280280ULL, 0x0080680280280680ULL,
271 0x0000680280680000ULL, 0x0000680280680400ULL, 0x0080680280680280ULL, 0x0080680280680680ULL,
272 0x0000680680000000ULL, 0x0000680680000400ULL, 0x0080680680000280ULL, 0x0080680680000680ULL,
273 0x0000680680400000ULL, 0x0000680680400400ULL, 0x0080680680400280ULL, 0x0080680680400680ULL,
274 0x0000680680280000ULL, 0x0000680680280400ULL, 0x0080680680280280ULL, 0x0080680680280680ULL,
275 0x0000680680680000ULL, 0x0000680680680400ULL, 0x0080680680680280ULL, 0x0080680680680680ULL
276 },
277 {
278 0x0000000000000000ULL, 0x0000000000005000ULL, 0x0000000000000800ULL, 0x0000000000005800ULL,
279 0x0000000005000000ULL, 0x0000000005005000ULL, 0x0000000005000800ULL, 0x0000000005005800ULL,
280 0x0000000000800000ULL, 0x0000000000805000ULL, 0x0000000000800800ULL, 0x0000000000805800ULL,
281 0x0000000005800000ULL, 0x0000000005805000ULL, 0x0000000005800800ULL, 0x0000000005805800ULL,
282 0x0000005000000000ULL, 0x0000005000005000ULL, 0x0000005000000800ULL, 0x0000005000005800ULL,
283 0x0000005005000000ULL, 0x0000005005005000ULL, 0x0000005005000800ULL, 0x0000005005005800ULL,
284 0x0000005000800000ULL, 0x0000005000805000ULL, 0x0000005000800800ULL, 0x0000005000805800ULL,
285 0x0000005005800000ULL, 0x0000005005805000ULL, 0x0000005005800800ULL, 0x0000005005805800ULL,
286 0x0000000800000000ULL, 0x0000000800005000ULL, 0x0000000800000800ULL, 0x0000000800005800ULL,
287 0x0000000805000000ULL, 0x0000000805005000ULL, 0x0000000805000800ULL, 0x0000000805005800ULL,
288 0x0000000800800000ULL, 0x0000000800805000ULL, 0x0000000800800800ULL, 0x0000000800805800ULL,
289 0x0000000805800000ULL, 0x0000000805805000ULL, 0x0000000805800800ULL, 0x0000000805805800ULL,
290 0x0000005800000000ULL, 0x0000005800005000ULL, 0x0000005800000800ULL, 0x0000005800005800ULL,
291 0x0000005805000000ULL, 0x0000005805005000ULL, 0x0000005805000800ULL, 0x0000005805005800ULL,
292 0x0000005800800000ULL, 0x0000005800805000ULL, 0x0000005800800800ULL, 0x0000005800805800ULL,
293 0x0000005805800000ULL, 0x0000005805805000ULL, 0x0000005805800800ULL, 0x0000005805805800ULL,
294 0x0005000000000004ULL, 0x0005000000005004ULL, 0x0005000000000804ULL, 0x0005000000005804ULL,
295 0x0005000005000004ULL, 0x0005000005005004ULL, 0x0005000005000804ULL, 0x0005000005005804ULL,
296 0x0005000000800004ULL, 0x0005000000805004ULL, 0x0005000000800804ULL, 0x0005000000805804ULL,
297 0x0005000005800004ULL, 0x0005000005805004ULL, 0x0005000005800804ULL, 0x0005000005805804ULL,
298 0x0005005000000004ULL, 0x0005005000005004ULL, 0x0005005000000804ULL, 0x0005005000005804ULL,
299 0x0005005005000004ULL, 0x0005005005005004ULL, 0x0005005005000804ULL, 0x0005005005005804ULL,
300 0x0005005000800004ULL, 0x0005005000805004ULL, 0x0005005000800804ULL, 0x0005005000805804ULL,
301 0x0005005005800004ULL, 0x0005005005805004ULL, 0x0005005005800804ULL, 0x0005005005805804ULL,
302 0x0005000800000004ULL, 0x0005000800005004ULL, 0x0005000800000804ULL, 0x0005000800005804ULL,
303 0x0005000805000004ULL, 0x0005000805005004ULL, 0x0005000805000804ULL, 0x0005000805005804ULL,
304 0x0005000800800004ULL, 0x0005000800805004ULL, 0x0005000800800804ULL, 0x0005000800805804ULL,
305 0x0005000805800004ULL, 0x0005000805805004ULL, 0x0005000805800804ULL, 0x0005000805805804ULL,
306 0x0005005800000004ULL, 0x0005005800005004ULL, 0x0005005800000804ULL, 0x0005005800005804ULL,
307 0x0005005805000004ULL, 0x0005005805005004ULL, 0x0005005805000804ULL, 0x0005005805005804ULL,
308 0x0005005800800004ULL, 0x0005005800805004ULL, 0x0005005800800804ULL, 0x0005005800805804ULL,
309 0x0005005805800004ULL, 0x0005005805805004ULL, 0x0005005805800804ULL, 0x0005005805805804ULL,
310 0x0000800000000000ULL, 0x0000800000005000ULL, 0x0000800000000800ULL, 0x0000800000005800ULL,
311 0x0000800005000000ULL, 0x0000800005005000ULL, 0x0000800005000800ULL, 0x0000800005005800ULL,
312 0x0000800000800000ULL, 0x0000800000805000ULL, 0x0000800000800800ULL, 0x0000800000805800ULL,
313 0x0000800005800000ULL, 0x0000800005805000ULL, 0x0000800005800800ULL, 0x0000800005805800ULL,
314 0x0000805000000000ULL, 0x0000805000005000ULL, 0x0000805000000800ULL, 0x0000805000005800ULL,
315 0x0000805005000000ULL, 0x0000805005005000ULL, 0x0000805005000800ULL, 0x0000805005005800ULL,
316 0x0000805000800000ULL, 0x0000805000805000ULL, 0x0000805000800800ULL, 0x0000805000805800ULL,
317 0x0000805005800000ULL, 0x0000805005805000ULL, 0x0000805005800800ULL, 0x0000805005805800ULL,
318 0x0000800800000000ULL, 0x0000800800005000ULL, 0x0000800800000800ULL, 0x0000800800005800ULL,
319 0x0000800805000000ULL, 0x0000800805005000ULL, 0x0000800805000800ULL, 0x0000800805005800ULL,
320 0x0000800800800000ULL, 0x0000800800805000ULL, 0x0000800800800800ULL, 0x0000800800805800ULL,
321 0x0000800805800000ULL, 0x0000800805805000ULL, 0x0000800805800800ULL, 0x0000800805805800ULL,
322 0x0000805800000000ULL, 0x0000805800005000ULL, 0x0000805800000800ULL, 0x0000805800005800ULL,
323 0x0000805805000000ULL, 0x0000805805005000ULL, 0x0000805805000800ULL, 0x0000805805005800ULL,
324 0x0000805800800000ULL, 0x0000805800805000ULL, 0x0000805800800800ULL, 0x0000805800805800ULL,
325 0x0000805805800000ULL, 0x0000805805805000ULL, 0x0000805805800800ULL, 0x0000805805805800ULL,
326 0x0005800000000004ULL, 0x0005800000005004ULL, 0x0005800000000804ULL, 0x0005800000005804ULL,
327 0x0005800005000004ULL, 0x0005800005005004ULL, 0x0005800005000804ULL, 0x0005800005005804ULL,
328 0x0005800000800004ULL, 0x0005800000805004ULL, 0x0005800000800804ULL, 0x0005800000805804ULL,
329 0x0005800005800004ULL, 0x0005800005805004ULL, 0x0005800005800804ULL, 0x0005800005805804ULL,
330 0x0005805000000004ULL, 0x0005805000005004ULL, 0x0005805000000804ULL, 0x0005805000005804ULL,
331 0x0005805005000004ULL, 0x0005805005005004ULL, 0x0005805005000804ULL, 0x0005805005005804ULL,
332 0x0005805000800004ULL, 0x0005805000805004ULL, 0x0005805000800804ULL, 0x0005805000805804ULL,
333 0x0005805005800004ULL, 0x0005805005805004ULL, 0x0005805005800804ULL, 0x0005805005805804ULL,
334 0x0005800800000004ULL, 0x0005800800005004ULL, 0x0005800800000804ULL, 0x0005800800005804ULL,
335 0x0005800805000004ULL, 0x0005800805005004ULL, 0x0005800805000804ULL, 0x0005800805005804ULL,
336 0x0005800800800004ULL, 0x0005800800805004ULL, 0x0005800800800804ULL, 0x0005800800805804ULL,
337 0x0005800805800004ULL, 0x0005800805805004ULL, 0x0005800805800804ULL, 0x0005800805805804ULL,
338 0x0005805800000004ULL, 0x0005805800005004ULL, 0x0005805800000804ULL, 0x0005805800005804ULL,
339 0x0005805805000004ULL, 0x0005805805005004ULL, 0x0005805805000804ULL, 0x0005805805005804ULL,
340 0x0005805800800004ULL, 0x0005805800805004ULL, 0x0005805800800804ULL, 0x0005805800805804ULL,
341 0x0005805805800004ULL, 0x0005805805805004ULL, 0x0005805805800804ULL, 0x0005805805805804ULL
342 }
343 /* END CSTYLED */
344 };
345 
346 static const uint32_t fp_table[256]=
347 {
348 0x00000000, 0x80000000, 0x00800000, 0x80800000,
349 0x00008000, 0x80008000, 0x00808000, 0x80808000,
350 0x00000080, 0x80000080, 0x00800080, 0x80800080,
351 0x00008080, 0x80008080, 0x00808080, 0x80808080,
352 0x40000000, 0xc0000000, 0x40800000, 0xc0800000,
353 0x40008000, 0xc0008000, 0x40808000, 0xc0808000,
354 0x40000080, 0xc0000080, 0x40800080, 0xc0800080,
355 0x40008080, 0xc0008080, 0x40808080, 0xc0808080,
356 0x00400000, 0x80400000, 0x00c00000, 0x80c00000,
357 0x00408000, 0x80408000, 0x00c08000, 0x80c08000,
358 0x00400080, 0x80400080, 0x00c00080, 0x80c00080,
359 0x00408080, 0x80408080, 0x00c08080, 0x80c08080,
360 0x40400000, 0xc0400000, 0x40c00000, 0xc0c00000,
361 0x40408000, 0xc0408000, 0x40c08000, 0xc0c08000,
362 0x40400080, 0xc0400080, 0x40c00080, 0xc0c00080,
363 0x40408080, 0xc0408080, 0x40c08080, 0xc0c08080,
364 0x00004000, 0x80004000, 0x00804000, 0x80804000,
365 0x0000c000, 0x8000c000, 0x0080c000, 0x8080c000,
366 0x00004080, 0x80004080, 0x00804080, 0x80804080,
367 0x0000c080, 0x8000c080, 0x0080c080, 0x8080c080,
368 0x40004000, 0xc0004000, 0x40804000, 0xc0804000,
369 0x4000c000, 0xc000c000, 0x4080c000, 0xc080c000,
370 0x40004080, 0xc0004080, 0x40804080, 0xc0804080,
371 0x4000c080, 0xc000c080, 0x4080c080, 0xc080c080,
372 0x00404000, 0x80404000, 0x00c04000, 0x80c04000,
373 0x0040c000, 0x8040c000, 0x00c0c000, 0x80c0c000,
374 0x00404080, 0x80404080, 0x00c04080, 0x80c04080,
375 0x0040c080, 0x8040c080, 0x00c0c080, 0x80c0c080,
376 0x40404000, 0xc0404000, 0x40c04000, 0xc0c04000,
377 0x4040c000, 0xc040c000, 0x40c0c000, 0xc0c0c000,
378 0x40404080, 0xc0404080, 0x40c04080, 0xc0c04080,
379 0x4040c080, 0xc040c080, 0x40c0c080, 0xc0c0c080,
380 0x00000040, 0x80000040, 0x00800040, 0x80800040,
381 0x00008040, 0x80008040, 0x00808040, 0x80808040,
382 0x000000c0, 0x800000c0, 0x008000c0, 0x808000c0,
383 0x000080c0, 0x800080c0, 0x008080c0, 0x808080c0,
384 0x40000040, 0xc0000040, 0x40800040, 0xc0800040,
385 0x40008040, 0xc0008040, 0x40808040, 0xc0808040,
386 0x400000c0, 0xc00000c0, 0x408000c0, 0xc08000c0,
387 0x400080c0, 0xc00080c0, 0x408080c0, 0xc08080c0,
388 0x00400040, 0x80400040, 0x00c00040, 0x80c00040,
389 0x00408040, 0x80408040, 0x00c08040, 0x80c08040,
390 0x004000c0, 0x804000c0, 0x00c000c0, 0x80c000c0,
391 0x004080c0, 0x804080c0, 0x00c080c0, 0x80c080c0,
392 0x40400040, 0xc0400040, 0x40c00040, 0xc0c00040,
393 0x40408040, 0xc0408040, 0x40c08040, 0xc0c08040,
394 0x404000c0, 0xc04000c0, 0x40c000c0, 0xc0c000c0,
395 0x404080c0, 0xc04080c0, 0x40c080c0, 0xc0c080c0,
396 0x00004040, 0x80004040, 0x00804040, 0x80804040,
397 0x0000c040, 0x8000c040, 0x0080c040, 0x8080c040,
398 0x000040c0, 0x800040c0, 0x008040c0, 0x808040c0,
399 0x0000c0c0, 0x8000c0c0, 0x0080c0c0, 0x8080c0c0,
400 0x40004040, 0xc0004040, 0x40804040, 0xc0804040,
401 0x4000c040, 0xc000c040, 0x4080c040, 0xc080c040,
402 0x400040c0, 0xc00040c0, 0x408040c0, 0xc08040c0,
403 0x4000c0c0, 0xc000c0c0, 0x4080c0c0, 0xc080c0c0,
404 0x00404040, 0x80404040, 0x00c04040, 0x80c04040,
405 0x0040c040, 0x8040c040, 0x00c0c040, 0x80c0c040,
406 0x004040c0, 0x804040c0, 0x00c040c0, 0x80c040c0,
407 0x0040c0c0, 0x8040c0c0, 0x00c0c0c0, 0x80c0c0c0,
408 0x40404040, 0xc0404040, 0x40c04040, 0xc0c04040,
409 0x4040c040, 0xc040c040, 0x40c0c040, 0xc0c0c040,
410 0x404040c0, 0xc04040c0, 0x40c040c0, 0xc0c040c0,
411 0x4040c0c0, 0xc040c0c0, 0x40c0c0c0, 0xc0c0c0c0
412 };
413 
414 static const uint64_t all_a = 0xaaaaaaaaaaaaaaaaULL;
415 static const uint64_t all_5 = 0x5555555555555555ULL;
416 static const uint64_t top_1 = 0xfc000000000000ULL;
417 static const uint64_t mid_4 = 0x3fffffc000000ULL;
418 static const uint64_t low_3 = 0x3ffff00ULL;
419 
420 
421 static void
422 des_ip(uint64_t *l, uint64_t *r, uint64_t pt)
423 {
424 	uint64_t a, b;
425 
426 	a = pt & all_a;
427 	b = pt & all_5;
428 	a = a | (a << 7);
429 	b = b | (b >> 7);
430 
431 	b = (ip_table[0][(b >> 48) & 255ULL]) |
432 		(ip_table[1][(b >> 32) & 255ULL]) |
433 		(ip_table[0][(b >> 16) & 255ULL] << 6) |
434 		(ip_table[1][b & 255ULL] << 6);
435 
436 	a = (ip_table[0][(a >> 56) & 255]) |
437 		(ip_table[1][(a >> 40) & 255]) |
438 		(ip_table[0][(a >> 24) & 255] << 6) |
439 		(ip_table[1][(a >> 8) & 255] << 6);
440 
441 	*l = ((b & top_1) << 8) |
442 		(b & mid_4) |
443 		((b & low_3) >> 5);
444 
445 	*r = ((a & top_1) << 8) |
446 		(a & mid_4) |
447 		((a & low_3) >> 5);
448 }
449 
450 
451 static uint64_t
452 des_fp(uint64_t l, uint64_t r)
453 {
454 	uint32_t upper, lower;
455 
456 	lower = fp_table[((l >> 55) & 240) | ((r >> 59) & 15)] |
457 		(fp_table[((l >> 35) & 240) | ((r>>39) & 15)] >> 2) |
458 		(fp_table[((l >> 23) & 240) | ((r >> 27) & 15)] >> 4) |
459 		(fp_table[((l >> 6) & 240) | ((r >> 10) & 15)] >> 6);
460 
461 	upper = fp_table[((l >> 41) & 240) | ((r >> 45) & 15)] |
462 		(fp_table[((l >> 29) & 240) | ((r >> 33) & 15)] >> 2) |
463 		(fp_table[((l >> 12) & 240) | ((r >> 16) & 15)] >> 4) |
464 		(fp_table[(l & 240) | (r >> 4) & 15] >> 6);
465 
466 	return ((((uint64_t)upper) << 32) | (uint64_t)lower);
467 
468 }
469 
470 uint64_t
471 des_crypt_impl(uint64_t *ks, uint64_t block, int one_or_three)
472 {
473 	int i, j;
474 	uint64_t l, r, t;
475 
476 	des_ip(&l, &r, block);
477 	for (j = 0; j < one_or_three; j++) {
478 		for (i = j * 16; i < (j + 1) * 16; i++) {
479 			t = r ^ ks[i];
480 			t = sbox_table[0][t >> 58] |
481 				sbox_table[1][(t >> 44) & 63] |
482 				sbox_table[2][(t >> 38) & 63] |
483 				sbox_table[3][(t >> 32) & 63] |
484 				sbox_table[4][(t >> 26) & 63] |
485 				sbox_table[5][(t >> 15) & 63] |
486 				sbox_table[6][(t >> 9) & 63] |
487 				sbox_table[7][(t >> 3) & 63];
488 			t = t^l;
489 			l = r;
490 			r = t;
491 		}
492 		r = l;
493 		l = t;
494 	}
495 
496 	return (des_fp(l, r));
497 }
498 #endif /* !sun4u */
499 
500 /* EXPORT DELETE END */
501 
502 void
503 des3_crunch_block(void *cookie, uint8_t block[DES_BLOCK_LEN],
504     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
505 {
506 /* EXPORT DELETE START */
507 	keysched3_t *ksch = (keysched3_t *)cookie;
508 
509 	/*
510 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
511 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
512 	 * copies the block without reversing bytes.
513 	 */
514 #ifdef _BIG_ENDIAN
515 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
516 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
517 		if (decrypt == B_TRUE)
518 			/* LINTED */
519 			*(uint64_t *)out_block = des_crypt_impl(
520 			    ksch->ksch_decrypt,
521 			    /* LINTED */
522 			    *(uint64_t *)block, 3);
523 		else
524 			/* LINTED */
525 			*(uint64_t *)out_block = des_crypt_impl(
526 			    ksch->ksch_encrypt,
527 			    /* LINTED */
528 			    *(uint64_t *)block, 3);
529 	} else {
530 #endif
531 		uint64_t tmp;
532 
533 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
534 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
535 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
536 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
537 
538 		if (decrypt == B_TRUE)
539 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 3);
540 		else
541 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 3);
542 
543 		out_block[0] = tmp >> 56;
544 		out_block[1] = tmp >> 48;
545 		out_block[2] = tmp >> 40;
546 		out_block[3] = tmp >> 32;
547 		out_block[4] = tmp >> 24;
548 		out_block[5] = tmp >> 16;
549 		out_block[6] = tmp >> 8;
550 		out_block[7] = (uint8_t)tmp;
551 #ifdef _BIG_ENDIAN
552 	}
553 #endif
554 /* EXPORT DELETE END */
555 }
556 
557 void
558 des_crunch_block(void *cookie, uint8_t block[DES_BLOCK_LEN],
559     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
560 {
561 /* EXPORT DELETE START */
562 	keysched_t *ksch = (keysched_t *)cookie;
563 
564 	/*
565 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
566 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
567 	 * copies the block without reversing bytes.
568 	 */
569 #ifdef _BIG_ENDIAN
570 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
571 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
572 		if (decrypt == B_TRUE)
573 			/* LINTED */
574 			*(uint64_t *)out_block = des_crypt_impl(
575 			    ksch->ksch_decrypt,
576 			    /* LINTED */
577 			    *(uint64_t *)block, 1);
578 		else
579 			/* LINTED */
580 			*(uint64_t *)out_block = des_crypt_impl(
581 			    ksch->ksch_encrypt,
582 			    /* LINTED */
583 			    *(uint64_t *)block, 1);
584 
585 	} else {
586 #endif
587 		uint64_t tmp;
588 
589 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
590 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
591 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
592 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
593 
594 		if (decrypt == B_TRUE)
595 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 1);
596 		else
597 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 1);
598 
599 		out_block[0] = tmp >> 56;
600 		out_block[1] = tmp >> 48;
601 		out_block[2] = tmp >> 40;
602 		out_block[3] = tmp >> 32;
603 		out_block[4] = tmp >> 24;
604 		out_block[5] = tmp >> 16;
605 		out_block[6] = tmp >> 8;
606 		out_block[7] = (uint8_t)tmp;
607 #ifdef _BIG_ENDIAN
608 	}
609 #endif
610 /* EXPORT DELETE END */
611 }
612 
613 static boolean_t
614 keycheck(uint8_t *key, uint8_t *corrected_key)
615 {
616 /* EXPORT DELETE START */
617 	uint64_t key_so_far;
618 	uint_t i;
619 	/*
620 	 * Table of weak and semi-weak keys.  Fortunately, weak keys are
621 	 * endian-independent, and some semi-weak keys can be paired up in
622 	 * endian-opposite order.  Since keys are stored as uint64_t's,
623 	 * use the ifdef _LITTLE_ENDIAN where appropriate.
624 	 */
625 	static uint64_t des_weak_keys[] = {
626 		/* Really weak keys.  Byte-order independent values. */
627 		0x0101010101010101ULL,
628 		0x1f1f1f1f0e0e0e0eULL,
629 		0xe0e0e0e0f1f1f1f1ULL,
630 		0xfefefefefefefefeULL,
631 
632 		/* Semi-weak (and a few possibly-weak) keys. */
633 
634 		/* Byte-order independent semi-weak keys. */
635 		0x01fe01fe01fe01feULL,	0xfe01fe01fe01fe01ULL,
636 
637 		/* Byte-order dependent semi-weak keys. */
638 #ifdef _LITTLE_ENDIAN
639 		0xf10ef10ee01fe01fULL,	0x0ef10ef11fe01fe0ULL,
640 		0x01f101f101e001e0ULL,	0xf101f101e001e001ULL,
641 		0x0efe0efe1ffe1ffeULL,	0xfe0efe0efe1ffe1fULL,
642 		0x010e010e011f011fULL,	0x0e010e011f011f01ULL,
643 		0xf1fef1fee0fee0feULL,	0xfef1fef1fee0fee0ULL,
644 #else	/* Big endian */
645 		0x1fe01fe00ef10ef1ULL,	0xe01fe01ff10ef10eULL,
646 		0x01e001e001f101f1ULL,	0xe001e001f101f101ULL,
647 		0x1ffe1ffe0efe0efeULL,	0xfe1ffe1ffe0efe0eULL,
648 		0x011f011f010e010eULL,	0x1f011f010e010e01ULL,
649 		0xe0fee0fef1fef1feULL,	0xfee0fee0fef1fef1ULL,
650 #endif
651 
652 		/* We'll save the other possibly-weak keys for the future. */
653 	};
654 
655 	if (key == NULL)
656 		return (B_FALSE);
657 
658 	/*
659 	 * The code below reverses the bytes on LITTLE_ENDIAN machines.
660 	 * On BIG_ENDIAN, the same code copies without reversing
661 	 * the bytes.
662 	 */
663 	key_so_far = (((uint64_t)key[0] << 56) | ((uint64_t)key[1] << 48) |
664 	    ((uint64_t)key[2] << 40) | ((uint64_t)key[3] << 32) |
665 	    ((uint64_t)key[4] << 24) | ((uint64_t)key[5] << 16) |
666 	    ((uint64_t)key[6] << 8) | (uint64_t)key[7]);
667 
668 	/*
669 	 * Fix parity.
670 	 */
671 	fix_des_parity(&key_so_far);
672 
673 	/* Do weak key check itself. */
674 	for (i = 0; i < (sizeof (des_weak_keys) / sizeof (uint64_t)); i++)
675 		if (key_so_far == des_weak_keys[i]) {
676 			return (B_FALSE);
677 		}
678 
679 	if (corrected_key != NULL) {
680 		/*
681 		 * The code below reverses the bytes on LITTLE_ENDIAN machines.
682 		 * On BIG_ENDIAN, the same code copies without reversing
683 		 * the bytes.
684 		 */
685 		corrected_key[0] = key_so_far >> 56;
686 		corrected_key[1] = key_so_far >> 48;
687 		corrected_key[2] = key_so_far >> 40;
688 		corrected_key[3] = key_so_far >> 32;
689 		corrected_key[4] = key_so_far >> 24;
690 		corrected_key[5] = key_so_far >> 16;
691 		corrected_key[6] = key_so_far >> 8;
692 		corrected_key[7] = (uint8_t)key_so_far;
693 	}
694 /* EXPORT DELETE END */
695 	return (B_TRUE);
696 }
697 
698 static boolean_t
699 des3_keycheck(uint8_t *key, uint8_t *corrected_key)
700 {
701 /* EXPORT DELETE START */
702 	uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
703 	uint64_t key_so_far, scratch, *currentkey;
704 	uint_t j, num_weakkeys = 0;
705 
706 	if (key == NULL) {
707 		return (B_FALSE);
708 	}
709 
710 	if (!IS_P2ALIGNED(key, sizeof (uint64_t))) {
711 		bcopy(key, aligned_key, DES3_KEYSIZE);
712 		currentkey = (uint64_t *)aligned_key;
713 	} else {
714 		/* LINTED */
715 		currentkey = (uint64_t *)key;
716 	}
717 
718 	for (j = 0; j < 3; j++) {
719 		key_so_far = currentkey[j];
720 
721 		if (!keycheck((uint8_t *)&key_so_far, (uint8_t *)&scratch)) {
722 			if (++num_weakkeys > 1) {
723 				return (B_FALSE);
724 			}
725 			/*
726 			 * We found a weak key, but since
727 			 * we've only found one weak key,
728 			 * we can not reject the whole 3DES
729 			 * set of keys as weak.
730 			 *
731 			 * Break from the weak key loop
732 			 * (since this DES key is weak) and
733 			 * continue on.
734 			 */
735 		}
736 
737 		currentkey[j] = scratch;
738 	}
739 
740 	/*
741 	 * Perform key equivalence checks, now that parity is properly set.
742 	 * 1st and 2nd keys must be unique, the 3rd key can be the same as
743 	 * the 1st key for the 2 key varient of 3DES.
744 	 */
745 	if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2])
746 		return (B_FALSE);
747 
748 	if (corrected_key != NULL) {
749 		bcopy(currentkey, corrected_key, DES3_KEYSIZE);
750 	}
751 
752 /* EXPORT DELETE END */
753 	return (B_TRUE);
754 }
755 
756 boolean_t
757 des_keycheck(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
758 {
759 	if (strength == DES) {
760 		return (keycheck(key, corrected_key));
761 	} else if (strength == DES3) {
762 		return (des3_keycheck(key, corrected_key));
763 	} else {
764 		return (B_FALSE);
765 	}
766 }
767 
768 void
769 des_parity_fix(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
770 {
771 /* EXPORT DELETE START */
772 	uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
773 	uint8_t *paritied_key;
774 	uint64_t key_so_far;
775 	int i = 0, offset = 0;
776 
777 	if (strength == DES)
778 		bcopy(key, aligned_key, DES_KEYSIZE);
779 	else
780 		bcopy(key, aligned_key, DES3_KEYSIZE);
781 
782 	paritied_key = (uint8_t *)aligned_key;
783 	while (strength > i) {
784 		offset = 8 * i;
785 		key_so_far = (((uint64_t)paritied_key[offset + 0] << 56) |
786 		    ((uint64_t)paritied_key[offset + 1] << 48) |
787 		    ((uint64_t)paritied_key[offset + 2] << 40) |
788 		    ((uint64_t)paritied_key[offset + 3] << 32) |
789 		    ((uint64_t)paritied_key[offset + 4] << 24) |
790 		    ((uint64_t)paritied_key[offset + 5] << 16) |
791 		    ((uint64_t)paritied_key[offset + 6] << 8) |
792 		    (uint64_t)paritied_key[offset + 7]);
793 
794 		fix_des_parity(&key_so_far);
795 
796 		paritied_key[offset + 0] = key_so_far >> 56;
797 		paritied_key[offset + 1] = key_so_far >> 48;
798 		paritied_key[offset + 2] = key_so_far >> 40;
799 		paritied_key[offset + 3] = key_so_far >> 32;
800 		paritied_key[offset + 4] = key_so_far >> 24;
801 		paritied_key[offset + 5] = key_so_far >> 16;
802 		paritied_key[offset + 6] = key_so_far >> 8;
803 		paritied_key[offset + 7] = (uint8_t)key_so_far;
804 
805 		i++;
806 	}
807 
808 	bcopy(paritied_key, corrected_key, DES_KEYSIZE * strength);
809 /* EXPORT DELETE END */
810 }
811 
812 
813 /*
814  * Initialize key schedule for DES, DES2, and DES3
815  */
816 void
817 des_init_keysched(uint8_t *cipherKey, des_strength_t strength, void *ks)
818 {
819 /* EXPORT DELETE START */
820 	uint64_t *encryption_ks;
821 	uint64_t *decryption_ks;
822 	uint64_t keysched[48];
823 	uint64_t key_uint64[3];
824 	uint64_t tmp;
825 	uint_t keysize, i, j;
826 
827 	switch (strength) {
828 	case DES:
829 		keysize = DES_KEYSIZE;
830 		encryption_ks = ((keysched_t *)ks)->ksch_encrypt;
831 		decryption_ks = ((keysched_t *)ks)->ksch_decrypt;
832 		break;
833 	case DES2:
834 		keysize = DES2_KEYSIZE;
835 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
836 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
837 		break;
838 	case DES3:
839 		keysize = DES3_KEYSIZE;
840 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
841 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
842 	}
843 
844 	/*
845 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
846 	 * reverses every 8 bytes in the key.  On BIG_ENDIAN, the same code
847 	 * copies the key without reversing bytes.
848 	 */
849 #ifdef _BIG_ENDIAN
850 	if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) {
851 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
852 			/* LINTED: pointer alignment */
853 			key_uint64[i] = *((uint64_t *)&cipherKey[j]);
854 		}
855 	} else {
856 #endif
857 	{
858 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
859 			key_uint64[i] = (((uint64_t)cipherKey[j] << 56) |
860 			    ((uint64_t)cipherKey[j + 1] << 48) |
861 			    ((uint64_t)cipherKey[j + 2] << 40) |
862 			    ((uint64_t)cipherKey[j + 3] << 32) |
863 			    ((uint64_t)cipherKey[j + 4] << 24) |
864 			    ((uint64_t)cipherKey[j + 5] << 16) |
865 			    ((uint64_t)cipherKey[j + 6] << 8) |
866 			    (uint64_t)cipherKey[j + 7]);
867 		}
868 	}
869 #ifdef _BIG_ENDIAN
870 	}
871 #endif
872 
873 	switch (strength) {
874 	case DES:
875 		des_ks(keysched, key_uint64[0]);
876 		break;
877 
878 	case DES2:
879 		/* DES2 is just DES3 with the first and third keys the same */
880 		bcopy(key_uint64, key_uint64 + 2, DES_KEYSIZE);
881 		/* FALLTHRU */
882 	case DES3:
883 		des_ks(keysched, key_uint64[0]);
884 		des_ks(keysched + 16, key_uint64[1]);
885 		for (i = 0; i < 8; i++) {
886 			tmp = keysched[16+i];
887 			keysched[16+i] = keysched[31-i];
888 			keysched[31-i] = tmp;
889 		}
890 		des_ks(keysched+32, key_uint64[2]);
891 		keysize = DES3_KEYSIZE;
892 	}
893 
894 	/* save the encryption keyschedule */
895 	bcopy(keysched, encryption_ks, keysize * 16);
896 
897 	/* reverse the key schedule */
898 	for (i = 0; i < keysize; i++) {
899 		tmp = keysched[i];
900 		keysched[i] = keysched[2 * keysize - 1 - i];
901 		keysched[2 * keysize -1 -i] = tmp;
902 	}
903 
904 	/* save the decryption keyschedule */
905 	bcopy(keysched, decryption_ks, keysize * 16);
906 /* EXPORT DELETE END */
907 }
908 
909 /*
910  * Allocate key schedule.
911  */
912 /*ARGSUSED*/
913 void *
914 des_alloc_keysched(size_t *keysched_size, des_strength_t strength, int kmflag)
915 {
916 	void *keysched;
917 
918 /* EXPORT DELETE START */
919 
920 	size_t size;
921 
922 	switch (strength) {
923 	case DES:
924 		size = sizeof (keysched_t);
925 		break;
926 	case DES2:
927 	case DES3:
928 		size = sizeof (keysched3_t);
929 	}
930 
931 #ifdef	_KERNEL
932 	keysched = (keysched_t *)kmem_alloc(size, kmflag);
933 #else	/* !_KERNEL */
934 	keysched = (keysched_t *)malloc(size);
935 #endif	/* _KERNEL */
936 
937 	if (keysched == NULL)
938 		return (NULL);
939 
940 	if (keysched_size != NULL)
941 		*keysched_size = size;
942 
943 /* EXPORT DELETE END */
944 
945 	return (keysched);
946 }
947 
948 /*
949  * Replace the LSB of each byte by the xor of the other
950  * 7 bits.  The tricky thing is that the original contents of the LSBs
951  * are nullifed by including them twice in the xor computation.
952  */
953 static void
954 fix_des_parity(uint64_t *keyp)
955 {
956 /* EXPORT DELETE START */
957 	uint64_t k = *keyp;
958 	k ^= k >> 1;
959 	k ^= k >> 2;
960 	k ^= k >> 4;
961 	*keyp ^= (k & 0x0101010101010101ULL);
962 	*keyp ^= 0x0101010101010101ULL;
963 /* EXPORT DELETE END */
964 }
965