xref: /onnv-gate/usr/src/common/crypto/des/des_impl.c (revision 1065:1b85d3382e43)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23416Skrishna  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include <sys/systm.h>
310Sstevel@tonic-gate #include <sys/ddi.h>
320Sstevel@tonic-gate #include <sys/sysmacros.h>
330Sstevel@tonic-gate #include <sys/strsun.h>
340Sstevel@tonic-gate #include <sys/note.h>
350Sstevel@tonic-gate #include <sys/crypto/common.h>
360Sstevel@tonic-gate #include "des_impl.h"
370Sstevel@tonic-gate #ifndef	_KERNEL
380Sstevel@tonic-gate #include <strings.h>
390Sstevel@tonic-gate #include <stdlib.h>
400Sstevel@tonic-gate #endif	/* !_KERNEL */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /* EXPORT DELETE START */
430Sstevel@tonic-gate 
440Sstevel@tonic-gate typedef struct keysched_s {
450Sstevel@tonic-gate 	uint64_t ksch_encrypt[16];
460Sstevel@tonic-gate 	uint64_t ksch_decrypt[16];
470Sstevel@tonic-gate } keysched_t;
480Sstevel@tonic-gate 
490Sstevel@tonic-gate typedef struct keysched3_s {
500Sstevel@tonic-gate 	uint64_t ksch_encrypt[48];
510Sstevel@tonic-gate 	uint64_t ksch_decrypt[48];
520Sstevel@tonic-gate } keysched3_t;
530Sstevel@tonic-gate 
540Sstevel@tonic-gate static void fix_des_parity(uint64_t *);
550Sstevel@tonic-gate 
560Sstevel@tonic-gate #ifndef sun4u
570Sstevel@tonic-gate 
580Sstevel@tonic-gate static const uint64_t sbox_table[8][64]=
590Sstevel@tonic-gate {
60416Skrishna /* BEGIN CSTYLED */
610Sstevel@tonic-gate {
62416Skrishna 0x0000140140020000ULL, 0x0000000000000000ULL, 0x0000000140000000ULL, 0x0000140140020020ULL,
63416Skrishna 0x0000140140000020ULL, 0x0000000140020020ULL, 0x0000000000000020ULL, 0x0000000140000000ULL,
64416Skrishna 0x0000000000020000ULL, 0x0000140140020000ULL, 0x0000140140020020ULL, 0x0000000000020000ULL,
65416Skrishna 0x0000140000020020ULL, 0x0000140140000020ULL, 0x0000140000000000ULL, 0x0000000000000020ULL,
66416Skrishna 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000140020000ULL,
67416Skrishna 0x0000000140020000ULL, 0x0000140140000000ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
68416Skrishna 0x0000000140000020ULL, 0x0000140000000020ULL, 0x0000140000000020ULL, 0x0000000140000020ULL,
69416Skrishna 0x0000000000000000ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140000000000ULL,
70416Skrishna 0x0000000140000000ULL, 0x0000140140020020ULL, 0x0000000000000020ULL, 0x0000140140000000ULL,
71416Skrishna 0x0000140140020000ULL, 0x0000140000000000ULL, 0x0000140000000000ULL, 0x0000000000020000ULL,
72416Skrishna 0x0000140140000020ULL, 0x0000000140000000ULL, 0x0000000140020000ULL, 0x0000140000000020ULL,
73416Skrishna 0x0000000000020000ULL, 0x0000000000000020ULL, 0x0000140000020020ULL, 0x0000000140020020ULL,
74416Skrishna 0x0000140140020020ULL, 0x0000000140000020ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
75416Skrishna 0x0000140000000020ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140140020000ULL,
76416Skrishna 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000000000000ULL,
77416Skrishna 0x0000000140000020ULL, 0x0000000140020000ULL, 0x0000000000000000ULL, 0x0000140140000020ULL
780Sstevel@tonic-gate },
790Sstevel@tonic-gate {
80416Skrishna 0x2000005020000500ULL, 0x2000000020000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL,
81416Skrishna 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL, 0x2000000020000500ULL,
82416Skrishna 0x2000000000000500ULL, 0x2000005020000500ULL, 0x2000005020000000ULL, 0x2000000000000000ULL,
83416Skrishna 0x2000000020000000ULL, 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL,
84416Skrishna 0x0000005020000000ULL, 0x0000005000000500ULL, 0x2000000020000500ULL, 0x0000000000000000ULL,
85416Skrishna 0x2000000000000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL, 0x2000005000000000ULL,
86416Skrishna 0x0000005000000500ULL, 0x2000000000000500ULL, 0x0000000000000000ULL, 0x0000005020000000ULL,
87416Skrishna 0x0000000020000500ULL, 0x2000005020000000ULL, 0x2000005000000000ULL, 0x0000000020000500ULL,
88416Skrishna 0x0000000000000000ULL, 0x0000005020000500ULL, 0x2000005000000500ULL, 0x0000005000000000ULL,
89416Skrishna 0x2000000020000500ULL, 0x2000005000000000ULL, 0x2000005020000000ULL, 0x0000000020000000ULL,
90416Skrishna 0x2000005000000000ULL, 0x2000000020000000ULL, 0x0000000000000500ULL, 0x2000005020000500ULL,
91416Skrishna 0x0000005020000500ULL, 0x0000000000000500ULL, 0x0000000020000000ULL, 0x2000000000000000ULL,
92416Skrishna 0x0000000020000500ULL, 0x2000005020000000ULL, 0x0000005000000000ULL, 0x2000000000000500ULL,
93416Skrishna 0x0000005000000500ULL, 0x2000000020000500ULL, 0x2000000000000500ULL, 0x0000005000000500ULL,
94416Skrishna 0x0000005020000000ULL, 0x0000000000000000ULL, 0x2000000020000000ULL, 0x0000000020000500ULL,
95416Skrishna 0x2000000000000000ULL, 0x2000005000000500ULL, 0x2000005020000500ULL, 0x0000005020000000ULL
960Sstevel@tonic-gate },
970Sstevel@tonic-gate {
98416Skrishna 0x0000000000014040ULL, 0x0000800280014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
99416Skrishna 0x0000800000014000ULL, 0x0000000000000000ULL, 0x0000000280014040ULL, 0x0000800000014000ULL,
100416Skrishna 0x0000000280000040ULL, 0x0000800000000040ULL, 0x0000800000000040ULL, 0x0000000280000000ULL,
101416Skrishna 0x0000800280014040ULL, 0x0000000280000040ULL, 0x0000800280000000ULL, 0x0000000000014040ULL,
102416Skrishna 0x0000800000000000ULL, 0x0000000000000040ULL, 0x0000800280014000ULL, 0x0000000000014000ULL,
103416Skrishna 0x0000000280014000ULL, 0x0000800280000000ULL, 0x0000800280000040ULL, 0x0000000280014040ULL,
104416Skrishna 0x0000800000014040ULL, 0x0000000280014000ULL, 0x0000000280000000ULL, 0x0000800000014040ULL,
105416Skrishna 0x0000000000000040ULL, 0x0000800280014040ULL, 0x0000000000014000ULL, 0x0000800000000000ULL,
106416Skrishna 0x0000800280014000ULL, 0x0000800000000000ULL, 0x0000000280000040ULL, 0x0000000000014040ULL,
107416Skrishna 0x0000000280000000ULL, 0x0000800280014000ULL, 0x0000800000014000ULL, 0x0000000000000000ULL,
108416Skrishna 0x0000000000014000ULL, 0x0000000280000040ULL, 0x0000800280014040ULL, 0x0000800000014000ULL,
109416Skrishna 0x0000800000000040ULL, 0x0000000000014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
110416Skrishna 0x0000800000014040ULL, 0x0000000280000000ULL, 0x0000800000000000ULL, 0x0000800280014040ULL,
111416Skrishna 0x0000000000000040ULL, 0x0000000280014040ULL, 0x0000000280014000ULL, 0x0000800000000040ULL,
112416Skrishna 0x0000800280000000ULL, 0x0000800000014040ULL, 0x0000000000014040ULL, 0x0000800280000000ULL,
113416Skrishna 0x0000000280014040ULL, 0x0000000000000040ULL, 0x0000800280000040ULL, 0x0000000280014000ULL
1140Sstevel@tonic-gate },
1150Sstevel@tonic-gate {
116416Skrishna 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
117416Skrishna 0x0000020008101000ULL, 0x4000020000001008ULL, 0x4000020000000008ULL, 0x4000000008100008ULL,
118416Skrishna 0x0000000000000000ULL, 0x0000020008100000ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
119416Skrishna 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000020000001000ULL, 0x4000020000000008ULL,
120416Skrishna 0x4000000000000008ULL, 0x0000000008100000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
121416Skrishna 0x0000000000001000ULL, 0x0000020000000000ULL, 0x4000000008100008ULL, 0x0000000008101000ULL,
122416Skrishna 0x4000020000001008ULL, 0x4000000000000008ULL, 0x0000000008101000ULL, 0x0000020000001000ULL,
123416Skrishna 0x0000000008100000ULL, 0x0000020008101000ULL, 0x4000020008101008ULL, 0x4000000000001008ULL,
124416Skrishna 0x0000020000001000ULL, 0x4000020000000008ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
125416Skrishna 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000020008100000ULL,
126416Skrishna 0x0000000008101000ULL, 0x0000020000001000ULL, 0x4000020000001008ULL, 0x4000000000000008ULL,
127416Skrishna 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
128416Skrishna 0x4000020008101008ULL, 0x4000000000001008ULL, 0x4000000000000008ULL, 0x0000000008100000ULL,
129416Skrishna 0x4000020000000008ULL, 0x4000000008100008ULL, 0x0000020008101000ULL, 0x4000020000001008ULL,
130416Skrishna 0x4000000008100008ULL, 0x0000000008101000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
131416Skrishna 0x0000000000001000ULL, 0x0000020000000000ULL, 0x0000000008100000ULL, 0x0000020008101000ULL
1320Sstevel@tonic-gate },
1330Sstevel@tonic-gate {
134416Skrishna 0x000000000000a000ULL, 0x000028080000a000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL,
135416Skrishna 0x0000000800000000ULL, 0x000000000000a000ULL, 0x1000000000000000ULL, 0x0000280800000000ULL,
136416Skrishna 0x100000080000a000ULL, 0x0000000800000000ULL, 0x000028000000a000ULL, 0x100000080000a000ULL,
137416Skrishna 0x100028000000a000ULL, 0x1000280800000000ULL, 0x000000080000a000ULL, 0x1000000000000000ULL,
138416Skrishna 0x0000280000000000ULL, 0x1000000800000000ULL, 0x1000000800000000ULL, 0x0000000000000000ULL,
139416Skrishna 0x100000000000a000ULL, 0x100028080000a000ULL, 0x100028080000a000ULL, 0x000028000000a000ULL,
140416Skrishna 0x1000280800000000ULL, 0x100000000000a000ULL, 0x0000000000000000ULL, 0x1000280000000000ULL,
141416Skrishna 0x000028080000a000ULL, 0x0000280000000000ULL, 0x1000280000000000ULL, 0x000000080000a000ULL,
142416Skrishna 0x0000000800000000ULL, 0x100028000000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL,
143416Skrishna 0x1000000000000000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL, 0x100000080000a000ULL,
144416Skrishna 0x000028000000a000ULL, 0x1000000000000000ULL, 0x1000280800000000ULL, 0x000028080000a000ULL,
145416Skrishna 0x100000080000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL, 0x1000280800000000ULL,
146416Skrishna 0x100028080000a000ULL, 0x000000080000a000ULL, 0x1000280000000000ULL, 0x100028080000a000ULL,
147416Skrishna 0x0000280800000000ULL, 0x0000000000000000ULL, 0x1000000800000000ULL, 0x1000280000000000ULL,
148416Skrishna 0x000000080000a000ULL, 0x000028000000a000ULL, 0x100000000000a000ULL, 0x0000000800000000ULL,
149416Skrishna 0x0000000000000000ULL, 0x1000000800000000ULL, 0x000028080000a000ULL, 0x100000000000a000ULL
1500Sstevel@tonic-gate },
1510Sstevel@tonic-gate {
152416Skrishna 0x0802000000000280ULL, 0x0802010000000000ULL, 0x0000000010000000ULL, 0x0802010010000280ULL,
153416Skrishna 0x0802010000000000ULL, 0x0000000000000280ULL, 0x0802010010000280ULL, 0x0000010000000000ULL,
154416Skrishna 0x0802000010000000ULL, 0x0000010010000280ULL, 0x0000010000000000ULL, 0x0802000000000280ULL,
155416Skrishna 0x0000010000000280ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
156416Skrishna 0x0000000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000010000000ULL,
157416Skrishna 0x0000010010000000ULL, 0x0802000010000280ULL, 0x0000000000000280ULL, 0x0802010000000280ULL,
158416Skrishna 0x0802010000000280ULL, 0x0000000000000000ULL, 0x0000010010000280ULL, 0x0802010010000000ULL,
159416Skrishna 0x0000000010000280ULL, 0x0000010010000000ULL, 0x0802010010000000ULL, 0x0802000000000000ULL,
160416Skrishna 0x0802000010000000ULL, 0x0000000000000280ULL, 0x0802010000000280ULL, 0x0000010010000000ULL,
161416Skrishna 0x0802010010000280ULL, 0x0000010000000000ULL, 0x0000000010000280ULL, 0x0802000000000280ULL,
162416Skrishna 0x0000010000000000ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
163416Skrishna 0x0802000000000280ULL, 0x0802010010000280ULL, 0x0000010010000000ULL, 0x0802010000000000ULL,
164416Skrishna 0x0000010010000280ULL, 0x0802010010000000ULL, 0x0000000000000000ULL, 0x0802010000000280ULL,
165416Skrishna 0x0000000000000280ULL, 0x0000000010000000ULL, 0x0802010000000000ULL, 0x0000010010000280ULL,
166416Skrishna 0x0000000010000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000000000000ULL,
167416Skrishna 0x0802010010000000ULL, 0x0802000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL
1680Sstevel@tonic-gate },
1690Sstevel@tonic-gate {
170416Skrishna 0x000000a000000000ULL, 0x800040a000000010ULL, 0x8000400000040010ULL, 0x0000000000000000ULL,
171416Skrishna 0x0000000000040000ULL, 0x8000400000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
172416Skrishna 0x800040a000040010ULL, 0x000000a000000000ULL, 0x0000000000000000ULL, 0x8000400000000010ULL,
173416Skrishna 0x8000000000000010ULL, 0x0000400000000000ULL, 0x800040a000000010ULL, 0x8000000000040010ULL,
174416Skrishna 0x0000400000040000ULL, 0x800000a000040010ULL, 0x800000a000000010ULL, 0x0000400000040000ULL,
175416Skrishna 0x8000400000000010ULL, 0x000040a000000000ULL, 0x000040a000040000ULL, 0x800000a000000010ULL,
176416Skrishna 0x000040a000000000ULL, 0x0000000000040000ULL, 0x8000000000040010ULL, 0x800040a000040010ULL,
177416Skrishna 0x000000a000040000ULL, 0x8000000000000010ULL, 0x0000400000000000ULL, 0x000000a000040000ULL,
178416Skrishna 0x0000400000000000ULL, 0x000000a000040000ULL, 0x000000a000000000ULL, 0x8000400000040010ULL,
179416Skrishna 0x8000400000040010ULL, 0x800040a000000010ULL, 0x800040a000000010ULL, 0x8000000000000010ULL,
180416Skrishna 0x800000a000000010ULL, 0x0000400000000000ULL, 0x0000400000040000ULL, 0x000000a000000000ULL,
181416Skrishna 0x000040a000040000ULL, 0x8000000000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
182416Skrishna 0x8000000000040010ULL, 0x8000400000000010ULL, 0x800040a000040010ULL, 0x000040a000000000ULL,
183416Skrishna 0x000000a000040000ULL, 0x0000000000000000ULL, 0x8000000000000010ULL, 0x800040a000040010ULL,
184416Skrishna 0x0000000000000000ULL, 0x800000a000040010ULL, 0x000040a000000000ULL, 0x0000000000040000ULL,
185416Skrishna 0x8000400000000010ULL, 0x0000400000040000ULL, 0x0000000000040000ULL, 0x800000a000000010ULL
1860Sstevel@tonic-gate },
1870Sstevel@tonic-gate {
188416Skrishna 0x0401000004080800ULL, 0x0000000004080000ULL, 0x0000000400000000ULL, 0x0401000404080800ULL,
189416Skrishna 0x0401000000000000ULL, 0x0401000004080800ULL, 0x0000000000000800ULL, 0x0401000000000000ULL,
190416Skrishna 0x0000000400000800ULL, 0x0401000400000000ULL, 0x0401000404080800ULL, 0x0000000404080000ULL,
191416Skrishna 0x0401000404080000ULL, 0x0000000404080800ULL, 0x0000000004080000ULL, 0x0000000000000800ULL,
192416Skrishna 0x0401000400000000ULL, 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000004080800ULL,
193416Skrishna 0x0000000404080000ULL, 0x0000000400000800ULL, 0x0401000400000800ULL, 0x0401000404080000ULL,
194416Skrishna 0x0000000004080800ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0401000400000800ULL,
195416Skrishna 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000404080800ULL, 0x0000000400000000ULL,
196416Skrishna 0x0000000404080800ULL, 0x0000000400000000ULL, 0x0401000404080000ULL, 0x0000000004080000ULL,
197416Skrishna 0x0000000000000800ULL, 0x0401000400000800ULL, 0x0000000004080000ULL, 0x0000000404080800ULL,
198416Skrishna 0x0401000004080000ULL, 0x0000000000000800ULL, 0x0401000000000800ULL, 0x0401000400000000ULL,
199416Skrishna 0x0401000400000800ULL, 0x0401000000000000ULL, 0x0000000400000000ULL, 0x0401000004080800ULL,
200416Skrishna 0x0000000000000000ULL, 0x0401000404080800ULL, 0x0000000400000800ULL, 0x0401000000000800ULL,
201416Skrishna 0x0401000400000000ULL, 0x0401000004080000ULL, 0x0401000004080800ULL, 0x0000000000000000ULL,
202416Skrishna 0x0401000404080800ULL, 0x0000000404080000ULL, 0x0000000404080000ULL, 0x0000000004080800ULL,
203416Skrishna 0x0000000004080800ULL, 0x0000000400000800ULL, 0x0401000000000000ULL, 0x0401000404080000ULL
2040Sstevel@tonic-gate }
205416Skrishna /* END CSTYLED */
2060Sstevel@tonic-gate };
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate static const uint64_t ip_table[2][256]=
2100Sstevel@tonic-gate {
211416Skrishna /* BEGIN CSTYLED */
2120Sstevel@tonic-gate {
213416Skrishna 0x0000000000000000ULL, 0x0000000000000400ULL, 0x0080000000000280ULL, 0x0080000000000680ULL,
214416Skrishna 0x0000000000400000ULL, 0x0000000000400400ULL, 0x0080000000400280ULL, 0x0080000000400680ULL,
215416Skrishna 0x0000000000280000ULL, 0x0000000000280400ULL, 0x0080000000280280ULL, 0x0080000000280680ULL,
216416Skrishna 0x0000000000680000ULL, 0x0000000000680400ULL, 0x0080000000680280ULL, 0x0080000000680680ULL,
217416Skrishna 0x0000000400000000ULL, 0x0000000400000400ULL, 0x0080000400000280ULL, 0x0080000400000680ULL,
218416Skrishna 0x0000000400400000ULL, 0x0000000400400400ULL, 0x0080000400400280ULL, 0x0080000400400680ULL,
219416Skrishna 0x0000000400280000ULL, 0x0000000400280400ULL, 0x0080000400280280ULL, 0x0080000400280680ULL,
220416Skrishna 0x0000000400680000ULL, 0x0000000400680400ULL, 0x0080000400680280ULL, 0x0080000400680680ULL,
221416Skrishna 0x0000000280000000ULL, 0x0000000280000400ULL, 0x0080000280000280ULL, 0x0080000280000680ULL,
222416Skrishna 0x0000000280400000ULL, 0x0000000280400400ULL, 0x0080000280400280ULL, 0x0080000280400680ULL,
223416Skrishna 0x0000000280280000ULL, 0x0000000280280400ULL, 0x0080000280280280ULL, 0x0080000280280680ULL,
224416Skrishna 0x0000000280680000ULL, 0x0000000280680400ULL, 0x0080000280680280ULL, 0x0080000280680680ULL,
225416Skrishna 0x0000000680000000ULL, 0x0000000680000400ULL, 0x0080000680000280ULL, 0x0080000680000680ULL,
226416Skrishna 0x0000000680400000ULL, 0x0000000680400400ULL, 0x0080000680400280ULL, 0x0080000680400680ULL,
227416Skrishna 0x0000000680280000ULL, 0x0000000680280400ULL, 0x0080000680280280ULL, 0x0080000680280680ULL,
228416Skrishna 0x0000000680680000ULL, 0x0000000680680400ULL, 0x0080000680680280ULL, 0x0080000680680680ULL,
229416Skrishna 0x0000400000000000ULL, 0x0000400000000400ULL, 0x0080400000000280ULL, 0x0080400000000680ULL,
230416Skrishna 0x0000400000400000ULL, 0x0000400000400400ULL, 0x0080400000400280ULL, 0x0080400000400680ULL,
231416Skrishna 0x0000400000280000ULL, 0x0000400000280400ULL, 0x0080400000280280ULL, 0x0080400000280680ULL,
232416Skrishna 0x0000400000680000ULL, 0x0000400000680400ULL, 0x0080400000680280ULL, 0x0080400000680680ULL,
233416Skrishna 0x0000400400000000ULL, 0x0000400400000400ULL, 0x0080400400000280ULL, 0x0080400400000680ULL,
234416Skrishna 0x0000400400400000ULL, 0x0000400400400400ULL, 0x0080400400400280ULL, 0x0080400400400680ULL,
235416Skrishna 0x0000400400280000ULL, 0x0000400400280400ULL, 0x0080400400280280ULL, 0x0080400400280680ULL,
236416Skrishna 0x0000400400680000ULL, 0x0000400400680400ULL, 0x0080400400680280ULL, 0x0080400400680680ULL,
237416Skrishna 0x0000400280000000ULL, 0x0000400280000400ULL, 0x0080400280000280ULL, 0x0080400280000680ULL,
238416Skrishna 0x0000400280400000ULL, 0x0000400280400400ULL, 0x0080400280400280ULL, 0x0080400280400680ULL,
239416Skrishna 0x0000400280280000ULL, 0x0000400280280400ULL, 0x0080400280280280ULL, 0x0080400280280680ULL,
240416Skrishna 0x0000400280680000ULL, 0x0000400280680400ULL, 0x0080400280680280ULL, 0x0080400280680680ULL,
241416Skrishna 0x0000400680000000ULL, 0x0000400680000400ULL, 0x0080400680000280ULL, 0x0080400680000680ULL,
242416Skrishna 0x0000400680400000ULL, 0x0000400680400400ULL, 0x0080400680400280ULL, 0x0080400680400680ULL,
243416Skrishna 0x0000400680280000ULL, 0x0000400680280400ULL, 0x0080400680280280ULL, 0x0080400680280680ULL,
244416Skrishna 0x0000400680680000ULL, 0x0000400680680400ULL, 0x0080400680680280ULL, 0x0080400680680680ULL,
245416Skrishna 0x0000280000000000ULL, 0x0000280000000400ULL, 0x0080280000000280ULL, 0x0080280000000680ULL,
246416Skrishna 0x0000280000400000ULL, 0x0000280000400400ULL, 0x0080280000400280ULL, 0x0080280000400680ULL,
247416Skrishna 0x0000280000280000ULL, 0x0000280000280400ULL, 0x0080280000280280ULL, 0x0080280000280680ULL,
248416Skrishna 0x0000280000680000ULL, 0x0000280000680400ULL, 0x0080280000680280ULL, 0x0080280000680680ULL,
249416Skrishna 0x0000280400000000ULL, 0x0000280400000400ULL, 0x0080280400000280ULL, 0x0080280400000680ULL,
250416Skrishna 0x0000280400400000ULL, 0x0000280400400400ULL, 0x0080280400400280ULL, 0x0080280400400680ULL,
251416Skrishna 0x0000280400280000ULL, 0x0000280400280400ULL, 0x0080280400280280ULL, 0x0080280400280680ULL,
252416Skrishna 0x0000280400680000ULL, 0x0000280400680400ULL, 0x0080280400680280ULL, 0x0080280400680680ULL,
253416Skrishna 0x0000280280000000ULL, 0x0000280280000400ULL, 0x0080280280000280ULL, 0x0080280280000680ULL,
254416Skrishna 0x0000280280400000ULL, 0x0000280280400400ULL, 0x0080280280400280ULL, 0x0080280280400680ULL,
255416Skrishna 0x0000280280280000ULL, 0x0000280280280400ULL, 0x0080280280280280ULL, 0x0080280280280680ULL,
256416Skrishna 0x0000280280680000ULL, 0x0000280280680400ULL, 0x0080280280680280ULL, 0x0080280280680680ULL,
257416Skrishna 0x0000280680000000ULL, 0x0000280680000400ULL, 0x0080280680000280ULL, 0x0080280680000680ULL,
258416Skrishna 0x0000280680400000ULL, 0x0000280680400400ULL, 0x0080280680400280ULL, 0x0080280680400680ULL,
259416Skrishna 0x0000280680280000ULL, 0x0000280680280400ULL, 0x0080280680280280ULL, 0x0080280680280680ULL,
260416Skrishna 0x0000280680680000ULL, 0x0000280680680400ULL, 0x0080280680680280ULL, 0x0080280680680680ULL,
261416Skrishna 0x0000680000000000ULL, 0x0000680000000400ULL, 0x0080680000000280ULL, 0x0080680000000680ULL,
262416Skrishna 0x0000680000400000ULL, 0x0000680000400400ULL, 0x0080680000400280ULL, 0x0080680000400680ULL,
263416Skrishna 0x0000680000280000ULL, 0x0000680000280400ULL, 0x0080680000280280ULL, 0x0080680000280680ULL,
264416Skrishna 0x0000680000680000ULL, 0x0000680000680400ULL, 0x0080680000680280ULL, 0x0080680000680680ULL,
265416Skrishna 0x0000680400000000ULL, 0x0000680400000400ULL, 0x0080680400000280ULL, 0x0080680400000680ULL,
266416Skrishna 0x0000680400400000ULL, 0x0000680400400400ULL, 0x0080680400400280ULL, 0x0080680400400680ULL,
267416Skrishna 0x0000680400280000ULL, 0x0000680400280400ULL, 0x0080680400280280ULL, 0x0080680400280680ULL,
268416Skrishna 0x0000680400680000ULL, 0x0000680400680400ULL, 0x0080680400680280ULL, 0x0080680400680680ULL,
269416Skrishna 0x0000680280000000ULL, 0x0000680280000400ULL, 0x0080680280000280ULL, 0x0080680280000680ULL,
270416Skrishna 0x0000680280400000ULL, 0x0000680280400400ULL, 0x0080680280400280ULL, 0x0080680280400680ULL,
271416Skrishna 0x0000680280280000ULL, 0x0000680280280400ULL, 0x0080680280280280ULL, 0x0080680280280680ULL,
272416Skrishna 0x0000680280680000ULL, 0x0000680280680400ULL, 0x0080680280680280ULL, 0x0080680280680680ULL,
273416Skrishna 0x0000680680000000ULL, 0x0000680680000400ULL, 0x0080680680000280ULL, 0x0080680680000680ULL,
274416Skrishna 0x0000680680400000ULL, 0x0000680680400400ULL, 0x0080680680400280ULL, 0x0080680680400680ULL,
275416Skrishna 0x0000680680280000ULL, 0x0000680680280400ULL, 0x0080680680280280ULL, 0x0080680680280680ULL,
276416Skrishna 0x0000680680680000ULL, 0x0000680680680400ULL, 0x0080680680680280ULL, 0x0080680680680680ULL
2770Sstevel@tonic-gate },
2780Sstevel@tonic-gate {
279416Skrishna 0x0000000000000000ULL, 0x0000000000005000ULL, 0x0000000000000800ULL, 0x0000000000005800ULL,
280416Skrishna 0x0000000005000000ULL, 0x0000000005005000ULL, 0x0000000005000800ULL, 0x0000000005005800ULL,
281416Skrishna 0x0000000000800000ULL, 0x0000000000805000ULL, 0x0000000000800800ULL, 0x0000000000805800ULL,
282416Skrishna 0x0000000005800000ULL, 0x0000000005805000ULL, 0x0000000005800800ULL, 0x0000000005805800ULL,
283416Skrishna 0x0000005000000000ULL, 0x0000005000005000ULL, 0x0000005000000800ULL, 0x0000005000005800ULL,
284416Skrishna 0x0000005005000000ULL, 0x0000005005005000ULL, 0x0000005005000800ULL, 0x0000005005005800ULL,
285416Skrishna 0x0000005000800000ULL, 0x0000005000805000ULL, 0x0000005000800800ULL, 0x0000005000805800ULL,
286416Skrishna 0x0000005005800000ULL, 0x0000005005805000ULL, 0x0000005005800800ULL, 0x0000005005805800ULL,
287416Skrishna 0x0000000800000000ULL, 0x0000000800005000ULL, 0x0000000800000800ULL, 0x0000000800005800ULL,
288416Skrishna 0x0000000805000000ULL, 0x0000000805005000ULL, 0x0000000805000800ULL, 0x0000000805005800ULL,
289416Skrishna 0x0000000800800000ULL, 0x0000000800805000ULL, 0x0000000800800800ULL, 0x0000000800805800ULL,
290416Skrishna 0x0000000805800000ULL, 0x0000000805805000ULL, 0x0000000805800800ULL, 0x0000000805805800ULL,
291416Skrishna 0x0000005800000000ULL, 0x0000005800005000ULL, 0x0000005800000800ULL, 0x0000005800005800ULL,
292416Skrishna 0x0000005805000000ULL, 0x0000005805005000ULL, 0x0000005805000800ULL, 0x0000005805005800ULL,
293416Skrishna 0x0000005800800000ULL, 0x0000005800805000ULL, 0x0000005800800800ULL, 0x0000005800805800ULL,
294416Skrishna 0x0000005805800000ULL, 0x0000005805805000ULL, 0x0000005805800800ULL, 0x0000005805805800ULL,
295416Skrishna 0x0005000000000004ULL, 0x0005000000005004ULL, 0x0005000000000804ULL, 0x0005000000005804ULL,
296416Skrishna 0x0005000005000004ULL, 0x0005000005005004ULL, 0x0005000005000804ULL, 0x0005000005005804ULL,
297416Skrishna 0x0005000000800004ULL, 0x0005000000805004ULL, 0x0005000000800804ULL, 0x0005000000805804ULL,
298416Skrishna 0x0005000005800004ULL, 0x0005000005805004ULL, 0x0005000005800804ULL, 0x0005000005805804ULL,
299416Skrishna 0x0005005000000004ULL, 0x0005005000005004ULL, 0x0005005000000804ULL, 0x0005005000005804ULL,
300416Skrishna 0x0005005005000004ULL, 0x0005005005005004ULL, 0x0005005005000804ULL, 0x0005005005005804ULL,
301416Skrishna 0x0005005000800004ULL, 0x0005005000805004ULL, 0x0005005000800804ULL, 0x0005005000805804ULL,
302416Skrishna 0x0005005005800004ULL, 0x0005005005805004ULL, 0x0005005005800804ULL, 0x0005005005805804ULL,
303416Skrishna 0x0005000800000004ULL, 0x0005000800005004ULL, 0x0005000800000804ULL, 0x0005000800005804ULL,
304416Skrishna 0x0005000805000004ULL, 0x0005000805005004ULL, 0x0005000805000804ULL, 0x0005000805005804ULL,
305416Skrishna 0x0005000800800004ULL, 0x0005000800805004ULL, 0x0005000800800804ULL, 0x0005000800805804ULL,
306416Skrishna 0x0005000805800004ULL, 0x0005000805805004ULL, 0x0005000805800804ULL, 0x0005000805805804ULL,
307416Skrishna 0x0005005800000004ULL, 0x0005005800005004ULL, 0x0005005800000804ULL, 0x0005005800005804ULL,
308416Skrishna 0x0005005805000004ULL, 0x0005005805005004ULL, 0x0005005805000804ULL, 0x0005005805005804ULL,
309416Skrishna 0x0005005800800004ULL, 0x0005005800805004ULL, 0x0005005800800804ULL, 0x0005005800805804ULL,
310416Skrishna 0x0005005805800004ULL, 0x0005005805805004ULL, 0x0005005805800804ULL, 0x0005005805805804ULL,
311416Skrishna 0x0000800000000000ULL, 0x0000800000005000ULL, 0x0000800000000800ULL, 0x0000800000005800ULL,
312416Skrishna 0x0000800005000000ULL, 0x0000800005005000ULL, 0x0000800005000800ULL, 0x0000800005005800ULL,
313416Skrishna 0x0000800000800000ULL, 0x0000800000805000ULL, 0x0000800000800800ULL, 0x0000800000805800ULL,
314416Skrishna 0x0000800005800000ULL, 0x0000800005805000ULL, 0x0000800005800800ULL, 0x0000800005805800ULL,
315416Skrishna 0x0000805000000000ULL, 0x0000805000005000ULL, 0x0000805000000800ULL, 0x0000805000005800ULL,
316416Skrishna 0x0000805005000000ULL, 0x0000805005005000ULL, 0x0000805005000800ULL, 0x0000805005005800ULL,
317416Skrishna 0x0000805000800000ULL, 0x0000805000805000ULL, 0x0000805000800800ULL, 0x0000805000805800ULL,
318416Skrishna 0x0000805005800000ULL, 0x0000805005805000ULL, 0x0000805005800800ULL, 0x0000805005805800ULL,
319416Skrishna 0x0000800800000000ULL, 0x0000800800005000ULL, 0x0000800800000800ULL, 0x0000800800005800ULL,
320416Skrishna 0x0000800805000000ULL, 0x0000800805005000ULL, 0x0000800805000800ULL, 0x0000800805005800ULL,
321416Skrishna 0x0000800800800000ULL, 0x0000800800805000ULL, 0x0000800800800800ULL, 0x0000800800805800ULL,
322416Skrishna 0x0000800805800000ULL, 0x0000800805805000ULL, 0x0000800805800800ULL, 0x0000800805805800ULL,
323416Skrishna 0x0000805800000000ULL, 0x0000805800005000ULL, 0x0000805800000800ULL, 0x0000805800005800ULL,
324416Skrishna 0x0000805805000000ULL, 0x0000805805005000ULL, 0x0000805805000800ULL, 0x0000805805005800ULL,
325416Skrishna 0x0000805800800000ULL, 0x0000805800805000ULL, 0x0000805800800800ULL, 0x0000805800805800ULL,
326416Skrishna 0x0000805805800000ULL, 0x0000805805805000ULL, 0x0000805805800800ULL, 0x0000805805805800ULL,
327416Skrishna 0x0005800000000004ULL, 0x0005800000005004ULL, 0x0005800000000804ULL, 0x0005800000005804ULL,
328416Skrishna 0x0005800005000004ULL, 0x0005800005005004ULL, 0x0005800005000804ULL, 0x0005800005005804ULL,
329416Skrishna 0x0005800000800004ULL, 0x0005800000805004ULL, 0x0005800000800804ULL, 0x0005800000805804ULL,
330416Skrishna 0x0005800005800004ULL, 0x0005800005805004ULL, 0x0005800005800804ULL, 0x0005800005805804ULL,
331416Skrishna 0x0005805000000004ULL, 0x0005805000005004ULL, 0x0005805000000804ULL, 0x0005805000005804ULL,
332416Skrishna 0x0005805005000004ULL, 0x0005805005005004ULL, 0x0005805005000804ULL, 0x0005805005005804ULL,
333416Skrishna 0x0005805000800004ULL, 0x0005805000805004ULL, 0x0005805000800804ULL, 0x0005805000805804ULL,
334416Skrishna 0x0005805005800004ULL, 0x0005805005805004ULL, 0x0005805005800804ULL, 0x0005805005805804ULL,
335416Skrishna 0x0005800800000004ULL, 0x0005800800005004ULL, 0x0005800800000804ULL, 0x0005800800005804ULL,
336416Skrishna 0x0005800805000004ULL, 0x0005800805005004ULL, 0x0005800805000804ULL, 0x0005800805005804ULL,
337416Skrishna 0x0005800800800004ULL, 0x0005800800805004ULL, 0x0005800800800804ULL, 0x0005800800805804ULL,
338416Skrishna 0x0005800805800004ULL, 0x0005800805805004ULL, 0x0005800805800804ULL, 0x0005800805805804ULL,
339416Skrishna 0x0005805800000004ULL, 0x0005805800005004ULL, 0x0005805800000804ULL, 0x0005805800005804ULL,
340416Skrishna 0x0005805805000004ULL, 0x0005805805005004ULL, 0x0005805805000804ULL, 0x0005805805005804ULL,
341416Skrishna 0x0005805800800004ULL, 0x0005805800805004ULL, 0x0005805800800804ULL, 0x0005805800805804ULL,
342416Skrishna 0x0005805805800004ULL, 0x0005805805805004ULL, 0x0005805805800804ULL, 0x0005805805805804ULL
3430Sstevel@tonic-gate }
344416Skrishna /* END CSTYLED */
3450Sstevel@tonic-gate };
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate static const uint32_t fp_table[256]=
3480Sstevel@tonic-gate {
3490Sstevel@tonic-gate 0x00000000, 0x80000000, 0x00800000, 0x80800000,
3500Sstevel@tonic-gate 0x00008000, 0x80008000, 0x00808000, 0x80808000,
3510Sstevel@tonic-gate 0x00000080, 0x80000080, 0x00800080, 0x80800080,
3520Sstevel@tonic-gate 0x00008080, 0x80008080, 0x00808080, 0x80808080,
3530Sstevel@tonic-gate 0x40000000, 0xc0000000, 0x40800000, 0xc0800000,
3540Sstevel@tonic-gate 0x40008000, 0xc0008000, 0x40808000, 0xc0808000,
3550Sstevel@tonic-gate 0x40000080, 0xc0000080, 0x40800080, 0xc0800080,
3560Sstevel@tonic-gate 0x40008080, 0xc0008080, 0x40808080, 0xc0808080,
3570Sstevel@tonic-gate 0x00400000, 0x80400000, 0x00c00000, 0x80c00000,
3580Sstevel@tonic-gate 0x00408000, 0x80408000, 0x00c08000, 0x80c08000,
3590Sstevel@tonic-gate 0x00400080, 0x80400080, 0x00c00080, 0x80c00080,
3600Sstevel@tonic-gate 0x00408080, 0x80408080, 0x00c08080, 0x80c08080,
3610Sstevel@tonic-gate 0x40400000, 0xc0400000, 0x40c00000, 0xc0c00000,
3620Sstevel@tonic-gate 0x40408000, 0xc0408000, 0x40c08000, 0xc0c08000,
3630Sstevel@tonic-gate 0x40400080, 0xc0400080, 0x40c00080, 0xc0c00080,
3640Sstevel@tonic-gate 0x40408080, 0xc0408080, 0x40c08080, 0xc0c08080,
3650Sstevel@tonic-gate 0x00004000, 0x80004000, 0x00804000, 0x80804000,
3660Sstevel@tonic-gate 0x0000c000, 0x8000c000, 0x0080c000, 0x8080c000,
3670Sstevel@tonic-gate 0x00004080, 0x80004080, 0x00804080, 0x80804080,
3680Sstevel@tonic-gate 0x0000c080, 0x8000c080, 0x0080c080, 0x8080c080,
3690Sstevel@tonic-gate 0x40004000, 0xc0004000, 0x40804000, 0xc0804000,
3700Sstevel@tonic-gate 0x4000c000, 0xc000c000, 0x4080c000, 0xc080c000,
3710Sstevel@tonic-gate 0x40004080, 0xc0004080, 0x40804080, 0xc0804080,
3720Sstevel@tonic-gate 0x4000c080, 0xc000c080, 0x4080c080, 0xc080c080,
3730Sstevel@tonic-gate 0x00404000, 0x80404000, 0x00c04000, 0x80c04000,
3740Sstevel@tonic-gate 0x0040c000, 0x8040c000, 0x00c0c000, 0x80c0c000,
3750Sstevel@tonic-gate 0x00404080, 0x80404080, 0x00c04080, 0x80c04080,
3760Sstevel@tonic-gate 0x0040c080, 0x8040c080, 0x00c0c080, 0x80c0c080,
3770Sstevel@tonic-gate 0x40404000, 0xc0404000, 0x40c04000, 0xc0c04000,
3780Sstevel@tonic-gate 0x4040c000, 0xc040c000, 0x40c0c000, 0xc0c0c000,
3790Sstevel@tonic-gate 0x40404080, 0xc0404080, 0x40c04080, 0xc0c04080,
3800Sstevel@tonic-gate 0x4040c080, 0xc040c080, 0x40c0c080, 0xc0c0c080,
3810Sstevel@tonic-gate 0x00000040, 0x80000040, 0x00800040, 0x80800040,
3820Sstevel@tonic-gate 0x00008040, 0x80008040, 0x00808040, 0x80808040,
3830Sstevel@tonic-gate 0x000000c0, 0x800000c0, 0x008000c0, 0x808000c0,
3840Sstevel@tonic-gate 0x000080c0, 0x800080c0, 0x008080c0, 0x808080c0,
3850Sstevel@tonic-gate 0x40000040, 0xc0000040, 0x40800040, 0xc0800040,
3860Sstevel@tonic-gate 0x40008040, 0xc0008040, 0x40808040, 0xc0808040,
3870Sstevel@tonic-gate 0x400000c0, 0xc00000c0, 0x408000c0, 0xc08000c0,
3880Sstevel@tonic-gate 0x400080c0, 0xc00080c0, 0x408080c0, 0xc08080c0,
3890Sstevel@tonic-gate 0x00400040, 0x80400040, 0x00c00040, 0x80c00040,
3900Sstevel@tonic-gate 0x00408040, 0x80408040, 0x00c08040, 0x80c08040,
3910Sstevel@tonic-gate 0x004000c0, 0x804000c0, 0x00c000c0, 0x80c000c0,
3920Sstevel@tonic-gate 0x004080c0, 0x804080c0, 0x00c080c0, 0x80c080c0,
3930Sstevel@tonic-gate 0x40400040, 0xc0400040, 0x40c00040, 0xc0c00040,
3940Sstevel@tonic-gate 0x40408040, 0xc0408040, 0x40c08040, 0xc0c08040,
3950Sstevel@tonic-gate 0x404000c0, 0xc04000c0, 0x40c000c0, 0xc0c000c0,
3960Sstevel@tonic-gate 0x404080c0, 0xc04080c0, 0x40c080c0, 0xc0c080c0,
3970Sstevel@tonic-gate 0x00004040, 0x80004040, 0x00804040, 0x80804040,
3980Sstevel@tonic-gate 0x0000c040, 0x8000c040, 0x0080c040, 0x8080c040,
3990Sstevel@tonic-gate 0x000040c0, 0x800040c0, 0x008040c0, 0x808040c0,
4000Sstevel@tonic-gate 0x0000c0c0, 0x8000c0c0, 0x0080c0c0, 0x8080c0c0,
4010Sstevel@tonic-gate 0x40004040, 0xc0004040, 0x40804040, 0xc0804040,
4020Sstevel@tonic-gate 0x4000c040, 0xc000c040, 0x4080c040, 0xc080c040,
4030Sstevel@tonic-gate 0x400040c0, 0xc00040c0, 0x408040c0, 0xc08040c0,
4040Sstevel@tonic-gate 0x4000c0c0, 0xc000c0c0, 0x4080c0c0, 0xc080c0c0,
4050Sstevel@tonic-gate 0x00404040, 0x80404040, 0x00c04040, 0x80c04040,
4060Sstevel@tonic-gate 0x0040c040, 0x8040c040, 0x00c0c040, 0x80c0c040,
4070Sstevel@tonic-gate 0x004040c0, 0x804040c0, 0x00c040c0, 0x80c040c0,
4080Sstevel@tonic-gate 0x0040c0c0, 0x8040c0c0, 0x00c0c0c0, 0x80c0c0c0,
4090Sstevel@tonic-gate 0x40404040, 0xc0404040, 0x40c04040, 0xc0c04040,
4100Sstevel@tonic-gate 0x4040c040, 0xc040c040, 0x40c0c040, 0xc0c0c040,
4110Sstevel@tonic-gate 0x404040c0, 0xc04040c0, 0x40c040c0, 0xc0c040c0,
4120Sstevel@tonic-gate 0x4040c0c0, 0xc040c0c0, 0x40c0c0c0, 0xc0c0c0c0
4130Sstevel@tonic-gate };
4140Sstevel@tonic-gate 
415416Skrishna static const uint64_t all_a = 0xaaaaaaaaaaaaaaaaULL;
416416Skrishna static const uint64_t all_5 = 0x5555555555555555ULL;
417416Skrishna static const uint64_t top_1 = 0xfc000000000000ULL;
418416Skrishna static const uint64_t mid_4 = 0x3fffffc000000ULL;
419416Skrishna static const uint64_t low_3 = 0x3ffff00ULL;
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate static void
4230Sstevel@tonic-gate des_ip(uint64_t *l, uint64_t *r, uint64_t pt)
4240Sstevel@tonic-gate {
4250Sstevel@tonic-gate 	uint64_t a, b;
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 	a = pt & all_a;
4280Sstevel@tonic-gate 	b = pt & all_5;
4290Sstevel@tonic-gate 	a = a | (a << 7);
4300Sstevel@tonic-gate 	b = b | (b >> 7);
4310Sstevel@tonic-gate 
432416Skrishna 	b = (ip_table[0][(b >> 48) & 255ULL]) |
433416Skrishna 		(ip_table[1][(b >> 32) & 255ULL]) |
434416Skrishna 		(ip_table[0][(b >> 16) & 255ULL] << 6) |
435416Skrishna 		(ip_table[1][b & 255ULL] << 6);
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 	a = (ip_table[0][(a >> 56) & 255]) |
4380Sstevel@tonic-gate 		(ip_table[1][(a >> 40) & 255]) |
4390Sstevel@tonic-gate 		(ip_table[0][(a >> 24) & 255] << 6) |
4400Sstevel@tonic-gate 		(ip_table[1][(a >> 8) & 255] << 6);
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 	*l = ((b & top_1) << 8) |
4430Sstevel@tonic-gate 		(b & mid_4) |
4440Sstevel@tonic-gate 		((b & low_3) >> 5);
4450Sstevel@tonic-gate 
4460Sstevel@tonic-gate 	*r = ((a & top_1) << 8) |
4470Sstevel@tonic-gate 		(a & mid_4) |
4480Sstevel@tonic-gate 		((a & low_3) >> 5);
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate static uint64_t
4530Sstevel@tonic-gate des_fp(uint64_t l, uint64_t r)
4540Sstevel@tonic-gate {
4550Sstevel@tonic-gate 	uint32_t upper, lower;
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate 	lower = fp_table[((l >> 55) & 240) | ((r >> 59) & 15)] |
4580Sstevel@tonic-gate 		(fp_table[((l >> 35) & 240) | ((r>>39) & 15)] >> 2) |
4590Sstevel@tonic-gate 		(fp_table[((l >> 23) & 240) | ((r >> 27) & 15)] >> 4) |
4600Sstevel@tonic-gate 		(fp_table[((l >> 6) & 240) | ((r >> 10) & 15)] >> 6);
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate 	upper = fp_table[((l >> 41) & 240) | ((r >> 45) & 15)] |
4630Sstevel@tonic-gate 		(fp_table[((l >> 29) & 240) | ((r >> 33) & 15)] >> 2) |
4640Sstevel@tonic-gate 		(fp_table[((l >> 12) & 240) | ((r >> 16) & 15)] >> 4) |
4650Sstevel@tonic-gate 		(fp_table[(l & 240) | (r >> 4) & 15] >> 6);
4660Sstevel@tonic-gate 
4670Sstevel@tonic-gate 	return ((((uint64_t)upper) << 32) | (uint64_t)lower);
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate }
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate uint64_t
4720Sstevel@tonic-gate des_crypt_impl(uint64_t *ks, uint64_t block, int one_or_three)
4730Sstevel@tonic-gate {
4740Sstevel@tonic-gate 	int i, j;
4750Sstevel@tonic-gate 	uint64_t l, r, t;
4760Sstevel@tonic-gate 
4770Sstevel@tonic-gate 	des_ip(&l, &r, block);
4780Sstevel@tonic-gate 	for (j = 0; j < one_or_three; j++) {
4790Sstevel@tonic-gate 		for (i = j * 16; i < (j + 1) * 16; i++) {
4800Sstevel@tonic-gate 			t = r ^ ks[i];
4810Sstevel@tonic-gate 			t = sbox_table[0][t >> 58] |
4820Sstevel@tonic-gate 				sbox_table[1][(t >> 44) & 63] |
4830Sstevel@tonic-gate 				sbox_table[2][(t >> 38) & 63] |
4840Sstevel@tonic-gate 				sbox_table[3][(t >> 32) & 63] |
4850Sstevel@tonic-gate 				sbox_table[4][(t >> 26) & 63] |
4860Sstevel@tonic-gate 				sbox_table[5][(t >> 15) & 63] |
4870Sstevel@tonic-gate 				sbox_table[6][(t >> 9) & 63] |
4880Sstevel@tonic-gate 				sbox_table[7][(t >> 3) & 63];
4890Sstevel@tonic-gate 			t = t^l;
4900Sstevel@tonic-gate 			l = r;
4910Sstevel@tonic-gate 			r = t;
4920Sstevel@tonic-gate 		}
4930Sstevel@tonic-gate 		r = l;
4940Sstevel@tonic-gate 		l = t;
4950Sstevel@tonic-gate 	}
4960Sstevel@tonic-gate 
4970Sstevel@tonic-gate 	return (des_fp(l, r));
4980Sstevel@tonic-gate }
4990Sstevel@tonic-gate #endif /* !sun4u */
5000Sstevel@tonic-gate 
5010Sstevel@tonic-gate /* EXPORT DELETE END */
5020Sstevel@tonic-gate 
5030Sstevel@tonic-gate void
5040Sstevel@tonic-gate des3_crunch_block(void *cookie, uint8_t block[DES_BLOCK_LEN],
5050Sstevel@tonic-gate     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
5060Sstevel@tonic-gate {
5070Sstevel@tonic-gate /* EXPORT DELETE START */
5080Sstevel@tonic-gate 	keysched3_t *ksch = (keysched3_t *)cookie;
5090Sstevel@tonic-gate 
5100Sstevel@tonic-gate 	/*
5110Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
5120Sstevel@tonic-gate 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
5130Sstevel@tonic-gate 	 * copies the block without reversing bytes.
5140Sstevel@tonic-gate 	 */
5150Sstevel@tonic-gate #ifdef _BIG_ENDIAN
5160Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
5170Sstevel@tonic-gate 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
5180Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5190Sstevel@tonic-gate 			/* LINTED */
5200Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5210Sstevel@tonic-gate 			    ksch->ksch_decrypt,
5220Sstevel@tonic-gate 			    /* LINTED */
5230Sstevel@tonic-gate 			    *(uint64_t *)block, 3);
5240Sstevel@tonic-gate 		else
5250Sstevel@tonic-gate 			/* LINTED */
5260Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5270Sstevel@tonic-gate 			    ksch->ksch_encrypt,
5280Sstevel@tonic-gate 			    /* LINTED */
5290Sstevel@tonic-gate 			    *(uint64_t *)block, 3);
5300Sstevel@tonic-gate 	} else {
5310Sstevel@tonic-gate #endif
5320Sstevel@tonic-gate 		uint64_t tmp;
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
5350Sstevel@tonic-gate 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
5360Sstevel@tonic-gate 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
5370Sstevel@tonic-gate 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
5380Sstevel@tonic-gate 
5390Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5400Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 3);
5410Sstevel@tonic-gate 		else
5420Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 3);
5430Sstevel@tonic-gate 
5440Sstevel@tonic-gate 		out_block[0] = tmp >> 56;
5450Sstevel@tonic-gate 		out_block[1] = tmp >> 48;
5460Sstevel@tonic-gate 		out_block[2] = tmp >> 40;
5470Sstevel@tonic-gate 		out_block[3] = tmp >> 32;
5480Sstevel@tonic-gate 		out_block[4] = tmp >> 24;
5490Sstevel@tonic-gate 		out_block[5] = tmp >> 16;
5500Sstevel@tonic-gate 		out_block[6] = tmp >> 8;
5510Sstevel@tonic-gate 		out_block[7] = (uint8_t)tmp;
5520Sstevel@tonic-gate #ifdef _BIG_ENDIAN
5530Sstevel@tonic-gate 	}
5540Sstevel@tonic-gate #endif
5550Sstevel@tonic-gate /* EXPORT DELETE END */
5560Sstevel@tonic-gate }
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate void
5590Sstevel@tonic-gate des_crunch_block(void *cookie, uint8_t block[DES_BLOCK_LEN],
5600Sstevel@tonic-gate     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
5610Sstevel@tonic-gate {
5620Sstevel@tonic-gate /* EXPORT DELETE START */
5630Sstevel@tonic-gate 	keysched_t *ksch = (keysched_t *)cookie;
5640Sstevel@tonic-gate 
5650Sstevel@tonic-gate 	/*
5660Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
5670Sstevel@tonic-gate 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
5680Sstevel@tonic-gate 	 * copies the block without reversing bytes.
5690Sstevel@tonic-gate 	 */
5700Sstevel@tonic-gate #ifdef _BIG_ENDIAN
5710Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
5720Sstevel@tonic-gate 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
5730Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5740Sstevel@tonic-gate 			/* LINTED */
5750Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5760Sstevel@tonic-gate 			    ksch->ksch_decrypt,
5770Sstevel@tonic-gate 			    /* LINTED */
5780Sstevel@tonic-gate 			    *(uint64_t *)block, 1);
5790Sstevel@tonic-gate 		else
5800Sstevel@tonic-gate 			/* LINTED */
5810Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5820Sstevel@tonic-gate 			    ksch->ksch_encrypt,
5830Sstevel@tonic-gate 			    /* LINTED */
5840Sstevel@tonic-gate 			    *(uint64_t *)block, 1);
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 	} else {
5870Sstevel@tonic-gate #endif
5880Sstevel@tonic-gate 		uint64_t tmp;
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
5910Sstevel@tonic-gate 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
5920Sstevel@tonic-gate 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
5930Sstevel@tonic-gate 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5960Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 1);
5970Sstevel@tonic-gate 		else
5980Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 1);
5990Sstevel@tonic-gate 
6000Sstevel@tonic-gate 		out_block[0] = tmp >> 56;
6010Sstevel@tonic-gate 		out_block[1] = tmp >> 48;
6020Sstevel@tonic-gate 		out_block[2] = tmp >> 40;
6030Sstevel@tonic-gate 		out_block[3] = tmp >> 32;
6040Sstevel@tonic-gate 		out_block[4] = tmp >> 24;
6050Sstevel@tonic-gate 		out_block[5] = tmp >> 16;
6060Sstevel@tonic-gate 		out_block[6] = tmp >> 8;
6070Sstevel@tonic-gate 		out_block[7] = (uint8_t)tmp;
6080Sstevel@tonic-gate #ifdef _BIG_ENDIAN
6090Sstevel@tonic-gate 	}
6100Sstevel@tonic-gate #endif
6110Sstevel@tonic-gate /* EXPORT DELETE END */
6120Sstevel@tonic-gate }
6130Sstevel@tonic-gate 
6140Sstevel@tonic-gate static boolean_t
6150Sstevel@tonic-gate keycheck(uint8_t *key, uint8_t *corrected_key)
6160Sstevel@tonic-gate {
6170Sstevel@tonic-gate /* EXPORT DELETE START */
6180Sstevel@tonic-gate 	uint64_t key_so_far;
6190Sstevel@tonic-gate 	uint_t i;
6200Sstevel@tonic-gate 	/*
6210Sstevel@tonic-gate 	 * Table of weak and semi-weak keys.  Fortunately, weak keys are
6220Sstevel@tonic-gate 	 * endian-independent, and some semi-weak keys can be paired up in
6230Sstevel@tonic-gate 	 * endian-opposite order.  Since keys are stored as uint64_t's,
6240Sstevel@tonic-gate 	 * use the ifdef _LITTLE_ENDIAN where appropriate.
6250Sstevel@tonic-gate 	 */
6260Sstevel@tonic-gate 	static uint64_t des_weak_keys[] = {
6270Sstevel@tonic-gate 		/* Really weak keys.  Byte-order independent values. */
628416Skrishna 		0x0101010101010101ULL,
629416Skrishna 		0x1f1f1f1f0e0e0e0eULL,
630416Skrishna 		0xe0e0e0e0f1f1f1f1ULL,
631416Skrishna 		0xfefefefefefefefeULL,
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate 		/* Semi-weak (and a few possibly-weak) keys. */
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 		/* Byte-order independent semi-weak keys. */
636416Skrishna 		0x01fe01fe01fe01feULL,	0xfe01fe01fe01fe01ULL,
6370Sstevel@tonic-gate 
6380Sstevel@tonic-gate 		/* Byte-order dependent semi-weak keys. */
6390Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
640416Skrishna 		0xf10ef10ee01fe01fULL,	0x0ef10ef11fe01fe0ULL,
641416Skrishna 		0x01f101f101e001e0ULL,	0xf101f101e001e001ULL,
642416Skrishna 		0x0efe0efe1ffe1ffeULL,	0xfe0efe0efe1ffe1fULL,
643416Skrishna 		0x010e010e011f011fULL,	0x0e010e011f011f01ULL,
644416Skrishna 		0xf1fef1fee0fee0feULL,	0xfef1fef1fee0fee0ULL,
6450Sstevel@tonic-gate #else	/* Big endian */
646416Skrishna 		0x1fe01fe00ef10ef1ULL,	0xe01fe01ff10ef10eULL,
647416Skrishna 		0x01e001e001f101f1ULL,	0xe001e001f101f101ULL,
648416Skrishna 		0x1ffe1ffe0efe0efeULL,	0xfe1ffe1ffe0efe0eULL,
649416Skrishna 		0x011f011f010e010eULL,	0x1f011f010e010e01ULL,
650416Skrishna 		0xe0fee0fef1fef1feULL,	0xfee0fee0fef1fef1ULL,
6510Sstevel@tonic-gate #endif
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 		/* We'll save the other possibly-weak keys for the future. */
6540Sstevel@tonic-gate 	};
6550Sstevel@tonic-gate 
6560Sstevel@tonic-gate 	if (key == NULL)
6570Sstevel@tonic-gate 		return (B_FALSE);
6580Sstevel@tonic-gate 
6590Sstevel@tonic-gate 	/*
6600Sstevel@tonic-gate 	 * The code below reverses the bytes on LITTLE_ENDIAN machines.
6610Sstevel@tonic-gate 	 * On BIG_ENDIAN, the same code copies without reversing
6620Sstevel@tonic-gate 	 * the bytes.
6630Sstevel@tonic-gate 	 */
6640Sstevel@tonic-gate 	key_so_far = (((uint64_t)key[0] << 56) | ((uint64_t)key[1] << 48) |
6650Sstevel@tonic-gate 	    ((uint64_t)key[2] << 40) | ((uint64_t)key[3] << 32) |
6660Sstevel@tonic-gate 	    ((uint64_t)key[4] << 24) | ((uint64_t)key[5] << 16) |
6670Sstevel@tonic-gate 	    ((uint64_t)key[6] << 8) | (uint64_t)key[7]);
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	/*
6700Sstevel@tonic-gate 	 * Fix parity.
6710Sstevel@tonic-gate 	 */
6720Sstevel@tonic-gate 	fix_des_parity(&key_so_far);
673416Skrishna 	key_so_far ^= 0x0101010101010101ULL;
6740Sstevel@tonic-gate 
6750Sstevel@tonic-gate 	/* Do weak key check itself. */
6760Sstevel@tonic-gate 	for (i = 0; i < (sizeof (des_weak_keys) / sizeof (uint64_t)); i++)
6770Sstevel@tonic-gate 		if (key_so_far == des_weak_keys[i]) {
6780Sstevel@tonic-gate 			return (B_FALSE);
6790Sstevel@tonic-gate 		}
6800Sstevel@tonic-gate 
6810Sstevel@tonic-gate 	if (corrected_key != NULL) {
6820Sstevel@tonic-gate 		/*
6830Sstevel@tonic-gate 		 * The code below reverses the bytes on LITTLE_ENDIAN machines.
6840Sstevel@tonic-gate 		 * On BIG_ENDIAN, the same code copies without reversing
6850Sstevel@tonic-gate 		 * the bytes.
6860Sstevel@tonic-gate 		 */
6870Sstevel@tonic-gate 		corrected_key[0] = key_so_far >> 56;
6880Sstevel@tonic-gate 		corrected_key[1] = key_so_far >> 48;
6890Sstevel@tonic-gate 		corrected_key[2] = key_so_far >> 40;
6900Sstevel@tonic-gate 		corrected_key[3] = key_so_far >> 32;
6910Sstevel@tonic-gate 		corrected_key[4] = key_so_far >> 24;
6920Sstevel@tonic-gate 		corrected_key[5] = key_so_far >> 16;
6930Sstevel@tonic-gate 		corrected_key[6] = key_so_far >> 8;
6940Sstevel@tonic-gate 		corrected_key[7] = (uint8_t)key_so_far;
6950Sstevel@tonic-gate 	}
6960Sstevel@tonic-gate /* EXPORT DELETE END */
6970Sstevel@tonic-gate 	return (B_TRUE);
6980Sstevel@tonic-gate }
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate static boolean_t
7010Sstevel@tonic-gate des3_keycheck(uint8_t *key, uint8_t *corrected_key)
7020Sstevel@tonic-gate {
7030Sstevel@tonic-gate /* EXPORT DELETE START */
7040Sstevel@tonic-gate 	uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
7050Sstevel@tonic-gate 	uint64_t key_so_far, scratch, *currentkey;
7060Sstevel@tonic-gate 	uint_t j, num_weakkeys = 0;
7070Sstevel@tonic-gate 
7080Sstevel@tonic-gate 	if (key == NULL) {
7090Sstevel@tonic-gate 		return (B_FALSE);
7100Sstevel@tonic-gate 	}
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate 	if (!IS_P2ALIGNED(key, sizeof (uint64_t))) {
7130Sstevel@tonic-gate 		bcopy(key, aligned_key, DES3_KEYSIZE);
7140Sstevel@tonic-gate 		currentkey = (uint64_t *)aligned_key;
7150Sstevel@tonic-gate 	} else {
7160Sstevel@tonic-gate 		/* LINTED */
7170Sstevel@tonic-gate 		currentkey = (uint64_t *)key;
7180Sstevel@tonic-gate 	}
7190Sstevel@tonic-gate 
7200Sstevel@tonic-gate 	for (j = 0; j < 3; j++) {
7210Sstevel@tonic-gate 		key_so_far = currentkey[j];
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate 		if (!keycheck((uint8_t *)&key_so_far, (uint8_t *)&scratch)) {
7240Sstevel@tonic-gate 			if (++num_weakkeys > 1) {
7250Sstevel@tonic-gate 				return (B_FALSE);
7260Sstevel@tonic-gate 			}
7270Sstevel@tonic-gate 			/*
7280Sstevel@tonic-gate 			 * We found a weak key, but since
7290Sstevel@tonic-gate 			 * we've only found one weak key,
7300Sstevel@tonic-gate 			 * we can not reject the whole 3DES
7310Sstevel@tonic-gate 			 * set of keys as weak.
7320Sstevel@tonic-gate 			 *
7330Sstevel@tonic-gate 			 * Break from the weak key loop
7340Sstevel@tonic-gate 			 * (since this DES key is weak) and
7350Sstevel@tonic-gate 			 * continue on.
7360Sstevel@tonic-gate 			 */
7370Sstevel@tonic-gate 		}
7380Sstevel@tonic-gate 
7390Sstevel@tonic-gate 		currentkey[j] = scratch;
7400Sstevel@tonic-gate 	}
7410Sstevel@tonic-gate 
7420Sstevel@tonic-gate 	/*
7430Sstevel@tonic-gate 	 * Perform key equivalence checks, now that parity is properly set.
744*1065Smarkfen 	 * 1st and 2nd keys must be unique, the 3rd key can be the same as
745*1065Smarkfen 	 * the 1st key for the 2 key varient of 3DES.
7460Sstevel@tonic-gate 	 */
747*1065Smarkfen 	if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2])
7480Sstevel@tonic-gate 		return (B_FALSE);
7490Sstevel@tonic-gate 
7500Sstevel@tonic-gate 	if (corrected_key != NULL) {
7510Sstevel@tonic-gate 		bcopy(currentkey, corrected_key, DES3_KEYSIZE);
7520Sstevel@tonic-gate 	}
7530Sstevel@tonic-gate /* EXPORT DELETE END */
7540Sstevel@tonic-gate 	return (B_TRUE);
7550Sstevel@tonic-gate }
7560Sstevel@tonic-gate 
7570Sstevel@tonic-gate boolean_t
7580Sstevel@tonic-gate des_keycheck(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
7590Sstevel@tonic-gate {
7600Sstevel@tonic-gate 	if (strength == DES) {
7610Sstevel@tonic-gate 		return (keycheck(key, corrected_key));
7620Sstevel@tonic-gate 	} else if (strength == DES3) {
7630Sstevel@tonic-gate 		return (des3_keycheck(key, corrected_key));
7640Sstevel@tonic-gate 	} else {
7650Sstevel@tonic-gate 		return (B_FALSE);
7660Sstevel@tonic-gate 	}
7670Sstevel@tonic-gate }
7680Sstevel@tonic-gate 
7690Sstevel@tonic-gate /*
7700Sstevel@tonic-gate  * Initialize key schedule for DES, DES2, and DES3
7710Sstevel@tonic-gate  */
7720Sstevel@tonic-gate void
7730Sstevel@tonic-gate des_init_keysched(uint8_t *cipherKey, des_strength_t strength, void *ks)
7740Sstevel@tonic-gate {
7750Sstevel@tonic-gate /* EXPORT DELETE START */
7760Sstevel@tonic-gate 	uint64_t *encryption_ks;
7770Sstevel@tonic-gate 	uint64_t *decryption_ks;
7780Sstevel@tonic-gate 	uint64_t keysched[48];
7790Sstevel@tonic-gate 	uint64_t key_uint64[3];
7800Sstevel@tonic-gate 	uint64_t tmp;
7810Sstevel@tonic-gate 	uint_t keysize, i, j;
7820Sstevel@tonic-gate 
7830Sstevel@tonic-gate 	switch (strength) {
7840Sstevel@tonic-gate 	case DES:
7850Sstevel@tonic-gate 		keysize = DES_KEYSIZE;
7860Sstevel@tonic-gate 		encryption_ks = ((keysched_t *)ks)->ksch_encrypt;
7870Sstevel@tonic-gate 		decryption_ks = ((keysched_t *)ks)->ksch_decrypt;
7880Sstevel@tonic-gate 		break;
7890Sstevel@tonic-gate 	case DES2:
7900Sstevel@tonic-gate 		keysize = DES2_KEYSIZE;
7910Sstevel@tonic-gate 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
7920Sstevel@tonic-gate 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
7930Sstevel@tonic-gate 		break;
7940Sstevel@tonic-gate 	case DES3:
7950Sstevel@tonic-gate 		keysize = DES3_KEYSIZE;
7960Sstevel@tonic-gate 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
7970Sstevel@tonic-gate 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
7980Sstevel@tonic-gate 	}
7990Sstevel@tonic-gate 
8000Sstevel@tonic-gate 	/*
8010Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
8020Sstevel@tonic-gate 	 * reverses every 8 bytes in the key.  On BIG_ENDIAN, the same code
8030Sstevel@tonic-gate 	 * copies the key without reversing bytes.
8040Sstevel@tonic-gate 	 */
8050Sstevel@tonic-gate #ifdef _BIG_ENDIAN
8060Sstevel@tonic-gate 	if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) {
8070Sstevel@tonic-gate 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
8080Sstevel@tonic-gate 			/* LINTED: pointer alignment */
8090Sstevel@tonic-gate 			key_uint64[i] = *((uint64_t *)&cipherKey[j]);
8100Sstevel@tonic-gate 		}
8110Sstevel@tonic-gate 	} else {
8120Sstevel@tonic-gate #endif
8130Sstevel@tonic-gate 	{
8140Sstevel@tonic-gate 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
8150Sstevel@tonic-gate 			key_uint64[i] = (((uint64_t)cipherKey[j] << 56) |
8160Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 1] << 48) |
8170Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 2] << 40) |
8180Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 3] << 32) |
8190Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 4] << 24) |
8200Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 5] << 16) |
8210Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 6] << 8) |
8220Sstevel@tonic-gate 			    (uint64_t)cipherKey[j + 7]);
8230Sstevel@tonic-gate 		}
8240Sstevel@tonic-gate 	}
8250Sstevel@tonic-gate #ifdef _BIG_ENDIAN
8260Sstevel@tonic-gate 	}
8270Sstevel@tonic-gate #endif
8280Sstevel@tonic-gate 
8290Sstevel@tonic-gate 	switch (strength) {
8300Sstevel@tonic-gate 	case DES:
8310Sstevel@tonic-gate 		des_ks(keysched, key_uint64[0]);
8320Sstevel@tonic-gate 		break;
8330Sstevel@tonic-gate 
8340Sstevel@tonic-gate 	case DES2:
8350Sstevel@tonic-gate 		/* DES2 is just DES3 with the first and third keys the same */
8360Sstevel@tonic-gate 		bcopy(key_uint64, key_uint64 + 2, DES_KEYSIZE);
8370Sstevel@tonic-gate 		/* FALLTHRU */
8380Sstevel@tonic-gate 	case DES3:
8390Sstevel@tonic-gate 		des_ks(keysched, key_uint64[0]);
8400Sstevel@tonic-gate 		des_ks(keysched + 16, key_uint64[1]);
8410Sstevel@tonic-gate 		for (i = 0; i < 8; i++) {
8420Sstevel@tonic-gate 			tmp = keysched[16+i];
8430Sstevel@tonic-gate 			keysched[16+i] = keysched[31-i];
8440Sstevel@tonic-gate 			keysched[31-i] = tmp;
8450Sstevel@tonic-gate 		}
8460Sstevel@tonic-gate 		des_ks(keysched+32, key_uint64[2]);
8470Sstevel@tonic-gate 		keysize = DES3_KEYSIZE;
8480Sstevel@tonic-gate 	}
8490Sstevel@tonic-gate 
8500Sstevel@tonic-gate 	/* save the encryption keyschedule */
8510Sstevel@tonic-gate 	bcopy(keysched, encryption_ks, keysize * 16);
8520Sstevel@tonic-gate 
8530Sstevel@tonic-gate 	/* reverse the key schedule */
8540Sstevel@tonic-gate 	for (i = 0; i < keysize; i++) {
8550Sstevel@tonic-gate 		tmp = keysched[i];
8560Sstevel@tonic-gate 		keysched[i] = keysched[2 * keysize - 1 - i];
8570Sstevel@tonic-gate 		keysched[2 * keysize -1 -i] = tmp;
8580Sstevel@tonic-gate 	}
8590Sstevel@tonic-gate 
8600Sstevel@tonic-gate 	/* save the decryption keyschedule */
8610Sstevel@tonic-gate 	bcopy(keysched, decryption_ks, keysize * 16);
8620Sstevel@tonic-gate /* EXPORT DELETE END */
8630Sstevel@tonic-gate }
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate /*
8660Sstevel@tonic-gate  * Allocate key schedule.
8670Sstevel@tonic-gate  */
8680Sstevel@tonic-gate /*ARGSUSED*/
8690Sstevel@tonic-gate void *
8700Sstevel@tonic-gate des_alloc_keysched(size_t *keysched_size, des_strength_t strength, int kmflag)
8710Sstevel@tonic-gate {
8720Sstevel@tonic-gate 	void *keysched;
8730Sstevel@tonic-gate 
8740Sstevel@tonic-gate /* EXPORT DELETE START */
8750Sstevel@tonic-gate 
8760Sstevel@tonic-gate 	size_t size;
8770Sstevel@tonic-gate 
8780Sstevel@tonic-gate 	switch (strength) {
8790Sstevel@tonic-gate 	case DES:
8800Sstevel@tonic-gate 		size = sizeof (keysched_t);
8810Sstevel@tonic-gate 		break;
8820Sstevel@tonic-gate 	case DES2:
8830Sstevel@tonic-gate 	case DES3:
8840Sstevel@tonic-gate 		size = sizeof (keysched3_t);
8850Sstevel@tonic-gate 	}
8860Sstevel@tonic-gate 
8870Sstevel@tonic-gate #ifdef	_KERNEL
8880Sstevel@tonic-gate 	keysched = (keysched_t *)kmem_alloc(size, kmflag);
8890Sstevel@tonic-gate #else	/* !_KERNEL */
8900Sstevel@tonic-gate 	keysched = (keysched_t *)malloc(size);
8910Sstevel@tonic-gate #endif	/* _KERNEL */
8920Sstevel@tonic-gate 
8930Sstevel@tonic-gate 	if (keysched == NULL)
8940Sstevel@tonic-gate 		return (NULL);
8950Sstevel@tonic-gate 
8960Sstevel@tonic-gate 	if (keysched_size != NULL)
8970Sstevel@tonic-gate 		*keysched_size = size;
8980Sstevel@tonic-gate 
8990Sstevel@tonic-gate /* EXPORT DELETE END */
9000Sstevel@tonic-gate 
9010Sstevel@tonic-gate 	return (keysched);
9020Sstevel@tonic-gate }
9030Sstevel@tonic-gate 
9040Sstevel@tonic-gate /*
9050Sstevel@tonic-gate  * Replace the LSB of each byte by the xor of the other
9060Sstevel@tonic-gate  * 7 bits.  The tricky thing is that the original contents of the LSBs
9070Sstevel@tonic-gate  * are nullifed by including them twice in the xor computation.
9080Sstevel@tonic-gate  */
9090Sstevel@tonic-gate static void
9100Sstevel@tonic-gate fix_des_parity(uint64_t *keyp)
9110Sstevel@tonic-gate {
9120Sstevel@tonic-gate /* EXPORT DELETE START */
9130Sstevel@tonic-gate 	uint64_t k = *keyp;
9140Sstevel@tonic-gate 	k ^= k >> 1;
9150Sstevel@tonic-gate 	k ^= k >> 2;
9160Sstevel@tonic-gate 	k ^= k >> 4;
917416Skrishna 	*keyp ^= (k & 0x0101010101010101ULL);
9180Sstevel@tonic-gate /* EXPORT DELETE END */
9190Sstevel@tonic-gate }
920