xref: /onnv-gate/usr/src/common/crypto/des/des_impl.c (revision 10444:713f936eb685)
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
52439Sizick  * Common Development and Distribution License (the "License").
62439Sizick  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*10444SVladimir.Kotal@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate #include <sys/systm.h>
280Sstevel@tonic-gate #include <sys/ddi.h>
290Sstevel@tonic-gate #include <sys/sysmacros.h>
300Sstevel@tonic-gate #include <sys/strsun.h>
317188Smcpowers #include <sys/crypto/spi.h>
327188Smcpowers #include <modes/modes.h>
330Sstevel@tonic-gate #include <sys/crypto/common.h>
340Sstevel@tonic-gate #include "des_impl.h"
350Sstevel@tonic-gate #ifndef	_KERNEL
360Sstevel@tonic-gate #include <strings.h>
370Sstevel@tonic-gate #include <stdlib.h>
380Sstevel@tonic-gate #endif	/* !_KERNEL */
390Sstevel@tonic-gate 
407421SDaniel.Anderson@Sun.COM #if defined(__i386) || defined(__amd64)
417421SDaniel.Anderson@Sun.COM #include <sys/byteorder.h>
427421SDaniel.Anderson@Sun.COM #define	UNALIGNED_POINTERS_PERMITTED
437421SDaniel.Anderson@Sun.COM #endif
447421SDaniel.Anderson@Sun.COM 
450Sstevel@tonic-gate /* EXPORT DELETE START */
460Sstevel@tonic-gate 
470Sstevel@tonic-gate typedef struct keysched_s {
480Sstevel@tonic-gate 	uint64_t ksch_encrypt[16];
490Sstevel@tonic-gate 	uint64_t ksch_decrypt[16];
500Sstevel@tonic-gate } keysched_t;
510Sstevel@tonic-gate 
520Sstevel@tonic-gate typedef struct keysched3_s {
530Sstevel@tonic-gate 	uint64_t ksch_encrypt[48];
540Sstevel@tonic-gate 	uint64_t ksch_decrypt[48];
550Sstevel@tonic-gate } keysched3_t;
560Sstevel@tonic-gate 
570Sstevel@tonic-gate static void fix_des_parity(uint64_t *);
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #ifndef sun4u
600Sstevel@tonic-gate 
610Sstevel@tonic-gate static const uint64_t sbox_table[8][64]=
620Sstevel@tonic-gate {
63416Skrishna /* BEGIN CSTYLED */
640Sstevel@tonic-gate {
65416Skrishna 0x0000140140020000ULL, 0x0000000000000000ULL, 0x0000000140000000ULL, 0x0000140140020020ULL,
66416Skrishna 0x0000140140000020ULL, 0x0000000140020020ULL, 0x0000000000000020ULL, 0x0000000140000000ULL,
67416Skrishna 0x0000000000020000ULL, 0x0000140140020000ULL, 0x0000140140020020ULL, 0x0000000000020000ULL,
68416Skrishna 0x0000140000020020ULL, 0x0000140140000020ULL, 0x0000140000000000ULL, 0x0000000000000020ULL,
69416Skrishna 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000140020000ULL,
70416Skrishna 0x0000000140020000ULL, 0x0000140140000000ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
71416Skrishna 0x0000000140000020ULL, 0x0000140000000020ULL, 0x0000140000000020ULL, 0x0000000140000020ULL,
72416Skrishna 0x0000000000000000ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140000000000ULL,
73416Skrishna 0x0000000140000000ULL, 0x0000140140020020ULL, 0x0000000000000020ULL, 0x0000140140000000ULL,
74416Skrishna 0x0000140140020000ULL, 0x0000140000000000ULL, 0x0000140000000000ULL, 0x0000000000020000ULL,
75416Skrishna 0x0000140140000020ULL, 0x0000000140000000ULL, 0x0000000140020000ULL, 0x0000140000000020ULL,
76416Skrishna 0x0000000000020000ULL, 0x0000000000000020ULL, 0x0000140000020020ULL, 0x0000000140020020ULL,
77416Skrishna 0x0000140140020020ULL, 0x0000000140000020ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
78416Skrishna 0x0000140000000020ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140140020000ULL,
79416Skrishna 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000000000000ULL,
80416Skrishna 0x0000000140000020ULL, 0x0000000140020000ULL, 0x0000000000000000ULL, 0x0000140140000020ULL
810Sstevel@tonic-gate },
820Sstevel@tonic-gate {
83416Skrishna 0x2000005020000500ULL, 0x2000000020000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL,
84416Skrishna 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL, 0x2000000020000500ULL,
85416Skrishna 0x2000000000000500ULL, 0x2000005020000500ULL, 0x2000005020000000ULL, 0x2000000000000000ULL,
86416Skrishna 0x2000000020000000ULL, 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL,
87416Skrishna 0x0000005020000000ULL, 0x0000005000000500ULL, 0x2000000020000500ULL, 0x0000000000000000ULL,
88416Skrishna 0x2000000000000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL, 0x2000005000000000ULL,
89416Skrishna 0x0000005000000500ULL, 0x2000000000000500ULL, 0x0000000000000000ULL, 0x0000005020000000ULL,
90416Skrishna 0x0000000020000500ULL, 0x2000005020000000ULL, 0x2000005000000000ULL, 0x0000000020000500ULL,
91416Skrishna 0x0000000000000000ULL, 0x0000005020000500ULL, 0x2000005000000500ULL, 0x0000005000000000ULL,
92416Skrishna 0x2000000020000500ULL, 0x2000005000000000ULL, 0x2000005020000000ULL, 0x0000000020000000ULL,
93416Skrishna 0x2000005000000000ULL, 0x2000000020000000ULL, 0x0000000000000500ULL, 0x2000005020000500ULL,
94416Skrishna 0x0000005020000500ULL, 0x0000000000000500ULL, 0x0000000020000000ULL, 0x2000000000000000ULL,
95416Skrishna 0x0000000020000500ULL, 0x2000005020000000ULL, 0x0000005000000000ULL, 0x2000000000000500ULL,
96416Skrishna 0x0000005000000500ULL, 0x2000000020000500ULL, 0x2000000000000500ULL, 0x0000005000000500ULL,
97416Skrishna 0x0000005020000000ULL, 0x0000000000000000ULL, 0x2000000020000000ULL, 0x0000000020000500ULL,
98416Skrishna 0x2000000000000000ULL, 0x2000005000000500ULL, 0x2000005020000500ULL, 0x0000005020000000ULL
990Sstevel@tonic-gate },
1000Sstevel@tonic-gate {
101416Skrishna 0x0000000000014040ULL, 0x0000800280014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
102416Skrishna 0x0000800000014000ULL, 0x0000000000000000ULL, 0x0000000280014040ULL, 0x0000800000014000ULL,
103416Skrishna 0x0000000280000040ULL, 0x0000800000000040ULL, 0x0000800000000040ULL, 0x0000000280000000ULL,
104416Skrishna 0x0000800280014040ULL, 0x0000000280000040ULL, 0x0000800280000000ULL, 0x0000000000014040ULL,
105416Skrishna 0x0000800000000000ULL, 0x0000000000000040ULL, 0x0000800280014000ULL, 0x0000000000014000ULL,
106416Skrishna 0x0000000280014000ULL, 0x0000800280000000ULL, 0x0000800280000040ULL, 0x0000000280014040ULL,
107416Skrishna 0x0000800000014040ULL, 0x0000000280014000ULL, 0x0000000280000000ULL, 0x0000800000014040ULL,
108416Skrishna 0x0000000000000040ULL, 0x0000800280014040ULL, 0x0000000000014000ULL, 0x0000800000000000ULL,
109416Skrishna 0x0000800280014000ULL, 0x0000800000000000ULL, 0x0000000280000040ULL, 0x0000000000014040ULL,
110416Skrishna 0x0000000280000000ULL, 0x0000800280014000ULL, 0x0000800000014000ULL, 0x0000000000000000ULL,
111416Skrishna 0x0000000000014000ULL, 0x0000000280000040ULL, 0x0000800280014040ULL, 0x0000800000014000ULL,
112416Skrishna 0x0000800000000040ULL, 0x0000000000014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
113416Skrishna 0x0000800000014040ULL, 0x0000000280000000ULL, 0x0000800000000000ULL, 0x0000800280014040ULL,
114416Skrishna 0x0000000000000040ULL, 0x0000000280014040ULL, 0x0000000280014000ULL, 0x0000800000000040ULL,
115416Skrishna 0x0000800280000000ULL, 0x0000800000014040ULL, 0x0000000000014040ULL, 0x0000800280000000ULL,
116416Skrishna 0x0000000280014040ULL, 0x0000000000000040ULL, 0x0000800280000040ULL, 0x0000000280014000ULL
1170Sstevel@tonic-gate },
1180Sstevel@tonic-gate {
119416Skrishna 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
120416Skrishna 0x0000020008101000ULL, 0x4000020000001008ULL, 0x4000020000000008ULL, 0x4000000008100008ULL,
121416Skrishna 0x0000000000000000ULL, 0x0000020008100000ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
122416Skrishna 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000020000001000ULL, 0x4000020000000008ULL,
123416Skrishna 0x4000000000000008ULL, 0x0000000008100000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
124416Skrishna 0x0000000000001000ULL, 0x0000020000000000ULL, 0x4000000008100008ULL, 0x0000000008101000ULL,
125416Skrishna 0x4000020000001008ULL, 0x4000000000000008ULL, 0x0000000008101000ULL, 0x0000020000001000ULL,
126416Skrishna 0x0000000008100000ULL, 0x0000020008101000ULL, 0x4000020008101008ULL, 0x4000000000001008ULL,
127416Skrishna 0x0000020000001000ULL, 0x4000020000000008ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
128416Skrishna 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000020008100000ULL,
129416Skrishna 0x0000000008101000ULL, 0x0000020000001000ULL, 0x4000020000001008ULL, 0x4000000000000008ULL,
130416Skrishna 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
131416Skrishna 0x4000020008101008ULL, 0x4000000000001008ULL, 0x4000000000000008ULL, 0x0000000008100000ULL,
132416Skrishna 0x4000020000000008ULL, 0x4000000008100008ULL, 0x0000020008101000ULL, 0x4000020000001008ULL,
133416Skrishna 0x4000000008100008ULL, 0x0000000008101000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
134416Skrishna 0x0000000000001000ULL, 0x0000020000000000ULL, 0x0000000008100000ULL, 0x0000020008101000ULL
1350Sstevel@tonic-gate },
1360Sstevel@tonic-gate {
137416Skrishna 0x000000000000a000ULL, 0x000028080000a000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL,
138416Skrishna 0x0000000800000000ULL, 0x000000000000a000ULL, 0x1000000000000000ULL, 0x0000280800000000ULL,
139416Skrishna 0x100000080000a000ULL, 0x0000000800000000ULL, 0x000028000000a000ULL, 0x100000080000a000ULL,
140416Skrishna 0x100028000000a000ULL, 0x1000280800000000ULL, 0x000000080000a000ULL, 0x1000000000000000ULL,
141416Skrishna 0x0000280000000000ULL, 0x1000000800000000ULL, 0x1000000800000000ULL, 0x0000000000000000ULL,
142416Skrishna 0x100000000000a000ULL, 0x100028080000a000ULL, 0x100028080000a000ULL, 0x000028000000a000ULL,
143416Skrishna 0x1000280800000000ULL, 0x100000000000a000ULL, 0x0000000000000000ULL, 0x1000280000000000ULL,
144416Skrishna 0x000028080000a000ULL, 0x0000280000000000ULL, 0x1000280000000000ULL, 0x000000080000a000ULL,
145416Skrishna 0x0000000800000000ULL, 0x100028000000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL,
146416Skrishna 0x1000000000000000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL, 0x100000080000a000ULL,
147416Skrishna 0x000028000000a000ULL, 0x1000000000000000ULL, 0x1000280800000000ULL, 0x000028080000a000ULL,
148416Skrishna 0x100000080000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL, 0x1000280800000000ULL,
149416Skrishna 0x100028080000a000ULL, 0x000000080000a000ULL, 0x1000280000000000ULL, 0x100028080000a000ULL,
150416Skrishna 0x0000280800000000ULL, 0x0000000000000000ULL, 0x1000000800000000ULL, 0x1000280000000000ULL,
151416Skrishna 0x000000080000a000ULL, 0x000028000000a000ULL, 0x100000000000a000ULL, 0x0000000800000000ULL,
152416Skrishna 0x0000000000000000ULL, 0x1000000800000000ULL, 0x000028080000a000ULL, 0x100000000000a000ULL
1530Sstevel@tonic-gate },
1540Sstevel@tonic-gate {
155416Skrishna 0x0802000000000280ULL, 0x0802010000000000ULL, 0x0000000010000000ULL, 0x0802010010000280ULL,
156416Skrishna 0x0802010000000000ULL, 0x0000000000000280ULL, 0x0802010010000280ULL, 0x0000010000000000ULL,
157416Skrishna 0x0802000010000000ULL, 0x0000010010000280ULL, 0x0000010000000000ULL, 0x0802000000000280ULL,
158416Skrishna 0x0000010000000280ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
159416Skrishna 0x0000000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000010000000ULL,
160416Skrishna 0x0000010010000000ULL, 0x0802000010000280ULL, 0x0000000000000280ULL, 0x0802010000000280ULL,
161416Skrishna 0x0802010000000280ULL, 0x0000000000000000ULL, 0x0000010010000280ULL, 0x0802010010000000ULL,
162416Skrishna 0x0000000010000280ULL, 0x0000010010000000ULL, 0x0802010010000000ULL, 0x0802000000000000ULL,
163416Skrishna 0x0802000010000000ULL, 0x0000000000000280ULL, 0x0802010000000280ULL, 0x0000010010000000ULL,
164416Skrishna 0x0802010010000280ULL, 0x0000010000000000ULL, 0x0000000010000280ULL, 0x0802000000000280ULL,
165416Skrishna 0x0000010000000000ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
166416Skrishna 0x0802000000000280ULL, 0x0802010010000280ULL, 0x0000010010000000ULL, 0x0802010000000000ULL,
167416Skrishna 0x0000010010000280ULL, 0x0802010010000000ULL, 0x0000000000000000ULL, 0x0802010000000280ULL,
168416Skrishna 0x0000000000000280ULL, 0x0000000010000000ULL, 0x0802010000000000ULL, 0x0000010010000280ULL,
169416Skrishna 0x0000000010000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000000000000ULL,
170416Skrishna 0x0802010010000000ULL, 0x0802000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL
1710Sstevel@tonic-gate },
1720Sstevel@tonic-gate {
173416Skrishna 0x000000a000000000ULL, 0x800040a000000010ULL, 0x8000400000040010ULL, 0x0000000000000000ULL,
174416Skrishna 0x0000000000040000ULL, 0x8000400000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
175416Skrishna 0x800040a000040010ULL, 0x000000a000000000ULL, 0x0000000000000000ULL, 0x8000400000000010ULL,
176416Skrishna 0x8000000000000010ULL, 0x0000400000000000ULL, 0x800040a000000010ULL, 0x8000000000040010ULL,
177416Skrishna 0x0000400000040000ULL, 0x800000a000040010ULL, 0x800000a000000010ULL, 0x0000400000040000ULL,
178416Skrishna 0x8000400000000010ULL, 0x000040a000000000ULL, 0x000040a000040000ULL, 0x800000a000000010ULL,
179416Skrishna 0x000040a000000000ULL, 0x0000000000040000ULL, 0x8000000000040010ULL, 0x800040a000040010ULL,
180416Skrishna 0x000000a000040000ULL, 0x8000000000000010ULL, 0x0000400000000000ULL, 0x000000a000040000ULL,
181416Skrishna 0x0000400000000000ULL, 0x000000a000040000ULL, 0x000000a000000000ULL, 0x8000400000040010ULL,
182416Skrishna 0x8000400000040010ULL, 0x800040a000000010ULL, 0x800040a000000010ULL, 0x8000000000000010ULL,
183416Skrishna 0x800000a000000010ULL, 0x0000400000000000ULL, 0x0000400000040000ULL, 0x000000a000000000ULL,
184416Skrishna 0x000040a000040000ULL, 0x8000000000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
185416Skrishna 0x8000000000040010ULL, 0x8000400000000010ULL, 0x800040a000040010ULL, 0x000040a000000000ULL,
186416Skrishna 0x000000a000040000ULL, 0x0000000000000000ULL, 0x8000000000000010ULL, 0x800040a000040010ULL,
187416Skrishna 0x0000000000000000ULL, 0x800000a000040010ULL, 0x000040a000000000ULL, 0x0000000000040000ULL,
188416Skrishna 0x8000400000000010ULL, 0x0000400000040000ULL, 0x0000000000040000ULL, 0x800000a000000010ULL
1890Sstevel@tonic-gate },
1900Sstevel@tonic-gate {
191416Skrishna 0x0401000004080800ULL, 0x0000000004080000ULL, 0x0000000400000000ULL, 0x0401000404080800ULL,
192416Skrishna 0x0401000000000000ULL, 0x0401000004080800ULL, 0x0000000000000800ULL, 0x0401000000000000ULL,
193416Skrishna 0x0000000400000800ULL, 0x0401000400000000ULL, 0x0401000404080800ULL, 0x0000000404080000ULL,
194416Skrishna 0x0401000404080000ULL, 0x0000000404080800ULL, 0x0000000004080000ULL, 0x0000000000000800ULL,
195416Skrishna 0x0401000400000000ULL, 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000004080800ULL,
196416Skrishna 0x0000000404080000ULL, 0x0000000400000800ULL, 0x0401000400000800ULL, 0x0401000404080000ULL,
197416Skrishna 0x0000000004080800ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0401000400000800ULL,
198416Skrishna 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000404080800ULL, 0x0000000400000000ULL,
199416Skrishna 0x0000000404080800ULL, 0x0000000400000000ULL, 0x0401000404080000ULL, 0x0000000004080000ULL,
200416Skrishna 0x0000000000000800ULL, 0x0401000400000800ULL, 0x0000000004080000ULL, 0x0000000404080800ULL,
201416Skrishna 0x0401000004080000ULL, 0x0000000000000800ULL, 0x0401000000000800ULL, 0x0401000400000000ULL,
202416Skrishna 0x0401000400000800ULL, 0x0401000000000000ULL, 0x0000000400000000ULL, 0x0401000004080800ULL,
203416Skrishna 0x0000000000000000ULL, 0x0401000404080800ULL, 0x0000000400000800ULL, 0x0401000000000800ULL,
204416Skrishna 0x0401000400000000ULL, 0x0401000004080000ULL, 0x0401000004080800ULL, 0x0000000000000000ULL,
205416Skrishna 0x0401000404080800ULL, 0x0000000404080000ULL, 0x0000000404080000ULL, 0x0000000004080800ULL,
206416Skrishna 0x0000000004080800ULL, 0x0000000400000800ULL, 0x0401000000000000ULL, 0x0401000404080000ULL
2070Sstevel@tonic-gate }
208416Skrishna /* END CSTYLED */
2090Sstevel@tonic-gate };
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate static const uint64_t ip_table[2][256]=
2130Sstevel@tonic-gate {
214416Skrishna /* BEGIN CSTYLED */
2150Sstevel@tonic-gate {
216416Skrishna 0x0000000000000000ULL, 0x0000000000000400ULL, 0x0080000000000280ULL, 0x0080000000000680ULL,
217416Skrishna 0x0000000000400000ULL, 0x0000000000400400ULL, 0x0080000000400280ULL, 0x0080000000400680ULL,
218416Skrishna 0x0000000000280000ULL, 0x0000000000280400ULL, 0x0080000000280280ULL, 0x0080000000280680ULL,
219416Skrishna 0x0000000000680000ULL, 0x0000000000680400ULL, 0x0080000000680280ULL, 0x0080000000680680ULL,
220416Skrishna 0x0000000400000000ULL, 0x0000000400000400ULL, 0x0080000400000280ULL, 0x0080000400000680ULL,
221416Skrishna 0x0000000400400000ULL, 0x0000000400400400ULL, 0x0080000400400280ULL, 0x0080000400400680ULL,
222416Skrishna 0x0000000400280000ULL, 0x0000000400280400ULL, 0x0080000400280280ULL, 0x0080000400280680ULL,
223416Skrishna 0x0000000400680000ULL, 0x0000000400680400ULL, 0x0080000400680280ULL, 0x0080000400680680ULL,
224416Skrishna 0x0000000280000000ULL, 0x0000000280000400ULL, 0x0080000280000280ULL, 0x0080000280000680ULL,
225416Skrishna 0x0000000280400000ULL, 0x0000000280400400ULL, 0x0080000280400280ULL, 0x0080000280400680ULL,
226416Skrishna 0x0000000280280000ULL, 0x0000000280280400ULL, 0x0080000280280280ULL, 0x0080000280280680ULL,
227416Skrishna 0x0000000280680000ULL, 0x0000000280680400ULL, 0x0080000280680280ULL, 0x0080000280680680ULL,
228416Skrishna 0x0000000680000000ULL, 0x0000000680000400ULL, 0x0080000680000280ULL, 0x0080000680000680ULL,
229416Skrishna 0x0000000680400000ULL, 0x0000000680400400ULL, 0x0080000680400280ULL, 0x0080000680400680ULL,
230416Skrishna 0x0000000680280000ULL, 0x0000000680280400ULL, 0x0080000680280280ULL, 0x0080000680280680ULL,
231416Skrishna 0x0000000680680000ULL, 0x0000000680680400ULL, 0x0080000680680280ULL, 0x0080000680680680ULL,
232416Skrishna 0x0000400000000000ULL, 0x0000400000000400ULL, 0x0080400000000280ULL, 0x0080400000000680ULL,
233416Skrishna 0x0000400000400000ULL, 0x0000400000400400ULL, 0x0080400000400280ULL, 0x0080400000400680ULL,
234416Skrishna 0x0000400000280000ULL, 0x0000400000280400ULL, 0x0080400000280280ULL, 0x0080400000280680ULL,
235416Skrishna 0x0000400000680000ULL, 0x0000400000680400ULL, 0x0080400000680280ULL, 0x0080400000680680ULL,
236416Skrishna 0x0000400400000000ULL, 0x0000400400000400ULL, 0x0080400400000280ULL, 0x0080400400000680ULL,
237416Skrishna 0x0000400400400000ULL, 0x0000400400400400ULL, 0x0080400400400280ULL, 0x0080400400400680ULL,
238416Skrishna 0x0000400400280000ULL, 0x0000400400280400ULL, 0x0080400400280280ULL, 0x0080400400280680ULL,
239416Skrishna 0x0000400400680000ULL, 0x0000400400680400ULL, 0x0080400400680280ULL, 0x0080400400680680ULL,
240416Skrishna 0x0000400280000000ULL, 0x0000400280000400ULL, 0x0080400280000280ULL, 0x0080400280000680ULL,
241416Skrishna 0x0000400280400000ULL, 0x0000400280400400ULL, 0x0080400280400280ULL, 0x0080400280400680ULL,
242416Skrishna 0x0000400280280000ULL, 0x0000400280280400ULL, 0x0080400280280280ULL, 0x0080400280280680ULL,
243416Skrishna 0x0000400280680000ULL, 0x0000400280680400ULL, 0x0080400280680280ULL, 0x0080400280680680ULL,
244416Skrishna 0x0000400680000000ULL, 0x0000400680000400ULL, 0x0080400680000280ULL, 0x0080400680000680ULL,
245416Skrishna 0x0000400680400000ULL, 0x0000400680400400ULL, 0x0080400680400280ULL, 0x0080400680400680ULL,
246416Skrishna 0x0000400680280000ULL, 0x0000400680280400ULL, 0x0080400680280280ULL, 0x0080400680280680ULL,
247416Skrishna 0x0000400680680000ULL, 0x0000400680680400ULL, 0x0080400680680280ULL, 0x0080400680680680ULL,
248416Skrishna 0x0000280000000000ULL, 0x0000280000000400ULL, 0x0080280000000280ULL, 0x0080280000000680ULL,
249416Skrishna 0x0000280000400000ULL, 0x0000280000400400ULL, 0x0080280000400280ULL, 0x0080280000400680ULL,
250416Skrishna 0x0000280000280000ULL, 0x0000280000280400ULL, 0x0080280000280280ULL, 0x0080280000280680ULL,
251416Skrishna 0x0000280000680000ULL, 0x0000280000680400ULL, 0x0080280000680280ULL, 0x0080280000680680ULL,
252416Skrishna 0x0000280400000000ULL, 0x0000280400000400ULL, 0x0080280400000280ULL, 0x0080280400000680ULL,
253416Skrishna 0x0000280400400000ULL, 0x0000280400400400ULL, 0x0080280400400280ULL, 0x0080280400400680ULL,
254416Skrishna 0x0000280400280000ULL, 0x0000280400280400ULL, 0x0080280400280280ULL, 0x0080280400280680ULL,
255416Skrishna 0x0000280400680000ULL, 0x0000280400680400ULL, 0x0080280400680280ULL, 0x0080280400680680ULL,
256416Skrishna 0x0000280280000000ULL, 0x0000280280000400ULL, 0x0080280280000280ULL, 0x0080280280000680ULL,
257416Skrishna 0x0000280280400000ULL, 0x0000280280400400ULL, 0x0080280280400280ULL, 0x0080280280400680ULL,
258416Skrishna 0x0000280280280000ULL, 0x0000280280280400ULL, 0x0080280280280280ULL, 0x0080280280280680ULL,
259416Skrishna 0x0000280280680000ULL, 0x0000280280680400ULL, 0x0080280280680280ULL, 0x0080280280680680ULL,
260416Skrishna 0x0000280680000000ULL, 0x0000280680000400ULL, 0x0080280680000280ULL, 0x0080280680000680ULL,
261416Skrishna 0x0000280680400000ULL, 0x0000280680400400ULL, 0x0080280680400280ULL, 0x0080280680400680ULL,
262416Skrishna 0x0000280680280000ULL, 0x0000280680280400ULL, 0x0080280680280280ULL, 0x0080280680280680ULL,
263416Skrishna 0x0000280680680000ULL, 0x0000280680680400ULL, 0x0080280680680280ULL, 0x0080280680680680ULL,
264416Skrishna 0x0000680000000000ULL, 0x0000680000000400ULL, 0x0080680000000280ULL, 0x0080680000000680ULL,
265416Skrishna 0x0000680000400000ULL, 0x0000680000400400ULL, 0x0080680000400280ULL, 0x0080680000400680ULL,
266416Skrishna 0x0000680000280000ULL, 0x0000680000280400ULL, 0x0080680000280280ULL, 0x0080680000280680ULL,
267416Skrishna 0x0000680000680000ULL, 0x0000680000680400ULL, 0x0080680000680280ULL, 0x0080680000680680ULL,
268416Skrishna 0x0000680400000000ULL, 0x0000680400000400ULL, 0x0080680400000280ULL, 0x0080680400000680ULL,
269416Skrishna 0x0000680400400000ULL, 0x0000680400400400ULL, 0x0080680400400280ULL, 0x0080680400400680ULL,
270416Skrishna 0x0000680400280000ULL, 0x0000680400280400ULL, 0x0080680400280280ULL, 0x0080680400280680ULL,
271416Skrishna 0x0000680400680000ULL, 0x0000680400680400ULL, 0x0080680400680280ULL, 0x0080680400680680ULL,
272416Skrishna 0x0000680280000000ULL, 0x0000680280000400ULL, 0x0080680280000280ULL, 0x0080680280000680ULL,
273416Skrishna 0x0000680280400000ULL, 0x0000680280400400ULL, 0x0080680280400280ULL, 0x0080680280400680ULL,
274416Skrishna 0x0000680280280000ULL, 0x0000680280280400ULL, 0x0080680280280280ULL, 0x0080680280280680ULL,
275416Skrishna 0x0000680280680000ULL, 0x0000680280680400ULL, 0x0080680280680280ULL, 0x0080680280680680ULL,
276416Skrishna 0x0000680680000000ULL, 0x0000680680000400ULL, 0x0080680680000280ULL, 0x0080680680000680ULL,
277416Skrishna 0x0000680680400000ULL, 0x0000680680400400ULL, 0x0080680680400280ULL, 0x0080680680400680ULL,
278416Skrishna 0x0000680680280000ULL, 0x0000680680280400ULL, 0x0080680680280280ULL, 0x0080680680280680ULL,
279416Skrishna 0x0000680680680000ULL, 0x0000680680680400ULL, 0x0080680680680280ULL, 0x0080680680680680ULL
2800Sstevel@tonic-gate },
2810Sstevel@tonic-gate {
282416Skrishna 0x0000000000000000ULL, 0x0000000000005000ULL, 0x0000000000000800ULL, 0x0000000000005800ULL,
283416Skrishna 0x0000000005000000ULL, 0x0000000005005000ULL, 0x0000000005000800ULL, 0x0000000005005800ULL,
284416Skrishna 0x0000000000800000ULL, 0x0000000000805000ULL, 0x0000000000800800ULL, 0x0000000000805800ULL,
285416Skrishna 0x0000000005800000ULL, 0x0000000005805000ULL, 0x0000000005800800ULL, 0x0000000005805800ULL,
286416Skrishna 0x0000005000000000ULL, 0x0000005000005000ULL, 0x0000005000000800ULL, 0x0000005000005800ULL,
287416Skrishna 0x0000005005000000ULL, 0x0000005005005000ULL, 0x0000005005000800ULL, 0x0000005005005800ULL,
288416Skrishna 0x0000005000800000ULL, 0x0000005000805000ULL, 0x0000005000800800ULL, 0x0000005000805800ULL,
289416Skrishna 0x0000005005800000ULL, 0x0000005005805000ULL, 0x0000005005800800ULL, 0x0000005005805800ULL,
290416Skrishna 0x0000000800000000ULL, 0x0000000800005000ULL, 0x0000000800000800ULL, 0x0000000800005800ULL,
291416Skrishna 0x0000000805000000ULL, 0x0000000805005000ULL, 0x0000000805000800ULL, 0x0000000805005800ULL,
292416Skrishna 0x0000000800800000ULL, 0x0000000800805000ULL, 0x0000000800800800ULL, 0x0000000800805800ULL,
293416Skrishna 0x0000000805800000ULL, 0x0000000805805000ULL, 0x0000000805800800ULL, 0x0000000805805800ULL,
294416Skrishna 0x0000005800000000ULL, 0x0000005800005000ULL, 0x0000005800000800ULL, 0x0000005800005800ULL,
295416Skrishna 0x0000005805000000ULL, 0x0000005805005000ULL, 0x0000005805000800ULL, 0x0000005805005800ULL,
296416Skrishna 0x0000005800800000ULL, 0x0000005800805000ULL, 0x0000005800800800ULL, 0x0000005800805800ULL,
297416Skrishna 0x0000005805800000ULL, 0x0000005805805000ULL, 0x0000005805800800ULL, 0x0000005805805800ULL,
298416Skrishna 0x0005000000000004ULL, 0x0005000000005004ULL, 0x0005000000000804ULL, 0x0005000000005804ULL,
299416Skrishna 0x0005000005000004ULL, 0x0005000005005004ULL, 0x0005000005000804ULL, 0x0005000005005804ULL,
300416Skrishna 0x0005000000800004ULL, 0x0005000000805004ULL, 0x0005000000800804ULL, 0x0005000000805804ULL,
301416Skrishna 0x0005000005800004ULL, 0x0005000005805004ULL, 0x0005000005800804ULL, 0x0005000005805804ULL,
302416Skrishna 0x0005005000000004ULL, 0x0005005000005004ULL, 0x0005005000000804ULL, 0x0005005000005804ULL,
303416Skrishna 0x0005005005000004ULL, 0x0005005005005004ULL, 0x0005005005000804ULL, 0x0005005005005804ULL,
304416Skrishna 0x0005005000800004ULL, 0x0005005000805004ULL, 0x0005005000800804ULL, 0x0005005000805804ULL,
305416Skrishna 0x0005005005800004ULL, 0x0005005005805004ULL, 0x0005005005800804ULL, 0x0005005005805804ULL,
306416Skrishna 0x0005000800000004ULL, 0x0005000800005004ULL, 0x0005000800000804ULL, 0x0005000800005804ULL,
307416Skrishna 0x0005000805000004ULL, 0x0005000805005004ULL, 0x0005000805000804ULL, 0x0005000805005804ULL,
308416Skrishna 0x0005000800800004ULL, 0x0005000800805004ULL, 0x0005000800800804ULL, 0x0005000800805804ULL,
309416Skrishna 0x0005000805800004ULL, 0x0005000805805004ULL, 0x0005000805800804ULL, 0x0005000805805804ULL,
310416Skrishna 0x0005005800000004ULL, 0x0005005800005004ULL, 0x0005005800000804ULL, 0x0005005800005804ULL,
311416Skrishna 0x0005005805000004ULL, 0x0005005805005004ULL, 0x0005005805000804ULL, 0x0005005805005804ULL,
312416Skrishna 0x0005005800800004ULL, 0x0005005800805004ULL, 0x0005005800800804ULL, 0x0005005800805804ULL,
313416Skrishna 0x0005005805800004ULL, 0x0005005805805004ULL, 0x0005005805800804ULL, 0x0005005805805804ULL,
314416Skrishna 0x0000800000000000ULL, 0x0000800000005000ULL, 0x0000800000000800ULL, 0x0000800000005800ULL,
315416Skrishna 0x0000800005000000ULL, 0x0000800005005000ULL, 0x0000800005000800ULL, 0x0000800005005800ULL,
316416Skrishna 0x0000800000800000ULL, 0x0000800000805000ULL, 0x0000800000800800ULL, 0x0000800000805800ULL,
317416Skrishna 0x0000800005800000ULL, 0x0000800005805000ULL, 0x0000800005800800ULL, 0x0000800005805800ULL,
318416Skrishna 0x0000805000000000ULL, 0x0000805000005000ULL, 0x0000805000000800ULL, 0x0000805000005800ULL,
319416Skrishna 0x0000805005000000ULL, 0x0000805005005000ULL, 0x0000805005000800ULL, 0x0000805005005800ULL,
320416Skrishna 0x0000805000800000ULL, 0x0000805000805000ULL, 0x0000805000800800ULL, 0x0000805000805800ULL,
321416Skrishna 0x0000805005800000ULL, 0x0000805005805000ULL, 0x0000805005800800ULL, 0x0000805005805800ULL,
322416Skrishna 0x0000800800000000ULL, 0x0000800800005000ULL, 0x0000800800000800ULL, 0x0000800800005800ULL,
323416Skrishna 0x0000800805000000ULL, 0x0000800805005000ULL, 0x0000800805000800ULL, 0x0000800805005800ULL,
324416Skrishna 0x0000800800800000ULL, 0x0000800800805000ULL, 0x0000800800800800ULL, 0x0000800800805800ULL,
325416Skrishna 0x0000800805800000ULL, 0x0000800805805000ULL, 0x0000800805800800ULL, 0x0000800805805800ULL,
326416Skrishna 0x0000805800000000ULL, 0x0000805800005000ULL, 0x0000805800000800ULL, 0x0000805800005800ULL,
327416Skrishna 0x0000805805000000ULL, 0x0000805805005000ULL, 0x0000805805000800ULL, 0x0000805805005800ULL,
328416Skrishna 0x0000805800800000ULL, 0x0000805800805000ULL, 0x0000805800800800ULL, 0x0000805800805800ULL,
329416Skrishna 0x0000805805800000ULL, 0x0000805805805000ULL, 0x0000805805800800ULL, 0x0000805805805800ULL,
330416Skrishna 0x0005800000000004ULL, 0x0005800000005004ULL, 0x0005800000000804ULL, 0x0005800000005804ULL,
331416Skrishna 0x0005800005000004ULL, 0x0005800005005004ULL, 0x0005800005000804ULL, 0x0005800005005804ULL,
332416Skrishna 0x0005800000800004ULL, 0x0005800000805004ULL, 0x0005800000800804ULL, 0x0005800000805804ULL,
333416Skrishna 0x0005800005800004ULL, 0x0005800005805004ULL, 0x0005800005800804ULL, 0x0005800005805804ULL,
334416Skrishna 0x0005805000000004ULL, 0x0005805000005004ULL, 0x0005805000000804ULL, 0x0005805000005804ULL,
335416Skrishna 0x0005805005000004ULL, 0x0005805005005004ULL, 0x0005805005000804ULL, 0x0005805005005804ULL,
336416Skrishna 0x0005805000800004ULL, 0x0005805000805004ULL, 0x0005805000800804ULL, 0x0005805000805804ULL,
337416Skrishna 0x0005805005800004ULL, 0x0005805005805004ULL, 0x0005805005800804ULL, 0x0005805005805804ULL,
338416Skrishna 0x0005800800000004ULL, 0x0005800800005004ULL, 0x0005800800000804ULL, 0x0005800800005804ULL,
339416Skrishna 0x0005800805000004ULL, 0x0005800805005004ULL, 0x0005800805000804ULL, 0x0005800805005804ULL,
340416Skrishna 0x0005800800800004ULL, 0x0005800800805004ULL, 0x0005800800800804ULL, 0x0005800800805804ULL,
341416Skrishna 0x0005800805800004ULL, 0x0005800805805004ULL, 0x0005800805800804ULL, 0x0005800805805804ULL,
342416Skrishna 0x0005805800000004ULL, 0x0005805800005004ULL, 0x0005805800000804ULL, 0x0005805800005804ULL,
343416Skrishna 0x0005805805000004ULL, 0x0005805805005004ULL, 0x0005805805000804ULL, 0x0005805805005804ULL,
344416Skrishna 0x0005805800800004ULL, 0x0005805800805004ULL, 0x0005805800800804ULL, 0x0005805800805804ULL,
345416Skrishna 0x0005805805800004ULL, 0x0005805805805004ULL, 0x0005805805800804ULL, 0x0005805805805804ULL
3460Sstevel@tonic-gate }
347416Skrishna /* END CSTYLED */
3480Sstevel@tonic-gate };
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate static const uint32_t fp_table[256]=
3510Sstevel@tonic-gate {
3520Sstevel@tonic-gate 0x00000000, 0x80000000, 0x00800000, 0x80800000,
3530Sstevel@tonic-gate 0x00008000, 0x80008000, 0x00808000, 0x80808000,
3540Sstevel@tonic-gate 0x00000080, 0x80000080, 0x00800080, 0x80800080,
3550Sstevel@tonic-gate 0x00008080, 0x80008080, 0x00808080, 0x80808080,
3560Sstevel@tonic-gate 0x40000000, 0xc0000000, 0x40800000, 0xc0800000,
3570Sstevel@tonic-gate 0x40008000, 0xc0008000, 0x40808000, 0xc0808000,
3580Sstevel@tonic-gate 0x40000080, 0xc0000080, 0x40800080, 0xc0800080,
3590Sstevel@tonic-gate 0x40008080, 0xc0008080, 0x40808080, 0xc0808080,
3600Sstevel@tonic-gate 0x00400000, 0x80400000, 0x00c00000, 0x80c00000,
3610Sstevel@tonic-gate 0x00408000, 0x80408000, 0x00c08000, 0x80c08000,
3620Sstevel@tonic-gate 0x00400080, 0x80400080, 0x00c00080, 0x80c00080,
3630Sstevel@tonic-gate 0x00408080, 0x80408080, 0x00c08080, 0x80c08080,
3640Sstevel@tonic-gate 0x40400000, 0xc0400000, 0x40c00000, 0xc0c00000,
3650Sstevel@tonic-gate 0x40408000, 0xc0408000, 0x40c08000, 0xc0c08000,
3660Sstevel@tonic-gate 0x40400080, 0xc0400080, 0x40c00080, 0xc0c00080,
3670Sstevel@tonic-gate 0x40408080, 0xc0408080, 0x40c08080, 0xc0c08080,
3680Sstevel@tonic-gate 0x00004000, 0x80004000, 0x00804000, 0x80804000,
3690Sstevel@tonic-gate 0x0000c000, 0x8000c000, 0x0080c000, 0x8080c000,
3700Sstevel@tonic-gate 0x00004080, 0x80004080, 0x00804080, 0x80804080,
3710Sstevel@tonic-gate 0x0000c080, 0x8000c080, 0x0080c080, 0x8080c080,
3720Sstevel@tonic-gate 0x40004000, 0xc0004000, 0x40804000, 0xc0804000,
3730Sstevel@tonic-gate 0x4000c000, 0xc000c000, 0x4080c000, 0xc080c000,
3740Sstevel@tonic-gate 0x40004080, 0xc0004080, 0x40804080, 0xc0804080,
3750Sstevel@tonic-gate 0x4000c080, 0xc000c080, 0x4080c080, 0xc080c080,
3760Sstevel@tonic-gate 0x00404000, 0x80404000, 0x00c04000, 0x80c04000,
3770Sstevel@tonic-gate 0x0040c000, 0x8040c000, 0x00c0c000, 0x80c0c000,
3780Sstevel@tonic-gate 0x00404080, 0x80404080, 0x00c04080, 0x80c04080,
3790Sstevel@tonic-gate 0x0040c080, 0x8040c080, 0x00c0c080, 0x80c0c080,
3800Sstevel@tonic-gate 0x40404000, 0xc0404000, 0x40c04000, 0xc0c04000,
3810Sstevel@tonic-gate 0x4040c000, 0xc040c000, 0x40c0c000, 0xc0c0c000,
3820Sstevel@tonic-gate 0x40404080, 0xc0404080, 0x40c04080, 0xc0c04080,
3830Sstevel@tonic-gate 0x4040c080, 0xc040c080, 0x40c0c080, 0xc0c0c080,
3840Sstevel@tonic-gate 0x00000040, 0x80000040, 0x00800040, 0x80800040,
3850Sstevel@tonic-gate 0x00008040, 0x80008040, 0x00808040, 0x80808040,
3860Sstevel@tonic-gate 0x000000c0, 0x800000c0, 0x008000c0, 0x808000c0,
3870Sstevel@tonic-gate 0x000080c0, 0x800080c0, 0x008080c0, 0x808080c0,
3880Sstevel@tonic-gate 0x40000040, 0xc0000040, 0x40800040, 0xc0800040,
3890Sstevel@tonic-gate 0x40008040, 0xc0008040, 0x40808040, 0xc0808040,
3900Sstevel@tonic-gate 0x400000c0, 0xc00000c0, 0x408000c0, 0xc08000c0,
3910Sstevel@tonic-gate 0x400080c0, 0xc00080c0, 0x408080c0, 0xc08080c0,
3920Sstevel@tonic-gate 0x00400040, 0x80400040, 0x00c00040, 0x80c00040,
3930Sstevel@tonic-gate 0x00408040, 0x80408040, 0x00c08040, 0x80c08040,
3940Sstevel@tonic-gate 0x004000c0, 0x804000c0, 0x00c000c0, 0x80c000c0,
3950Sstevel@tonic-gate 0x004080c0, 0x804080c0, 0x00c080c0, 0x80c080c0,
3960Sstevel@tonic-gate 0x40400040, 0xc0400040, 0x40c00040, 0xc0c00040,
3970Sstevel@tonic-gate 0x40408040, 0xc0408040, 0x40c08040, 0xc0c08040,
3980Sstevel@tonic-gate 0x404000c0, 0xc04000c0, 0x40c000c0, 0xc0c000c0,
3990Sstevel@tonic-gate 0x404080c0, 0xc04080c0, 0x40c080c0, 0xc0c080c0,
4000Sstevel@tonic-gate 0x00004040, 0x80004040, 0x00804040, 0x80804040,
4010Sstevel@tonic-gate 0x0000c040, 0x8000c040, 0x0080c040, 0x8080c040,
4020Sstevel@tonic-gate 0x000040c0, 0x800040c0, 0x008040c0, 0x808040c0,
4030Sstevel@tonic-gate 0x0000c0c0, 0x8000c0c0, 0x0080c0c0, 0x8080c0c0,
4040Sstevel@tonic-gate 0x40004040, 0xc0004040, 0x40804040, 0xc0804040,
4050Sstevel@tonic-gate 0x4000c040, 0xc000c040, 0x4080c040, 0xc080c040,
4060Sstevel@tonic-gate 0x400040c0, 0xc00040c0, 0x408040c0, 0xc08040c0,
4070Sstevel@tonic-gate 0x4000c0c0, 0xc000c0c0, 0x4080c0c0, 0xc080c0c0,
4080Sstevel@tonic-gate 0x00404040, 0x80404040, 0x00c04040, 0x80c04040,
4090Sstevel@tonic-gate 0x0040c040, 0x8040c040, 0x00c0c040, 0x80c0c040,
4100Sstevel@tonic-gate 0x004040c0, 0x804040c0, 0x00c040c0, 0x80c040c0,
4110Sstevel@tonic-gate 0x0040c0c0, 0x8040c0c0, 0x00c0c0c0, 0x80c0c0c0,
4120Sstevel@tonic-gate 0x40404040, 0xc0404040, 0x40c04040, 0xc0c04040,
4130Sstevel@tonic-gate 0x4040c040, 0xc040c040, 0x40c0c040, 0xc0c0c040,
4140Sstevel@tonic-gate 0x404040c0, 0xc04040c0, 0x40c040c0, 0xc0c040c0,
4150Sstevel@tonic-gate 0x4040c0c0, 0xc040c0c0, 0x40c0c0c0, 0xc0c0c0c0
4160Sstevel@tonic-gate };
4170Sstevel@tonic-gate 
418416Skrishna static const uint64_t all_a = 0xaaaaaaaaaaaaaaaaULL;
419416Skrishna static const uint64_t all_5 = 0x5555555555555555ULL;
420416Skrishna static const uint64_t top_1 = 0xfc000000000000ULL;
421416Skrishna static const uint64_t mid_4 = 0x3fffffc000000ULL;
422416Skrishna static const uint64_t low_3 = 0x3ffff00ULL;
4230Sstevel@tonic-gate 
4240Sstevel@tonic-gate 
4250Sstevel@tonic-gate static void
des_ip(uint64_t * l,uint64_t * r,uint64_t pt)4260Sstevel@tonic-gate des_ip(uint64_t *l, uint64_t *r, uint64_t pt)
4270Sstevel@tonic-gate {
4280Sstevel@tonic-gate 	uint64_t a, b;
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 	a = pt & all_a;
4310Sstevel@tonic-gate 	b = pt & all_5;
4320Sstevel@tonic-gate 	a = a | (a << 7);
4330Sstevel@tonic-gate 	b = b | (b >> 7);
4340Sstevel@tonic-gate 
435416Skrishna 	b = (ip_table[0][(b >> 48) & 255ULL]) |
4367188Smcpowers 	    (ip_table[1][(b >> 32) & 255ULL]) |
4377188Smcpowers 	    (ip_table[0][(b >> 16) & 255ULL] << 6) |
4387188Smcpowers 	    (ip_table[1][b & 255ULL] << 6);
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 	a = (ip_table[0][(a >> 56) & 255]) |
4417188Smcpowers 	    (ip_table[1][(a >> 40) & 255]) |
4427188Smcpowers 	    (ip_table[0][(a >> 24) & 255] << 6) |
4437188Smcpowers 	    (ip_table[1][(a >> 8) & 255] << 6);
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate 	*l = ((b & top_1) << 8) |
4467188Smcpowers 	    (b & mid_4) |
4477188Smcpowers 	    ((b & low_3) >> 5);
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 	*r = ((a & top_1) << 8) |
4507188Smcpowers 	    (a & mid_4) |
4517188Smcpowers 	    ((a & low_3) >> 5);
4520Sstevel@tonic-gate }
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate static uint64_t
des_fp(uint64_t l,uint64_t r)4560Sstevel@tonic-gate des_fp(uint64_t l, uint64_t r)
4570Sstevel@tonic-gate {
4580Sstevel@tonic-gate 	uint32_t upper, lower;
4590Sstevel@tonic-gate 
4600Sstevel@tonic-gate 	lower = fp_table[((l >> 55) & 240) | ((r >> 59) & 15)] |
4617188Smcpowers 	    (fp_table[((l >> 35) & 240) | ((r>>39) & 15)] >> 2) |
4627188Smcpowers 	    (fp_table[((l >> 23) & 240) | ((r >> 27) & 15)] >> 4) |
4637188Smcpowers 	    (fp_table[((l >> 6) & 240) | ((r >> 10) & 15)] >> 6);
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate 	upper = fp_table[((l >> 41) & 240) | ((r >> 45) & 15)] |
4667188Smcpowers 	    (fp_table[((l >> 29) & 240) | ((r >> 33) & 15)] >> 2) |
4677188Smcpowers 	    (fp_table[((l >> 12) & 240) | ((r >> 16) & 15)] >> 4) |
4687188Smcpowers 	    (fp_table[(l & 240) | (r >> 4) & 15] >> 6);
4690Sstevel@tonic-gate 
4700Sstevel@tonic-gate 	return ((((uint64_t)upper) << 32) | (uint64_t)lower);
4710Sstevel@tonic-gate 
4720Sstevel@tonic-gate }
4730Sstevel@tonic-gate 
4740Sstevel@tonic-gate uint64_t
des_crypt_impl(uint64_t * ks,uint64_t block,int one_or_three)4750Sstevel@tonic-gate des_crypt_impl(uint64_t *ks, uint64_t block, int one_or_three)
4760Sstevel@tonic-gate {
4770Sstevel@tonic-gate 	int i, j;
4780Sstevel@tonic-gate 	uint64_t l, r, t;
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 	des_ip(&l, &r, block);
4810Sstevel@tonic-gate 	for (j = 0; j < one_or_three; j++) {
4820Sstevel@tonic-gate 		for (i = j * 16; i < (j + 1) * 16; i++) {
4830Sstevel@tonic-gate 			t = r ^ ks[i];
4840Sstevel@tonic-gate 			t = sbox_table[0][t >> 58] |
4857188Smcpowers 			    sbox_table[1][(t >> 44) & 63] |
4867188Smcpowers 			    sbox_table[2][(t >> 38) & 63] |
4877188Smcpowers 			    sbox_table[3][(t >> 32) & 63] |
4887188Smcpowers 			    sbox_table[4][(t >> 26) & 63] |
4897188Smcpowers 			    sbox_table[5][(t >> 15) & 63] |
4907188Smcpowers 			    sbox_table[6][(t >> 9) & 63] |
4917188Smcpowers 			    sbox_table[7][(t >> 3) & 63];
4920Sstevel@tonic-gate 			t = t^l;
4930Sstevel@tonic-gate 			l = r;
4940Sstevel@tonic-gate 			r = t;
4950Sstevel@tonic-gate 		}
4960Sstevel@tonic-gate 		r = l;
4970Sstevel@tonic-gate 		l = t;
4980Sstevel@tonic-gate 	}
4990Sstevel@tonic-gate 
5000Sstevel@tonic-gate 	return (des_fp(l, r));
5010Sstevel@tonic-gate }
5020Sstevel@tonic-gate #endif /* !sun4u */
5030Sstevel@tonic-gate 
5040Sstevel@tonic-gate /* EXPORT DELETE END */
5050Sstevel@tonic-gate 
5067188Smcpowers int
des3_crunch_block(const void * cookie,const uint8_t block[DES_BLOCK_LEN],uint8_t out_block[DES_BLOCK_LEN],boolean_t decrypt)5077188Smcpowers des3_crunch_block(const void *cookie, const uint8_t block[DES_BLOCK_LEN],
5080Sstevel@tonic-gate     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
5090Sstevel@tonic-gate {
5100Sstevel@tonic-gate /* EXPORT DELETE START */
5110Sstevel@tonic-gate 	keysched3_t *ksch = (keysched3_t *)cookie;
5120Sstevel@tonic-gate 
5130Sstevel@tonic-gate 	/*
5140Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
5150Sstevel@tonic-gate 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
5160Sstevel@tonic-gate 	 * copies the block without reversing bytes.
5170Sstevel@tonic-gate 	 */
5180Sstevel@tonic-gate #ifdef _BIG_ENDIAN
5190Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
5200Sstevel@tonic-gate 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
5210Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5220Sstevel@tonic-gate 			/* LINTED */
5230Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5247421SDaniel.Anderson@Sun.COM 			    ksch->ksch_decrypt, /* LINTED */
5250Sstevel@tonic-gate 			    *(uint64_t *)block, 3);
5260Sstevel@tonic-gate 		else
5270Sstevel@tonic-gate 			/* LINTED */
5280Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5297421SDaniel.Anderson@Sun.COM 			    ksch->ksch_encrypt, /* LINTED */
5300Sstevel@tonic-gate 			    *(uint64_t *)block, 3);
5317421SDaniel.Anderson@Sun.COM 	} else
5327421SDaniel.Anderson@Sun.COM #endif	/* _BIG_ENDIAN */
5337421SDaniel.Anderson@Sun.COM 	{
5340Sstevel@tonic-gate 		uint64_t tmp;
5350Sstevel@tonic-gate 
5367421SDaniel.Anderson@Sun.COM #ifdef UNALIGNED_POINTERS_PERMITTED
5377434SDaniel.Anderson@Sun.COM 		tmp = htonll(*(uint64_t *)(void *)&block[0]);
5387421SDaniel.Anderson@Sun.COM #else
5390Sstevel@tonic-gate 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
5400Sstevel@tonic-gate 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
5410Sstevel@tonic-gate 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
5420Sstevel@tonic-gate 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
5437421SDaniel.Anderson@Sun.COM #endif	/* UNALIGNED_POINTERS_PERMITTED */
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5460Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 3);
5470Sstevel@tonic-gate 		else
5480Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 3);
5490Sstevel@tonic-gate 
5507421SDaniel.Anderson@Sun.COM #ifdef UNALIGNED_POINTERS_PERMITTED
5517434SDaniel.Anderson@Sun.COM 		*(uint64_t *)(void *)&out_block[0] = htonll(tmp);
5527421SDaniel.Anderson@Sun.COM #else
5530Sstevel@tonic-gate 		out_block[0] = tmp >> 56;
5540Sstevel@tonic-gate 		out_block[1] = tmp >> 48;
5550Sstevel@tonic-gate 		out_block[2] = tmp >> 40;
5560Sstevel@tonic-gate 		out_block[3] = tmp >> 32;
5570Sstevel@tonic-gate 		out_block[4] = tmp >> 24;
5580Sstevel@tonic-gate 		out_block[5] = tmp >> 16;
5590Sstevel@tonic-gate 		out_block[6] = tmp >> 8;
5600Sstevel@tonic-gate 		out_block[7] = (uint8_t)tmp;
5617421SDaniel.Anderson@Sun.COM #endif	/* UNALIGNED_POINTERS_PERMITTED */
5620Sstevel@tonic-gate 	}
5630Sstevel@tonic-gate /* EXPORT DELETE END */
5647188Smcpowers 	return (CRYPTO_SUCCESS);
5650Sstevel@tonic-gate }
5660Sstevel@tonic-gate 
5677188Smcpowers int
des_crunch_block(const void * cookie,const uint8_t block[DES_BLOCK_LEN],uint8_t out_block[DES_BLOCK_LEN],boolean_t decrypt)5687188Smcpowers des_crunch_block(const void *cookie, const uint8_t block[DES_BLOCK_LEN],
5690Sstevel@tonic-gate     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
5700Sstevel@tonic-gate {
5710Sstevel@tonic-gate /* EXPORT DELETE START */
5720Sstevel@tonic-gate 	keysched_t *ksch = (keysched_t *)cookie;
5730Sstevel@tonic-gate 
5740Sstevel@tonic-gate 	/*
5750Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
5760Sstevel@tonic-gate 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
5770Sstevel@tonic-gate 	 * copies the block without reversing bytes.
5780Sstevel@tonic-gate 	 */
5790Sstevel@tonic-gate #ifdef _BIG_ENDIAN
5800Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
5810Sstevel@tonic-gate 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
5820Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5830Sstevel@tonic-gate 			/* LINTED */
5840Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5857421SDaniel.Anderson@Sun.COM 			    ksch->ksch_decrypt, /* LINTED */
5860Sstevel@tonic-gate 			    *(uint64_t *)block, 1);
5870Sstevel@tonic-gate 		else
5880Sstevel@tonic-gate 			/* LINTED */
5890Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5907421SDaniel.Anderson@Sun.COM 			    ksch->ksch_encrypt, /* LINTED */
5910Sstevel@tonic-gate 			    *(uint64_t *)block, 1);
5920Sstevel@tonic-gate 
5937421SDaniel.Anderson@Sun.COM 	} else
5947421SDaniel.Anderson@Sun.COM #endif	/* _BIG_ENDIAN */
5957421SDaniel.Anderson@Sun.COM 	{
5960Sstevel@tonic-gate 		uint64_t tmp;
5970Sstevel@tonic-gate 
5987421SDaniel.Anderson@Sun.COM #ifdef UNALIGNED_POINTERS_PERMITTED
5997434SDaniel.Anderson@Sun.COM 		tmp = htonll(*(uint64_t *)(void *)&block[0]);
6007421SDaniel.Anderson@Sun.COM #else
6010Sstevel@tonic-gate 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
6020Sstevel@tonic-gate 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
6030Sstevel@tonic-gate 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
6040Sstevel@tonic-gate 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
6057421SDaniel.Anderson@Sun.COM #endif	/* UNALIGNED_POINTERS_PERMITTED */
6067421SDaniel.Anderson@Sun.COM 
6070Sstevel@tonic-gate 
6080Sstevel@tonic-gate 		if (decrypt == B_TRUE)
6090Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 1);
6100Sstevel@tonic-gate 		else
6110Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 1);
6120Sstevel@tonic-gate 
6137421SDaniel.Anderson@Sun.COM #ifdef UNALIGNED_POINTERS_PERMITTED
6147434SDaniel.Anderson@Sun.COM 		*(uint64_t *)(void *)&out_block[0] = htonll(tmp);
6157421SDaniel.Anderson@Sun.COM #else
6160Sstevel@tonic-gate 		out_block[0] = tmp >> 56;
6170Sstevel@tonic-gate 		out_block[1] = tmp >> 48;
6180Sstevel@tonic-gate 		out_block[2] = tmp >> 40;
6190Sstevel@tonic-gate 		out_block[3] = tmp >> 32;
6200Sstevel@tonic-gate 		out_block[4] = tmp >> 24;
6210Sstevel@tonic-gate 		out_block[5] = tmp >> 16;
6220Sstevel@tonic-gate 		out_block[6] = tmp >> 8;
6230Sstevel@tonic-gate 		out_block[7] = (uint8_t)tmp;
6247421SDaniel.Anderson@Sun.COM #endif	/* UNALIGNED_POINTERS_PERMITTED */
6250Sstevel@tonic-gate 	}
6260Sstevel@tonic-gate /* EXPORT DELETE END */
6277188Smcpowers 	return (CRYPTO_SUCCESS);
6280Sstevel@tonic-gate }
6290Sstevel@tonic-gate 
6300Sstevel@tonic-gate static boolean_t
keycheck(uint8_t * key,uint8_t * corrected_key)6310Sstevel@tonic-gate keycheck(uint8_t *key, uint8_t *corrected_key)
6320Sstevel@tonic-gate {
6330Sstevel@tonic-gate /* EXPORT DELETE START */
6340Sstevel@tonic-gate 	uint64_t key_so_far;
6350Sstevel@tonic-gate 	uint_t i;
6360Sstevel@tonic-gate 	/*
6370Sstevel@tonic-gate 	 * Table of weak and semi-weak keys.  Fortunately, weak keys are
6380Sstevel@tonic-gate 	 * endian-independent, and some semi-weak keys can be paired up in
6390Sstevel@tonic-gate 	 * endian-opposite order.  Since keys are stored as uint64_t's,
6400Sstevel@tonic-gate 	 * use the ifdef _LITTLE_ENDIAN where appropriate.
6410Sstevel@tonic-gate 	 */
6420Sstevel@tonic-gate 	static uint64_t des_weak_keys[] = {
6430Sstevel@tonic-gate 		/* Really weak keys.  Byte-order independent values. */
644416Skrishna 		0x0101010101010101ULL,
645416Skrishna 		0x1f1f1f1f0e0e0e0eULL,
646416Skrishna 		0xe0e0e0e0f1f1f1f1ULL,
647416Skrishna 		0xfefefefefefefefeULL,
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 		/* Semi-weak (and a few possibly-weak) keys. */
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate 		/* Byte-order independent semi-weak keys. */
652416Skrishna 		0x01fe01fe01fe01feULL,	0xfe01fe01fe01fe01ULL,
6530Sstevel@tonic-gate 
6540Sstevel@tonic-gate 		/* Byte-order dependent semi-weak keys. */
6550Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
656416Skrishna 		0xf10ef10ee01fe01fULL,	0x0ef10ef11fe01fe0ULL,
657416Skrishna 		0x01f101f101e001e0ULL,	0xf101f101e001e001ULL,
658416Skrishna 		0x0efe0efe1ffe1ffeULL,	0xfe0efe0efe1ffe1fULL,
659416Skrishna 		0x010e010e011f011fULL,	0x0e010e011f011f01ULL,
660416Skrishna 		0xf1fef1fee0fee0feULL,	0xfef1fef1fee0fee0ULL,
6610Sstevel@tonic-gate #else	/* Big endian */
662416Skrishna 		0x1fe01fe00ef10ef1ULL,	0xe01fe01ff10ef10eULL,
663416Skrishna 		0x01e001e001f101f1ULL,	0xe001e001f101f101ULL,
664416Skrishna 		0x1ffe1ffe0efe0efeULL,	0xfe1ffe1ffe0efe0eULL,
665416Skrishna 		0x011f011f010e010eULL,	0x1f011f010e010e01ULL,
666416Skrishna 		0xe0fee0fef1fef1feULL,	0xfee0fee0fef1fef1ULL,
6677421SDaniel.Anderson@Sun.COM #endif	/* _LITTLE_ENDIAN */
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 		/* We'll save the other possibly-weak keys for the future. */
6700Sstevel@tonic-gate 	};
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate 	if (key == NULL)
6730Sstevel@tonic-gate 		return (B_FALSE);
6740Sstevel@tonic-gate 
6757421SDaniel.Anderson@Sun.COM #ifdef UNALIGNED_POINTERS_PERMITTED
6767434SDaniel.Anderson@Sun.COM 	key_so_far = htonll(*(uint64_t *)(void *)&key[0]);
6777421SDaniel.Anderson@Sun.COM #else
6780Sstevel@tonic-gate 	/*
6790Sstevel@tonic-gate 	 * The code below reverses the bytes on LITTLE_ENDIAN machines.
6800Sstevel@tonic-gate 	 * On BIG_ENDIAN, the same code copies without reversing
6810Sstevel@tonic-gate 	 * the bytes.
6820Sstevel@tonic-gate 	 */
6830Sstevel@tonic-gate 	key_so_far = (((uint64_t)key[0] << 56) | ((uint64_t)key[1] << 48) |
6840Sstevel@tonic-gate 	    ((uint64_t)key[2] << 40) | ((uint64_t)key[3] << 32) |
6850Sstevel@tonic-gate 	    ((uint64_t)key[4] << 24) | ((uint64_t)key[5] << 16) |
6860Sstevel@tonic-gate 	    ((uint64_t)key[6] << 8) | (uint64_t)key[7]);
6877421SDaniel.Anderson@Sun.COM #endif	/* UNALIGNED_POINTERS_PERMITTED */
6880Sstevel@tonic-gate 
6890Sstevel@tonic-gate 	/*
6900Sstevel@tonic-gate 	 * Fix parity.
6910Sstevel@tonic-gate 	 */
6920Sstevel@tonic-gate 	fix_des_parity(&key_so_far);
6930Sstevel@tonic-gate 
6940Sstevel@tonic-gate 	/* Do weak key check itself. */
6950Sstevel@tonic-gate 	for (i = 0; i < (sizeof (des_weak_keys) / sizeof (uint64_t)); i++)
6960Sstevel@tonic-gate 		if (key_so_far == des_weak_keys[i]) {
6970Sstevel@tonic-gate 			return (B_FALSE);
6980Sstevel@tonic-gate 		}
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate 	if (corrected_key != NULL) {
7017421SDaniel.Anderson@Sun.COM #ifdef UNALIGNED_POINTERS_PERMITTED
7027434SDaniel.Anderson@Sun.COM 		*(uint64_t *)(void *)&corrected_key[0] = htonll(key_so_far);
7037421SDaniel.Anderson@Sun.COM #else
7040Sstevel@tonic-gate 		/*
7050Sstevel@tonic-gate 		 * The code below reverses the bytes on LITTLE_ENDIAN machines.
7060Sstevel@tonic-gate 		 * On BIG_ENDIAN, the same code copies without reversing
7070Sstevel@tonic-gate 		 * the bytes.
7080Sstevel@tonic-gate 		 */
7090Sstevel@tonic-gate 		corrected_key[0] = key_so_far >> 56;
7100Sstevel@tonic-gate 		corrected_key[1] = key_so_far >> 48;
7110Sstevel@tonic-gate 		corrected_key[2] = key_so_far >> 40;
7120Sstevel@tonic-gate 		corrected_key[3] = key_so_far >> 32;
7130Sstevel@tonic-gate 		corrected_key[4] = key_so_far >> 24;
7140Sstevel@tonic-gate 		corrected_key[5] = key_so_far >> 16;
7150Sstevel@tonic-gate 		corrected_key[6] = key_so_far >> 8;
7160Sstevel@tonic-gate 		corrected_key[7] = (uint8_t)key_so_far;
7177421SDaniel.Anderson@Sun.COM #endif	/* UNALIGNED_POINTERS_PERMITTED */
7180Sstevel@tonic-gate 	}
7190Sstevel@tonic-gate /* EXPORT DELETE END */
7200Sstevel@tonic-gate 	return (B_TRUE);
7210Sstevel@tonic-gate }
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate static boolean_t
des23_keycheck(uint8_t * key,uint8_t * corrected_key,boolean_t des3)724*10444SVladimir.Kotal@Sun.COM des23_keycheck(uint8_t *key, uint8_t *corrected_key, boolean_t des3)
7250Sstevel@tonic-gate {
7260Sstevel@tonic-gate /* EXPORT DELETE START */
7270Sstevel@tonic-gate 	uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
7280Sstevel@tonic-gate 	uint64_t key_so_far, scratch, *currentkey;
7290Sstevel@tonic-gate 	uint_t j, num_weakkeys = 0;
730*10444SVladimir.Kotal@Sun.COM 	uint8_t keysize = DES3_KEYSIZE;
731*10444SVladimir.Kotal@Sun.COM 	uint8_t checks = 3;
7320Sstevel@tonic-gate 
7330Sstevel@tonic-gate 	if (key == NULL) {
7340Sstevel@tonic-gate 		return (B_FALSE);
7350Sstevel@tonic-gate 	}
7360Sstevel@tonic-gate 
737*10444SVladimir.Kotal@Sun.COM 	if (des3 == B_FALSE) {
738*10444SVladimir.Kotal@Sun.COM 		keysize = DES2_KEYSIZE;
739*10444SVladimir.Kotal@Sun.COM 		checks = 2;
740*10444SVladimir.Kotal@Sun.COM 	}
741*10444SVladimir.Kotal@Sun.COM 
7420Sstevel@tonic-gate 	if (!IS_P2ALIGNED(key, sizeof (uint64_t))) {
743*10444SVladimir.Kotal@Sun.COM 		bcopy(key, aligned_key, keysize);
7440Sstevel@tonic-gate 		currentkey = (uint64_t *)aligned_key;
7450Sstevel@tonic-gate 	} else {
7460Sstevel@tonic-gate 		/* LINTED */
7470Sstevel@tonic-gate 		currentkey = (uint64_t *)key;
7480Sstevel@tonic-gate 	}
7490Sstevel@tonic-gate 
750*10444SVladimir.Kotal@Sun.COM 	for (j = 0; j < checks; j++) {
7510Sstevel@tonic-gate 		key_so_far = currentkey[j];
7520Sstevel@tonic-gate 
7530Sstevel@tonic-gate 		if (!keycheck((uint8_t *)&key_so_far, (uint8_t *)&scratch)) {
7540Sstevel@tonic-gate 			if (++num_weakkeys > 1) {
7550Sstevel@tonic-gate 				return (B_FALSE);
7560Sstevel@tonic-gate 			}
7570Sstevel@tonic-gate 			/*
7580Sstevel@tonic-gate 			 * We found a weak key, but since
7590Sstevel@tonic-gate 			 * we've only found one weak key,
7600Sstevel@tonic-gate 			 * we can not reject the whole 3DES
7610Sstevel@tonic-gate 			 * set of keys as weak.
7620Sstevel@tonic-gate 			 *
7630Sstevel@tonic-gate 			 * Break from the weak key loop
7640Sstevel@tonic-gate 			 * (since this DES key is weak) and
7650Sstevel@tonic-gate 			 * continue on.
7660Sstevel@tonic-gate 			 */
7670Sstevel@tonic-gate 		}
7680Sstevel@tonic-gate 
7690Sstevel@tonic-gate 		currentkey[j] = scratch;
7700Sstevel@tonic-gate 	}
7710Sstevel@tonic-gate 
7720Sstevel@tonic-gate 	/*
7730Sstevel@tonic-gate 	 * Perform key equivalence checks, now that parity is properly set.
7741065Smarkfen 	 * 1st and 2nd keys must be unique, the 3rd key can be the same as
7757421SDaniel.Anderson@Sun.COM 	 * the 1st key for the 2 key variant of 3DES.
7760Sstevel@tonic-gate 	 */
7771065Smarkfen 	if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2])
7780Sstevel@tonic-gate 		return (B_FALSE);
7790Sstevel@tonic-gate 
7800Sstevel@tonic-gate 	if (corrected_key != NULL) {
781*10444SVladimir.Kotal@Sun.COM 		bcopy(currentkey, corrected_key, keysize);
7820Sstevel@tonic-gate 	}
7832439Sizick 
7840Sstevel@tonic-gate /* EXPORT DELETE END */
7850Sstevel@tonic-gate 	return (B_TRUE);
7860Sstevel@tonic-gate }
7870Sstevel@tonic-gate 
7880Sstevel@tonic-gate boolean_t
des_keycheck(uint8_t * key,des_strength_t strength,uint8_t * corrected_key)7890Sstevel@tonic-gate des_keycheck(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
7900Sstevel@tonic-gate {
7910Sstevel@tonic-gate 	if (strength == DES) {
7920Sstevel@tonic-gate 		return (keycheck(key, corrected_key));
793*10444SVladimir.Kotal@Sun.COM 	} else if (strength == DES2) {
794*10444SVladimir.Kotal@Sun.COM 		return (des23_keycheck(key, corrected_key, B_FALSE));
7950Sstevel@tonic-gate 	} else if (strength == DES3) {
796*10444SVladimir.Kotal@Sun.COM 		return (des23_keycheck(key, corrected_key, B_TRUE));
7970Sstevel@tonic-gate 	} else {
7980Sstevel@tonic-gate 		return (B_FALSE);
7990Sstevel@tonic-gate 	}
8000Sstevel@tonic-gate }
8010Sstevel@tonic-gate 
8022439Sizick void
des_parity_fix(uint8_t * key,des_strength_t strength,uint8_t * corrected_key)8032439Sizick des_parity_fix(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
8042439Sizick {
8052452Sizick /* EXPORT DELETE START */
8062439Sizick 	uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
8072439Sizick 	uint8_t *paritied_key;
8082439Sizick 	uint64_t key_so_far;
8092439Sizick 	int i = 0, offset = 0;
8102439Sizick 
8112439Sizick 	if (strength == DES)
8122439Sizick 		bcopy(key, aligned_key, DES_KEYSIZE);
8132439Sizick 	else
8142439Sizick 		bcopy(key, aligned_key, DES3_KEYSIZE);
8152439Sizick 
8162439Sizick 	paritied_key = (uint8_t *)aligned_key;
8172439Sizick 	while (strength > i) {
8182439Sizick 		offset = 8 * i;
8197421SDaniel.Anderson@Sun.COM #ifdef UNALIGNED_POINTERS_PERMITTED
8207434SDaniel.Anderson@Sun.COM 		key_so_far = htonll(*(uint64_t *)(void *)&paritied_key[offset]);
8217421SDaniel.Anderson@Sun.COM #else
8222439Sizick 		key_so_far = (((uint64_t)paritied_key[offset + 0] << 56) |
8232439Sizick 		    ((uint64_t)paritied_key[offset + 1] << 48) |
8242439Sizick 		    ((uint64_t)paritied_key[offset + 2] << 40) |
8252439Sizick 		    ((uint64_t)paritied_key[offset + 3] << 32) |
8262439Sizick 		    ((uint64_t)paritied_key[offset + 4] << 24) |
8272439Sizick 		    ((uint64_t)paritied_key[offset + 5] << 16) |
8282439Sizick 		    ((uint64_t)paritied_key[offset + 6] << 8) |
8292439Sizick 		    (uint64_t)paritied_key[offset + 7]);
8307421SDaniel.Anderson@Sun.COM #endif	/* UNALIGNED_POINTERS_PERMITTED */
8312439Sizick 
8322439Sizick 		fix_des_parity(&key_so_far);
8332439Sizick 
8347421SDaniel.Anderson@Sun.COM #ifdef UNALIGNED_POINTERS_PERMITTED
8357434SDaniel.Anderson@Sun.COM 		*(uint64_t *)(void *)&paritied_key[offset] = htonll(key_so_far);
8367421SDaniel.Anderson@Sun.COM #else
8372439Sizick 		paritied_key[offset + 0] = key_so_far >> 56;
8382439Sizick 		paritied_key[offset + 1] = key_so_far >> 48;
8392439Sizick 		paritied_key[offset + 2] = key_so_far >> 40;
8402439Sizick 		paritied_key[offset + 3] = key_so_far >> 32;
8412439Sizick 		paritied_key[offset + 4] = key_so_far >> 24;
8422439Sizick 		paritied_key[offset + 5] = key_so_far >> 16;
8432439Sizick 		paritied_key[offset + 6] = key_so_far >> 8;
8442439Sizick 		paritied_key[offset + 7] = (uint8_t)key_so_far;
8457421SDaniel.Anderson@Sun.COM #endif	/* UNALIGNED_POINTERS_PERMITTED */
8462439Sizick 
8472439Sizick 		i++;
8482439Sizick 	}
8492439Sizick 
8502439Sizick 	bcopy(paritied_key, corrected_key, DES_KEYSIZE * strength);
8512452Sizick /* EXPORT DELETE END */
8522439Sizick }
8532439Sizick 
8542439Sizick 
8550Sstevel@tonic-gate /*
8560Sstevel@tonic-gate  * Initialize key schedule for DES, DES2, and DES3
8570Sstevel@tonic-gate  */
8580Sstevel@tonic-gate void
des_init_keysched(uint8_t * cipherKey,des_strength_t strength,void * ks)8590Sstevel@tonic-gate des_init_keysched(uint8_t *cipherKey, des_strength_t strength, void *ks)
8600Sstevel@tonic-gate {
8610Sstevel@tonic-gate /* EXPORT DELETE START */
8620Sstevel@tonic-gate 	uint64_t *encryption_ks;
8630Sstevel@tonic-gate 	uint64_t *decryption_ks;
8640Sstevel@tonic-gate 	uint64_t keysched[48];
8650Sstevel@tonic-gate 	uint64_t key_uint64[3];
8660Sstevel@tonic-gate 	uint64_t tmp;
8670Sstevel@tonic-gate 	uint_t keysize, i, j;
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate 	switch (strength) {
8700Sstevel@tonic-gate 	case DES:
8710Sstevel@tonic-gate 		keysize = DES_KEYSIZE;
8720Sstevel@tonic-gate 		encryption_ks = ((keysched_t *)ks)->ksch_encrypt;
8730Sstevel@tonic-gate 		decryption_ks = ((keysched_t *)ks)->ksch_decrypt;
8740Sstevel@tonic-gate 		break;
8750Sstevel@tonic-gate 	case DES2:
8760Sstevel@tonic-gate 		keysize = DES2_KEYSIZE;
8770Sstevel@tonic-gate 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
8780Sstevel@tonic-gate 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
8790Sstevel@tonic-gate 		break;
8800Sstevel@tonic-gate 	case DES3:
8810Sstevel@tonic-gate 		keysize = DES3_KEYSIZE;
8820Sstevel@tonic-gate 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
8830Sstevel@tonic-gate 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
8840Sstevel@tonic-gate 	}
8850Sstevel@tonic-gate 
8860Sstevel@tonic-gate 	/*
8870Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
8880Sstevel@tonic-gate 	 * reverses every 8 bytes in the key.  On BIG_ENDIAN, the same code
8890Sstevel@tonic-gate 	 * copies the key without reversing bytes.
8900Sstevel@tonic-gate 	 */
8910Sstevel@tonic-gate #ifdef _BIG_ENDIAN
8920Sstevel@tonic-gate 	if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) {
8930Sstevel@tonic-gate 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
8940Sstevel@tonic-gate 			/* LINTED: pointer alignment */
8950Sstevel@tonic-gate 			key_uint64[i] = *((uint64_t *)&cipherKey[j]);
8960Sstevel@tonic-gate 		}
8977421SDaniel.Anderson@Sun.COM 	} else
8987421SDaniel.Anderson@Sun.COM #endif	/* _BIG_ENDIAN */
8990Sstevel@tonic-gate 	{
9000Sstevel@tonic-gate 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
9017421SDaniel.Anderson@Sun.COM #ifdef UNALIGNED_POINTERS_PERMITTED
9027434SDaniel.Anderson@Sun.COM 			key_uint64[i] =
9037434SDaniel.Anderson@Sun.COM 			    htonll(*(uint64_t *)(void *)&cipherKey[j]);
9047421SDaniel.Anderson@Sun.COM #else
9050Sstevel@tonic-gate 			key_uint64[i] = (((uint64_t)cipherKey[j] << 56) |
9060Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 1] << 48) |
9070Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 2] << 40) |
9080Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 3] << 32) |
9090Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 4] << 24) |
9100Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 5] << 16) |
9110Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 6] << 8) |
9120Sstevel@tonic-gate 			    (uint64_t)cipherKey[j + 7]);
9137421SDaniel.Anderson@Sun.COM #endif	/* UNALIGNED_POINTERS_PERMITTED */
9140Sstevel@tonic-gate 		}
9150Sstevel@tonic-gate 	}
9160Sstevel@tonic-gate 
9170Sstevel@tonic-gate 	switch (strength) {
9180Sstevel@tonic-gate 	case DES:
9190Sstevel@tonic-gate 		des_ks(keysched, key_uint64[0]);
9200Sstevel@tonic-gate 		break;
9210Sstevel@tonic-gate 
9220Sstevel@tonic-gate 	case DES2:
9230Sstevel@tonic-gate 		/* DES2 is just DES3 with the first and third keys the same */
9240Sstevel@tonic-gate 		bcopy(key_uint64, key_uint64 + 2, DES_KEYSIZE);
9250Sstevel@tonic-gate 		/* FALLTHRU */
9260Sstevel@tonic-gate 	case DES3:
9270Sstevel@tonic-gate 		des_ks(keysched, key_uint64[0]);
9280Sstevel@tonic-gate 		des_ks(keysched + 16, key_uint64[1]);
9290Sstevel@tonic-gate 		for (i = 0; i < 8; i++) {
9300Sstevel@tonic-gate 			tmp = keysched[16+i];
9310Sstevel@tonic-gate 			keysched[16+i] = keysched[31-i];
9320Sstevel@tonic-gate 			keysched[31-i] = tmp;
9330Sstevel@tonic-gate 		}
9340Sstevel@tonic-gate 		des_ks(keysched+32, key_uint64[2]);
9350Sstevel@tonic-gate 		keysize = DES3_KEYSIZE;
9360Sstevel@tonic-gate 	}
9370Sstevel@tonic-gate 
9380Sstevel@tonic-gate 	/* save the encryption keyschedule */
9390Sstevel@tonic-gate 	bcopy(keysched, encryption_ks, keysize * 16);
9400Sstevel@tonic-gate 
9410Sstevel@tonic-gate 	/* reverse the key schedule */
9420Sstevel@tonic-gate 	for (i = 0; i < keysize; i++) {
9430Sstevel@tonic-gate 		tmp = keysched[i];
9440Sstevel@tonic-gate 		keysched[i] = keysched[2 * keysize - 1 - i];
9450Sstevel@tonic-gate 		keysched[2 * keysize -1 -i] = tmp;
9460Sstevel@tonic-gate 	}
9470Sstevel@tonic-gate 
9480Sstevel@tonic-gate 	/* save the decryption keyschedule */
9490Sstevel@tonic-gate 	bcopy(keysched, decryption_ks, keysize * 16);
9500Sstevel@tonic-gate /* EXPORT DELETE END */
9510Sstevel@tonic-gate }
9520Sstevel@tonic-gate 
9530Sstevel@tonic-gate /*
9540Sstevel@tonic-gate  * Allocate key schedule.
9550Sstevel@tonic-gate  */
9560Sstevel@tonic-gate /*ARGSUSED*/
9570Sstevel@tonic-gate void *
des_alloc_keysched(size_t * keysched_size,des_strength_t strength,int kmflag)9580Sstevel@tonic-gate des_alloc_keysched(size_t *keysched_size, des_strength_t strength, int kmflag)
9590Sstevel@tonic-gate {
9600Sstevel@tonic-gate 	void *keysched;
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate /* EXPORT DELETE START */
9630Sstevel@tonic-gate 
9640Sstevel@tonic-gate 	size_t size;
9650Sstevel@tonic-gate 
9660Sstevel@tonic-gate 	switch (strength) {
9670Sstevel@tonic-gate 	case DES:
9680Sstevel@tonic-gate 		size = sizeof (keysched_t);
9690Sstevel@tonic-gate 		break;
9700Sstevel@tonic-gate 	case DES2:
9710Sstevel@tonic-gate 	case DES3:
9720Sstevel@tonic-gate 		size = sizeof (keysched3_t);
9730Sstevel@tonic-gate 	}
9740Sstevel@tonic-gate 
9750Sstevel@tonic-gate #ifdef	_KERNEL
9760Sstevel@tonic-gate 	keysched = (keysched_t *)kmem_alloc(size, kmflag);
9770Sstevel@tonic-gate #else	/* !_KERNEL */
9780Sstevel@tonic-gate 	keysched = (keysched_t *)malloc(size);
9790Sstevel@tonic-gate #endif	/* _KERNEL */
9800Sstevel@tonic-gate 
9810Sstevel@tonic-gate 	if (keysched == NULL)
9820Sstevel@tonic-gate 		return (NULL);
9830Sstevel@tonic-gate 
9840Sstevel@tonic-gate 	if (keysched_size != NULL)
9850Sstevel@tonic-gate 		*keysched_size = size;
9860Sstevel@tonic-gate 
9870Sstevel@tonic-gate /* EXPORT DELETE END */
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate 	return (keysched);
9900Sstevel@tonic-gate }
9910Sstevel@tonic-gate 
9920Sstevel@tonic-gate /*
9930Sstevel@tonic-gate  * Replace the LSB of each byte by the xor of the other
9940Sstevel@tonic-gate  * 7 bits.  The tricky thing is that the original contents of the LSBs
9957421SDaniel.Anderson@Sun.COM  * are nullified by including them twice in the xor computation.
9960Sstevel@tonic-gate  */
9970Sstevel@tonic-gate static void
fix_des_parity(uint64_t * keyp)9980Sstevel@tonic-gate fix_des_parity(uint64_t *keyp)
9990Sstevel@tonic-gate {
10000Sstevel@tonic-gate /* EXPORT DELETE START */
10010Sstevel@tonic-gate 	uint64_t k = *keyp;
10020Sstevel@tonic-gate 	k ^= k >> 1;
10030Sstevel@tonic-gate 	k ^= k >> 2;
10040Sstevel@tonic-gate 	k ^= k >> 4;
1005416Skrishna 	*keyp ^= (k & 0x0101010101010101ULL);
10062439Sizick 	*keyp ^= 0x0101010101010101ULL;
10070Sstevel@tonic-gate /* EXPORT DELETE END */
10080Sstevel@tonic-gate }
10097188Smcpowers 
10107188Smcpowers void
des_copy_block(uint8_t * in,uint8_t * out)10117188Smcpowers des_copy_block(uint8_t *in, uint8_t *out)
10127188Smcpowers {
10137188Smcpowers 	if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
10147188Smcpowers 	    IS_P2ALIGNED(out, sizeof (uint32_t))) {
10157188Smcpowers 		/* LINTED: pointer alignment */
10167188Smcpowers 		*(uint32_t *)&out[0] = *(uint32_t *)&in[0];
10177188Smcpowers 		/* LINTED: pointer alignment */
10187188Smcpowers 		*(uint32_t *)&out[4] = *(uint32_t *)&in[4];
10197188Smcpowers 	} else {
10207188Smcpowers 		DES_COPY_BLOCK(in, out);
10217188Smcpowers 	}
10227188Smcpowers }
10237188Smcpowers 
10247188Smcpowers /* XOR block of data into dest */
10257188Smcpowers void
des_xor_block(uint8_t * data,uint8_t * dst)10267188Smcpowers des_xor_block(uint8_t *data, uint8_t *dst)
10277188Smcpowers {
10287188Smcpowers 	if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
10297188Smcpowers 	    IS_P2ALIGNED(data, sizeof (uint32_t))) {
10307188Smcpowers 		/* LINTED: pointer alignment */
10317188Smcpowers 		*(uint32_t *)&dst[0] ^=
10327421SDaniel.Anderson@Sun.COM 		    /* LINTED: pointer alignment */
10337188Smcpowers 		    *(uint32_t *)&data[0];
10347421SDaniel.Anderson@Sun.COM 		    /* LINTED: pointer alignment */
10357188Smcpowers 		*(uint32_t *)&dst[4] ^=
10367421SDaniel.Anderson@Sun.COM 		    /* LINTED: pointer alignment */
10377188Smcpowers 		    *(uint32_t *)&data[4];
10387188Smcpowers 	} else {
10397188Smcpowers 		DES_XOR_BLOCK(data, dst);
10407188Smcpowers 	}
10417188Smcpowers }
10427188Smcpowers 
10437188Smcpowers int
des_encrypt_block(const void * keysched,const uint8_t * in,uint8_t * out)10447188Smcpowers des_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
10457188Smcpowers {
10467188Smcpowers 	return (des_crunch_block(keysched, in, out, B_FALSE));
10477188Smcpowers }
10487188Smcpowers 
10497188Smcpowers int
des3_encrypt_block(const void * keysched,const uint8_t * in,uint8_t * out)10507188Smcpowers des3_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
10517188Smcpowers {
10527188Smcpowers 	return (des3_crunch_block(keysched, in, out, B_FALSE));
10537188Smcpowers }
10547188Smcpowers 
10557188Smcpowers int
des_decrypt_block(const void * keysched,const uint8_t * in,uint8_t * out)10567188Smcpowers des_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
10577188Smcpowers {
10587188Smcpowers 	return (des_crunch_block(keysched, in, out, B_TRUE));
10597188Smcpowers }
10607188Smcpowers 
10617188Smcpowers int
des3_decrypt_block(const void * keysched,const uint8_t * in,uint8_t * out)10627188Smcpowers des3_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
10637188Smcpowers {
10647188Smcpowers 	return (des3_crunch_block(keysched, in, out, B_TRUE));
10657188Smcpowers }
10667188Smcpowers 
10677188Smcpowers /*
10687188Smcpowers  * Encrypt multiple blocks of data according to mode.
10697188Smcpowers  */
10707188Smcpowers int
des_encrypt_contiguous_blocks(void * ctx,char * data,size_t length,crypto_data_t * out)10717188Smcpowers des_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
10727188Smcpowers     crypto_data_t *out)
10737188Smcpowers {
10747188Smcpowers 	des_ctx_t *des_ctx = ctx;
10757188Smcpowers 	int rv;
10767188Smcpowers 
10777188Smcpowers 	if (des_ctx->dc_flags & DES3_STRENGTH) {
10787188Smcpowers 		if (des_ctx->dc_flags & CBC_MODE) {
10797188Smcpowers 			rv = cbc_encrypt_contiguous_blocks(ctx, data,
10807188Smcpowers 			    length, out, DES_BLOCK_LEN, des3_encrypt_block,
10817188Smcpowers 			    des_copy_block, des_xor_block);
10827188Smcpowers 		} else {
10837188Smcpowers 			rv = ecb_cipher_contiguous_blocks(ctx, data, length,
10847188Smcpowers 			    out, DES_BLOCK_LEN, des3_encrypt_block);
10857188Smcpowers 		}
10867188Smcpowers 	} else {
10877188Smcpowers 		if (des_ctx->dc_flags & CBC_MODE) {
10887188Smcpowers 			rv = cbc_encrypt_contiguous_blocks(ctx, data,
10897188Smcpowers 			    length, out, DES_BLOCK_LEN, des_encrypt_block,
10907188Smcpowers 			    des_copy_block, des_xor_block);
10917188Smcpowers 		} else {
10927188Smcpowers 			rv = ecb_cipher_contiguous_blocks(ctx, data, length,
10937188Smcpowers 			    out, DES_BLOCK_LEN, des_encrypt_block);
10947188Smcpowers 		}
10957188Smcpowers 	}
10967188Smcpowers 	return (rv);
10977188Smcpowers }
10987188Smcpowers 
10997188Smcpowers /*
11007188Smcpowers  * Decrypt multiple blocks of data according to mode.
11017188Smcpowers  */
11027188Smcpowers int
des_decrypt_contiguous_blocks(void * ctx,char * data,size_t length,crypto_data_t * out)11037188Smcpowers des_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
11047188Smcpowers     crypto_data_t *out)
11057188Smcpowers {
11067188Smcpowers 	des_ctx_t *des_ctx = ctx;
11077188Smcpowers 	int rv;
11087188Smcpowers 
11097188Smcpowers 	if (des_ctx->dc_flags & DES3_STRENGTH) {
11107188Smcpowers 		if (des_ctx->dc_flags & CBC_MODE) {
11117188Smcpowers 			rv = cbc_decrypt_contiguous_blocks(ctx, data,
11127188Smcpowers 			    length, out, DES_BLOCK_LEN, des3_decrypt_block,
11137188Smcpowers 			    des_copy_block, des_xor_block);
11147188Smcpowers 		} else {
11157188Smcpowers 			rv = ecb_cipher_contiguous_blocks(ctx, data, length,
11167188Smcpowers 			    out, DES_BLOCK_LEN, des3_decrypt_block);
11177188Smcpowers 			if (rv == CRYPTO_DATA_LEN_RANGE)
11187188Smcpowers 				rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
11197188Smcpowers 		}
11207188Smcpowers 	} else {
11217188Smcpowers 		if (des_ctx->dc_flags & CBC_MODE) {
11227188Smcpowers 			rv = cbc_decrypt_contiguous_blocks(ctx, data,
11237188Smcpowers 			    length, out, DES_BLOCK_LEN, des_decrypt_block,
11247188Smcpowers 			    des_copy_block, des_xor_block);
11257188Smcpowers 		} else {
11267188Smcpowers 			rv = ecb_cipher_contiguous_blocks(ctx, data, length,
11277188Smcpowers 			    out, DES_BLOCK_LEN, des_decrypt_block);
11287188Smcpowers 			if (rv == CRYPTO_DATA_LEN_RANGE)
11297188Smcpowers 				rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
11307188Smcpowers 		}
11317188Smcpowers 	}
11327188Smcpowers 	return (rv);
11337188Smcpowers }
1134