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
523c57df7Smcpowers  * Common Development and Distribution License (the "License").
623c57df7Smcpowers  * 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*95014fbbSDan OpenSolaris Anderson  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * Blowfish encryption/decryption and keyschedule code.
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/systm.h>
327c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
337c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
347c478bd9Sstevel@tonic-gate #include <sys/strsun.h>
357c478bd9Sstevel@tonic-gate #include <sys/note.h>
367c478bd9Sstevel@tonic-gate #include <sys/byteorder.h>
3723c57df7Smcpowers #include <sys/crypto/spi.h>
3823c57df7Smcpowers #include <modes/modes.h>
397c478bd9Sstevel@tonic-gate #include <sys/crypto/common.h>
407c478bd9Sstevel@tonic-gate #include "blowfish_impl.h"
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #ifdef _KERNEL
43f66d273dSizick 
447c478bd9Sstevel@tonic-gate #define	BLOWFISH_ASSERT(x)	ASSERT(x)
45f66d273dSizick 
467c478bd9Sstevel@tonic-gate #else /* !_KERNEL */
47f66d273dSizick 
48f66d273dSizick #include <strings.h>
49f66d273dSizick #include <stdlib.h>
507c478bd9Sstevel@tonic-gate #define	BLOWFISH_ASSERT(x)
517c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
527c478bd9Sstevel@tonic-gate 
534b56a003SDaniel Anderson #if defined(__i386) || defined(__amd64)
544b56a003SDaniel Anderson #include <sys/byteorder.h>
554b56a003SDaniel Anderson #define	UNALIGNED_POINTERS_PERMITTED
564b56a003SDaniel Anderson #endif
574b56a003SDaniel Anderson 
587c478bd9Sstevel@tonic-gate /*
597c478bd9Sstevel@tonic-gate  * Blowfish initial P box and S boxes, derived from the hex digits of PI.
607c478bd9Sstevel@tonic-gate  *
617c478bd9Sstevel@tonic-gate  * NOTE:  S boxes are placed into one large array.
627c478bd9Sstevel@tonic-gate  */
637c478bd9Sstevel@tonic-gate static const uint32_t init_P[] = {
647c478bd9Sstevel@tonic-gate 	0x243f6a88U, 0x85a308d3U, 0x13198a2eU,
657c478bd9Sstevel@tonic-gate 	0x03707344U, 0xa4093822U, 0x299f31d0U,
667c478bd9Sstevel@tonic-gate 	0x082efa98U, 0xec4e6c89U, 0x452821e6U,
677c478bd9Sstevel@tonic-gate 	0x38d01377U, 0xbe5466cfU, 0x34e90c6cU,
687c478bd9Sstevel@tonic-gate 	0xc0ac29b7U, 0xc97c50ddU, 0x3f84d5b5U,
697c478bd9Sstevel@tonic-gate 	0xb5470917U, 0x9216d5d9U, 0x8979fb1bU
707c478bd9Sstevel@tonic-gate };
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate static const uint32_t init_S[] = {
737c478bd9Sstevel@tonic-gate 	/* S-Box 0. */
747c478bd9Sstevel@tonic-gate 	0xd1310ba6U, 0x98dfb5acU, 0x2ffd72dbU, 0xd01adfb7U,
757c478bd9Sstevel@tonic-gate 	0xb8e1afedU, 0x6a267e96U, 0xba7c9045U, 0xf12c7f99U,
767c478bd9Sstevel@tonic-gate 	0x24a19947U, 0xb3916cf7U, 0x0801f2e2U, 0x858efc16U,
777c478bd9Sstevel@tonic-gate 	0x636920d8U, 0x71574e69U, 0xa458fea3U, 0xf4933d7eU,
787c478bd9Sstevel@tonic-gate 	0x0d95748fU, 0x728eb658U, 0x718bcd58U, 0x82154aeeU,
797c478bd9Sstevel@tonic-gate 	0x7b54a41dU, 0xc25a59b5U, 0x9c30d539U, 0x2af26013U,
807c478bd9Sstevel@tonic-gate 	0xc5d1b023U, 0x286085f0U, 0xca417918U, 0xb8db38efU,
817c478bd9Sstevel@tonic-gate 	0x8e79dcb0U, 0x603a180eU, 0x6c9e0e8bU, 0xb01e8a3eU,
827c478bd9Sstevel@tonic-gate 	0xd71577c1U, 0xbd314b27U, 0x78af2fdaU, 0x55605c60U,
837c478bd9Sstevel@tonic-gate 	0xe65525f3U, 0xaa55ab94U, 0x57489862U, 0x63e81440U,
847c478bd9Sstevel@tonic-gate 	0x55ca396aU, 0x2aab10b6U, 0xb4cc5c34U, 0x1141e8ceU,
857c478bd9Sstevel@tonic-gate 	0xa15486afU, 0x7c72e993U, 0xb3ee1411U, 0x636fbc2aU,
867c478bd9Sstevel@tonic-gate 	0x2ba9c55dU, 0x741831f6U, 0xce5c3e16U, 0x9b87931eU,
877c478bd9Sstevel@tonic-gate 	0xafd6ba33U, 0x6c24cf5cU, 0x7a325381U, 0x28958677U,
887c478bd9Sstevel@tonic-gate 	0x3b8f4898U, 0x6b4bb9afU, 0xc4bfe81bU, 0x66282193U,
897c478bd9Sstevel@tonic-gate 	0x61d809ccU, 0xfb21a991U, 0x487cac60U, 0x5dec8032U,
907c478bd9Sstevel@tonic-gate 	0xef845d5dU, 0xe98575b1U, 0xdc262302U, 0xeb651b88U,
917c478bd9Sstevel@tonic-gate 	0x23893e81U, 0xd396acc5U, 0x0f6d6ff3U, 0x83f44239U,
927c478bd9Sstevel@tonic-gate 	0x2e0b4482U, 0xa4842004U, 0x69c8f04aU, 0x9e1f9b5eU,
937c478bd9Sstevel@tonic-gate 	0x21c66842U, 0xf6e96c9aU, 0x670c9c61U, 0xabd388f0U,
947c478bd9Sstevel@tonic-gate 	0x6a51a0d2U, 0xd8542f68U, 0x960fa728U, 0xab5133a3U,
957c478bd9Sstevel@tonic-gate 	0x6eef0b6cU, 0x137a3be4U, 0xba3bf050U, 0x7efb2a98U,
967c478bd9Sstevel@tonic-gate 	0xa1f1651dU, 0x39af0176U, 0x66ca593eU, 0x82430e88U,
977c478bd9Sstevel@tonic-gate 	0x8cee8619U, 0x456f9fb4U, 0x7d84a5c3U, 0x3b8b5ebeU,
987c478bd9Sstevel@tonic-gate 	0xe06f75d8U, 0x85c12073U, 0x401a449fU, 0x56c16aa6U,
997c478bd9Sstevel@tonic-gate 	0x4ed3aa62U, 0x363f7706U, 0x1bfedf72U, 0x429b023dU,
1007c478bd9Sstevel@tonic-gate 	0x37d0d724U, 0xd00a1248U, 0xdb0fead3U, 0x49f1c09bU,
1017c478bd9Sstevel@tonic-gate 	0x075372c9U, 0x80991b7bU, 0x25d479d8U, 0xf6e8def7U,
1027c478bd9Sstevel@tonic-gate 	0xe3fe501aU, 0xb6794c3bU, 0x976ce0bdU, 0x04c006baU,
1037c478bd9Sstevel@tonic-gate 	0xc1a94fb6U, 0x409f60c4U, 0x5e5c9ec2U, 0x196a2463U,
1047c478bd9Sstevel@tonic-gate 	0x68fb6fafU, 0x3e6c53b5U, 0x1339b2ebU, 0x3b52ec6fU,
1057c478bd9Sstevel@tonic-gate 	0x6dfc511fU, 0x9b30952cU, 0xcc814544U, 0xaf5ebd09U,
1067c478bd9Sstevel@tonic-gate 	0xbee3d004U, 0xde334afdU, 0x660f2807U, 0x192e4bb3U,
1077c478bd9Sstevel@tonic-gate 	0xc0cba857U, 0x45c8740fU, 0xd20b5f39U, 0xb9d3fbdbU,
1087c478bd9Sstevel@tonic-gate 	0x5579c0bdU, 0x1a60320aU, 0xd6a100c6U, 0x402c7279U,
1097c478bd9Sstevel@tonic-gate 	0x679f25feU, 0xfb1fa3ccU, 0x8ea5e9f8U, 0xdb3222f8U,
1107c478bd9Sstevel@tonic-gate 	0x3c7516dfU, 0xfd616b15U, 0x2f501ec8U, 0xad0552abU,
1117c478bd9Sstevel@tonic-gate 	0x323db5faU, 0xfd238760U, 0x53317b48U, 0x3e00df82U,
1127c478bd9Sstevel@tonic-gate 	0x9e5c57bbU, 0xca6f8ca0U, 0x1a87562eU, 0xdf1769dbU,
1137c478bd9Sstevel@tonic-gate 	0xd542a8f6U, 0x287effc3U, 0xac6732c6U, 0x8c4f5573U,
1147c478bd9Sstevel@tonic-gate 	0x695b27b0U, 0xbbca58c8U, 0xe1ffa35dU, 0xb8f011a0U,
1157c478bd9Sstevel@tonic-gate 	0x10fa3d98U, 0xfd2183b8U, 0x4afcb56cU, 0x2dd1d35bU,
1167c478bd9Sstevel@tonic-gate 	0x9a53e479U, 0xb6f84565U, 0xd28e49bcU, 0x4bfb9790U,
1177c478bd9Sstevel@tonic-gate 	0xe1ddf2daU, 0xa4cb7e33U, 0x62fb1341U, 0xcee4c6e8U,
1187c478bd9Sstevel@tonic-gate 	0xef20cadaU, 0x36774c01U, 0xd07e9efeU, 0x2bf11fb4U,
1197c478bd9Sstevel@tonic-gate 	0x95dbda4dU, 0xae909198U, 0xeaad8e71U, 0x6b93d5a0U,
1207c478bd9Sstevel@tonic-gate 	0xd08ed1d0U, 0xafc725e0U, 0x8e3c5b2fU, 0x8e7594b7U,
1217c478bd9Sstevel@tonic-gate 	0x8ff6e2fbU, 0xf2122b64U, 0x8888b812U, 0x900df01cU,
1227c478bd9Sstevel@tonic-gate 	0x4fad5ea0U, 0x688fc31cU, 0xd1cff191U, 0xb3a8c1adU,
1237c478bd9Sstevel@tonic-gate 	0x2f2f2218U, 0xbe0e1777U, 0xea752dfeU, 0x8b021fa1U,
1247c478bd9Sstevel@tonic-gate 	0xe5a0cc0fU, 0xb56f74e8U, 0x18acf3d6U, 0xce89e299U,
1257c478bd9Sstevel@tonic-gate 	0xb4a84fe0U, 0xfd13e0b7U, 0x7cc43b81U, 0xd2ada8d9U,
1267c478bd9Sstevel@tonic-gate 	0x165fa266U, 0x80957705U, 0x93cc7314U, 0x211a1477U,
1277c478bd9Sstevel@tonic-gate 	0xe6ad2065U, 0x77b5fa86U, 0xc75442f5U, 0xfb9d35cfU,
1287c478bd9Sstevel@tonic-gate 	0xebcdaf0cU, 0x7b3e89a0U, 0xd6411bd3U, 0xae1e7e49U,
1297c478bd9Sstevel@tonic-gate 	0x00250e2dU, 0x2071b35eU, 0x226800bbU, 0x57b8e0afU,
1307c478bd9Sstevel@tonic-gate 	0x2464369bU, 0xf009b91eU, 0x5563911dU, 0x59dfa6aaU,
1317c478bd9Sstevel@tonic-gate 	0x78c14389U, 0xd95a537fU, 0x207d5ba2U, 0x02e5b9c5U,
1327c478bd9Sstevel@tonic-gate 	0x83260376U, 0x6295cfa9U, 0x11c81968U, 0x4e734a41U,
1337c478bd9Sstevel@tonic-gate 	0xb3472dcaU, 0x7b14a94aU, 0x1b510052U, 0x9a532915U,
1347c478bd9Sstevel@tonic-gate 	0xd60f573fU, 0xbc9bc6e4U, 0x2b60a476U, 0x81e67400U,
1357c478bd9Sstevel@tonic-gate 	0x08ba6fb5U, 0x571be91fU, 0xf296ec6bU, 0x2a0dd915U,
1367c478bd9Sstevel@tonic-gate 	0xb6636521U, 0xe7b9f9b6U, 0xff34052eU, 0xc5855664U,
1377c478bd9Sstevel@tonic-gate 	0x53b02d5dU, 0xa99f8fa1U, 0x08ba4799U, 0x6e85076aU,
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	/* S-Box 1. */
1407c478bd9Sstevel@tonic-gate 	0x4b7a70e9U, 0xb5b32944U, 0xdb75092eU, 0xc4192623U,
1417c478bd9Sstevel@tonic-gate 	0xad6ea6b0U, 0x49a7df7dU, 0x9cee60b8U, 0x8fedb266U,
1427c478bd9Sstevel@tonic-gate 	0xecaa8c71U, 0x699a17ffU, 0x5664526cU, 0xc2b19ee1U,
1437c478bd9Sstevel@tonic-gate 	0x193602a5U, 0x75094c29U, 0xa0591340U, 0xe4183a3eU,
1447c478bd9Sstevel@tonic-gate 	0x3f54989aU, 0x5b429d65U, 0x6b8fe4d6U, 0x99f73fd6U,
1457c478bd9Sstevel@tonic-gate 	0xa1d29c07U, 0xefe830f5U, 0x4d2d38e6U, 0xf0255dc1U,
1467c478bd9Sstevel@tonic-gate 	0x4cdd2086U, 0x8470eb26U, 0x6382e9c6U, 0x021ecc5eU,
1477c478bd9Sstevel@tonic-gate 	0x09686b3fU, 0x3ebaefc9U, 0x3c971814U, 0x6b6a70a1U,
1487c478bd9Sstevel@tonic-gate 	0x687f3584U, 0x52a0e286U, 0xb79c5305U, 0xaa500737U,
1497c478bd9Sstevel@tonic-gate 	0x3e07841cU, 0x7fdeae5cU, 0x8e7d44ecU, 0x5716f2b8U,
1507c478bd9Sstevel@tonic-gate 	0xb03ada37U, 0xf0500c0dU, 0xf01c1f04U, 0x0200b3ffU,
1517c478bd9Sstevel@tonic-gate 	0xae0cf51aU, 0x3cb574b2U, 0x25837a58U, 0xdc0921bdU,
1527c478bd9Sstevel@tonic-gate 	0xd19113f9U, 0x7ca92ff6U, 0x94324773U, 0x22f54701U,
1537c478bd9Sstevel@tonic-gate 	0x3ae5e581U, 0x37c2dadcU, 0xc8b57634U, 0x9af3dda7U,
1547c478bd9Sstevel@tonic-gate 	0xa9446146U, 0x0fd0030eU, 0xecc8c73eU, 0xa4751e41U,
1557c478bd9Sstevel@tonic-gate 	0xe238cd99U, 0x3bea0e2fU, 0x3280bba1U, 0x183eb331U,
1567c478bd9Sstevel@tonic-gate 	0x4e548b38U, 0x4f6db908U, 0x6f420d03U, 0xf60a04bfU,
1577c478bd9Sstevel@tonic-gate 	0x2cb81290U, 0x24977c79U, 0x5679b072U, 0xbcaf89afU,
1587c478bd9Sstevel@tonic-gate 	0xde9a771fU, 0xd9930810U, 0xb38bae12U, 0xdccf3f2eU,
1597c478bd9Sstevel@tonic-gate 	0x5512721fU, 0x2e6b7124U, 0x501adde6U, 0x9f84cd87U,
1607c478bd9Sstevel@tonic-gate 	0x7a584718U, 0x7408da17U, 0xbc9f9abcU, 0xe94b7d8cU,
1617c478bd9Sstevel@tonic-gate 	0xec7aec3aU, 0xdb851dfaU, 0x63094366U, 0xc464c3d2U,
1627c478bd9Sstevel@tonic-gate 	0xef1c1847U, 0x3215d908U, 0xdd433b37U, 0x24c2ba16U,
1637c478bd9Sstevel@tonic-gate 	0x12a14d43U, 0x2a65c451U, 0x50940002U, 0x133ae4ddU,
1647c478bd9Sstevel@tonic-gate 	0x71dff89eU, 0x10314e55U, 0x81ac77d6U, 0x5f11199bU,
1657c478bd9Sstevel@tonic-gate 	0x043556f1U, 0xd7a3c76bU, 0x3c11183bU, 0x5924a509U,
1667c478bd9Sstevel@tonic-gate 	0xf28fe6edU, 0x97f1fbfaU, 0x9ebabf2cU, 0x1e153c6eU,
1677c478bd9Sstevel@tonic-gate 	0x86e34570U, 0xeae96fb1U, 0x860e5e0aU, 0x5a3e2ab3U,
1687c478bd9Sstevel@tonic-gate 	0x771fe71cU, 0x4e3d06faU, 0x2965dcb9U, 0x99e71d0fU,
1697c478bd9Sstevel@tonic-gate 	0x803e89d6U, 0x5266c825U, 0x2e4cc978U, 0x9c10b36aU,
1707c478bd9Sstevel@tonic-gate 	0xc6150ebaU, 0x94e2ea78U, 0xa5fc3c53U, 0x1e0a2df4U,
1717c478bd9Sstevel@tonic-gate 	0xf2f74ea7U, 0x361d2b3dU, 0x1939260fU, 0x19c27960U,
1727c478bd9Sstevel@tonic-gate 	0x5223a708U, 0xf71312b6U, 0xebadfe6eU, 0xeac31f66U,
1737c478bd9Sstevel@tonic-gate 	0xe3bc4595U, 0xa67bc883U, 0xb17f37d1U, 0x018cff28U,
1747c478bd9Sstevel@tonic-gate 	0xc332ddefU, 0xbe6c5aa5U, 0x65582185U, 0x68ab9802U,
1757c478bd9Sstevel@tonic-gate 	0xeecea50fU, 0xdb2f953bU, 0x2aef7dadU, 0x5b6e2f84U,
1767c478bd9Sstevel@tonic-gate 	0x1521b628U, 0x29076170U, 0xecdd4775U, 0x619f1510U,
1777c478bd9Sstevel@tonic-gate 	0x13cca830U, 0xeb61bd96U, 0x0334fe1eU, 0xaa0363cfU,
1787c478bd9Sstevel@tonic-gate 	0xb5735c90U, 0x4c70a239U, 0xd59e9e0bU, 0xcbaade14U,
1797c478bd9Sstevel@tonic-gate 	0xeecc86bcU, 0x60622ca7U, 0x9cab5cabU, 0xb2f3846eU,
1807c478bd9Sstevel@tonic-gate 	0x648b1eafU, 0x19bdf0caU, 0xa02369b9U, 0x655abb50U,
1817c478bd9Sstevel@tonic-gate 	0x40685a32U, 0x3c2ab4b3U, 0x319ee9d5U, 0xc021b8f7U,
1827c478bd9Sstevel@tonic-gate 	0x9b540b19U, 0x875fa099U, 0x95f7997eU, 0x623d7da8U,
1837c478bd9Sstevel@tonic-gate 	0xf837889aU, 0x97e32d77U, 0x11ed935fU, 0x16681281U,
1847c478bd9Sstevel@tonic-gate 	0x0e358829U, 0xc7e61fd6U, 0x96dedfa1U, 0x7858ba99U,
1857c478bd9Sstevel@tonic-gate 	0x57f584a5U, 0x1b227263U, 0x9b83c3ffU, 0x1ac24696U,
1867c478bd9Sstevel@tonic-gate 	0xcdb30aebU, 0x532e3054U, 0x8fd948e4U, 0x6dbc3128U,
1877c478bd9Sstevel@tonic-gate 	0x58ebf2efU, 0x34c6ffeaU, 0xfe28ed61U, 0xee7c3c73U,
1887c478bd9Sstevel@tonic-gate 	0x5d4a14d9U, 0xe864b7e3U, 0x42105d14U, 0x203e13e0U,
1897c478bd9Sstevel@tonic-gate 	0x45eee2b6U, 0xa3aaabeaU, 0xdb6c4f15U, 0xfacb4fd0U,
1907c478bd9Sstevel@tonic-gate 	0xc742f442U, 0xef6abbb5U, 0x654f3b1dU, 0x41cd2105U,
1917c478bd9Sstevel@tonic-gate 	0xd81e799eU, 0x86854dc7U, 0xe44b476aU, 0x3d816250U,
1927c478bd9Sstevel@tonic-gate 	0xcf62a1f2U, 0x5b8d2646U, 0xfc8883a0U, 0xc1c7b6a3U,
1937c478bd9Sstevel@tonic-gate 	0x7f1524c3U, 0x69cb7492U, 0x47848a0bU, 0x5692b285U,
1947c478bd9Sstevel@tonic-gate 	0x095bbf00U, 0xad19489dU, 0x1462b174U, 0x23820e00U,
1957c478bd9Sstevel@tonic-gate 	0x58428d2aU, 0x0c55f5eaU, 0x1dadf43eU, 0x233f7061U,
1967c478bd9Sstevel@tonic-gate 	0x3372f092U, 0x8d937e41U, 0xd65fecf1U, 0x6c223bdbU,
1977c478bd9Sstevel@tonic-gate 	0x7cde3759U, 0xcbee7460U, 0x4085f2a7U, 0xce77326eU,
1987c478bd9Sstevel@tonic-gate 	0xa6078084U, 0x19f8509eU, 0xe8efd855U, 0x61d99735U,
1997c478bd9Sstevel@tonic-gate 	0xa969a7aaU, 0xc50c06c2U, 0x5a04abfcU, 0x800bcadcU,
2007c478bd9Sstevel@tonic-gate 	0x9e447a2eU, 0xc3453484U, 0xfdd56705U, 0x0e1e9ec9U,
2017c478bd9Sstevel@tonic-gate 	0xdb73dbd3U, 0x105588cdU, 0x675fda79U, 0xe3674340U,
2027c478bd9Sstevel@tonic-gate 	0xc5c43465U, 0x713e38d8U, 0x3d28f89eU, 0xf16dff20U,
2037c478bd9Sstevel@tonic-gate 	0x153e21e7U, 0x8fb03d4aU, 0xe6e39f2bU, 0xdb83adf7U,
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	/* S-Box 2. */
2067c478bd9Sstevel@tonic-gate 	0xe93d5a68U, 0x948140f7U, 0xf64c261cU, 0x94692934U,
2077c478bd9Sstevel@tonic-gate 	0x411520f7U, 0x7602d4f7U, 0xbcf46b2eU, 0xd4a20068U,
2087c478bd9Sstevel@tonic-gate 	0xd4082471U, 0x3320f46aU, 0x43b7d4b7U, 0x500061afU,
2097c478bd9Sstevel@tonic-gate 	0x1e39f62eU, 0x97244546U, 0x14214f74U, 0xbf8b8840U,
2107c478bd9Sstevel@tonic-gate 	0x4d95fc1dU, 0x96b591afU, 0x70f4ddd3U, 0x66a02f45U,
2117c478bd9Sstevel@tonic-gate 	0xbfbc09ecU, 0x03bd9785U, 0x7fac6dd0U, 0x31cb8504U,
2127c478bd9Sstevel@tonic-gate 	0x96eb27b3U, 0x55fd3941U, 0xda2547e6U, 0xabca0a9aU,
2137c478bd9Sstevel@tonic-gate 	0x28507825U, 0x530429f4U, 0x0a2c86daU, 0xe9b66dfbU,
2147c478bd9Sstevel@tonic-gate 	0x68dc1462U, 0xd7486900U, 0x680ec0a4U, 0x27a18deeU,
2157c478bd9Sstevel@tonic-gate 	0x4f3ffea2U, 0xe887ad8cU, 0xb58ce006U, 0x7af4d6b6U,
2167c478bd9Sstevel@tonic-gate 	0xaace1e7cU, 0xd3375fecU, 0xce78a399U, 0x406b2a42U,
2177c478bd9Sstevel@tonic-gate 	0x20fe9e35U, 0xd9f385b9U, 0xee39d7abU, 0x3b124e8bU,
2187c478bd9Sstevel@tonic-gate 	0x1dc9faf7U, 0x4b6d1856U, 0x26a36631U, 0xeae397b2U,
2197c478bd9Sstevel@tonic-gate 	0x3a6efa74U, 0xdd5b4332U, 0x6841e7f7U, 0xca7820fbU,
2207c478bd9Sstevel@tonic-gate 	0xfb0af54eU, 0xd8feb397U, 0x454056acU, 0xba489527U,
2217c478bd9Sstevel@tonic-gate 	0x55533a3aU, 0x20838d87U, 0xfe6ba9b7U, 0xd096954bU,
2227c478bd9Sstevel@tonic-gate 	0x55a867bcU, 0xa1159a58U, 0xcca92963U, 0x99e1db33U,
2237c478bd9Sstevel@tonic-gate 	0xa62a4a56U, 0x3f3125f9U, 0x5ef47e1cU, 0x9029317cU,
2247c478bd9Sstevel@tonic-gate 	0xfdf8e802U, 0x04272f70U, 0x80bb155cU, 0x05282ce3U,
2257c478bd9Sstevel@tonic-gate 	0x95c11548U, 0xe4c66d22U, 0x48c1133fU, 0xc70f86dcU,
2267c478bd9Sstevel@tonic-gate 	0x07f9c9eeU, 0x41041f0fU, 0x404779a4U, 0x5d886e17U,
2277c478bd9Sstevel@tonic-gate 	0x325f51ebU, 0xd59bc0d1U, 0xf2bcc18fU, 0x41113564U,
2287c478bd9Sstevel@tonic-gate 	0x257b7834U, 0x602a9c60U, 0xdff8e8a3U, 0x1f636c1bU,
2297c478bd9Sstevel@tonic-gate 	0x0e12b4c2U, 0x02e1329eU, 0xaf664fd1U, 0xcad18115U,
2307c478bd9Sstevel@tonic-gate 	0x6b2395e0U, 0x333e92e1U, 0x3b240b62U, 0xeebeb922U,
2317c478bd9Sstevel@tonic-gate 	0x85b2a20eU, 0xe6ba0d99U, 0xde720c8cU, 0x2da2f728U,
2327c478bd9Sstevel@tonic-gate 	0xd0127845U, 0x95b794fdU, 0x647d0862U, 0xe7ccf5f0U,
2337c478bd9Sstevel@tonic-gate 	0x5449a36fU, 0x877d48faU, 0xc39dfd27U, 0xf33e8d1eU,
2347c478bd9Sstevel@tonic-gate 	0x0a476341U, 0x992eff74U, 0x3a6f6eabU, 0xf4f8fd37U,
2357c478bd9Sstevel@tonic-gate 	0xa812dc60U, 0xa1ebddf8U, 0x991be14cU, 0xdb6e6b0dU,
2367c478bd9Sstevel@tonic-gate 	0xc67b5510U, 0x6d672c37U, 0x2765d43bU, 0xdcd0e804U,
2377c478bd9Sstevel@tonic-gate 	0xf1290dc7U, 0xcc00ffa3U, 0xb5390f92U, 0x690fed0bU,
2387c478bd9Sstevel@tonic-gate 	0x667b9ffbU, 0xcedb7d9cU, 0xa091cf0bU, 0xd9155ea3U,
2397c478bd9Sstevel@tonic-gate 	0xbb132f88U, 0x515bad24U, 0x7b9479bfU, 0x763bd6ebU,
2407c478bd9Sstevel@tonic-gate 	0x37392eb3U, 0xcc115979U, 0x8026e297U, 0xf42e312dU,
2417c478bd9Sstevel@tonic-gate 	0x6842ada7U, 0xc66a2b3bU, 0x12754cccU, 0x782ef11cU,
2427c478bd9Sstevel@tonic-gate 	0x6a124237U, 0xb79251e7U, 0x06a1bbe6U, 0x4bfb6350U,
2437c478bd9Sstevel@tonic-gate 	0x1a6b1018U, 0x11caedfaU, 0x3d25bdd8U, 0xe2e1c3c9U,
2447c478bd9Sstevel@tonic-gate 	0x44421659U, 0x0a121386U, 0xd90cec6eU, 0xd5abea2aU,
2457c478bd9Sstevel@tonic-gate 	0x64af674eU, 0xda86a85fU, 0xbebfe988U, 0x64e4c3feU,
2467c478bd9Sstevel@tonic-gate 	0x9dbc8057U, 0xf0f7c086U, 0x60787bf8U, 0x6003604dU,
2477c478bd9Sstevel@tonic-gate 	0xd1fd8346U, 0xf6381fb0U, 0x7745ae04U, 0xd736fcccU,
2487c478bd9Sstevel@tonic-gate 	0x83426b33U, 0xf01eab71U, 0xb0804187U, 0x3c005e5fU,
2497c478bd9Sstevel@tonic-gate 	0x77a057beU, 0xbde8ae24U, 0x55464299U, 0xbf582e61U,
2507c478bd9Sstevel@tonic-gate 	0x4e58f48fU, 0xf2ddfda2U, 0xf474ef38U, 0x8789bdc2U,
2517c478bd9Sstevel@tonic-gate 	0x5366f9c3U, 0xc8b38e74U, 0xb475f255U, 0x46fcd9b9U,
2527c478bd9Sstevel@tonic-gate 	0x7aeb2661U, 0x8b1ddf84U, 0x846a0e79U, 0x915f95e2U,
2537c478bd9Sstevel@tonic-gate 	0x466e598eU, 0x20b45770U, 0x8cd55591U, 0xc902de4cU,
2547c478bd9Sstevel@tonic-gate 	0xb90bace1U, 0xbb8205d0U, 0x11a86248U, 0x7574a99eU,
2557c478bd9Sstevel@tonic-gate 	0xb77f19b6U, 0xe0a9dc09U, 0x662d09a1U, 0xc4324633U,
2567c478bd9Sstevel@tonic-gate 	0xe85a1f02U, 0x09f0be8cU, 0x4a99a025U, 0x1d6efe10U,
2577c478bd9Sstevel@tonic-gate 	0x1ab93d1dU, 0x0ba5a4dfU, 0xa186f20fU, 0x2868f169U,
2587c478bd9Sstevel@tonic-gate 	0xdcb7da83U, 0x573906feU, 0xa1e2ce9bU, 0x4fcd7f52U,
2597c478bd9Sstevel@tonic-gate 	0x50115e01U, 0xa70683faU, 0xa002b5c4U, 0x0de6d027U,
2607c478bd9Sstevel@tonic-gate 	0x9af88c27U, 0x773f8641U, 0xc3604c06U, 0x61a806b5U,
2617c478bd9Sstevel@tonic-gate 	0xf0177a28U, 0xc0f586e0U, 0x006058aaU, 0x30dc7d62U,
2627c478bd9Sstevel@tonic-gate 	0x11e69ed7U, 0x2338ea63U, 0x53c2dd94U, 0xc2c21634U,
2637c478bd9Sstevel@tonic-gate 	0xbbcbee56U, 0x90bcb6deU, 0xebfc7da1U, 0xce591d76U,
2647c478bd9Sstevel@tonic-gate 	0x6f05e409U, 0x4b7c0188U, 0x39720a3dU, 0x7c927c24U,
2657c478bd9Sstevel@tonic-gate 	0x86e3725fU, 0x724d9db9U, 0x1ac15bb4U, 0xd39eb8fcU,
2667c478bd9Sstevel@tonic-gate 	0xed545578U, 0x08fca5b5U, 0xd83d7cd3U, 0x4dad0fc4U,
2677c478bd9Sstevel@tonic-gate 	0x1e50ef5eU, 0xb161e6f8U, 0xa28514d9U, 0x6c51133cU,
2687c478bd9Sstevel@tonic-gate 	0x6fd5c7e7U, 0x56e14ec4U, 0x362abfceU, 0xddc6c837U,
2697c478bd9Sstevel@tonic-gate 	0xd79a3234U, 0x92638212U, 0x670efa8eU, 0x406000e0U,
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	/* S-Box 3. */
2727c478bd9Sstevel@tonic-gate 	0x3a39ce37U, 0xd3faf5cfU, 0xabc27737U, 0x5ac52d1bU,
2737c478bd9Sstevel@tonic-gate 	0x5cb0679eU, 0x4fa33742U, 0xd3822740U, 0x99bc9bbeU,
2747c478bd9Sstevel@tonic-gate 	0xd5118e9dU, 0xbf0f7315U, 0xd62d1c7eU, 0xc700c47bU,
2757c478bd9Sstevel@tonic-gate 	0xb78c1b6bU, 0x21a19045U, 0xb26eb1beU, 0x6a366eb4U,
2767c478bd9Sstevel@tonic-gate 	0x5748ab2fU, 0xbc946e79U, 0xc6a376d2U, 0x6549c2c8U,
2777c478bd9Sstevel@tonic-gate 	0x530ff8eeU, 0x468dde7dU, 0xd5730a1dU, 0x4cd04dc6U,
2787c478bd9Sstevel@tonic-gate 	0x2939bbdbU, 0xa9ba4650U, 0xac9526e8U, 0xbe5ee304U,
2797c478bd9Sstevel@tonic-gate 	0xa1fad5f0U, 0x6a2d519aU, 0x63ef8ce2U, 0x9a86ee22U,
2807c478bd9Sstevel@tonic-gate 	0xc089c2b8U, 0x43242ef6U, 0xa51e03aaU, 0x9cf2d0a4U,
2817c478bd9Sstevel@tonic-gate 	0x83c061baU, 0x9be96a4dU, 0x8fe51550U, 0xba645bd6U,
2827c478bd9Sstevel@tonic-gate 	0x2826a2f9U, 0xa73a3ae1U, 0x4ba99586U, 0xef5562e9U,
2837c478bd9Sstevel@tonic-gate 	0xc72fefd3U, 0xf752f7daU, 0x3f046f69U, 0x77fa0a59U,
2847c478bd9Sstevel@tonic-gate 	0x80e4a915U, 0x87b08601U, 0x9b09e6adU, 0x3b3ee593U,
2857c478bd9Sstevel@tonic-gate 	0xe990fd5aU, 0x9e34d797U, 0x2cf0b7d9U, 0x022b8b51U,
2867c478bd9Sstevel@tonic-gate 	0x96d5ac3aU, 0x017da67dU, 0xd1cf3ed6U, 0x7c7d2d28U,
2877c478bd9Sstevel@tonic-gate 	0x1f9f25cfU, 0xadf2b89bU, 0x5ad6b472U, 0x5a88f54cU,
2887c478bd9Sstevel@tonic-gate 	0xe029ac71U, 0xe019a5e6U, 0x47b0acfdU, 0xed93fa9bU,
2897c478bd9Sstevel@tonic-gate 	0xe8d3c48dU, 0x283b57ccU, 0xf8d56629U, 0x79132e28U,
2907c478bd9Sstevel@tonic-gate 	0x785f0191U, 0xed756055U, 0xf7960e44U, 0xe3d35e8cU,
2917c478bd9Sstevel@tonic-gate 	0x15056dd4U, 0x88f46dbaU, 0x03a16125U, 0x0564f0bdU,
2927c478bd9Sstevel@tonic-gate 	0xc3eb9e15U, 0x3c9057a2U, 0x97271aecU, 0xa93a072aU,
2937c478bd9Sstevel@tonic-gate 	0x1b3f6d9bU, 0x1e6321f5U, 0xf59c66fbU, 0x26dcf319U,
2947c478bd9Sstevel@tonic-gate 	0x7533d928U, 0xb155fdf5U, 0x03563482U, 0x8aba3cbbU,
2957c478bd9Sstevel@tonic-gate 	0x28517711U, 0xc20ad9f8U, 0xabcc5167U, 0xccad925fU,
2967c478bd9Sstevel@tonic-gate 	0x4de81751U, 0x3830dc8eU, 0x379d5862U, 0x9320f991U,
2977c478bd9Sstevel@tonic-gate 	0xea7a90c2U, 0xfb3e7bceU, 0x5121ce64U, 0x774fbe32U,
2987c478bd9Sstevel@tonic-gate 	0xa8b6e37eU, 0xc3293d46U, 0x48de5369U, 0x6413e680U,
2997c478bd9Sstevel@tonic-gate 	0xa2ae0810U, 0xdd6db224U, 0x69852dfdU, 0x09072166U,
3007c478bd9Sstevel@tonic-gate 	0xb39a460aU, 0x6445c0ddU, 0x586cdecfU, 0x1c20c8aeU,
3017c478bd9Sstevel@tonic-gate 	0x5bbef7ddU, 0x1b588d40U, 0xccd2017fU, 0x6bb4e3bbU,
3027c478bd9Sstevel@tonic-gate 	0xdda26a7eU, 0x3a59ff45U, 0x3e350a44U, 0xbcb4cdd5U,
3037c478bd9Sstevel@tonic-gate 	0x72eacea8U, 0xfa6484bbU, 0x8d6612aeU, 0xbf3c6f47U,
3047c478bd9Sstevel@tonic-gate 	0xd29be463U, 0x542f5d9eU, 0xaec2771bU, 0xf64e6370U,
3057c478bd9Sstevel@tonic-gate 	0x740e0d8dU, 0xe75b1357U, 0xf8721671U, 0xaf537d5dU,
3067c478bd9Sstevel@tonic-gate 	0x4040cb08U, 0x4eb4e2ccU, 0x34d2466aU, 0x0115af84U,
3077c478bd9Sstevel@tonic-gate 	0xe1b00428U, 0x95983a1dU, 0x06b89fb4U, 0xce6ea048U,
3087c478bd9Sstevel@tonic-gate 	0x6f3f3b82U, 0x3520ab82U, 0x011a1d4bU, 0x277227f8U,
3097c478bd9Sstevel@tonic-gate 	0x611560b1U, 0xe7933fdcU, 0xbb3a792bU, 0x344525bdU,
3107c478bd9Sstevel@tonic-gate 	0xa08839e1U, 0x51ce794bU, 0x2f32c9b7U, 0xa01fbac9U,
3117c478bd9Sstevel@tonic-gate 	0xe01cc87eU, 0xbcc7d1f6U, 0xcf0111c3U, 0xa1e8aac7U,
3127c478bd9Sstevel@tonic-gate 	0x1a908749U, 0xd44fbd9aU, 0xd0dadecbU, 0xd50ada38U,
3137c478bd9Sstevel@tonic-gate 	0x0339c32aU, 0xc6913667U, 0x8df9317cU, 0xe0b12b4fU,
3147c478bd9Sstevel@tonic-gate 	0xf79e59b7U, 0x43f5bb3aU, 0xf2d519ffU, 0x27d9459cU,
3157c478bd9Sstevel@tonic-gate 	0xbf97222cU, 0x15e6fc2aU, 0x0f91fc71U, 0x9b941525U,
3167c478bd9Sstevel@tonic-gate 	0xfae59361U, 0xceb69cebU, 0xc2a86459U, 0x12baa8d1U,
3177c478bd9Sstevel@tonic-gate 	0xb6c1075eU, 0xe3056a0cU, 0x10d25065U, 0xcb03a442U,
3187c478bd9Sstevel@tonic-gate 	0xe0ec6e0eU, 0x1698db3bU, 0x4c98a0beU, 0x3278e964U,
3197c478bd9Sstevel@tonic-gate 	0x9f1f9532U, 0xe0d392dfU, 0xd3a0342bU, 0x8971f21eU,
3207c478bd9Sstevel@tonic-gate 	0x1b0a7441U, 0x4ba3348cU, 0xc5be7120U, 0xc37632d8U,
3217c478bd9Sstevel@tonic-gate 	0xdf359f8dU, 0x9b992f2eU, 0xe60b6f47U, 0x0fe3f11dU,
3227c478bd9Sstevel@tonic-gate 	0xe54cda54U, 0x1edad891U, 0xce6279cfU, 0xcd3e7e6fU,
3237c478bd9Sstevel@tonic-gate 	0x1618b166U, 0xfd2c1d05U, 0x848fd2c5U, 0xf6fb2299U,
3247c478bd9Sstevel@tonic-gate 	0xf523f357U, 0xa6327623U, 0x93a83531U, 0x56cccd02U,
3257c478bd9Sstevel@tonic-gate 	0xacf08162U, 0x5a75ebb5U, 0x6e163697U, 0x88d273ccU,
3267c478bd9Sstevel@tonic-gate 	0xde966292U, 0x81b949d0U, 0x4c50901bU, 0x71c65614U,
3277c478bd9Sstevel@tonic-gate 	0xe6c6c7bdU, 0x327a140aU, 0x45e1d006U, 0xc3f27b9aU,
3287c478bd9Sstevel@tonic-gate 	0xc9aa53fdU, 0x62a80f00U, 0xbb25bfe2U, 0x35bdd2f6U,
3297c478bd9Sstevel@tonic-gate 	0x71126905U, 0xb2040222U, 0xb6cbcf7cU, 0xcd769c2bU,
3307c478bd9Sstevel@tonic-gate 	0x53113ec0U, 0x1640e3d3U, 0x38abbd60U, 0x2547adf0U,
3317c478bd9Sstevel@tonic-gate 	0xba38209cU, 0xf746ce76U, 0x77afa1c5U, 0x20756060U,
3327c478bd9Sstevel@tonic-gate 	0x85cbfe4eU, 0x8ae88dd8U, 0x7aaaf9b0U, 0x4cf9aa7eU,
3337c478bd9Sstevel@tonic-gate 	0x1948c25cU, 0x02fb8a8cU, 0x01c36ae4U, 0xd6ebe1f9U,
3347c478bd9Sstevel@tonic-gate 	0x90d4f869U, 0xa65cdea0U, 0x3f09252dU, 0xc208e69fU,
3357c478bd9Sstevel@tonic-gate 	0xb74e6132U, 0xce77e25bU, 0x578fdfe3U, 0x3ac372e6U,
3367c478bd9Sstevel@tonic-gate };
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate typedef struct keysched_s {
3397c478bd9Sstevel@tonic-gate 	uint32_t ksch_S[1024];	/* The 4 S boxes are 256 32-bit words. */
3407c478bd9Sstevel@tonic-gate 	uint32_t ksch_P[18];	/* P box is 18 32-bit words. */
3417c478bd9Sstevel@tonic-gate } keysched_t;
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate /*
3447c478bd9Sstevel@tonic-gate  * Since ROUND() is a macro, make sure that the things inside can be
3457c478bd9Sstevel@tonic-gate  * evaluated more than once.  Especially when calling F().
3467c478bd9Sstevel@tonic-gate  * Assume the presence of local variables:
3477c478bd9Sstevel@tonic-gate  *
3487c478bd9Sstevel@tonic-gate  *	uint32_t *P;
3497c478bd9Sstevel@tonic-gate  *	uint32_t *S;
3507c478bd9Sstevel@tonic-gate  *	uint32_t tmp;
3517c478bd9Sstevel@tonic-gate  *
3527c478bd9Sstevel@tonic-gate  *
3537c478bd9Sstevel@tonic-gate  * And to Microsoft interview survivors out there, perhaps I should do the
3547c478bd9Sstevel@tonic-gate  * XOR swap trick, or at least #ifdef (__i386) the tmp = ... = tmp; stuff.
3557c478bd9Sstevel@tonic-gate  */
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate #define	F(word) \
3587c478bd9Sstevel@tonic-gate 	(((S[(word >> 24) & 0xff] + S[256 + ((word >> 16) & 0xff)]) ^ \
3597c478bd9Sstevel@tonic-gate 		S[512 + ((word >> 8) & 0xff)]) + S[768 + (word & 0xff)])
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate #define	ROUND(left, right, i) \
3627c478bd9Sstevel@tonic-gate 	(left) ^= P[i]; \
3637c478bd9Sstevel@tonic-gate 	(right) ^= F((left)); \
3647c478bd9Sstevel@tonic-gate 	tmp = (left); \
3657c478bd9Sstevel@tonic-gate 	(left) = (right); \
3667c478bd9Sstevel@tonic-gate 	(right) = tmp;
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate /*
3697c478bd9Sstevel@tonic-gate  * Encrypt a block of data.  Because of addition operations, convert blocks
3707c478bd9Sstevel@tonic-gate  * to their big-endian representation, even on Intel boxen.
3717c478bd9Sstevel@tonic-gate  */
37223c57df7Smcpowers /* ARGSUSED */
37323c57df7Smcpowers int
blowfish_encrypt_block(const void * cookie,const uint8_t * block,uint8_t * out_block)37423c57df7Smcpowers blowfish_encrypt_block(const void *cookie, const uint8_t *block,
37523c57df7Smcpowers     uint8_t *out_block)
3767c478bd9Sstevel@tonic-gate {
3777c478bd9Sstevel@tonic-gate 	keysched_t *ksch = (keysched_t *)cookie;
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate 	uint32_t left, right, tmp;
3807c478bd9Sstevel@tonic-gate 	uint32_t *P = ksch->ksch_P;
3817c478bd9Sstevel@tonic-gate 	uint32_t *S = ksch->ksch_S;
3827c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
3837c478bd9Sstevel@tonic-gate 	uint32_t *b32;
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
386f66d273dSizick 		/* LINTED:  pointer alignment */
3877c478bd9Sstevel@tonic-gate 		b32 = (uint32_t *)block;
3887c478bd9Sstevel@tonic-gate 		left = b32[0];
3897c478bd9Sstevel@tonic-gate 		right = b32[1];
3904b56a003SDaniel Anderson 	} else
3917c478bd9Sstevel@tonic-gate #endif
3924b56a003SDaniel Anderson 	{
3937c478bd9Sstevel@tonic-gate 	/*
3947c478bd9Sstevel@tonic-gate 	 * Read input block and place in left/right in big-endian order.
3957c478bd9Sstevel@tonic-gate 	 */
3964b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
39725cc6a40SDaniel Anderson 	left = htonl(*(uint32_t *)(void *)&block[0]);
39825cc6a40SDaniel Anderson 	right = htonl(*(uint32_t *)(void *)&block[4]);
3994b56a003SDaniel Anderson #else
4007c478bd9Sstevel@tonic-gate 	left = ((uint32_t)block[0] << 24)
4017c478bd9Sstevel@tonic-gate 	    | ((uint32_t)block[1] << 16)
4027c478bd9Sstevel@tonic-gate 	    | ((uint32_t)block[2] << 8)
4037c478bd9Sstevel@tonic-gate 	    | (uint32_t)block[3];
4047c478bd9Sstevel@tonic-gate 	right = ((uint32_t)block[4] << 24)
4057c478bd9Sstevel@tonic-gate 	    | ((uint32_t)block[5] << 16)
4067c478bd9Sstevel@tonic-gate 	    | ((uint32_t)block[6] << 8)
4077c478bd9Sstevel@tonic-gate 	    | (uint32_t)block[7];
4084b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
4097c478bd9Sstevel@tonic-gate 	}
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	ROUND(left, right, 0);
4127c478bd9Sstevel@tonic-gate 	ROUND(left, right, 1);
4137c478bd9Sstevel@tonic-gate 	ROUND(left, right, 2);
4147c478bd9Sstevel@tonic-gate 	ROUND(left, right, 3);
4157c478bd9Sstevel@tonic-gate 	ROUND(left, right, 4);
4167c478bd9Sstevel@tonic-gate 	ROUND(left, right, 5);
4177c478bd9Sstevel@tonic-gate 	ROUND(left, right, 6);
4187c478bd9Sstevel@tonic-gate 	ROUND(left, right, 7);
4197c478bd9Sstevel@tonic-gate 	ROUND(left, right, 8);
4207c478bd9Sstevel@tonic-gate 	ROUND(left, right, 9);
4217c478bd9Sstevel@tonic-gate 	ROUND(left, right, 10);
4227c478bd9Sstevel@tonic-gate 	ROUND(left, right, 11);
4237c478bd9Sstevel@tonic-gate 	ROUND(left, right, 12);
4247c478bd9Sstevel@tonic-gate 	ROUND(left, right, 13);
4257c478bd9Sstevel@tonic-gate 	ROUND(left, right, 14);
4267c478bd9Sstevel@tonic-gate 	ROUND(left, right, 15);
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 	tmp = left;
4297c478bd9Sstevel@tonic-gate 	left = right;
4307c478bd9Sstevel@tonic-gate 	right = tmp;
4317c478bd9Sstevel@tonic-gate 	right ^= P[16];
4327c478bd9Sstevel@tonic-gate 	left ^= P[17];
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
4357c478bd9Sstevel@tonic-gate 	if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
436f66d273dSizick 		/* LINTED:  pointer alignment */
4377c478bd9Sstevel@tonic-gate 		b32 = (uint32_t *)out_block;
4387c478bd9Sstevel@tonic-gate 		b32[0] = left;
4397c478bd9Sstevel@tonic-gate 		b32[1] = right;
4404b56a003SDaniel Anderson 	} else
4417c478bd9Sstevel@tonic-gate #endif
4424b56a003SDaniel Anderson 	{
4434b56a003SDaniel Anderson 		/* Put the block back into the user's block with final swap */
4444b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
44525cc6a40SDaniel Anderson 		*(uint32_t *)(void *)&out_block[0] = htonl(left);
44625cc6a40SDaniel Anderson 		*(uint32_t *)(void *)&out_block[4] = htonl(right);
4474b56a003SDaniel Anderson #else
4484b56a003SDaniel Anderson 		out_block[0] = left >> 24;
4494b56a003SDaniel Anderson 		out_block[1] = left >> 16;
4504b56a003SDaniel Anderson 		out_block[2] = left >> 8;
4514b56a003SDaniel Anderson 		out_block[3] = left;
4524b56a003SDaniel Anderson 		out_block[4] = right >> 24;
4534b56a003SDaniel Anderson 		out_block[5] = right >> 16;
4544b56a003SDaniel Anderson 		out_block[6] = right >> 8;
4554b56a003SDaniel Anderson 		out_block[7] = right;
4564b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
4577c478bd9Sstevel@tonic-gate 	}
45823c57df7Smcpowers 	return (CRYPTO_SUCCESS);
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate /*
4627c478bd9Sstevel@tonic-gate  * Decrypt a block of data.  Because of addition operations, convert blocks
4637c478bd9Sstevel@tonic-gate  * to their big-endian representation, even on Intel boxen.
4647c478bd9Sstevel@tonic-gate  * It should look like the blowfish_encrypt_block() operation
4657c478bd9Sstevel@tonic-gate  * except for the order in which the S/P boxes are accessed.
4667c478bd9Sstevel@tonic-gate  */
46723c57df7Smcpowers /* ARGSUSED */
46823c57df7Smcpowers int
blowfish_decrypt_block(const void * cookie,const uint8_t * block,uint8_t * out_block)46923c57df7Smcpowers blowfish_decrypt_block(const void *cookie, const uint8_t *block,
47023c57df7Smcpowers     uint8_t *out_block)
4717c478bd9Sstevel@tonic-gate {
4727c478bd9Sstevel@tonic-gate 	keysched_t *ksch = (keysched_t *)cookie;
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	uint32_t left, right, tmp;
4757c478bd9Sstevel@tonic-gate 	uint32_t *P = ksch->ksch_P;
4767c478bd9Sstevel@tonic-gate 	uint32_t *S = ksch->ksch_S;
4777c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
4787c478bd9Sstevel@tonic-gate 	uint32_t *b32;
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
481f66d273dSizick 		/* LINTED:  pointer alignment */
4827c478bd9Sstevel@tonic-gate 		b32 = (uint32_t *)block;
4837c478bd9Sstevel@tonic-gate 		left = b32[0];
4847c478bd9Sstevel@tonic-gate 		right = b32[1];
4854b56a003SDaniel Anderson 	} else
4867c478bd9Sstevel@tonic-gate #endif
4874b56a003SDaniel Anderson 	{
4887c478bd9Sstevel@tonic-gate 	/*
4897c478bd9Sstevel@tonic-gate 	 * Read input block and place in left/right in big-endian order.
4907c478bd9Sstevel@tonic-gate 	 */
4914b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
49225cc6a40SDaniel Anderson 	left = htonl(*(uint32_t *)(void *)&block[0]);
49325cc6a40SDaniel Anderson 	right = htonl(*(uint32_t *)(void *)&block[4]);
4944b56a003SDaniel Anderson #else
4957c478bd9Sstevel@tonic-gate 	left = ((uint32_t)block[0] << 24)
4967c478bd9Sstevel@tonic-gate 	    | ((uint32_t)block[1] << 16)
4977c478bd9Sstevel@tonic-gate 	    | ((uint32_t)block[2] << 8)
4987c478bd9Sstevel@tonic-gate 	    | (uint32_t)block[3];
4997c478bd9Sstevel@tonic-gate 	right = ((uint32_t)block[4] << 24)
5007c478bd9Sstevel@tonic-gate 	    | ((uint32_t)block[5] << 16)
5017c478bd9Sstevel@tonic-gate 	    | ((uint32_t)block[6] << 8)
5027c478bd9Sstevel@tonic-gate 	    | (uint32_t)block[7];
5034b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
5047c478bd9Sstevel@tonic-gate 	}
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate 	ROUND(left, right, 17);
5077c478bd9Sstevel@tonic-gate 	ROUND(left, right, 16);
5087c478bd9Sstevel@tonic-gate 	ROUND(left, right, 15);
5097c478bd9Sstevel@tonic-gate 	ROUND(left, right, 14);
5107c478bd9Sstevel@tonic-gate 	ROUND(left, right, 13);
5117c478bd9Sstevel@tonic-gate 	ROUND(left, right, 12);
5127c478bd9Sstevel@tonic-gate 	ROUND(left, right, 11);
5137c478bd9Sstevel@tonic-gate 	ROUND(left, right, 10);
5147c478bd9Sstevel@tonic-gate 	ROUND(left, right, 9);
5157c478bd9Sstevel@tonic-gate 	ROUND(left, right, 8);
5167c478bd9Sstevel@tonic-gate 	ROUND(left, right, 7);
5177c478bd9Sstevel@tonic-gate 	ROUND(left, right, 6);
5187c478bd9Sstevel@tonic-gate 	ROUND(left, right, 5);
5197c478bd9Sstevel@tonic-gate 	ROUND(left, right, 4);
5207c478bd9Sstevel@tonic-gate 	ROUND(left, right, 3);
5217c478bd9Sstevel@tonic-gate 	ROUND(left, right, 2);
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate 	tmp = left;
5247c478bd9Sstevel@tonic-gate 	left = right;
5257c478bd9Sstevel@tonic-gate 	right = tmp;
5267c478bd9Sstevel@tonic-gate 	right ^= P[1];
5277c478bd9Sstevel@tonic-gate 	left ^= P[0];
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
5307c478bd9Sstevel@tonic-gate 	if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
531f66d273dSizick 		/* LINTED:  pointer alignment */
5327c478bd9Sstevel@tonic-gate 		b32 = (uint32_t *)out_block;
5337c478bd9Sstevel@tonic-gate 		b32[0] = left;
5347c478bd9Sstevel@tonic-gate 		b32[1] = right;
5354b56a003SDaniel Anderson 	} else
5367c478bd9Sstevel@tonic-gate #endif
5374b56a003SDaniel Anderson 	{
5387c478bd9Sstevel@tonic-gate 	/* Put the block back into the user's block with final swap */
5394b56a003SDaniel Anderson #ifdef UNALIGNED_POINTERS_PERMITTED
54025cc6a40SDaniel Anderson 		*(uint32_t *)(void *)&out_block[0] = htonl(left);
54125cc6a40SDaniel Anderson 		*(uint32_t *)(void *)&out_block[4] = htonl(right);
5424b56a003SDaniel Anderson #else
5434b56a003SDaniel Anderson 		out_block[0] = left >> 24;
5444b56a003SDaniel Anderson 		out_block[1] = left >> 16;
5454b56a003SDaniel Anderson 		out_block[2] = left >> 8;
5464b56a003SDaniel Anderson 		out_block[3] = left;
5474b56a003SDaniel Anderson 		out_block[4] = right >> 24;
5484b56a003SDaniel Anderson 		out_block[5] = right >> 16;
5494b56a003SDaniel Anderson 		out_block[6] = right >> 8;
5504b56a003SDaniel Anderson 		out_block[7] = right;
5514b56a003SDaniel Anderson #endif	/* UNALIGNED_POINTERS_PERMITTED */
5527c478bd9Sstevel@tonic-gate 	}
55323c57df7Smcpowers 	return (CRYPTO_SUCCESS);
5547c478bd9Sstevel@tonic-gate }
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate static void
bitrepeat(uint8_t * pattern,uint_t len_bytes,uint_t len_bits,uint8_t * dst,uint_t dst_len_bytes)5577c478bd9Sstevel@tonic-gate bitrepeat(uint8_t *pattern, uint_t len_bytes, uint_t len_bits, uint8_t *dst,
5587c478bd9Sstevel@tonic-gate     uint_t dst_len_bytes)
5597c478bd9Sstevel@tonic-gate {
5607c478bd9Sstevel@tonic-gate 	uint8_t *current = dst;
561*95014fbbSDan OpenSolaris Anderson 	uint_t bitsleft = CRYPTO_BYTES2BITS(dst_len_bytes);
5627c478bd9Sstevel@tonic-gate 	uint_t bitoffset = 0;
5637c478bd9Sstevel@tonic-gate 	uint_t currentbits;
5647c478bd9Sstevel@tonic-gate 	int i;
5657c478bd9Sstevel@tonic-gate 
566*95014fbbSDan OpenSolaris Anderson 	BLOWFISH_ASSERT(CRYPTO_BITS2BYTES(len_bits) == len_bytes);
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate 	bzero(dst, dst_len_bytes);
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	while (bitsleft != 0) {
5717c478bd9Sstevel@tonic-gate 		if (bitsleft >= len_bits) {
5727c478bd9Sstevel@tonic-gate 			currentbits = len_bits;
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 			for (i = 0; i < len_bytes; i++) {
5757c478bd9Sstevel@tonic-gate 				if (currentbits >= 8) {
5767c478bd9Sstevel@tonic-gate 					*current++ |= pattern[i] >> bitoffset;
5777c478bd9Sstevel@tonic-gate 					*current |= pattern[i] << 8 - bitoffset;
5787c478bd9Sstevel@tonic-gate 					currentbits -= 8;
5797c478bd9Sstevel@tonic-gate 				} else {
5807c478bd9Sstevel@tonic-gate 					*current |= pattern[i] >> bitoffset;
5817c478bd9Sstevel@tonic-gate 					bitoffset = bitoffset + currentbits;
5827c478bd9Sstevel@tonic-gate 					bitoffset &= 0x7;
5837c478bd9Sstevel@tonic-gate 					if (bitoffset == 0)
5847c478bd9Sstevel@tonic-gate 						current++;
5857c478bd9Sstevel@tonic-gate 				}
5867c478bd9Sstevel@tonic-gate 			}
5877c478bd9Sstevel@tonic-gate 			bitsleft -= len_bits;
5887c478bd9Sstevel@tonic-gate 		} else {
5897c478bd9Sstevel@tonic-gate 			currentbits = bitsleft;
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 			for (i = 0; i < len_bytes && bitsleft != 0; i++) {
5927c478bd9Sstevel@tonic-gate 				if (currentbits >= 8 &&
5937c478bd9Sstevel@tonic-gate 				    current < dst + dst_len_bytes) {
5947c478bd9Sstevel@tonic-gate 					*current++ |= pattern[i] >> bitoffset;
5957c478bd9Sstevel@tonic-gate 					*current |= pattern[i] << 8 - bitoffset;
5967c478bd9Sstevel@tonic-gate 					currentbits -= 8;
5977c478bd9Sstevel@tonic-gate 					bitsleft -= 8;
5987c478bd9Sstevel@tonic-gate 				} else {
5997c478bd9Sstevel@tonic-gate 					*current |= pattern[i] >> bitoffset;
6007c478bd9Sstevel@tonic-gate 					bitsleft -= bitoffset;
6017c478bd9Sstevel@tonic-gate 					bitoffset = bitoffset + currentbits;
6027c478bd9Sstevel@tonic-gate 					bitoffset &= 0x7;
6037c478bd9Sstevel@tonic-gate 					if (bitoffset == 0)
6047c478bd9Sstevel@tonic-gate 						current++;
6057c478bd9Sstevel@tonic-gate 					currentbits = 0;
6067c478bd9Sstevel@tonic-gate 				}
6077c478bd9Sstevel@tonic-gate 			}
6087c478bd9Sstevel@tonic-gate 			bitsleft = 0;
6097c478bd9Sstevel@tonic-gate 		}
6107c478bd9Sstevel@tonic-gate 	}
6117c478bd9Sstevel@tonic-gate }
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate /*
6147c478bd9Sstevel@tonic-gate  * Initialize key schedules for Blowfish.
6157c478bd9Sstevel@tonic-gate  */
6167c478bd9Sstevel@tonic-gate void
blowfish_init_keysched(uint8_t * key,uint_t bits,void * keysched)6177c478bd9Sstevel@tonic-gate blowfish_init_keysched(uint8_t *key, uint_t bits, void *keysched)
6187c478bd9Sstevel@tonic-gate {
6197c478bd9Sstevel@tonic-gate 	keysched_t *newbie = keysched;
6207c478bd9Sstevel@tonic-gate 	uint32_t *P = newbie->ksch_P;
6217c478bd9Sstevel@tonic-gate 	uint32_t *S = newbie->ksch_S;
6227c478bd9Sstevel@tonic-gate 	uint32_t *initp;
6237c478bd9Sstevel@tonic-gate 	uint32_t tmpblock[] = {0, 0};
6247c478bd9Sstevel@tonic-gate 	uint8_t *rawkeybytes = (uint8_t *)P;
6257c478bd9Sstevel@tonic-gate 	int i, slop, copylen;
6267c478bd9Sstevel@tonic-gate 	uintptr_t bytesleft;
6277c478bd9Sstevel@tonic-gate 	uint_t len;
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate 	len = CRYPTO_BITS2BYTES(bits);
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 	if ((bits & 0x7) != 0) {
6327c478bd9Sstevel@tonic-gate 		/*
6337c478bd9Sstevel@tonic-gate 		 * Really slow case, bits aren't on a byte boundary.
6347c478bd9Sstevel@tonic-gate 		 * Keep track of individual bits copied over.  :-P
6357c478bd9Sstevel@tonic-gate 		 */
6367c478bd9Sstevel@tonic-gate 		bitrepeat(key, len, bits, rawkeybytes, 72);
6377c478bd9Sstevel@tonic-gate 	} else {
6387c478bd9Sstevel@tonic-gate 		slop = 72 % len;
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 		/* Someone gave us a nice amount (i.e. div by 8) of bits */
6417c478bd9Sstevel@tonic-gate 		while (rawkeybytes != (uint8_t *)(P + 18)) {
6427c478bd9Sstevel@tonic-gate 			bytesleft =
6437c478bd9Sstevel@tonic-gate 			    (uintptr_t)(P + 18) - (uintptr_t)rawkeybytes;
6447c478bd9Sstevel@tonic-gate 			copylen = (bytesleft >= len) ? len : slop;
6457c478bd9Sstevel@tonic-gate 			bcopy(key, rawkeybytes, copylen);
6467c478bd9Sstevel@tonic-gate 			rawkeybytes += copylen;
6477c478bd9Sstevel@tonic-gate 		}
6487c478bd9Sstevel@tonic-gate 	}
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate 	for (i = 0; i < 18; i++)
6517c478bd9Sstevel@tonic-gate 		P[i] = ntohl(P[i]) ^ init_P[i];
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate 	/* Go bcopy go!  (Hope that Ultra's bcopy is faster than me!) */
6547c478bd9Sstevel@tonic-gate 	bcopy(init_S, S, sizeof (init_S));
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 	/*
6577c478bd9Sstevel@tonic-gate 	 * When initializing P and S boxes, store the results of a single
6587c478bd9Sstevel@tonic-gate 	 * encrypt-block operation in "host order", which on little-endian
6597c478bd9Sstevel@tonic-gate 	 * means byte-swapping.  Fortunately, the ntohl() function does this
6607c478bd9Sstevel@tonic-gate 	 * quite nicely, and it a NOP on big-endian machine.
6617c478bd9Sstevel@tonic-gate 	 */
6627c478bd9Sstevel@tonic-gate 	initp = P;
6637c478bd9Sstevel@tonic-gate 	for (i = 0; i < 9; i++) {
66423c57df7Smcpowers 		(void) blowfish_encrypt_block(newbie, (uint8_t *)tmpblock,
6657c478bd9Sstevel@tonic-gate 		    (uint8_t *)tmpblock);
6667c478bd9Sstevel@tonic-gate 		*initp++ = ntohl(tmpblock[0]);
6677c478bd9Sstevel@tonic-gate 		*initp++ = ntohl(tmpblock[1]);
6687c478bd9Sstevel@tonic-gate 	}
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 	initp = S;
6717c478bd9Sstevel@tonic-gate 	for (i = 0; i < 512; i++) {
67223c57df7Smcpowers 		(void) blowfish_encrypt_block(newbie, (uint8_t *)tmpblock,
6737c478bd9Sstevel@tonic-gate 		    (uint8_t *)tmpblock);
6747c478bd9Sstevel@tonic-gate 		*initp++ = ntohl(tmpblock[0]);
6757c478bd9Sstevel@tonic-gate 		*initp++ = ntohl(tmpblock[1]);
6767c478bd9Sstevel@tonic-gate 	}
6777c478bd9Sstevel@tonic-gate }
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate /*
6807c478bd9Sstevel@tonic-gate  * Allocate key schedule for Blowfish.
6817c478bd9Sstevel@tonic-gate  */
682f66d273dSizick /* ARGSUSED */
6837c478bd9Sstevel@tonic-gate void *
blowfish_alloc_keysched(size_t * size,int kmflag)6847c478bd9Sstevel@tonic-gate blowfish_alloc_keysched(size_t *size, int kmflag)
6857c478bd9Sstevel@tonic-gate {
6867c478bd9Sstevel@tonic-gate 	keysched_t *keysched;
6877c478bd9Sstevel@tonic-gate 
688f66d273dSizick #ifdef _KERNEL
6897c478bd9Sstevel@tonic-gate 	keysched = (keysched_t *)kmem_alloc(sizeof (keysched_t), kmflag);
690f66d273dSizick #else
691f66d273dSizick 	keysched = (keysched_t *)malloc(sizeof (keysched_t));
692f66d273dSizick #endif /* _KERNEL */
6937c478bd9Sstevel@tonic-gate 	if (keysched != NULL) {
6947c478bd9Sstevel@tonic-gate 		*size = sizeof (keysched_t);
6957c478bd9Sstevel@tonic-gate 		return (keysched);
6967c478bd9Sstevel@tonic-gate 	}
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate 	return (NULL);
6997c478bd9Sstevel@tonic-gate }
70023c57df7Smcpowers 
70123c57df7Smcpowers void
blowfish_copy_block(uint8_t * in,uint8_t * out)70223c57df7Smcpowers blowfish_copy_block(uint8_t *in, uint8_t *out)
70323c57df7Smcpowers {
70423c57df7Smcpowers 	if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
70523c57df7Smcpowers 	    IS_P2ALIGNED(out, sizeof (uint32_t))) {
70623c57df7Smcpowers 		/* LINTED: pointer alignment */
70723c57df7Smcpowers 		*(uint32_t *)&out[0] = *(uint32_t *)&in[0];
70823c57df7Smcpowers 		/* LINTED: pointer alignment */
70923c57df7Smcpowers 		*(uint32_t *)&out[4] = *(uint32_t *)&in[4];
71023c57df7Smcpowers 	} else {
71123c57df7Smcpowers 		BLOWFISH_COPY_BLOCK(in, out);
71223c57df7Smcpowers 	}
71323c57df7Smcpowers }
71423c57df7Smcpowers 
71523c57df7Smcpowers /* XOR block of data into dest */
71623c57df7Smcpowers void
blowfish_xor_block(uint8_t * data,uint8_t * dst)71723c57df7Smcpowers blowfish_xor_block(uint8_t *data, uint8_t *dst)
71823c57df7Smcpowers {
71923c57df7Smcpowers 	if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
72023c57df7Smcpowers 	    IS_P2ALIGNED(data, sizeof (uint32_t))) {
72123c57df7Smcpowers 		/* LINTED: pointer alignment */
72223c57df7Smcpowers 		*(uint32_t *)&dst[0] ^= *(uint32_t *)&data[0];
72323c57df7Smcpowers 		/* LINTED: pointer alignment */
72423c57df7Smcpowers 		*(uint32_t *)&dst[4] ^= *(uint32_t *)&data[4];
72523c57df7Smcpowers 	} else {
72623c57df7Smcpowers 		BLOWFISH_XOR_BLOCK(data, dst);
72723c57df7Smcpowers 	}
72823c57df7Smcpowers }
72923c57df7Smcpowers 
73023c57df7Smcpowers /*
73123c57df7Smcpowers  * Encrypt multiple blocks of data according to mode.
73223c57df7Smcpowers  */
73323c57df7Smcpowers int
blowfish_encrypt_contiguous_blocks(void * ctx,char * data,size_t length,crypto_data_t * out)73423c57df7Smcpowers blowfish_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
73523c57df7Smcpowers     crypto_data_t *out)
73623c57df7Smcpowers {
73723c57df7Smcpowers 	blowfish_ctx_t *blowfish_ctx = ctx;
73823c57df7Smcpowers 	int rv;
73923c57df7Smcpowers 
74023c57df7Smcpowers 	if (blowfish_ctx->bc_flags & CBC_MODE) {
74123c57df7Smcpowers 		rv = cbc_encrypt_contiguous_blocks(ctx, data, length, out,
74223c57df7Smcpowers 		    BLOWFISH_BLOCK_LEN, blowfish_encrypt_block,
74323c57df7Smcpowers 		    blowfish_copy_block, blowfish_xor_block);
74423c57df7Smcpowers 	} else {
74523c57df7Smcpowers 		rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
74623c57df7Smcpowers 		    BLOWFISH_BLOCK_LEN, blowfish_encrypt_block);
74723c57df7Smcpowers 	}
74823c57df7Smcpowers 	return (rv);
74923c57df7Smcpowers }
75023c57df7Smcpowers 
75123c57df7Smcpowers /*
75223c57df7Smcpowers  * Decrypt multiple blocks of data according to mode.
75323c57df7Smcpowers  */
75423c57df7Smcpowers int
blowfish_decrypt_contiguous_blocks(void * ctx,char * data,size_t length,crypto_data_t * out)75523c57df7Smcpowers blowfish_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
75623c57df7Smcpowers     crypto_data_t *out)
75723c57df7Smcpowers {
75823c57df7Smcpowers 	blowfish_ctx_t *blowfish_ctx = ctx;
75923c57df7Smcpowers 	int rv;
76023c57df7Smcpowers 
76123c57df7Smcpowers 	if (blowfish_ctx->bc_flags & CBC_MODE) {
76223c57df7Smcpowers 		rv = cbc_decrypt_contiguous_blocks(ctx, data, length, out,
76323c57df7Smcpowers 		    BLOWFISH_BLOCK_LEN, blowfish_decrypt_block,
76423c57df7Smcpowers 		    blowfish_copy_block, blowfish_xor_block);
76523c57df7Smcpowers 	} else {
76623c57df7Smcpowers 		rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
76723c57df7Smcpowers 		    BLOWFISH_BLOCK_LEN, blowfish_decrypt_block);
76823c57df7Smcpowers 		if (rv == CRYPTO_DATA_LEN_RANGE)
76923c57df7Smcpowers 			rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
77023c57df7Smcpowers 	}
77123c57df7Smcpowers 	return (rv);
77223c57df7Smcpowers }
773