xref: /titanic_51/usr/src/common/crypto/des/des_impl.c (revision 694c35faa87b858ecdadfe4fc592615f4eefbb07)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5690caf98Sizick  * Common Development and Distribution License (the "License").
6690caf98Sizick  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*436935a1SVladimir Kotal  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate #include <sys/systm.h>
287c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
297c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
307c478bd9Sstevel@tonic-gate #include <sys/strsun.h>
3123c57df7Smcpowers #include <sys/crypto/spi.h>
3223c57df7Smcpowers #include <modes/modes.h>
337c478bd9Sstevel@tonic-gate #include <sys/crypto/common.h>
347c478bd9Sstevel@tonic-gate #include "des_impl.h"
357c478bd9Sstevel@tonic-gate #ifndef	_KERNEL
367c478bd9Sstevel@tonic-gate #include <strings.h>
377c478bd9Sstevel@tonic-gate #include <stdlib.h>
387c478bd9Sstevel@tonic-gate #endif	/* !_KERNEL */
397c478bd9Sstevel@tonic-gate 
404b56a003SDaniel Anderson #if defined(__i386) || defined(__amd64)
414b56a003SDaniel Anderson #include <sys/byteorder.h>
424b56a003SDaniel Anderson #define	UNALIGNED_POINTERS_PERMITTED
434b56a003SDaniel Anderson #endif
444b56a003SDaniel Anderson 
457c478bd9Sstevel@tonic-gate typedef struct keysched_s {
467c478bd9Sstevel@tonic-gate 	uint64_t ksch_encrypt[16];
477c478bd9Sstevel@tonic-gate 	uint64_t ksch_decrypt[16];
487c478bd9Sstevel@tonic-gate } keysched_t;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate typedef struct keysched3_s {
517c478bd9Sstevel@tonic-gate 	uint64_t ksch_encrypt[48];
527c478bd9Sstevel@tonic-gate 	uint64_t ksch_decrypt[48];
537c478bd9Sstevel@tonic-gate } keysched3_t;
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate static void fix_des_parity(uint64_t *);
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate #ifndef sun4u
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate static const uint64_t sbox_table[8][64]=
607c478bd9Sstevel@tonic-gate {
614cc1ac68Skrishna /* BEGIN CSTYLED */
627c478bd9Sstevel@tonic-gate {
634cc1ac68Skrishna 0x0000140140020000ULL, 0x0000000000000000ULL, 0x0000000140000000ULL, 0x0000140140020020ULL,
644cc1ac68Skrishna 0x0000140140000020ULL, 0x0000000140020020ULL, 0x0000000000000020ULL, 0x0000000140000000ULL,
654cc1ac68Skrishna 0x0000000000020000ULL, 0x0000140140020000ULL, 0x0000140140020020ULL, 0x0000000000020000ULL,
664cc1ac68Skrishna 0x0000140000020020ULL, 0x0000140140000020ULL, 0x0000140000000000ULL, 0x0000000000000020ULL,
674cc1ac68Skrishna 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000140020000ULL,
684cc1ac68Skrishna 0x0000000140020000ULL, 0x0000140140000000ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
694cc1ac68Skrishna 0x0000000140000020ULL, 0x0000140000000020ULL, 0x0000140000000020ULL, 0x0000000140000020ULL,
704cc1ac68Skrishna 0x0000000000000000ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140000000000ULL,
714cc1ac68Skrishna 0x0000000140000000ULL, 0x0000140140020020ULL, 0x0000000000000020ULL, 0x0000140140000000ULL,
724cc1ac68Skrishna 0x0000140140020000ULL, 0x0000140000000000ULL, 0x0000140000000000ULL, 0x0000000000020000ULL,
734cc1ac68Skrishna 0x0000140140000020ULL, 0x0000000140000000ULL, 0x0000000140020000ULL, 0x0000140000000020ULL,
744cc1ac68Skrishna 0x0000000000020000ULL, 0x0000000000000020ULL, 0x0000140000020020ULL, 0x0000000140020020ULL,
754cc1ac68Skrishna 0x0000140140020020ULL, 0x0000000140000020ULL, 0x0000140140000000ULL, 0x0000140000020020ULL,
764cc1ac68Skrishna 0x0000140000000020ULL, 0x0000000000020020ULL, 0x0000000140020020ULL, 0x0000140140020000ULL,
774cc1ac68Skrishna 0x0000000000020020ULL, 0x0000140000020000ULL, 0x0000140000020000ULL, 0x0000000000000000ULL,
784cc1ac68Skrishna 0x0000000140000020ULL, 0x0000000140020000ULL, 0x0000000000000000ULL, 0x0000140140000020ULL
797c478bd9Sstevel@tonic-gate },
807c478bd9Sstevel@tonic-gate {
814cc1ac68Skrishna 0x2000005020000500ULL, 0x2000000020000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL,
824cc1ac68Skrishna 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL, 0x2000000020000500ULL,
834cc1ac68Skrishna 0x2000000000000500ULL, 0x2000005020000500ULL, 0x2000005020000000ULL, 0x2000000000000000ULL,
844cc1ac68Skrishna 0x2000000020000000ULL, 0x0000005000000000ULL, 0x0000000000000500ULL, 0x2000005000000500ULL,
854cc1ac68Skrishna 0x0000005020000000ULL, 0x0000005000000500ULL, 0x2000000020000500ULL, 0x0000000000000000ULL,
864cc1ac68Skrishna 0x2000000000000000ULL, 0x0000000020000000ULL, 0x0000005020000500ULL, 0x2000005000000000ULL,
874cc1ac68Skrishna 0x0000005000000500ULL, 0x2000000000000500ULL, 0x0000000000000000ULL, 0x0000005020000000ULL,
884cc1ac68Skrishna 0x0000000020000500ULL, 0x2000005020000000ULL, 0x2000005000000000ULL, 0x0000000020000500ULL,
894cc1ac68Skrishna 0x0000000000000000ULL, 0x0000005020000500ULL, 0x2000005000000500ULL, 0x0000005000000000ULL,
904cc1ac68Skrishna 0x2000000020000500ULL, 0x2000005000000000ULL, 0x2000005020000000ULL, 0x0000000020000000ULL,
914cc1ac68Skrishna 0x2000005000000000ULL, 0x2000000020000000ULL, 0x0000000000000500ULL, 0x2000005020000500ULL,
924cc1ac68Skrishna 0x0000005020000500ULL, 0x0000000000000500ULL, 0x0000000020000000ULL, 0x2000000000000000ULL,
934cc1ac68Skrishna 0x0000000020000500ULL, 0x2000005020000000ULL, 0x0000005000000000ULL, 0x2000000000000500ULL,
944cc1ac68Skrishna 0x0000005000000500ULL, 0x2000000020000500ULL, 0x2000000000000500ULL, 0x0000005000000500ULL,
954cc1ac68Skrishna 0x0000005020000000ULL, 0x0000000000000000ULL, 0x2000000020000000ULL, 0x0000000020000500ULL,
964cc1ac68Skrishna 0x2000000000000000ULL, 0x2000005000000500ULL, 0x2000005020000500ULL, 0x0000005020000000ULL
977c478bd9Sstevel@tonic-gate },
987c478bd9Sstevel@tonic-gate {
994cc1ac68Skrishna 0x0000000000014040ULL, 0x0000800280014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
1004cc1ac68Skrishna 0x0000800000014000ULL, 0x0000000000000000ULL, 0x0000000280014040ULL, 0x0000800000014000ULL,
1014cc1ac68Skrishna 0x0000000280000040ULL, 0x0000800000000040ULL, 0x0000800000000040ULL, 0x0000000280000000ULL,
1024cc1ac68Skrishna 0x0000800280014040ULL, 0x0000000280000040ULL, 0x0000800280000000ULL, 0x0000000000014040ULL,
1034cc1ac68Skrishna 0x0000800000000000ULL, 0x0000000000000040ULL, 0x0000800280014000ULL, 0x0000000000014000ULL,
1044cc1ac68Skrishna 0x0000000280014000ULL, 0x0000800280000000ULL, 0x0000800280000040ULL, 0x0000000280014040ULL,
1054cc1ac68Skrishna 0x0000800000014040ULL, 0x0000000280014000ULL, 0x0000000280000000ULL, 0x0000800000014040ULL,
1064cc1ac68Skrishna 0x0000000000000040ULL, 0x0000800280014040ULL, 0x0000000000014000ULL, 0x0000800000000000ULL,
1074cc1ac68Skrishna 0x0000800280014000ULL, 0x0000800000000000ULL, 0x0000000280000040ULL, 0x0000000000014040ULL,
1084cc1ac68Skrishna 0x0000000280000000ULL, 0x0000800280014000ULL, 0x0000800000014000ULL, 0x0000000000000000ULL,
1094cc1ac68Skrishna 0x0000000000014000ULL, 0x0000000280000040ULL, 0x0000800280014040ULL, 0x0000800000014000ULL,
1104cc1ac68Skrishna 0x0000800000000040ULL, 0x0000000000014000ULL, 0x0000000000000000ULL, 0x0000800280000040ULL,
1114cc1ac68Skrishna 0x0000800000014040ULL, 0x0000000280000000ULL, 0x0000800000000000ULL, 0x0000800280014040ULL,
1124cc1ac68Skrishna 0x0000000000000040ULL, 0x0000000280014040ULL, 0x0000000280014000ULL, 0x0000800000000040ULL,
1134cc1ac68Skrishna 0x0000800280000000ULL, 0x0000800000014040ULL, 0x0000000000014040ULL, 0x0000800280000000ULL,
1144cc1ac68Skrishna 0x0000000280014040ULL, 0x0000000000000040ULL, 0x0000800280000040ULL, 0x0000000280014000ULL
1157c478bd9Sstevel@tonic-gate },
1167c478bd9Sstevel@tonic-gate {
1174cc1ac68Skrishna 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
1184cc1ac68Skrishna 0x0000020008101000ULL, 0x4000020000001008ULL, 0x4000020000000008ULL, 0x4000000008100008ULL,
1194cc1ac68Skrishna 0x0000000000000000ULL, 0x0000020008100000ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
1204cc1ac68Skrishna 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000020000001000ULL, 0x4000020000000008ULL,
1214cc1ac68Skrishna 0x4000000000000008ULL, 0x0000000008100000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
1224cc1ac68Skrishna 0x0000000000001000ULL, 0x0000020000000000ULL, 0x4000000008100008ULL, 0x0000000008101000ULL,
1234cc1ac68Skrishna 0x4000020000001008ULL, 0x4000000000000008ULL, 0x0000000008101000ULL, 0x0000020000001000ULL,
1244cc1ac68Skrishna 0x0000000008100000ULL, 0x0000020008101000ULL, 0x4000020008101008ULL, 0x4000000000001008ULL,
1254cc1ac68Skrishna 0x0000020000001000ULL, 0x4000020000000008ULL, 0x0000020008100000ULL, 0x4000020008101008ULL,
1264cc1ac68Skrishna 0x4000000000001008ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000020008100000ULL,
1274cc1ac68Skrishna 0x0000000008101000ULL, 0x0000020000001000ULL, 0x4000020000001008ULL, 0x4000000000000008ULL,
1284cc1ac68Skrishna 0x4000020008100008ULL, 0x4000000008101008ULL, 0x4000000008101008ULL, 0x0000000000001000ULL,
1294cc1ac68Skrishna 0x4000020008101008ULL, 0x4000000000001008ULL, 0x4000000000000008ULL, 0x0000000008100000ULL,
1304cc1ac68Skrishna 0x4000020000000008ULL, 0x4000000008100008ULL, 0x0000020008101000ULL, 0x4000020000001008ULL,
1314cc1ac68Skrishna 0x4000000008100008ULL, 0x0000000008101000ULL, 0x0000020000000000ULL, 0x4000020008100008ULL,
1324cc1ac68Skrishna 0x0000000000001000ULL, 0x0000020000000000ULL, 0x0000000008100000ULL, 0x0000020008101000ULL
1337c478bd9Sstevel@tonic-gate },
1347c478bd9Sstevel@tonic-gate {
1354cc1ac68Skrishna 0x000000000000a000ULL, 0x000028080000a000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL,
1364cc1ac68Skrishna 0x0000000800000000ULL, 0x000000000000a000ULL, 0x1000000000000000ULL, 0x0000280800000000ULL,
1374cc1ac68Skrishna 0x100000080000a000ULL, 0x0000000800000000ULL, 0x000028000000a000ULL, 0x100000080000a000ULL,
1384cc1ac68Skrishna 0x100028000000a000ULL, 0x1000280800000000ULL, 0x000000080000a000ULL, 0x1000000000000000ULL,
1394cc1ac68Skrishna 0x0000280000000000ULL, 0x1000000800000000ULL, 0x1000000800000000ULL, 0x0000000000000000ULL,
1404cc1ac68Skrishna 0x100000000000a000ULL, 0x100028080000a000ULL, 0x100028080000a000ULL, 0x000028000000a000ULL,
1414cc1ac68Skrishna 0x1000280800000000ULL, 0x100000000000a000ULL, 0x0000000000000000ULL, 0x1000280000000000ULL,
1424cc1ac68Skrishna 0x000028080000a000ULL, 0x0000280000000000ULL, 0x1000280000000000ULL, 0x000000080000a000ULL,
1434cc1ac68Skrishna 0x0000000800000000ULL, 0x100028000000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL,
1444cc1ac68Skrishna 0x1000000000000000ULL, 0x0000280800000000ULL, 0x100028000000a000ULL, 0x100000080000a000ULL,
1454cc1ac68Skrishna 0x000028000000a000ULL, 0x1000000000000000ULL, 0x1000280800000000ULL, 0x000028080000a000ULL,
1464cc1ac68Skrishna 0x100000080000a000ULL, 0x000000000000a000ULL, 0x0000280000000000ULL, 0x1000280800000000ULL,
1474cc1ac68Skrishna 0x100028080000a000ULL, 0x000000080000a000ULL, 0x1000280000000000ULL, 0x100028080000a000ULL,
1484cc1ac68Skrishna 0x0000280800000000ULL, 0x0000000000000000ULL, 0x1000000800000000ULL, 0x1000280000000000ULL,
1494cc1ac68Skrishna 0x000000080000a000ULL, 0x000028000000a000ULL, 0x100000000000a000ULL, 0x0000000800000000ULL,
1504cc1ac68Skrishna 0x0000000000000000ULL, 0x1000000800000000ULL, 0x000028080000a000ULL, 0x100000000000a000ULL
1517c478bd9Sstevel@tonic-gate },
1527c478bd9Sstevel@tonic-gate {
1534cc1ac68Skrishna 0x0802000000000280ULL, 0x0802010000000000ULL, 0x0000000010000000ULL, 0x0802010010000280ULL,
1544cc1ac68Skrishna 0x0802010000000000ULL, 0x0000000000000280ULL, 0x0802010010000280ULL, 0x0000010000000000ULL,
1554cc1ac68Skrishna 0x0802000010000000ULL, 0x0000010010000280ULL, 0x0000010000000000ULL, 0x0802000000000280ULL,
1564cc1ac68Skrishna 0x0000010000000280ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
1574cc1ac68Skrishna 0x0000000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000010000000ULL,
1584cc1ac68Skrishna 0x0000010010000000ULL, 0x0802000010000280ULL, 0x0000000000000280ULL, 0x0802010000000280ULL,
1594cc1ac68Skrishna 0x0802010000000280ULL, 0x0000000000000000ULL, 0x0000010010000280ULL, 0x0802010010000000ULL,
1604cc1ac68Skrishna 0x0000000010000280ULL, 0x0000010010000000ULL, 0x0802010010000000ULL, 0x0802000000000000ULL,
1614cc1ac68Skrishna 0x0802000010000000ULL, 0x0000000000000280ULL, 0x0802010000000280ULL, 0x0000010010000000ULL,
1624cc1ac68Skrishna 0x0802010010000280ULL, 0x0000010000000000ULL, 0x0000000010000280ULL, 0x0802000000000280ULL,
1634cc1ac68Skrishna 0x0000010000000000ULL, 0x0802000010000000ULL, 0x0802000000000000ULL, 0x0000000010000280ULL,
1644cc1ac68Skrishna 0x0802000000000280ULL, 0x0802010010000280ULL, 0x0000010010000000ULL, 0x0802010000000000ULL,
1654cc1ac68Skrishna 0x0000010010000280ULL, 0x0802010010000000ULL, 0x0000000000000000ULL, 0x0802010000000280ULL,
1664cc1ac68Skrishna 0x0000000000000280ULL, 0x0000000010000000ULL, 0x0802010000000000ULL, 0x0000010010000280ULL,
1674cc1ac68Skrishna 0x0000000010000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL, 0x0000000000000000ULL,
1684cc1ac68Skrishna 0x0802010010000000ULL, 0x0802000000000000ULL, 0x0000010000000280ULL, 0x0802000010000280ULL
1697c478bd9Sstevel@tonic-gate },
1707c478bd9Sstevel@tonic-gate {
1714cc1ac68Skrishna 0x000000a000000000ULL, 0x800040a000000010ULL, 0x8000400000040010ULL, 0x0000000000000000ULL,
1724cc1ac68Skrishna 0x0000000000040000ULL, 0x8000400000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
1734cc1ac68Skrishna 0x800040a000040010ULL, 0x000000a000000000ULL, 0x0000000000000000ULL, 0x8000400000000010ULL,
1744cc1ac68Skrishna 0x8000000000000010ULL, 0x0000400000000000ULL, 0x800040a000000010ULL, 0x8000000000040010ULL,
1754cc1ac68Skrishna 0x0000400000040000ULL, 0x800000a000040010ULL, 0x800000a000000010ULL, 0x0000400000040000ULL,
1764cc1ac68Skrishna 0x8000400000000010ULL, 0x000040a000000000ULL, 0x000040a000040000ULL, 0x800000a000000010ULL,
1774cc1ac68Skrishna 0x000040a000000000ULL, 0x0000000000040000ULL, 0x8000000000040010ULL, 0x800040a000040010ULL,
1784cc1ac68Skrishna 0x000000a000040000ULL, 0x8000000000000010ULL, 0x0000400000000000ULL, 0x000000a000040000ULL,
1794cc1ac68Skrishna 0x0000400000000000ULL, 0x000000a000040000ULL, 0x000000a000000000ULL, 0x8000400000040010ULL,
1804cc1ac68Skrishna 0x8000400000040010ULL, 0x800040a000000010ULL, 0x800040a000000010ULL, 0x8000000000000010ULL,
1814cc1ac68Skrishna 0x800000a000000010ULL, 0x0000400000000000ULL, 0x0000400000040000ULL, 0x000000a000000000ULL,
1824cc1ac68Skrishna 0x000040a000040000ULL, 0x8000000000040010ULL, 0x800000a000040010ULL, 0x000040a000040000ULL,
1834cc1ac68Skrishna 0x8000000000040010ULL, 0x8000400000000010ULL, 0x800040a000040010ULL, 0x000040a000000000ULL,
1844cc1ac68Skrishna 0x000000a000040000ULL, 0x0000000000000000ULL, 0x8000000000000010ULL, 0x800040a000040010ULL,
1854cc1ac68Skrishna 0x0000000000000000ULL, 0x800000a000040010ULL, 0x000040a000000000ULL, 0x0000000000040000ULL,
1864cc1ac68Skrishna 0x8000400000000010ULL, 0x0000400000040000ULL, 0x0000000000040000ULL, 0x800000a000000010ULL
1877c478bd9Sstevel@tonic-gate },
1887c478bd9Sstevel@tonic-gate {
1894cc1ac68Skrishna 0x0401000004080800ULL, 0x0000000004080000ULL, 0x0000000400000000ULL, 0x0401000404080800ULL,
1904cc1ac68Skrishna 0x0401000000000000ULL, 0x0401000004080800ULL, 0x0000000000000800ULL, 0x0401000000000000ULL,
1914cc1ac68Skrishna 0x0000000400000800ULL, 0x0401000400000000ULL, 0x0401000404080800ULL, 0x0000000404080000ULL,
1924cc1ac68Skrishna 0x0401000404080000ULL, 0x0000000404080800ULL, 0x0000000004080000ULL, 0x0000000000000800ULL,
1934cc1ac68Skrishna 0x0401000400000000ULL, 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000004080800ULL,
1944cc1ac68Skrishna 0x0000000404080000ULL, 0x0000000400000800ULL, 0x0401000400000800ULL, 0x0401000404080000ULL,
1954cc1ac68Skrishna 0x0000000004080800ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0401000400000800ULL,
1964cc1ac68Skrishna 0x0401000000000800ULL, 0x0401000004080000ULL, 0x0000000404080800ULL, 0x0000000400000000ULL,
1974cc1ac68Skrishna 0x0000000404080800ULL, 0x0000000400000000ULL, 0x0401000404080000ULL, 0x0000000004080000ULL,
1984cc1ac68Skrishna 0x0000000000000800ULL, 0x0401000400000800ULL, 0x0000000004080000ULL, 0x0000000404080800ULL,
1994cc1ac68Skrishna 0x0401000004080000ULL, 0x0000000000000800ULL, 0x0401000000000800ULL, 0x0401000400000000ULL,
2004cc1ac68Skrishna 0x0401000400000800ULL, 0x0401000000000000ULL, 0x0000000400000000ULL, 0x0401000004080800ULL,
2014cc1ac68Skrishna 0x0000000000000000ULL, 0x0401000404080800ULL, 0x0000000400000800ULL, 0x0401000000000800ULL,
2024cc1ac68Skrishna 0x0401000400000000ULL, 0x0401000004080000ULL, 0x0401000004080800ULL, 0x0000000000000000ULL,
2034cc1ac68Skrishna 0x0401000404080800ULL, 0x0000000404080000ULL, 0x0000000404080000ULL, 0x0000000004080800ULL,
2044cc1ac68Skrishna 0x0000000004080800ULL, 0x0000000400000800ULL, 0x0401000000000000ULL, 0x0401000404080000ULL
2057c478bd9Sstevel@tonic-gate }
2064cc1ac68Skrishna /* END CSTYLED */
2077c478bd9Sstevel@tonic-gate };
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate static const uint64_t ip_table[2][256]=
2117c478bd9Sstevel@tonic-gate {
2124cc1ac68Skrishna /* BEGIN CSTYLED */
2137c478bd9Sstevel@tonic-gate {
2144cc1ac68Skrishna 0x0000000000000000ULL, 0x0000000000000400ULL, 0x0080000000000280ULL, 0x0080000000000680ULL,
2154cc1ac68Skrishna 0x0000000000400000ULL, 0x0000000000400400ULL, 0x0080000000400280ULL, 0x0080000000400680ULL,
2164cc1ac68Skrishna 0x0000000000280000ULL, 0x0000000000280400ULL, 0x0080000000280280ULL, 0x0080000000280680ULL,
2174cc1ac68Skrishna 0x0000000000680000ULL, 0x0000000000680400ULL, 0x0080000000680280ULL, 0x0080000000680680ULL,
2184cc1ac68Skrishna 0x0000000400000000ULL, 0x0000000400000400ULL, 0x0080000400000280ULL, 0x0080000400000680ULL,
2194cc1ac68Skrishna 0x0000000400400000ULL, 0x0000000400400400ULL, 0x0080000400400280ULL, 0x0080000400400680ULL,
2204cc1ac68Skrishna 0x0000000400280000ULL, 0x0000000400280400ULL, 0x0080000400280280ULL, 0x0080000400280680ULL,
2214cc1ac68Skrishna 0x0000000400680000ULL, 0x0000000400680400ULL, 0x0080000400680280ULL, 0x0080000400680680ULL,
2224cc1ac68Skrishna 0x0000000280000000ULL, 0x0000000280000400ULL, 0x0080000280000280ULL, 0x0080000280000680ULL,
2234cc1ac68Skrishna 0x0000000280400000ULL, 0x0000000280400400ULL, 0x0080000280400280ULL, 0x0080000280400680ULL,
2244cc1ac68Skrishna 0x0000000280280000ULL, 0x0000000280280400ULL, 0x0080000280280280ULL, 0x0080000280280680ULL,
2254cc1ac68Skrishna 0x0000000280680000ULL, 0x0000000280680400ULL, 0x0080000280680280ULL, 0x0080000280680680ULL,
2264cc1ac68Skrishna 0x0000000680000000ULL, 0x0000000680000400ULL, 0x0080000680000280ULL, 0x0080000680000680ULL,
2274cc1ac68Skrishna 0x0000000680400000ULL, 0x0000000680400400ULL, 0x0080000680400280ULL, 0x0080000680400680ULL,
2284cc1ac68Skrishna 0x0000000680280000ULL, 0x0000000680280400ULL, 0x0080000680280280ULL, 0x0080000680280680ULL,
2294cc1ac68Skrishna 0x0000000680680000ULL, 0x0000000680680400ULL, 0x0080000680680280ULL, 0x0080000680680680ULL,
2304cc1ac68Skrishna 0x0000400000000000ULL, 0x0000400000000400ULL, 0x0080400000000280ULL, 0x0080400000000680ULL,
2314cc1ac68Skrishna 0x0000400000400000ULL, 0x0000400000400400ULL, 0x0080400000400280ULL, 0x0080400000400680ULL,
2324cc1ac68Skrishna 0x0000400000280000ULL, 0x0000400000280400ULL, 0x0080400000280280ULL, 0x0080400000280680ULL,
2334cc1ac68Skrishna 0x0000400000680000ULL, 0x0000400000680400ULL, 0x0080400000680280ULL, 0x0080400000680680ULL,
2344cc1ac68Skrishna 0x0000400400000000ULL, 0x0000400400000400ULL, 0x0080400400000280ULL, 0x0080400400000680ULL,
2354cc1ac68Skrishna 0x0000400400400000ULL, 0x0000400400400400ULL, 0x0080400400400280ULL, 0x0080400400400680ULL,
2364cc1ac68Skrishna 0x0000400400280000ULL, 0x0000400400280400ULL, 0x0080400400280280ULL, 0x0080400400280680ULL,
2374cc1ac68Skrishna 0x0000400400680000ULL, 0x0000400400680400ULL, 0x0080400400680280ULL, 0x0080400400680680ULL,
2384cc1ac68Skrishna 0x0000400280000000ULL, 0x0000400280000400ULL, 0x0080400280000280ULL, 0x0080400280000680ULL,
2394cc1ac68Skrishna 0x0000400280400000ULL, 0x0000400280400400ULL, 0x0080400280400280ULL, 0x0080400280400680ULL,
2404cc1ac68Skrishna 0x0000400280280000ULL, 0x0000400280280400ULL, 0x0080400280280280ULL, 0x0080400280280680ULL,
2414cc1ac68Skrishna 0x0000400280680000ULL, 0x0000400280680400ULL, 0x0080400280680280ULL, 0x0080400280680680ULL,
2424cc1ac68Skrishna 0x0000400680000000ULL, 0x0000400680000400ULL, 0x0080400680000280ULL, 0x0080400680000680ULL,
2434cc1ac68Skrishna 0x0000400680400000ULL, 0x0000400680400400ULL, 0x0080400680400280ULL, 0x0080400680400680ULL,
2444cc1ac68Skrishna 0x0000400680280000ULL, 0x0000400680280400ULL, 0x0080400680280280ULL, 0x0080400680280680ULL,
2454cc1ac68Skrishna 0x0000400680680000ULL, 0x0000400680680400ULL, 0x0080400680680280ULL, 0x0080400680680680ULL,
2464cc1ac68Skrishna 0x0000280000000000ULL, 0x0000280000000400ULL, 0x0080280000000280ULL, 0x0080280000000680ULL,
2474cc1ac68Skrishna 0x0000280000400000ULL, 0x0000280000400400ULL, 0x0080280000400280ULL, 0x0080280000400680ULL,
2484cc1ac68Skrishna 0x0000280000280000ULL, 0x0000280000280400ULL, 0x0080280000280280ULL, 0x0080280000280680ULL,
2494cc1ac68Skrishna 0x0000280000680000ULL, 0x0000280000680400ULL, 0x0080280000680280ULL, 0x0080280000680680ULL,
2504cc1ac68Skrishna 0x0000280400000000ULL, 0x0000280400000400ULL, 0x0080280400000280ULL, 0x0080280400000680ULL,
2514cc1ac68Skrishna 0x0000280400400000ULL, 0x0000280400400400ULL, 0x0080280400400280ULL, 0x0080280400400680ULL,
2524cc1ac68Skrishna 0x0000280400280000ULL, 0x0000280400280400ULL, 0x0080280400280280ULL, 0x0080280400280680ULL,
2534cc1ac68Skrishna 0x0000280400680000ULL, 0x0000280400680400ULL, 0x0080280400680280ULL, 0x0080280400680680ULL,
2544cc1ac68Skrishna 0x0000280280000000ULL, 0x0000280280000400ULL, 0x0080280280000280ULL, 0x0080280280000680ULL,
2554cc1ac68Skrishna 0x0000280280400000ULL, 0x0000280280400400ULL, 0x0080280280400280ULL, 0x0080280280400680ULL,
2564cc1ac68Skrishna 0x0000280280280000ULL, 0x0000280280280400ULL, 0x0080280280280280ULL, 0x0080280280280680ULL,
2574cc1ac68Skrishna 0x0000280280680000ULL, 0x0000280280680400ULL, 0x0080280280680280ULL, 0x0080280280680680ULL,
2584cc1ac68Skrishna 0x0000280680000000ULL, 0x0000280680000400ULL, 0x0080280680000280ULL, 0x0080280680000680ULL,
2594cc1ac68Skrishna 0x0000280680400000ULL, 0x0000280680400400ULL, 0x0080280680400280ULL, 0x0080280680400680ULL,
2604cc1ac68Skrishna 0x0000280680280000ULL, 0x0000280680280400ULL, 0x0080280680280280ULL, 0x0080280680280680ULL,
2614cc1ac68Skrishna 0x0000280680680000ULL, 0x0000280680680400ULL, 0x0080280680680280ULL, 0x0080280680680680ULL,
2624cc1ac68Skrishna 0x0000680000000000ULL, 0x0000680000000400ULL, 0x0080680000000280ULL, 0x0080680000000680ULL,
2634cc1ac68Skrishna 0x0000680000400000ULL, 0x0000680000400400ULL, 0x0080680000400280ULL, 0x0080680000400680ULL,
2644cc1ac68Skrishna 0x0000680000280000ULL, 0x0000680000280400ULL, 0x0080680000280280ULL, 0x0080680000280680ULL,
2654cc1ac68Skrishna 0x0000680000680000ULL, 0x0000680000680400ULL, 0x0080680000680280ULL, 0x0080680000680680ULL,
2664cc1ac68Skrishna 0x0000680400000000ULL, 0x0000680400000400ULL, 0x0080680400000280ULL, 0x0080680400000680ULL,
2674cc1ac68Skrishna 0x0000680400400000ULL, 0x0000680400400400ULL, 0x0080680400400280ULL, 0x0080680400400680ULL,
2684cc1ac68Skrishna 0x0000680400280000ULL, 0x0000680400280400ULL, 0x0080680400280280ULL, 0x0080680400280680ULL,
2694cc1ac68Skrishna 0x0000680400680000ULL, 0x0000680400680400ULL, 0x0080680400680280ULL, 0x0080680400680680ULL,
2704cc1ac68Skrishna 0x0000680280000000ULL, 0x0000680280000400ULL, 0x0080680280000280ULL, 0x0080680280000680ULL,
2714cc1ac68Skrishna 0x0000680280400000ULL, 0x0000680280400400ULL, 0x0080680280400280ULL, 0x0080680280400680ULL,
2724cc1ac68Skrishna 0x0000680280280000ULL, 0x0000680280280400ULL, 0x0080680280280280ULL, 0x0080680280280680ULL,
2734cc1ac68Skrishna 0x0000680280680000ULL, 0x0000680280680400ULL, 0x0080680280680280ULL, 0x0080680280680680ULL,
2744cc1ac68Skrishna 0x0000680680000000ULL, 0x0000680680000400ULL, 0x0080680680000280ULL, 0x0080680680000680ULL,
2754cc1ac68Skrishna 0x0000680680400000ULL, 0x0000680680400400ULL, 0x0080680680400280ULL, 0x0080680680400680ULL,
2764cc1ac68Skrishna 0x0000680680280000ULL, 0x0000680680280400ULL, 0x0080680680280280ULL, 0x0080680680280680ULL,
2774cc1ac68Skrishna 0x0000680680680000ULL, 0x0000680680680400ULL, 0x0080680680680280ULL, 0x0080680680680680ULL
2787c478bd9Sstevel@tonic-gate },
2797c478bd9Sstevel@tonic-gate {
2804cc1ac68Skrishna 0x0000000000000000ULL, 0x0000000000005000ULL, 0x0000000000000800ULL, 0x0000000000005800ULL,
2814cc1ac68Skrishna 0x0000000005000000ULL, 0x0000000005005000ULL, 0x0000000005000800ULL, 0x0000000005005800ULL,
2824cc1ac68Skrishna 0x0000000000800000ULL, 0x0000000000805000ULL, 0x0000000000800800ULL, 0x0000000000805800ULL,
2834cc1ac68Skrishna 0x0000000005800000ULL, 0x0000000005805000ULL, 0x0000000005800800ULL, 0x0000000005805800ULL,
2844cc1ac68Skrishna 0x0000005000000000ULL, 0x0000005000005000ULL, 0x0000005000000800ULL, 0x0000005000005800ULL,
2854cc1ac68Skrishna 0x0000005005000000ULL, 0x0000005005005000ULL, 0x0000005005000800ULL, 0x0000005005005800ULL,
2864cc1ac68Skrishna 0x0000005000800000ULL, 0x0000005000805000ULL, 0x0000005000800800ULL, 0x0000005000805800ULL,
2874cc1ac68Skrishna 0x0000005005800000ULL, 0x0000005005805000ULL, 0x0000005005800800ULL, 0x0000005005805800ULL,
2884cc1ac68Skrishna 0x0000000800000000ULL, 0x0000000800005000ULL, 0x0000000800000800ULL, 0x0000000800005800ULL,
2894cc1ac68Skrishna 0x0000000805000000ULL, 0x0000000805005000ULL, 0x0000000805000800ULL, 0x0000000805005800ULL,
2904cc1ac68Skrishna 0x0000000800800000ULL, 0x0000000800805000ULL, 0x0000000800800800ULL, 0x0000000800805800ULL,
2914cc1ac68Skrishna 0x0000000805800000ULL, 0x0000000805805000ULL, 0x0000000805800800ULL, 0x0000000805805800ULL,
2924cc1ac68Skrishna 0x0000005800000000ULL, 0x0000005800005000ULL, 0x0000005800000800ULL, 0x0000005800005800ULL,
2934cc1ac68Skrishna 0x0000005805000000ULL, 0x0000005805005000ULL, 0x0000005805000800ULL, 0x0000005805005800ULL,
2944cc1ac68Skrishna 0x0000005800800000ULL, 0x0000005800805000ULL, 0x0000005800800800ULL, 0x0000005800805800ULL,
2954cc1ac68Skrishna 0x0000005805800000ULL, 0x0000005805805000ULL, 0x0000005805800800ULL, 0x0000005805805800ULL,
2964cc1ac68Skrishna 0x0005000000000004ULL, 0x0005000000005004ULL, 0x0005000000000804ULL, 0x0005000000005804ULL,
2974cc1ac68Skrishna 0x0005000005000004ULL, 0x0005000005005004ULL, 0x0005000005000804ULL, 0x0005000005005804ULL,
2984cc1ac68Skrishna 0x0005000000800004ULL, 0x0005000000805004ULL, 0x0005000000800804ULL, 0x0005000000805804ULL,
2994cc1ac68Skrishna 0x0005000005800004ULL, 0x0005000005805004ULL, 0x0005000005800804ULL, 0x0005000005805804ULL,
3004cc1ac68Skrishna 0x0005005000000004ULL, 0x0005005000005004ULL, 0x0005005000000804ULL, 0x0005005000005804ULL,
3014cc1ac68Skrishna 0x0005005005000004ULL, 0x0005005005005004ULL, 0x0005005005000804ULL, 0x0005005005005804ULL,
3024cc1ac68Skrishna 0x0005005000800004ULL, 0x0005005000805004ULL, 0x0005005000800804ULL, 0x0005005000805804ULL,
3034cc1ac68Skrishna 0x0005005005800004ULL, 0x0005005005805004ULL, 0x0005005005800804ULL, 0x0005005005805804ULL,
3044cc1ac68Skrishna 0x0005000800000004ULL, 0x0005000800005004ULL, 0x0005000800000804ULL, 0x0005000800005804ULL,
3054cc1ac68Skrishna 0x0005000805000004ULL, 0x0005000805005004ULL, 0x0005000805000804ULL, 0x0005000805005804ULL,
3064cc1ac68Skrishna 0x0005000800800004ULL, 0x0005000800805004ULL, 0x0005000800800804ULL, 0x0005000800805804ULL,
3074cc1ac68Skrishna 0x0005000805800004ULL, 0x0005000805805004ULL, 0x0005000805800804ULL, 0x0005000805805804ULL,
3084cc1ac68Skrishna 0x0005005800000004ULL, 0x0005005800005004ULL, 0x0005005800000804ULL, 0x0005005800005804ULL,
3094cc1ac68Skrishna 0x0005005805000004ULL, 0x0005005805005004ULL, 0x0005005805000804ULL, 0x0005005805005804ULL,
3104cc1ac68Skrishna 0x0005005800800004ULL, 0x0005005800805004ULL, 0x0005005800800804ULL, 0x0005005800805804ULL,
3114cc1ac68Skrishna 0x0005005805800004ULL, 0x0005005805805004ULL, 0x0005005805800804ULL, 0x0005005805805804ULL,
3124cc1ac68Skrishna 0x0000800000000000ULL, 0x0000800000005000ULL, 0x0000800000000800ULL, 0x0000800000005800ULL,
3134cc1ac68Skrishna 0x0000800005000000ULL, 0x0000800005005000ULL, 0x0000800005000800ULL, 0x0000800005005800ULL,
3144cc1ac68Skrishna 0x0000800000800000ULL, 0x0000800000805000ULL, 0x0000800000800800ULL, 0x0000800000805800ULL,
3154cc1ac68Skrishna 0x0000800005800000ULL, 0x0000800005805000ULL, 0x0000800005800800ULL, 0x0000800005805800ULL,
3164cc1ac68Skrishna 0x0000805000000000ULL, 0x0000805000005000ULL, 0x0000805000000800ULL, 0x0000805000005800ULL,
3174cc1ac68Skrishna 0x0000805005000000ULL, 0x0000805005005000ULL, 0x0000805005000800ULL, 0x0000805005005800ULL,
3184cc1ac68Skrishna 0x0000805000800000ULL, 0x0000805000805000ULL, 0x0000805000800800ULL, 0x0000805000805800ULL,
3194cc1ac68Skrishna 0x0000805005800000ULL, 0x0000805005805000ULL, 0x0000805005800800ULL, 0x0000805005805800ULL,
3204cc1ac68Skrishna 0x0000800800000000ULL, 0x0000800800005000ULL, 0x0000800800000800ULL, 0x0000800800005800ULL,
3214cc1ac68Skrishna 0x0000800805000000ULL, 0x0000800805005000ULL, 0x0000800805000800ULL, 0x0000800805005800ULL,
3224cc1ac68Skrishna 0x0000800800800000ULL, 0x0000800800805000ULL, 0x0000800800800800ULL, 0x0000800800805800ULL,
3234cc1ac68Skrishna 0x0000800805800000ULL, 0x0000800805805000ULL, 0x0000800805800800ULL, 0x0000800805805800ULL,
3244cc1ac68Skrishna 0x0000805800000000ULL, 0x0000805800005000ULL, 0x0000805800000800ULL, 0x0000805800005800ULL,
3254cc1ac68Skrishna 0x0000805805000000ULL, 0x0000805805005000ULL, 0x0000805805000800ULL, 0x0000805805005800ULL,
3264cc1ac68Skrishna 0x0000805800800000ULL, 0x0000805800805000ULL, 0x0000805800800800ULL, 0x0000805800805800ULL,
3274cc1ac68Skrishna 0x0000805805800000ULL, 0x0000805805805000ULL, 0x0000805805800800ULL, 0x0000805805805800ULL,
3284cc1ac68Skrishna 0x0005800000000004ULL, 0x0005800000005004ULL, 0x0005800000000804ULL, 0x0005800000005804ULL,
3294cc1ac68Skrishna 0x0005800005000004ULL, 0x0005800005005004ULL, 0x0005800005000804ULL, 0x0005800005005804ULL,
3304cc1ac68Skrishna 0x0005800000800004ULL, 0x0005800000805004ULL, 0x0005800000800804ULL, 0x0005800000805804ULL,
3314cc1ac68Skrishna 0x0005800005800004ULL, 0x0005800005805004ULL, 0x0005800005800804ULL, 0x0005800005805804ULL,
3324cc1ac68Skrishna 0x0005805000000004ULL, 0x0005805000005004ULL, 0x0005805000000804ULL, 0x0005805000005804ULL,
3334cc1ac68Skrishna 0x0005805005000004ULL, 0x0005805005005004ULL, 0x0005805005000804ULL, 0x0005805005005804ULL,
3344cc1ac68Skrishna 0x0005805000800004ULL, 0x0005805000805004ULL, 0x0005805000800804ULL, 0x0005805000805804ULL,
3354cc1ac68Skrishna 0x0005805005800004ULL, 0x0005805005805004ULL, 0x0005805005800804ULL, 0x0005805005805804ULL,
3364cc1ac68Skrishna 0x0005800800000004ULL, 0x0005800800005004ULL, 0x0005800800000804ULL, 0x0005800800005804ULL,
3374cc1ac68Skrishna 0x0005800805000004ULL, 0x0005800805005004ULL, 0x0005800805000804ULL, 0x0005800805005804ULL,
3384cc1ac68Skrishna 0x0005800800800004ULL, 0x0005800800805004ULL, 0x0005800800800804ULL, 0x0005800800805804ULL,
3394cc1ac68Skrishna 0x0005800805800004ULL, 0x0005800805805004ULL, 0x0005800805800804ULL, 0x0005800805805804ULL,
3404cc1ac68Skrishna 0x0005805800000004ULL, 0x0005805800005004ULL, 0x0005805800000804ULL, 0x0005805800005804ULL,
3414cc1ac68Skrishna 0x0005805805000004ULL, 0x0005805805005004ULL, 0x0005805805000804ULL, 0x0005805805005804ULL,
3424cc1ac68Skrishna 0x0005805800800004ULL, 0x0005805800805004ULL, 0x0005805800800804ULL, 0x0005805800805804ULL,
3434cc1ac68Skrishna 0x0005805805800004ULL, 0x0005805805805004ULL, 0x0005805805800804ULL, 0x0005805805805804ULL
3447c478bd9Sstevel@tonic-gate }
3454cc1ac68Skrishna /* END CSTYLED */
3467c478bd9Sstevel@tonic-gate };
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate static const uint32_t fp_table[256]=
3497c478bd9Sstevel@tonic-gate {
3507c478bd9Sstevel@tonic-gate 0x00000000, 0x80000000, 0x00800000, 0x80800000,
3517c478bd9Sstevel@tonic-gate 0x00008000, 0x80008000, 0x00808000, 0x80808000,
3527c478bd9Sstevel@tonic-gate 0x00000080, 0x80000080, 0x00800080, 0x80800080,
3537c478bd9Sstevel@tonic-gate 0x00008080, 0x80008080, 0x00808080, 0x80808080,
3547c478bd9Sstevel@tonic-gate 0x40000000, 0xc0000000, 0x40800000, 0xc0800000,
3557c478bd9Sstevel@tonic-gate 0x40008000, 0xc0008000, 0x40808000, 0xc0808000,
3567c478bd9Sstevel@tonic-gate 0x40000080, 0xc0000080, 0x40800080, 0xc0800080,
3577c478bd9Sstevel@tonic-gate 0x40008080, 0xc0008080, 0x40808080, 0xc0808080,
3587c478bd9Sstevel@tonic-gate 0x00400000, 0x80400000, 0x00c00000, 0x80c00000,
3597c478bd9Sstevel@tonic-gate 0x00408000, 0x80408000, 0x00c08000, 0x80c08000,
3607c478bd9Sstevel@tonic-gate 0x00400080, 0x80400080, 0x00c00080, 0x80c00080,
3617c478bd9Sstevel@tonic-gate 0x00408080, 0x80408080, 0x00c08080, 0x80c08080,
3627c478bd9Sstevel@tonic-gate 0x40400000, 0xc0400000, 0x40c00000, 0xc0c00000,
3637c478bd9Sstevel@tonic-gate 0x40408000, 0xc0408000, 0x40c08000, 0xc0c08000,
3647c478bd9Sstevel@tonic-gate 0x40400080, 0xc0400080, 0x40c00080, 0xc0c00080,
3657c478bd9Sstevel@tonic-gate 0x40408080, 0xc0408080, 0x40c08080, 0xc0c08080,
3667c478bd9Sstevel@tonic-gate 0x00004000, 0x80004000, 0x00804000, 0x80804000,
3677c478bd9Sstevel@tonic-gate 0x0000c000, 0x8000c000, 0x0080c000, 0x8080c000,
3687c478bd9Sstevel@tonic-gate 0x00004080, 0x80004080, 0x00804080, 0x80804080,
3697c478bd9Sstevel@tonic-gate 0x0000c080, 0x8000c080, 0x0080c080, 0x8080c080,
3707c478bd9Sstevel@tonic-gate 0x40004000, 0xc0004000, 0x40804000, 0xc0804000,
3717c478bd9Sstevel@tonic-gate 0x4000c000, 0xc000c000, 0x4080c000, 0xc080c000,
3727c478bd9Sstevel@tonic-gate 0x40004080, 0xc0004080, 0x40804080, 0xc0804080,
3737c478bd9Sstevel@tonic-gate 0x4000c080, 0xc000c080, 0x4080c080, 0xc080c080,
3747c478bd9Sstevel@tonic-gate 0x00404000, 0x80404000, 0x00c04000, 0x80c04000,
3757c478bd9Sstevel@tonic-gate 0x0040c000, 0x8040c000, 0x00c0c000, 0x80c0c000,
3767c478bd9Sstevel@tonic-gate 0x00404080, 0x80404080, 0x00c04080, 0x80c04080,
3777c478bd9Sstevel@tonic-gate 0x0040c080, 0x8040c080, 0x00c0c080, 0x80c0c080,
3787c478bd9Sstevel@tonic-gate 0x40404000, 0xc0404000, 0x40c04000, 0xc0c04000,
3797c478bd9Sstevel@tonic-gate 0x4040c000, 0xc040c000, 0x40c0c000, 0xc0c0c000,
3807c478bd9Sstevel@tonic-gate 0x40404080, 0xc0404080, 0x40c04080, 0xc0c04080,
3817c478bd9Sstevel@tonic-gate 0x4040c080, 0xc040c080, 0x40c0c080, 0xc0c0c080,
3827c478bd9Sstevel@tonic-gate 0x00000040, 0x80000040, 0x00800040, 0x80800040,
3837c478bd9Sstevel@tonic-gate 0x00008040, 0x80008040, 0x00808040, 0x80808040,
3847c478bd9Sstevel@tonic-gate 0x000000c0, 0x800000c0, 0x008000c0, 0x808000c0,
3857c478bd9Sstevel@tonic-gate 0x000080c0, 0x800080c0, 0x008080c0, 0x808080c0,
3867c478bd9Sstevel@tonic-gate 0x40000040, 0xc0000040, 0x40800040, 0xc0800040,
3877c478bd9Sstevel@tonic-gate 0x40008040, 0xc0008040, 0x40808040, 0xc0808040,
3887c478bd9Sstevel@tonic-gate 0x400000c0, 0xc00000c0, 0x408000c0, 0xc08000c0,
3897c478bd9Sstevel@tonic-gate 0x400080c0, 0xc00080c0, 0x408080c0, 0xc08080c0,
3907c478bd9Sstevel@tonic-gate 0x00400040, 0x80400040, 0x00c00040, 0x80c00040,
3917c478bd9Sstevel@tonic-gate 0x00408040, 0x80408040, 0x00c08040, 0x80c08040,
3927c478bd9Sstevel@tonic-gate 0x004000c0, 0x804000c0, 0x00c000c0, 0x80c000c0,
3937c478bd9Sstevel@tonic-gate 0x004080c0, 0x804080c0, 0x00c080c0, 0x80c080c0,
3947c478bd9Sstevel@tonic-gate 0x40400040, 0xc0400040, 0x40c00040, 0xc0c00040,
3957c478bd9Sstevel@tonic-gate 0x40408040, 0xc0408040, 0x40c08040, 0xc0c08040,
3967c478bd9Sstevel@tonic-gate 0x404000c0, 0xc04000c0, 0x40c000c0, 0xc0c000c0,
3977c478bd9Sstevel@tonic-gate 0x404080c0, 0xc04080c0, 0x40c080c0, 0xc0c080c0,
3987c478bd9Sstevel@tonic-gate 0x00004040, 0x80004040, 0x00804040, 0x80804040,
3997c478bd9Sstevel@tonic-gate 0x0000c040, 0x8000c040, 0x0080c040, 0x8080c040,
4007c478bd9Sstevel@tonic-gate 0x000040c0, 0x800040c0, 0x008040c0, 0x808040c0,
4017c478bd9Sstevel@tonic-gate 0x0000c0c0, 0x8000c0c0, 0x0080c0c0, 0x8080c0c0,
4027c478bd9Sstevel@tonic-gate 0x40004040, 0xc0004040, 0x40804040, 0xc0804040,
4037c478bd9Sstevel@tonic-gate 0x4000c040, 0xc000c040, 0x4080c040, 0xc080c040,
4047c478bd9Sstevel@tonic-gate 0x400040c0, 0xc00040c0, 0x408040c0, 0xc08040c0,
4057c478bd9Sstevel@tonic-gate 0x4000c0c0, 0xc000c0c0, 0x4080c0c0, 0xc080c0c0,
4067c478bd9Sstevel@tonic-gate 0x00404040, 0x80404040, 0x00c04040, 0x80c04040,
4077c478bd9Sstevel@tonic-gate 0x0040c040, 0x8040c040, 0x00c0c040, 0x80c0c040,
4087c478bd9Sstevel@tonic-gate 0x004040c0, 0x804040c0, 0x00c040c0, 0x80c040c0,
4097c478bd9Sstevel@tonic-gate 0x0040c0c0, 0x8040c0c0, 0x00c0c0c0, 0x80c0c0c0,
4107c478bd9Sstevel@tonic-gate 0x40404040, 0xc0404040, 0x40c04040, 0xc0c04040,
4117c478bd9Sstevel@tonic-gate 0x4040c040, 0xc040c040, 0x40c0c040, 0xc0c0c040,
4127c478bd9Sstevel@tonic-gate 0x404040c0, 0xc04040c0, 0x40c040c0, 0xc0c040c0,
4137c478bd9Sstevel@tonic-gate 0x4040c0c0, 0xc040c0c0, 0x40c0c0c0, 0xc0c0c0c0
4147c478bd9Sstevel@tonic-gate };
4157c478bd9Sstevel@tonic-gate 
4164cc1ac68Skrishna static const uint64_t all_a = 0xaaaaaaaaaaaaaaaaULL;
4174cc1ac68Skrishna static const uint64_t all_5 = 0x5555555555555555ULL;
4184cc1ac68Skrishna static const uint64_t top_1 = 0xfc000000000000ULL;
4194cc1ac68Skrishna static const uint64_t mid_4 = 0x3fffffc000000ULL;
4204cc1ac68Skrishna static const uint64_t low_3 = 0x3ffff00ULL;
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate static void
4247c478bd9Sstevel@tonic-gate des_ip(uint64_t *l, uint64_t *r, uint64_t pt)
4257c478bd9Sstevel@tonic-gate {
4267c478bd9Sstevel@tonic-gate 	uint64_t a, b;
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 	a = pt & all_a;
4297c478bd9Sstevel@tonic-gate 	b = pt & all_5;
4307c478bd9Sstevel@tonic-gate 	a = a | (a << 7);
4317c478bd9Sstevel@tonic-gate 	b = b | (b >> 7);
4327c478bd9Sstevel@tonic-gate 
4334cc1ac68Skrishna 	b = (ip_table[0][(b >> 48) & 255ULL]) |
4344cc1ac68Skrishna 	    (ip_table[1][(b >> 32) & 255ULL]) |
4354cc1ac68Skrishna 	    (ip_table[0][(b >> 16) & 255ULL] << 6) |
4364cc1ac68Skrishna 	    (ip_table[1][b & 255ULL] << 6);
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 	a = (ip_table[0][(a >> 56) & 255]) |
4397c478bd9Sstevel@tonic-gate 	    (ip_table[1][(a >> 40) & 255]) |
4407c478bd9Sstevel@tonic-gate 	    (ip_table[0][(a >> 24) & 255] << 6) |
4417c478bd9Sstevel@tonic-gate 	    (ip_table[1][(a >> 8) & 255] << 6);
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 	*l = ((b & top_1) << 8) |
4447c478bd9Sstevel@tonic-gate 	    (b & mid_4) |
4457c478bd9Sstevel@tonic-gate 	    ((b & low_3) >> 5);
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 	*r = ((a & top_1) << 8) |
4487c478bd9Sstevel@tonic-gate 	    (a & mid_4) |
4497c478bd9Sstevel@tonic-gate 	    ((a & low_3) >> 5);
4507c478bd9Sstevel@tonic-gate }
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate static uint64_t
4547c478bd9Sstevel@tonic-gate des_fp(uint64_t l, uint64_t r)
4557c478bd9Sstevel@tonic-gate {
4567c478bd9Sstevel@tonic-gate 	uint32_t upper, lower;
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	lower = fp_table[((l >> 55) & 240) | ((r >> 59) & 15)] |
4597c478bd9Sstevel@tonic-gate 	    (fp_table[((l >> 35) & 240) | ((r>>39) & 15)] >> 2) |
4607c478bd9Sstevel@tonic-gate 	    (fp_table[((l >> 23) & 240) | ((r >> 27) & 15)] >> 4) |
4617c478bd9Sstevel@tonic-gate 	    (fp_table[((l >> 6) & 240) | ((r >> 10) & 15)] >> 6);
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 	upper = fp_table[((l >> 41) & 240) | ((r >> 45) & 15)] |
4647c478bd9Sstevel@tonic-gate 	    (fp_table[((l >> 29) & 240) | ((r >> 33) & 15)] >> 2) |
4657c478bd9Sstevel@tonic-gate 	    (fp_table[((l >> 12) & 240) | ((r >> 16) & 15)] >> 4) |
4667c478bd9Sstevel@tonic-gate 	    (fp_table[(l & 240) | (r >> 4) & 15] >> 6);
4677c478bd9Sstevel@tonic-gate 
4687c478bd9Sstevel@tonic-gate 	return ((((uint64_t)upper) << 32) | (uint64_t)lower);
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate }
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate uint64_t
4737c478bd9Sstevel@tonic-gate des_crypt_impl(uint64_t *ks, uint64_t block, int one_or_three)
4747c478bd9Sstevel@tonic-gate {
4757c478bd9Sstevel@tonic-gate 	int i, j;
4767c478bd9Sstevel@tonic-gate 	uint64_t l, r, t;
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate 	des_ip(&l, &r, block);
4797c478bd9Sstevel@tonic-gate 	for (j = 0; j < one_or_three; j++) {
4807c478bd9Sstevel@tonic-gate 		for (i = j * 16; i < (j + 1) * 16; i++) {
4817c478bd9Sstevel@tonic-gate 			t = r ^ ks[i];
4827c478bd9Sstevel@tonic-gate 			t = sbox_table[0][t >> 58] |
4837c478bd9Sstevel@tonic-gate 			    sbox_table[1][(t >> 44) & 63] |
4847c478bd9Sstevel@tonic-gate 			    sbox_table[2][(t >> 38) & 63] |
4857c478bd9Sstevel@tonic-gate 			    sbox_table[3][(t >> 32) & 63] |
4867c478bd9Sstevel@tonic-gate 			    sbox_table[4][(t >> 26) & 63] |
4877c478bd9Sstevel@tonic-gate 			    sbox_table[5][(t >> 15) & 63] |
4887c478bd9Sstevel@tonic-gate 			    sbox_table[6][(t >> 9) & 63] |
4897c478bd9Sstevel@tonic-gate 			    sbox_table[7][(t >> 3) & 63];
4907c478bd9Sstevel@tonic-gate 			t = t^l;
4917c478bd9Sstevel@tonic-gate 			l = r;
4927c478bd9Sstevel@tonic-gate 			r = t;
4937c478bd9Sstevel@tonic-gate 		}
4947c478bd9Sstevel@tonic-gate 		r = l;
4957c478bd9Sstevel@tonic-gate 		l = t;
4967c478bd9Sstevel@tonic-gate 	}
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	return (des_fp(l, r));
4997c478bd9Sstevel@tonic-gate }
5007c478bd9Sstevel@tonic-gate #endif /* !sun4u */
5017c478bd9Sstevel@tonic-gate 
50223c57df7Smcpowers int
50323c57df7Smcpowers des3_crunch_block(const void *cookie, const uint8_t block[DES_BLOCK_LEN],
5047c478bd9Sstevel@tonic-gate     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
5057c478bd9Sstevel@tonic-gate {
5067c478bd9Sstevel@tonic-gate 	keysched3_t *ksch = (keysched3_t *)cookie;
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	/*
5097c478bd9Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
5107c478bd9Sstevel@tonic-gate 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
5117c478bd9Sstevel@tonic-gate 	 * copies the block without reversing bytes.
5127c478bd9Sstevel@tonic-gate 	 */
5137c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
5147c478bd9Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
5157c478bd9Sstevel@tonic-gate 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
5167c478bd9Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5177c478bd9Sstevel@tonic-gate 			/* LINTED */
5187c478bd9Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5194b56a003SDaniel Anderson 			    ksch->ksch_decrypt, /* LINTED */
5207c478bd9Sstevel@tonic-gate 			    *(uint64_t *)block, 3);
5217c478bd9Sstevel@tonic-gate 		else
5227c478bd9Sstevel@tonic-gate 			/* LINTED */
5237c478bd9Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5244b56a003SDaniel Anderson 			    ksch->ksch_encrypt, /* LINTED */
5257c478bd9Sstevel@tonic-gate 			    *(uint64_t *)block, 3);
5264b56a003SDaniel Anderson 	} else
5274b56a003SDaniel Anderson #endif	/* _BIG_ENDIAN */
5284b56a003SDaniel Anderson 	{
5297c478bd9Sstevel@tonic-gate 		uint64_t tmp;
5307c478bd9Sstevel@tonic-gate 
5314b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
53225cc6a40SDaniel Anderson 		tmp = htonll(*(uint64_t *)(void *)&block[0]);
5334b56a003SDaniel Anderson #else
5347c478bd9Sstevel@tonic-gate 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
5357c478bd9Sstevel@tonic-gate 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
5367c478bd9Sstevel@tonic-gate 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
5377c478bd9Sstevel@tonic-gate 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
5384b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5417c478bd9Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 3);
5427c478bd9Sstevel@tonic-gate 		else
5437c478bd9Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 3);
5447c478bd9Sstevel@tonic-gate 
5454b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
54625cc6a40SDaniel Anderson 		*(uint64_t *)(void *)&out_block[0] = htonll(tmp);
5474b56a003SDaniel Anderson #else
5487c478bd9Sstevel@tonic-gate 		out_block[0] = tmp >> 56;
5497c478bd9Sstevel@tonic-gate 		out_block[1] = tmp >> 48;
5507c478bd9Sstevel@tonic-gate 		out_block[2] = tmp >> 40;
5517c478bd9Sstevel@tonic-gate 		out_block[3] = tmp >> 32;
5527c478bd9Sstevel@tonic-gate 		out_block[4] = tmp >> 24;
5537c478bd9Sstevel@tonic-gate 		out_block[5] = tmp >> 16;
5547c478bd9Sstevel@tonic-gate 		out_block[6] = tmp >> 8;
5557c478bd9Sstevel@tonic-gate 		out_block[7] = (uint8_t)tmp;
5564b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
5577c478bd9Sstevel@tonic-gate 	}
55823c57df7Smcpowers 	return (CRYPTO_SUCCESS);
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate 
56123c57df7Smcpowers int
56223c57df7Smcpowers des_crunch_block(const void *cookie, const uint8_t block[DES_BLOCK_LEN],
5637c478bd9Sstevel@tonic-gate     uint8_t out_block[DES_BLOCK_LEN], boolean_t decrypt)
5647c478bd9Sstevel@tonic-gate {
5657c478bd9Sstevel@tonic-gate 	keysched_t *ksch = (keysched_t *)cookie;
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 	/*
5687c478bd9Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
5697c478bd9Sstevel@tonic-gate 	 * reverses bytes in the block.  On BIG_ENDIAN, the same code
5707c478bd9Sstevel@tonic-gate 	 * copies the block without reversing bytes.
5717c478bd9Sstevel@tonic-gate 	 */
5727c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
5737c478bd9Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint64_t)) &&
5747c478bd9Sstevel@tonic-gate 	    IS_P2ALIGNED(out_block, sizeof (uint64_t))) {
5757c478bd9Sstevel@tonic-gate 		if (decrypt == B_TRUE)
5767c478bd9Sstevel@tonic-gate 			/* LINTED */
5777c478bd9Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5784b56a003SDaniel Anderson 			    ksch->ksch_decrypt, /* LINTED */
5797c478bd9Sstevel@tonic-gate 			    *(uint64_t *)block, 1);
5807c478bd9Sstevel@tonic-gate 		else
5817c478bd9Sstevel@tonic-gate 			/* LINTED */
5827c478bd9Sstevel@tonic-gate 			*(uint64_t *)out_block = des_crypt_impl(
5834b56a003SDaniel Anderson 			    ksch->ksch_encrypt, /* LINTED */
5847c478bd9Sstevel@tonic-gate 			    *(uint64_t *)block, 1);
5857c478bd9Sstevel@tonic-gate 
5864b56a003SDaniel Anderson 	} else
5874b56a003SDaniel Anderson #endif	/* _BIG_ENDIAN */
5884b56a003SDaniel Anderson 	{
5897c478bd9Sstevel@tonic-gate 		uint64_t tmp;
5907c478bd9Sstevel@tonic-gate 
5914b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
59225cc6a40SDaniel Anderson 		tmp = htonll(*(uint64_t *)(void *)&block[0]);
5934b56a003SDaniel Anderson #else
5947c478bd9Sstevel@tonic-gate 		tmp = (((uint64_t)block[0] << 56) | ((uint64_t)block[1] << 48) |
5957c478bd9Sstevel@tonic-gate 		    ((uint64_t)block[2] << 40) | ((uint64_t)block[3] << 32) |
5967c478bd9Sstevel@tonic-gate 		    ((uint64_t)block[4] << 24) | ((uint64_t)block[5] << 16) |
5977c478bd9Sstevel@tonic-gate 		    ((uint64_t)block[6] << 8) | (uint64_t)block[7]);
5984b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
5994b56a003SDaniel Anderson 
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 		if (decrypt == B_TRUE)
6027c478bd9Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_decrypt, tmp, 1);
6037c478bd9Sstevel@tonic-gate 		else
6047c478bd9Sstevel@tonic-gate 			tmp = des_crypt_impl(ksch->ksch_encrypt, tmp, 1);
6057c478bd9Sstevel@tonic-gate 
6064b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
60725cc6a40SDaniel Anderson 		*(uint64_t *)(void *)&out_block[0] = htonll(tmp);
6084b56a003SDaniel Anderson #else
6097c478bd9Sstevel@tonic-gate 		out_block[0] = tmp >> 56;
6107c478bd9Sstevel@tonic-gate 		out_block[1] = tmp >> 48;
6117c478bd9Sstevel@tonic-gate 		out_block[2] = tmp >> 40;
6127c478bd9Sstevel@tonic-gate 		out_block[3] = tmp >> 32;
6137c478bd9Sstevel@tonic-gate 		out_block[4] = tmp >> 24;
6147c478bd9Sstevel@tonic-gate 		out_block[5] = tmp >> 16;
6157c478bd9Sstevel@tonic-gate 		out_block[6] = tmp >> 8;
6167c478bd9Sstevel@tonic-gate 		out_block[7] = (uint8_t)tmp;
6174b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
6187c478bd9Sstevel@tonic-gate 	}
61923c57df7Smcpowers 	return (CRYPTO_SUCCESS);
6207c478bd9Sstevel@tonic-gate }
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate static boolean_t
6237c478bd9Sstevel@tonic-gate keycheck(uint8_t *key, uint8_t *corrected_key)
6247c478bd9Sstevel@tonic-gate {
6257c478bd9Sstevel@tonic-gate 	uint64_t key_so_far;
6267c478bd9Sstevel@tonic-gate 	uint_t i;
6277c478bd9Sstevel@tonic-gate 	/*
6287c478bd9Sstevel@tonic-gate 	 * Table of weak and semi-weak keys.  Fortunately, weak keys are
6297c478bd9Sstevel@tonic-gate 	 * endian-independent, and some semi-weak keys can be paired up in
6307c478bd9Sstevel@tonic-gate 	 * endian-opposite order.  Since keys are stored as uint64_t's,
6317c478bd9Sstevel@tonic-gate 	 * use the ifdef _LITTLE_ENDIAN where appropriate.
6327c478bd9Sstevel@tonic-gate 	 */
6337c478bd9Sstevel@tonic-gate 	static uint64_t des_weak_keys[] = {
6347c478bd9Sstevel@tonic-gate 		/* Really weak keys.  Byte-order independent values. */
6354cc1ac68Skrishna 		0x0101010101010101ULL,
6364cc1ac68Skrishna 		0x1f1f1f1f0e0e0e0eULL,
6374cc1ac68Skrishna 		0xe0e0e0e0f1f1f1f1ULL,
6384cc1ac68Skrishna 		0xfefefefefefefefeULL,
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 		/* Semi-weak (and a few possibly-weak) keys. */
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate 		/* Byte-order independent semi-weak keys. */
6434cc1ac68Skrishna 		0x01fe01fe01fe01feULL,	0xfe01fe01fe01fe01ULL,
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate 		/* Byte-order dependent semi-weak keys. */
6467c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
6474cc1ac68Skrishna 		0xf10ef10ee01fe01fULL,	0x0ef10ef11fe01fe0ULL,
6484cc1ac68Skrishna 		0x01f101f101e001e0ULL,	0xf101f101e001e001ULL,
6494cc1ac68Skrishna 		0x0efe0efe1ffe1ffeULL,	0xfe0efe0efe1ffe1fULL,
6504cc1ac68Skrishna 		0x010e010e011f011fULL,	0x0e010e011f011f01ULL,
6514cc1ac68Skrishna 		0xf1fef1fee0fee0feULL,	0xfef1fef1fee0fee0ULL,
6527c478bd9Sstevel@tonic-gate #else	/* Big endian */
6534cc1ac68Skrishna 		0x1fe01fe00ef10ef1ULL,	0xe01fe01ff10ef10eULL,
6544cc1ac68Skrishna 		0x01e001e001f101f1ULL,	0xe001e001f101f101ULL,
6554cc1ac68Skrishna 		0x1ffe1ffe0efe0efeULL,	0xfe1ffe1ffe0efe0eULL,
6564cc1ac68Skrishna 		0x011f011f010e010eULL,	0x1f011f010e010e01ULL,
6574cc1ac68Skrishna 		0xe0fee0fef1fef1feULL,	0xfee0fee0fef1fef1ULL,
6584b56a003SDaniel Anderson #endif	/* _LITTLE_ENDIAN */
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 		/* We'll save the other possibly-weak keys for the future. */
6617c478bd9Sstevel@tonic-gate 	};
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	if (key == NULL)
6647c478bd9Sstevel@tonic-gate 		return (B_FALSE);
6657c478bd9Sstevel@tonic-gate 
6664b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
66725cc6a40SDaniel Anderson 	key_so_far = htonll(*(uint64_t *)(void *)&key[0]);
6684b56a003SDaniel Anderson #else
6697c478bd9Sstevel@tonic-gate 	/*
6707c478bd9Sstevel@tonic-gate 	 * The code below reverses the bytes on LITTLE_ENDIAN machines.
6717c478bd9Sstevel@tonic-gate 	 * On BIG_ENDIAN, the same code copies without reversing
6727c478bd9Sstevel@tonic-gate 	 * the bytes.
6737c478bd9Sstevel@tonic-gate 	 */
6747c478bd9Sstevel@tonic-gate 	key_so_far = (((uint64_t)key[0] << 56) | ((uint64_t)key[1] << 48) |
6757c478bd9Sstevel@tonic-gate 	    ((uint64_t)key[2] << 40) | ((uint64_t)key[3] << 32) |
6767c478bd9Sstevel@tonic-gate 	    ((uint64_t)key[4] << 24) | ((uint64_t)key[5] << 16) |
6777c478bd9Sstevel@tonic-gate 	    ((uint64_t)key[6] << 8) | (uint64_t)key[7]);
6784b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
6797c478bd9Sstevel@tonic-gate 
6807c478bd9Sstevel@tonic-gate 	/*
6817c478bd9Sstevel@tonic-gate 	 * Fix parity.
6827c478bd9Sstevel@tonic-gate 	 */
6837c478bd9Sstevel@tonic-gate 	fix_des_parity(&key_so_far);
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate 	/* Do weak key check itself. */
6867c478bd9Sstevel@tonic-gate 	for (i = 0; i < (sizeof (des_weak_keys) / sizeof (uint64_t)); i++)
6877c478bd9Sstevel@tonic-gate 		if (key_so_far == des_weak_keys[i]) {
6887c478bd9Sstevel@tonic-gate 			return (B_FALSE);
6897c478bd9Sstevel@tonic-gate 		}
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate 	if (corrected_key != NULL) {
6924b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
69325cc6a40SDaniel Anderson 		*(uint64_t *)(void *)&corrected_key[0] = htonll(key_so_far);
6944b56a003SDaniel Anderson #else
6957c478bd9Sstevel@tonic-gate 		/*
6967c478bd9Sstevel@tonic-gate 		 * The code below reverses the bytes on LITTLE_ENDIAN machines.
6977c478bd9Sstevel@tonic-gate 		 * On BIG_ENDIAN, the same code copies without reversing
6987c478bd9Sstevel@tonic-gate 		 * the bytes.
6997c478bd9Sstevel@tonic-gate 		 */
7007c478bd9Sstevel@tonic-gate 		corrected_key[0] = key_so_far >> 56;
7017c478bd9Sstevel@tonic-gate 		corrected_key[1] = key_so_far >> 48;
7027c478bd9Sstevel@tonic-gate 		corrected_key[2] = key_so_far >> 40;
7037c478bd9Sstevel@tonic-gate 		corrected_key[3] = key_so_far >> 32;
7047c478bd9Sstevel@tonic-gate 		corrected_key[4] = key_so_far >> 24;
7057c478bd9Sstevel@tonic-gate 		corrected_key[5] = key_so_far >> 16;
7067c478bd9Sstevel@tonic-gate 		corrected_key[6] = key_so_far >> 8;
7077c478bd9Sstevel@tonic-gate 		corrected_key[7] = (uint8_t)key_so_far;
7084b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
7097c478bd9Sstevel@tonic-gate 	}
7107c478bd9Sstevel@tonic-gate 	return (B_TRUE);
7117c478bd9Sstevel@tonic-gate }
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate static boolean_t
714*436935a1SVladimir Kotal des23_keycheck(uint8_t *key, uint8_t *corrected_key, boolean_t des3)
7157c478bd9Sstevel@tonic-gate {
7167c478bd9Sstevel@tonic-gate 	uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
7177c478bd9Sstevel@tonic-gate 	uint64_t key_so_far, scratch, *currentkey;
7187c478bd9Sstevel@tonic-gate 	uint_t j, num_weakkeys = 0;
719*436935a1SVladimir Kotal 	uint8_t keysize = DES3_KEYSIZE;
720*436935a1SVladimir Kotal 	uint8_t checks = 3;
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate 	if (key == NULL) {
7237c478bd9Sstevel@tonic-gate 		return (B_FALSE);
7247c478bd9Sstevel@tonic-gate 	}
7257c478bd9Sstevel@tonic-gate 
726*436935a1SVladimir Kotal 	if (des3 == B_FALSE) {
727*436935a1SVladimir Kotal 		keysize = DES2_KEYSIZE;
728*436935a1SVladimir Kotal 		checks = 2;
729*436935a1SVladimir Kotal 	}
730*436935a1SVladimir Kotal 
7317c478bd9Sstevel@tonic-gate 	if (!IS_P2ALIGNED(key, sizeof (uint64_t))) {
732*436935a1SVladimir Kotal 		bcopy(key, aligned_key, keysize);
7337c478bd9Sstevel@tonic-gate 		currentkey = (uint64_t *)aligned_key;
7347c478bd9Sstevel@tonic-gate 	} else {
7357c478bd9Sstevel@tonic-gate 		/* LINTED */
7367c478bd9Sstevel@tonic-gate 		currentkey = (uint64_t *)key;
7377c478bd9Sstevel@tonic-gate 	}
7387c478bd9Sstevel@tonic-gate 
739*436935a1SVladimir Kotal 	for (j = 0; j < checks; j++) {
7407c478bd9Sstevel@tonic-gate 		key_so_far = currentkey[j];
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 		if (!keycheck((uint8_t *)&key_so_far, (uint8_t *)&scratch)) {
7437c478bd9Sstevel@tonic-gate 			if (++num_weakkeys > 1) {
7447c478bd9Sstevel@tonic-gate 				return (B_FALSE);
7457c478bd9Sstevel@tonic-gate 			}
7467c478bd9Sstevel@tonic-gate 			/*
7477c478bd9Sstevel@tonic-gate 			 * We found a weak key, but since
7487c478bd9Sstevel@tonic-gate 			 * we've only found one weak key,
7497c478bd9Sstevel@tonic-gate 			 * we can not reject the whole 3DES
7507c478bd9Sstevel@tonic-gate 			 * set of keys as weak.
7517c478bd9Sstevel@tonic-gate 			 *
7527c478bd9Sstevel@tonic-gate 			 * Break from the weak key loop
7537c478bd9Sstevel@tonic-gate 			 * (since this DES key is weak) and
7547c478bd9Sstevel@tonic-gate 			 * continue on.
7557c478bd9Sstevel@tonic-gate 			 */
7567c478bd9Sstevel@tonic-gate 		}
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate 		currentkey[j] = scratch;
7597c478bd9Sstevel@tonic-gate 	}
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate 	/*
7627c478bd9Sstevel@tonic-gate 	 * Perform key equivalence checks, now that parity is properly set.
76358d17812Smarkfen 	 * 1st and 2nd keys must be unique, the 3rd key can be the same as
7644b56a003SDaniel Anderson 	 * the 1st key for the 2 key variant of 3DES.
7657c478bd9Sstevel@tonic-gate 	 */
76658d17812Smarkfen 	if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2])
7677c478bd9Sstevel@tonic-gate 		return (B_FALSE);
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate 	if (corrected_key != NULL) {
770*436935a1SVladimir Kotal 		bcopy(currentkey, corrected_key, keysize);
7717c478bd9Sstevel@tonic-gate 	}
772690caf98Sizick 
7737c478bd9Sstevel@tonic-gate 	return (B_TRUE);
7747c478bd9Sstevel@tonic-gate }
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate boolean_t
7777c478bd9Sstevel@tonic-gate des_keycheck(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
7787c478bd9Sstevel@tonic-gate {
7797c478bd9Sstevel@tonic-gate 	if (strength == DES) {
7807c478bd9Sstevel@tonic-gate 		return (keycheck(key, corrected_key));
781*436935a1SVladimir Kotal 	} else if (strength == DES2) {
782*436935a1SVladimir Kotal 		return (des23_keycheck(key, corrected_key, B_FALSE));
7837c478bd9Sstevel@tonic-gate 	} else if (strength == DES3) {
784*436935a1SVladimir Kotal 		return (des23_keycheck(key, corrected_key, B_TRUE));
7857c478bd9Sstevel@tonic-gate 	} else {
7867c478bd9Sstevel@tonic-gate 		return (B_FALSE);
7877c478bd9Sstevel@tonic-gate 	}
7887c478bd9Sstevel@tonic-gate }
7897c478bd9Sstevel@tonic-gate 
790690caf98Sizick void
791690caf98Sizick des_parity_fix(uint8_t *key, des_strength_t strength, uint8_t *corrected_key)
792690caf98Sizick {
793690caf98Sizick 	uint64_t aligned_key[DES3_KEYSIZE / sizeof (uint64_t)];
794690caf98Sizick 	uint8_t *paritied_key;
795690caf98Sizick 	uint64_t key_so_far;
796690caf98Sizick 	int i = 0, offset = 0;
797690caf98Sizick 
798690caf98Sizick 	if (strength == DES)
799690caf98Sizick 		bcopy(key, aligned_key, DES_KEYSIZE);
800690caf98Sizick 	else
801690caf98Sizick 		bcopy(key, aligned_key, DES3_KEYSIZE);
802690caf98Sizick 
803690caf98Sizick 	paritied_key = (uint8_t *)aligned_key;
804690caf98Sizick 	while (strength > i) {
805690caf98Sizick 		offset = 8 * i;
8064b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
80725cc6a40SDaniel Anderson 		key_so_far = htonll(*(uint64_t *)(void *)&paritied_key[offset]);
8084b56a003SDaniel Anderson #else
809690caf98Sizick 		key_so_far = (((uint64_t)paritied_key[offset + 0] << 56) |
810690caf98Sizick 		    ((uint64_t)paritied_key[offset + 1] << 48) |
811690caf98Sizick 		    ((uint64_t)paritied_key[offset + 2] << 40) |
812690caf98Sizick 		    ((uint64_t)paritied_key[offset + 3] << 32) |
813690caf98Sizick 		    ((uint64_t)paritied_key[offset + 4] << 24) |
814690caf98Sizick 		    ((uint64_t)paritied_key[offset + 5] << 16) |
815690caf98Sizick 		    ((uint64_t)paritied_key[offset + 6] << 8) |
816690caf98Sizick 		    (uint64_t)paritied_key[offset + 7]);
8174b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
818690caf98Sizick 
819690caf98Sizick 		fix_des_parity(&key_so_far);
820690caf98Sizick 
8214b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
82225cc6a40SDaniel Anderson 		*(uint64_t *)(void *)&paritied_key[offset] = htonll(key_so_far);
8234b56a003SDaniel Anderson #else
824690caf98Sizick 		paritied_key[offset + 0] = key_so_far >> 56;
825690caf98Sizick 		paritied_key[offset + 1] = key_so_far >> 48;
826690caf98Sizick 		paritied_key[offset + 2] = key_so_far >> 40;
827690caf98Sizick 		paritied_key[offset + 3] = key_so_far >> 32;
828690caf98Sizick 		paritied_key[offset + 4] = key_so_far >> 24;
829690caf98Sizick 		paritied_key[offset + 5] = key_so_far >> 16;
830690caf98Sizick 		paritied_key[offset + 6] = key_so_far >> 8;
831690caf98Sizick 		paritied_key[offset + 7] = (uint8_t)key_so_far;
8324b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
833690caf98Sizick 
834690caf98Sizick 		i++;
835690caf98Sizick 	}
836690caf98Sizick 
837690caf98Sizick 	bcopy(paritied_key, corrected_key, DES_KEYSIZE * strength);
838690caf98Sizick }
839690caf98Sizick 
840690caf98Sizick 
8417c478bd9Sstevel@tonic-gate /*
8427c478bd9Sstevel@tonic-gate  * Initialize key schedule for DES, DES2, and DES3
8437c478bd9Sstevel@tonic-gate  */
8447c478bd9Sstevel@tonic-gate void
8457c478bd9Sstevel@tonic-gate des_init_keysched(uint8_t *cipherKey, des_strength_t strength, void *ks)
8467c478bd9Sstevel@tonic-gate {
8477c478bd9Sstevel@tonic-gate 	uint64_t *encryption_ks;
8487c478bd9Sstevel@tonic-gate 	uint64_t *decryption_ks;
8497c478bd9Sstevel@tonic-gate 	uint64_t keysched[48];
8507c478bd9Sstevel@tonic-gate 	uint64_t key_uint64[3];
8517c478bd9Sstevel@tonic-gate 	uint64_t tmp;
8527c478bd9Sstevel@tonic-gate 	uint_t keysize, i, j;
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 	switch (strength) {
8557c478bd9Sstevel@tonic-gate 	case DES:
8567c478bd9Sstevel@tonic-gate 		keysize = DES_KEYSIZE;
8577c478bd9Sstevel@tonic-gate 		encryption_ks = ((keysched_t *)ks)->ksch_encrypt;
8587c478bd9Sstevel@tonic-gate 		decryption_ks = ((keysched_t *)ks)->ksch_decrypt;
8597c478bd9Sstevel@tonic-gate 		break;
8607c478bd9Sstevel@tonic-gate 	case DES2:
8617c478bd9Sstevel@tonic-gate 		keysize = DES2_KEYSIZE;
8627c478bd9Sstevel@tonic-gate 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
8637c478bd9Sstevel@tonic-gate 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
8647c478bd9Sstevel@tonic-gate 		break;
8657c478bd9Sstevel@tonic-gate 	case DES3:
8667c478bd9Sstevel@tonic-gate 		keysize = DES3_KEYSIZE;
8677c478bd9Sstevel@tonic-gate 		encryption_ks = ((keysched3_t *)ks)->ksch_encrypt;
8687c478bd9Sstevel@tonic-gate 		decryption_ks = ((keysched3_t *)ks)->ksch_decrypt;
8697c478bd9Sstevel@tonic-gate 	}
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 	/*
8727c478bd9Sstevel@tonic-gate 	 * The code below, that is always executed on LITTLE_ENDIAN machines,
8737c478bd9Sstevel@tonic-gate 	 * reverses every 8 bytes in the key.  On BIG_ENDIAN, the same code
8747c478bd9Sstevel@tonic-gate 	 * copies the key without reversing bytes.
8757c478bd9Sstevel@tonic-gate 	 */
8767c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
8777c478bd9Sstevel@tonic-gate 	if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) {
8787c478bd9Sstevel@tonic-gate 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
8797c478bd9Sstevel@tonic-gate 			/* LINTED: pointer alignment */
8807c478bd9Sstevel@tonic-gate 			key_uint64[i] = *((uint64_t *)&cipherKey[j]);
8817c478bd9Sstevel@tonic-gate 		}
8824b56a003SDaniel Anderson 	} else
8834b56a003SDaniel Anderson #endif	/* _BIG_ENDIAN */
8847c478bd9Sstevel@tonic-gate 	{
8857c478bd9Sstevel@tonic-gate 		for (i = 0, j = 0; j < keysize; i++, j += 8) {
8864b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
88725cc6a40SDaniel Anderson 			key_uint64[i] =
88825cc6a40SDaniel Anderson 			    htonll(*(uint64_t *)(void *)&cipherKey[j]);
8894b56a003SDaniel Anderson #else
8907c478bd9Sstevel@tonic-gate 			key_uint64[i] = (((uint64_t)cipherKey[j] << 56) |
8917c478bd9Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 1] << 48) |
8927c478bd9Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 2] << 40) |
8937c478bd9Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 3] << 32) |
8947c478bd9Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 4] << 24) |
8957c478bd9Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 5] << 16) |
8967c478bd9Sstevel@tonic-gate 			    ((uint64_t)cipherKey[j + 6] << 8) |
8977c478bd9Sstevel@tonic-gate 			    (uint64_t)cipherKey[j + 7]);
8984b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
8997c478bd9Sstevel@tonic-gate 		}
9007c478bd9Sstevel@tonic-gate 	}
9017c478bd9Sstevel@tonic-gate 
9027c478bd9Sstevel@tonic-gate 	switch (strength) {
9037c478bd9Sstevel@tonic-gate 	case DES:
9047c478bd9Sstevel@tonic-gate 		des_ks(keysched, key_uint64[0]);
9057c478bd9Sstevel@tonic-gate 		break;
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate 	case DES2:
9087c478bd9Sstevel@tonic-gate 		/* DES2 is just DES3 with the first and third keys the same */
9097c478bd9Sstevel@tonic-gate 		bcopy(key_uint64, key_uint64 + 2, DES_KEYSIZE);
9107c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
9117c478bd9Sstevel@tonic-gate 	case DES3:
9127c478bd9Sstevel@tonic-gate 		des_ks(keysched, key_uint64[0]);
9137c478bd9Sstevel@tonic-gate 		des_ks(keysched + 16, key_uint64[1]);
9147c478bd9Sstevel@tonic-gate 		for (i = 0; i < 8; i++) {
9157c478bd9Sstevel@tonic-gate 			tmp = keysched[16+i];
9167c478bd9Sstevel@tonic-gate 			keysched[16+i] = keysched[31-i];
9177c478bd9Sstevel@tonic-gate 			keysched[31-i] = tmp;
9187c478bd9Sstevel@tonic-gate 		}
9197c478bd9Sstevel@tonic-gate 		des_ks(keysched+32, key_uint64[2]);
9207c478bd9Sstevel@tonic-gate 		keysize = DES3_KEYSIZE;
9217c478bd9Sstevel@tonic-gate 	}
9227c478bd9Sstevel@tonic-gate 
9237c478bd9Sstevel@tonic-gate 	/* save the encryption keyschedule */
9247c478bd9Sstevel@tonic-gate 	bcopy(keysched, encryption_ks, keysize * 16);
9257c478bd9Sstevel@tonic-gate 
9267c478bd9Sstevel@tonic-gate 	/* reverse the key schedule */
9277c478bd9Sstevel@tonic-gate 	for (i = 0; i < keysize; i++) {
9287c478bd9Sstevel@tonic-gate 		tmp = keysched[i];
9297c478bd9Sstevel@tonic-gate 		keysched[i] = keysched[2 * keysize - 1 - i];
9307c478bd9Sstevel@tonic-gate 		keysched[2 * keysize -1 -i] = tmp;
9317c478bd9Sstevel@tonic-gate 	}
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate 	/* save the decryption keyschedule */
9347c478bd9Sstevel@tonic-gate 	bcopy(keysched, decryption_ks, keysize * 16);
9357c478bd9Sstevel@tonic-gate }
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate /*
9387c478bd9Sstevel@tonic-gate  * Allocate key schedule.
9397c478bd9Sstevel@tonic-gate  */
9407c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9417c478bd9Sstevel@tonic-gate void *
9427c478bd9Sstevel@tonic-gate des_alloc_keysched(size_t *keysched_size, des_strength_t strength, int kmflag)
9437c478bd9Sstevel@tonic-gate {
9447c478bd9Sstevel@tonic-gate 	void *keysched;
9457c478bd9Sstevel@tonic-gate 
9467c478bd9Sstevel@tonic-gate 	size_t size;
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate 	switch (strength) {
9497c478bd9Sstevel@tonic-gate 	case DES:
9507c478bd9Sstevel@tonic-gate 		size = sizeof (keysched_t);
9517c478bd9Sstevel@tonic-gate 		break;
9527c478bd9Sstevel@tonic-gate 	case DES2:
9537c478bd9Sstevel@tonic-gate 	case DES3:
9547c478bd9Sstevel@tonic-gate 		size = sizeof (keysched3_t);
9557c478bd9Sstevel@tonic-gate 	}
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate #ifdef	_KERNEL
9587c478bd9Sstevel@tonic-gate 	keysched = (keysched_t *)kmem_alloc(size, kmflag);
9597c478bd9Sstevel@tonic-gate #else	/* !_KERNEL */
9607c478bd9Sstevel@tonic-gate 	keysched = (keysched_t *)malloc(size);
9617c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate 	if (keysched == NULL)
9647c478bd9Sstevel@tonic-gate 		return (NULL);
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate 	if (keysched_size != NULL)
9677c478bd9Sstevel@tonic-gate 		*keysched_size = size;
9687c478bd9Sstevel@tonic-gate 
9697c478bd9Sstevel@tonic-gate 	return (keysched);
9707c478bd9Sstevel@tonic-gate }
9717c478bd9Sstevel@tonic-gate 
9727c478bd9Sstevel@tonic-gate /*
9737c478bd9Sstevel@tonic-gate  * Replace the LSB of each byte by the xor of the other
9747c478bd9Sstevel@tonic-gate  * 7 bits.  The tricky thing is that the original contents of the LSBs
9754b56a003SDaniel Anderson  * are nullified by including them twice in the xor computation.
9767c478bd9Sstevel@tonic-gate  */
9777c478bd9Sstevel@tonic-gate static void
9787c478bd9Sstevel@tonic-gate fix_des_parity(uint64_t *keyp)
9797c478bd9Sstevel@tonic-gate {
9807c478bd9Sstevel@tonic-gate 	uint64_t k = *keyp;
9817c478bd9Sstevel@tonic-gate 	k ^= k >> 1;
9827c478bd9Sstevel@tonic-gate 	k ^= k >> 2;
9837c478bd9Sstevel@tonic-gate 	k ^= k >> 4;
9844cc1ac68Skrishna 	*keyp ^= (k & 0x0101010101010101ULL);
985690caf98Sizick 	*keyp ^= 0x0101010101010101ULL;
9867c478bd9Sstevel@tonic-gate }
98723c57df7Smcpowers 
98823c57df7Smcpowers void
98923c57df7Smcpowers des_copy_block(uint8_t *in, uint8_t *out)
99023c57df7Smcpowers {
99123c57df7Smcpowers 	if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
99223c57df7Smcpowers 	    IS_P2ALIGNED(out, sizeof (uint32_t))) {
99323c57df7Smcpowers 		/* LINTED: pointer alignment */
99423c57df7Smcpowers 		*(uint32_t *)&out[0] = *(uint32_t *)&in[0];
99523c57df7Smcpowers 		/* LINTED: pointer alignment */
99623c57df7Smcpowers 		*(uint32_t *)&out[4] = *(uint32_t *)&in[4];
99723c57df7Smcpowers 	} else {
99823c57df7Smcpowers 		DES_COPY_BLOCK(in, out);
99923c57df7Smcpowers 	}
100023c57df7Smcpowers }
100123c57df7Smcpowers 
100223c57df7Smcpowers /* XOR block of data into dest */
100323c57df7Smcpowers void
100423c57df7Smcpowers des_xor_block(uint8_t *data, uint8_t *dst)
100523c57df7Smcpowers {
100623c57df7Smcpowers 	if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
100723c57df7Smcpowers 	    IS_P2ALIGNED(data, sizeof (uint32_t))) {
100823c57df7Smcpowers 		/* LINTED: pointer alignment */
100923c57df7Smcpowers 		*(uint32_t *)&dst[0] ^=
101023c57df7Smcpowers 		    /* LINTED: pointer alignment */
101123c57df7Smcpowers 		    *(uint32_t *)&data[0];
101223c57df7Smcpowers 		    /* LINTED: pointer alignment */
101323c57df7Smcpowers 		*(uint32_t *)&dst[4] ^=
101423c57df7Smcpowers 		    /* LINTED: pointer alignment */
101523c57df7Smcpowers 		    *(uint32_t *)&data[4];
101623c57df7Smcpowers 	} else {
101723c57df7Smcpowers 		DES_XOR_BLOCK(data, dst);
101823c57df7Smcpowers 	}
101923c57df7Smcpowers }
102023c57df7Smcpowers 
102123c57df7Smcpowers int
102223c57df7Smcpowers des_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
102323c57df7Smcpowers {
102423c57df7Smcpowers 	return (des_crunch_block(keysched, in, out, B_FALSE));
102523c57df7Smcpowers }
102623c57df7Smcpowers 
102723c57df7Smcpowers int
102823c57df7Smcpowers des3_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
102923c57df7Smcpowers {
103023c57df7Smcpowers 	return (des3_crunch_block(keysched, in, out, B_FALSE));
103123c57df7Smcpowers }
103223c57df7Smcpowers 
103323c57df7Smcpowers int
103423c57df7Smcpowers des_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
103523c57df7Smcpowers {
103623c57df7Smcpowers 	return (des_crunch_block(keysched, in, out, B_TRUE));
103723c57df7Smcpowers }
103823c57df7Smcpowers 
103923c57df7Smcpowers int
104023c57df7Smcpowers des3_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
104123c57df7Smcpowers {
104223c57df7Smcpowers 	return (des3_crunch_block(keysched, in, out, B_TRUE));
104323c57df7Smcpowers }
104423c57df7Smcpowers 
104523c57df7Smcpowers /*
104623c57df7Smcpowers  * Encrypt multiple blocks of data according to mode.
104723c57df7Smcpowers  */
104823c57df7Smcpowers int
104923c57df7Smcpowers des_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
105023c57df7Smcpowers     crypto_data_t *out)
105123c57df7Smcpowers {
105223c57df7Smcpowers 	des_ctx_t *des_ctx = ctx;
105323c57df7Smcpowers 	int rv;
105423c57df7Smcpowers 
105523c57df7Smcpowers 	if (des_ctx->dc_flags & DES3_STRENGTH) {
105623c57df7Smcpowers 		if (des_ctx->dc_flags & CBC_MODE) {
105723c57df7Smcpowers 			rv = cbc_encrypt_contiguous_blocks(ctx, data,
105823c57df7Smcpowers 			    length, out, DES_BLOCK_LEN, des3_encrypt_block,
105923c57df7Smcpowers 			    des_copy_block, des_xor_block);
106023c57df7Smcpowers 		} else {
106123c57df7Smcpowers 			rv = ecb_cipher_contiguous_blocks(ctx, data, length,
106223c57df7Smcpowers 			    out, DES_BLOCK_LEN, des3_encrypt_block);
106323c57df7Smcpowers 		}
106423c57df7Smcpowers 	} else {
106523c57df7Smcpowers 		if (des_ctx->dc_flags & CBC_MODE) {
106623c57df7Smcpowers 			rv = cbc_encrypt_contiguous_blocks(ctx, data,
106723c57df7Smcpowers 			    length, out, DES_BLOCK_LEN, des_encrypt_block,
106823c57df7Smcpowers 			    des_copy_block, des_xor_block);
106923c57df7Smcpowers 		} else {
107023c57df7Smcpowers 			rv = ecb_cipher_contiguous_blocks(ctx, data, length,
107123c57df7Smcpowers 			    out, DES_BLOCK_LEN, des_encrypt_block);
107223c57df7Smcpowers 		}
107323c57df7Smcpowers 	}
107423c57df7Smcpowers 	return (rv);
107523c57df7Smcpowers }
107623c57df7Smcpowers 
107723c57df7Smcpowers /*
107823c57df7Smcpowers  * Decrypt multiple blocks of data according to mode.
107923c57df7Smcpowers  */
108023c57df7Smcpowers int
108123c57df7Smcpowers des_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
108223c57df7Smcpowers     crypto_data_t *out)
108323c57df7Smcpowers {
108423c57df7Smcpowers 	des_ctx_t *des_ctx = ctx;
108523c57df7Smcpowers 	int rv;
108623c57df7Smcpowers 
108723c57df7Smcpowers 	if (des_ctx->dc_flags & DES3_STRENGTH) {
108823c57df7Smcpowers 		if (des_ctx->dc_flags & CBC_MODE) {
108923c57df7Smcpowers 			rv = cbc_decrypt_contiguous_blocks(ctx, data,
109023c57df7Smcpowers 			    length, out, DES_BLOCK_LEN, des3_decrypt_block,
109123c57df7Smcpowers 			    des_copy_block, des_xor_block);
109223c57df7Smcpowers 		} else {
109323c57df7Smcpowers 			rv = ecb_cipher_contiguous_blocks(ctx, data, length,
109423c57df7Smcpowers 			    out, DES_BLOCK_LEN, des3_decrypt_block);
109523c57df7Smcpowers 			if (rv == CRYPTO_DATA_LEN_RANGE)
109623c57df7Smcpowers 				rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
109723c57df7Smcpowers 		}
109823c57df7Smcpowers 	} else {
109923c57df7Smcpowers 		if (des_ctx->dc_flags & CBC_MODE) {
110023c57df7Smcpowers 			rv = cbc_decrypt_contiguous_blocks(ctx, data,
110123c57df7Smcpowers 			    length, out, DES_BLOCK_LEN, des_decrypt_block,
110223c57df7Smcpowers 			    des_copy_block, des_xor_block);
110323c57df7Smcpowers 		} else {
110423c57df7Smcpowers 			rv = ecb_cipher_contiguous_blocks(ctx, data, length,
110523c57df7Smcpowers 			    out, DES_BLOCK_LEN, des_decrypt_block);
110623c57df7Smcpowers 			if (rv == CRYPTO_DATA_LEN_RANGE)
110723c57df7Smcpowers 				rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
110823c57df7Smcpowers 		}
110923c57df7Smcpowers 	}
111023c57df7Smcpowers 	return (rv);
111123c57df7Smcpowers }
1112