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